Initial commit: Revids REST API for LTX-2.3 image-to-video generation
- 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/
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
# Revids
|
||||
|
||||
REST API for generating video from images using [LTX-2.3](https://docs.ltx.video/open-source-model/integration-tools/pytorch-api).
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# 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
|
||||
```bash
|
||||
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:
|
||||
```json
|
||||
{"job_id": "abc123def456", "status": "pending"}
|
||||
```
|
||||
|
||||
### Check Job Status
|
||||
```bash
|
||||
curl http://localhost:8000/jobs/abc123def456
|
||||
```
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"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`)
|
||||
```bash
|
||||
curl http://localhost:8000/jobs/abc123def456/download -o output.mp4
|
||||
```
|
||||
|
||||
### Delete Job (removes DB record + video file)
|
||||
```bash
|
||||
curl -X DELETE http://localhost:8000/jobs/abc123def456
|
||||
```
|
||||
|
||||
### Health Check
|
||||
```bash
|
||||
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+1` pattern (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
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
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.
|
||||
Reference in New Issue
Block a user