Skip to content

[Coverage] Direct unit-test suites for five untested core modules (conversion, core_utils, tensor_quantizer, model_calib, export/postprocess) — plus bugs found along the way #1902

Description

@arham766

Summary

While auditing test coverage, we found that several load-bearing modules have no direct unit-test file — they are exercised only incidentally through higher-level flows. We wrote hermetic, CPU-only unit suites (per CONTRIBUTING's tests/unit rules: fast, no network, no GPU) for five of them, adversarially reviewed and mutation-checked each suite, and will attach one PR per module so each is reviewable in isolation:

Module Suite Tests
torch/quantization/conversion.py test_conversion.py 63
torch/quantization/utils/core_utils.py test_core_utils.py 128
torch/quantization/nn/modules/tensor_quantizer.py test_tensor_quantizer.py 90 (incl. hand-computed INT8/FP8/block fake-quant values)
torch/quantization/model_calib.py test_model_calib.py 42
torch/export/postprocess.py test_postprocess.py 74 (TP/PP split layouts, padding math)

397 tests, ~4.2k lines, total runtime ~5s. Each suite was verified to kill seeded mutations of its target (wrong scale direction, flipped split axes, broken running-max, etc.), so this is regression-detection capacity, not line-count.

Bugs found while writing these (documented in-test with NOTE: documents current behavior comments; happy to file/fix separately as preferred)

  1. _normalize_fused_experts_quantizer_name collides with SequentialQuantizer child names (introduced in [NVBug 6108145] Fix PTQ calibration and export for fused-experts MoE (Qwen3.5-MoE VLM) #1340: the singular weight_quantizer.<N> pattern matches sequential children). Two consequences, both reproduced: (a) applying the same list-of-configs twice via set_quantizer_attributes_full nests SequentialQuantizers inside sub-slots (non-idempotent, corrupt state); (b) set_quantizer_attributes_partial with a list and a *weight_quantizer wildcard now raises ValueError mid-iteration for targets that are already sequential — a regression against its own docstring. Suggested fix: skip normalization when the matched quantizer's parent is a SequentialQuantizer.
  2. awq() silently no-ops on an unknown algorithm string (public __all__ API; only the mtq.quantize config layer validates the literal). One-line raise ValueError in an else would match the module's fail-fast style.
  3. TensorQuantizer.extra_repr dead code: the disabled branch builds a detailed string, then returns the literal "disabled", discarding it.
  4. update_lm_head_quantization warns "Enable lm_head quantization" even when quantizers are already disabled, and its sole call site (model_config_export.py:323) appears to pass inference_pipeline_parallel into the inference_tensor_parallel parameter.
  5. Minor exception-safety inconsistencies: replace_function/calibrate_with_adapters/enable_fake_quant yield without try/finally (unlike export_torch_mode et al.), so an exception mid-context leaks the patched state.

The behavior-documenting tests are written to fail-and-force-update when these are fixed.

PRs

Will be linked below, one per module, each self-contained.

Activity

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

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions