Files
vllm-omni/examples/online_serving/helios/helios_client.py
T

213 lines
5.4 KiB
Python

#!/usr/bin/env python3
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
"""
Helios video generation client example using the /v1/videos API.
This example demonstrates how to use the generic extra_params field
to pass Helios-specific parameters without modifying the API.
"""
import argparse
import json
import time
from pathlib import Path
import requests
def create_video_job(
api_url: str,
prompt: str,
model: str,
width: int = 640,
height: int = 384,
num_frames: int = 99,
guidance_scale: float = 5.0,
seed: int = 42,
extra_params: dict | None = None,
input_image: Path | None = None,
) -> dict:
"""Create a video generation job."""
data = {
"prompt": prompt,
"model": model,
"width": width,
"height": height,
"num_frames": num_frames,
"guidance_scale": guidance_scale,
"seed": seed,
}
files = {}
if input_image:
files["input_reference"] = open(input_image, "rb")
if extra_params:
data["extra_params"] = json.dumps(extra_params)
response = requests.post(f"{api_url}/v1/videos", data=data, files=files)
response.raise_for_status()
if files:
files["input_reference"].close()
return response.json()
def poll_video_status(api_url: str, video_id: str, poll_interval: int = 2) -> dict:
"""Poll video generation status until completion."""
print(f"Polling video job: {video_id}")
while True:
response = requests.get(f"{api_url}/v1/videos/{video_id}")
response.raise_for_status()
status_data = response.json()
status = status_data["status"]
progress = status_data.get("progress", 0)
print(f"Status: {status}, Progress: {progress}%")
if status == "completed":
print("Video generation completed!")
return status_data
elif status == "failed":
error = status_data.get("error", {})
raise RuntimeError(f"Video generation failed: {error}")
time.sleep(poll_interval)
def main():
parser = argparse.ArgumentParser(description="Helios video generation client")
parser.add_argument(
"--api-url",
default="http://localhost:8000",
help="API server URL",
)
parser.add_argument(
"--model",
default="BestWishYsh/Helios-Base",
help="Model name (Helios-Base, Helios-Mid, Helios-Distilled)",
)
parser.add_argument(
"--prompt",
default="A serene lakeside sunrise with mist over the water.",
help="Text prompt",
)
parser.add_argument(
"--width",
type=int,
default=640,
help="Video width",
)
parser.add_argument(
"--height",
type=int,
default=384,
help="Video height",
)
parser.add_argument(
"--num-frames",
type=int,
default=99,
help="Number of frames",
)
parser.add_argument(
"--guidance-scale",
type=float,
default=5.0,
help="Guidance scale",
)
parser.add_argument(
"--seed",
type=int,
default=42,
help="Random seed",
)
parser.add_argument(
"--input-image",
type=Path,
help="Input image for I2V mode",
)
parser.add_argument(
"--preset",
choices=["base", "mid-stage2", "distilled"],
default="base",
help="Helios preset configuration",
)
args = parser.parse_args()
# Define preset configurations
presets = {
"base": None, # No extra params for base model
"mid-stage2": {
"is_enable_stage2": True,
"pyramid_num_stages": 3,
"pyramid_num_inference_steps_list": [20, 20, 20],
"use_cfg_zero_star": True,
"use_zero_init": True,
"zero_steps": 1,
},
"distilled": {
"is_enable_stage2": True,
"pyramid_num_stages": 3,
"pyramid_num_inference_steps_list": [2, 2, 2],
"is_amplify_first_chunk": True,
},
}
extra_params = presets[args.preset]
print("=" * 50)
print("Helios Video Generation")
print("=" * 50)
print(f"API URL: {args.api_url}")
print(f"Model: {args.model}")
print(f"Preset: {args.preset}")
print(f"Prompt: {args.prompt}")
print(f"Size: {args.width}x{args.height}")
print(f"Frames: {args.num_frames}")
print(f"Guidance Scale: {args.guidance_scale}")
if extra_params:
print(f"Extra Params: {json.dumps(extra_params, indent=2)}")
print()
# Create video job
print("Creating video generation job...")
job = create_video_job(
api_url=args.api_url,
prompt=args.prompt,
model=args.model,
width=args.width,
height=args.height,
num_frames=args.num_frames,
guidance_scale=args.guidance_scale,
seed=args.seed,
extra_params=extra_params,
input_image=args.input_image,
)
video_id = job["id"]
print(f"Video job created: {video_id}")
print()
# Poll for completion
result = poll_video_status(args.api_url, video_id)
print()
print("=" * 50)
print("Generation Complete")
print("=" * 50)
print(f"Video ID: {result['id']}")
print(f"File: {result.get('file_name', 'N/A')}")
print(f"Inference Time: {result.get('inference_time_s', 'N/A')}s")
print()
if __name__ == "__main__":
main()