Instructions to use deathlegionteam/LEGION-Video-Gen with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use deathlegionteam/LEGION-Video-Gen with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("deathlegionteam/LEGION-Video-Gen", dtype=torch.bfloat16, device_map="cuda") prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" image = pipe(prompt).images[0] - Notebooks
- Google Colab
- Kaggle
| import os | |
| import sys | |
| import time | |
| import logging | |
| import shutil | |
| import tempfile | |
| from pathlib import Path | |
| from typing import Optional, List | |
| import uuid | |
| from fastapi import FastAPI, UploadFile, File, Form, BackgroundTasks, HTTPException | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.responses import FileResponse, JSONResponse | |
| from pydantic import BaseModel, Field | |
| import uvicorn | |
| # Add project root to path | |
| sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | |
| logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s] %(name)s: %(message)s') | |
| logger = logging.getLogger("LegionAPI") | |
| app = FastAPI( | |
| title="LEGION Video Generation API", | |
| description="High-quality video generation with text-to-video and image-to-video capabilities", | |
| version="1.0.0", | |
| ) | |
| # CORS middleware - allow all origins | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # Global generator instance (lazy initialized) | |
| _generator = None | |
| def get_generator(): | |
| global _generator | |
| if _generator is None: | |
| from inference import LegionVideoGenerator | |
| _generator = LegionVideoGenerator() | |
| logger.info(f"Generator initialized: device={_generator.device}, mock={_generator.mock_mode}") | |
| return _generator | |
| # --- Request/Response Models --- | |
| class TextToVideoRequest(BaseModel): | |
| prompt: str = Field(..., description="Text description of the video") | |
| negative_prompt: str = Field( | |
| default="warped, distorted, flickering, jittery, low quality, blurry, artifacts, ugly, deformed, bad anatomy, bad proportions", | |
| description="Things to avoid in the video" | |
| ) | |
| num_frames: int = Field(default=49, ge=1, le=129, description="Number of frames") | |
| width: int = Field(default=480, ge=128, le=720, description="Video width") | |
| height: int = Field(default=480, ge=128, le=720, description="Video height") | |
| num_inference_steps: int = Field(default=50, ge=1, le=100, description="Inference steps") | |
| guidance_scale: float = Field(default=6.0, ge=1.0, le=20.0, description="CFG scale") | |
| watermark_strength: float = Field(default=0.3, ge=0.0, le=1.0, description="QWatermark opacity") | |
| seed: Optional[int] = Field(default=None, description="Random seed") | |
| class ImageToVideoRequest(BaseModel): | |
| prompt: str = Field(..., description="Text description of motion/action") | |
| negative_prompt: str = Field(default="warped, distorted, flickering, jittery, low quality, blurry, artifacts", description="Things to avoid") | |
| num_frames: int = Field(default=49, ge=1, le=129) | |
| width: int = Field(default=480, ge=128, le=720) | |
| height: int = Field(default=480, ge=128, le=720) | |
| num_inference_steps: int = Field(default=50, ge=1, le=100) | |
| guidance_scale: float = Field(default=6.0, ge=1.0, le=20.0) | |
| watermark_strength: float = Field(default=0.3, ge=0.0, le=1.0) | |
| seed: Optional[int] = Field(default=None) | |
| class StatusResponse(BaseModel): | |
| status: str | |
| model: str | |
| gpu: bool | |
| mock_mode: bool | |
| device: str | |
| version: str | |
| # --- Endpoints --- | |
| async def api_status(): | |
| gen = get_generator() | |
| return StatusResponse( | |
| status="ok", | |
| model="LEGION Video Gen v1.0", | |
| gpu=(gen.device == "cuda"), | |
| mock_mode=gen.mock_mode, | |
| device=gen.device, | |
| version="1.0.0" | |
| ) | |
| async def api_models(): | |
| gen = get_generator() | |
| return {"models": [{"id": "legion-t2v", "name": "LEGION Text-to-Video"}, {"id": "legion-i2v", "name": "LEGION Image-to-Video"}]} | |
| async def generate_text( | |
| request: TextToVideoRequest, | |
| background_tasks: BackgroundTasks, | |
| ): | |
| """ | |
| Generate a video from a text prompt. | |
| Returns the video file as an MP4 download. | |
| """ | |
| logger.info(f"API T2V: prompt='{request.prompt[:50]}...', frames={request.num_frames}") | |
| try: | |
| output_path = get_generator().generate_from_text( | |
| prompt=request.prompt, | |
| negative_prompt=request.negative_prompt, | |
| num_frames=request.num_frames, | |
| width=request.width, | |
| height=request.height, | |
| num_inference_steps=request.num_inference_steps, | |
| guidance_scale=request.guidance_scale, | |
| watermark_strength=request.watermark_strength, | |
| seed=request.seed, | |
| ) | |
| if not os.path.exists(output_path): | |
| raise HTTPException(status_code=500, detail="Video generation failed - no output file") | |
| filename = os.path.basename(output_path) | |
| return FileResponse( | |
| path=output_path, | |
| media_type="video/mp4", | |
| filename=filename, | |
| headers={"Content-Disposition": f'attachment; filename="{filename}"'} | |
| ) | |
| except Exception as e: | |
| logger.error(f"T2V generation failed: {e}") | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def generate_image( | |
| file: UploadFile = File(...), | |
| prompt: str = Form(...), | |
| negative_prompt: str = Form("warped, distorted, flickering, jittery, low quality, blurry, artifacts"), | |
| num_frames: int = Form(49), | |
| width: int = Form(480), | |
| height: int = Form(480), | |
| num_inference_steps: int = Form(50), | |
| guidance_scale: float = Form(6.0), | |
| watermark_strength: float = Form(0.3), | |
| seed: Optional[int] = Form(None), | |
| ): | |
| """ | |
| Generate a video from an uploaded image + text prompt. | |
| """ | |
| logger.info(f"API I2V: file='{file.filename}', prompt='{prompt[:50]}...'") | |
| temp_dir = tempfile.mkdtemp() | |
| try: | |
| image_path = os.path.join(temp_dir, file.filename or "input_image.jpg") | |
| with open(image_path, "wb") as f: | |
| content = await file.read() | |
| f.write(content) | |
| output_path = get_generator().generate_from_image( | |
| image_path=image_path, | |
| prompt=prompt, | |
| negative_prompt=negative_prompt, | |
| num_frames=num_frames, | |
| width=width, | |
| height=height, | |
| num_inference_steps=num_inference_steps, | |
| guidance_scale=guidance_scale, | |
| watermark_strength=watermark_strength, | |
| seed=seed, | |
| ) | |
| if not os.path.exists(output_path): | |
| raise HTTPException(status_code=500, detail="Video generation failed - no output file") | |
| filename = os.path.basename(output_path) | |
| return FileResponse( | |
| path=output_path, | |
| media_type="video/mp4", | |
| filename=filename, | |
| headers={"Content-Disposition": f'attachment; filename="{filename}"'} | |
| ) | |
| except Exception as e: | |
| logger.error(f"I2V generation failed: {e}") | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| finally: | |
| shutil.rmtree(temp_dir, ignore_errors=True) | |
| async def root(): | |
| return { | |
| "service": "LEGION Video Generation API", | |
| "version": "1.0.0", | |
| "docs": "/docs", | |
| "endpoints": { | |
| "status": "GET /api/status", | |
| "models": "GET /api/models", | |
| "text_to_video": "POST /api/generate/text", | |
| "image_to_video": "POST /api/generate/image", | |
| } | |
| } | |
| if __name__ == "__main__": | |
| port = int(os.environ.get("BACKEND_PORT", 8081)) | |
| logger.info(f"Starting LEGION API server on port {port}") | |
| uvicorn.run(app, host="0.0.0.0", port=port, log_level="info") |