nvidia-modelopt 0.35.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (272) hide show
  1. modelopt/__init__.py +20 -0
  2. modelopt/deploy/__init__.py +16 -0
  3. modelopt/deploy/llm/__init__.py +30 -0
  4. modelopt/deploy/llm/generate.py +345 -0
  5. modelopt/onnx/__init__.py +34 -0
  6. modelopt/onnx/autocast/__init__.py +19 -0
  7. modelopt/onnx/autocast/__main__.py +187 -0
  8. modelopt/onnx/autocast/convert.py +202 -0
  9. modelopt/onnx/autocast/graphsanitizer.py +422 -0
  10. modelopt/onnx/autocast/logging_config.py +78 -0
  11. modelopt/onnx/autocast/nodeclassifier.py +416 -0
  12. modelopt/onnx/autocast/precisionconverter.py +1032 -0
  13. modelopt/onnx/autocast/referencerunner.py +159 -0
  14. modelopt/onnx/autocast/utils.py +117 -0
  15. modelopt/onnx/llm_export_utils/__init__.py +16 -0
  16. modelopt/onnx/llm_export_utils/export_utils.py +162 -0
  17. modelopt/onnx/llm_export_utils/quantization_utils.py +122 -0
  18. modelopt/onnx/llm_export_utils/surgeon_utils.py +120 -0
  19. modelopt/onnx/logging_config.py +77 -0
  20. modelopt/onnx/op_types.py +300 -0
  21. modelopt/onnx/quantization/__init__.py +20 -0
  22. modelopt/onnx/quantization/__main__.py +291 -0
  23. modelopt/onnx/quantization/calib_utils.py +178 -0
  24. modelopt/onnx/quantization/extensions.py +35 -0
  25. modelopt/onnx/quantization/fp8.py +375 -0
  26. modelopt/onnx/quantization/graph_utils.py +1479 -0
  27. modelopt/onnx/quantization/gs_patching.py +112 -0
  28. modelopt/onnx/quantization/int4.py +1347 -0
  29. modelopt/onnx/quantization/int8.py +283 -0
  30. modelopt/onnx/quantization/operators.py +121 -0
  31. modelopt/onnx/quantization/ort_patching.py +1766 -0
  32. modelopt/onnx/quantization/ort_utils.py +346 -0
  33. modelopt/onnx/quantization/partitioning.py +439 -0
  34. modelopt/onnx/quantization/qdq_utils.py +1349 -0
  35. modelopt/onnx/quantization/quant_utils.py +283 -0
  36. modelopt/onnx/quantization/quantize.py +528 -0
  37. modelopt/onnx/quantization/src/modelopt_round_and_pack_ext.cpp +127 -0
  38. modelopt/onnx/trt_utils.py +424 -0
  39. modelopt/onnx/utils.py +753 -0
  40. modelopt/torch/__init__.py +41 -0
  41. modelopt/torch/_deploy/__init__.py +23 -0
  42. modelopt/torch/_deploy/_runtime/__init__.py +29 -0
  43. modelopt/torch/_deploy/_runtime/common.py +72 -0
  44. modelopt/torch/_deploy/_runtime/ort_client.py +193 -0
  45. modelopt/torch/_deploy/_runtime/registry.py +83 -0
  46. modelopt/torch/_deploy/_runtime/runtime_client.py +154 -0
  47. modelopt/torch/_deploy/_runtime/tensorrt/constants.py +108 -0
  48. modelopt/torch/_deploy/_runtime/tensorrt/engine_builder.py +324 -0
  49. modelopt/torch/_deploy/_runtime/tensorrt/hw_param_config.py +51 -0
  50. modelopt/torch/_deploy/_runtime/tensorrt/layerwise_profiling.py +178 -0
  51. modelopt/torch/_deploy/_runtime/tensorrt/parse_trtexec_log.py +151 -0
  52. modelopt/torch/_deploy/_runtime/tensorrt/tensorrt_utils.py +200 -0
  53. modelopt/torch/_deploy/_runtime/trt_client.py +219 -0
  54. modelopt/torch/_deploy/compilation.py +142 -0
  55. modelopt/torch/_deploy/device_model.py +157 -0
  56. modelopt/torch/_deploy/profiling.py +193 -0
  57. modelopt/torch/_deploy/utils/__init__.py +18 -0
  58. modelopt/torch/_deploy/utils/onnx_optimizer.py +120 -0
  59. modelopt/torch/_deploy/utils/onnx_utils.py +58 -0
  60. modelopt/torch/_deploy/utils/torch_onnx.py +593 -0
  61. modelopt/torch/distill/__init__.py +28 -0
  62. modelopt/torch/distill/config.py +130 -0
  63. modelopt/torch/distill/distillation.py +84 -0
  64. modelopt/torch/distill/distillation_model.py +318 -0
  65. modelopt/torch/distill/loss_balancers.py +140 -0
  66. modelopt/torch/distill/losses.py +275 -0
  67. modelopt/torch/distill/mode.py +223 -0
  68. modelopt/torch/distill/plugins/__init__.py +24 -0
  69. modelopt/torch/distill/plugins/huggingface.py +110 -0
  70. modelopt/torch/distill/plugins/megatron.py +476 -0
  71. modelopt/torch/distill/registry.py +23 -0
  72. modelopt/torch/export/__init__.py +24 -0
  73. modelopt/torch/export/convert_hf_config.py +117 -0
  74. modelopt/torch/export/distribute.py +300 -0
  75. modelopt/torch/export/hf_config_map.py +84 -0
  76. modelopt/torch/export/layer_utils.py +1893 -0
  77. modelopt/torch/export/mcore_config_map.py +25 -0
  78. modelopt/torch/export/model_config.py +623 -0
  79. modelopt/torch/export/model_config_export.py +552 -0
  80. modelopt/torch/export/model_config_utils.py +392 -0
  81. modelopt/torch/export/model_utils.py +71 -0
  82. modelopt/torch/export/plugins/__init__.py +21 -0
  83. modelopt/torch/export/plugins/mcore_common.py +67 -0
  84. modelopt/torch/export/plugins/mcore_custom.py +530 -0
  85. modelopt/torch/export/plugins/mcore_deepseek.py +143 -0
  86. modelopt/torch/export/plugins/mcore_gptoss.py +71 -0
  87. modelopt/torch/export/plugins/mcore_llama.py +164 -0
  88. modelopt/torch/export/plugins/mcore_nemotron.py +90 -0
  89. modelopt/torch/export/plugins/mcore_qwen.py +99 -0
  90. modelopt/torch/export/plugins/megatron_importer.py +647 -0
  91. modelopt/torch/export/postprocess.py +847 -0
  92. modelopt/torch/export/quant_utils.py +1069 -0
  93. modelopt/torch/export/tensorrt_llm_type.py +42 -0
  94. modelopt/torch/export/tensorrt_llm_utils.py +405 -0
  95. modelopt/torch/export/transformer_engine.py +94 -0
  96. modelopt/torch/export/unified_export_hf.py +537 -0
  97. modelopt/torch/export/unified_export_megatron.py +1164 -0
  98. modelopt/torch/nas/__init__.py +27 -0
  99. modelopt/torch/nas/algorithms.py +856 -0
  100. modelopt/torch/nas/autonas.py +808 -0
  101. modelopt/torch/nas/conversion.py +119 -0
  102. modelopt/torch/nas/hparams/__init__.py +19 -0
  103. modelopt/torch/nas/hparams/concat.py +319 -0
  104. modelopt/torch/nas/hparams/container.py +48 -0
  105. modelopt/torch/nas/modules/__init__.py +21 -0
  106. modelopt/torch/nas/modules/container.py +99 -0
  107. modelopt/torch/nas/modules/conv.py +254 -0
  108. modelopt/torch/nas/modules/linear.py +76 -0
  109. modelopt/torch/nas/modules/norm.py +193 -0
  110. modelopt/torch/nas/modules/utils.py +61 -0
  111. modelopt/torch/nas/patch.py +261 -0
  112. modelopt/torch/nas/plugins/__init__.py +29 -0
  113. modelopt/torch/nas/plugins/megatron.py +1497 -0
  114. modelopt/torch/nas/plugins/torch.py +71 -0
  115. modelopt/torch/nas/plugins/transformer_engine.py +42 -0
  116. modelopt/torch/nas/plugins/transformers.py +210 -0
  117. modelopt/torch/nas/registry.py +23 -0
  118. modelopt/torch/nas/search_space.py +260 -0
  119. modelopt/torch/nas/traced_hp.py +149 -0
  120. modelopt/torch/nas/utils.py +408 -0
  121. modelopt/torch/opt/__init__.py +41 -0
  122. modelopt/torch/opt/_hooks.py +98 -0
  123. modelopt/torch/opt/config.py +383 -0
  124. modelopt/torch/opt/conversion.py +620 -0
  125. modelopt/torch/opt/dynamic.py +1367 -0
  126. modelopt/torch/opt/hparam.py +275 -0
  127. modelopt/torch/opt/mode.py +353 -0
  128. modelopt/torch/opt/plugins/__init__.py +38 -0
  129. modelopt/torch/opt/plugins/diffusers.py +40 -0
  130. modelopt/torch/opt/plugins/huggingface.py +162 -0
  131. modelopt/torch/opt/plugins/mcore_dist_checkpointing.py +211 -0
  132. modelopt/torch/opt/plugins/megatron.py +142 -0
  133. modelopt/torch/opt/plugins/peft.py +108 -0
  134. modelopt/torch/opt/plugins/transformers.py +160 -0
  135. modelopt/torch/opt/searcher.py +363 -0
  136. modelopt/torch/opt/utils.py +125 -0
  137. modelopt/torch/prune/__init__.py +26 -0
  138. modelopt/torch/prune/fastnas.py +376 -0
  139. modelopt/torch/prune/gradnas.py +349 -0
  140. modelopt/torch/prune/plugins/__init__.py +24 -0
  141. modelopt/torch/prune/plugins/mcore_minitron.py +263 -0
  142. modelopt/torch/prune/plugins/transformers.py +41 -0
  143. modelopt/torch/prune/pruning.py +211 -0
  144. modelopt/torch/quantization/__init__.py +26 -0
  145. modelopt/torch/quantization/algorithms.py +671 -0
  146. modelopt/torch/quantization/backends/__init__.py +20 -0
  147. modelopt/torch/quantization/backends/fp8_per_tensor_gemm.py +204 -0
  148. modelopt/torch/quantization/backends/gemm_registry.py +156 -0
  149. modelopt/torch/quantization/backends/nvfp4_gemm.py +201 -0
  150. modelopt/torch/quantization/backends/utils.py +28 -0
  151. modelopt/torch/quantization/calib/__init__.py +25 -0
  152. modelopt/torch/quantization/calib/bias.py +172 -0
  153. modelopt/torch/quantization/calib/calibrator.py +63 -0
  154. modelopt/torch/quantization/calib/histogram.py +434 -0
  155. modelopt/torch/quantization/calib/max.py +110 -0
  156. modelopt/torch/quantization/compress.py +227 -0
  157. modelopt/torch/quantization/config.py +1180 -0
  158. modelopt/torch/quantization/conversion.py +389 -0
  159. modelopt/torch/quantization/export_onnx.py +639 -0
  160. modelopt/torch/quantization/extensions.py +89 -0
  161. modelopt/torch/quantization/mode.py +428 -0
  162. modelopt/torch/quantization/model_calib.py +949 -0
  163. modelopt/torch/quantization/model_quant.py +477 -0
  164. modelopt/torch/quantization/nn/__init__.py +26 -0
  165. modelopt/torch/quantization/nn/functional.py +109 -0
  166. modelopt/torch/quantization/nn/modules/__init__.py +16 -0
  167. modelopt/torch/quantization/nn/modules/quant_activations.py +22 -0
  168. modelopt/torch/quantization/nn/modules/quant_batchnorm.py +24 -0
  169. modelopt/torch/quantization/nn/modules/quant_conv.py +123 -0
  170. modelopt/torch/quantization/nn/modules/quant_instancenorm.py +39 -0
  171. modelopt/torch/quantization/nn/modules/quant_linear.py +258 -0
  172. modelopt/torch/quantization/nn/modules/quant_module.py +211 -0
  173. modelopt/torch/quantization/nn/modules/quant_pooling.py +99 -0
  174. modelopt/torch/quantization/nn/modules/quant_rnn.py +527 -0
  175. modelopt/torch/quantization/nn/modules/tensor_quantizer.py +1293 -0
  176. modelopt/torch/quantization/plugins/__init__.py +73 -0
  177. modelopt/torch/quantization/plugins/accelerate.py +214 -0
  178. modelopt/torch/quantization/plugins/apex.py +52 -0
  179. modelopt/torch/quantization/plugins/attention.py +312 -0
  180. modelopt/torch/quantization/plugins/custom.py +192 -0
  181. modelopt/torch/quantization/plugins/diffusers.py +237 -0
  182. modelopt/torch/quantization/plugins/fairscale.py +45 -0
  183. modelopt/torch/quantization/plugins/huggingface.py +736 -0
  184. modelopt/torch/quantization/plugins/megatron.py +462 -0
  185. modelopt/torch/quantization/plugins/peft.py +148 -0
  186. modelopt/torch/quantization/plugins/transformer_engine.py +60 -0
  187. modelopt/torch/quantization/plugins/transformers.py +52 -0
  188. modelopt/torch/quantization/plugins/transformers_trainer.py +426 -0
  189. modelopt/torch/quantization/plugins/trl.py +27 -0
  190. modelopt/torch/quantization/plugins/vllm.py +199 -0
  191. modelopt/torch/quantization/qtensor/__init__.py +24 -0
  192. modelopt/torch/quantization/qtensor/base_qtensor.py +370 -0
  193. modelopt/torch/quantization/qtensor/fp8_tensor.py +151 -0
  194. modelopt/torch/quantization/qtensor/int4_tensor.py +130 -0
  195. modelopt/torch/quantization/qtensor/int8_tensor.py +124 -0
  196. modelopt/torch/quantization/qtensor/mxfp4_tensor.py +144 -0
  197. modelopt/torch/quantization/qtensor/nf4_tensor.py +199 -0
  198. modelopt/torch/quantization/qtensor/nvfp4_tensor.py +295 -0
  199. modelopt/torch/quantization/src/tensor_quant.cpp +77 -0
  200. modelopt/torch/quantization/src/tensor_quant.h +69 -0
  201. modelopt/torch/quantization/src/tensor_quant_fp8.cpp +48 -0
  202. modelopt/torch/quantization/src/tensor_quant_gpu.cu +361 -0
  203. modelopt/torch/quantization/src/tensor_quant_gpu_fp8.cu +122 -0
  204. modelopt/torch/quantization/src/tensor_quant_mx.cu +411 -0
  205. modelopt/torch/quantization/src/tensor_quant_mx.h +247 -0
  206. modelopt/torch/quantization/tensor_quant.py +816 -0
  207. modelopt/torch/quantization/triton/__init__.py +36 -0
  208. modelopt/torch/quantization/triton/fp4_kernel.py +303 -0
  209. modelopt/torch/quantization/utils.py +443 -0
  210. modelopt/torch/sparsity/__init__.py +19 -0
  211. modelopt/torch/sparsity/config.py +51 -0
  212. modelopt/torch/sparsity/magnitude.py +148 -0
  213. modelopt/torch/sparsity/mode.py +203 -0
  214. modelopt/torch/sparsity/module.py +87 -0
  215. modelopt/torch/sparsity/plugins/__init__.py +27 -0
  216. modelopt/torch/sparsity/plugins/megatron.py +93 -0
  217. modelopt/torch/sparsity/searcher.py +84 -0
  218. modelopt/torch/sparsity/sparsegpt.py +276 -0
  219. modelopt/torch/sparsity/sparsification.py +123 -0
  220. modelopt/torch/speculative/__init__.py +20 -0
  221. modelopt/torch/speculative/config.py +100 -0
  222. modelopt/torch/speculative/eagle/__init__.py +20 -0
  223. modelopt/torch/speculative/eagle/conversion.py +67 -0
  224. modelopt/torch/speculative/eagle/default_config.py +50 -0
  225. modelopt/torch/speculative/eagle/eagle_model.py +51 -0
  226. modelopt/torch/speculative/eagle/utils.py +91 -0
  227. modelopt/torch/speculative/medusa/__init__.py +19 -0
  228. modelopt/torch/speculative/medusa/conversion.py +59 -0
  229. modelopt/torch/speculative/medusa/medusa_model.py +32 -0
  230. modelopt/torch/speculative/mode.py +86 -0
  231. modelopt/torch/speculative/plugins/__init__.py +33 -0
  232. modelopt/torch/speculative/plugins/megatron_eagle.py +2119 -0
  233. modelopt/torch/speculative/plugins/megatron_medusa.py +312 -0
  234. modelopt/torch/speculative/plugins/transformers.py +1138 -0
  235. modelopt/torch/speculative/speculative_decoding.py +59 -0
  236. modelopt/torch/speculative/utils.py +364 -0
  237. modelopt/torch/trace/__init__.py +25 -0
  238. modelopt/torch/trace/analyzer.py +1368 -0
  239. modelopt/torch/trace/modules/__init__.py +19 -0
  240. modelopt/torch/trace/modules/concat.py +384 -0
  241. modelopt/torch/trace/modules/nn.py +153 -0
  242. modelopt/torch/trace/plugins/__init__.py +34 -0
  243. modelopt/torch/trace/plugins/megatron.py +36 -0
  244. modelopt/torch/trace/plugins/transformers.py +58 -0
  245. modelopt/torch/trace/symbols.py +545 -0
  246. modelopt/torch/trace/tracer.py +331 -0
  247. modelopt/torch/utils/__init__.py +28 -0
  248. modelopt/torch/utils/_pytree.py +133 -0
  249. modelopt/torch/utils/cpp_extension.py +91 -0
  250. modelopt/torch/utils/dataset_utils.py +484 -0
  251. modelopt/torch/utils/distributed.py +311 -0
  252. modelopt/torch/utils/graph.py +123 -0
  253. modelopt/torch/utils/image_processor.py +112 -0
  254. modelopt/torch/utils/import_utils.py +35 -0
  255. modelopt/torch/utils/list.py +54 -0
  256. modelopt/torch/utils/logging.py +127 -0
  257. modelopt/torch/utils/memory_monitor.py +146 -0
  258. modelopt/torch/utils/network.py +658 -0
  259. modelopt/torch/utils/perf.py +174 -0
  260. modelopt/torch/utils/plugins/__init__.py +27 -0
  261. modelopt/torch/utils/plugins/megatron_generate.py +299 -0
  262. modelopt/torch/utils/plugins/megatron_mmlu.py +152 -0
  263. modelopt/torch/utils/plugins/megatron_preprocess_data.py +200 -0
  264. modelopt/torch/utils/random.py +163 -0
  265. modelopt/torch/utils/speech_dataset_utils.py +134 -0
  266. modelopt/torch/utils/tensor.py +87 -0
  267. modelopt/torch/utils/vlm_dataset_utils.py +110 -0
  268. nvidia_modelopt-0.35.0.dist-info/METADATA +171 -0
  269. nvidia_modelopt-0.35.0.dist-info/RECORD +272 -0
  270. nvidia_modelopt-0.35.0.dist-info/WHEEL +5 -0
  271. nvidia_modelopt-0.35.0.dist-info/licenses/LICENSE +14 -0
  272. nvidia_modelopt-0.35.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,392 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ """Common utils for the ModelConfig."""
17
+
18
+ import dataclasses
19
+ import math
20
+ from types import UnionType
21
+ from typing import Union, get_args, get_origin
22
+
23
+ import numpy as np
24
+ import torch
25
+
26
+ from .model_config import (
27
+ QUANTIZATION_FP8_PC_PT,
28
+ QUANTIZATION_INT4_AWQ,
29
+ QUANTIZATION_W4A8_AWQ,
30
+ DecoderLayerConfig,
31
+ LayernormConfig,
32
+ LinearConfig,
33
+ MLPConfig,
34
+ ModelConfig,
35
+ MOEConfig,
36
+ QKVConfig,
37
+ )
38
+ from .quant_utils import to_quantized_weight
39
+
40
+ # numpy doesn't know bfloat16, define abstract binary type instead
41
+ np_bfloat16 = np.dtype("V2", metadata={"dtype": "bfloat16"})
42
+
43
+
44
+ def _numpy_to_torch(x):
45
+ """Convert numpy array to torch tensor."""
46
+ if isinstance(x, torch.Tensor):
47
+ return x
48
+
49
+ if x.dtype != np_bfloat16:
50
+ return torch.tensor(x)
51
+ return torch.tensor(x.view(np.int16)).view(torch.bfloat16)
52
+
53
+
54
+ def model_config_to_dict(model_config: ModelConfig) -> dict:
55
+ """Converts the instance to a python dict."""
56
+ assert model_config is not None, "model_config is None"
57
+
58
+ def _to_dict(obj):
59
+ if dataclasses.is_dataclass(obj):
60
+ return {k: _to_dict(v) for k, v in vars(obj).items()}
61
+ elif isinstance(obj, dict):
62
+ return {k: _to_dict(v) for k, v in obj.items()}
63
+ elif isinstance(obj, list):
64
+ return [_to_dict(v) for v in obj]
65
+ return obj
66
+
67
+ return _to_dict(model_config)
68
+
69
+
70
+ def split_config_and_weights(
71
+ config,
72
+ weights: dict[str, torch.tensor],
73
+ prefix: str = "transformer",
74
+ layer_config_dict: dict = {},
75
+ ):
76
+ """Util function to split the weights or any torch.Tensor in nested config to weights.
77
+
78
+ A weight id starts with transformers or lm_head will also be generated to link the original key to the weights dict.
79
+ The weights in the weights dict are contiguous.
80
+
81
+ layer_config_dict: A dictionary containing layerwise quantization format information and awq_block_size information
82
+ when relevant. It is used to export quantization.json for auto_quant checkpoint.
83
+ """
84
+ if isinstance(config, dict):
85
+ for k, v in config.items():
86
+ if k == "lm_head" and "medusa_heads" not in prefix:
87
+ # lm_head is not part of the transformer.
88
+ array_key = k
89
+ elif k == "experts":
90
+ # Omit the 'experts' key that is not in the model name
91
+ array_key = prefix
92
+ elif k == "medusa_heads":
93
+ # medusa_heads is not part of the transformer
94
+ array_key = k
95
+ elif "rel_attn_table" in prefix:
96
+ # rel_attn_table is treated as a weight for quantize loop whereas in TRTLLM it is a Tensor
97
+ array_key = prefix
98
+ else:
99
+ array_key = f"{prefix}.{k}"
100
+
101
+ # TensorRT-LLM 0.17 uses the kv_cache_scaling_factor,
102
+ # the following code will be deprecated after the 0.18 upgrade.
103
+ if "v_cache_scaling_factor" in array_key:
104
+ k_cache_scaling_factor_key = array_key.replace(
105
+ "v_cache_scaling_factor", "k_cache_scaling_factor"
106
+ )
107
+ if k_cache_scaling_factor_key in weights:
108
+ weights[
109
+ array_key.replace("v_cache_scaling_factor", "kv_cache_scaling_factor")
110
+ ] = torch.maximum(v, weights[k_cache_scaling_factor_key])
111
+
112
+ # Construct per_layer quantization dictionary, with block size information
113
+ if array_key != "transformer.quantization" and (
114
+ "quantization" in array_key or "awq_block_size" in array_key
115
+ ):
116
+ layer_config_dict[array_key] = v
117
+
118
+ if isinstance(v, torch.Tensor):
119
+ weights[array_key] = v
120
+ config[k] = f"{array_key}"
121
+ else:
122
+ split_config_and_weights(v, weights, array_key, layer_config_dict)
123
+ elif isinstance(config, list):
124
+ for i, v in enumerate(config):
125
+ array_key = f"{prefix}.{i}"
126
+ if isinstance(v, torch.Tensor):
127
+ weights[array_key] = v
128
+ config[i] = f"{array_key}"
129
+ else:
130
+ split_config_and_weights(v, weights, array_key, layer_config_dict)
131
+
132
+
133
+ def _unified_weights_key(k: str) -> str:
134
+ """Try to unify the weights dict key between old npz and the new safetensors format."""
135
+ prefixes = ["transformer.", "_np:"]
136
+ for prefix in prefixes:
137
+ k = k.removeprefix(prefix)
138
+
139
+ k = k.replace("final_layernorm", "ln_f")
140
+
141
+ return k.replace(":", ".")
142
+
143
+
144
+ def _restore_model_config(model_config, weights: dict[str, np.ndarray | torch.Tensor]):
145
+ def _is_tensor_key(k):
146
+ return isinstance(k, str) and _unified_weights_key(k) in weights
147
+
148
+ if isinstance(model_config, dict):
149
+ for k, v in model_config.items():
150
+ if _is_tensor_key(v):
151
+ model_config[k] = _numpy_to_torch(weights[_unified_weights_key(v)])
152
+ else:
153
+ _restore_model_config(v, weights)
154
+ if isinstance(model_config, list):
155
+ for i, v in enumerate(model_config):
156
+ if _is_tensor_key(v):
157
+ model_config[i] = _numpy_to_torch(weights[_unified_weights_key(v)])
158
+ else:
159
+ _restore_model_config(v, weights)
160
+
161
+
162
+ def restore_model_config(model_config, weights: dict[str, np.ndarray | torch.Tensor]):
163
+ """Recursively restores the model_config from json and loads np.ndarray or torch.Tensor weights from weights."""
164
+ unified_key_weights = {}
165
+ for k, v in weights.items():
166
+ unified_key_weights[_unified_weights_key(k)] = v
167
+
168
+ _restore_model_config(model_config, unified_key_weights)
169
+
170
+
171
+ def _from_dict(class_type, data):
172
+ """Helper function to load the data as a class_type. class_type must be a dataclass."""
173
+ if data is None:
174
+ return None
175
+
176
+ # class_type of quantization is str | None, which is catergrorized as Union
177
+ if class_type != str | None and get_origin(class_type) in [Union, UnionType]:
178
+ # Handle QKV
179
+ if all(key in data for key in ["q", "k", "v"]):
180
+ # splitted qkv case
181
+ class_type = QKVConfig
182
+ elif all(key in data for key in ["router", "experts"]):
183
+ # moe
184
+ class_type = MOEConfig
185
+ elif all(key in data for key in ["fc", "gate", "proj"]):
186
+ # mlp
187
+ class_type = MLPConfig
188
+ else:
189
+ # merged qkv case
190
+ assert "linear_type" in data, f"{data} is not a valid LinearConfig"
191
+ class_type = LinearConfig
192
+
193
+ if dataclasses.is_dataclass(class_type):
194
+ fieldtypes = {f.name: f.type for f in dataclasses.fields(class_type)}
195
+ fields_map = {}
196
+ for k, v in data.items():
197
+ if k in fieldtypes:
198
+ # We only handle keys available in the fields.
199
+ # Deprecated fields in the checkpoint will be ignored.
200
+ fields_map[k] = _from_dict(fieldtypes[k], v)
201
+ return class_type(**fields_map)
202
+ elif get_origin(class_type) is list and dataclasses.is_dataclass(get_args(class_type)[0]):
203
+ list_value = []
204
+ for child in data:
205
+ child_class_type = get_args(class_type)[0]
206
+ list_value.append(_from_dict(child_class_type, child))
207
+ return list_value
208
+ else:
209
+ return data
210
+
211
+
212
+ def model_config_from_dict(d: dict) -> ModelConfig:
213
+ """Load a dict to a `ModelConfig` instance."""
214
+ config_type = ModelConfig
215
+
216
+ config_type_map = {}
217
+ for t in [ModelConfig, DecoderLayerConfig, LayernormConfig, LinearConfig]:
218
+ config_type_map[t.__name__] = t
219
+
220
+ if "__name__" in d:
221
+ config_name = d.pop("__name__")
222
+ try:
223
+ config_type = config_type_map[config_name]
224
+ except Exception as e:
225
+ raise NotImplementedError(f"{config_name} not supported") from e
226
+
227
+ return _from_dict(config_type, d)
228
+
229
+
230
+ def pad_weights(weights, tp_size):
231
+ """Returns the padded weights to tp_size."""
232
+ assert len(weights.shape) > 1
233
+
234
+ def _pad_size(original_size, tp_size):
235
+ return int(math.ceil(original_size / tp_size) * tp_size)
236
+
237
+ original_size = weights.shape[0]
238
+ padded_size = _pad_size(original_size, tp_size)
239
+
240
+ if original_size != padded_size:
241
+ pad_width = padded_size - original_size
242
+ return torch.nn.functional.pad(weights, (0, 0, 0, pad_width), "constant", value=0)
243
+ return weights
244
+
245
+
246
+ def merge_qkv(model_config):
247
+ """Merges the qkv fields in model_config from QKVConfig to a single LinearConfig."""
248
+ for decoder_config in model_config.layers:
249
+ for attention_key in ["attention", "self_attention", "cross_attention"]:
250
+ attention = getattr(decoder_config, attention_key, None)
251
+ if attention and isinstance(attention.qkv, QKVConfig):
252
+ splitted_qkv = attention.qkv
253
+ attention.qkv = LinearConfig()
254
+ attention.qkv.weight = splitted_qkv.weight
255
+ attention.qkv.bias = splitted_qkv.bias
256
+ attention.qkv.activation_scaling_factor = splitted_qkv.activation_scaling_factor
257
+ attention.qkv.weights_scaling_factor = splitted_qkv.weights_scaling_factor
258
+ attention.qkv.weights_scaling_factor_2 = splitted_qkv.weights_scaling_factor_2
259
+ attention.qkv.prequant_scaling_factor = splitted_qkv.prequant_scaling_factor
260
+ attention.qkv.awq_block_size = splitted_qkv.awq_block_size
261
+ # Assert q,k,v have same quantization formats before merging
262
+ assert (
263
+ splitted_qkv.q.quantization
264
+ == splitted_qkv.k.quantization
265
+ == splitted_qkv.v.quantization
266
+ ), "Quantization formats of q,k,v must be the same."
267
+ attention.qkv.quantization = splitted_qkv.q.quantization
268
+
269
+ # Collect GPU memory from the deleted tensors
270
+ del splitted_qkv
271
+
272
+
273
+ def merge_gate_fc(model_config):
274
+ """Postprocess the MLP config for TensorRT-LLM export."""
275
+ for decoder_config in model_config.layers:
276
+ mlp = None
277
+ if isinstance(decoder_config.mlp, MLPConfig):
278
+ mlp = decoder_config.mlp
279
+ elif (
280
+ isinstance(decoder_config.mlp, MOEConfig)
281
+ and decoder_config.mlp.shared_expert is not None
282
+ ):
283
+ mlp = decoder_config.mlp.shared_expert
284
+
285
+ if mlp is not None and mlp.merge_gate_fc and mlp.gate is not None and mlp.fc is not None:
286
+ mlp.fc.weight = torch.cat(
287
+ [
288
+ mlp.gate.weight,
289
+ mlp.fc.weight,
290
+ ],
291
+ dim=0,
292
+ )
293
+
294
+ if (
295
+ mlp.fc.weights_scaling_factor is not None
296
+ and mlp.fc.weights_scaling_factor.numel() > 1
297
+ ):
298
+ mlp.fc.weights_scaling_factor = torch.cat(
299
+ [mlp.gate.weights_scaling_factor, mlp.fc.weights_scaling_factor], dim=0
300
+ )
301
+
302
+ mlp.gate = None
303
+
304
+
305
+ def pack_linear_weights(model_config: ModelConfig):
306
+ """Packs the quantized linear weights in the model_config to the quantized format."""
307
+
308
+ def _linear_layer_to_quantized_weight(linear_layers):
309
+ for linear_layer in linear_layers:
310
+ # Check if quantization of the layer is None to support auto_quant
311
+ if isinstance(linear_layer, LinearConfig) and (
312
+ linear_layer.weights_scaling_factor is not None
313
+ and linear_layer.quantization is not None
314
+ ):
315
+ # Quantize on CPU if we are short of GPU memory.
316
+ # Using 2x of the tensor size as a threshold.
317
+ if linear_layer.weight.is_cuda:
318
+ free_mem, _ = torch.cuda.mem_get_info(linear_layer.weight.device)
319
+ if (
320
+ free_mem
321
+ < 2 * linear_layer.weight.element_size() * linear_layer.weight.nelement()
322
+ ):
323
+ linear_layer.weight = linear_layer.weight.cpu()
324
+
325
+ # Save the quantize layer weights to cpu and save gpu memory.
326
+ if linear_layer.weight.element_size() > 1:
327
+ linear_layer.weight = to_quantized_weight(
328
+ linear_layer.weight,
329
+ linear_layer.weights_scaling_factor,
330
+ linear_layer.quantization,
331
+ linear_layer.weights_scaling_factor_2,
332
+ linear_layer.awq_block_size,
333
+ ).cpu()
334
+
335
+ # Convert to int8 if to make the checkpoint compatible with the latest TensorRT-LLM release.
336
+ # The future TensorRT-LLM release will use uint8 weights instead.
337
+ if linear_layer.quantization in [QUANTIZATION_INT4_AWQ, QUANTIZATION_W4A8_AWQ]:
338
+ linear_layer.weight = linear_layer.weight.view(torch.int8)
339
+
340
+ # TensorRT-LLM uses per_channel_scale for FP8 per channel weight quantization.
341
+ if linear_layer.quantization == QUANTIZATION_FP8_PC_PT:
342
+ linear_layer.per_channel_scale = linear_layer.weights_scaling_factor.cpu()
343
+ linear_layer.weights_scaling_factor = None
344
+ else:
345
+ linear_layer.weights_scaling_factor = linear_layer.weights_scaling_factor.cpu()
346
+
347
+ if not model_config.quantization:
348
+ return
349
+
350
+ def _find_linear_configs_recursive(model_config):
351
+ linear_configs = []
352
+
353
+ # Base case - not a dataclass
354
+ if not dataclasses.is_dataclass(model_config):
355
+ return linear_configs
356
+
357
+ # Check if current object is a LinearConfig
358
+ if isinstance(model_config, LinearConfig):
359
+ linear_configs.append(model_config)
360
+ return linear_configs
361
+
362
+ # Recursively check all fields
363
+ for field in dataclasses.fields(model_config):
364
+ value = getattr(model_config, field.name)
365
+
366
+ if isinstance(value, list):
367
+ for item in value:
368
+ linear_configs.extend(_find_linear_configs_recursive(item))
369
+
370
+ elif isinstance(value, dict):
371
+ for item in value.values():
372
+ linear_configs.extend(_find_linear_configs_recursive(item))
373
+
374
+ # Handle nested dataclasses
375
+ elif dataclasses.is_dataclass(value):
376
+ linear_configs.extend(_find_linear_configs_recursive(value))
377
+
378
+ return linear_configs
379
+
380
+ linear_layers = _find_linear_configs_recursive(model_config)
381
+
382
+ _linear_layer_to_quantized_weight(linear_layers)
383
+
384
+ if model_config.medusa_heads is not None:
385
+ linear_layers = []
386
+
387
+ for head in model_config.medusa_heads:
388
+ linear_layers.append(head.lm_head)
389
+ for layer in head.medusa_layers:
390
+ linear_layers.append(layer.linear)
391
+
392
+ _linear_layer_to_quantized_weight(linear_layers)
@@ -0,0 +1,71 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ """Utility functions for model type detection and classification."""
16
+
17
+ MODEL_NAME_TO_TYPE = {
18
+ "GPT2": "gpt",
19
+ "Mllama": "mllama",
20
+ "Llama4": "llama4",
21
+ "Llama": "llama",
22
+ "Mistral": "llama",
23
+ "GPTJ": "gptj",
24
+ "FalconForCausalLM": "falcon",
25
+ "RWForCausalLM": "falcon",
26
+ "baichuan": "baichuan",
27
+ "MPT": "mpt",
28
+ "Bloom": "bloom",
29
+ "ChatGLM": "chatglm",
30
+ "QWen": "qwen",
31
+ "RecurrentGemma": "recurrentgemma",
32
+ "Gemma3": "gemma3",
33
+ "Gemma2": "gemma2",
34
+ "Gemma": "gemma",
35
+ "phi3small": "phi3small",
36
+ "phi3": "phi3",
37
+ "PhiMoEForCausalLM": "phi3",
38
+ "Phi4MMForCausalLM": "phi4mm",
39
+ "phi": "phi",
40
+ "TLGv4ForCausalLM": "phi",
41
+ "MixtralForCausalLM": "llama",
42
+ "ArcticForCausalLM": "llama",
43
+ "StarCoder": "gpt",
44
+ "Dbrx": "dbrx",
45
+ "T5": "t5",
46
+ "Bart": "bart",
47
+ "GLM": "glm",
48
+ "InternLM2ForCausalLM": "internlm",
49
+ "ExaoneForCausalLM": "exaone",
50
+ "Nemotron": "gpt",
51
+ "Deepseek": "deepseek",
52
+ "Whisper": "whisper",
53
+ "gptoss": "gptoss",
54
+ }
55
+
56
+ __doc__ = f"""Utility functions for model type detection and classification.
57
+
58
+ .. code-block:: python
59
+
60
+ {MODEL_NAME_TO_TYPE=}
61
+ """
62
+
63
+ __all__ = ["get_model_type"]
64
+
65
+
66
+ def get_model_type(model):
67
+ """Try get the model type from the model name. If not found, return None."""
68
+ for k, v in MODEL_NAME_TO_TYPE.items():
69
+ if k.lower() in type(model).__name__.lower():
70
+ return v
71
+ return None
@@ -0,0 +1,21 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ """Export package plugin."""
17
+
18
+ from modelopt.torch.utils import import_plugin
19
+
20
+ with import_plugin("megatron_importer"):
21
+ from .megatron_importer import *
@@ -0,0 +1,67 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ """Custom mapping from Megatron Core models to their Hugging Face counter part."""
17
+
18
+ from typing import Any
19
+
20
+ from .mcore_deepseek import deepseek_causal_lm_export, deepseek_causal_lm_import
21
+ from .mcore_gptoss import gptoss_causal_lm_export, gptoss_causal_lm_import
22
+ from .mcore_llama import (
23
+ eagle3_llama_causal_lm_export,
24
+ eagle_llama_causal_lm_export,
25
+ llama4_causal_lm_export,
26
+ llama4_causal_lm_import,
27
+ llama_causal_lm_export,
28
+ llama_causal_lm_import,
29
+ )
30
+ from .mcore_nemotron import (
31
+ nemotron_causal_lm_export,
32
+ nemotron_h_causal_lm_export,
33
+ nemotron_h_causal_lm_import,
34
+ )
35
+ from .mcore_qwen import (
36
+ qwen3_causal_lm_export,
37
+ qwen3_causal_lm_import,
38
+ qwen25_causal_lm_export,
39
+ qwen25_causal_lm_import,
40
+ )
41
+
42
+ all_mcore_hf_export_mapping: dict[str, Any] = {
43
+ "DeepseekV2ForCausalLM": deepseek_causal_lm_export,
44
+ "DeepseekV3ForCausalLM": deepseek_causal_lm_export,
45
+ "LlamaForCausalLM": llama_causal_lm_export,
46
+ "Llama4ForConditionalGeneration": llama4_causal_lm_export,
47
+ "NemotronForCausalLM": nemotron_causal_lm_export,
48
+ "NemotronHForCausalLM": nemotron_h_causal_lm_export,
49
+ "LlamaForCausalLMEagle": eagle_llama_causal_lm_export,
50
+ "LlamaForCausalLMEagle3": eagle3_llama_causal_lm_export,
51
+ "Qwen3ForCausalLM": qwen3_causal_lm_export,
52
+ "Qwen3MoeForCausalLM": qwen3_causal_lm_export,
53
+ "Qwen2ForCausalLM": qwen25_causal_lm_export,
54
+ "GptOssForCausalLM": gptoss_causal_lm_export,
55
+ }
56
+
57
+ all_mcore_hf_import_mapping: dict[str, Any] = {
58
+ "LlamaForCausalLM": llama_causal_lm_import,
59
+ "Llama4ForConditionalGeneration": llama4_causal_lm_import,
60
+ "DeepseekV2ForCausalLM": deepseek_causal_lm_import,
61
+ "DeepseekV3ForCausalLM": deepseek_causal_lm_import,
62
+ "NemotronHForCausalLM": nemotron_h_causal_lm_import,
63
+ "Qwen3ForCausalLM": qwen3_causal_lm_import,
64
+ "Qwen3MoeForCausalLM": qwen3_causal_lm_import,
65
+ "Qwen2ForCausalLM": qwen25_causal_lm_import,
66
+ "GptOssForCausalLM": gptoss_causal_lm_import,
67
+ }