Skip to content

fix(deepseek_v4): contract mHC comb on the column-normalised axis - #1040

Open
yuankaichen-amd wants to merge 4 commits into
AMD-AGI:mainfrom
yuankaichen-amd:fix/model/mhc-comb-contraction-axis
Open

fix(deepseek_v4): contract mHC comb on the column-normalised axis#1040
yuankaichen-amd wants to merge 4 commits into
AMD-AGI:mainfrom
yuankaichen-amd:fix/model/mhc-comb-contraction-axis

Conversation

@yuankaichen-amd

Copy link
Copy Markdown
Contributor

HyperMixer.expand computed matmul(comb, x), contracting comb's second index, while the DeepSeek-V4 inference kernels (SGLang hc_post and its tilelang mhc_post) contract the first. sinkhorn_normalize ends on a column normalisation, so comb's columns sum to 1 while its rows sum to 0.93-1.07; contracting the second index therefore leaves each output stream carrying the row mass rather than 1.

Link to SGLang implementation: https://github.com/sgl-project/sglang/blob/7ddf92d5f481e79abd6db4f6c28dd27641fd2a7e/python/sglang/srt/models/deepseek_v4.py#L2041-L2048

The two conventions differ by 5.5% per call on real layer-0 weights, and expand runs twice per layer, so the error compounds with depth: on an 8-layer DeepSeek-V4-Flash proxy the residual stream diverged from SGLang by 13.3% at layer 0 and 30.9% at layer 7. Transposing comb makes the eager and Triton paths agree with the inference kernel to bf16 noise (5.5e-2 -> 9e-4) and cuts trainer-vs-engine KL on sampled sequences from 0.265 to 0.148 nats/token.

HyperMixer.expand computed matmul(comb, x), contracting comb's second index,
while the DeepSeek-V4 inference kernels (SGLang hc_post and its tilelang
mhc_post) contract the first. sinkhorn_normalize ends on a column
normalisation, so comb's columns sum to 1 while its rows sum to 0.93-1.07;
contracting the second index therefore leaves each output stream carrying the
row mass rather than 1.

The two conventions differ by 5.5% per call on real layer-0 weights, and
expand runs twice per layer, so the error compounds with depth: on an 8-layer
DeepSeek-V4-Flash proxy the residual stream diverged from SGLang by 13.3% at
layer 0 and 30.9% at layer 7. Transposing comb makes the eager and Triton
paths agree with the inference kernel to bf16 noise (5.5e-2 -> 9e-4) and cuts
trainer-vs-engine KL on sampled sequences from 0.265 to 0.148 nats/token.
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