Skip to content

[Bug] MiniMax-H3 DiT: MLP fc1 output exceeds Vulkan's 4 GiB buffer limit above 37,449 tokens; the MLP of every layer falls back to CPU #2242

Closed

Description

@yufei-pan

Git commit

e41fbcf (release master-1015). MiniMaxH3::MLP is unchanged on the latest release, master-1024-77b72a2.

Operating System & Version

Arch Linux, kernel 7.2.11, Mesa 26.2.5 (RADV)

GGML backends

Vulkan (AMD Radeon AI PRO R9700, gfx1201, 32 GB; matrix cores: KHR_coopmat)

RADV limits on this device: maxStorageBufferRange = 4294967295, maxMemoryAllocationSize = maxBufferSize = 0xfffffffc.

Command-line arguments used

sd-cli -M vid_gen --diffusion-model minimax_h3_fl2va_pruned-Q8_0.gguf \
  --vae minimax_h3_video_vae_fp16.safetensors --audio-vae minimax_h3_audio_vae_fp32.safetensors \
  --llm qwen3vl_32b_minimax_h3-Q4_K_M.gguf --init-img a.png --end-img b.png -p "..." \
  --cfg-scale 1 -W 1024 -H 768 --rng cpu --fps 24 --video-frames 158 --steps 4 --flow-shift 12 \
  --backend te=cpu --mmap --auto-fit off --max-vram 22.5 --flash-attn off,diffusion=on -v

(with the turbo-4 LoRA in the prompt)

Steps to reproduce

Render FL2V at 1024x768 with 141 frames, then with 158 frames. Nothing else changes.

What you expected to happen

Step time grows smoothly with the frame count, and the DiT stays on the GPU.

What actually happened

frames latent DiT compute buffer step time
141 64x48x42 16,362 MB VRAM 182 s (241 s step 1)
158 64x48x47 10,256 MB VRAM + 9,687 MB RAM on CPU 1,053 s (step 1)
158, --max-vram 30 64x48x47 identical split 943 s (step 1)
175 and up CPU buffer keeps growing process OOM-killed at a 10 GB RAM cap

Cause: in MiniMaxH3::MLP::forward, the fc1 output is [2*ffn, N] F32 = 2 × 14336 × 4 = 114,688 bytes per token. It passes 0xfffffffc once the packed sequence is longer than 37,449 tokens.

  • 141 frames: 42 × 768 video tokens + 235 audio + keyframes and text. Under the limit.
  • 158 frames: 47 × 768 + 263 audio + 2 × 768 keyframe latents = 37,895 before text. Over the limit.

ggml_backend_vk_device_supports_op rejects any op whose src or dst is larger than max_buffer_size, so the scheduler runs fc1, the chunk views, silu, mul and fc2 of all 50 layers on the CPU. --max-vram has no effect on this. RADV can't allocate a single buffer above maxBufferSize, so the backend can't hold this tensor at all.

Suggested fix

Chunk the MLP along the token axis. It works per token, so this is exact. When N * 2 * ffn * sizeof(float) would exceed the backend's max buffer size (ggml_backend_buft_get_max_size), run fc1 → SwiGLU → fc2 on slices of x and concatenate. This is the same class of problem as #1986, where materialized attention hit the 4 GiB limit; it was fixed in the graph.

Minimal repro (not run in this exact form)

T2V needs no keyframes. At 1024x768, --video-frames 175 --steps 1 gives 52 × 768 + 292 = 40,228 tokens, which crosses the limit regardless of prompt length. Then look for minimax_h3 compute buffer size: ... MB(RAM) on CPU in the -v log. 141 frames shows no CPU buffer.

Activity

  1. leejet commented on Nov 1, 2026

    @leejet
    Owner

    Fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions