Files
SolitaryThinker cb46d63f07 [bugfix]: unset GenerationRequest fields inherit model presets
Directly-constructed GenerationRequests marked every schema default as
explicit (normalize_generation_request bound the full serialization when
_fastvideo_explicit_paths was absent), so request_to_sampling_param
overwrote model preset values with schema defaults: FastWan DMD ran
3->50 steps, TurboDiffusion 4->50, stable-audio 100 steps/CFG7 ->
50/CFG1, and 1.3B Wan examples rendered 720x1280x125f with CFG off.

Fix at the root: SamplingConfig fields now default to None = "inherit
the model preset". None leaves are never bound as explicit paths — for
directly-constructed requests (normalize_generation_request) and for
parsed YAML/JSON (parse_config treats explicit null as unset, so
widening the types cannot let nulls stomp presets either). Dicts
emptied by the pruning are dropped too, so None-valued extensions
cannot resurface via the live-attribute read in
explicit_request_updates. The _SCHEMA_DEFAULT_UPDATES tolerance hack is
deleted (an explicitly-set field unsupported by a model's SamplingParam
now always fails loudly), and return_state is skipped in the update
loop since it is already translated to return_continuation_state.

Consumers of raw (pre-resolution) sampling fields are guarded: the
streaming server validates operator-pinned default_request.sampling
before the multi-minute model boot (run_server) and in build_app; its
segment negative_prompt merge preserves an explicit "" clear; the mock
server supplies concrete fallbacks; generate_async resolves the preset
so its advertised total_steps matches the actual run; the ray-serve
gradio demo passes "" to keep its no-negative-prompt default. Stale
schema-default claims in video_api/ServeConfig/openai.md docs updated.

Tests: test_preset_inheritance.py locks the contract (bare request
inherits preset; partial override; explicit value equal to an old
schema default wins; negative_prompt None-inherits/""-clears; parsed
nulls inherit; None-valued extensions are dropped; unsupported explicit
field raises) plus a build_app pin-validation test.
2026-07-11 03:26:33 -07:00

43 lines
1.3 KiB
Python

# SPDX-License-Identifier: Apache-2.0
from fastvideo.api import (
GenerationRequest,
GeneratorConfig,
RunConfig,
SamplingConfig,
ServeConfig,
config_to_dict,
)
def test_run_config_roundtrip_preserves_nested_defaults() -> None:
config = RunConfig(
generator=GeneratorConfig(model_path="hf://model"),
request=GenerationRequest(
prompt="hello",
sampling=SamplingConfig(num_frames=48, width=832, height=480),
),
)
dumped = config_to_dict(config)
assert dumped["generator"]["model_path"] == "hf://model"
assert dumped["generator"]["engine"]["execution_backend"] == "mp"
assert dumped["request"]["sampling"]["num_frames"] == 48
assert dumped["request"]["sampling"]["guidance_scale_2"] is None
assert dumped["request"]["output"]["save_video"] is True
def test_serve_config_includes_server_and_default_request_defaults() -> None:
config = ServeConfig(generator=GeneratorConfig(model_path="/models/ltx2"))
dumped = config_to_dict(config)
assert dumped["server"] == {
"host": "0.0.0.0",
"port": 8000,
"output_dir": "outputs/",
}
# Sampling fields default to None = "inherit the model preset".
assert dumped["default_request"]["sampling"]["fps"] is None
assert dumped["default_request"]["runtime"]["enable_teacache"] is False