[BugFix][Quant] Accumulate per-token BF16 amax in FP32#15
Open
JayceSu98 wants to merge 1 commit into
Open
Conversation
Per-token FP8/FP4 casts derive each output scale factor from an absmax reduction over a token/channel group. For BF16 inputs, the reduction result was stored in a BF16 fragment, so TileLang lowered the local reduction through the BF16 packed path before the final cross-thread max. On H100 with CUDA 13.2 this can underestimate the row amax for large hidden blocks. With round_sf=True, the underestimated amax rounds the dequant scale one power-of-two too small, so the quantized E4M3/E2M1 bytes and the stored scaling factors diverge from the PyTorch reference. Store the per-group amax reduction result in FP32. The input data remains BF16, but scale selection is a FP32 numeric contract and should not depend on low-precision packed BF16 reduction behavior. JayceSu98 <jayce.su@enflame-tech.com> authored and validated this patch. Co-author GitHub: https://github.com/dingsg Verified on H100 (NVIDIA H100 PCIe, sm_90) with CUDA 13.2, PyTorch 2.12.0+cu132, and TileLang 0.1.10+cuda.git23d91c58: the 43 previously failing BF16 per_token_cast E4M3/E2M1 cases passed with pytest -n 2. Co-authored-by: dingsg <shengge.ding@enflame-tech.com>
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.
Per-token FP8/FP4 casts derive each output scale factor from an absmax reduction over a token/channel group. For BF16 inputs, the reduction result was stored in a BF16 fragment, so TileLang lowered the local reduction through the BF16 packed path before the final cross-thread max.
On H100 with CUDA 13.2 this can underestimate the row amax for large hidden blocks. With round_sf=True, the underestimated amax rounds the dequant scale one power-of-two too small, so the quantized E4M3/E2M1 bytes and the stored scaling factors diverge from the PyTorch reference.
Store the per-group amax reduction result in FP32. The input data remains BF16, but scale selection is a FP32 numeric contract and should not depend on low-precision packed BF16 reduction behavior.
Verified on H100 (NVIDIA H100 PCIe, sm_90) with CUDA 13.2, PyTorch 2.12.0+cu132, and TileLang 0.1.10+cuda.git23d91c58: the 43 previously failing BF16 per_token_cast E4M3/E2M1 cases passed with pytest -n 2.
JayceSu98 jayce.su@enflame-tech.com authored and validated this patch.
Co-author GitHub: https://github.com/dingsg