Skip to content

[BugFix][Quant] Guard scale tails and FP32 absmax#4

Closed
JayceSu98 wants to merge 1 commit into
mainfrom
jayce/quant-scale-tail-fp32-absmax
Closed

[BugFix][Quant] Guard scale tails and FP32 absmax#4
JayceSu98 wants to merge 1 commit into
mainfrom
jayce/quant-scale-tail-fp32-absmax

Conversation

@JayceSu98

Copy link
Copy Markdown
Owner

Context

The full H100/CuTeDSL correctness run covers quantization shapes where token counts, hidden sizes, scale blocks, and packed E5M6 groups do not always land exactly on a kernel tile boundary.

That exposed two TileKernels-side issues:

  • Tail tiles could load or store scaling factors outside the real scaling-factor grid.
  • Per-token scale generation used in_config.dtype as the absmax fragment dtype, even though that dtype describes input storage rather than the reduction accumulator.

For BF16 and narrow quantization paths, using the input storage dtype as the absmax accumulator can round or overflow the scale path before the final cast, producing byte mismatches against the PyTorch reference.

Fix

  • Guard scale loads in cast-back and per-block lossless paths with the real scale-grid dimensions.
  • Guard scale stores in per-block and per-token cast paths with the real token/channel scale extents.
  • Guard packed E5M6 output stores for token and hidden tail tiles.
  • Use T.float32 fragments for per-token absmax reductions before computing reciprocal scales.

Why this is a TileKernels fix

These are kernel-level bounds and accumulator-dtype issues. The implementation schedules aligned tile work for performance, but memory accesses and reduction precision must still follow the logical tensor/scaling-factor layout. The fix is not tied to one CuTeDSL package version.

Validation

Validated as part of the H100 PCIe CuTeDSL full correctness and benchmark run after the matching TileLang CuTeDSL fixes were applied.

Local sanity checks for this split branch:

  • git diff --check origin/main..82fbd40
  • ruff check on the changed TileKernels Python files

The full H100/CuTeDSL correctness run covers token and hidden sizes that do not land exactly on the kernel tile, scaling-factor block, or E5M6 packing granularity. Those edge tiles exposed two independent quantization issues.

First, cast-back and lossless/per-token cast kernels could load or store scaling factors for padded token/channel blocks. The same edge condition also applied to packed E5M6 output rows and columns, where the final tile may not contain a full logical token row or hidden group.

Second, per-token scale generation used in_config.dtype as the absmax fragment dtype. That dtype describes the input tensor storage, not the reduction accumulator. For BF16 and narrow quantization paths, keeping absmax in the input dtype can round or overflow the scale path before the final output cast, producing byte mismatches against the PyTorch reference.

Guard scale loads/stores and packed E5M6 stores with the real token/channel extents, keep invalid scale lanes zero-initialized, and use FP32 fragments for per-token absmax reductions before computing the reciprocal scale.

Co-authored-by: dingsg <shengge.ding@enflame-tech.com>
@JayceSu98

Copy link
Copy Markdown
Owner Author

Duplicate fork-local PR. The complete Quant fix is now tracked upstream by updating deepseek-ai#15; deepseek-ai#16 was closed as superseded.

@JayceSu98 JayceSu98 closed this Jun 12, 2026
@JayceSu98 JayceSu98 deleted the jayce/quant-scale-tail-fp32-absmax branch June 12, 2026 06:45
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.

1 participant