diff --git a/.gitignore b/.gitignore index 30372720..588c01be 100644 --- a/.gitignore +++ b/.gitignore @@ -194,6 +194,7 @@ examples/03_BenchmarkComparison/vllm_venv/ .cursor/ docs/superpowers/ .claude/agent-memory/ +.worktrees/ # User-specific local dev configs; do not commit CLAUDE.local.md diff --git a/AGENTS.md b/AGENTS.md index bb79bc42..efd4228f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -74,16 +74,17 @@ Dataset Manager --> Load Generator --> Endpoint Client --> External Endpoint ### Key Components -| Component | Location | Purpose | -| ------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -| **Load Generator** | `src/inference_endpoint/load_generator/` | Central orchestrator: `BenchmarkSession` owns the lifecycle, `Scheduler` controls timing, `LoadGenerator` issues queries | -| **Endpoint Client** | `src/inference_endpoint/endpoint_client/` | Multi-process HTTP workers communicating via ZMQ IPC. `HTTPEndpointClient` is the main entry point | -| **Dataset Manager** | `src/inference_endpoint/dataset_manager/` | Loads JSONL, HuggingFace, CSV, JSON, Parquet datasets. `Dataset` base class with `load_sample()`/`num_samples()` interface | -| **Metrics** | `src/inference_endpoint/metrics/` | `EventRecorder` writes to SQLite, `MetricsReporter` reads and aggregates (QPS, latency, TTFT, TPOT) | -| **Config** | `src/inference_endpoint/config/`, `endpoint_client/config.py` | Pydantic-based YAML schema (`schema.py`), `HTTPClientConfig` (single Pydantic model for CLI/YAML/runtime), `RuntimeSettings` | -| **CLI** | `src/inference_endpoint/main.py`, `commands/benchmark/cli.py` | cyclopts-based, auto-generated from `schema.py` and `HTTPClientConfig` Pydantic models. Flat shorthands via `cyclopts.Parameter(alias=...)` | -| **Async Utils** | `src/inference_endpoint/async_utils/` | `LoopManager` (uvloop + eager_task_factory), ZMQ transport layer, event publisher | -| **OpenAI/SGLang** | `src/inference_endpoint/openai/`, `sglang/` | Protocol adapters and response accumulators for different API formats | +| Component | Location | Purpose | +| ------------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Load Generator** | `src/inference_endpoint/load_generator/` | Central orchestrator: `BenchmarkSession` owns the lifecycle, `Scheduler` controls timing, `LoadGenerator` issues queries | +| **Endpoint Client** | `src/inference_endpoint/endpoint_client/` | Multi-process HTTP workers communicating via ZMQ IPC. `HTTPEndpointClient` is the main entry point | +| **Dataset Manager** | `src/inference_endpoint/dataset_manager/` | Loads JSONL, HuggingFace, CSV, JSON, Parquet datasets. `Dataset` base class with `load_sample()`/`num_samples()` interface | +| **Metrics** | `src/inference_endpoint/metrics/` | `EventRecorder` writes to SQLite, `MetricsReporter` reads and aggregates (QPS, latency, TTFT, TPOT) | +| **Config** | `src/inference_endpoint/config/`, `endpoint_client/config.py` | Pydantic-based YAML schema (`schema.py`), `HTTPClientConfig` (single Pydantic model for CLI/YAML/runtime), `RuntimeSettings` | +| **CLI** | `src/inference_endpoint/main.py`, `commands/benchmark/cli.py` | cyclopts-based, auto-generated from `schema.py` and `HTTPClientConfig` Pydantic models. Flat shorthands via `cyclopts.Parameter(alias=...)` | +| **Async Utils** | `src/inference_endpoint/async_utils/` | `LoopManager` (uvloop + eager_task_factory), ZMQ transport layer, event publisher | +| **OpenAI/SGLang** | `src/inference_endpoint/openai/`, `sglang/` | Protocol adapters and response accumulators for different API formats | +| **VideoGen** | `src/inference_endpoint/videogen/` | Adapter for video-generation endpoints (e.g. trtllm-serve `POST /v1/videos/generations`, used by MLPerf WAN2.2-T2V-A14B). Defaults to `response_format=video_path` (server saves video to shared storage and returns path) to avoid large byte payloads; switch to `video_bytes` for accuracy mode. Dataset is ingested via the generic JSONL loader. | ### Hot-Path Architecture @@ -199,6 +200,10 @@ src/inference_endpoint/ │ ├── accumulator.py # Streaming response accumulator │ └── harmony.py # openai_harmony integration ├── sglang/ # SGLang API adapter +├── videogen/ # Video generation adapter (e.g. WAN2.2 T2V workload) +│ ├── __init__.py +│ ├── types.py # Pydantic: VideoPathRequest, VideoPathResponse, VideoPayloadResponse +│ └── adapter.py # VideoGenAdapter (HttpRequestAdapter) + VideoGenAccumulator (no-op) ├── evaluation/ # Accuracy evaluation (extractor, scoring, livecodebench) ├── plugins/ # Plugin system ├── profiling/ # line_profiler integration, pytest plugin diff --git a/examples/09_Wan22_VideoGen_Example/offline_wan22.yaml b/examples/09_Wan22_VideoGen_Example/offline_wan22.yaml new file mode 100644 index 00000000..508af97c --- /dev/null +++ b/examples/09_Wan22_VideoGen_Example/offline_wan22.yaml @@ -0,0 +1,54 @@ +# Offline Video Generation Benchmark for WAN 2.2 (GB200/GB300) +# +# Targets trtllm-serve POST /v1/videos/generations directly (no proxy). +# Uses response_format=video_path: server saves video to Lustre and returns +# the file path, avoiding large video byte payloads over HTTP/ZMQ. +# +# MLPerf inference parameters (text_to_video task): +# Resolution: 720x1280 (portrait) +# Duration: 81 frames = 5 s +# Steps: 20 denoising steps +# Guidance: 4.0 (primary CFG) / 3.0 (null-text secondary) +# Seed: 42 (fixed for reproducibility; combine with fixed_latent.pt) +# Dataset: 248 prompts from shopify_product_catalogue::q3vl +# +# Resolution / duration / steps / guidance / seed are defaulted on +# `VideoPathRequest`. Each JSONL row carries `prompt` plus the canonical +# MLPerf `negative_prompt`; both flow into `query.data` and serialise into +# the request body, while unset fields fall back to the request defaults. + +name: "offline-wan22-video-generation-benchmark" +version: "1.0" +type: "offline" + +model_params: + name: "wan22" + max_new_tokens: 1 # Ignored by VideoGenAdapter; kept >0 so swapping api_type to openai/sglang for debugging doesn't yield a 400. + streaming: "off" # WAN 2.2 uses non-streaming HTTP POST/response + +datasets: + - name: wan22_prompts + path: examples/09_Wan22_VideoGen_Example/wan22_prompts.jsonl + type: "performance" + samples: 248 + +settings: + runtime: + max_duration_ms: 600000 # 10 minute cap + scheduler_random_seed: 42 + dataloader_random_seed: 42 + n_samples_to_issue: 248 + + load_pattern: + type: "max_throughput" + + client: + num_workers: 4 + +endpoint_config: + endpoints: + - "http://localhost:8000" + api_type: "videogen" + api_key: null + +report_dir: logs/wan22_video_generation_benchmark diff --git a/examples/09_Wan22_VideoGen_Example/setup_and_test.sh b/examples/09_Wan22_VideoGen_Example/setup_and_test.sh new file mode 100755 index 00000000..a5014f96 --- /dev/null +++ b/examples/09_Wan22_VideoGen_Example/setup_and_test.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# setup_and_test.sh — End-to-end runbook for the WAN 2.2 video-generation example. +# +# Steps: +# 1. Download the WAN 2.2 weights from HuggingFace. +# 2. Launch trtllm-serve in a separate shell. +# 3. Run the offline benchmark from this script. +# +# Prerequisites: Python 3.12, a GPU host with trtllm-serve installed, +# and HuggingFace credentials (`huggingface-cli login`) — the WAN 2.2 +# weights are gated. + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" + +MODEL_REPO="Wan-AI/Wan2.2-T2V-A14B" # https://huggingface.co/Wan-AI/Wan2.2-T2V-A14B +MODEL_DIR="${MODEL_DIR:-${HOME}/models/wan2.2-t2v-a14b}" + +cd "${REPO_ROOT}" + +# 1. Download model weights (~28 GB). +huggingface-cli download "${MODEL_REPO}" --local-dir "${MODEL_DIR}" + +# 2. Launch the server in a separate shell, then re-run this script: +# +# trtllm-serve "${MODEL_DIR}" --host 0.0.0.0 --port 8000 \ +# --backend pytorch --task text_to_video +# +# 3. Run the offline benchmark. +inference-endpoint benchmark from-config \ + --config "${SCRIPT_DIR}/offline_wan22.yaml" diff --git a/examples/09_Wan22_VideoGen_Example/wan22_prompts.jsonl b/examples/09_Wan22_VideoGen_Example/wan22_prompts.jsonl new file mode 100644 index 00000000..9b469e89 --- /dev/null +++ b/examples/09_Wan22_VideoGen_Example/wan22_prompts.jsonl @@ -0,0 +1,248 @@ +{"prompt": "a person swimming in ocean", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a person giving a presentation to a room full of colleagues", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a person washing the dishes", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a person eating a burger", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a person walking in the snowstorm", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a person drinking coffee in a cafe", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a person playing guitar", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a bicycle leaning against a tree", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a bicycle gliding through a snowy field", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a bicycle slowing down to stop", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a bicycle accelerating to gain speed", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a car stuck in traffic during rush hour", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a car turning a corner", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a car slowing down to stop", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a car accelerating to gain speed", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a motorcycle cruising along a coastal highway", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a motorcycle turning a corner", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a motorcycle slowing down to stop", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a motorcycle gliding through a snowy field", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a motorcycle accelerating to gain speed", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "an airplane soaring through a clear blue sky", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "an airplane taking off", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "an airplane landing smoothly on a runway", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "an airplane accelerating to gain speed", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a bus turning a corner", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a bus stuck in traffic during rush hour", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a bus accelerating to gain speed", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a train speeding down the tracks", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a train crossing over a tall bridge", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a train accelerating to gain speed", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a truck turning a corner", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a truck anchored in a tranquil bay", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a truck stuck in traffic during rush hour", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a truck slowing down to stop", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a truck accelerating to gain speed", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a boat sailing smoothly on a calm lake", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a boat slowing down to stop", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a boat accelerating to gain speed", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a bird soaring gracefully in the sky", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a bird building a nest from twigs and leaves", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a bird flying over a snowy forest", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a cat grooming itself meticulously with its tongue", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a cat playing in park", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a cat drinking water", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a cat running happily", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a dog enjoying a peaceful walk", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a dog playing in park", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a dog drinking water", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a dog running happily", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a horse bending down to drink water from a river", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a horse galloping across an open field", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a horse taking a peaceful walk", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a horse running to join a herd of its kind", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a sheep bending down to drink water from a river", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a sheep taking a peaceful walk", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a sheep running to join a herd of its kind", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a cow bending down to drink water from a river", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a cow chewing cud while resting in a tranquil barn", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a cow running to join a herd of its kind", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "an elephant spraying itself with water using its trunk to cool down", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "an elephant taking a peaceful walk", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "an elephant running to join a herd of its kind", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a bear catching a salmon in its powerful jaws", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a bear sniffing the air for scents of food", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a bear climbing a tree", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a bear hunting for prey", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a zebra bending down to drink water from a river", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a zebra running to join a herd of its kind", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a zebra taking a peaceful walk", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a giraffe bending down to drink water from a river", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a giraffe taking a peaceful walk", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a giraffe running to join a herd of its kind", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A beautiful coastal beach in spring, waves lapping on sand, Van Gogh style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A beautiful coastal beach in spring, waves lapping on sand, oil painting", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A beautiful coastal beach in spring, waves lapping on sand by Hokusai, in the style of Ukiyo", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A beautiful coastal beach in spring, waves lapping on sand, black and white", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A beautiful coastal beach in spring, waves lapping on sand, pixel art", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A beautiful coastal beach in spring, waves lapping on sand, in cyberpunk style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A beautiful coastal beach in spring, waves lapping on sand, animated style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A beautiful coastal beach in spring, waves lapping on sand, watercolor painting", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A beautiful coastal beach in spring, waves lapping on sand, surrealism style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "The bund Shanghai, Van Gogh style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "The bund Shanghai, oil painting", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "The bund Shanghai by Hokusai, in the style of Ukiyo", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "The bund Shanghai, black and white", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "The bund Shanghai, pixel art", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "The bund Shanghai, in cyberpunk style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "The bund Shanghai, animated style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "The bund Shanghai, watercolor painting", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "The bund Shanghai, surrealism style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a shark is swimming in the ocean, Van Gogh style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a shark is swimming in the ocean, oil painting", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a shark is swimming in the ocean by Hokusai, in the style of Ukiyo", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a shark is swimming in the ocean, black and white", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a shark is swimming in the ocean, pixel art", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a shark is swimming in the ocean, in cyberpunk style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a shark is swimming in the ocean, animated style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a shark is swimming in the ocean, watercolor painting", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "a shark is swimming in the ocean, surrealism style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A panda drinking coffee in a cafe in Paris, Van Gogh style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A panda drinking coffee in a cafe in Paris, oil painting", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A panda drinking coffee in a cafe in Paris by Hokusai, in the style of Ukiyo", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A panda drinking coffee in a cafe in Paris, black and white", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A panda drinking coffee in a cafe in Paris, pixel art", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A panda drinking coffee in a cafe in Paris, in cyberpunk style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A panda drinking coffee in a cafe in Paris, animated style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A panda drinking coffee in a cafe in Paris, watercolor painting", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A panda drinking coffee in a cafe in Paris, surrealism style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A cute happy Corgi playing in park, sunset, Van Gogh style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A cute happy Corgi playing in park, sunset, oil painting", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A cute happy Corgi playing in park, sunset by Hokusai, in the style of Ukiyo", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A cute happy Corgi playing in park, sunset, black and white", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A cute happy Corgi playing in park, sunset, pixel art", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A cute happy Corgi playing in park, sunset, in cyberpunk style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A cute happy Corgi playing in park, sunset, animated style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A cute happy Corgi playing in park, sunset, watercolor painting", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A cute happy Corgi playing in park, sunset, surrealism style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "Gwen Stacy reading a book, Van Gogh style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "Gwen Stacy reading a book, oil painting", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "Gwen Stacy reading a book by Hokusai, in the style of Ukiyo", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "Gwen Stacy reading a book, black and white", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "Gwen Stacy reading a book, pixel art", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "Gwen Stacy reading a book, in cyberpunk style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "Gwen Stacy reading a book, animated style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "Gwen Stacy reading a book, watercolor painting", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "Gwen Stacy reading a book, surrealism style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A boat sailing leisurely along the Seine River with the Eiffel Tower in background, Van Gogh style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A boat sailing leisurely along the Seine River with the Eiffel Tower in background, oil painting", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A boat sailing leisurely along the Seine River with the Eiffel Tower in background by Hokusai, in the style of Ukiyo", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A boat sailing leisurely along the Seine River with the Eiffel Tower in background, black and white", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A boat sailing leisurely along the Seine River with the Eiffel Tower in background, pixel art", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A boat sailing leisurely along the Seine River with the Eiffel Tower in background, in cyberpunk style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A boat sailing leisurely along the Seine River with the Eiffel Tower in background, animated style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A boat sailing leisurely along the Seine River with the Eiffel Tower in background, watercolor painting", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A boat sailing leisurely along the Seine River with the Eiffel Tower in background, surrealism style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A couple in formal evening wear going home get caught in a heavy downpour with umbrellas, Van Gogh style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A couple in formal evening wear going home get caught in a heavy downpour with umbrellas, oil painting", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A couple in formal evening wear going home get caught in a heavy downpour with umbrellas by Hokusai, in the style of Ukiyo", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A couple in formal evening wear going home get caught in a heavy downpour with umbrellas, black and white", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A couple in formal evening wear going home get caught in a heavy downpour with umbrellas, pixel art", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A couple in formal evening wear going home get caught in a heavy downpour with umbrellas, in cyberpunk style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A couple in formal evening wear going home get caught in a heavy downpour with umbrellas, animated style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A couple in formal evening wear going home get caught in a heavy downpour with umbrellas, watercolor painting", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "A couple in formal evening wear going home get caught in a heavy downpour with umbrellas, surrealism style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "An astronaut flying in space, Van Gogh style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "An astronaut flying in space, oil painting", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "An astronaut flying in space by Hokusai, in the style of Ukiyo", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "An astronaut flying in space, black and white", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "An astronaut flying in space, pixel art", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "An astronaut flying in space, in cyberpunk style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "An astronaut flying in space, animated style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "An astronaut flying in space, watercolor painting", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "An astronaut flying in space, surrealism style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "Snow rocky mountains peaks canyon. snow blanketed rocky mountains surround and shadow deep canyons. the canyons twist and bend through the high elevated mountain peaks, Van Gogh style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "Snow rocky mountains peaks canyon. snow blanketed rocky mountains surround and shadow deep canyons. the canyons twist and bend through the high elevated mountain peaks, oil painting", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "Snow rocky mountains peaks canyon. snow blanketed rocky mountains surround and shadow deep canyons. the canyons twist and bend through the high elevated mountain peaks by Hokusai, in the style of Ukiyo", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "Snow rocky mountains peaks canyon. snow blanketed rocky mountains surround and shadow deep canyons. the canyons twist and bend through the high elevated mountain peaks, black and white", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "Snow rocky mountains peaks canyon. snow blanketed rocky mountains surround and shadow deep canyons. the canyons twist and bend through the high elevated mountain peaks, pixel art", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "Snow rocky mountains peaks canyon. snow blanketed rocky mountains surround and shadow deep canyons. the canyons twist and bend through the high elevated mountain peaks, in cyberpunk style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "Snow rocky mountains peaks canyon. snow blanketed rocky mountains surround and shadow deep canyons. the canyons twist and bend through the high elevated mountain peaks, animated style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "Snow rocky mountains peaks canyon. snow blanketed rocky mountains surround and shadow deep canyons. the canyons twist and bend through the high elevated mountain peaks, watercolor painting", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "Snow rocky mountains peaks canyon. snow blanketed rocky mountains surround and shadow deep canyons. the canyons twist and bend through the high elevated mountain peaks, surrealism style", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "alley", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "amusement park", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "aquarium", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "arch", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "art gallery", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "bathroom", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "bakery shop", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "ballroom", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "bar", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "barn", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "basement", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "beach", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "bedroom", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "bridge", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "botanical garden", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "cafeteria", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "campsite", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "campus", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "carrousel", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "castle", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "cemetery", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "classroom", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "cliff", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "crosswalk", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "construction site", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "corridor", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "courtyard", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "desert", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "downtown", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "driveway", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "farm", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "food court", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "football field", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "forest road", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "fountain", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "gas station", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "glacier", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "golf course", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "indoor gymnasium", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "harbor", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "highway", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "hospital", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "house", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "iceberg", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "industrial area", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "jail cell", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "junkyard", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "kitchen", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "indoor library", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "lighthouse", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "laboratory", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "mansion", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "marsh", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "mountain", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "indoor movie theater", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "indoor museum", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "music studio", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "nursery", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "ocean", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "office", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "palace", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "parking lot", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "pharmacy", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "phone booth", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "raceway", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "restaurant", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "river", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "science museum", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "shower", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "ski slope", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "sky", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "skyscraper", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "baseball stadium", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "staircase", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "street", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "supermarket", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "indoor swimming pool", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "tower", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "outdoor track", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "train railway", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "train station platform", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "underwater coral reef", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "valley", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "volcano", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "waterfall", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} +{"prompt": "windmill", "negative_prompt": "vivid colors, overexposed, static, blurry details, subtitles, style, work of art, painting, picture, still, overall grayish, worst quality, low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, static image, cluttered background, three legs, many people in the background, walking backwards"} diff --git a/src/inference_endpoint/commands/probe.py b/src/inference_endpoint/commands/probe.py index e74361ee..de840b5d 100644 --- a/src/inference_endpoint/commands/probe.py +++ b/src/inference_endpoint/commands/probe.py @@ -50,7 +50,9 @@ class ProbeConfig(BaseModel): model: str api_type: Annotated[ APIType, - cyclopts.Parameter(alias="--api-type", help="API type: openai or sglang"), + cyclopts.Parameter( + alias="--api-type", help="API type: openai, sglang, or videogen" + ), ] = APIType.OPENAI requests: int = Field(10, ge=1) prompt: str = Field( @@ -77,6 +79,18 @@ async def _probe_async(config: ProbeConfig) -> None: test_prompt = config.prompt api_type = config.api_type + # Probe assumes second-scale latencies (probe_timeout=60s below) and + # text prompt/response semantics — neither holds for video generation, + # where each request takes minutes and there are no chat tokens to + # display. Reject upfront rather than emitting a misleading + # "0/N requests successful" failure after the timeout. + if api_type == APIType.VIDEOGEN: + raise InputValidationError( + "Probe does not support api_type=videogen " + "(per-request latencies exceed the probe timeout). " + "Use a dedicated health check or a benchmark from-config run instead." + ) + # Model: use provided or default to valid OpenAI model name model_name = config.model if not model_name: diff --git a/src/inference_endpoint/config/schema.py b/src/inference_endpoint/config/schema.py index 6a1884b4..8ab8f3b0 100644 --- a/src/inference_endpoint/config/schema.py +++ b/src/inference_endpoint/config/schema.py @@ -439,7 +439,9 @@ class EndpointConfig(BaseModel): ] = None api_type: Annotated[ APIType, - cyclopts.Parameter(alias="--api-type", help="API type: openai or sglang"), + cyclopts.Parameter( + alias="--api-type", help="API type: openai, sglang, or videogen" + ), ] = APIType.OPENAI @field_validator("endpoints", mode="after") diff --git a/src/inference_endpoint/config/templates/concurrency_template_full.yaml b/src/inference_endpoint/config/templates/concurrency_template_full.yaml index 3a8e004f..835300a8 100644 --- a/src/inference_endpoint/config/templates/concurrency_template_full.yaml +++ b/src/inference_endpoint/config/templates/concurrency_template_full.yaml @@ -72,7 +72,7 @@ endpoint_config: endpoints: # Endpoint URL(s). Must include scheme, e.g. 'http://host:port'. - http://localhost:8000 api_key: null # API key - api_type: openai # API type: openai or sglang | options: openai, sglang + api_type: openai # API type: openai, sglang, or videogen | options: openai, sglang, videogen report_dir: null # Report output directory timeout: null # Global timeout in seconds verbose: false # Enable verbose logging diff --git a/src/inference_endpoint/config/templates/offline_template_full.yaml b/src/inference_endpoint/config/templates/offline_template_full.yaml index faabffde..5f4dd50c 100644 --- a/src/inference_endpoint/config/templates/offline_template_full.yaml +++ b/src/inference_endpoint/config/templates/offline_template_full.yaml @@ -72,7 +72,7 @@ endpoint_config: endpoints: # Endpoint URL(s). Must include scheme, e.g. 'http://host:port'. - http://localhost:8000 api_key: null # API key - api_type: openai # API type: openai or sglang | options: openai, sglang + api_type: openai # API type: openai, sglang, or videogen | options: openai, sglang, videogen report_dir: null # Report output directory timeout: null # Global timeout in seconds verbose: false # Enable verbose logging diff --git a/src/inference_endpoint/config/templates/online_template_full.yaml b/src/inference_endpoint/config/templates/online_template_full.yaml index e9b7a673..434b1778 100644 --- a/src/inference_endpoint/config/templates/online_template_full.yaml +++ b/src/inference_endpoint/config/templates/online_template_full.yaml @@ -72,7 +72,7 @@ endpoint_config: endpoints: # Endpoint URL(s). Must include scheme, e.g. 'http://host:port'. - http://localhost:8000 api_key: null # API key - api_type: openai # API type: openai or sglang | options: openai, sglang + api_type: openai # API type: openai, sglang, or videogen | options: openai, sglang, videogen report_dir: null # Report output directory timeout: null # Global timeout in seconds verbose: false # Enable verbose logging diff --git a/src/inference_endpoint/core/types.py b/src/inference_endpoint/core/types.py index accd2ca8..bde8f2d3 100644 --- a/src/inference_endpoint/core/types.py +++ b/src/inference_endpoint/core/types.py @@ -36,6 +36,7 @@ class APIType(str, Enum): OPENAI = "openai" SGLANG = "sglang" + VIDEOGEN = "videogen" def default_route(self) -> str: """Return the default HTTP path for this API type.""" @@ -44,6 +45,8 @@ def default_route(self) -> str: return "/v1/chat/completions" case APIType.SGLANG: return "/generate" + case APIType.VIDEOGEN: + return "/v1/videos/generations" case _: raise ValueError(f"Invalid API type: {self}") diff --git a/src/inference_endpoint/endpoint_client/config.py b/src/inference_endpoint/endpoint_client/config.py index e24eb709..a4a62ed4 100644 --- a/src/inference_endpoint/endpoint_client/config.py +++ b/src/inference_endpoint/endpoint_client/config.py @@ -48,11 +48,13 @@ ADAPTER_MAP = { APIType.OPENAI: "inference_endpoint.openai.openai_msgspec_adapter.OpenAIMsgspecAdapter", APIType.SGLANG: "inference_endpoint.sglang.adapter.SGLangGenerateAdapter", + APIType.VIDEOGEN: "inference_endpoint.videogen.adapter.VideoGenAdapter", } ACCUMULATOR_MAP = { APIType.OPENAI: "inference_endpoint.openai.accumulator.OpenAISSEAccumulator", APIType.SGLANG: "inference_endpoint.sglang.accumulator.SGLangSSEAccumulator", + APIType.VIDEOGEN: "inference_endpoint.videogen.adapter.VideoGenAccumulator", } diff --git a/src/inference_endpoint/testing/echo_server.py b/src/inference_endpoint/testing/echo_server.py index 6555f2e6..980c613e 100644 --- a/src/inference_endpoint/testing/echo_server.py +++ b/src/inference_endpoint/testing/echo_server.py @@ -311,16 +311,23 @@ def _run_server(self): asyncio.set_event_loop(self._loop) self._loop.run_until_complete(self._start_server()) + def _register_routes(self, app: "web.Application") -> None: + """Register HTTP routes on the aiohttp app. + + Subclasses can override to swap out the OpenAI-shaped routes for + a different wire contract while reusing the lifecycle plumbing. + """ + app.router.add_post( + "/v1/chat/completions", self._handle_echo_chat_completions_request + ) + app.router.add_post("/echo", self._handle_echo_request) + async def _start_server(self): """Start the HTTP server.""" try: # Create the web application self.app = web.Application() - - self.app.router.add_post( - "/v1/chat/completions", self._handle_echo_chat_completions_request - ) - self.app.router.add_post("/echo", self._handle_echo_request) + self._register_routes(self.app) # Start the server self.runner = web.AppRunner(self.app) diff --git a/src/inference_endpoint/videogen/__init__.py b/src/inference_endpoint/videogen/__init__.py new file mode 100644 index 00000000..2ecd71ed --- /dev/null +++ b/src/inference_endpoint/videogen/__init__.py @@ -0,0 +1,27 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Public API for the video generation inference module.""" + +from .adapter import VideoGenAccumulator, VideoGenAdapter +from .types import VideoPathRequest, VideoPathResponse, VideoPayloadResponse + +__all__ = [ + "VideoGenAdapter", + "VideoGenAccumulator", + "VideoPathRequest", + "VideoPathResponse", + "VideoPayloadResponse", +] diff --git a/src/inference_endpoint/videogen/adapter.py b/src/inference_endpoint/videogen/adapter.py new file mode 100644 index 00000000..08dddb1c --- /dev/null +++ b/src/inference_endpoint/videogen/adapter.py @@ -0,0 +1,137 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Adapter for trtllm-serve's POST /v1/videos/generations endpoint.""" + +import json +from typing import TYPE_CHECKING, Any + +from inference_endpoint.core.types import ( + Query, + QueryResult, + StreamChunk, +) +from inference_endpoint.dataset_manager.transforms import ColumnFilter +from inference_endpoint.endpoint_client.adapter_protocol import HttpRequestAdapter + +from .types import VideoPathRequest, VideoPathResponse, VideoPayloadResponse + +if TYPE_CHECKING: + from inference_endpoint.config.schema import ModelParams + from inference_endpoint.dataset_manager.transforms import Transform + + +class VideoGenAdapter(HttpRequestAdapter): + """Adapter for trtllm-serve POST /v1/videos/generations. + + `response_format` is read from `query.data` (default "video_path") and + is *not* derived from BenchmarkConfig.benchmark_mode. Callers that want + accuracy-mode bytes must inject `response_format="video_bytes"` into the + dataset rows — typically via an `AddStaticColumns` transform. + """ + + @classmethod + def dataset_transforms(cls, model_params: "ModelParams") -> "list[Transform]": + # ColumnFilter rejects unknown columns at dataset-load time so typos + # (e.g. "negitive_prompt") fail loud instead of silently falling back + # to server-side defaults. + request_fields = list(VideoPathRequest.model_fields.keys()) + return [ + ColumnFilter( + required_columns=["prompt"], + optional_columns=[f for f in request_fields if f != "prompt"], + ), + ] + + @classmethod + def encode_query(cls, query: Query) -> bytes: + """Serialise query.data to VideoPathRequest JSON bytes. + + Only `prompt` is required. All other fields fall back to defaults on + VideoPathRequest but can be overridden via query.data. Streaming is + not supported — `stream=True` raises. + """ + data = query.data + if "prompt" not in data: + raise KeyError( + f"'prompt' not found in query.data keys: {list(data.keys())}" + ) + if data.get("stream"): + raise ValueError( + "VideoGenAdapter is non-streaming; remove `stream` from query.data." + ) + known = VideoPathRequest.model_fields.keys() + req = VideoPathRequest.model_validate({k: data[k] for k in known if k in data}) + # exclude_none so optional fields with value None fall back to + # server-side defaults; fields explicitly set in query.data + # (e.g. negative_prompt from the bundled JSONL) are forwarded. + return req.model_dump_json(exclude_none=True).encode() + + @classmethod + def decode_response(cls, response_bytes: bytes, query_id: str) -> QueryResult: + """Deserialise trtllm-serve response JSON bytes to QueryResult. + + Dispatches on the response shape: + - video_bytes response (str payload): metadata["video_bytes"]. + - video_path response: metadata["video_path"]. + """ + raw = json.loads(response_bytes) + # Truthiness check, not key presence: a server that returns + # `"video_bytes": null` belongs in the video_path branch. + if isinstance(raw.get("video_bytes"), str): + resp_bytes = VideoPayloadResponse.model_validate(raw) + return QueryResult( + id=query_id, + metadata={ + "video_id": resp_bytes.video_id, + "video_bytes": resp_bytes.video_bytes, + }, + ) + resp_path = VideoPathResponse.model_validate(raw) + return QueryResult( + id=query_id, + metadata={ + "video_id": resp_path.video_id, + "video_path": resp_path.video_path, + }, + ) + + @classmethod + def decode_sse_message(cls, json_bytes: bytes) -> str: + raise NotImplementedError("VideoGenAdapter does not use SSE streaming") + + +class VideoGenAccumulator: + """SSE accumulator stub for HTTPClientConfig contract. + + Video generation requests are non-streaming HTTP, so this class should + never be exercised. `get_final_output` raises rather than returning an + empty `QueryResult`, because the worker's SSE path swallows the + `NotImplementedError` from `decode_sse_message` and would otherwise + surface zero-output queries as successful. + """ + + def __init__(self, query_id: str, stream_all_chunks: bool) -> None: + self.query_id = query_id + # stream_all_chunks is intentionally ignored: non-streaming endpoint. + + def add_chunk(self, delta: Any) -> StreamChunk | None: + return None + + def get_final_output(self) -> QueryResult: + raise RuntimeError( + "VideoGenAccumulator.get_final_output called: video generation is " + "non-streaming — check HTTPClientConfig.streaming and query.data['stream']." + ) diff --git a/src/inference_endpoint/videogen/types.py b/src/inference_endpoint/videogen/types.py new file mode 100644 index 00000000..26423b23 --- /dev/null +++ b/src/inference_endpoint/videogen/types.py @@ -0,0 +1,102 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Wire models for trtllm-serve POST /v1/videos/generations.""" + +from typing import Literal + +from pydantic import BaseModel, ConfigDict, Field + + +class VideoPathRequest(BaseModel): + """Request body for POST /v1/videos/generations. + + Matches trtllm-serve's VideoGenerationRequest. All fields have MLPerf defaults + so that only `prompt` is required from the dataset. + + `response_format` defaults to "video_path"; callers wanting accuracy-mode + behaviour must inject `response_format="video_bytes"` into `query.data` + via the dataset (the adapter does not derive it from `benchmark_mode`). + """ + + prompt: str + negative_prompt: str | None = Field( + default=None, + description=( + "Text describing what to avoid. None means the field is omitted " + "from the JSON payload so trtllm-serve can apply its model default. " + "The bundled MLPerf prompts dataset carries the canonical negative " + "prompt per row." + ), + ) + size: str = Field(default="720x1280", description="Frame size in 'WxH' format.") + seconds: float = Field( + default=5.0, + description="Video duration. 81 frames @ ~16.2 fps = 5 s (MLPerf standard).", + ) + fps: int = Field(default=16, description="Frames per second (MLPerf: 16).") + num_inference_steps: int = Field( + default=20, description="Denoising steps (MLPerf: 20)." + ) + guidance_scale: float = Field( + default=4.0, description="CFG guidance scale (MLPerf: 4.0)." + ) + guidance_scale_2: float = Field( + default=3.0, + description="Secondary guidance scale for null-text CFG (MLPerf: 3.0).", + ) + seed: int = Field(default=42, description="Random seed (MLPerf: 42).") + latent_path: str | None = Field( + default=None, + description=( + "Absolute path to a pre-computed latent tensor (.pt file) on shared " + "storage accessible to the server (e.g. Lustre). When provided, the " + "server uses this tensor as the initial denoising noise instead of " + "sampling random noise. MLPerf uses a fixed latent for reproducibility." + ), + ) + output_format: Literal["mp4", "avi", "auto"] = "auto" + response_format: Literal["video_bytes", "video_path"] = "video_path" + + +class VideoPathResponse(BaseModel): + """Response body from trtllm-serve when response_format='video_path'. + + The server saves the encoded video to its local filesystem (e.g. Lustre) + and returns the absolute path instead of video bytes. + Used in perf mode: MLPerf defines query completion as server finishing + generation, so bytes do not need to cross the wire. + + `extra="forbid"` so a server returning unexpected fields (or both + video_path and video_bytes) fails loudly at deserialisation. + """ + + model_config = ConfigDict(extra="forbid") + + video_id: str + video_path: str + + +class VideoPayloadResponse(BaseModel): + """Response body from trtllm-serve when response_format='video_bytes'. + + Used in accuracy mode. video_bytes is the base64-encoded video content, + which the accuracy evaluator decodes to score quality (e.g. FVD). + """ + + model_config = ConfigDict(extra="forbid") + + video_id: str + video_bytes: str # base64-encoded video content diff --git a/tests/integration/commands/test_probe_command.py b/tests/integration/commands/test_probe_command.py index bc3c046e..a1088584 100644 --- a/tests/integration/commands/test_probe_command.py +++ b/tests/integration/commands/test_probe_command.py @@ -25,7 +25,8 @@ import pytest from inference_endpoint.commands.probe import ProbeConfig, execute_probe -from inference_endpoint.exceptions import ExecutionError +from inference_endpoint.config.schema import APIType +from inference_endpoint.exceptions import ExecutionError, InputValidationError class TestProbeCommandIntegration: @@ -84,6 +85,19 @@ def test_probe_shows_multiple_responses(self, mock_http_echo_server, caplog): assert "[probe-0]" in caplog.text assert "Sample response text" in caplog.text + @pytest.mark.integration + def test_probe_rejects_videogen_api_type(self): + """Probe assumes second-scale latencies; videogen requests run for minutes.""" + config = ProbeConfig( + endpoints="http://localhost:8000", + model="wan22", + api_type=APIType.VIDEOGEN, + requests=1, + prompt="a cat", + ) + with pytest.raises(InputValidationError, match="videogen"): + execute_probe(config) + @pytest.mark.integration def test_probe_with_invalid_endpoint(self): """Test probe fails gracefully with invalid endpoint.""" diff --git a/tests/integration/videogen/__init__.py b/tests/integration/videogen/__init__.py new file mode 100644 index 00000000..46707983 --- /dev/null +++ b/tests/integration/videogen/__init__.py @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/tests/integration/videogen/conftest.py b/tests/integration/videogen/conftest.py new file mode 100644 index 00000000..aff23910 --- /dev/null +++ b/tests/integration/videogen/conftest.py @@ -0,0 +1,107 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Integration test fixtures for the videogen adapter. + +The two mocks subclass `EchoServer` to reuse its background-thread +aiohttp lifecycle (port discovery, start/stop, ready event). Only the +route registration differs — videogen serves `/v1/videos/generations` +instead of OpenAI's `/v1/chat/completions`. +""" + +import base64 +import hashlib +from collections.abc import Generator + +import pytest +from aiohttp import web +from inference_endpoint.testing.echo_server import EchoServer + +# Minimal dummy video bytes returned in accuracy mode (base64-encoded in responses). +DUMMY_VIDEO_BYTES = b"\x00\x00\x00\x20ftypmp42" + b"\x00" * 24 + + +@pytest.fixture(scope="module") +def mock_video_path(tmp_path_factory: pytest.TempPathFactory) -> str: + """Stable per-module path string the mock server returns for video_path mode. + + The mock never writes a real file — the path only needs to be a unique + string the adapter and tests can assert against. Using tmp_path_factory + avoids hardcoding shared-storage locations like /lustre/.... + """ + return str(tmp_path_factory.mktemp("videogen") / "mock_video_001.mp4") + + +class MockTrtllmServe(EchoServer): + """trtllm-serve-shaped mock for `/v1/videos/generations`. + + Branches on the request body's `response_format` field: + - "video_bytes": returns VideoPayloadResponse JSON with base64-encoded + DUMMY_VIDEO_BYTES. + - anything else (default): returns VideoPathResponse JSON pointing at + the configured `video_path`. + """ + + def __init__(self, video_path: str) -> None: + super().__init__(port=0) + self.video_path = video_path + + def _register_routes(self, app: web.Application) -> None: + app.router.add_post("/v1/videos/generations", self._handle_videogen) + + async def _handle_videogen(self, request: web.Request) -> web.Response: + body = await request.json() + # sha1 not hash() — Python's hash() is salted per-interpreter via + # PYTHONHASHSEED, which makes the mock id non-deterministic across runs. + prompt = body.get("prompt", "") + digest = hashlib.sha1(prompt.encode()).hexdigest()[:4] + video_id = f"mock_video_{digest}" + if body.get("response_format") == "video_bytes": + return web.json_response( + { + "video_id": video_id, + "video_bytes": base64.b64encode(DUMMY_VIDEO_BYTES).decode(), + } + ) + return web.json_response({"video_id": video_id, "video_path": self.video_path}) + + +@pytest.fixture(scope="module") +def mock_trtllm_serve(mock_video_path: str) -> Generator[MockTrtllmServe, None, None]: + server = MockTrtllmServe(video_path=mock_video_path) + server.start() + yield server + server.stop() + + +class MockTrtllmServeError(EchoServer): + """Mock trtllm-serve that returns HTTP 500 for `/v1/videos/generations`.""" + + def __init__(self) -> None: + super().__init__(port=0) + + def _register_routes(self, app: web.Application) -> None: + app.router.add_post("/v1/videos/generations", self._handle_error) + + async def _handle_error(self, request: web.Request) -> web.Response: + return web.Response(status=500, text="Internal Server Error") + + +@pytest.fixture(scope="module") +def mock_trtllm_serve_error() -> Generator[MockTrtllmServeError, None, None]: + server = MockTrtllmServeError() + server.start() + yield server + server.stop() diff --git a/tests/integration/videogen/test_adapter.py b/tests/integration/videogen/test_adapter.py new file mode 100644 index 00000000..1ee9ad27 --- /dev/null +++ b/tests/integration/videogen/test_adapter.py @@ -0,0 +1,157 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Integration tests: VideoGenAdapter encode/decode round-trip against mock trtllm-serve.""" + +import base64 +import json +import urllib.request +from urllib.error import HTTPError + +import pytest +from inference_endpoint.core.types import Query +from inference_endpoint.videogen.adapter import VideoGenAdapter +from pydantic import ValidationError + +from .conftest import ( + DUMMY_VIDEO_BYTES, + MockTrtllmServe, + MockTrtllmServeError, +) + + +def _post(url: str, body: bytes) -> tuple[int, bytes]: + """Synchronous HTTP POST returning (status_code, response_body).""" + req = urllib.request.Request( + url, + data=body, + headers={"Content-Type": "application/json"}, + method="POST", + ) + try: + with urllib.request.urlopen(req) as resp: + return resp.status, resp.read() + except HTTPError as e: + return e.code, e.read() + + +@pytest.mark.integration +class TestVideoGenAdapterRoundTrip: + """Verify encode_query → HTTP POST → decode_response against mock trtllm-serve.""" + + def test_perf_mode_round_trip_returns_video_path( + self, mock_trtllm_serve: MockTrtllmServe + ) -> None: + """Default response_format=video_path → server returns the saved-video path.""" + query = Query(id="q1", data={"prompt": "a golden retriever running on a beach"}) + request_bytes = VideoGenAdapter.encode_query(query) + + status, content = _post( + f"{mock_trtllm_serve.url}/v1/videos/generations", request_bytes + ) + assert status == 200 + + result = VideoGenAdapter.decode_response(content, query.id) + assert result.id == "q1" + assert result.error is None + assert result.response_output is None + assert result.metadata["video_path"] == mock_trtllm_serve.video_path + assert isinstance(result.metadata["video_id"], str) + + def test_accuracy_mode_round_trip_returns_video_bytes( + self, mock_trtllm_serve: MockTrtllmServe + ) -> None: + """response_format=video_bytes → server returns base64 payload inline.""" + query = Query( + id="q1b", + data={ + "prompt": "a golden retriever running on a beach", + "response_format": "video_bytes", + }, + ) + request_bytes = VideoGenAdapter.encode_query(query) + + status, content = _post( + f"{mock_trtllm_serve.url}/v1/videos/generations", request_bytes + ) + assert status == 200 + + result = VideoGenAdapter.decode_response(content, query.id) + assert result.id == "q1b" + assert result.error is None + assert result.response_output is None + assert isinstance(result.metadata["video_id"], str) + decoded = base64.b64decode(result.metadata["video_bytes"]) + assert decoded == DUMMY_VIDEO_BYTES + + def test_request_default_response_format_is_video_path( + self, mock_trtllm_serve: MockTrtllmServe + ) -> None: + query = Query(id="q2", data={"prompt": "ocean waves at sunset"}) + payload = json.loads(VideoGenAdapter.encode_query(query)) + assert payload["response_format"] == "video_path" + + def test_request_accuracy_mode_asks_for_video_bytes( + self, mock_trtllm_serve: MockTrtllmServe + ) -> None: + query = Query( + id="q2b", + data={"prompt": "ocean waves at sunset", "response_format": "video_bytes"}, + ) + payload = json.loads(VideoGenAdapter.encode_query(query)) + assert payload["response_format"] == "video_bytes" + + def test_request_carries_mlperf_defaults( + self, mock_trtllm_serve: MockTrtllmServe + ) -> None: + query = Query(id="q3", data={"prompt": "ocean waves at sunset"}) + payload = json.loads(VideoGenAdapter.encode_query(query)) + assert payload["fps"] == 16 + assert payload["seconds"] == pytest.approx(5.0) + assert payload["size"] == "720x1280" + assert payload["num_inference_steps"] == 20 + assert payload["guidance_scale"] == pytest.approx(4.0) + assert payload["seed"] == 42 + + +@pytest.mark.integration +class TestVideoGenAdapterErrorHandling: + def test_http_500_response_raises_on_decode( + self, mock_trtllm_serve_error: MockTrtllmServeError + ) -> None: + query = Query(id="q4", data={"prompt": "a cat"}) + status, content = _post( + f"{mock_trtllm_serve_error.url}/v1/videos/generations", + VideoGenAdapter.encode_query(query), + ) + assert status == 500 + with pytest.raises((ValidationError, json.JSONDecodeError)): + VideoGenAdapter.decode_response(content, query.id) + + def test_malformed_json_response_raises(self) -> None: + with pytest.raises(json.JSONDecodeError): + VideoGenAdapter.decode_response(b"not json at all", "q5") + + def test_video_path_branch_missing_video_path_raises(self) -> None: + """No video_bytes key → dispatch to VideoPathResponse → video_path required.""" + bad_body = b'{"video_id": "vid_001"}' + with pytest.raises(ValidationError): + VideoGenAdapter.decode_response(bad_body, "q6") + + def test_video_bytes_branch_missing_video_id_raises(self) -> None: + """video_bytes key present → dispatch to VideoPayloadResponse → video_id required.""" + bad_body = b'{"video_bytes": "AAEC"}' + with pytest.raises(ValidationError): + VideoGenAdapter.decode_response(bad_body, "q7") diff --git a/tests/unit/videogen/__init__.py b/tests/unit/videogen/__init__.py new file mode 100644 index 00000000..46707983 --- /dev/null +++ b/tests/unit/videogen/__init__.py @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/tests/unit/videogen/test_adapter.py b/tests/unit/videogen/test_adapter.py new file mode 100644 index 00000000..dc1b470a --- /dev/null +++ b/tests/unit/videogen/test_adapter.py @@ -0,0 +1,171 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Unit tests for VideoGenAdapter and VideoGenAccumulator (trtllm-native API).""" + +import json + +import pytest +from inference_endpoint.config.schema import ModelParams +from inference_endpoint.core.types import APIType, Query, QueryResult +from inference_endpoint.endpoint_client.accumulator_protocol import ( + SSEAccumulatorProtocol, +) +from inference_endpoint.videogen.adapter import VideoGenAccumulator, VideoGenAdapter +from inference_endpoint.videogen.types import VideoPathResponse, VideoPayloadResponse + + +@pytest.mark.unit +class TestVideoGenAdapter: + def test_encode_query_produces_valid_json(self): + query = Query(id="q1", data={"prompt": "a golden retriever running"}) + payload = json.loads(VideoGenAdapter.encode_query(query)) + assert payload["prompt"] == "a golden retriever running" + + def test_encode_query_default_response_format_is_video_path(self): + """Perf mode default — server saves to Lustre, returns path only.""" + query = Query(id="q1", data={"prompt": "ocean waves"}) + payload = json.loads(VideoGenAdapter.encode_query(query)) + assert payload["response_format"] == "video_path" + + def test_encode_query_accuracy_mode_requests_video_bytes(self): + """Accuracy mode override — query.data opts in to inline bytes.""" + query = Query( + id="q1", data={"prompt": "ocean waves", "response_format": "video_bytes"} + ) + payload = json.loads(VideoGenAdapter.encode_query(query)) + assert payload["response_format"] == "video_bytes" + + def test_encode_query_uses_mlperf_defaults(self): + query = Query(id="q1", data={"prompt": "ocean waves"}) + payload = json.loads(VideoGenAdapter.encode_query(query)) + assert payload["fps"] == 16 + assert payload["seconds"] == pytest.approx(5.0) + assert payload["size"] == "720x1280" + assert payload["num_inference_steps"] == 20 + assert payload["guidance_scale"] == pytest.approx(4.0) + assert payload["guidance_scale_2"] == pytest.approx(3.0) + assert payload["seed"] == 42 + + def test_encode_query_allows_override_via_data(self): + query = Query( + id="q1", + data={"prompt": "test", "seed": 99, "fps": 24, "guidance_scale": 6.0}, + ) + payload = json.loads(VideoGenAdapter.encode_query(query)) + assert payload["seed"] == 99 + assert payload["fps"] == 24 + assert payload["guidance_scale"] == pytest.approx(6.0) + + def test_encode_query_includes_negative_prompt(self): + query = Query(id="q1", data={"prompt": "test", "negative_prompt": "blurry"}) + payload = json.loads(VideoGenAdapter.encode_query(query)) + assert payload["negative_prompt"] == "blurry" + + def test_encode_query_omits_negative_prompt_when_absent(self): + """exclude_none=True so server can apply its own default.""" + query = Query(id="q1", data={"prompt": "test"}) + payload = json.loads(VideoGenAdapter.encode_query(query)) + assert "negative_prompt" not in payload + + def test_encode_query_includes_latent_path(self): + query = Query( + id="q1", data={"prompt": "test", "latent_path": "/lustre/fixed_latent.pt"} + ) + payload = json.loads(VideoGenAdapter.encode_query(query)) + assert payload["latent_path"] == "/lustre/fixed_latent.pt" + + def test_encode_query_omits_latent_path_when_absent(self): + query = Query(id="q1", data={"prompt": "test"}) + payload = json.loads(VideoGenAdapter.encode_query(query)) + assert "latent_path" not in payload + + def test_encode_query_missing_prompt_raises(self): + query = Query(id="q1", data={"seed": 42}) + with pytest.raises(KeyError): + VideoGenAdapter.encode_query(query) + + def test_encode_query_rejects_stream_true(self): + query = Query(id="q1", data={"prompt": "test", "stream": True}) + with pytest.raises(ValueError, match="non-streaming"): + VideoGenAdapter.encode_query(query) + + def test_decode_response_returns_video_bytes_in_metadata(self): + resp = VideoPayloadResponse( + video_id="video_abc123", + video_bytes="dGVzdCB2aWRlbyBjb250ZW50", + ) + result = VideoGenAdapter.decode_response(resp.model_dump_json().encode(), "q1") + assert isinstance(result, QueryResult) + assert result.id == "q1" + assert result.error is None + assert result.response_output is None + assert result.metadata == { + "video_id": "video_abc123", + "video_bytes": "dGVzdCB2aWRlbyBjb250ZW50", + } + + def test_decode_response_returns_video_path_in_metadata(self): + """Perf-mode decode branch — covered separately from integration.""" + resp = VideoPathResponse( + video_id="vid_perf_001", + video_path="/lustre/videos/vid_perf_001.mp4", + ) + result = VideoGenAdapter.decode_response(resp.model_dump_json().encode(), "q1") + assert isinstance(result, QueryResult) + assert result.id == "q1" + assert result.error is None + assert result.response_output is None + assert result.metadata == { + "video_id": "vid_perf_001", + "video_path": "/lustre/videos/vid_perf_001.mp4", + } + + def test_decode_sse_message_raises_not_implemented(self): + with pytest.raises(NotImplementedError): + VideoGenAdapter.decode_sse_message(b"{}") + + def test_dataset_transforms_returns_column_filter(self): + from inference_endpoint.dataset_manager.transforms import ColumnFilter + from inference_endpoint.videogen.types import VideoPathRequest + + params = ModelParams() + transforms = VideoGenAdapter.dataset_transforms(params) + assert len(transforms) == 1 + cf = transforms[0] + assert isinstance(cf, ColumnFilter) + assert cf.required_columns == ["prompt"] + # Optional columns mirror VideoPathRequest fields except prompt itself. + expected_optional = {f for f in VideoPathRequest.model_fields if f != "prompt"} + assert set(cf.optional_columns or []) == expected_optional + + def test_default_route_is_trtllm_native(self): + assert APIType.VIDEOGEN.default_route() == "/v1/videos/generations" + + +@pytest.mark.unit +class TestVideoGenAccumulator: + def test_add_chunk_always_returns_none(self): + acc = VideoGenAccumulator(query_id="q1", stream_all_chunks=True) + assert acc.add_chunk("anything") is None + assert acc.add_chunk(None) is None + + def test_get_final_output_raises_because_videogen_is_non_streaming(self): + acc = VideoGenAccumulator(query_id="q1", stream_all_chunks=False) + with pytest.raises(RuntimeError, match="non-streaming"): + acc.get_final_output() + + def test_satisfies_sse_accumulator_protocol(self): + assert isinstance(VideoGenAccumulator("q1", False), SSEAccumulatorProtocol) diff --git a/tests/unit/videogen/test_init.py b/tests/unit/videogen/test_init.py new file mode 100644 index 00000000..c29ea42e --- /dev/null +++ b/tests/unit/videogen/test_init.py @@ -0,0 +1,35 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Verify videogen public namespace exports.""" + +import pytest +from inference_endpoint.videogen import ( + VideoGenAccumulator, + VideoGenAdapter, + VideoPathRequest, + VideoPathResponse, + VideoPayloadResponse, +) + + +@pytest.mark.unit +class TestVideoGenPublicExports: + def test_all_public_exports_importable(self): + assert VideoPathRequest is not None + assert VideoPathResponse is not None + assert VideoPayloadResponse is not None + assert VideoGenAdapter is not None + assert VideoGenAccumulator is not None diff --git a/tests/unit/videogen/test_registration.py b/tests/unit/videogen/test_registration.py new file mode 100644 index 00000000..08f8bea3 --- /dev/null +++ b/tests/unit/videogen/test_registration.py @@ -0,0 +1,62 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Tests that APIType.VIDEOGEN is registered and wired up correctly.""" + +from importlib import import_module + +import pytest +from inference_endpoint.core.types import APIType +from inference_endpoint.endpoint_client.config import ACCUMULATOR_MAP, ADAPTER_MAP + + +@pytest.mark.unit +def test_api_type_videogen_exists(): + assert APIType.VIDEOGEN == "videogen" + + +@pytest.mark.unit +def test_api_type_videogen_default_route(): + assert APIType.VIDEOGEN.default_route() == "/v1/videos/generations" + + +@pytest.mark.unit +def test_videogen_in_adapter_map(): + assert APIType.VIDEOGEN in ADAPTER_MAP + assert "VideoGenAdapter" in ADAPTER_MAP[APIType.VIDEOGEN] + + +@pytest.mark.unit +def test_videogen_in_accumulator_map(): + assert APIType.VIDEOGEN in ACCUMULATOR_MAP + assert "VideoGenAccumulator" in ACCUMULATOR_MAP[APIType.VIDEOGEN] + + +@pytest.mark.unit +def test_videogen_adapter_loadable(): + path = ADAPTER_MAP[APIType.VIDEOGEN] + module_path, class_name = path.rsplit(".", 1) + mod = import_module(module_path) + cls = getattr(mod, class_name) + assert cls is not None + + +@pytest.mark.unit +def test_videogen_accumulator_loadable(): + path = ACCUMULATOR_MAP[APIType.VIDEOGEN] + module_path, class_name = path.rsplit(".", 1) + mod = import_module(module_path) + cls = getattr(mod, class_name) + assert cls is not None diff --git a/tests/unit/videogen/test_types.py b/tests/unit/videogen/test_types.py new file mode 100644 index 00000000..f70aa82d --- /dev/null +++ b/tests/unit/videogen/test_types.py @@ -0,0 +1,102 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Unit tests for videogen Pydantic wire models (trtllm-serve native API).""" + +import pytest +from inference_endpoint.videogen.types import ( + VideoPathRequest, + VideoPathResponse, + VideoPayloadResponse, +) +from pydantic import ValidationError + + +class TestVideoPathRequest: + @pytest.mark.unit + def test_defaults(self): + req = VideoPathRequest(prompt="a cat") + assert req.negative_prompt is None + assert req.latent_path is None + assert req.size == "720x1280" + assert req.seconds == pytest.approx(5.0) + assert req.fps == 16 + assert req.num_inference_steps == 20 + assert req.guidance_scale == pytest.approx(4.0) + assert req.guidance_scale_2 == pytest.approx(3.0) + assert req.seed == 42 + assert req.output_format == "auto" + assert req.response_format == "video_path" + + @pytest.mark.unit + def test_custom_values(self): + req = VideoPathRequest( + prompt="ocean waves", + seed=99, + fps=24, + size="640x480", + guidance_scale=6.0, + num_inference_steps=50, + ) + assert req.seed == 99 + assert req.fps == 24 + assert req.size == "640x480" + assert req.guidance_scale == pytest.approx(6.0) + assert req.num_inference_steps == 50 + + @pytest.mark.unit + def test_response_format_video_bytes(self): + req = VideoPathRequest(prompt="test", response_format="video_bytes") + assert req.response_format == "video_bytes" + + @pytest.mark.unit + def test_invalid_output_format_rejected(self): + with pytest.raises(ValidationError): + VideoPathRequest(prompt="test", output_format="invalid") + + @pytest.mark.unit + def test_invalid_response_format_rejected(self): + with pytest.raises(ValidationError): + VideoPathRequest(prompt="test", response_format="invalid") + + +class TestVideoPathResponse: + @pytest.mark.unit + def test_basic(self): + resp = VideoPathResponse(video_id="vid_001", video_path="/lustre/vid_001.mp4") + assert resp.video_id == "vid_001" + assert resp.video_path == "/lustre/vid_001.mp4" + + @pytest.mark.unit + def test_roundtrip_json(self): + resp = VideoPathResponse(video_id="vid_abc", video_path="/data/vid_abc.mp4") + restored = VideoPathResponse.model_validate_json(resp.model_dump_json()) + assert restored.video_id == resp.video_id + assert restored.video_path == resp.video_path + + +class TestVideoPayloadResponse: + @pytest.mark.unit + def test_basic(self): + resp = VideoPayloadResponse(video_id="vid_001", video_bytes="AAEC") + assert resp.video_id == "vid_001" + assert resp.video_bytes == "AAEC" + + @pytest.mark.unit + def test_roundtrip_json(self): + resp = VideoPayloadResponse(video_id="vid_abc", video_bytes="dGVzdA==") + restored = VideoPayloadResponse.model_validate_json(resp.model_dump_json()) + assert restored.video_id == resp.video_id + assert restored.video_bytes == resp.video_bytes diff --git a/uv.lock b/uv.lock index ed84bd7e..9017350e 100644 --- a/uv.lock +++ b/uv.lock @@ -877,7 +877,7 @@ requires-dist = [ { name = "sphinx-autodoc-typehints", marker = "extra == 'dev'", specifier = "==3.9.11" }, { name = "sphinx-rtd-theme", marker = "extra == 'dev'", specifier = "==3.1.0" }, { name = "sqlalchemy", marker = "extra == 'sql'", specifier = "==2.0.48" }, - { name = "transformers", specifier = "==5.4.0" }, + { name = "transformers", specifier = "==5.5.0" }, { name = "typing-extensions", specifier = "==4.15.0" }, { name = "uvloop", specifier = "==0.22.1" }, { name = "websocket-client", specifier = "==1.9.0" }, @@ -2403,7 +2403,7 @@ wheels = [ [[package]] name = "transformers" -version = "5.4.0" +version = "5.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "huggingface-hub", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'x86_64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, @@ -2416,9 +2416,9 @@ dependencies = [ { name = "tqdm", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'x86_64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "typer", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'x86_64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0b/4c/42a8e1c7bbe668d8e073941ec3205263afb1cd02683fa5a8a75e615fdfbe/transformers-5.4.0.tar.gz", hash = "sha256:cb34ca89dce345ae3224b290346b9c0fa9694b951d54f3ed16334a4b1bfe3d04", size = 8152836, upload-time = "2026-03-27T00:24:24.692Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ff/9d/fb46e729b461985f41a5740167688b924a4019141e5c164bea77548d3d9e/transformers-5.5.0.tar.gz", hash = "sha256:c8db656cf51c600cd8c75f06b20ef85c72e8b8ff9abc880c5d3e8bc70e0ddcbd", size = 8237745, upload-time = "2026-04-02T16:13:08.113Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0b/a0/0a87883e564e364baab32adcacb4bec2e200b28a568423c8cf7fde316461/transformers-5.4.0-py3-none-any.whl", hash = "sha256:9fbe50602d2a4e6d0aa8a35a605433dfac72d595ee2192eae192590a6cc2df86", size = 10105556, upload-time = "2026-03-27T00:24:21.735Z" }, + { url = "https://files.pythonhosted.org/packages/e7/28/35f7411ff80a3640c1f4fc907dcbb6a65061ebb82f66950e38bfc9f7f740/transformers-5.5.0-py3-none-any.whl", hash = "sha256:821a9ff0961abbb29eb1eb686d78df1c85929fdf213a3fe49dc6bd94f9efa944", size = 10245591, upload-time = "2026-04-02T16:13:03.462Z" }, ] [[package]]