Skip to content

Fail with a message when MiniMax-H3 is run in img_gen mode - #1863

Open
danielhanchen wants to merge 1 commit into
leejet:masterfrom
unslothai:up/h3-img-gen-guard
Open

Fail with a message when MiniMax-H3 is run in img_gen mode#1863
danielhanchen wants to merge 1 commit into
leejet:masterfrom
unslothai:up/h3-img-gen-guard

Conversation

@danielhanchen

Copy link
Copy Markdown

MiniMax-H3 is video-only. Its denoiser always splits the packed latent into a video half and an audio half, and only `generate_video` computes the audio length, so an H3 checkpoint that reaches `generate_image` is guaranteed to die on `GGML_ASSERT(!audio_input_cache.empty())`.

That happens whenever `--mode vid_gen` is left off, which is easy to do because it is the one flag not implied by passing `--audio-vae`. The failure arrives after the several minutes it takes to load the weights, as a core dump with a raw ggml assert and a stack trace, and nothing in the output points at the missing flag.

Before, on a q4_K H3 denoiser with the Qwen3-VL encoder and both VAEs, no `--mode`:

src/model/diffusion/minimax_h3.hpp:1040: GGML_ASSERT(!audio_input_cache.empty()) failed
...15 frames of stack trace...
Aborted (core dumped)   rc=134

After, same command:

[ERROR] stable-diffusion.cpp:5595 - MiniMax-H3 is a video model and cannot be run in img_gen mode; use --mode vid_gen
[ERROR] main.cpp:952  - generate failed
rc=1

The AnimateDiff path routes `vid_gen` back through `generate_image`, but that is SD1.5 plus a motion module and never H3, so the guard cannot fire there.

H3 is video-only: the denoiser always splits the packed latent into a video and
an audio half, and only generate_video computes the audio length. Reaching
generate_image with an H3 checkpoint therefore hits
GGML_ASSERT(!audio_input_cache.empty()) and core dumps, after the minutes it
takes to load the weights and with nothing in the output naming the cause.
Forgetting --mode vid_gen is easy since it is the one flag not implied by
passing --audio-vae.

Before: SIGABRT, exit 134, a ggml assert and a stack trace.
After:  "MiniMax-H3 is a video model and cannot be run in img_gen mode; use
        --mode vid_gen", exit 1.

The AnimateDiff branch routes vid_gen back through generate_image, but that is
SD1.5 plus a motion module and never H3, so the guard cannot fire there.
danielhanchen added a commit to unslothai/stable-diffusion.cpp that referenced this pull request Aug 8, 2026
The prebuilt pipeline builds leejet's source at an aged release tag, not this
fork's master, so the three MiniMax-H3 fixes on master reach nobody: every
Studio user installs a binary that still aborts on the default cfg-scale, still
aborts on --vae-on-cpu, and still quantizes H3's 1-D norms into an output
uncorrelated with its own bf16 reference.

Building from master instead would throw away the reason the pipeline is shaped
this way, which is that what we publish should be traceable to a specific
upstream release. So keep the upstream tag as the base and carry the delta
explicitly:

- patches/ holds one file per fix, each with its upstream pull request in the
  header. All three are open on leejet: leejet#1861, leejet#1862, leejet#1863.
- resolve applies them to the checked-out tag, after running git apply --check
  over the whole set so a stale patch stops the run before the tree is half
  modified. That failure is the signal to delete the patch (upstream merged it)
  or refresh it (upstream moved the code).
- a non-empty set moves the published tag to <upstream tag>-u<id>, where id is
  the sha256 prefix of the concatenated patches. The tag then says whether a box
  is stock, and a changed patch set republishes rather than matching an existing
  release and skipping.
- the manifest and the release notes both record the applied list.

An empty patches/ leaves the tag and every asset name exactly as they are today.

Verified by running the resolve step against master-813-bfbef5b with gh stubbed:
all three patches apply, the tag becomes master-813-bfbef5b-u<id>, and the
stamped source tarball contains the fixes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant