Skip to main content
Flash is now part of the Runpod SDK. This page documents the standalone runpod-flash package, which stops getting fixes and updates after its deprecation date. For new projects, use the Runpod SDK. To see how Flash commands and imports map to the SDK, see Migrating from Flash.
This tutorial shows you how to build a text generation script using Flash and Hugging Face’s transformers library. You’ll learn how to load a pretrained language model on a GPU worker and generate text from prompts.

Requirements

What you’ll build

By the end of this tutorial, you’ll have a working text generation application that:
  • Accepts text prompts as input.
  • Generates natural language completions using GPT-2.
  • Runs entirely on Runpod’s GPU infrastructure.
  • Returns generated text with execution metadata.

Step 1: Set up your project

Create a new directory for your project and set up a Python virtual environment:
Install Flash using uv:
Log in so Flash can deploy and call endpoints on your account:
Alternatively, create a .env file with your API key. Flash loads .env from the current directory automatically:
Replace YOUR_API_KEY with your API key from the Runpod console.
The directory name becomes your Flash app name. Run flash deploy and your script from this directory.

Step 2: Understand the Hugging Face transformers library

Hugging Face transformers is a Python library for running pretrained language models. The same API loads thousands of models from the Hugging Face Hub. This tutorial uses GPT-2, a 124M-parameter model from OpenAI. It’s small (about 500 MB), loads in seconds, and needs less than 2 GB of VRAM. It continues text rather than following instructions, so expect creative completions, not answers.

Step 3: Create your project file

Create a file called text_generation.py in your project directory. The next three steps build it up section by section. The complete file is at the end of Step 6.

Step 4: Add imports and configuration

_model and _tokenizer cache the model on the worker, so only the first request on each worker loads it.

Step 5: Define the text generation function

Add the endpoint function that runs on the GPU worker:
Configuration breakdown:
  • name="text-generation": Identifies your endpoint in the Runpod console.
  • gpu=[GpuGroup.AMPERE_24, GpuGroup.ADA_24]: Uses 24 GB GPUs such as the RTX 3090, RTX 4090, L4, or A5000. GPT-2 needs far less, so any of them work.
  • workers=3: Allows up to 3 parallel workers for concurrent requests.
  • idle_timeout=600: Keeps a worker running for 10 minutes after its last request, so the loaded model stays in memory.
  • dependencies: Installed into your build. torch is already in the worker image, so Flash leaves it out of the upload.
Don’t add accelerate to dependencies. GPT-2 doesn’t need it, and because it requires torch, on Linux flash deploy downloads torch and several GB of CUDA libraries into the local build. Without it, the build is about 40 MB.
Imports inside the function: torch and transformers are imported inside generate_text because they’re installed on the worker, not on your machine.Model caching:
The worker imports your file once and keeps it in memory between requests, so module-level variables persist. The first request on a worker downloads and loads GPT-2. Later requests on the same worker reuse it. model_cached in the result tells you which happened.Tokenization:
Converts the prompt into token IDs on the GPU.Generation parameters:
  • max_new_tokens: How many tokens to generate after the prompt.
  • do_sample=True: Samples from the model’s predictions instead of always picking the most likely token, so each run gives a different completion.
  • temperature: Controls randomness when sampling. Lower values are more predictable, higher values more varied.
  • pad_token_id: GPT-2 has no padding token, so this reuses the end-of-text token and avoids a warning.
No gradient tracking: torch.no_grad() skips the bookkeeping needed for training, which saves memory during inference.

Step 6: Add the main function

Add a main() function that calls the endpoint. It runs on your machine:
Keep the if __name__ == "__main__": block at the end of the file. Without it, the script exits without doing anything.

Complete file

Step 7: Deploy and run your first generation

Deploy the endpoint from your project directory:
Then run the script from the same directory:
The first run takes about a minute while a worker starts and loads the model:
Run it again while the worker is warm. The model is already loaded, so the whole run takes about 2 seconds:
Your completions will differ because do_sample=True picks tokens at random.
The first request on a new worker can take longer than the 90 seconds runpod-flash 1.21.0 waits for a result, especially if the worker has to wait for a free GPU. If the script fails with timed out after 90s. the endpoint may not be deployed or the worker is still starting or KeyError: 'generated_text', the endpoint is deployed and the worker is still starting. Run the script again. See First run fails after 90 seconds.

Step 8: Try several prompts in parallel

Replace main() with a version that sends three prompts at once:
You only changed code outside the @Endpoint function, so you don’t need to redeploy. Run it again:
All three requests are sent at once. A warm worker returned all three completions in about 3 seconds. If requests queue up, Flash starts more workers, up to workers=3, and each new worker loads the model on its first request.

Troubleshooting

Model download fails

Issue: Error: Failed to download model from Hugging Face. Solutions:
  1. Check internet connectivity from workers (rare issue on Runpod).
  2. Try a different model that might be available faster.
  3. Increase execution timeout in configuration:

Out of memory error

Issue: RuntimeError: CUDA out of memory. Solutions:
  1. Use smaller models (GPT-2 instead of GPT-2 Large).
  2. Reduce max_new_tokens.
  3. Use larger GPUs:

Slow generation

Issue: Every request takes much longer than a few seconds. Check model_cached in the result. If it’s False on most requests, workers are loading the model again:
  1. Make sure _model and _tokenizer are module-level variables and generate_text declares global _model, _tokenizer.
  2. Increase idle_timeout so workers stay up between requests:
  3. Set workers=(1, 3) to keep one worker running at all times. You pay for that worker while it’s idle.
If model_cached is True and generation is still slow, reduce max_new_tokens.

First run fails after 90 seconds

Issue: The first run fails with one of these errors:
Cause: runpod-flash 1.21.0 waits up to 90 seconds for a result. The first request on a new worker can take longer: the worker may wait for a free GPU, then it starts and loads the model. The endpoint is deployed, and the request keeps running after the error. Solution: Run the script again. The worker keeps starting after the error, so the next run is faster. Raising FLASH_SENTINEL_TIMEOUT above 90 doesn’t help in 1.21.0: the request returns at 90 seconds with the job still running, and the script fails with the KeyError instead. To see whether a worker is up, check the endpoint’s health with its ID from flash deploy. curl reads your API key from the RUNPOD_API_KEY environment variable, which flash login doesn’t set, so export it first:
A non-zero workers.throttled means the worker is waiting for a GPU. A non-zero workers.idle, workers.ready, or workers.running means a worker is up.

Generation quality is poor

Issue: Generated text is incoherent or repetitive. Solutions:
  1. Adjust temperature (try 0.7-0.9)
  2. Add top_p and top_k sampling:
  3. Try a larger model (GPT-2 Medium or Large).

Next steps

Now that you’ve built a text generation script with Flash, you can:

Explore other models

Try different models from Hugging Face: Change MODEL_NAME and run flash deploy again:

Build a chat interface

Extend your app to handle multi-turn conversations:

Deploy as a Flash app

Convert your script to a production Flash app:
flash init creates gpu_worker.py, cpu_worker.py, and lb_worker.py at the project root.
When deploying queue-based functions with flash deploy, each function must have its own unique endpoint configuration. generate_text and chat in this tutorial already have separate configs (name="text-generation" and name="chat"), so keep them that way when you move them into a Flash app. See understanding endpoint architecture for details.

Optimize performance

Last modified on October 27, 2026