Skip to content

[feat] [4/n] Improve API: refactor sampling param and merge with presets#1234

Merged
SolitaryThinker merged 8 commits intomainfrom
will/api_4
Apr 16, 2026
Merged

[feat] [4/n] Improve API: refactor sampling param and merge with presets#1234
SolitaryThinker merged 8 commits intomainfrom
will/api_4

Conversation

@SolitaryThinker
Copy link
Copy Markdown
Collaborator

Purpose

PR 4 of the API improvement series. Introduces a profile registry — named inference presets that replace the 20+
SamplingParam subclasses scattered across fastvideo/configs/sample/ — and moves the canonical SamplingParam to
fastvideo/api/sampling_param.py.

Continues from #1226 (PR 3), #1220 (PR 2), #1218 (PR 1).

Changes

  • Profile registry (fastvideo/api/profiles.py): PipelineProfile / ProfileStageSpec frozen dataclasses,
    register_profile() / get_profile() with typed validation of stage overrides
  • 13 profile definition files (fastvideo/pipelines/basic//profiles.py): one per model family (wan, ltx2,
    hunyuan, hunyuan15, hyworld, gamecraft, lingbotworld, longcat, matrixgame, gen3c, cosmos, sd35, turbodiffusion) —
    37 profiles total
  • SamplingParam moved from configs/sample/base.py to fastvideo/api/sampling_param.py; model-specific fields (LTX2,
    HYWorld, GameCraft, GEN3C, LongCat) promoted to the base class; from_pretrained() → _from_profile() chain for
    profile-based defaults
  • Registry updated (fastvideo/registry.py): all register_configs calls now use sampling_param_cls=None +
    model_family + default_profile; added _register_profiles(), get_model_family(), get_default_profile()
  • Deleted 12 subclass files (configs/sample/{wan,ltx2,hunyuan,hunyuan15,hyworld,hunyuangamecraft,lingbotworld,gen3c
    ,cosmos,cosmos2_5,sd35,turbodiffusion}.py); configs/sample/{base,init}.py are backward-compatible re-export
    shims
  • Bug fixes: copy.deepcopy for mutable profile defaults (prevents shared state between instances), narrowed bare
    except Exception to (ValueError, RuntimeError), numeric-aware version sorting
  • 48 import sites updated across examples, training, tests, entrypoints
  • 551-line test suite (fastvideo/tests/api/test_profiles.py) + updated SSIM tests and LTX2 registry tests

Checklist

  • I ran pre-commit run --all-files and fixed all issues
  • I added or updated tests for my changes
  • I updated documentation if needed
  • I considered GPU memory impact of my changes

For model/pipeline changes, also check:

  • I verified SSIM regression tests pass
  • I updated the support matrix if adding a new model

- Add fastvideo/api/profiles.py with PipelineProfile, ProfileStageSpec,
  and profile registry (register/get/validate)
