Skip to content

Commit 1a7d4b3

Browse files
committed
[feat] first version of wan eval
1 parent bd59a68 commit 1a7d4b3

1 file changed

Lines changed: 118 additions & 0 deletions

File tree

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
"""Generate one Wan video and score it with VBench metrics.
2+
3+
This example mirrors ``examples/inference/eval/basic_ltx2_eval.py`` but uses
4+
Wan as the text-to-video generator.
5+
6+
Wan outputs are video-only by default, so this script evaluates video metrics
7+
rather than audio metrics. Audio metrics should only be used if an audio track
8+
is explicitly available or muxed into the generated mp4.
9+
10+
The first run downloads the VBench-related checkpoints to
11+
``~/.cache/fastvideo/eval/``.
12+
"""
13+
14+
from pathlib import Path
15+
16+
import torch
17+
18+
from fastvideo import VideoGenerator
19+
from fastvideo.eval import Evaluator
20+
from fastvideo.eval.io import build_eval_kwargs
21+
22+
PROMPT = (
23+
"A cinematic shot of a small dog running through a sunny park, "
24+
"with realistic motion, natural lighting, and a shallow depth of field. "
25+
"The camera follows the dog from the side as it runs across the grass."
26+
)
27+
28+
# VBench sub-metrics meaningful for an arbitrary text-to-video sample.
29+
# Structured-prompt metrics such as vbench.color, vbench.multiple_objects,
30+
# and vbench.scene are excluded because they need prompts built to a
31+
# specific schema.
32+
METRICS = [
33+
"vbench.aesthetic_quality",
34+
"vbench.subject_consistency",
35+
"vbench.background_consistency",
36+
"vbench.imaging_quality",
37+
"vbench.temporal_flickering",
38+
"vbench.motion_smoothness",
39+
"vbench.dynamic_degree",
40+
"vbench.overall_consistency",
41+
]
42+
43+
MODEL_PATH = "Wan-AI/Wan2.1-T2V-1.3B-Diffusers"
44+
OUTPUT_PATH = Path("outputs_video/wan_basic/output_wan_t2v_480_832.mp4")
45+
FPS = 16.0
46+
47+
48+
def _print_results(results) -> None:
49+
print("\n=== VBench scores ===")
50+
51+
for name in METRICS:
52+
if name not in results:
53+
print(f" {name}: MISSING")
54+
continue
55+
56+
r = results[name]
57+
58+
if r.score is None:
59+
reason = (
60+
r.details.get("skipped", "no score")
61+
if isinstance(r.details, dict)
62+
else "no score"
63+
)
64+
print(f" {name}: SKIPPED ({reason})")
65+
else:
66+
print(f" {name}: {r.score:.4f}")
67+
68+
if r.details:
69+
for key, value in r.details.items():
70+
print(f" {key}: {value}")
71+
72+
73+
def main() -> None:
74+
OUTPUT_PATH.parent.mkdir(parents=True, exist_ok=True)
75+
76+
# ----- generation -----
77+
if OUTPUT_PATH.exists():
78+
print(f"[eval] using existing video: {OUTPUT_PATH}")
79+
else:
80+
print("[eval] generating Wan video...")
81+
82+
generator = VideoGenerator.from_pretrained(
83+
MODEL_PATH,
84+
num_gpus=1,
85+
)
86+
87+
generator.generate_video(
88+
prompt=PROMPT,
89+
output_path=str(OUTPUT_PATH),
90+
save_video=True,
91+
num_frames=81,
92+
height=480,
93+
width=832,
94+
)
95+
96+
generator.shutdown()
97+
98+
# Free residual CUDA memory before building the evaluator.
99+
torch.cuda.empty_cache()
100+
101+
# ----- scoring -----
102+
print(f"\n[eval] building evaluator: {METRICS}")
103+
evaluator = Evaluator(metrics=METRICS)
104+
105+
sample = build_eval_kwargs(
106+
{"prompt": PROMPT},
107+
str(OUTPUT_PATH),
108+
fps=FPS,
109+
)
110+
111+
print(f"[eval] running ({sample['video'].shape[1]} frames @ {FPS:g} fps)...")
112+
results = evaluator.evaluate(**sample)
113+
114+
_print_results(results)
115+
116+
117+
if __name__ == "__main__":
118+
main()

0 commit comments

Comments
 (0)