fix: layernorm_fp8 kernel produces garbage scales for all but row 0 - #13
Open
pauliano22 wants to merge 1 commit into
Open
fix: layernorm_fp8 kernel produces garbage scales for all but row 0#13pauliano22 wants to merge 1 commit into
pauliano22 wants to merge 1 commit into
Conversation
Two compounding bugs made this kernel completely non-functional: 1. `.to(tl.float8e4m3fn)` referenced a dtype that has never existed in triton.language (checked triton 3.6.0 and 3.7.1 — the correct name for this format is `tl.float8e4nv`). Every call raised AttributeError immediately, so the kernel could never run. 2. Once that's fixed, `if tl.program_id(0) == 0:` guarded the scale store, so only row 0's scale was ever written to Scale_ptr; rows 1..M-1 kept whatever uninitialized memory torch.empty happened to allocate. Scale_ptr is sized (M,) and each row already computes its own max_val/scale, so a per-row scale was clearly intended — the guard was leftover confusion (see the now-removed comment "once for the whole tensor or per row"). Verified via TRITON_INTERPRET=1 against a reference LayerNorm+quant computation: before the fix, 7/8 rows returned garbage (including subnormal floats where uninitialized memory happened to look like one); after the fix, all rows match the reference to 1e-3.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
kernels/layer_norm_fp8.pyhad two compounding bugs that made the kernel completely non-functional:.to(tl.float8e4m3fn)referenced a dtype that doesn't exist intriton.language— checked both the pinnedtriton==3.6.0and current3.7.1, neither has afloat8e4m3fnattribute (triton/language/core.pyonly definesfloat8e4nv,float8e5,float8e5b16,float8e4b8,float8e4b15). Every call raisedAttributeErrorimmediately, so this kernel could never actually run. Fixed totl.float8e4nv, triton's name for the NVIDIA E4M3 format (matches thetorch.float8_e4m3fndtype already used for the output tensor on the host side).if tl.program_id(0) == 0:guarded the scale store, so only row 0's scale was ever written toScale_ptr; rows1..M-1kept whatever uninitialized memorytorch.emptyhappened to allocate.Scale_ptris sized(M,)and each row already computes its ownmax_val/scalea few lines above, so a per-row scale was clearly the intent — the guard looks like leftover confusion (the removed comment literally said "once for the whole tensor or per row").Verification
No test harness or CI exists for this repo's kernels, so I verified manually via
TRITON_INTERPRET=1(CPU interpreter mode) against a reference LayerNorm + per-row quantization computation:AttributeErrorand could not run at all.rtol=1e-3, atol=1e-3.Test plan
TRITON_INTERPRET=1run against a hand-written reference implementation — passes for all rowsGenerated by Claude Code