NVIDIA / NVIDIA/TensorRT-LLM

[None][refactor] AutoDeploy: Use PyTorch-native format for NVFP4 weight_scale in IR ops, defer kernel-specific swizzling to fusion passes

Open
#11,988 0 comments 0 reactions 1 assignee View on GitHub

@Fridah-nv is already working on this.

Since Mar 6, 2026.

  • #11991 by @Fridah-nv — closed without merging
AutoDeploy AutoDeploy/llmc-blocker Customized kernels Model optimization
Dominant language
Python
Stars
14.7k
Forks
2.8k
Avg merge
2d 23h
Merged PRs (30d)
489

Description

Summary

The AutoDeploy IR op torch_fake_quant_nvfp4_linear currently stores weight_scale as swizzled uint8 — a CUTLASS-specific format applied during the weight loading transform (quantization.py load hook). This causes problems for downstream consumers (e.g., ONNX export in EdgeLLM, PR #11946) that expect scales in a PyTorch-native dtype (torch.float8_e4m3fn) and un-swizzled layout.

The uint8 dtype is used as a generic byte buffer because the CUTLASS FP4 kernel expects a specific memory layout that doesn't map to any native PyTorch floating-point type. However, coupling the IR op to a specific kernel's format leaks backend assumptions into the shared representation.

Problem

  1. ONNX export misinterprets uint8 weight scales — TensorRT rejects the exported model because it expects float-typed scales (PR #11946).
  2. Swizzled layout is kernel-dependent — different backends (CUTLASS FP4, trtllmgen NVFP4) require different swizzling, so baking one kernel's format into the IR op creates coupling issues.
  3. MoE flow uses torch_quant_nvfp4_linear (the CUTLASS-bound op) directly in quantize_nvfp4_moe instead of the IR op torch_fake_quant_nvfp4_linear, further entangling the IR with a specific backend.

Proposed Design

As discussed, the long-term design should be:

  1. torch_fake_quant_nvfp4_linear everywhere until post-load fusion stage — this is the AutoDeploy IR op for NVFP4 GEMM. Weight scales should be stored in PyTorch-native format (e.g., torch.float8_e4m3fn, un-swizzled, matching the modelopt/unified checkpoint format).
  2. Post-load fusion passes (the ones that swap the IR op for performant kernel backends) are responsible for:
    • Converting weight scales to the kernel-expected format (e.g., CUTLASS swizzled uint8)
    • No runtime modification needed (no performance drop)
    • Different transforms can apply different swizzling as needed
  3. Load hooks should load into the PyTorch-native format (may simplify to no-op if it matches modelopt-native format).
Naming Cleanup
  • Rename torch_quant_nvfp4_lineartrtllm_quant_nvfp4_linear (or similar) to indicate it's a CUTLASS/TRT-LLM-specific op, aligning with AutoDeploy IR naming convention.
  • Rename torch_fake_quant_nvfp4_lineartorch_quant_nvfp4_linear to reflect that it is the canonical IR op (not "fake").

Affected Code

File What needs to change
tensorrt_llm/_torch/auto_deploy/transform/library/quantization.py (L401-429) Remove swizzling from load_hook; keep scales in native format
tensorrt_llm/_torch/auto_deploy/custom_ops/quantization/torch_quant.py Rename ops per naming cleanup
tensorrt_llm/_torch/auto_deploy/transform/library/quantize_moe.py Use IR op (torch_fake_quant_nvfp4_linear) instead of CUTLASS-bound op; add swizzle in MoE fusion pass
tensorrt_llm/_torch/auto_deploy/transform/library/fuse_swiglu.py Update swiglu fusion to handle scale format conversion when replacing IR op with fused kernel op
Post-load fusion passes Add weight scale swizzling + dtype conversion when swapping to performant backends

Phased Approach

Phase 1 (unblocks EdgeLLM / PR #11946)
  • Handle transforms that use torch_fake_quant_nvfp4_linear: remove swizzling from load hook, move it to the post-load fusion pass that replaces with torch_quant_nvfp4_linear.
  • MoE transforms can use a small workaround for now.
Phase 2
  • Update MoE transforms to use torch_fake_quant_nvfp4_linear as the IR op.
  • Revisit MoE unit tests (may need hand-written inputs to avoid fake-quant vs real-quant numerical drift).
  • Apply the op renaming cleanup.

Context

  • EdgeLLM ONNX export PR: #11946
  • Models using swiglu fusion (e.g., GLM 4.7 Flash) — any model with shared experts + silu/mul activation
  • trtllmgen NVFP4 also required re-doing swizzling, confirming it is not standardized across kernels

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.