Skip to content

Add RNNT quantization passes and ONNX MatMulNBits graph surgery - #2761

Open
shaahji wants to merge 3 commits into
mainfrom
shaahji/rnnt
Open

shaahji wants to merge 3 commits into
mainfrom
shaahji/rnnt

Conversation

@shaahji

@shaahji shaahji commented Oct 27, 2026

Copy link
Copy Markdown
Collaborator

Add RNNT quantization passes and ONNX MatMulNBits graph surgery

Introduce RNNT-specific optimization paths without requiring transformer-centric model metadata.

  • Register RnntSelectiveMixedPrecision and RnntGptq passes.
  • Add grouped linear-weight quantization with RTN and shared k-quant parameter selection.
  • Resolve group sizes against layer dimensions and persist quantized state dictionaries.
  • Keep decoder and joint precision unchanged by ignoring their per-module precision overrides.

Add configurable MatMul-to-MatMulNBits graph conversion:

  • Reuse ONNX k-quant packing and canonical initializer naming.
  • Support per-node settings, wildcard exclusions, accuracy levels, and progress logging.
  • Preserve graph outputs and rewire intermediate consumers.
  • Reuse shared quantized initializers and remove unused weights.
  • Provide a standalone RemoveUnusedInitializers surgery.

Load Hugging Face configuration before resolving task model classes, retain the required AutoConfig import, and add external-data serialization diagnostics.

Add regression tests for RNNT quantization, shared k-quant parameters, MatMulNBits conversion and naming, initializer reuse and cleanup, and external-data serialization.

Checklist before requesting a review

  • Add unit tests for this change.
  • Make sure all tests can pass.
  • Update documents if necessary.
  • Lint and apply fixes to your code by running lintrunner -a
  • Is this a user-facing change? If yes, give a description of this change to be included in the release notes.

(Optional) Issue link

Introduce RNNT-specific optimization paths without requiring
transformer-centric model metadata.

- Register RnntSelectiveMixedPrecision and RnntGptq passes.
- Add grouped linear-weight quantization with RTN and shared
  k-quant parameter selection.
- Resolve group sizes against layer dimensions and persist
  quantized state dictionaries.
- Keep decoder and joint precision unchanged by ignoring their
  per-module precision overrides.

Add configurable MatMul-to-MatMulNBits graph conversion:
- Reuse ONNX k-quant packing and canonical initializer naming.
- Support per-node settings, wildcard exclusions, accuracy levels,
  and progress logging.
- Preserve graph outputs and rewire intermediate consumers.
- Reuse shared quantized initializers and remove unused weights.
- Provide a standalone RemoveUnusedInitializers surgery.

Load Hugging Face configuration before resolving task model classes,
retain the required AutoConfig import, and add external-data
serialization diagnostics.

Add regression tests for RNNT quantization, shared k-quant parameters,
MatMulNBits conversion and naming, initializer reuse and cleanup,
and external-data serialization.
- Save through ir_model_to_olive_model to match ONNX k-quant
- Preserve output-directory creation and initializer deduplication
- Test inline/external weights, output paths, and deduplication modes

Resolves the observed ~134 MB encoder size overhead from protobuf saving.
Copilot AI balanced review requested due to automatic review settings October 27, 2026 17:42
Comment thread olive/passes/onnx/graph_surgeries.py Fixed
Comment thread olive/passes/onnx/graph_surgeries.py Fixed
Comment thread olive/passes/pytorch/rnnt_gptq.py Fixed
Comment thread olive/passes/pytorch/rnnt_gptq.py Fixed
Comment thread test/passes/onnx/test_graph_surgeries.py Fixed
Comment thread test/passes/onnx/test_graph_surgeries.py Fixed
Comment thread test/passes/onnx/test_graph_surgeries.py Fixed
Comment thread test/passes/onnx/test_graph_surgeries.py Fixed

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.

🟡 Changes recommended

Unresolved checkpoint handoff and graph-rewrite defects can discard quantization results or produce invalid ONNX models.

7 open issues
What changed in this PR

This PR adds RNNT-specific quantization paths to Olive without relying on transformer metadata, alongside configurable ONNX MatMulNBits graph conversion.

Changes:

  • Register RNNT mixed-precision and grouped weight-quantization passes using RTN or shared k-quant parameters.
  • Add MatMulNBits conversion and unused-initializer cleanup, with regression tests.
  • Update graph serialization and load Hugging Face configuration before resolving task model classes.
File Description
test/​passes/​pytorch/​test_rnnt_quantization.py Tests RNNT metadata and quantized weights.
test/​passes/​onnx/​test_graph_surgeries.py Tests conversion, initializer reuse, cleanup, and serialization.
olive/​passes/​pytorch/​rnnt_selective_mixed_precision.py Adds RNNT mixed-precision metadata generation.
olive/​passes/​pytorch/​rnnt_gptq.py Adds grouped RNNT weight quantization and checkpoint saving.
olive/​passes/​onnx/​graph_surgeries.py Adds quantization surgeries and switches to IR-based serialization.
olive/​olive_config.json Registers the RNNT passes.
olive/​common/​hf/​utils.py Loads model configuration before task-class resolution.

Review effort: Balanced

Comment thread olive/passes/onnx/graph_surgeries.py Outdated
Comment thread olive/passes/onnx/graph_surgeries.py Outdated
Comment on lines +2357 to +2361
if not is_graph_output:
for downstream in graph.node:
for i, downstream_input in enumerate(downstream.input):
if downstream_input == old_output_name:
downstream.input[i] = new_output_name
Comment thread olive/passes/onnx/graph_surgeries.py Outdated
Comment thread olive/passes/onnx/graph_surgeries.py
Comment thread olive/passes/pytorch/rnnt_gptq.py Outdated
Comment thread olive/passes/pytorch/rnnt_gptq.py

@github-advanced-security github-advanced-security 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.

lintrunner found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.

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.

🟡 Changes recommended

Critical defects can invalidate ONNX graphs through unsafe value renaming and unsupported block sizes, while quantized checkpoint loading depends on unbundled source resources and can mix CPU weights with CUDA parameters.

5 open issues
1 previously missed issue

In code that hasn't changed since last review

Medium severity Check shared-weight cache before quantization

olive/​passes/​onnx/​graph_surgeries.py:2280

The shared-weight cache is checked only after _kquant_block_quant has already run. Consequently, every MatMul using the same weight and settings repeats the full k-quant search and packing, then discards the duplicate arrays; only initializer storage is reused. Check (weight_name, node_bits, node_block_size) before quantization and run the expensive work only on a cache miss, especially for large shared weights.

6 resolved since last review

Review effort: Balanced

logger.debug("MatMul weight is not 2D. Skip quantization of %s.", node_name)
continue

node_bits, node_block_size = self._resolve_node_config(node_name)
b_quant_name, scales_name, zero_point_name = qparam_names[quantization_key]
old_output_name = node.output[0]
is_graph_output = any(output.name == old_output_name for output in graph.output)
new_output_name = f"{old_output_name}_Q{node_bits}" if not is_graph_output else old_output_name

def load_quantized_rnnt_model(model_path):
checkpoint = torch.load(model_path, map_location="cpu", weights_only=False)
model = ModelConfig.from_json(checkpoint["model_config"]).create_model().load_model(cache_model=False)
raise ValueError("Quantized RNNT checkpoint does not match the original model architecture.")
for name, weight in quantized_weights.items():
module_name, _, parameter_name = name.rpartition(".")
install_quant_tensor_param(model.get_submodule(module_name), parameter_name, weight)

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants