2d50679ec0
- FastAPI with job polling: POST /generate, GET /jobs/{id}, /download, /health
- SQLite job persistence (aiosqlite), background task processing
- LTX-2.3 DistilledPipeline via native ltx-pipelines (editable install from submodule)
- Configurable model paths, LoRA support, FP8 quantization via env vars
- Single-concurrency GPU lock for safe inference
- LTX-2 as git submodule under libs/
4.1 KiB
4.1 KiB
Revids
REST API for generating video from images using LTX-2.3.
Quick Start
# 1. Clone the repo (including submodule)
git clone --recursive <repo-url> revids
cd revids
# 2. Create venv and install LTX packages (editable, from submodule)
python -m venv .venv && source .venv/bin/activate
pip install -e libs/LTX-2/packages/ltx-core -e libs/LTX-2/packages/ltx-pipelines
# 3. Install API deps
pip install -r requirements.txt
# 4. Download LTX-2.3 model weights
huggingface-cli download Lightricks/LTX-2.3 \
--include "ltx-2.3-22b-distilled-1.1.safetensors" \
--local-dir models/
# 5. Download Gemma/GPT-4o text encoder
huggingface-cli download Lightricks/LTX-2 \
--local-dir models/gpt-4o-5805-ava-gguf-model
# 6. Download spatial upsampler (optional, for higher-res output)
huggingface-cli download Lightricks/LTX-2 \
--include "ltx-2.3-22b-spatial-upscaler.safetensors" \
--local-dir models/
# 7. Run
uvicorn app.main:app --reload
The API will be available at http://localhost:8000. Interactive docs at http://localhost:8000/docs.
API Endpoints
Submit a Job
curl -X POST http://localhost:8000/generate \
-F "image=@photo.jpg" \
-F "prompt=A cinematic pan across the landscape" \
-F "width=768" \
-F "height=512" \
-F "num_frames=65" \
-F "fps=24.0"
Response:
{"job_id": "abc123def456", "status": "pending"}
Check Job Status
curl http://localhost:8000/jobs/abc123def456
Response:
{
"job_id": "abc123def456",
"status": "completed",
"prompt": "A cinematic pan across the landscape",
"params": {"width": 768, "height": 512, "num_frames": 65, "fps": 24.0},
"error": null,
"created_at": "2025-01-01T00:00:00+00:00",
"completed_at": "2025-01-01T00:01:30+00:00"
}
Download Video (.mp4)
curl http://localhost:8000/jobs/abc123def456/download -o output.mp4
Delete Job (removes DB record + video file)
curl -X DELETE http://localhost:8000/jobs/abc123def456
Health Check
curl http://localhost:8000/health
Returns GPU availability and device name.
Generation Constraints
- Width/Height: must be divisible by 32 (min 256, max 2048)
- num_frames: must follow
8n+1pattern (9, 17, ..., 65, 97, 121, 161, 257, ...) - fps: 0 < fps <= 60
Configuration
All settings in app/config.py can be overridden via .env or env vars prefixed with REVIDS_:
| Variable | Default | Description |
|---|---|---|
REVIDS_HOST |
0.0.0.0 |
Bind address |
REVIDS_PORT |
8000 |
Port |
REVIDS_RELOAD |
true |
uvicorn auto-reload |
REVIDS_LTX_DISTILLED_CHECKPOINT |
models/ltx-2.3-22b-distilled-1.1.safetensors |
Distilled model path |
REVIDS_LTX_GEMMA_ROOT |
models/gpt-4o-5805-ava-gguf-model |
Gemma text encoder path |
REVIDS_LTX_SPATIAL_UPSAMPLER |
(none) | Spatial upsampler model path |
REVIDS_LTX_QUANTIZATION |
fp8_cast |
Quantization mode (fp8_cast, fp8_scaled_mm, or unset for bfloat16) |
REVIDS_LTX_LORAS |
(empty) | LoRA paths, colon-separated: "models/lora1.safetensors:1.0,models/lora2.safetensors:0.5" |
REVIDS_MAX_CONCURRENT_JOBS |
1 |
GPU concurrency |
Project Structure
revids/
app/
main.py # FastAPI app + routes
config.py # Settings (pydantic-settings)
models.py # Request/response schemas
service.py # LTX pipeline wrapper + job processing
database.py # SQLite job store
libs/
LTX-2/ # LTX-2 git submodule
requirements.txt
videos/ # Generated video output (gitignored)
Hardware Requirements
- NVIDIA GPU with CUDA (>= 24GB VRAM for bfloat16, ~14GB with FP8)
- ~30GB disk for model weights
Memory Optimization
export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True
Set REVIDS_LTX_QUANTIZATION=fp8_cast (~40% VRAM reduction) or fp8_scaled_mm (Hopper GPUs only).
LoRA Support
Configure LoRAs via environment variable:
export REVIDS_LTX_LORAS="models/my-style.safetensors:1.0,models/my-motion.safetensors:0.5"
Or set as a comma-separated list of path:scale entries.