Skip to content

QVAC-18026: Wan video Metal support — bump ggml to IM2COL_3D + PAD branch, add test infra - #4

Closed
aegioscy wants to merge 3 commits into
masterfrom
feature/metal-im2col-3d-clean
Closed

QVAC-18026: Wan video Metal support — bump ggml to IM2COL_3D + PAD branch, add test infra#4
aegioscy wants to merge 3 commits into
masterfrom
feature/metal-im2col-3d-clean

Conversation

@aegioscy

Copy link
Copy Markdown

Summary

Enables Metal GPU acceleration for Wan2.1 / Wan2.2 video generation on Apple Silicon by bumping the ggml submodule to a patched branch that adds the two Metal ops Wan actually needs, plus the test infrastructure to exercise it from `sd-cli`.

Changes

  • Submodule bump: `ggml` → `tetherto/qvac-ext-ggml@feature/metal-pr-16669-clean`
    • Metal `IM2COL_3D` kernel (f32 + f16) — required for Wan VAE/transformer 3D convs
    • Metal `PAD` left-padding support (`lp0..lp3`) — required for Wan input preprocessing
  • `.gitmodules`: point at `tetherto/qvac-ext-ggml` so clones fetch the patched submodule
  • `.gitignore`: ignore `test-wan/output/`, `test-wan/models/`, `test-wan/cache/`
  • Test infrastructure:
    • Top-level `Makefile` wrapper with `build-metal` / `build-cuda` / `build-vulkan` targets
    • `test-wan/` directory with shell-based runner, helper functions, model download script, verification script, and docs
    • `BUILDING_WAN.md` — top-level Wan build guide

Why no Metal DIAG_MASK_INF kernel

The earlier iteration of this PR also pulled in a Metal `DIAG_MASK_INF` kernel (from CLDawes' ggml-org/llama.cpp#16669). That has been intentionally dropped from the new ggml branch because:

  1. `GGML_OP_DIAG_MASK_INF` is being deprecated upstream in favor of generic ops — see Refactor: Deprecate DIAG_MASK_* operators, migrate kernels to TRI ggml-org/llama.cpp#17654 and ggerganov's comment on Add Metal support for GGML_OP_DIAG_MASK_INF for CLIP on Apple GPUs ggml-org/ggml#1395 explicitly steering contributors away from new DIAG_MASK_INF backend kernels.
  2. refactor: unify the processing of the attention mask leejet/stable-diffusion.cpp#1230 (already in this branch's base, merged Jan 2026) refactored every CLIP / SD / MMDiT / RoPE / VAE attention site to build explicit `-INFINITY` mask tensors and removed all `diag_mask_inf=true` calls. Static check confirms zero `ggml_diag_mask_inf` call sites in app code.
  3. Wan never used it. All `ggml_ext_attention_ext(...)` calls in `src/wan.hpp` pass `mask = nullptr`. A Metal DIAG_MASK_INF kernel would be dead code on this stack.

Net effect: smaller, future-proof patch.

Build (Apple Silicon)

```bash
make build-metal
```

This produces `build/bin/sd-cli` with Metal enabled and the patched ggml ops linked in.

Test (Wan2.1 1.3B)

```bash
cd test-wan
./test-wan-models.sh wan2-1-t2v-small
```

Expected on Apple M3 Ultra: ~432 s for a 33-frame 832×480 clip; host process at 0–1.5 % CPU throughout (no CPU fallback for ops in the hot path).

Dependencies

All commits are signed with an SSH ED25519 key.

Made with Cursor

leejet and others added 3 commits April 29, 2026 07:39
Bumps the ggml submodule to tetherto/qvac-ext-ggml@feature/metal-pr-16669-clean,
which adds the two Metal ops actually required by Wan video diffusion:

  - IM2COL_3D (3D im2col for Wan VAE/transformer 3D convs)
  - PAD left-padding support (Wan input preprocessing)

Without this, the Metal backend crashes during Wan inference with:
    ggml_metal_op_encode_impl: error: unsupported op 'IM2COL_3D'

Why no DIAG_MASK_INF Metal kernel
---------------------------------
The original CLDawes patch (ggml-org/llama.cpp#16669) bundled a Metal
DIAG_MASK_INF kernel along with IM2COL_3D + PAD. It is intentionally
not pulled in here because:

  - GGML_OP_DIAG_MASK_INF is being deprecated upstream in favor of
    generic ops (ggml-org/llama.cpp#17654), and ggerganov has steered
    contributors away from new DIAG_MASK_INF backend kernels
    (ggml-org/ggml#1395).
  - leejet#1230 (already in our base, merged
    Jan 2026) refactored every CLIP / SD / MMDiT / RoPE / VAE
    attention site to build explicit -INFINITY mask tensors and
    removed all `diag_mask_inf=true` calls. There are zero
    ggml_diag_mask_inf call sites left in app code.
  - All ggml_ext_attention_ext(...) calls in src/wan.hpp pass
    mask = nullptr, so a Metal DIAG_MASK_INF kernel would be dead
    code on this stack.

Other changes
-------------
  - Point .gitmodules at tetherto/qvac-ext-ggml so clones can fetch
    the patched submodule directly.
  - Ignore test-wan/output/, test-wan/models/, and test-wan/cache/
    so generated videos, downloaded weights, and model caches are
    not accidentally committed.

Verified on Apple M3 Ultra: Wan2.1 1.3B txt2video runs end-to-end
on Metal with the host process at 0-1.5% CPU throughout.

Made-with: Cursor
@aegioscy aegioscy closed this Jun 1, 2026
@gianni-cor
gianni-cor deleted the feature/metal-im2col-3d-clean branch June 4, 2026 12:24
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.

2 participants