Skip to main content
This tutorial shows you how to build an image generation script using Flash and Stable Diffusion XL (SDXL). You’ll learn how to load a pretrained diffusion model on a GPU worker and generate images from text prompts.

Requirements

What you’ll build

By the end of this tutorial, you’ll have a working image generation application that:
  • Accepts text prompts as input.
  • Generates photorealistic images using Stable Diffusion XL.
  • Runs entirely on Runpod’s GPU infrastructure.
  • Saves generated images to your local machine.

Step 1: Set up your project

Create a new directory for your project and set up a Python virtual environment:
Install Flash using uv:
Create a .env file with your Runpod API key:
Replace YOUR_API_KEY with your actual API key from the Runpod console.

Step 2: Understand Stable Diffusion XL

Stable Diffusion XL (SDXL) is a state-of-the-art text-to-image model from Stability AI. It offers:
  • High-quality images: Generates photorealistic 1024x1024 images
  • Better prompt understanding: Improved text comprehension compared to SD 1.5
  • Fine details: Enhanced rendering of hands, faces, and text
  • Open source: Available for free on Hugging Face
SDXL requires significant GPU resources:
  • Model size: ~7GB of weights
  • VRAM requirement: Minimum 16GB (24GB recommended)
  • Generation time: 20-40 seconds per image on RTX 4090
We’ll use the diffusers library from Hugging Face, which provides a clean Python API for Stable Diffusion models.

Step 3: Create your project file

Create a new file called image_generation.py:
Open this file in your code editor. The following steps walk through building the image generation application.

Step 4: Add imports and configuration

Add the necessary imports and Flash configuration:

Step 5: Define the image generation function

Add the endpoint function that will run on the GPU worker:
Configuration breakdown:
  • name="image-generation": Identifies your endpoint in the Runpod console.
  • gpu=[GpuGroup.ADA_24, GpuGroup.AMPERE_24]: Uses RTX 4090 or L4/A5000 GPUs (both have 24GB VRAM, sufficient for SDXL).
  • workers=2: Allows up to 2 parallel workers.
  • idle_timeout=900: Keeps workers active for 15 minutes (SDXL models are large, so we want longer caching).
SDXL requires at least 16GB VRAM. Using 24GB GPUs provides comfortable headroom and faster generation.
This function:
  • Loads the SDXL model from Hugging Face.
  • Moves the model to the GPU.
  • Generates an image from the prompt.
  • Encodes the image as base64.
  • Returns the image as a base64 string (and other metadata).
Expand this section for a full breakdown:
Dependencies: The function requires four packages:
  • diffusers: Hugging Face library for diffusion models
  • torch: PyTorch for GPU computation
  • transformers: Text encoder dependencies
  • accelerate: Efficient model loading
Model loading:
This downloads SDXL from Hugging Face. Key parameters:
  • torch_dtype=torch.float16: Use half-precision (saves VRAM, faster)
  • use_safetensors=True: Use safe tensor format
  • variant="fp16": Download the fp16 version (~7GB instead of ~14GB)
GPU acceleration:
Moves the entire pipeline (text encoder, UNet, VAE) to GPU.Image generation:
Parameters:
  • prompt: What you want to see in the image
  • negative_prompt: What you don’t want (e.g., “blurry, low quality”)
  • num_inference_steps: More steps = better quality but slower (20-50 typical)
  • guidance_scale: How closely to follow the prompt (7-10 recommended)
  • height/width: SDXL is trained for 1024x1024
Image encoding:
We encode the image as base64 to return it through Flash. This allows us to transmit the image data as a string.

Step 6: Add the main function and image saving

Create functions to call the generator and save images:
This main function:
  • Calls the remote function with await.
  • Creates a generated_images directory if it doesn’t exist.
  • Decodes and saves the base64 image to disk.
  • Displays generation metadata.

Step 7: Run your first generation

Run the application:
First run output (takes 2-3 minutes):
Subsequent runs (takes 30-40 seconds):
Open generated_images/sdxl_output.png to see your generated image!
The first run downloads ~7GB of model weights, which takes 1-2 minutes. Subsequent runs reuse the cached model and complete in 30-40 seconds.

Step 8: Experiment with different prompts

Try various prompts to see SDXL’s capabilities:
Run it:
You’ll see three different images generated sequentially on the same GPU worker. Each generation takes about 30-40 seconds after the first one.

Understanding generation parameters

Let’s explore how different parameters affect image quality:

Number of inference steps

Effects:
  • 15-20 steps: Faster (15-20 seconds) but less refined details.
  • 30 steps: Good balance of quality and speed (30-40 seconds) - recommended.
  • 50+ steps: Diminishing returns, minimal quality improvement.

Guidance scale

Effects:
  • 3-5: More artistic freedom, less literal interpretation.
  • 7-10: Balanced, follows prompt closely - recommended.
  • 12+: Very literal, may produce oversaturated or exaggerated images.

Negative prompts

Negative prompts tell the model what to avoid:
Use negative prompts to:
  • Remove common artifacts (“distorted”, “low quality”).
  • Avoid unwanted styles (“cartoon”, “3D render”).
  • Fix common issues (“bad anatomy”, “extra fingers”).

Troubleshooting

Out of memory error

Issue: RuntimeError: CUDA out of memory. Cause: SDXL requires significant VRAM (16GB minimum). Solutions:
  1. Verify you’re using 24GB GPUs:
  2. Use half-precision (already in the example):
  3. If still failing, use 48GB GPUs:

Model download fails

Issue: Error: Failed to download model from Hugging Face. Solutions:
  1. Increase execution timeout for first run:
  2. Check Hugging Face Hub status at status.huggingface.co.
  3. Try a smaller model first to test connectivity:

Image quality is poor

Issue: Generated images look blurry or low quality. Solutions:
  1. Increase inference steps:
  2. Adjust guidance scale:
  3. Improve your prompt:
  4. Add quality keywords to your prompt:
    • “highly detailed”
    • “sharp focus”
    • “8k”
    • “photorealistic”
    • “professional”

Slow generation

Issue: Image generation takes >60 seconds per image. Possible causes:
  1. Worker scaled down (cold start).
  2. Model not cached.
  3. Too many inference steps.
Solutions:
  1. Increase idle_timeout to keep workers active:
  2. Reduce inference steps:
  3. Set workers=(1, 2) to always have a warm worker ready.

Images look distorted or have artifacts

Issue: Generated images have weird artifacts or distortions. Solutions:
  1. Use negative prompts:
  2. Adjust guidance scale (try 7-9 range):
  3. Increase inference steps for better refinement:

Next steps

Now that you’ve built an image generation script with Flash, you can:

Try other Stable Diffusion models

Explore different models from Hugging Face:

Add image-to-image generation

Use an existing image as a starting point:

Build a Flash app

Convert your script to a production Flash app:

Optimize with network volumes

Use network volumes to cache models across workers:

Explore advanced features

  • LoRA fine-tuning: Customize SDXL for specific styles.
  • ControlNet: Guide generation with edge maps, depth, or pose.
  • Inpainting: Edit specific parts of images.
  • Upscaling: Generate higher resolution images.