Skip to content

Commit b8b5eaf

Browse files
committed
Merge branch 'main' into jingyux/2-3-diffusion-export
2 parents 8b29228 + 945ee02 commit b8b5eaf

26 files changed

Lines changed: 1077 additions & 405 deletions

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"--no-cov",
4141
],
4242
"evenBetterToml.schema.enabled": false, // disable toml/json schema since we have custom fields
43-
"python.analysis.extraPaths": [
43+
"cursorpyright.analysis.extraPaths": [
4444
"./tests/" // add tests to python path just like pytest does in pyproject.toml
4545
],
4646
"git.alwaysSignOff": true,

CHANGELOG.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
NVIDIA Model Optimizer Changelog (Linux)
22
========================================
33

4-
0.42 (TBD)
4+
0.42 (2026-02-xx)
55
^^^^^^^^^^^^^^^^^
66

77
**Bug Fixes**
@@ -12,6 +12,7 @@ NVIDIA Model Optimizer Changelog (Linux)
1212

1313
- Add standalone type inference option (``--use_standalone_type_inference``) in ONNX AutoCast as an alternative to ONNX's ``infer_shapes``. This experimental feature performs type-only inference without shape inference, useful as a workaround when shape inference fails or to avoid unnecessary shape inference overhead.
1414
- Add support for Kimi K2 Thinking model quantization from the original int4 checkpoint.
15+
- Add support for ``params`` constraint based automatic neural architecture search in Minitron pruning (``mcore_minitron``) as an alternative to manual pruning (using ``export_config``). See `examples/pruning/README.md <https://github.com/NVIDIA/Model-Optimizer/tree/main/examples/pruning>`_ for more details on its usage.
1516

1617
0.41 (2026-01-19)
1718
^^^^^^^^^^^^^^^^^
@@ -96,7 +97,7 @@ NVIDIA Model Optimizer Changelog (Linux)
9697

9798
**Documentation**
9899

99-
- Add general guidelines for Minitron pruning and distillation. See `examples/pruning/README.md <https://github.com/NVIDIA/Model-Optimizer/tree/main/examples/pruning#pruning-guidelines>`_ for more details.
100+
- Add general guidelines for Minitron pruning and distillation. See `pruning guidelines <https://github.com/NVIDIA/Model-Optimizer/tree/main/examples/pruning#pruning-guidelines>`_ for more details.
100101
- Added example for exporting QLoRA checkpoint for vLLM deployment. Refer to `examples/llm_qat/README.md <https://github.com/NVIDIA/Model-Optimizer/blob/79ef31bc7269ba4da0cfab446da5b64509cbfcef/examples/llm_qat/README.md#qlora-deployment>`_ for more details
101102

102103
0.37 (2025-10-08)

examples/pruning/README.md

Lines changed: 136 additions & 56 deletions
Large diffs are not rendered by default.

modelopt/torch/nas/plugins/megatron.py

Lines changed: 11 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,18 @@
1818
import types
1919
from abc import ABC
2020
from collections.abc import Callable, Sequence
21-
from typing import Any
2221

2322
import torch
2423
import torch.nn as nn
2524
from megatron.core.fusions.fused_layer_norm import FusedLayerNorm
2625
from megatron.core.models.common.embeddings.language_model_embedding import LanguageModelEmbedding
2726
from megatron.core.models.gpt import GPTModel
28-
from megatron.core.parallel_state import (
29-
get_data_parallel_group,
30-
get_pipeline_model_parallel_group,
31-
get_tensor_model_parallel_group,
32-
is_pipeline_first_stage,
33-
is_pipeline_last_stage,
34-
)
27+
from megatron.core.parallel_state import is_pipeline_first_stage, is_pipeline_last_stage
3528
from megatron.core.tensor_parallel.layers import (
3629
ColumnParallelLinear,
3730
RowParallelLinear,
3831
VocabParallelEmbedding,
3932
)
40-
from megatron.core.transformer import MegatronModule
4133
from megatron.core.transformer.attention import SelfAttention
4234
from megatron.core.transformer.dot_product_attention import DotProductAttention
4335
from megatron.core.transformer.mlp import MLP
@@ -51,29 +43,14 @@
5143
from modelopt.torch.nas.modules import DynamicModuleList
5244
from modelopt.torch.opt.dynamic import DynamicModule
5345
from modelopt.torch.opt.hparam import HPType
54-
from modelopt.torch.opt.searcher import ConstraintsDict
5546
from modelopt.torch.trace import Symbol
5647
from modelopt.torch.utils import distributed as dist
57-
from modelopt.torch.utils import (
58-
get_module_device,
59-
make_divisible,
60-
param_num_from_forward,
61-
print_rank_0,
62-
random,
63-
)
48+
from modelopt.torch.utils import make_divisible
6449

65-
from ..algorithms import (
66-
MODULE_TYPE_TO_CONSTRAINTS_FUNC,
67-
ConstraintEvalFunc,
68-
ConstraintInterpolator,
69-
ConstraintsFunc,
70-
ConstraintsRes,
71-
)
7250
from ..hparams.concat import build_concat_hp
7351
from ..modules import _DynamicLayerNorm
7452
from ..modules.utils import get_sliced_tensor, get_sliced_tensor_by_slices
7553
from ..registry import DMRegistry
76-
from ..search_space import SampleFunc
7754
from ..traced_hp import TracedHp
7855

7956
SUPPORTED_MODELS = {GPTModel: "megatron.core.models.gpt.GPTModel"}
@@ -634,7 +611,6 @@ def modify(
634611

635612
def _export_reinit_token_dispatcher(self) -> None:
636613
"""Reinitialize the token dispatcher after pruning."""
637-
print_rank_0("Reinitializing token dispatcher after pruning")
638614
if hasattr(moe_utils, "get_default_model_comm_pgs"):
639615
model_comm_pgs = moe_utils.get_default_model_comm_pgs()
640616
else:
@@ -1045,27 +1021,30 @@ def modify(
10451021
*,
10461022
hidden_size_divisor: int = 1,
10471023
ffn_hidden_size_divisor: int = 1,
1048-
mamba_num_heads_divisor: int = 1,
10491024
mamba_head_dim_divisor: int = 1,
10501025
num_moe_experts_divisor: int = 1,
1026+
num_layers_divisor: int = 1,
10511027
):
10521028
"""Modify the dynamic choices of the module according to provided keyword arguments.
10531029
10541030
Args:
10551031
hidden_size_divisor: The divisor of the hidden_size.
10561032
ffn_hidden_size_divisor: The divisor of the mlp ffn_hidden_size.
1057-
mamba_num_heads_divisor: The divisor of the mamba num_heads.
10581033
mamba_head_dim_divisor: The divisor of the mamba head_dim.
10591034
num_moe_experts_divisor: The divisor of the number of MoE experts.
1035+
num_layers_divisor: The divisor of the number of layers.
10601036
"""
1061-
hp = self.get_hparam("hidden_size")
1062-
choices = {int(make_divisible(c, hidden_size_divisor)) for c in hp.choices} # type: ignore[arg-type]
1063-
hp.choices = list(set(hp.choices) & choices | {hp.original})
1037+
for hp_name, divisor in [
1038+
("hidden_size", hidden_size_divisor),
1039+
("num_layers", num_layers_divisor),
1040+
]:
1041+
hp = self.get_hparam(hp_name)
1042+
choices = {int(make_divisible(c, divisor)) for c in hp.choices} # type: ignore[arg-type]
1043+
hp.choices = list(set(hp.choices) & choices | {hp.original})
10641044

10651045
for layer in self.decoder.layers:
10661046
layer.modify(
10671047
ffn_hidden_size_divisor=ffn_hidden_size_divisor,
1068-
mamba_num_heads_divisor=mamba_num_heads_divisor,
10691048
mamba_head_dim_divisor=mamba_head_dim_divisor,
10701049
num_moe_experts_divisor=num_moe_experts_divisor,
10711050
)
@@ -1084,86 +1063,3 @@ def export(self) -> torch.nn.Module:
10841063
).export()
10851064
self.output_layer.export()
10861065
return super().export()
1087-
1088-
1089-
class MegatronConstraintsFunc(ConstraintsFunc):
1090-
"""A Functor class to check if sub-net satisfied all provided constraints.
1091-
1092-
We intentionally expose some attributes like `limits` s.t. we can modify it manually.
1093-
"""
1094-
1095-
_sample_points_dict: dict[tuple[str, ...], dict[str, SampleFunc]] = {
1096-
("params",): {"min": min, "centroid": random.centroid, "max": max},
1097-
}
1098-
1099-
def __init__(
1100-
self,
1101-
model: MegatronModule,
1102-
constraints: ConstraintsDict,
1103-
dummy_input: Any | tuple[Any, ...],
1104-
deployment: dict | None = None,
1105-
fast_eval: bool = True,
1106-
):
1107-
"""Initialize with additional data parallel group info from megatron."""
1108-
for key in constraints:
1109-
if key != "params":
1110-
raise ValueError("Only params constraints is supported for MegatronModule!")
1111-
1112-
self.model = model
1113-
self.dummy_input = dummy_input
1114-
self.deployment = deployment
1115-
self._fast_eval = fast_eval
1116-
1117-
# Getting data parallel group for
1118-
self.dp_group = get_data_parallel_group()
1119-
1120-
# initialize latency interpolator
1121-
keys_for_interpolation = ("params",)
1122-
if ConstraintsFunc.is_configurable(self.model, "depth"):
1123-
keys_for_interpolation += ("flops_min_depth",)
1124-
self._latency_interpolator = ConstraintInterpolator(
1125-
self.model,
1126-
points_funcs={k: self.constraint_eval_funcs[k] for k in keys_for_interpolation},
1127-
value_func=self._get_true_latency,
1128-
)
1129-
# set fast/regular mode for latency interpolator
1130-
self._latency_interpolator.collect_mode = not self.fast_eval
1131-
1132-
# set limit at the end with setter to use sanity checks on constraints
1133-
self._limits = {}
1134-
self.limits = constraints
1135-
1136-
@property
1137-
def constraint_eval_funcs(self) -> dict[str, ConstraintEvalFunc]:
1138-
"""Get constraint eval fns."""
1139-
return {
1140-
"params": self._get_params,
1141-
}
1142-
1143-
def _get_params(self, _: ConstraintsRes | None = None) -> float:
1144-
"""Get number of model parameters from forward pass."""
1145-
params = param_num_from_forward(self.model, args=self.dummy_input, unit=1.0)
1146-
reduced_params = torch.Tensor([params]).to(device=get_module_device(self.model))
1147-
torch.distributed.all_reduce(reduced_params, group=get_pipeline_model_parallel_group())
1148-
torch.distributed.all_reduce(reduced_params, group=get_tensor_model_parallel_group())
1149-
return reduced_params.item()
1150-
1151-
def _get_flops(self, _: ConstraintsRes | None = None) -> float:
1152-
"""Get inference FLOPs."""
1153-
raise NotImplementedError
1154-
1155-
def _get_flops_min_depth(self, _: ConstraintsRes | None = None) -> float:
1156-
"""Get inference FLOPs with depth set to minimum."""
1157-
raise NotImplementedError
1158-
1159-
def _get_true_latency(self, _: ConstraintsRes | None = None) -> float:
1160-
"""Get true inference latency."""
1161-
raise NotImplementedError
1162-
1163-
def _get_latency(self, precomputed: ConstraintsRes | None = None) -> float:
1164-
"""Get inference latency from interpolator."""
1165-
raise NotImplementedError
1166-
1167-
1168-
# Clear the mapping and reinsert.
1169-
MODULE_TYPE_TO_CONSTRAINTS_FUNC[MegatronModule] = MegatronConstraintsFunc

modelopt/torch/nas/search_space.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,7 @@ def sort_parameters(self, hps_to_sort: set[str] | None = None, verbose: bool = F
135135
hps_to_sort: A set of hparam names to sort. If not provided or empty, all hparams will be sorted.
136136
verbose: Whether to print the search space and hparam importances.
137137
"""
138-
print_rank_0("Sorting parameters...")
139-
if verbose:
140-
self.print_summary()
138+
print_rank_0("\nSorting parameters...")
141139

142140
# get config and set to max
143141
config = self.config()

modelopt/torch/opt/searcher.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
import torch.nn as nn
3636

3737
from modelopt.torch.utils import distributed as dist
38-
from modelopt.torch.utils import no_stdout, run_forward_loop
38+
from modelopt.torch.utils import no_stdout, print_rank_0, run_forward_loop
3939

4040
LimitsTuple = tuple[float, float]
4141
ConstraintsDict = dict[str, str | float | dict | None]
@@ -212,6 +212,7 @@ def construct_forward_loop(
212212
return None
213213

214214
def forward_loop_with_silence_check(m: nn.Module) -> None:
215+
print_rank_0("Running forward loop...")
215216
with no_stdout() if silent else nullcontext():
216217
if data_loader is not None:
217218
run_forward_loop(

modelopt/torch/prune/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
simplifies the overall workflow to accommodate for the simpler nature of pruning algorithms.
2020
"""
2121

22-
# nas is a required - so let's check if it's available
23-
import modelopt.torch.nas
2422
from modelopt.torch.utils import import_plugin
2523

2624
from . import fastnas, gradnas, plugins

0 commit comments

Comments
 (0)