Files
vllm-omni/docs/user_guide/examples/online_serving/text_to_video.md
T
92f771d455 [Frontend] Rewrite video API for async job lifecycle (#1665)
Signed-off-by: Ian Eaves <ian.k.eaves@gmail.com>
Signed-off-by: Samit <285365963@qq.com>
Co-authored-by: Samit <285365963@qq.com>
Co-authored-by: Gao Han <gaohan19@huawei.com>
2026-03-13 17:11:06 +08:00

6.6 KiB

Text-To-Video

Source https://github.com/vllm-project/vllm-omni/tree/main/examples/online_serving/text_to_video.

This example demonstrates how to deploy the Wan2.2 text-to-video model for online video generation using vLLM-Omni.

Start Server

Basic Start

vllm serve Wan-AI/Wan2.2-T2V-A14B-Diffusers --omni --port 8091

Start with Parameters

Or use the startup script:

bash run_server.sh

The script allows overriding:

  • MODEL (default: Wan-AI/Wan2.2-T2V-A14B-Diffusers)
  • PORT (default: 8091)
  • BOUNDARY_RATIO (default: 0.875)
  • FLOW_SHIFT (default: 5.0)
  • CACHE_BACKEND (default: none)
  • ENABLE_CACHE_DIT_SUMMARY (default: 0)

Async Job Behavior

POST /v1/videos is asynchronous. It creates a video job and immediately returns metadata like the job ID and initial queued status. To get the final artifact, poll the job status and then download the completed file from the content endpoint.

The main endpoints are:

  • POST /v1/videos: create a video generation job
  • GET /v1/videos/{video_id}: retrieve the current job status and metadata
  • GET /v1/videos: list stored video jobs
  • GET /v1/videos/{video_id}/content: download the generated video file
  • DELETE /v1/videos/{video_id}: delete the job and any stored output

Storage

Generated video files are stored on local disk by the async video API.

  • VLLM_OMNI_STORAGE_PATH: directory used for generated files (default: /tmp/storage)
  • VLLM_OMNI_STORAGE_MAX_CONCURRENCY: max concurrent save/delete operations (default: 4)

Example:

export VLLM_OMNI_STORAGE_PATH=/var/tmp/vllm-omni-videos
export VLLM_OMNI_STORAGE_MAX_CONCURRENCY=8

API Calls

Method 1: Using curl

# Basic text-to-video generation
bash run_curl_text_to_video.sh

# Or execute directly (OpenAI-style multipart)
create_response=$(curl -s http://localhost:8091/v1/videos \
  -H "Accept: application/json" \
  -F "prompt=Two anthropomorphic cats in comfy boxing gear and bright gloves fight intensely on a spotlighted stage." \
  -F "width=832" \
  -F "height=480" \
  -F "num_frames=33" \
  -F "negative_prompt=色调艳丽 ,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走" \
  -F "fps=16" \
  -F "num_inference_steps=40" \
  -F "guidance_scale=4.0" \
  -F "guidance_scale_2=4.0" \
  -F "boundary_ratio=0.875" \
  -F "flow_shift=5.0" \
  -F "seed=42")

video_id=$(echo "$create_response" | jq -r '.id')
while true; do
  status=$(curl -s "http://localhost:8091/v1/videos/${video_id}" | jq -r '.status')
  if [ "$status" = "completed" ]; then
    break
  fi
  if [ "$status" = "failed" ]; then
    echo "Video generation failed"
    exit 1
  fi
  sleep 2
done

curl -s "http://localhost:8091/v1/videos/${video_id}" | jq .
curl -L "http://localhost:8091/v1/videos/${video_id}/content" -o wan22_output.mp4

Request Format

Simple Text-to-Video Generation

curl -X POST http://localhost:8091/v1/videos \
  -F "prompt=A cinematic view of a futuristic city at sunset"

Generation with Parameters

curl -X POST http://localhost:8091/v1/videos \
  -F "prompt=A cinematic view of a futuristic city at sunset" \
  -F "width=832" \
  -F "height=480" \
  -F "num_frames=33" \
  -F "negative_prompt=low quality, blurry, static" \
  -F "fps=16" \
  -F "num_inference_steps=40" \
  -F "guidance_scale=4.0" \
  -F "guidance_scale_2=4.0" \
  -F "boundary_ratio=0.875" \
  -F "flow_shift=5.0" \
  -F "seed=42"

Generation Parameters

Parameter Type Default Description
prompt str - Text description of the desired video
seconds str None Clip duration in seconds
size str None Output size in WIDTHxHEIGHT format
negative_prompt str None Negative prompt
width int None Video width in pixels
height int None Video height in pixels
num_frames int None Number of frames to generate
fps int None Frames per second for output video
num_inference_steps int None Number of denoising steps
guidance_scale float None CFG guidance scale (low-noise stage)
guidance_scale_2 float None CFG guidance scale (high-noise stage, Wan2.2)
boundary_ratio float None Boundary split ratio for low/high DiT (Wan2.2)
flow_shift float None Scheduler flow shift (Wan2.2)
seed int None Random seed (reproducible)
lora object None LoRA configuration

Create Response Format

POST /v1/videos returns a job record.

{
  "id": "video_gen_123",
  "object": "video",
  "status": "queued",
  "model": "Wan-AI/Wan2.2-T2V-A14B-Diffusers",
  "prompt": "A cinematic view of a futuristic city at sunset",
  "created_at": 1234567890
}

Retrieve, List, Download, and Delete

Retrieve a job

curl -s http://localhost:8091/v1/videos/${video_id} | jq .

List jobs

curl -s http://localhost:8091/v1/videos | jq .

Download the completed video

curl -L http://localhost:8091/v1/videos/${video_id}/content -o wan22_output.mp4

Delete a job and its stored file

curl -X DELETE http://localhost:8091/v1/videos/${video_id} | jq .

Poll Until Complete

while true; do
  status=$(curl -s http://localhost:8091/v1/videos/${video_id} | jq -r '.status')
  if [ "$status" = "completed" ]; then
    break
  fi
  if [ "$status" = "failed" ]; then
    echo "Video generation failed"
    exit 1
  fi
  sleep 2
done

Example materials

??? abstract "run_curl_text_to_video.sh" sh --8<-- "examples/online_serving/text_to_video/run_curl_text_to_video.sh" ??? abstract "run_server.sh" sh --8<-- "examples/online_serving/text_to_video/run_server.sh"