Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Z-Image-Turbo FastAPI Inference Server

A production-ready, high-performance FastAPI microservice for image generation using the Z-Image-Turbo diffusion model. Optimized for GPU execution with NVIDIA CUDA support, API key protection, and comprehensive logging.

πŸš€ Features

  • FastAPI Framework: Modern async Python web framework with automatic OpenAPI documentation
  • GPU-Optimized: CUDA 12.1 support with memory-efficient inference (fp16, bfloat16, fp8)
  • Singleton Model Loading: Efficient model management with thread-safe singleton pattern
  • API Key Authentication: Secure X-API-Key header-based authentication
  • Health Monitoring: Public health endpoint with GPU/memory metrics
  • Docker Ready: Production-grade Dockerfile with multi-stage builds
  • Comprehensive Logging: Detailed logs including GPU memory tracking
  • Error Handling: Graceful CUDA OOM handling and validation
  • Pydantic Validation: Strong type hints and request validation

πŸ“‹ Requirements

System

  • GPU: NVIDIA GPU with CUDA 12.1 support (Tesla T4, V100, A100, H100, etc.)
  • CPU: 4+ cores recommended
  • RAM: 16GB minimum, 32GB+ recommended
  • VRAM: 6GB minimum (for fp16), 12GB+ recommended

Software

  • Docker: With NVIDIA Container Runtime support
  • Python: 3.10+ (if running locally)
  • CUDA: 12.1 (automatically included in Docker image)

πŸ—οΈ Project Structure

sdxl-zimage-api/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ __init__.py              # Package initialization
β”‚   β”œβ”€β”€ main.py                  # FastAPI routes and application setup
β”‚   β”œβ”€β”€ config.py                # Pydantic Settings for configuration
β”‚   β”œβ”€β”€ auth.py                  # API Key validation
β”‚   └── model_pipeline.py        # Model engine and inference logic
β”œβ”€β”€ Dockerfile                   # Multi-stage production Docker setup
β”œβ”€β”€ requirements.txt             # Python dependencies
β”œβ”€β”€ .env.example                 # Example environment configuration
└── README.md                    # This file

πŸ”§ Configuration

Environment Variables

Copy .env.example to .env and update values:

cp .env.example .env

Key environment variables:

  • API_KEY: Secret key for X-API-Key authentication (change in production!)
  • MODEL_ID: Hugging Face model repository ID (default: stabilityai/sd-turbo)
  • PRECISION: Model precision - fp32, fp16, bfloat16, or fp8
  • GPU_DEVICE: CUDA device ID (default: cuda)
  • MAX_QUEUE_SIZE: Maximum concurrent requests (default: 10)

See .env.example for all available options.

🐳 Docker Deployment

Build the Docker Image

docker build -t z-image-turbo-api:latest .

Run the Container

docker run --gpus all \
  --env-file .env \
  -p 8000:8000 \
  z-image-turbo-api:latest

Docker Compose (Optional)

Create docker-compose.yml:

version: '3.8'

services:
  api:
    build: .
    container_name: z-image-turbo-api
    env_file: .env
    ports:
      - "8000:8000"
    volumes:
      - ./models_cache:/home/appuser/.cache/huggingface  # Cache models
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]
    restart: unless-stopped

Run with:

docker-compose up -d

πŸƒ Local Development

Setup

# Create virtual environment
python3.10 -m venv venv
source venv/bin/activate

# Install dependencies
pip install -r requirements.txt

Run Locally

# Set environment variables
export API_KEY="test-key-12345"
export MODEL_ID="stabilityai/sd-turbo"

# Run server
python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload

πŸ“‘ API Usage

Base URL

http://localhost:8000

Authentication

All endpoints (except /health) require the X-API-Key header:

X-API-Key: your-secret-api-key

Endpoints

1. Health Check (Public)

GET /health

Response:

{
  "status": "healthy",
  "model_ready": true,
  "device": "cuda",
  "gpu_memory": {
    "allocated_gb": 5.2,
    "reserved_gb": 6.0,
    "available_gb": 16.0
  },
  "system_memory_gb": 8.5
}

2. Generate Image (Protected)

POST /api/v1/generate
Content-Type: application/json
X-API-Key: your-secret-api-key

{
  "prompt": "A futuristic city with neon lights, high resolution",
  "negative_prompt": "blurry, low quality, distorted",
  "width": 768,
  "height": 768,
  "num_inference_steps": 8,
  "guidance_scale": 1.5,
  "return_type": "base64"
}

Response (return_type: "base64"):

{
  "success": true,
  "image": "iVBORw0KGgoAAAANSUhEUgAA...",
  "format": "png",
  "size": {
    "width": 768,
    "height": 768
  },
  "prompt": "A futuristic city with neon lights, high resolution",
  "inference_steps": 8
}

Response (return_type: "binary"):

Raw PNG image data with Content-Type: image/png

Example Requests

Using cURL

# Health check
curl http://localhost:8000/health

# Generate image with base64 response
curl -X POST http://localhost:8000/api/v1/generate \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-secret-api-key" \
  -d '{
    "prompt": "A serene mountain landscape at sunset",
    "width": 768,
    "height": 768,
    "num_inference_steps": 8,
    "guidance_scale": 1.5
  }' > response.json

# Generate image with binary response (save directly)
curl -X POST http://localhost:8000/api/v1/generate \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-secret-api-key" \
  -d '{
    "prompt": "A robot painting a masterpiece",
    "width": 768,
    "height": 768,
    "num_inference_steps": 8,
    "return_type": "binary"
  }' > generated_image.png

Using Python Requests

import requests
import json
from PIL import Image
from io import BytesIO
import base64

API_KEY = "your-secret-api-key"
BASE_URL = "http://localhost:8000"

