Skip to content

[PyTorch] Share MXFP8 data tensor between rowwise and columnwise for 2D quantization - #3385

Open
TangChangcheng wants to merge 1 commit into
NVIDIA:mainfrom
TangChangcheng:mxfp8-2d-share-data
Open

[PyTorch] Share MXFP8 data tensor between rowwise and columnwise for 2D quantization#3385
TangChangcheng wants to merge 1 commit into
NVIDIA:mainfrom
TangChangcheng:mxfp8-2d-share-data

Conversation

@TangChangcheng

Copy link
Copy Markdown

Summary

For 2D MXFP8 quantization, the rowwise and columnwise FP8 data tensors are byte-identical since they originate from the same 32x32 block scales. Currently, two separate [M, K] uint8 buffers are allocated and written with identical data.

This PR shares a single data buffer between the two representations, halving the FP8 weight memory footprint for 2D-quantized weights.

Changes

  • C++ quantizer (quantizer.cpp): When with_2d_quantization && rowwise_usage && columnwise_usage, reuse rowwise_data_tensor as columnwise_data_tensor instead of allocating a separate buffer.
  • Python inner_tensor_specs (mxfp8_tensor.py): Skip _columnwise_data allocation when 2D and rowwise is already enabled.
  • MXFP8Tensor.__new__ (mxfp8_tensor.py): When columnwise_data is None and 2D quantization is active, alias it to rowwise_data.

No GEMM or kernel changes are needed: cuBLAS already selects the appropriate pointer via the transA flag and handles the transpose internally.

Related

@github-actions github-actions Bot added the community-contribution PRs from external contributor outside the core maintainers, representing community-driven work. label Aug 17, 2026
@greptile-apps

greptile-apps Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR reduces dual-direction 2D MXFP8 weight storage by sharing the byte-identical rowwise data buffer with the columnwise representation.

  • Aliases rowwise and columnwise data in the native C++ tensor allocator.
  • Omits the redundant columnwise allocation from Python allocation specifications.
  • Restores the alias when constructing dual-use Python MXFP8 tensor wrappers.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
transformer_engine/pytorch/csrc/quantizer.cpp Shares the rowwise data allocation with the columnwise representation for dual-use 2D MXFP8 tensors while retaining direction-specific scales.
transformer_engine/pytorch/tensor/mxfp8_tensor.py Aligns Python allocation and wrapper construction with the shared-data representation, including the columnwise-usage guard that resolves the prior rowwise-only availability issue.

Reviews (2): Last reviewed commit: "[PyTorch] Share MXFP8 data tensor betwee..." | Re-trigger Greptile

Comment thread transformer_engine/pytorch/tensor/mxfp8_tensor.py
…2D quantization

For 2D MXFP8 quantization, the rowwise and columnwise FP8 data
tensors are byte-identical since they originate from the same
32x32 block scales. This commit shares a single data buffer
between the two representations, halving the FP8 weight memory
footprint for 2D-quantized weights.

The columnwise data tensor is reused as an alias of the rowwise
data tensor in the C++ quantizer, the inner_tensor_specs paths,
and the MXFP8Tensor constructor. The cuBLAS GEMM path already
selects the appropriate pointer via the transA flag and handles
the transpose internally, so no GEMM changes are needed.

Signed-off-by: tangcc1127 <tangcc1127@gmail.com>
@ptrendx

ptrendx commented Aug 17, 2026

Copy link
Copy Markdown
Member

In general I agree with this optimization (although I would like this change to also include a change to the kernel to skip writing the transposed data if the pointers for columnwise and rowwise tensors are the same).

One problem is that currently Megatron does not have a good handling of the 2D MXFP8 weights and so enabling this optimization unconditionally could possibly make it unusable there. @kunlunl @zhongbozhu could you comment on this - if we still technically have both rowwise and columnwise tensors on the pyTorch side, but they are backed by the same actual buffer, is the distributed optimizer still going to work or do we need more work for that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community-contribution PRs from external contributor outside the core maintainers, representing community-driven work.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants