support MXFP8 (#21146)#21146
Conversation
🔗 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 PendingAs of commit 1a5735a with merge base 96e87e3 ( This comment was automatically generated by Dr. CI and updates every 15 minutes. |
|
@metascroy has exported this pull request. If you are a Meta employee, you can view the originating Diff in D113113318. |
This PR needs a
|
b55f201 to
7247ffc
Compare
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
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
7247ffc to
f652c5d
Compare
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
f652c5d to
1a5735a
Compare
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.
ExportableMXFP8Tensor(extension/llm/export/mxfp8.py): a torchao tensorsubclass carrying MLX-native packed weights (uint32 qdata, uint8 E8M0 block
scales, group_size 32, 8-bit FP8), with a registered
torchao::dequantize_mxfp8custom op so the dequant survives torch.export, and a payload-preserving
.to()so activation-dtype casts do not dequantize it.
.to()so block-scaled weights survive
model.to(activation_dtype)instead of beingdequantized.
add
parse_dequant_mxfp8_nodeand MXFP8 linear/embedding pattern handlers thatemit 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.
fuse_along_outputandmaybe_castto handle the NVFP4 / MXFP8 carrier tensors (the per-tensor scaleis treated as a shared, assert-equal field rather than concatenated).
per-tensor from
config.json(a default mode plus per-module overrides) andbuild 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