- Add pipeline-local profiles for all model families under
  fastvideo/pipelines/basic/*/profiles.py
- Migrate Wan family: remove 14 SamplingParam subclasses, use
  default_profile in registry, profiles provide all defaults
- Add _from_profile() to SamplingParam.from_pretrained() for
  profile-based default resolution
- Add default_profile and model_family to ConfigInfo in registry
- Add guidance_scale_2 to base SamplingParam
- Break LingBotWorld cross-family inheritance
- Update SSIM tests to use SamplingParam.from_pretrained()
- Add comprehensive profile tests (test_profiles.py)
…m defaults

Delete 12 SamplingParam subclass files (LTX2, Hunyuan, Hunyuan15,
HYWorld, GameCraft, LingBotWorld, MatrixGame, GEN3C, Cosmos, Cosmos25,
SD35, TurboDiffusion) and replace them with profile-based defaults.

Each family's register_configs now sets sampling_param_cls=None and
default_profile="<name>", so SamplingParam.from_pretrained() resolves
defaults from the pipeline profile instead of subclass fields.

Model-specific fields (LTX2 multi-modal CFG/STG, HYWorld attention
masks, GameCraft camera/action control) promoted to base SamplingParam.
LongCat entries also get default_profile for completeness.
Canonical location for SamplingParam is now fastvideo.api.sampling_param.
All 48 import sites updated. Old configs/sample/base.py and __init__.py
kept as backward-compatible re-export shims.
…swallowing, version sort

- deepcopy profile defaults to prevent shared mutable list references
  between SamplingParam instances (e.g. ltx2_stg_blocks_video, sigmas)
- narrow bare except Exception to (ValueError, RuntimeError) in
  _from_profile() so real errors aren't silently swallowed
- use numeric-aware version sorting in get_profile() to handle
  multi-segment versions correctly (e.g. "2" > "10" string sort bug)
- remove dead get_sampling_param_cls_for_name fallback from
  from_pretrained() since all sampling_param_cls are now None
- update test_ltx2_registry.py for profile-based behavior
Delete the backward-compatible re-export shims in configs/sample/ and
update all docs, tests, and CI config to point to the canonical location
at fastvideo/api/sampling_param.py.
@mergify mergify Bot added scope: training Training pipeline, methods, configs scope: inference Inference pipeline, serving, CLI scope: data Data preprocessing, datasets scope: infra CI, tests, Docker, build scope: docs Documentation labels Apr 16, 2026
@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented Apr 16, 2026

⚠️ PR title format required

Your PR title must start with a type tag in brackets. Examples:

  • [feat] Add new model support
  • [bugfix] Fix VAE tiling corruption
  • [refactor] Restructure training pipeline
  • [perf] Optimize attention kernel
  • [ci] Update test infrastructure
  • [docs] Add inference guide
  • [misc] Clean up configs
  • [new-model] Port Flux2 to FastVideo

Valid tags: feat, feature, bugfix, fix, refactor, perf, ci, doc, docs, misc, chore, kernel, new-model

Please update your PR title and the merge protection check will pass automatically.

@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented Apr 16, 2026

Merge Protections

Your pull request matches the following merge protections and will not be merged until they are valid.

🔴 PR merge requirements

Waiting for:

  • #approved-reviews-by>=1
  • check-success=fastcheck-passed
  • check-success=full-suite-passed
This rule is failing.
  • #approved-reviews-by>=1
  • check-success=fastcheck-passed
  • check-success=full-suite-passed
  • check-success~=pre-commit
  • title~=(?i)^\[(feat|feature|bugfix|fix|refactor|perf|ci|doc|docs|misc|chore|kernel|new.?model)\]

🟢 📃 Configuration Change Requirements

Wonderful, this rule succeeded.

Mergify configuration change

  • check-success = Configuration changed

@SolitaryThinker SolitaryThinker changed the title [dont merge] Improve API: refactor sampling param and merge with profiles [feat] [dont merge] Improve API: refactor sampling param and merge with profiles Apr 16, 2026
@mergify mergify Bot added the type: feat New feature or capability label Apr 16, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a centralized pipeline profile registry to manage inference presets and stage-based validation across model families, effectively replacing the legacy system of multiple SamplingParam subclasses. Key additions include the profile management system in fastvideo/api/profiles.py and the relocation of SamplingParam to fastvideo/api/sampling_param.py with integrated profile support. Review feedback highlights the need for more robust attribute validation in SamplingParam to prevent overwriting methods via hasattr, the correction of logger.exception usage, and a potential TypeError in the version sorting logic within the profile registry.

Comment thread fastvideo/api/sampling_param.py Outdated
Comment thread fastvideo/api/sampling_param.py Outdated
Comment thread fastvideo/api/profiles.py Outdated
@SolitaryThinker
Copy link
Copy Markdown
Collaborator Author

/test full

…tage_schemas (#1234)

Address PR #1234 review feedback.

Rename the profile registry to "preset" throughout:
- PipelineProfile → InferencePreset, ProfileStageSpec → PresetStageSpec
- fastvideo/api/profiles.py → presets.py; 13 pipeline profiles.py → presets.py
- Registry API, ConfigInfo.default_profile, PipelineSelection fields renamed

Simplify version: str → int; drop the _version_key helper (every
registered version is "1", plain int comparison suffices).

Rename InferencePreset.stages → stage_schemas to clarify it is
validation metadata; the real execution DAG lives in each pipeline's
create_pipeline_stages().

Misc review fixes:
- logger.exception → logger.warning in SamplingParam.update()
- Collapse double config lookup via get_preset_selection()
- Fix "image-to-prompt" typo on wan_fun_1_3b_inp
- Loosen test_total_profile_count (== 37 → >= 37)
- Revert CRLF whitespace churn in test_lingbot_similarity.py
- Remove unused _clear_registry
SolitaryThinker added a commit that referenced this pull request Apr 16, 2026
…tage_schemas (#1234)

Address PR #1234 review feedback.

Rename the profile registry to "preset" throughout:
- PipelineProfile → InferencePreset, ProfileStageSpec → PresetStageSpec
- fastvideo/api/profiles.py → presets.py; 13 pipeline profiles.py → presets.py
- Registry API, ConfigInfo.default_profile, PipelineSelection fields renamed

Simplify version: str → int; drop the _version_key helper (every
registered version is "1", plain int comparison suffices).

Rename InferencePreset.stages → stage_schemas to clarify it is
validation metadata; the real execution DAG lives in each pipeline's
create_pipeline_stages().

Misc review fixes:
- logger.exception → logger.warning in SamplingParam.update()
- Collapse double config lookup via get_preset_selection()
- Fix "image-to-prompt" typo on wan_fun_1_3b_inp
- Loosen test_total_profile_count (== 37 → >= 37)
- Revert CRLF whitespace churn in test_lingbot_similarity.py
- Remove unused _clear_registry

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ields (#1234)

hasattr-based validation let callers overwrite methods (e.g. update
itself) or other non-field attributes. Switch update() and
_from_preset() to check dataclasses.fields instead, and use
logger.error with a clearer "has no field" message on unknown keys.
SolitaryThinker added a commit that referenced this pull request Apr 16, 2026
…ields (#1234)

hasattr-based validation let callers overwrite methods (e.g. update
itself) or other non-field attributes. Switch update() and
_from_preset() to check dataclasses.fields instead, and use
logger.error with a clearer "has no field" message on unknown keys.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@SolitaryThinker
Copy link
Copy Markdown
Collaborator Author

/merge

@github-actions github-actions Bot added the ready PR is ready to merge label Apr 16, 2026
@SolitaryThinker SolitaryThinker changed the title [feat] [dont merge] Improve API: refactor sampling param and merge with profiles [feat] [4/n] Improve API: refactor sampling param and merge with profiles Apr 16, 2026
@SolitaryThinker SolitaryThinker changed the title [feat] [4/n] Improve API: refactor sampling param and merge with profiles [feat] [4/n] Improve API: refactor sampling param and merge with presets Apr 16, 2026
@SolitaryThinker SolitaryThinker merged commit 145a3f1 into main Apr 16, 2026
14 of 20 checks passed
@SolitaryThinker SolitaryThinker deleted the will/api_4 branch April 16, 2026 21:10
SolitaryThinker added a commit that referenced this pull request Apr 22, 2026
PR 4 (#1234) moved SamplingParam defaults into preset.defaults dicts.
Four entries (matrixgame × 1, turbodiffusion × 3) set
'negative_prompt': None, which overrides SamplingParam.negative_prompt
(typed str) with None. When the CFG branch in text_encoding.py:81
runs, 'assert isinstance(batch.negative_prompt, str)' crashes.

Concrete repro: the TurboWan2.2-I2V-A14B-Diffusers SSIM test on Modal
L40S fails with AssertionError at text_encoding.py:81 before any
generation happens. CFG is entered despite guidance_scale=1.0 because
of a separate bug — LTX-2-specific class defaults on shared
SamplingParam (ltx2_cfg_scale_video=3.0, ltx2_cfg_scale_audio=7.0)
force do_classifier_free_guidance=True in ForwardBatch.__post_init__
for any non-LTX2 model that doesn't explicitly override them. That
deeper issue is tracked in PR plan.md § 'LTX2-specific defaults leak
onto shared SamplingParam' — this commit only fixes the type-contract
violation that surfaces it.

Fix: change 'negative_prompt': None -> 'negative_prompt': ''.
Runtime-equivalent (both mean 'no negative prompt') but keeps the str
invariant so the CFG branch no longer crashes.

Regression guard: new test_presets.py::TestPresetDefaultTypes asserts
no preset sets negative_prompt=None across all registered presets.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready PR is ready to merge scope: data Data preprocessing, datasets scope: docs Documentation scope: inference Inference pipeline, serving, CLI scope: infra CI, tests, Docker, build scope: training Training pipeline, methods, configs type: feat New feature or capability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant