Skip to content

[feat]: Activate MagiHuman pipeline (registry + examples + SSIM) (8/8) - #1302

Open
SolitaryThinker wants to merge 1 commit into
mainfrom
will/magi-06-activate
Open

[feat]: Activate MagiHuman pipeline (registry + examples + SSIM) (8/8)#1302
SolitaryThinker wants to merge 1 commit into
mainfrom
will/magi-06-activate

Conversation

@SolitaryThinker

Copy link
Copy Markdown
Collaborator

Summary

The activation switch. After this PR merges, MagiHuman is publicly loadable:

from fastvideo import VideoGenerator
gen = VideoGenerator.from_pretrained("FastVideo/MagiHuman-Diffusers/base")
gen.generate_video(prompt="...", output_path="out.mp4", save_video=True)

Changes

File LOC Purpose
fastvideo/registry.py +153 register_configs / register_presets for all 4 variants × 2 modes (8 entrypoints)
examples/inference/basic/basic_magi_human*.py 322 (8 files) User-facing scripts, one per variant × mode
fastvideo/tests/ssim/test_magi_human_similarity.py 113 CI-eligible SSIM regression against the umbrella HF repo
.agents/memory/codebase-map/models/magi_human.md 77 (new) Codebase-map entry; first per-model entry under models/ (sets the convention)
fastvideo/pipelines/basic/magi_human/AGENTS.md (modified) Provenance section finalized with all 8 PR numbers + the will/magi source SHA

Verification

  • pre-commit run --files <changed paths> ✓ (yapf, ruff, codespell, mypy, pymarkdown all green)
  • The 8 example scripts use the same VideoGenerator.from_pretrained("FastVideo/MagiHuman-Diffusers/<variant>") pattern; no per-script duplication of pipeline wiring.
  • Base T2V mp4 hash: should be dcf5f2bf6534c7c0d91e7353e42b23db (stable across all 43 commits of the original port).
  • SSIM regression test is GPU-gated and runs on Modal CI per the existing fastvideo/tests/ssim/ workflow.

Stack context

Step 8 of 8 — the final PR in the decomposition. Stacked on:

main → #1293 (activation-trace, prereq)
       → #1294 (loader-infra, prereq)
         → #1295 (1/8 housekeeping)
           → #1296 (2/8 t5gemma)
             → #1297 (3/8 DiT)
               → #1298 (4/8 stages)
                 → #1299 (5/8 orchestrator)
                   → #1300 (6/8 provenance)
                     → #1301 (7/8 conversion)
                       → #THIS  (8/8 activate)

Once #1293 and #1294 merge to main, the entire magi stack auto-rebases. The 8 magi PRs can then squash-merge in order.

Provenance

Source PR: #1280 (will/magi @ 4e1603634d27c8e1b5c4cc5d9387f046547f5c49)

Total decomposition: 9,812 LOC in the original PR → 10 stacked PRs + 2 prerequisite PRs (PR-A activation-trace, PR-B loader-infra), each independently reviewable. After all merge: 14 of 14 parity tests bit-exact at the tip; mp4 hash preserved end-to-end.

@mergify mergify Bot added type: feat New feature or capability scope: inference Inference pipeline, serving, CLI scope: infra CI, tests, Docker, build labels May 7, 2026

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

Copy link
Copy Markdown
Contributor

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 integrates the MagiHuman model family into the FastVideo framework by registering several variants (Base, Distill, SR-540p, and SR-1080p) for text-to-AV and image-to-AV tasks. It also adds a suite of inference examples, a codebase map, and SSIM-based similarity tests. Review feedback suggested improving the robustness of model detectors in the registry by using more comprehensive keyword matching and removing redundant manual overrides in the example scripts.

Comment thread fastvideo/registry.py
Comment on lines +341 to +346
model_detectors=[
lambda path:
(("magihuman" in path.lower() or "magi_human" in path.lower() or "magi-human" in path.lower()) and
("sr_540p" in path.lower() or "sr-540p" in path.lower() or "540p_sr" in path.lower() or "srpipeline" in
path.lower()) and "1080" not in path.lower() and "ti2v" not in path.lower()),
],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The sr_540p model detector is missing the "sr540p" keyword (without underscore), which is inconsistent with the sr_1080p detector at line 309. This could cause a path like magihuman_sr540p to fail matching this detector and potentially fall through to the base model detector.

Consider using a more robust any() check to simplify the logic and ensure all common naming conventions are covered.

Suggested change
model_detectors=[
lambda path:
(("magihuman" in path.lower() or "magi_human" in path.lower() or "magi-human" in path.lower()) and
("sr_540p" in path.lower() or "sr-540p" in path.lower() or "540p_sr" in path.lower() or "srpipeline" in
path.lower()) and "1080" not in path.lower() and "ti2v" not in path.lower()),
],
model_detectors=[
lambda path:
(("magihuman" in path.lower() or "magi_human" in path.lower() or "magi-human" in path.lower()) and
any(x in path.lower() for x in ("sr_540p", "sr-540p", "540p_sr", "sr540p", "srpipeline")) and
"1080" not in path.lower() and "ti2v" not in path.lower()),
],

Comment thread fastvideo/registry.py
Comment on lines +379 to +385
model_detectors=[
lambda path:
(("magihuman" in path.lower() or "magi_human" in path.lower() or "magi-human" in path.lower()
) and "distill" not in path.lower() and "ti2v" not in path.lower() and "sr_540p" not in path.lower() and
"sr-540p" not in path.lower() and "540p_sr" not in path.lower() and "sr_1080p" not in path.lower() and
"sr-1080p" not in path.lower() and "1080p_sr" not in path.lower() and "srpipeline" not in path.lower()),
],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The base model detector uses a fragile exclusion list that is missing several keywords used by other variants (e.g., "sr1080p", "sr540p", "1080", "540"). This makes the detector prone to false positives if a user provides a path for an SR variant that doesn't exactly match the current exclusion strings.

Since the base model is essentially the "fallback" MagiHuman variant, it's safer to exclude any path containing keywords associated with specialized variants.

        model_detectors=[
            lambda path:
            (("magihuman" in path.lower() or "magi_human" in path.lower() or "magi-human" in path.lower())
             and not any(x in path.lower() for x in ("distill", "ti2v", "sr", "1080", "540"))),
        ],

Comment on lines +31 to +34
"FastVideo/MagiHuman-Diffusers/sr_1080p",
num_gpus=1,
override_pipeline_cls_name="MagiHumanSR1080pPipeline",
pipeline_config=MagiHumanSR1080pConfig(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The manual overrides for override_pipeline_cls_name and pipeline_config appear to be redundant here. Since the model path "FastVideo/MagiHuman-Diffusers/sr_1080p" is correctly registered in fastvideo/registry.py (line 304) with the appropriate config and pipeline class, VideoGenerator.from_pretrained should be able to resolve these automatically, matching the cleaner pattern used in the sr_540p example.

Suggested change
"FastVideo/MagiHuman-Diffusers/sr_1080p",
num_gpus=1,
override_pipeline_cls_name="MagiHumanSR1080pPipeline",
pipeline_config=MagiHumanSR1080pConfig(),
"FastVideo/MagiHuman-Diffusers/sr_1080p",
num_gpus=1,

@SolitaryThinker
SolitaryThinker force-pushed the will/magi-05-conversion branch from 547fcd9 to 06077ec Compare May 12, 2026 22:42
Base automatically changed from will/magi-05-conversion to main May 12, 2026 22:45
@mergify mergify Bot added scope: docs Documentation scope: model Model architecture (DiTs, encoders, VAEs) labels May 12, 2026
@mergify

mergify Bot commented May 12, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

🔴 1 of 1 protections blocking · waiting on 👀 reviews and 🤖 CI

Protection Waiting on
🔴 PR merge requirements 👀 reviews and 🤖 CI

🔴 PR merge requirements

Waiting for

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

@mergify

mergify Bot commented May 12, 2026

Copy link
Copy Markdown
Contributor

This PR has merge conflicts with the base branch. Please rebase:

git fetch origin main
git rebase origin/main
# Resolve any conflicts, then:
git push --force-with-lease

@mergify mergify Bot added the needs-rebase PR has merge conflicts label May 12, 2026
@SolitaryThinker
SolitaryThinker force-pushed the will/magi-06-activate branch from 361cc4c to 783be66 Compare May 12, 2026 22:49
@mergify mergify Bot removed the needs-rebase PR has merge conflicts label May 12, 2026
@mergify

mergify Bot commented May 29, 2026

Copy link
Copy Markdown
Contributor

This PR has merge conflicts with the base branch. Please rebase:

git fetch origin main
git rebase origin/main
# Resolve any conflicts, then:
git push --force-with-lease

@mergify mergify Bot added the needs-rebase PR has merge conflicts label May 29, 2026
…ssion)

The activation switch. After this PR merges, MagiHuman is publicly
loadable via:

    from fastvideo import VideoGenerator
    gen = VideoGenerator.from_pretrained('FastVideo/MagiHuman-Diffusers/base')

Files:
- fastvideo/registry.py: 153 lines of register_configs/register_presets
  calls covering all 4 variants x 2 modes (8 total entrypoints).
- examples/inference/basic/basic_magi_human{_,_ti2v,_distill,_distill_ti2v,
  _sr540p,_sr540p_ti2v,_sr1080p,_sr1080p_ti2v}.py: 8 user-facing scripts.
- fastvideo/tests/ssim/test_magi_human_similarity.py: CI-eligible SSIM
  regression test against the umbrella HF repo.
- .agents/memory/codebase-map/models/magi_human.md: codebase-map entry
  (first per-model entry under the models/ subdir; sets the convention).
