Skip to content

support MXFP8 (#21146)#21146

Merged
meta-codesync[bot] merged 1 commit into
pytorch:mainfrom
metascroy:export-D113113318
Jul 23, 2026
Merged

support MXFP8 (#21146)#21146
meta-codesync[bot] merged 1 commit into
pytorch:mainfrom
metascroy:export-D113113318

Conversation

@metascroy

@metascroy metascroy commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary:

Add MXFP8 block-scaled float quantization support to the MLX backend, alongside
the existing NVFP4 path, and unify the MLX safetensors checkpoint loader so it can
load block-scaled (NVFP4 / MXFP8) checkpoints directly.

  • New ExportableMXFP8Tensor (extension/llm/export/mxfp8.py): a torchao tensor
    subclass carrying MLX-native packed weights (uint32 qdata, uint8 E8M0 block
    scales, group_size 32, 8-bit FP8), with a registered torchao::dequantize_mxfp8
    custom op so the dequant survives torch.export, and a payload-preserving .to()
    so activation-dtype casts do not dequantize it.
  • NVFP4 (extension/llm/export/nvfp4.py): add the same payload-preserving .to()
    so block-scaled weights survive model.to(activation_dtype) instead of being
    dequantized.
  • MLX backend lowering (backends/mlx/patterns.py, backends/mlx/builder/op_helpers.py):
    add parse_dequant_mxfp8_node and MXFP8 linear/embedding pattern handlers that
    emit the MLX mode="mxfp8" quantized matmul / gather (group_size 32, bits 8).
    The bundled MLX runtime already accepts this mode, so no C++/runtime changes.
  • Fusion (extension/llm/export/quant/convert.py): extend fuse_along_output and
    maybe_cast to handle the NVFP4 / MXFP8 carrier tensors (the per-tensor scale
    is treated as a shared, assert-equal field rather than concatenated).
  • Checkpoint loader: unify the MLX reader to resolve each weight's quant mode
    per-tensor from config.json (a default mode plus per-module overrides) and
    build the matching representation -- affine -> torchao intx, nvfp4 ->
    ExportableNVFP4Tensor, mxfp8 -> ExportableMXFP8Tensor -- so mixed-format
    checkpoints load correctly from a single path.

Reviewed By: Gasoonjia

Differential Revision: D113113318

@pytorch-bot

pytorch-bot Bot commented Jul 22, 2026

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/21146

Note: Links to docs will display an error until the docs builds have been completed.

⏳ No Failures, 27 Pending

As of commit 1a5735a with merge base 96e87e3 (image):
💚 Looks good so far! There are no failures yet. 💚

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jul 22, 2026
@meta-codesync

meta-codesync Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

@metascroy has exported this pull request. If you are a Meta employee, you can view the originating Diff in D113113318.

@github-actions

Copy link
Copy Markdown

This PR needs a release notes: label

If your change should be included in the release notes (i.e. would users of this library care about this change?), please use a label starting with release notes:. This helps us keep track and include your important work in the next release notes.

To add a label, you can comment to pytorchbot, for example
@pytorchbot label "release notes: none"

For more information, see
https://github.com/pytorch/pytorch/wiki/PyTorch-AutoLabel-Bot#why-categorize-for-release-notes-and-how-does-it-work.

@meta-codesync meta-codesync Bot changed the title support MXFP8 support MXFP8 (#21146) Jul 22, 2026
@metascroy
metascroy force-pushed the export-D113113318 branch from b55f201 to 7247ffc Compare July 22, 2026 23:26
metascroy added a commit to metascroy/executorch that referenced this pull request Jul 22, 2026
Summary:

Add MXFP8 block-scaled float quantization support to the MLX backend, alongside
the existing NVFP4 path, and unify the MLX safetensors checkpoint loader so it can
load block-scaled (NVFP4 / MXFP8) checkpoints directly.

- New `ExportableMXFP8Tensor` (extension/llm/export/mxfp8.py): a torchao tensor
  subclass carrying MLX-native packed weights (uint32 qdata, uint8 E8M0 block
  scales, group_size 32, 8-bit FP8), with a registered `torchao::dequantize_mxfp8`
  custom op so the dequant survives torch.export, and a payload-preserving `.to()`
  so activation-dtype casts do not dequantize it.
- NVFP4 (extension/llm/export/nvfp4.py): add the same payload-preserving `.to()`
  so block-scaled weights survive `model.to(activation_dtype)` instead of being
  dequantized.
- MLX backend lowering (backends/mlx/patterns.py, backends/mlx/builder/op_helpers.py):
  add `parse_dequant_mxfp8_node` and MXFP8 linear/embedding pattern handlers that
  emit the MLX `mode="mxfp8"` quantized matmul / gather (group_size 32, bits 8).
  The bundled MLX runtime already accepts this mode, so no C++/runtime changes.
- Fusion (extension/llm/export/quant/convert.py): extend `fuse_along_output` and
  `maybe_cast` to handle the NVFP4 / MXFP8 carrier tensors (the per-tensor scale
  is treated as a shared, assert-equal field rather than concatenated).
- Checkpoint loader: unify the MLX reader to resolve each weight's quant mode
  per-tensor from `config.json` (a default mode plus per-module overrides) and
  build the matching representation -- affine -> torchao intx, nvfp4 ->
  ExportableNVFP4Tensor, mxfp8 -> ExportableMXFP8Tensor -- so mixed-format
  checkpoints load correctly from a single path.

Reviewed By: Gasoonjia

Differential Revision: D113113318
metascroy added a commit to metascroy/executorch that referenced this pull request Jul 22, 2026
Summary:

Add MXFP8 block-scaled float quantization support to the MLX backend, alongside
the existing NVFP4 path, and unify the MLX safetensors checkpoint loader so it can
load block-scaled (NVFP4 / MXFP8) checkpoints directly.

- New `ExportableMXFP8Tensor` (extension/llm/export/mxfp8.py): a torchao tensor
  subclass carrying MLX-native packed weights (uint32 qdata, uint8 E8M0 block
  scales, group_size 32, 8-bit FP8), with a registered `torchao::dequantize_mxfp8`
  custom op so the dequant survives torch.export, and a payload-preserving `.to()`
  so activation-dtype casts do not dequantize it.
- NVFP4 (extension/llm/export/nvfp4.py): add the same payload-preserving `.to()`
  so block-scaled weights survive `model.to(activation_dtype)` instead of being
  dequantized.
- MLX backend lowering (backends/mlx/patterns.py, backends/mlx/builder/op_helpers.py):
  add `parse_dequant_mxfp8_node` and MXFP8 linear/embedding pattern handlers that
  emit the MLX `mode="mxfp8"` quantized matmul / gather (group_size 32, bits 8).
  The bundled MLX runtime already accepts this mode, so no C++/runtime changes.
- Fusion (extension/llm/export/quant/convert.py): extend `fuse_along_output` and
  `maybe_cast` to handle the NVFP4 / MXFP8 carrier tensors (the per-tensor scale
  is treated as a shared, assert-equal field rather than concatenated).
- Checkpoint loader: unify the MLX reader to resolve each weight's quant mode
  per-tensor from `config.json` (a default mode plus per-module overrides) and
  build the matching representation -- affine -> torchao intx, nvfp4 ->
  ExportableNVFP4Tensor, mxfp8 -> ExportableMXFP8Tensor -- so mixed-format
  checkpoints load correctly from a single path.

Reviewed By: Gasoonjia

Differential Revision: D113113318
@metascroy
metascroy force-pushed the export-D113113318 branch from 7247ffc to f652c5d Compare July 22, 2026 23:35
Summary:

Add MXFP8 block-scaled float quantization support to the MLX backend, alongside
the existing NVFP4 path, and unify the MLX safetensors checkpoint loader so it can
load block-scaled (NVFP4 / MXFP8) checkpoints directly.

- New `ExportableMXFP8Tensor` (extension/llm/export/mxfp8.py): a torchao tensor
  subclass carrying MLX-native packed weights (uint32 qdata, uint8 E8M0 block
  scales, group_size 32, 8-bit FP8), with a registered `torchao::dequantize_mxfp8`
  custom op so the dequant survives torch.export, and a payload-preserving `.to()`
  so activation-dtype casts do not dequantize it.
- NVFP4 (extension/llm/export/nvfp4.py): add the same payload-preserving `.to()`
  so block-scaled weights survive `model.to(activation_dtype)` instead of being
  dequantized.
- MLX backend lowering (backends/mlx/patterns.py, backends/mlx/builder/op_helpers.py):
  add `parse_dequant_mxfp8_node` and MXFP8 linear/embedding pattern handlers that
  emit the MLX `mode="mxfp8"` quantized matmul / gather (group_size 32, bits 8).
  The bundled MLX runtime already accepts this mode, so no C++/runtime changes.
- Fusion (extension/llm/export/quant/convert.py): extend `fuse_along_output` and
  `maybe_cast` to handle the NVFP4 / MXFP8 carrier tensors (the per-tensor scale
  is treated as a shared, assert-equal field rather than concatenated).
- Checkpoint loader: unify the MLX reader to resolve each weight's quant mode
  per-tensor from `config.json` (a default mode plus per-module overrides) and
  build the matching representation -- affine -> torchao intx, nvfp4 ->
  ExportableNVFP4Tensor, mxfp8 -> ExportableMXFP8Tensor -- so mixed-format
  checkpoints load correctly from a single path.

Reviewed By: Gasoonjia

Differential Revision: D113113318
@metascroy
metascroy force-pushed the export-D113113318 branch from f652c5d to 1a5735a Compare July 23, 2026 21:33
@meta-codesync
meta-codesync Bot merged commit 42fcf94 into pytorch:main Jul 23, 2026
199 of 203 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. meta-exported

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants