Skip to content

feat: add quantized tensor support for blockwise grouped gemm#422

Merged
xiaobochen-amd merged 1 commit into
mainfrom
dev/zhangrb/add_qt_for_blockwise_gg
Jul 21, 2026
Merged

feat: add quantized tensor support for blockwise grouped gemm#422
xiaobochen-amd merged 1 commit into
mainfrom
dev/zhangrb/add_qt_for_blockwise_gg

Conversation

@RuibinCheung

Copy link
Copy Markdown
Collaborator

Description

This PR adds QuantizedTensor support to the BLOCKWISE FP8 grouped GEMM path, so a pre-quantized 2D-block weight can be passed directly into grouped_gemm_fp8 without going through an internal dequantize/re-quantize round trip.

Previously the BLOCKWISE grouped GEMM only accepted raw high-precision tensors and asserted on anything else.
It now accepts a QuantizedTensor weight (b) and reuses its qdata / scale_inv buffers directly in both forward and backward.
The activation (a) must remain a raw tensor, because the grouped BLOCKWISE quant kernel emits fused pre-shuffled row scales plus segment-padded column scales that are not compatible with the standard QuantizedTensor layout.

As part of this change the MX_BLOCKWISE path is migrated onto the unified, granularity-aware quant entry points (quantize_fp8_with_trans / grouped_quantize_fp8_with_trans), replacing the MX-specific *_mxfp8_flydsl_impl helpers so both granularities share one quant interface.

Fixes # (issue)

Type of change

  • Documentation change (change only to the documentation, either a fix or a new content)
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Infra/Build change
  • Code refactoring

Changes

Please list the changes introduced in this PR:

  • Extend FP8GroupedGemmBlockFunc to accept a pre-quantized 2D-block weight b as a QuantizedTensor, reusing its qdata / scale_inv in forward and backward instead of re-quantizing.
  • Add a_t / b_t placeholder arguments (currently unused) to the FP8GroupedGemmBlockFunc.forward signature and update the backward return tuple and the grouped_gemm_fp8 dispatch accordingly, aligning the API with the other grouped GEMM functions.
  • Raise a clear NotImplementedError when a pre-quantized activation a is supplied to the BLOCKWISE path, since the fused pre-shuffled row / segment-padded col scales from the grouped quant kernel are not compatible with QuantizedTensor.
  • Validate the incoming weight QuantizedTensor via check_quantized_tensor against the ScalingRecipe(use_2d_block=True) recipe.
  • Rename the internal scale variables from *_scale_inv_* to *_scale_* for consistency across the forward/backward code paths.
  • Migrate the MX_BLOCKWISE path to the unified, granularity-aware quant helpers quantize_fp8_with_trans / grouped_quantize_fp8_with_trans (passing config.granularity) in place of the MX-specific *_mxfp8_flydsl_impl functions.
  • Add test_grouped_gemm_fp8_blockwise_weight_quantized_tensor covering a pre-quantized 2D-block weight with a raw activation, checking output and gradient SNR across formats, backends, auto-tune, and transpose configurations.

Checklist:

  • The functionality is complete
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Copilot AI review requested due to automatic review settings July 20, 2026 10:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the FP8 BLOCKWISE grouped GEMM path to accept a pre-quantized 2D-block QuantizedTensor for the weight (b), avoiding an internal dequantize/re-quantize cycle, and migrates the MX_BLOCKWISE path to unified granularity-aware quantization entry points.

Changes:

  • Allow FP8GroupedGemmBlockFunc to take b as a QuantizedTensor and reuse qdata / scale_inv in forward and backward; explicitly reject pre-quantized activations for BLOCKWISE.
  • Align BLOCKWISE autograd function signatures/dispatch with other grouped GEMM paths by adding placeholder a_t / b_t arguments and updating backward returns.
  • Add a new test covering BLOCKWISE grouped GEMM with an externally pre-quantized 2D-block weight.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
tests/pytorch/ops/test_grouped_gemm_fp8.py Adds coverage for BLOCKWISE grouped GEMM when b is provided as a pre-quantized 2D-block QuantizedTensor.
primus_turbo/pytorch/ops/grouped_gemm_fp8.py Enables BLOCKWISE grouped GEMM to reuse pre-quantized weight buffers and migrates MX_BLOCKWISE to unified quantization helpers.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

assert config.granularity == ScalingGranularity.BLOCKWISE
assert config.block_size in [128], "Only block_size 128 is supported currently."
if isinstance(a, QuantizedTensor):
# TODO(ruibin): grouped BLOCKWISE emits fused pre-shuffled row / segment-padded col scales, from the quant kernel, it is not compatible with the QuantizedTensor."
Comment on lines +107 to 111
# --- A side: fused row + segment-padded col grouped quant in one bf16 read.
gemm_n = b.size(-2) if trans_b else b.size(-1)
a_fp8_row, a_fp8_col, a_scale_inv_row, a_scale_inv_col, _, _ = (
quant_fp8_blockwise_segment_m_row_col_impl(
a, a_dtype, config.block_size, group_lens, group_offs, gemm_other_dim=gemm_n
)
a_fp8_row, a_fp8_col, a_scale_row, a_scale_col, _, _ = quant_fp8_blockwise_segment_m_row_col_impl(
a, a_dtype, config.block_size, group_lens, group_offs, gemm_other_dim=gemm_n
)
Comment on lines +116 to +120
if isinstance(b, QuantizedTensor):
check_quantized_tensor(b, config, scaling_recipe=b_scaling_recipe)
b_fp8, b_scale = b.qdata, b.scale_inv
else:
b_fp8, b_scale = quant_fp8_blockwise_for_weight_impl(b, b_dtype, block_size=config.block_size)
@xiaobochen-amd
xiaobochen-amd merged commit edc8d2c into main Jul 21, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants