Skip to content

[doc] fix: mark NVTE_FP8_BLOCK_SCALING_FP32_SCALES=1 as Hopper-only - #8062

Merged
wuxibin89 merged 1 commit into
verl-project:mainfrom
wengeezhang:docs/fp8-blockwise-fp32-scales-hopper-only
Sep 29, 2026
Merged

wuxibin89 merged 1 commit into
verl-project:mainfrom
wengeezhang:docs/fp8-blockwise-fp32-scales-hopper-only

Conversation

@wengeezhang

Copy link
Copy Markdown
Contributor

What does this PR do?

The FP8 end-to-end section of docs/low_precision/fp8.md lists NVTE_FP8_BLOCK_SCALING_FP32_SCALES=1 as a general requirement. It only applies on Hopper.

On Blackwell (SM100+), Transformer Engine has no native block-scaled GEMM. It runs the block-wise recipe through MXFP8 GEMMs, whose E8M0 scales hold only an exponent. So both of its block-quantize kernels assert power-of-two scales on SM100+, and a run with the variable set stops at the first FP8 quantization:

transformer_engine/common/transpose/quantize_transpose_vector_blockwise.cu:534 in function quantize_transpose_vector_blockwise:
Assertion failed: pow2_scale. On Blackwell and newer, the FP8 block scaling recipe is emulated with MXFP8, which requires using power of two scaling factors.

This is the failure reported in #6172 (8×B200) when following this doc and the verl-recipe FP8 E2E script. This PR marks the variable as Hopper-only and says that on Blackwell it must stay unset; power-of-two scales are the Transformer Engine default. Docs only.

Refs #6172. This does not fix #6172: that issue also reports garbled FP8 rollouts on Blackwell once the variable is removed, and this PR does not address that.

Checklist Before Starting

Test

Documentation-only change.

  • pre-commit run --files docs/low_precision/fp8.md: all hooks pass, including "Check docs Last updated info".
  • Reproduced on 1×B200 (SM 10.0, torch 2.11.0+cu130, CUDA 13.0, Transformer Engine 2.16.1). te.Linear (2048→2048) and te.GroupedLinear (4 × 2048→768) ran forward and backward under Float8BlockScaling(fp8_format=Format.E4M3) and were compared with a bf16 run of the same module:
NVTE_FP8_BLOCK_SCALING_FP32_SCALES te.Linear out / dgrad / wgrad rel. err te.GroupedLinear out / dgrad / wgrad rel. err
unset (power-of-two scales) 0.0377 / 0.0423 / 0.0462 0.0376 / 0.0475 / 0.0510
1 RuntimeError: the pow2_scale assertion above same

The same modules under MXFP8BlockScaling give the same errors as the unset row, with or without the variable.

Source references (Transformer Engine 2.16.1, commit c9877beb):

  • transformer_engine/common/transpose/quantize_transpose_vector_blockwise.cu:533-536 and transformer_engine/common/transpose/quantize_transpose_square_blockwise.cu:490-493: if (sm_arch() >= 100) NVTE_CHECK(pow2_scale, ...).
  • transformer_engine/pytorch/csrc/extensions/gemm.cpp:289-300: "Emulate the FP8 block scaling recipe with MXFP8 on Blackwell and newer as it is not natively supported by cublasLt".
  • transformer_engine/common/swizzle/swizzle_block_scaling.cu:116-118, 205-206: each FP32 block scale becomes an E8M0 scale by keeping only its exponent byte, (sf >> 23) & 0xFF. This is why the scales must be powers of two.

API and Usage Example

None.

Design & Code Changes

docs/low_precision/fp8.md:

  • The requirement line now says that the variable is Hopper-only, why it fails on Blackwell, and what to do there.
  • "Last updated" is bumped.

The verl-recipe script low_precision/run_dapo_qwen3_moe_30b_megatron_fp8e2e.sh also exports the variable unconditionally. That lives in the recipe repository and can get a matching note separately.

Checklist Before Submitting

  • Read the Contribute Guide.
  • Apply pre-commit checks.
  • Add / Update the documentation.
  • Add unit or end-to-end test(s) to the CI workflow to cover all the code. If not feasible, explain why: documentation-only change; the behaviour it documents was checked on B200 as described under Test.
  • Once your PR is ready for CI, send a message in the ci-request channel.
  • If your PR is related to the recipe submodule, please also update the reference to the submodule commit: not applicable.

AI assistance: this PR was prepared with AI assistance (Claude Code). I reviewed the change and the evidence above, and the checks listed under Test were run for this PR.

🤖 Generated with Claude Code

The FP8 end-to-end requirements list NVTE_FP8_BLOCK_SCALING_FP32_SCALES=1
unconditionally. On Blackwell (SM100+) Transformer Engine emulates the
block-wise recipe with MXFP8 GEMMs, whose E8M0 scales carry only an
exponent, and both of its block-quantize kernels assert power-of-two
scales there, so a run with the variable set stops at the first FP8
quantization (the error reported in verl-project#6172). Say that the variable is for
Hopper and that on Blackwell it must stay unset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@wuxibin89
wuxibin89 merged commit 3084c26 into verl-project:main Sep 29, 2026
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.

FP8 e2e training on Blackwell

2 participants