New Features
Sparsity
- Add skip-softmax calibration through vLLM for FlashAttention and FlashInfer, requiring
--validation_prompts_fileand validating serving sparsity on calibration and held-out prompts before exporting prefill/decode fits and their validation scope assparse_attention_config. Calibration uses single-sequence, unchunked eager execution; serving preserves the calibrated 128-token KV-tile granularity and 128-row prefill Q tiles, autotunes only its execution schedule, and uses a smaller Q tile for one-token decode. - Sparse-only vLLM installs now reject unsupported DCP, DBO/ubatching, speculative decoding, and FULL mixed-batch CUDA graphs; calibrated decode also rejects FULL decode graphs.
Quantization
- Add metadata-only export specifications and non-mutating per-weight quantizer-state capture.
- Add functional quantized-weight packing, topology-aligned state merge/select and transport APIs, and canonical Hugging Face quantization-config construction.
- HF export records canonical activation schemes, group/block sizes and weight-only MXFP4 metadata; mixed-format exports retain unquantized-layer exclusions, and non-square FP8 block layouts are rejected.
- Add Q8_0 weight-only quantization with 32-value GGML blocks, packed unified HF and Megatron export, and a built-in
q8_0PTQ recipe. - Add Hugging Face PTQ calibration and export support for Nemotron-H MTP modules, preserving calibrated expert input scales.
- Add the
models/nvidia/NVIDIA-Nemotron-3.5-Super-VL-120B-A12B-BF16/ptq/nvfp4-msePTQ recipe, the PTQ stage for NVIDIA Nemotron 3.5 Super VL: weight-MSE calibrated NVFP4 routed and shared MoE experts, FP8 attention projections, Mambain_proj/out_projandlm_head, and an FP8 KV cache. The latent MoE, router, embeddings and the vision and audio encoders stay in BF16, and the MTP rules apply only to checkpoints that carry an MTP tail. It reproduces the released precision assignment, not the released weights: the published NVFP4 checkpoint adds quantization-aware distillation after this stage. - Backfill checkpoint aliases for three more published NVFP4 releases:
moonshotai/Kimi-K2.7-Code,google/gemma-4-26B-A4B-itandgoogle/diffusiongemma-26B-A4B-it. Each imports an existing general recipe wholesale rather than copying its body. - Backfill checkpoint aliases for nine more published NVFP4 releases, so each is reachable from its source model's hub path:
zai-org/GLM-5.1andGLM-5.2,MiniMaxAI/MiniMax-M2.5andMiniMax-M3,deepseek-ai/DeepSeek-V3.1andDeepSeek-V3.2,Qwen/Qwen3-235B-A22B-Instruct-2507and-Thinking-2507, andQwen/Qwen3.6-27B. Each imports an existing general or architecture recipe wholesale rather than copying its body. - Add composed Hugging Face AutoQuantize recipes that run fixed PTQ or weight AutoQuantize before
a separate KV-cache AutoQuantize stage, with independent resumable checkpoints for the weight and
KV searches. Uniform-weight plus layer-wise mixed-KV exports are marked unsupported for deployment
until a runtime consumes that metadata combination. - Add IQ1_S and IQ2_XS weight-only quantization with GGML-compatible 256-value block encoders, built-in
iq1_s/iq2_xsPTQ recipes, and unified HF and Megatron export of the packed blocks. Quantized weights must have a final dimension divisible by 256, and Megatron export requires tensor and pipeline parallel sizes of 1. - Add
iq2_xxsweight-only quantization with a CUDA encoder and ageneral/ptqrecipe, at 2.0625 bits per weight betweeniq1_sandiq2_xs. The same 256-value block constraint applies. - Add
iq2_sweight-only quantization with a CUDA encoder and ageneral/ptqrecipe, at 2.5625 bits per weight aboveiq2_xs. The same 256-value block constraint applies. - Add
iq1_mweight-only quantization with a CUDA encoder and ageneral/ptqrecipe, at 1.75 bits per weight betweeniq1_sandiq2_xxs. The same 256-value block constraint applies. - GPTQ (
algorithm: {method: gptq}) now supports the GGML formats (iq1_s,iq1_m,iq2_xxs,iq2_xs,iq2_s,q8_0). Each GGML block is quantized as a whole and its error compensated in the later columns, and export writes exactly the codes GPTQ chose.block_sizemust be a multiple of the format's block size (256 for the IQ formats). The built-iniq1_s,iq1_m,iq2_xxs,iq2_xsandiq2_srecipes now quantize only the MLP/MoE weights and calibrate them with GPTQ, so they need calibration data. - The
iq1_s,iq1_m,iq2_xxs,iq2_xsandiq2_sencoders accept an optional per-input-columnimportancethat weights each value's squared error in the codebook search, as llama.cpp's imatrix does. GPTQ's newimportance_weightedoption passes them the square root of its Hessian diagonal, and the built-in IQ1 and IQ2 recipes enable it, so each block's search favours the columns its outputs depend on most. - A recipe can now delegate its whole body to another recipe with a top-level
$import; any top-level key given alongside it overrides the imported one.metadata.recipe_typebecame optional along with it: a recipe states its kind with a# modelopt-schema:comment, withmetadata.recipe_type, or by delegating to a recipe that does, and only a recipe that another file imports has to carry the schema comment. Whatever a recipe does state must be true: a schema comment and arecipe_typemust agree, and so must a recipe and the recipe it delegates to.modelopt_recipes/models/uses this for checkpoint entries that a portable recipe already reproduces: the entry aliases that recipe instead of copying it. - Backfill the recipes behind NVIDIA's already-published checkpoints under
modelopt_recipes/models/, so a released checkpoint's quantization scheme is reachable from its own model-hub path rather than only from the general tier. For example,moonshotai/Kimi-K2.6(published asnvidia/Kimi-K2.6-NVFP4) andQwen/Qwen3.5-397B-A17B(published asnvidia/Qwen3.5-397B-A17B-NVFP4-V2) each alias a portable recipe wholesale -- the general expert-only NVFP4 recipe and theqwen3_5_moearchitecture recipe respectively -- rather than copying its body; other checkpoints follow in separate changes. - Add
layerwise.export_dir: layerwise calibration writes each decoder layer to its own quantized checkpoint shard as it finishes, so no separateexport_hf_checkpoint()pass is needed and, withlayerwise.checkpoint_dir, an interrupted run resumes without redoing finished layers. Calibration writes the layer shards;finalize()on the exporter left on the model adds the tail shard, the index and the config artifacts, and the checkpoint does not load until it runs.examples/hf_ptqdoes this for you. Supports FP8 and NVFP4 on single-process models, resident or offloaded, including multimodal models and models with MTP layers; other formats and placements raiseNotImplementedErrorbefore calibration starts. - Add support for quantizing and calibrating enabled operators outside the transformer layers, such as
lm_head, when using layerwise calibration. - Add an end-to-end BEVFormer ONNX PTQ example with temporal calibration data generation, INT8 and FP8 quantization, TensorRT engine building, and nuScenes accuracy evaluation. See examples/onnx_ptq/bevformer/README.md for details.
- Add a reusable local-Hessian NVFP4 PTQ recipe and the quantization recipe used for
nvidia/Qwen3.8-27B-NVFP4. - Add experimental dynamic FP8 fake quantization of GatedDeltaNet chunk-boundary states and WY activations for training through the standard
quant_cfginterface. The fused GDN path requiresfla-core==0.5.1and chunk size 64; state emulation requires SM89 or newer. - Add fake quantization of the sparse-attention indexer key cache and query for DeepSeek-V4 (vLLM and Megatron-Core) and GLM-5.3-Flash (vLLM) through the new
indexer_k_quantizerandindexer_q_quantizer. Enable them by importing theconfigs/ptq/units/indexer_k_nvfp4andconfigs/ptq/units/indexer_q_nvfp4units (NVFP4 with the global scale fixed to 1) into a recipe. - Add
indexer_scorer_kwargs_quantizerto pass keyword arguments, such as the numerics options of a DeepGEMM build, to the DeepGEMM indexer scorer kernel of GLM-5.3-Flash per layer in vLLM fake-quant serving; see examples/vllm_serve/README.md. - Add the
configs/ptq/units/kv_nvfp4_mlarecipe unit for fake quantization of the MLA KV cache (DeepSeek-V3, GLM-5.3-Flash, ...) in vLLM fake-quant serving: NVFP4 for the latent and FP8 for the RoPE key. See examples/vllm_serve/README.md for an example recipe. - Add fake quantization of MoE expert-parallel communication to vLLM fake-quant serving through the new
dispatch_quantizerandcombine_quantizeron vLLM's routed experts, for MoE layers built on vLLM's fused-MoE layer and any all-to-all backend, and for the DeepGEMM Mega-MoE kernel of DeepSeek-V4 and Kimi-K3 (--moe-backend deep_gemm_mega_moe). Enable them by importing theconfigs/ptq/units/moe_dispatch_nvfp4andconfigs/ptq/units/moe_combine_nvfp4units into a recipe; seeexamples/vllm_serve/README.md. - vLLM fake-quant serving now runs on pre-quantized checkpoints such as FP8 when the recipe leaves those layers unquantized (for example a KV-cache-only recipe), and on MLA models with an FP8 KV cache; both previously failed during quantization.
KV_QUANT_CFGpresets in vLLM fake-quant serving now quantize the MLA KV cache; on vLLM 0.16 and later they silently quantized nothing for MLA models.- vLLM fake-quant serving of NVFP4 and cast-mode KV-cache configs no longer needs
--enforce-eager.examples/vllm_serve/vllm_serve_fakequant.pynow setsVLLM_DISABLE_COMPILE_CACHE=1for fake-quant serves by default, because a cached torch.compile graph of the same model without the fake quant would otherwise be reused. examples/deepseek/deepseek_v4/ptq.pynow supports DeepSeek-V4.1-Flash, whose reference implementation uses 32x32 FP8 blocks and a tokenizer-awareTransformer; this is the setup used to producenvidia/DeepSeek-V4.1-Flash-NVFP4. DeepSeek-V4-Pro checkpoints work as before.
Speculative Decoding
- Add the DFlash2 draft variant, selected with
dflash_architecture_config.projector_type="dflash2": DFlash's one-pass parallel backbone plus a grouped dynamic convolution around every attention/MLP sublayer (conv_kernel_size/conv_group_size) and a low-rank candidate selector (selector_rank/selector_top_k, weighted bydflash_selector_loss_alpha). Exported checkpoints declareDFlash2DraftModeland load in the SGLang/vLLM DFlash2 serving path. - LiLiCorr now trains offline and in streaming mode, not only online: the target logits its distractor penalty reads are reconstructed from the captured final hidden state, the same path self-logit distillation uses.
- Add
dflash_lilicorr_w_cal(default0.0, off): an optional LiLiCorr proposal-calibration term, a KL divergence from the target's distribution over each slot's candidates to the reranker's candidate distribution, usable in place of the distractor penalty. examples/speculative_decoding/distributed_generate/server_generate_vlm_sglang.py--api_mode openaiworks against any OpenAI-compatible server, including vLLM, and gains--media_inlineto send media as base64data:URIs. Without--media_url_baseor--media_inlinethe media path is still passed through verbatim, which only servers that read their own filesystem resolve (SGLang native does; vLLM needs--allowed-local-media-path); that case now warns.
Megatron Framework (M-LM / M-Bridge)
- Add chat-data distillation to
examples/megatron_bridge/distill.py:--sft --sft_hf_datasettakes a local chat.jsonlor a Hugging Face Hub dataset, renders each conversation with the model's chat template, and--sft_loss_modeselects which turns are trained. Requires a Megatron-Bridge withDirectHFSFTDatasetConfig. - Add
freeze_mtpto the MegatronDistillationConfig(--freeze_mtpinexamples/megatron_bridge/distill.py): the student's MTP head keeps its input weights and its loss is skipped, so distillation trains the rest of the model on the distillation loss alone. - Add
output_format: chat_jsonltoprepare_megatron_data_blend: it writes a weighted blend astrain.jsonl/validation.jsonlchat data fordistill.py --sft --sft_hf_dataset, so the distillation loss can be restricted to assistant tokens. See the Megatron data preparation guide. - Add mergeable LoRA QAD for fake-quantized dense Megatron/Transformer Engine linear layers. Enable it with
--lora_rankin Megatron-Bridge PTQ, train through the normal QAD flow, and export a standalone quantized checkpoint without deployment adapters. - Add optional Top-P (nucleus) truncation to the Megatron top-k logits KD loss (now
TopLogitsKLLoss) vialogit_kl_top_pandlogit_kl_top_p_min_kinDistillationConfig: after the global Top-K selection, only the smallest prefix whose cumulative teacher probability reachestop_p(with a floor ofmin_kentries) contributes to the KL, mirroring--logits-save-top-p/--logits-save-top-p-min-kin Megatron-LM's logits saver. - Add an end-to-end W4A4 NVFP4 PTQ and QAD tutorial for Qwen3.6-35B-A3B also covering evaluation and vLLM throughput benchmarking. See examples/megatron_bridge/tutorials/Qwen3.6-35B-A3B/README.md for details.
- Add
--mlflow <tracking-uri>to theexamples/megatron_bridgescripts that write a checkpoint --prune_minitron.py,quantize.py,distill.py,export_quantized_megatron_to_hf.pyandexport_distilled_megatron_to_hf.py(MLflow's ownMLFLOW_TRACKING_URIis honoured too). Each run records the invocation, its arguments as searchable params and its log -- a distillation records its training metrics instead of the rank-0 log -- and writes.experiment.jsoninto the checkpoint it produced, so a pruning, a quantization, the distillation that refines its checkpoint and the export that deploys it can be traced to one another; uploading the checkpoints themselves stays off unless--mlflow_log_checkpointsis passed. - Add
--ep_sizetoexamples/megatron_bridge/export_quantized_megatron_to_hf.pyso large MoE models with grouped-GEMM experts can be exported with their experts sharded across GPUs. Checkpoints built with--no_moe_grouped_gemmmust still be exported at--ep_size 1. - Add unified HF export of GLM-5 / GLM-5.2 (
glm_moe_dsa) checkpoints quantized withexamples/megatron_bridge. The MTP layer, which Megatron-Bridge does not build for these models, is copied through unquantized from the source checkpoint. DSA sparse-attention models also gain FP8 KV-cache quantization on Megatron.
Misc
-
Add
--modelopt-*options to theexamples/vllm_servelauncher for fakequant calibration and checkpoint reload. Point it at an exported fakequant model directory to reload automatically: Hugging Face exports usevllm_fq_modelopt_state.pth, while Megatron-Core exports now includequant_recipe.yamlalongsidequantizer_state.pthfor reload. -
Add a
kd_loss_alphaoption to HuggingFaceKDTrainerto blend cross-entropy and knowledge distillation losses during training. -
A tracked
examples/hf_ptq/hf_ptq.pyrun now writes.experiment.jsoninto--export_pathand uploads the same file with the run, so a checkpoint on disk names the experiment and MLflow run id that produced it. The pointer is written only once the export completes, and an export that is not tracked removes one it would otherwise inherit from a reused--export_pathor from a quantized source checkpoint. -
export_hf_checkpointand the vLLM fake-quant export now copy the source checkpoint's non-model files (tokenizer, processor, remote code, chat templates, ...) into the export unchanged. They read the source from local disk only: get a local copy of a Hugging Face Hub model withmodelopt.torch.export.ensure_local_checkpointand load it from there. -
Add Parallel Decoding Distillation (PDD) to
modelopt.torch.fastgenwith Qwen-Image training, distributed-checkpoint export, and PDD-2/4/8 inference. AutoModel remains an unmodified pinned runtime dependency.
Backward Breaking Changes
-
modelopt.torch.utils.distributed.broadcast/allgathernow reject objects of unregistered custom classes. Register them withtorch.serialization.add_safe_globals. -
Bump minimum transformers version to
5.5instead of4.57; transformers 4.x is no longer supported. Upgrade withpip install -U "nvidia-modelopt[hf]". -
modelopt.torch.distill.plugins.megatron.TopKLogitsKLLoss(logit_kl_topkinDistillationConfig) is renamed toTopLogitsKLLoss, keeping the old name as a deprecated alias. It now normalizes both distributions over the full vocabulary instead of re-normalizing over the Top-K entries, and always appends a "ghost" token holding the probability mass outside the Top-K to both student and teacher (matching Megatron-LM's offline cached-logits KD loss). Loss values change for existinglogit_kl_topkruns. -
LogitsAndIntermediatesLossBalancer(Megatron distillation plugin) no longer rescales the distillation loss to the magnitude of the LM loss when the LM loss is included. The total is now the fixed convex combination(1 - alpha) * lm_loss + alpha * kd_losswithDistillationConfig.kd_loss_alpha(in [0, 1]), matching Megatron-LM's offline cached-logits KD. The defaultkd_loss_alpha=1.0skips the LM loss, as before.DistillationConfig.skip_lm_lossandkd_loss_scaleare removed and raiseValueErrorif passed; setkd_loss_alphainstead. Inexamples/megatron_bridge/distill.py,--kd_loss_alphareplaces--no_skip_lm_lossand--kd_loss_scale. -
The
examples/vllm_servefakequant launcher no longer supports vLLM 0.9.0. Upgrade to a version listed as tested in the example README. -
The Megatron-Core DeepSeek-V4 indexer (
CSAIndexer) is now a quantization module and persists its quantizer state in the checkpoint asindexer._extra_state. A DeepSeek-V4 model quantized with an earlier release resumes from itstorch_distcheckpoint only with a non-strict load (--dist-ckpt-strictness log_unexpectedin Megatron-LM) until it is saved again. -
examples/hf_ptqno longer detects MTP layers by name. Checkpoint weights the model has no parameter for -- an MTP head, an auxiliary tower -- are worked out once, when the model loads, and carried into the export unchanged. Load with the newmodelopt.torch.utils.plugins.model_load_utils.load_pretrained, ashf_ptqdoes, to record them then;export_hf_checkpointworks them out itself for a model loaded another way. Everything the loader did place goes through the normal export path. This removesload_mtp_weights,mtp_layer_prefixes_from_checkpointand their support matrix of MTP storage conventions, along with_add_mtp_exclusionsand the pre-quantizationenable: Falseentrieshf_ptqappended to the recipe'squant_cfg. Two consequences: MTP layers now follow the recipe like any other module instead of being force-excluded by the script -- matchingexamples/megatron_bridge, which has no MTP-specific code at all -- andquantization_config.ignorecan no longer claim a layer is unquantized that the export in fact quantized. Recipes importingconfigs/ptq/units/default_disabled_quantizersstill disablemtp.*, so their behaviour is unchanged; a recipe omitting that unit will now quantize an MTP the model actually built. -
examples/hf_ptq --vllm_fakequant_exportnow raisesNotImplementedErrorwhen the checkpoint holds weights the model has no parameter for and a shard actually provides them (an MTP head, an auxiliary tower). The fake-quant exporter writes only model-backed state, so it would otherwise drop those weights silently -- and a fake-quant checkpoint is evaluated, where a missing head changes the score rather than failing loudly. Use the unified HF export, which carries them through. Buffers Transformers recomputes are not weights to lose:*.inv_freqis skipped even when a shard provides it, since older Llama/Mistral-lineage conversions do list it in the index and refusing an export over it would reject checkpoints that export correctly today. The check runs immediately after the model loads, not at export time, so an incompatible run fails before calibration rather than after it. -
The
modelopt.onnx.quantization.ort_patchingmodule has been removed with no
compatibility shim; update direct imports to useort_sessionfor model loading
and session setup,ort_calibrationorort_calibration_per_nodefor calibration,
ort_quantizationfor static Q/DQ quantization, andort_patchesfor patch composition. -
The
modelopt.onnx.quantization.graph_utilsmodule has been removed with no
compatibility shim; update direct imports using this migration map:modelopt.onnx.quantization.graph_indexing:expand_node_names_from_patterns,
find_mha_partitions,get_fusible_backbone,
get_tensor_consumer_node_indices,get_tensor_consumer_nodes,
get_tensor_from_name,get_tensor_producer_nodes,has_const_input,
has_path_type,is_const_input, andmatch_fp8_mha_pattern.modelopt.onnx.quantization.graph_selection:find_nodes_from_convs_to_exclude,
find_nodes_from_matmul_to_exclude,find_nodes_from_mha_to_exclude,
find_nodes_to_exclude,get_extended_model_outputs,get_input_shapes,
andvalidate_op_types_spelling.modelopt.onnx.quantization.graph_rewrites:cast_custom_ops,
convert_fp16_io,insert_fp8_mha_casts,insert_matmul_casts,
remove_output_initializers, andremove_redundant_cast_nodes.modelopt.onnx.quantization.qdq_graph:build_non_residual_input_map,
classify_partially_quantized_weighted_ops,classify_partition_nodes,
filter_quantizable_kgen_heads,find_conv_to_layernorm_nodes,
get_concat_eliminated_tensors,get_layer_info,
get_layer_precision_mapping,get_resize_scales,print_stat,
remove_partial_input_qdq,should_quantize_to_8bit, and
validate_8bit_layers.
-
Layerwise calibration now uses prior-layer QDQ activations by default
(layerwise.get_qdq_activations_from_prev_layer=True). Set it toFalseto
preserve full-precision activations for subsequent layers (the default behavior for
max calibration without layerwise calibration). -
get_te_hybrid_stack_specwas removed frommodelopt.torch.nas.plugins.megatron; it had no use outside tests. Usemodelopt.torch.utils.plugins.megatron_layer_specs.te_hybrid_stack_spec_sequential_mlpfor the SequentialMLP layout, ormegatron.core.models.hybrid.hybrid_layer_specs.hybrid_stack_specfor grouped GEMM. -
Unified HuggingFace export now fails with
NotImplementedErrorwhen it meets an MoE block whose expert projection names it does not know, instead of assuming Mixtral'sw1/w2/w3. If you hit this, register aModelSpecfor the model undermodelopt/torch/models/. Every MoE architecture ModelOpt exported correctly before this change is registered, so no supported model regresses. -
--recipe(andmodelopt.recipe.load_recipe) now resolve a recipe path filesystem-first: a recipe of the same relative path in the current working directory takes precedence over the shipped built-in of that name, matching how recipe$importpaths already resolve. Previously the built-in won.
Deprecations
- The Diffusers ONNX export and TensorRT engine deployment workflow is deprecated and will be removed no earlier than 0.49.0, after the one-release migration period. Export unified Hugging Face checkpoints with
--hf-ckpt-dirand follow the diffusion deployment guide to select a compatible backend. - The
examples/vllm_serveQUANT_CFG/KV_QUANT_CFGenvironment variables and their
--modelopt-quant-cfg/--modelopt-kv-quant-cfgflags will be deprecated in a future release.
For new runs, use a PTQ recipe viaRECIPE_PATHor--modelopt-recipe-path; unset the old
variables when switching because the launcher rejects mixing them with a recipe. - KV-domain searches in
examples/hf_ptqnow use--kv_auto_quantize_checkpoint;
--auto_quantize_checkpointremains a deprecated fallback for a KV-primary recipe for one
release. - Rename the architecture-specific recipe tier from
modelopt_recipes/huggingface/tomodelopt_recipes/model_type/to clarify that it holds recipes shared across every checkpoint of a Hugging Facemodel_type. Saved--recipe huggingface/<model_type>/...paths still resolve via a backward-compatibility alias but now emit aFutureWarning, so update them tomodel_type/<model_type>/...as thehuggingface/prefix is deprecated. - The single-format quantization CLI flags are deprecated in favour of
--recipeand will be removed in a future release; passing one now emits aFutureWarning.examples/hf_ptq:--qformatand--kv_cache_qformat.examples/megatron_bridge/quantize.py:--quant_cfg,--kv_cache_quantand--weight_only.examples/torch_onnx/torch_quant_to_onnx.py:--qformat. A recipe carries the quantization config, the calibration algorithm and the KV-cache setting in one file, so they cannot drift apart the way separate flags can -- and--recipealready took precedence over all six, silently onhf_ptqand with a warning onmegatron_bridge-- with one gap the recipe closes rather than inherits: a weight AutoQuantize recipe that omitskv_cachestill falls back to--kv_cache_qformat, so setkv_cachein the recipe when migrating. Use a recipe frommodelopt_recipes/general/ptq/, an architecture-specific one undermodelopt_recipes/model_type/<model_type>/, or a checkpoint-specific one undermodelopt_recipes/models/. The warning fires only when a flag is passed explicitly:--qformatdefaults tofp8and--kv_cache_qformattofp8_cast, so warning on the defaults would fire on every run, including runs that correctly use--recipe.examples/speculative_decoding/scripts/quantize_drafter.pykeeps--qformatundeprecated: it has no--recipealternative yet. - The TensorRT-LLM checkpoint export format is deprecated and will be removed in 0.49.0:
export_tensorrt_llm_checkpointandtorch_to_tensorrt_llm_checkpointnow emit aDeprecationWarningon use. Useexport_hf_checkpoint, which exports a unified Hugging Face checkpoint deployable on TensorRT-LLM, vLLM and SGLang. Its implementation moved tomodelopt.torch.export.trtllm, so import those two functions from there and theModelConfigdataclasses frommodelopt.torch.export.trtllm.model_config; both functions remain importable frommodelopt.torch.exportfor this release only. modelopt.torch.export.get_model_typeandmodelopt.torch.export.model_utils.MODEL_NAME_TO_TYPEreturn TensorRT-LLM model names and are deprecated for removal in 0.49.0 (they now emit aDeprecationWarning); use the Hugging Face model type,model.config.model_type, instead.export_tensorrt_llm_checkpointnow detectsdecoder_typewhen it is omitted, andexamples/hf_ptquses Hugging Face model types throughout.- The
evaluationagent skill no longer supports GDPVal: its task recipe, example config and Apptainer SIF helper are removed, and the shared NeMo Gym machinery it carried now lives atreferences/gym.mdwith the launcher wrapper renamedscripts/nel-gym.sh. GDPVal is an AA-suite member, so an "AA" request now generates theaa/tasks only -- report per-task scores rather than an aggregate compared against a published AA Index. - DBRX model support is removed: ModelOpt no longer quantizes or exports DBRX (
DbrxForCausalLM) checkpoints. Use ModelOpt 0.47 to quantize DBRX, or write your own plugin as described in the customized-model quantization guide. - Deprecate
metadata.recipe_typein recipe YAML, for both single-file recipes and a directory recipe'smetadata.yml. A recipe now says what kind it is with a# modelopt-schema:comment naming its schema class, or by delegating to a recipe that does (single-file recipes only -- a directory recipe has no body to delegate through);recipe_typeis still read and still honoured, so a recipe outside this repo keeps working unchanged, but new recipes should leave it out and every recipe shipped here has been converted. Where both are present they must agree, and so must a recipe and the recipe it delegates to -- a disagreement is an error rather than a silent preference.
Bug Fixes
- Fix corrupted ONNX external tensor data when exporting models on Windows by upgrading ONNX. Regenerate affected models from clean weights.
- Fix
import modelopt.torchfailing withModuleNotFoundErrorforrequestsorhuggingface_hubwhennvidia-modeloptis installed without the[hf]extra. - Harden the distributed object broadcast/allgather helpers and the Megatron expert-parallel export gather so a compromised peer rank can no longer execute code through a crafted pickle payload: payloads load with
weights_only=Trueand the export gathers raw bytes instead of pickled objects. - Fix LSQ clamping small, representable FP8 block scales too aggressively, which could zero quantized values and suppress scale gradients.
- Fix ONNX AutoTune benchmark initialization with TensorRT 11 while preserving strongly typed networks on TensorRT 10.
- Keep vision-block Linears in high precision in the
qwen3_vlandqwen3_5FP8 vision recipes so exported checkpoints avoid a vLLM vision-attention shape failure. The recipes still quantize primary and deepstack merger Linears; re-quantize affected checkpoints before deployment. - Fix unified HF export writing a weight name the source checkpoint does not use when a model declares a backwards-compatibility load rename as a reversible
WeightRenaming. Reversing such a rule rewrote the canonical name to a legacy spelling, and a deployment runtime keyed on the canonical name then failed to load the quantized checkpoint. Each exported name is now resolved against the names the source checkpoint actually carries, for both the exported tensors and the quantization config's module references. - Fix exports using the built-in Transformers NemotronH implementation retaining incompatible legacy remote-code config and model mappings. Re-export affected checkpoints before deployment.
- Fix
export_hf_checkpointdropping Diffusers pipeline settings, such as Wan 2.2boundary_ratio, frommodel_index.jsonwhencomponentsis given. Re-export affected checkpoints to a new directory, since component exports do not overwrite an existingmodel_index.json. - Fix INT8 real quantization (
mtq.compress) of FP16 weights zeroing or clipping channels with a small amax: their scales underflowed in FP16. Scales of newly compressed INT8 weights are now stored in FP32. - Fix Hugging Face exports classifying registered Qwen VLM parameters as unplaced source weights, which overwrote quantized tensors with original weights and incorrectly excluded their modules from quantization. Re-export affected checkpoints.
- Right-pad labeled calibration samples to avoid fully masked causal rows that can produce non-finite cuDNN attention gradients during AutoQuantize. Generation previews remove padding before decoding.
- Fix ONNX quantization reusing existing tensor names for scale and zero-point parameters while preserving INT8 calibration-cache lookup. The boolean
--target_dla/target_dla=Truenow preserves scalar multiplication/division operands and padding fill values as constants; use Q/DQ Translator for compatible TensorRT 10.7-and-earlier DLA deployments, or direct Q/DQ with strongly typed DLA enabled in a compatible TensorRT 11.4+ build. - Fix calibration silently dropping samples when an out-of-memory error forces the batch to be
split and a smaller working batch size is already known: the slices stopped tiling the batch,
so the rows between the old and the new width never reached the model and the collected
statistics covered fewer samples than requested. Splitting a batch that holds aNoneentry
no longer raisesTypeErroreither, and a batch holding a value under
allowed_non_tensor_keysnow reports that its rows cannot be split instead. - Fix Megatron unified HF export of MoE models with grouped-GEMM experts when only the experts are quantized (e.g.
nvfp4_experts_only-*recipes):hf_quant_config.jsonand thequantization_configinconfig.jsonwere not written, so the quantized experts were served as unquantized weights. Re-export such checkpoints. - Fix DFlash conversion on NoPE targets whose config leaves
rope_thetaunset. - Fix offline DFlash training failing to reconstruct the target logits when the captured hidden states are stored in a different dtype than the target's weights.
- Fix
hf_ptqoverwriting a model's existingpad_tokenwitheos_tokenwhen the model already has a valid padding token. The exported tokenizer now preserves the source model's padding configuration. - Fix Hugging Face exports dropping off-index safetensors such as GLM-4.7's
mtp.safetensors. - Fix Megatron-Core checkpoint saving for quantized grouped MoE experts when tensor and expert parallelism are both enabled.
- Fix FP8 fake quantization treating a positive amax at or below 2**-24 as zero, which silently zeroed such tensors and channels and every block of a static NVFP4 weight (
NVFP4StaticQuantizer, including LSQ) with a global amax below ~3.6e-7. Fake quantization now matches the exported checkpoint. - Fix
megatron_preprocess_datawithworkers > 1segfaulting when run in a process that has already initialized CUDA or other native threads (for example in-process after GPU work): the tokenization worker pool now uses theforkserverstart method instead offork. - Fix unified HuggingFace export of RADIO-based VLMs retaining post-conversion vision and
projector names instead of restoring the hub layout; deployment loaders could skip those weights.
Streaming, offload, FSDP2, and layerwise export now reject reverse conversions that regroup
tensors; use resident export for those models. - Fix that same reverse rename double-prefixing tensors copied from the source checkpoint rather
than loaded by the model, when a conversion mapping renames a module to a suffix of its original
name. Those tensors already carry the hub name, so C-RADIO towers exported
vision_model.radio_model.radio_model.input_conditioner.norm_mean. Re-export affected
checkpoints. - Fix shared ONNX export metadata and Diffusers attention policy: every
NVFP4QuantExporterpost-process now upgrades the default-domain opset to at least 23, all FP8 custom-op exports re-run ONNX shape/type inference after setting output metadata, and quantized SDPA derives FP8 MHA enablement from the live Q/K/V quantizers instead of honoring a caller-set_disable_fp8_mhaattribute. - Fix ONNX FP16 conversion failing to preserve public output types when type inference changes a graph output declaration before output casts are inserted.
- Fix
examples/hf_ptq/hf_ptq.pydiscarding a completed PTQ run (no checkpoint exported) when the optional post-quantization sanity-checkgenerate()call raised, for example becausedevice_map="auto"placed part of the model on CPU. That failure is now caught and only skips the sanity check; export proceeds regardless. - Fix
examples/megatron_bridge/export_quantized_megatron_to_hf.pystoring the MoE router at Megatron'smoe_router_dtype, which is a routing compute dtype, not a storage one. The router now exports at the exportdtypelike every other unquantized weight, matching whathf_ptq.pyand the released NVFP4 checkpoints contain; passmoe_router_dtypetoexport_mcore_gpt_to_hfexplicitly if you want the old fp32 storage. - Fix unified Megatron export writing a second, unreferenced copy of the vocab embedding when a model with MTP layers is exported with pipeline parallelism. The duplicate was never loaded but inflated the checkpoint by the size of the embedding (about 1 GB for Qwen3.6-35B-A3B); re-export to reclaim the space.
- Fail fast on non-finite AutoQuantize output gradients with an actionable error before accumulating sensitivity scores, without changing attention backend settings.
- Fix ONNX INT8 entropy calibration failing or producing invalid quantization parameters for FP16 activations.
- Fix HuggingFace checkpoint export failing with
activation scaling factor 0.0 not positivewhen a dynamic-block quantizer (such as an NVFP4 input quantizer) ends calibration with an amax of zero because the calibration data never activated that layer or expert. Such a quantizer now exports a positive fallback scale and warns instead of crashing, matching what static quantizers already did; if you see the warning, check whether the layer is expected to be inactive and consider a larger calibration size. - Fix
--use_fsdp2HuggingFace checkpoint export gathering the whole model onto rank 0, which made export the dominant phase of a PTQ run and could exhaust host memory on large models. The model is now split into per-decoder-layer units dealt round-robin across ranks; each rank gathers every unit but keeps, packs, and writes only the ones it owns, so a rank buffers roughlymodel / world_sizeinstead of the whole checkpoint, and rank 0 writes the combined index. Export configurations that cannot be split this way now raise instead of producing a mismatched checkpoint: FSDP2 combined with another DTensor parallelism (for example FSDP2 + tensor parallel on a 2-D mesh; HSDP is supported), models whose decoder layers cannot be discovered, a decoder layer object reused across layers, and a module that holds the decoder layers while owning parameters of its own. - Speed up
mtq.quantizeon FSDP2-sharded fused-MoE models. Promoting static-block weight quantizers gathered each expert's slice of the fused weight across ranks even though only quantizer state is read, adding a collective per expert to calibration. - Add FP8 and INT8 recipes that quantize timm ResNet shortcut inputs immediately before residual adds. The torch ONNX example now accepts PTQ and AutoQuantize recipes through
--recipeand uses--qformatwhen no recipe is provided. ResNet supports only FP8 and INT8 because TensorRT has limited convolution kernel support; AutoQuantize and other quantization formats are no longer supported for ResNet. - Fix
dflash_fp32_master_weightsbeing inert outside HFTrainerand lossy across a resume, by moving the extra precision from the model into the optimizer. The draft now always matches the frozen base's dtype, andMasterWeightAdamWholds an fp32 master copy plus fp32 Adam moments, applies the update in fp32 and writes the result back at the parameter's dtype -- the standard mixed-precision placement. Nothing has to reconcile dtypes at forward time any more, so evaluation,pseudo_speculative_generate(which AR validation calls outside the Trainer's autocast) and a plainmtsp.convert()followed by a forward all behave the same as training; gradients stay in the base dtype, so the DDP gradient all-reduce is no longer doubled; and the exported drafter is unchanged. The training loop has to build the optimizer --examples/speculative_decodingdoes -- andVerifyMasterWeightsCallbackraises after the first step if it did not, rather than letting the flag be silently absent for a whole job.dflash_fp32_master_weightsnow defaults toTrue: with the draft no longer promoted, turning it on changes optimizer memory and optimizer arithmetic but nothing about the model, so every DFlash-family recipe gets it. Set it toFalseto reclaim the memory. - Fix a DDP hang in DFlash training at scale where a rank whose batch contained no valid anchor skipped the draft forward, leaving its rotary buffer list shorter than other ranks' and causing
broadcast_buffersto hang. The buffer is now created duringmodify()before training begins. - Fix
megatron_generatedropping the VLM vision inputs (pixel_values/image_grid_thw/image_sizes) after the first generated token when KV-cache decoding is off, including the automatic fallback under sequence parallelism, which made generation silently ignore the image. No other ModelOpt feature is affected. - Fix two issues in the vLLM offline hidden-state dump (
examples/speculative_decoding/collect_hidden_states/compute_hidden_states_vllm.py) that only surface on large runs. Resume: the filter that skips conversations whose.ptalready exists now runs withload_from_cache_file=False. It depends on on-disk state, which is not part of the fingerprintdatasetscomputes from the function and the dataset, so with a persistent HF cache reused across a resumed or requeued run the cached "keep everything" result from an earlier run was replayed and the dump re-generated and overwrote conversations it had already finished (observed: tens of thousands of.ptrewritten while the output count stayed flat). Staging: generation is now chunked (--save-chunk-size, default 256), so each chunk is saved and its staged hidden states freed before the next chunk is generated. Previously the whole dataset was generated before anything was saved, which kept every conversation staged in the connector'sshared_storage_path(/dev/shm, i.e. RAM, by default) at once and exhausted it partway through large dumps. Chunking also makes the dump incrementally durable, so an interrupted run keeps its finished conversations and resumes from them. The save path now also frees each conversation's staged hidden states in afinally, so a conversation skipped mid-loop (e.g. a shortloss_mask) can no longer leak its staging file, and conversation ids are validated as plain filenames before being used to build output paths. - Fix YAML config I/O decoding with the locale codepage instead of UTF-8, which made a config containing any non-ASCII byte fail to load on a machine whose locale is not UTF-8 (notably Windows, where the default is cp1252).
modelopt/recipe/loader.py, the two ONNX autotune state files, the two transformers config readers, the distill config and the puzzletron profile now passencoding="utf-8"explicitly. Only the YAML config paths are covered: these are the files most likely to carry non-ASCII text in comments, model names or paths, and the only ones read inside a user's process. - Hybrid (e.g. Nemotron-H) checkpoints saved by the
examples/megatron_bridgescripts now record their layer spec inrun_config.yamlin a form that reloads, so they can be converted to HuggingFace; a checkpoint saved by an earlier release still needs itsmodel.hybrid_stack_specblock replaced by hand. - Fix ONNX export of quantized models failing with
Unsupported op_type for real weight quantization: Transposewhen a weight reaches its consumer transposed, as in MaxViT's attention blocks. The same export now also quantizes each weight along the axis its Q/DQ pair declares, correcting silently wrongdq_onlyoutput when that axis differed from the consumer's default. - Fix the
evaluationagent skill's LiveCodeBench recipe scoring correct solutions that use binary standard I/O (sys.stdin.buffer/sys.stdout.buffer) as failures: the recipe now pins a fixed LiveCodeBench judge in the NeMo-Skills container. LiveCodeBench scores change as a result, so re-run earlier baselines before comparing. - Fix GPTQ with Megatron data parallelism: each data-parallel replica of a module now builds its Hessian from the whole calibration set instead of only its own shard, so all replicas reach the same quantized weights.
- Fix
examples/llm_sparsity/weight_sparsity/finetune.pysaving a sharded state dict under FSDP2, the default FSDP version in Transformers 5, which madeexport_hf_ckpt.pyfail to restore it. Re-run finetuning to produce a loadablefinetuned_modelopt_state.pth.