Compare commits

...
Author SHA1 Message Date
SolitaryThinkerandClaude Opus 4.6 4bcaf9bef8 [feat] [4/n] Improve API: migrate GEN3C, Cosmos, and Cosmos25 to profile-based defaults
Replace SamplingParam subclasses for GEN3C, Cosmos, and Cosmos25 with
declarative ModelProfile instances.  SamplingParam.from_pretrained now
checks ConfigInfo.default_profile first and applies profile defaults
via setattr on a base SamplingParam, removing the need for per-model
subclass files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 16:40:06 -07:00
8 changed files with 144 additions and 73 deletions
+29 -4
View File
@@ -104,17 +104,42 @@ class SamplingParam:
@classmethod
def from_pretrained(cls, model_path: str) -> "SamplingParam":
from fastvideo.registry import get_sampling_param_cls_for_name
sampling_cls = get_sampling_param_cls_for_name(model_path)
from fastvideo.registry import _get_config_info
config_info = _get_config_info(
model_path,
raise_on_missing=False,
)
if config_info is not None and config_info.default_profile:
return cls._from_profile(config_info.default_profile)
sampling_cls = (config_info.sampling_param_cls if config_info is not None else None)
if sampling_cls is not None:
sampling_param: SamplingParam = sampling_cls()
else:
logger.warning("Couldn't find an optimal sampling param for %s. Using the default sampling param.",
model_path)
logger.warning(
"Couldn't find an optimal sampling param "
"for %s. Using the default sampling param.",
model_path,
)
sampling_param = cls()
return sampling_param
@classmethod
def _from_profile(cls, profile_name: str) -> "SamplingParam":
from fastvideo.configs.sample.profiles import get_profile
profile = get_profile(profile_name)
if profile is None:
raise ValueError(f"Profile {profile_name!r} not found in "
"profile registry")
instance = cls()
for key, value in profile.defaults.items():
setattr(instance, key, value)
instance.__post_init__()
return instance
@staticmethod
def add_cli_args(parser: Any) -> Any:
"""Add CLI arguments for SamplingParam fields"""
+2 -17
View File
@@ -1,18 +1,3 @@
# SPDX-License-Identifier: Apache-2.0
from dataclasses import dataclass
from fastvideo.configs.sample.base import SamplingParam
@dataclass
class Cosmos_Predict2_2B_Video2World_SamplingParam(SamplingParam):
# Video parameters
height: int = 704
width: int = 1280
num_frames: int = 93
fps: int = 16
# Denoising stage
guidance_scale: float = 7.0
negative_prompt: str = "The video captures a series of frames showing ugly scenes, static with no motion, motion blur, over-saturation, shaky footage, low resolution, grainy texture, pixelated images, poorly lit areas, underexposed and overexposed scenes, poor color balance, washed out colors, choppy sequences, jerky movements, low frame rate, artifacting, color banding, unnatural transitions, outdated special effects, fake elements, unconvincing visuals, poorly edited content, jump cuts, visual noise, and flickering. Overall, the video is of poor quality."
num_inference_steps: int = 35
# Migrated to profile-based defaults.
# See fastvideo/pipelines/basic/cosmos/profiles.py
+2 -22
View File
@@ -1,23 +1,3 @@
# SPDX-License-Identifier: Apache-2.0
from dataclasses import dataclass
from fastvideo.configs.sample.base import SamplingParam
@dataclass
class Cosmos25SamplingParamBase(SamplingParam):
height: int = 704
width: int = 1280
num_frames: int = 77
fps: int = 24
seed: int = 0
guidance_scale: float = 7.0
negative_prompt: str = (
"The video captures a series of frames showing ugly scenes, static with no motion, motion blur, "
"over-saturation, shaky footage, low resolution, grainy texture, pixelated images, poorly lit areas, "
"underexposed and overexposed scenes, poor color balance, washed out colors, choppy sequences, jerky movements, "
"low frame rate, artifacting, color banding, unnatural transitions, outdated special effects, fake elements, "
"unconvincing visuals, poorly edited content, jump cuts, visual noise, and flickering. "
"Overall, the video is of poor quality.")
num_inference_steps: int = 35
# Migrated to profile-based defaults.
# See fastvideo/pipelines/basic/cosmos/profiles.py
+2 -23
View File
@@ -1,24 +1,3 @@
# SPDX-License-Identifier: Apache-2.0
from dataclasses import dataclass
from fastvideo.configs.sample.base import SamplingParam
@dataclass
class Gen3C_Cosmos_7B_SamplingParam(SamplingParam):
"""Defaults for GEN3C (Cosmos-7B) camera-controlled video generation."""
# Video parameters (matching official GEN3C defaults)
height: int = 704
width: int = 1280
num_frames: int = 121
fps: int = 24
# Denoising stage
guidance_scale: float = 1.0
num_inference_steps: int = 35
# GEN3C camera control defaults
trajectory_type: str = "left"
movement_distance: float = 0.3
camera_rotation: str = "center_facing"
# Migrated to profile-based defaults.
# See fastvideo/pipelines/basic/gen3c/profiles.py
+33
View File
@@ -0,0 +1,33 @@
# SPDX-License-Identifier: Apache-2.0
"""
Profile-based defaults for SamplingParam.
A ModelProfile captures the recommended sampling defaults for a specific
model variant (resolution, fps, guidance scale, etc.) without requiring
a dedicated SamplingParam subclass. ``SamplingParam.from_pretrained``
resolves the profile via the registry and applies its ``defaults`` dict
with simple ``setattr`` calls on a base ``SamplingParam`` instance.
"""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any
# Global registry: profile name -> ModelProfile
_PROFILE_REGISTRY: dict[str, ModelProfile] = {}
@dataclass
class ModelProfile:
"""Declarative bag of sampling defaults for one model variant."""
name: str
defaults: dict[str, Any] = field(default_factory=dict)
def __post_init__(self) -> None:
_PROFILE_REGISTRY[self.name] = self
def get_profile(name: str) -> ModelProfile | None:
"""Look up a registered profile by name."""
return _PROFILE_REGISTRY.get(name)
@@ -0,0 +1,41 @@
# SPDX-License-Identifier: Apache-2.0
"""Sampling profiles for Cosmos and Cosmos 2.5 models."""
from fastvideo.configs.sample.profiles import ModelProfile
_COSMOS_NEGATIVE_PROMPT = ("The video captures a series of frames showing ugly scenes, "
"static with no motion, motion blur, over-saturation, "
"shaky footage, low resolution, grainy texture, "
"pixelated images, poorly lit areas, underexposed and "
"overexposed scenes, poor color balance, washed out colors, "
"choppy sequences, jerky movements, low frame rate, "
"artifacting, color banding, unnatural transitions, "
"outdated special effects, fake elements, unconvincing "
"visuals, poorly edited content, jump cuts, visual noise, "
"and flickering. Overall, the video is of poor quality.")
COSMOS_PREDICT2_2B = ModelProfile(
name="cosmos_predict2_2b",
defaults={
"height": 704,
"width": 1280,
"num_frames": 93,
"fps": 16,
"guidance_scale": 7.0,
"num_inference_steps": 35,
"negative_prompt": _COSMOS_NEGATIVE_PROMPT,
},
)
COSMOS25_PREDICT2_2B = ModelProfile(
name="cosmos25_predict2_2b",
defaults={
"height": 704,
"width": 1280,
"num_frames": 77,
"fps": 24,
"seed": 0,
"guidance_scale": 7.0,
"num_inference_steps": 35,
"negative_prompt": _COSMOS_NEGATIVE_PROMPT,
},
)
@@ -0,0 +1,18 @@
# SPDX-License-Identifier: Apache-2.0
"""Sampling profiles for GEN3C models."""
from fastvideo.configs.sample.profiles import ModelProfile
GEN3C_COSMOS_7B = ModelProfile(
name="gen3c_cosmos_7b",
defaults={
"height": 704,
"width": 1280,
"num_frames": 121,
"fps": 24,
"guidance_scale": 1.0,
"num_inference_steps": 35,
"trajectory_type": "left",
"movement_distance": 0.3,
"camera_rotation": "center_facing",
},
)
+17 -7
View File
@@ -49,10 +49,6 @@ from fastvideo.configs.pipelines.wan import (
)
from fastvideo.configs.pipelines.sd35 import SD35Config
from fastvideo.configs.sample.base import SamplingParam
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,
@@ -138,6 +134,7 @@ class ConfigInfo:
sampling_param_cls: type[SamplingParam] | None
pipeline_config_cls: type[PipelineConfig]
workload_types: tuple[WorkloadType, ...]
default_profile: str | None = None
# The central registry mapping a model name to its configuration information
@@ -156,6 +153,7 @@ def register_configs(
workload_types: tuple[WorkloadType, ...],
hf_model_paths: list[str] | None = None,
model_detectors: list[Callable[[str], bool]] | None = None,
default_profile: str | None = None,
) -> None:
"""Register config classes for a model family.
@@ -168,6 +166,7 @@ def register_configs(
sampling_param_cls=sampling_param_cls,
pipeline_config_cls=pipeline_config_cls,
workload_types=workload_types,
default_profile=default_profile,
)
if hf_model_paths:
@@ -240,6 +239,14 @@ def _get_config_info(
def _register_configs() -> None:
# Import profile modules so they self-register into the
# profile registry. Deferred to here (rather than top-level)
# so that fastvideo.registry is sufficiently initialised when
# the transitive fastvideo.pipelines.__init__ import fires.
import importlib
importlib.import_module("fastvideo.pipelines.basic.cosmos.profiles")
importlib.import_module("fastvideo.pipelines.basic.gen3c.profiles")
# LTX-2 (base)
register_configs(
sampling_param_cls=LTX2BaseSamplingParam,
@@ -430,7 +437,7 @@ def _register_configs() -> None:
# GEN3C (must register before generic Cosmos detector)
register_configs(
sampling_param_cls=Gen3C_Cosmos_7B_SamplingParam,
sampling_param_cls=None,
pipeline_config_cls=Gen3CConfig,
workload_types=(WorkloadType.T2V, ),
hf_model_paths=[
@@ -439,11 +446,12 @@ def _register_configs() -> None:
model_detectors=[
lambda path: "gen3c" in path.lower(),
],
default_profile="gen3c_cosmos_7b",
)
# Cosmos 2.5
register_configs(
sampling_param_cls=Cosmos25SamplingParamBase,
sampling_param_cls=None,
pipeline_config_cls=Cosmos25Config,
workload_types=(WorkloadType.T2V, ),
hf_model_paths=[
@@ -456,11 +464,12 @@ def _register_configs() -> None:
"cosmos2.5",
)),
],
default_profile="cosmos25_predict2_2b",
)
# Cosmos 2
register_configs(
sampling_param_cls=Cosmos_Predict2_2B_Video2World_SamplingParam,
sampling_param_cls=None,
pipeline_config_cls=CosmosConfig,
workload_types=(WorkloadType.T2V, ),
hf_model_paths=[
@@ -470,6 +479,7 @@ def _register_configs() -> None:
lambda path: "cosmos" in path.lower() and ("2.5" not in path.lower() and "2_5" not in path.lower() and "25"
not in path.lower() and "gen3c" not in path.lower()),
],
default_profile="cosmos_predict2_2b",
)
# TurboDiffusion