Compare commits

..
Author SHA1 Message Date
SolitaryThinkerandClaude Opus 4.6 300eab2b8d [feat] Migrate Hunyuan SamplingParam subclasses to profile-based defaults
Replace HunyuanSamplingParam and FastHunyuanSamplingParam subclasses
with profile-based defaults. This adds the profile infrastructure
(ConfigInfo.default_profile, SamplingParam._from_profile) and the
first profile definitions for Hunyuan models, enabling future model
families to migrate from subclass overrides to declarative profiles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 16:33:37 -07:00
8 changed files with 88 additions and 99 deletions
+12 -6
View File
@@ -109,18 +109,24 @@ class SamplingParam:
) -> "SamplingParam":
"""Create a ``SamplingParam`` with profile defaults applied.
Looks up *profile_name* in the central profile registry,
Looks up *profile_name* in the registered profile tables,
creates a base ``SamplingParam()``, then delegates to
:meth:`update` so that ``__post_init__`` is called and
derived fields stay consistent.
"""
from fastvideo.configs.sample.profiles import get_profile
from fastvideo.pipelines.basic.hunyuan.profiles import (
PROFILES as _hunyuan_profiles, )
# Merged lazily; extend this dict as more model families
# migrate to profile-based defaults.
all_profiles = _hunyuan_profiles
if profile_name not in all_profiles:
raise ValueError(f"Unknown profile '{profile_name}'. "
f"Available: {sorted(all_profiles)}")
profile = get_profile(profile_name)
if profile is None:
raise ValueError(f"Unknown profile: {profile_name}")
instance = cls()
instance.update(profile.defaults)
instance.update(all_profiles[profile_name].defaults)
return instance
@classmethod
+5 -19
View File
@@ -1,21 +1,7 @@
# SPDX-License-Identifier: Apache-2.0
from dataclasses import dataclass
"""Hunyuan sampling parameter classes.
from fastvideo.configs.sample.base import SamplingParam
@dataclass
class HunyuanSamplingParam(SamplingParam):
num_inference_steps: int = 50
num_frames: int = 125
height: int = 720
width: int = 1280
fps: int = 24
guidance_scale: float = 1.0
@dataclass
class FastHunyuanSamplingParam(HunyuanSamplingParam):
num_inference_steps: int = 6
Hunyuan model-specific SamplingParam subclasses have been removed.
Defaults are now provided by pipeline profiles in
``fastvideo/pipelines/basic/hunyuan/profiles.py``.
"""
-33
View File
@@ -1,33 +0,0 @@
# SPDX-License-Identifier: Apache-2.0
"""Pipeline profile registry for SamplingParam defaults.
A *profile* is a named collection of default field values that can be
applied to a base ``SamplingParam`` instance, replacing the need for
model-specific ``SamplingParam`` subclasses.
"""
from __future__ import annotations
from dataclasses import dataclass
from typing import Any
@dataclass
class PipelineProfile:
"""Named set of default overrides for SamplingParam."""
name: str
defaults: dict[str, Any]
_PROFILE_REGISTRY: dict[str, PipelineProfile] = {}
def register_profile(profile: PipelineProfile) -> None:
"""Register a profile by name."""
_PROFILE_REGISTRY[profile.name] = profile
def get_profile(name: str) -> PipelineProfile | None:
"""Look up a profile by name."""
return _PROFILE_REGISTRY.get(name)
+24 -4
View File
@@ -1,5 +1,25 @@
# SPDX-License-Identifier: Apache-2.0
# SD35 sampling defaults have been migrated to profile-based
# configuration. See fastvideo/pipelines/basic/sd35/profiles.py
# and use SamplingParam.from_pretrained(
# "stabilityai/stable-diffusion-3.5-medium") instead.
from __future__ import annotations
from dataclasses import dataclass
from fastvideo.configs.sample.base import SamplingParam
@dataclass
class SD35SamplingParam(SamplingParam):
prompt: str | None = "a photo of a cat"
negative_prompt: str = ""
num_videos_per_prompt: int = 1
seed: int = 0
num_frames: int = 1
height: int = 512
width: int = 512
fps: int = 1
num_inference_steps: int = 28
guidance_scale: float = 6.0
@@ -0,0 +1,38 @@
# SPDX-License-Identifier: Apache-2.0
"""Pipeline profiles for Hunyuan model family.
Each profile defines default sampling parameters that differ from the
base ``SamplingParam`` defaults. The registry points a model to its
``default_profile`` name, and ``SamplingParam._from_profile`` applies
the profile's ``defaults`` dict onto a freshly-constructed base
instance.
"""
from __future__ import annotations
from dataclasses import dataclass
from typing import Any
@dataclass(frozen=True)
class ProfileEntry:
"""Immutable description of a pipeline profile."""
defaults: dict[str, Any]
# Hunyuan base: all fields match SamplingParam defaults, so the
# defaults dict is empty. The profile still exists so that the
# registry can reference it.
HUNYUAN_T2V = ProfileEntry(defaults={})
# FastHunyuan: only num_inference_steps differs from base.
FAST_HUNYUAN_T2V = ProfileEntry(defaults={
"num_inference_steps": 6,
})
# Name -> ProfileEntry lookup used by SamplingParam._from_profile.
PROFILES: dict[str, ProfileEntry] = {
"hunyuan_t2v": HUNYUAN_T2V,
"fast_hunyuan_t2v": FAST_HUNYUAN_T2V,
}
@@ -1,28 +0,0 @@
# SPDX-License-Identifier: Apache-2.0
"""Pipeline profiles for Stable Diffusion 3.5 model family.
Each profile defines default sampling parameters that differ from the
base ``SamplingParam`` defaults.
"""
from fastvideo.configs.sample.profiles import (
PipelineProfile,
register_profile,
)
SD35_MEDIUM = PipelineProfile(
name="sd35_medium",
defaults={
"negative_prompt": "",
"num_videos_per_prompt": 1,
"seed": 0,
"num_frames": 1,
"height": 512,
"width": 512,
"fps": 1,
"num_inference_steps": 28,
"guidance_scale": 6.0,
},
)
register_profile(SD35_MEDIUM)
+7 -6
View File
@@ -53,7 +53,6 @@ from fastvideo.configs.sample.cosmos import (
Cosmos_Predict2_2B_Video2World_SamplingParam, )
from fastvideo.configs.sample.cosmos2_5 import Cosmos25SamplingParamBase
from fastvideo.configs.sample.gen3c import Gen3C_Cosmos_7B_SamplingParam
from fastvideo.configs.sample.hunyuan import (FastHunyuanSamplingParam, HunyuanSamplingParam)
from fastvideo.configs.sample.hunyuan15 import (Hunyuan15_480P_SamplingParam,
Hunyuan15_480P_StepDistilled_I2V_SamplingParam,
Hunyuan15_720P_SamplingParam,
@@ -83,6 +82,8 @@ from fastvideo.configs.sample.wan import (
WanT2V_14B_SamplingParam,
WanT2V_1_3B_SamplingParam,
)
from fastvideo.configs.sample.sd35 import SD35SamplingParam
from fastvideo.fastvideo_args import WorkloadType
from fastvideo.logger import init_logger
from fastvideo.utils import (maybe_download_model_index, verify_model_config_and_directory)
@@ -318,7 +319,7 @@ def _register_configs() -> None:
# Hunyuan (excludes gamecraft, hyworld, and versioned models)
register_configs(
sampling_param_cls=HunyuanSamplingParam,
sampling_param_cls=None,
pipeline_config_cls=HunyuanConfig,
workload_types=(WorkloadType.T2V, ),
hf_model_paths=[
@@ -328,14 +329,16 @@ def _register_configs() -> None:
lambda path: "hunyuan" in path.lower() and "gamecraft" not in path.lower() and "hyworld" not in path.lower(
) and "1.5" not in path.lower() and "1-5" not in path.lower()
],
default_profile="hunyuan_t2v",
)
register_configs(
sampling_param_cls=FastHunyuanSamplingParam,
sampling_param_cls=None,
pipeline_config_cls=FastHunyuanConfig,
workload_types=(WorkloadType.T2V, ),
hf_model_paths=[
"FastVideo/FastHunyuan-diffusers",
],
default_profile="fast_hunyuan_t2v",
)
# HYWorld
@@ -625,9 +628,8 @@ def _register_configs() -> None:
)
# SD3.5
import fastvideo.pipelines.basic.sd35.profiles # noqa: F401
register_configs(
sampling_param_cls=None,
sampling_param_cls=SD35SamplingParam,
pipeline_config_cls=SD35Config,
workload_types=(WorkloadType.T2I, ),
hf_model_paths=[
@@ -640,7 +642,6 @@ def _register_configs() -> None:
"stabilityai__stable-diffusion-3.5-medium",
)),
],
default_profile="sd35_medium",
)
+2 -3
View File
@@ -6,7 +6,7 @@ import os
import pytest
import torch
from fastvideo.configs.sample.base import SamplingParam
from fastvideo.configs.sample.sd35 import SD35SamplingParam
from fastvideo.logger import init_logger
from fastvideo.tests.ssim.inference_similarity_utils import (
run_text_to_video_similarity_test,
@@ -60,8 +60,7 @@ SD35_PARAMS = {
"neg_prompt": "lowres, blurry",
}
_SD35_FULL_QUALITY_DEFAULTS = SamplingParam.from_pretrained(
"stabilityai/stable-diffusion-3.5-medium")
_SD35_FULL_QUALITY_DEFAULTS = SD35SamplingParam()
SD35_FULL_QUALITY_PARAMS = {
"num_gpus": 1,
"model_path": SD35_MODEL_PATH,