* Add AI image editing tools (qwen-edit, upscale) New features: - image_edit.py: AI image editing using Qwen-Image-Edit-2511 - Style transfer, background replacement, custom prompts - Multi-image compositing support - Presets for common operations - upscale.py: AI image upscaling using RealESRGAN - 2x/4x upscaling with general, anime, and photo models - Optional face enhancement (GFPGAN) - qwen-edit skill: Prompting patterns and best practices - RunPod workers for cloud GPU processing Both tools use RunPod serverless for cloud processing. See docs/qwen-edit-patterns.md for prompting guidance. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Add pre-built Docker image references for RunPod tools - Add GHCR image URLs for qwen-edit, realesrgan, propainter - Consolidate Cloud GPU tools category (image_edit, upscale, dewatermark) - Document that --setup uses pre-built images (no building required) Images hosted at ghcr.io/conalmullan/video-toolkit-* 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Update RunPod docs for all Cloud GPU tools, bump to v0.8.0 - Restructure runpod-setup.md to cover image_edit, upscale, dewatermark - Add GPU requirements table for each tool - Document all three endpoint environment variables - Update pre-built image references - Bump version to 0.8.0 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
RunPod Qwen-Edit Docker Image
Serverless GPU handler for AI-powered image editing using Qwen-Image-Edit-2511 with LightX2V acceleration.
This is Worker 1 in the video generation pipeline:
Reference Image -> [Qwen-Edit] -> Edited Frame -> [Wan I2V] -> Video Clip
Quick Start
Option A: Use Pre-built Public Image (Recommended)
ghcr.io/conalmullan/video-toolkit-qwen-edit:latest
Skip to Step 2: Deploy on RunPod below.
Option B: Build Your Own Image
cd docker/runpod-qwen-edit
# Build for linux/amd64 (required for RunPod)
docker buildx build --platform linux/amd64 -t ghcr.io/yourusername/video-toolkit-qwen-edit:latest --push .
Build takes ~45-60 minutes (downloads ~30GB of model weights).
Important: Make the image public
GHCR images are private by default. RunPod cannot pull private images.
- Go to https://github.com/users/yourusername/packages/container/video-toolkit-qwen-edit/settings
- Scroll to "Danger Zone"
- Click "Change visibility" → Select "Public" → Confirm
Deploy on RunPod
- Go to RunPod Serverless
- Click New Endpoint
- Configure:
- Docker Image:
ghcr.io/conalmullan/video-toolkit-qwen-edit:latest - GPU: L4 24GB or RTX 4090 (24GB+ VRAM required)
- Max Workers: 1 (scale up as needed)
- Idle Timeout: 5 seconds (fast scale-down)
- Execution Timeout: 120 seconds (2 min max per job)
- Docker Image:
- Copy the Endpoint ID for your
.envfile
Configure Local Tool
Add to your .env:
RUNPOD_API_KEY=your_api_key_here
RUNPOD_QWEN_EDIT_ENDPOINT_ID=your_endpoint_id_here
Use It
# Generate edited frame (via orchestration tool - coming soon)
python tools/videogen.py edit \
--image reference.png \
--prompt "Change background to modern office" \
--output edited.png
Image Details
| Property | Value |
|---|---|
| Base | nvidia/cuda:12.4.1-cudnn-devel-ubuntu22.04 |
| Size | ~25GB |
| Cold Start | ~60 seconds |
| Python | 3.11 |
| PyTorch | 2.5.1 + CUDA 12.4 |
Pre-baked Components
- Qwen-Image-Edit-2511 base model (~20GB)
- LightX2V Lightning FP8 weights (~10GB)
- 4-step inference (vs 40 native)
- FP8 quantization (50% VRAM reduction)
- Flash Attention 3 for optimized inference
- FFmpeg for image processing
- RunPod SDK
API Reference
Edit Operation
Edit an image based on text prompt while preserving subject identity.
Input:
{
"input": {
"image_base64": "<base64 encoded image>",
"prompt": "Change the background to a modern office",
"negative_prompt": "blurry, distorted",
"num_inference_steps": 8,
"guidance_scale": 1.0,
"seed": 42,
"use_fp8": true,
"r2": {
"endpoint_url": "https://...",
"access_key_id": "...",
"secret_access_key": "...",
"bucket_name": "..."
}
}
}
| Parameter | Required | Default | Description |
|---|---|---|---|
image_base64 |
Yes | - | Base64 encoded input image |
prompt |
Yes | - | Edit instruction |
negative_prompt |
No | "" | Things to avoid |
num_inference_steps |
No | 8 (FP8), 4 (LoRA) | Diffusion steps |
guidance_scale |
No | 1.0 | CFG scale |
seed |
No | random | Random seed for reproducibility |
use_fp8 |
No | true | Use FP8 quantization (lower VRAM) |
auto_resize |
No | true | Auto-resize for optimal processing |
r2 |
No | - | R2 config for result upload |
Output:
{
"success": true,
"edited_image_base64": "<base64 encoded result>",
"seed": 42,
"inference_time_ms": 1800,
"image_size": [1024, 1024],
"num_inference_steps": 8,
"use_fp8": true
}
If R2 config provided:
{
"success": true,
"edited_image_base64": "<base64>",
"output_url": "https://r2.example.com/...",
"r2_key": "qwen-edit/results/abc123.png",
...
}
Example Prompts
Background changes:
- "Change the background to a modern office"
- "Replace background with outdoor park scene"
- "Add a professional studio backdrop"
Pose/expression adjustments:
- "Change pose to speaking gesture"
- "Add subtle smile"
- "Subject looking slightly left"
Lighting/style:
- "Add professional lighting"
- "Apply warm color grading"
- "Make lighting more dramatic"
GPU Memory Requirements
| GPU VRAM | FP8 Mode | BF16 Mode | Notes |
|---|---|---|---|
| 24GB | Yes | Yes* | *May be tight |
| 48GB | Yes | Yes | Recommended |
| 80GB | Yes | Yes | Fastest |
Recommendation: Use L4, RTX 4090, or A6000 (24GB+) with FP8 mode.
Performance
Using L4 24GB (~$0.34/hr):
| Mode | Steps | Time | Cost/Edit |
|---|---|---|---|
| FP8 Lightning | 8 | ~2s | ~$0.0002 |
| LoRA Lightning | 4 | ~1.5s | ~$0.00014 |
| Native (no accel) | 40 | ~15s | ~$0.0014 |
LightX2V acceleration provides ~10x speedup and ~50% VRAM reduction.
Local Testing
Test the image locally with NVIDIA GPU:
# Build
docker build -t qwen-edit-test .
# Run interactive shell
docker run --gpus all -it qwen-edit-test /bin/bash
# Inside container, test GPU
python3 -c "import torch; print(f'CUDA: {torch.cuda.is_available()}')"
# Test LightX2V
python3 -c "from lightx2v import LightX2VPipeline; print('LightX2V OK')"
# Test model paths
python3 -c "from pathlib import Path; print(f'Model: {Path(\"/models/qwen-edit\").exists()}')"
Troubleshooting
"CUDA out of memory"
- Ensure
use_fp8: trueis set (default) - Use a GPU with 24GB+ VRAM
- Enable auto_resize to scale down large images
"Generation failed - no output file"
Check the prompt syntax. Qwen-Image-Edit works best with:
- Clear, specific instructions
- Focus on ONE change at a time
- Avoid contradictory instructions
Cold start is slow (~60s)
First request after idle loads the full model. Options:
- Set longer idle timeout
- Use "always on" worker for frequent usage
- Pre-warm with a test request
Identity drift in chained edits
This is a known challenge. Mitigations:
- Use consistent seed across edits
- Keep prompts focused on single changes
- Consider IP-Adapter for explicit identity conditioning (future)
Pipeline Integration
This worker is designed for the video generation pipeline:
# Pseudo-code for pipeline orchestration
def generate_video_segment(reference_image, scenes):
current_frame = reference_image
for scene in scenes:
# Worker 1: Edit frame
edited = call_qwen_edit(current_frame, scene["edit_prompt"])
# Worker 2: Animate (separate endpoint)
video = call_wan_i2v(edited, scene["motion_prompt"])
# Chain: last frame becomes next input
current_frame = video["last_frame"]
return concat_videos(videos)
See .ai_dev/video-generation-pipeline.md for full pipeline documentation.
Related Workers
| Worker | Purpose | Status |
|---|---|---|
runpod-qwen-edit |
Frame editing (this) | Phase 1 |
runpod-wan-i2v |
Image-to-video | Phase 2 (planned) |
runpod-propainter |
Watermark removal | Deployed |
runpod-animate |
SVD animation | Deployed |