- fastvideo/pipelines/basic/magi_human/AGENTS.md: provenance section
  finalized with all 8 PR numbers + the will/magi source SHA.

Verification:
- Existing tests on main: should still pass (no shared component changes
  in this PR; the umbrella loader infra landed in PR-B / loader-infra).
- pre-commit run --all-files: clean.
- E2E smoke after activation: any of the 8 examples emits expected mp4
  with hash dcf5f2bf6534c7c0d91e7353e42b23db on the base T2V variant.

Magi-Stack: 8/8
@SolitaryThinker
SolitaryThinker force-pushed the will/magi-06-activate branch from 783be66 to e541061 Compare July 13, 2026 10:21
@SolitaryThinker

Copy link
Copy Markdown
Collaborator Author

Rebased onto main (783be66 -> e541061) to clear the registry.py conflict from main's flux2/matrixgame2+3 registry additions; pure union-resolve, no content changes (range-diff clean).

@mergify mergify Bot removed the needs-rebase PR has merge conflicts label Jul 13, 2026
@SolitaryThinker

Copy link
Copy Markdown
Collaborator Author

/test full

@SolitaryThinker

Copy link
Copy Markdown
Collaborator Author

I reviewed exact head e54106110e5f01153a199672eb08ce13d5a90b4a against the add-model pipeline/SSIM gates. I am requesting changes for the following blockers.

  1. [P1] The four advertised TI2V entrypoints are not registry-routable. Each canonical umbrella subfolder is registered only once, and config/preset lookup does not take workload_type. A normal FastVideo/MagiHuman-Diffusers/{base,distill,sr_540p,sr_1080p} call with workload_type="i2v" resolves to the T2V pipeline, T2V config, and T2V preset; vae_config.load_encoder remains false and the T2V reference-image hook is a no-op. The examples hide this by manually injecting an internal config and override_pipeline_cls_name, so the claimed 4 variants x 2 modes do not pass normal public dispatch. The detectors also key on ti2v while the actual entry classes use I2V, making model-index/local fallback ambiguous and order-dependent. Please make variant + workload resolution first-class and add exact registry tests for all eight combinations. Also remove GAIR/daVinci-MagiHuman from hf_model_paths: that upstream checkpoint has no root Diffusers model_index.json and requires conversion.

  2. [P1] The new SSIM test is deterministically broken after successful generation. Its 100-character prompt ends in ., VideoGenerator sanitizes that to ...smile.mp4, but run_text_to_video_similarity_test predicts ...smile..mp4. Buildkite 4351 generated the video successfully and then failed only with Video2 not found on the double-dot path. Fix the shared helper at the root by reusing fastvideo.eval.io.paths.sanitize_prompt for reference lookup and generated output naming (including the sibling image path), and add a CPU regression for terminal punctuation.

  3. [P1] The claimed joint audio-video regression checks only video frames. compute_video_ssim_torchvision cannot detect missing or corrupt audio even though the seeded reference contains AAC audio. Add a separate audio-quality assertion, or record an explicit accepted audio-regression deferral; stream presence alone would only be a minimal mux guard, not a quality gate. The current min_acceptable_ssim=0.60 is also unsupported: this run never reached a score, while neighboring video gates are 0.90-0.98. Record the corrected exact-head score and choose a justified margin.

  4. [P1] Delete .agents/memory/codebase-map/models/magi_human.md. Repository policy explicitly forbids static codebase maps under .agents; this file duplicates the package-local AGENTS.md and already drifted (it lists the DiT as lazy-loaded and says 1920x1056 while the config is 1920x1080).

Before activation, please attach non-skipped exact-head evidence that the four newly public TI2V/SR paths load and write readable joint-AV outputs. The only durable E2E evidence currently recorded is base T2V. The purported CPU preflight cannot supply this evidence: it fails constructing the DiT with ValueError: Invalid attention backend for CPU.

Nonblocking cleanup while revising: remove the broad except Exception around full-quality preset resolution (and do not advertise full-quality until that reference is seeded); update the stale SSIM seeding docstring; remove local-conversion instructions that the examples ignore (including the author-specific /raid/william5lin... path); and correct the base example's documented width from 448 to 480.

Positive evidence: all eight scripts parse/import, their explicit manual class/config pairings are internally consistent, the TI2V image asset exists, Modal discovers the intended model split, and the already-seeded default L40S reference is readable H.264 + AAC. No retry is useful until the deterministic filename bug is fixed.

@mergify

mergify Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

This PR has merge conflicts with the base branch. Please rebase:

git fetch origin main
git rebase origin/main
# Resolve any conflicts, then:
git push --force-with-lease

@mergify mergify Bot added the needs-rebase PR has merge conflicts label Aug 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-rebase PR has merge conflicts scope: docs Documentation scope: inference Inference pipeline, serving, CLI scope: infra CI, tests, Docker, build scope: model Model architecture (DiTs, encoders, VAEs) type: feat New feature or capability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant