vulkan: add DeepSeek-V4 hyper-connection fused ops (DSV4_HC_COMB/PRE/POST) - #26578
vulkan: add DeepSeek-V4 hyper-connection fused ops (DSV4_HC_COMB/PRE/POST)#26578kh0pper wants to merge 1 commit into
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
5f3a82a to
ccbc178
Compare
|
I'd still prefer to have the transpose in a separate PR. I've looked at that part of the code and I think we could get it in pretty quickly. |
|
The transpose is now split out as #26585. I'll rebase this PR to drop that commit once it lands. |
|
Closing temporarily to respect the one-open-PR limit for new contributors while #26585 (the transpose, split out at the maintainer's request) goes first. I'll reopen this after it lands and rebase to drop the shared commit. |
…POST) CUDA has these ops from the DeepSeek-V4 merge and Metal gained them in PR 26459. Vulkan was the last major backend running the unfused primitive chain. On DeepSeek-V4-Flash the unfused Sinkhorn comb chain alone takes about 32% of decode op time on gfx1151 (Strix Halo), spread over roughly 16k dispatches per token. dsv4_hc_comb runs the full 20-iteration Sinkhorn in registers. A token's 4x4 comb matrix lives in 16 consecutive subgroup lanes, with idst in bits 0-1 and isrc in bits 2-3 to match the CPU reference layout, so subgroupShuffleXor by 1|2 reduces rows and by 4|8 reduces columns. One dispatch replaces about 137 strictly ordered node executions per site. The shuffle masks never cross a 16-lane boundary, so a subgroup of size 64 packs 4 independent tokens. dsv4_hc_pre and dsv4_hc_post handle the elementwise stream collapse and fan-out, with per-token coefficients staged in shared memory. GGML_VK_DISABLE_DSV4_HC disables all three ops. The _COMB, _PRE and _POST variants gate each op independently so a single kernel can be bisected against the unfused graph. Adds eval cases at the production n_iter=20 across batch sizes that cross subgroup and workgroup boundaries.
ccbc178 to
0554f85
Compare
|
@neuromaniacMD @antoinezambelli Reopened and rebased onto master as a single commit — the transpose this branch used to carry merged separately as #26585, so this PR is now just the three HC ops. Your generation and decode numbers came from these ops, so this is the right thread for them if you're still willing to repost. The RADV gfx1100/gfx1201 offer would be welcome here too. |
|
Thanks — reposting the HC-relevant results from our combined-branch test. Tested
Full hardware, driver, launch configuration, and methodology are in the original #26585 report. |
|
Thanks @antoinezambelli — appreciated, especially the two-node RPC coverage. For reviewers: |
Overview
Implements the three DeepSeek-V4 hyper-connection fused ops (DSV4_HC_COMB, DSV4_HC_PRE, DSV4_HC_POST) for the Vulkan backend. CUDA has had them since the original DeepSeek-V4 merge and Metal gained them in #26459, leaving Vulkan as the last major backend without them. On DeepSeek-V4-Flash the unfused Sinkhorn comb chain alone accounts for roughly 32% of decode op time on gfx1151 (Strix Halo), spread across about 16k dispatches per token.
Implementation
dsv4_hc_comb.comp runs the full 20-iteration Sinkhorn in registers. A token's 4x4 comb matrix occupies 16 consecutive subgroup lanes (idst in bits 0-1, isrc in bits 2-3, matching the CPU reference layout), so subgroupShuffleXor by 1|2 reduces rows and by 4|8 reduces columns. One dispatch replaces the roughly 137 strictly ordered node executions of the unfused chain per site. Shuffle masks never cross a 16-lane boundary, so a 64-wide subgroup packs 4 independent tokens.
dsv4_hc_pre.comp and dsv4_hc_post.comp handle elementwise stream collapse and fan-out, with per-token coefficients staged in shared memory.
ggml-vulkan.cpp adds the pipelines, push constants, dispatch, and supports_op entries.
Rebased onto current master as a single commit. The CONT transpose fix this PR originally carried was split out at a maintainer's request and merged as #26585, so it is now in master and both arms of the performance table below include it.
Correctness
test-backend-ops passes the full suite, including added eval cases at the production shape (n_iter=20, n_tokens 1/256/336/512/513/1024/2048).
GGML_VULKAN_CHECK_RESULTS under a real 9k-token DeepSeek-V4-Flash prompt shows 2322 comb node executions, max avg_err of 5.1e-08, zero divergent nodes.
Beyond standard checks, the ops were verified equivalent to the decomposed build_hc_sinkhorn chain, to a float64 reference, and to the official HF modeling_deepseek_v4.py formula (softmax axis, eps placements, col-first iteration order, consumer orientation), using the model's real per-layer hc_scale and hc_base weights across input magnitudes into deep softmax saturation. Max deviation between any two implementations was about 6e-7, consistent with float rounding.
Performance
gfx1151 (Strix Halo), DeepSeek-V4-Flash IQ3_XXS, 9k-token prompt, ABBA order, n=2 per arm, within-arm spread below 1%, branch rebased onto current master.
Additional information
Greedy-decoding trajectory sensitivity. Recording this so the behavior is on record before it gets reported as a regression.
During validation, DeepSeek-V4-Flash at IQ3_XXS on one in-distribution 9k-token chat prompt produced a degenerate repetition (播客播客…) under greedy decoding on most rounding paths. The CPU backend produces it with the fused ops disabled. The previously unfused Vulkan path produced clean output on the same prompt.
No implementation is at fault. All paths agree to float epsilon, and the per-layer difference between paths grows smoothly from about 1e-9 to about 1e-3 over the 43 layers (measured with a filtered eval-callback). This is ordinary trajectory divergence of a quantized model near a degenerate attractor. Under sampled decoding (temp 0.3 and 0.7, n=8 per arm) fused and unfused outputs are indistinguishable in quality, and the worst degenerate sample came from the unfused side. DeepSeek's first-party serving endpoint produces clean greedy output on the same prompt, so the sensitivity is a property of the quantization and is absent at serving precision. CUDA and Metal users already run the fused rounding path today. Full instrumented write-up available on request.
Requirements