# Check health
response = requests.get(f"{BASE_URL}/health")
print(response.json())

# Generate image
payload = {
    "prompt": "A cyberpunk samurai warrior",
    "width": 768,
    "height": 768,
    "num_inference_steps": 8,
    "guidance_scale": 1.5,
    "return_type": "base64"
}

headers = {"X-API-Key": API_KEY}
response = requests.post(
    f"{BASE_URL}/api/v1/generate",
    json=payload,
    headers=headers
)

if response.status_code == 200:
    data = response.json()

    # Decode base64 image
    image_data = base64.b64decode(data["image"])
    image = Image.open(BytesIO(image_data))
    image.save("generated.png")
    print("Image saved as generated.png")
else:
    print(f"Error: {response.status_code}")
    print(response.json())

Using JavaScript/Node.js

const API_KEY = "your-secret-api-key";
const BASE_URL = "http://localhost:8000";

async function generateImage() {
  const payload = {
    prompt: "A majestic dragon flying over mountains",
    width: 768,
    height: 768,
    num_inference_steps: 8,
    guidance_scale: 1.5,
    return_type: "base64"
  };

  const response = await fetch(`${BASE_URL}/api/v1/generate`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-Key": API_KEY
    },
    body: JSON.stringify(payload)
  });

  if (response.ok) {
    const data = await response.json();
    console.log("Image generated successfully!");
    console.log(`Size: ${data.size.width}x${data.size.height}`);
    // Download or display base64 image
    return data.image;
  } else {
    console.error(`Error: ${response.status}`, await response.json());
  }
}

generateImage();

πŸ”’ Security Considerations

  1. API Key Protection

    • Change API_KEY in .env for production
    • Use strong, random API keys (min 32 characters)
    • Rotate keys periodically
  2. Network Security

    • Deploy behind a reverse proxy (nginx, traefik)
    • Use HTTPS/TLS in production
    • Implement rate limiting
    • Use firewall rules to restrict access
  3. GPU Security

    • Run container with --gpus all (not --privileged)
    • Use read-only filesystem where possible
    • Drop unnecessary Linux capabilities
  4. Resource Limits

    • Set memory limits in Docker
    • Configure MAX_QUEUE_SIZE to prevent abuse
    • Implement request timeouts

πŸ“Š Performance Tuning

Inference Speed

  • num_inference_steps: Lower = faster but lower quality (try 4-8)
  • guidance_scale: Lower values speed up inference (try 1.0-2.0)
  • Image size: Smaller images are faster (try 512x512)

Memory Usage

  • precision: Use fp16 or bfloat16 to reduce memory
  • enable_xformers: Significantly reduces VRAM usage
  • batch_size: Currently supports single image generation

GPU Optimization Tips

# In production Docker, use:
ENV CUDA_VISIBLE_DEVICES=0  # Single GPU
ENV CUDA_LAUNCH_BLOCKING=0   # Async GPU launches

πŸ› Troubleshooting

CUDA Out of Memory

RuntimeError: CUDA out of memory

Solutions:

  • Reduce num_inference_steps (try 4-6)
  • Reduce image dimensions (try 512x512)
  • Enable ENABLE_XFORMERS=true
  • Use PRECISION=fp8 instead of fp16

Model Download Fails

OSError: Can't load model...

Solutions:

  • Check internet connection
  • Pre-download model: huggingface-cli download stabilityai/sd-turbo
  • Mount model cache volume in Docker

GPU Not Detected

RuntimeError: No CUDA GPUs available

Solutions:

  • Verify NVIDIA GPU: nvidia-smi
  • Install NVIDIA Container Runtime: nvidia-ctk runtime configure --runtime=docker
  • Restart Docker: systemctl restart docker
  • Ensure --gpus all flag is set

πŸ“ˆ Monitoring & Logs

View Container Logs

docker logs -f z-image-turbo-api

Key Log Messages

# Successful startup
INFO: Uvicorn running on http://0.0.0.0:8000
INFO: Model loaded successfully on device: cuda

# Inference
INFO: GPU Memory before inference: allocated=4.2GB, reserved=5.0GB
INFO: GPU Memory after inference: allocated=0.2GB, reserved=5.0GB

# Errors
ERROR: CUDA out of memory error during inference
ERROR: Model engine not ready

πŸ“š API Documentation

Interactive API Docs

Once server is running:

πŸš€ Production Deployment

AWS EC2 (GPU Instance)

# Launch g4dn.xlarge or g5.xlarge instance
# Install Docker and NVIDIA Container Runtime

# Build and run
docker build -t z-image-turbo-api:latest .
docker run --gpus all --env-file .env -p 8000:8000 z-image-turbo-api:latest

Kubernetes

apiVersion: v1
kind: Pod
metadata:
  name: z-image-turbo
spec:
  containers:
  - name: api
    image: z-image-turbo-api:latest
    envFrom:
    - configMapRef:
        name: api-config
    ports:
    - containerPort: 8000
    resources:
      limits:
        nvidia.com/gpu: 1
      requests:
        memory: "16Gi"
        cpu: "4"

Reverse Proxy (nginx)

server {
    listen 443 ssl http2;
    server_name api.example.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    location / {
        proxy_pass http://localhost:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 300s;
        proxy_connect_timeout 300s;
    }
}

πŸ“ License

Specify your license here (e.g., MIT, Apache 2.0)

🀝 Contributing

Contributions welcome! Please ensure:

  • Code follows existing style
  • Type hints are complete
  • Error handling is comprehensive
  • Documentation is updated

πŸ“ž Support

For issues, questions, or feature requests, please open an issue on GitHub.


Made with ❀️ for high-performance image generation

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages