已合并
[Feature]命令行参数优化与help提示优化 #805
[Feature]命令行参数优化与help提示优化 #805
已合并
chenruijie创建于 22 天前
51 个文件变更+931-194
@@ -176,7 +176,7 @@ msmodelslim quant --model_path ${MODEL_PATH} \
176 --save_path ${SAVE_PATH} \176 --save_path ${SAVE_PATH} \
177 --device npu \177 --device npu \
178 --model_type ${MODEL_TYPE} \178 --model_type ${MODEL_TYPE} \
179- --config_path ${CONFIG_PATH} \179+ --config ${CONFIG_PATH} \
180 --trust_remote_code False180 --trust_remote_code False
181```181```
182 182 
@@ -546,7 +546,7 @@ msmodelslim quant --model_path ${MODEL_PATH} \
546 --save_path ${SAVE_PATH} \546 --save_path ${SAVE_PATH} \
547 --device npu \547 --device npu \
548 --model_type ${MODEL_TYPE} \548 --model_type ${MODEL_TYPE} \
549- --config_path ${CONFIG_PATH} \549+ --config ${CONFIG_PATH} \
550 --trust_remote_code True550 --trust_remote_code True
551```551```
552 552 
@@ -47,7 +47,7 @@ Perform distributed quantization by using multiple devices and enable debug mode
47msmodelslim quant \47msmodelslim quant \
48 --model_path ${MODEL_PATH} \48 --model_path ${MODEL_PATH} \
49 --save_path ${SAVE_PATH} \49 --save_path ${SAVE_PATH} \
50- --device npu:0,1,2,3 \50+ --device npu --device_id 0 1 2 3 \
51 --model_type Qwen2.5-7B-Instruct \51 --model_type Qwen2.5-7B-Instruct \
52 --quant_type w8a8 \52 --quant_type w8a8 \
53 --trust_remote_code True \53 --trust_remote_code True \
@@ -64,7 +64,7 @@ msmodelslim quant \
64 --save_path ${SAVE_PATH} \64 --save_path ${SAVE_PATH} \
65 --device npu \65 --device npu \
66 --model_type ${MODEL_TYPE} \66 --model_type ${MODEL_TYPE} \
67- --config_path ${CONFIG_PATH} \67+ --config ${CONFIG_PATH} \
68 --trust_remote_code True \68 --trust_remote_code True \
69 --debug69 --debug
70```70```
@@ -111,7 +111,7 @@ msmodelslim quant \
111 --save_path ${SAVE_PATH} \111 --save_path ${SAVE_PATH} \
112 --device npu \112 --device npu \
113 --model_type ${MODEL_TYPE} \113 --model_type ${MODEL_TYPE} \
114- --config_path ${CONFIG_PATH} \114+ --config ${CONFIG_PATH} \
115 --trust_remote_code ${TRUST_REMOTE_CODE}115 --trust_remote_code ${TRUST_REMOTE_CODE}
116```116```
117 117 
@@ -123,7 +123,7 @@ Use four NPUs for distributed quantization:
123msmodelslim quant \123msmodelslim quant \
124 --model_path ${MODEL_PATH} \124 --model_path ${MODEL_PATH} \
125 --save_path ${SAVE_PATH} \125 --save_path ${SAVE_PATH} \
126- --device npu:0,1,2,3 \126+ --device npu --device_id 0 1 2 3 \
127 --model_type ${MODEL_TYPE} \127 --model_type ${MODEL_TYPE} \
128 --quant_type w8a8 \128 --quant_type w8a8 \
129 --trust_remote_code True129 --trust_remote_code True
@@ -192,10 +192,10 @@ spec:
192 192 
193```bash193```bash
194# Single-device layer-wise quantization194# Single-device layer-wise quantization
195-msmodelslim quant --device npu:0 ...195+msmodelslim quant --device npu --device_id 0 ...
196 196 
197# Multi-device DP layer-wise quantization (DP is automatically enabled)197# Multi-device DP layer-wise quantization (DP is automatically enabled)
198-msmodelslim quant --device npu:0,1,2,3 ...198+msmodelslim quant --device npu --device_id 0 1 2 3 ...
199```199```
200 200 
201#### Precautions201#### Precautions
@@ -51,10 +51,10 @@ msmodelslim analyze [parameters]
51| Parameter| Type| Default Value| Description| Example Value|51| Parameter| Type| Default Value| Description| Example Value|
52|------|------|--------|------|--------|52|------|------|--------|------|--------|
53| `--device` | `str` | `npu` | Target device used to run the analysis. Options: `npu`, `cpu`.| `npu` |53| `--device` | `str` | `npu` | Target device used to run the analysis. Options: `npu`, `cpu`.| `npu` |
54-| `--pattern` | `List[str]` | `["*"]` | Layer-name patterns to analyze. Wildcards are supported. You can specify multiple patterns separated by spaces. If no value is passed, the default value is used.| `"*linear*"` `"*attention.*"` `"*mlp.*"` |54+| `--patterns` | `List[str]` | `["*"]` | Layer-name patterns to analyze. Wildcards are supported. You can specify multiple patterns separated by spaces. If no value is passed, the default value is used.| `"*linear*"` `"*attention.*"` `"*mlp.*"` |
55| `--metrics` | `str` | `"kurtosis"` | Metric used for analysis. Options: `"std"`, `"quantile"`, `"kurtosis"`, `"attention_mse"`, `"mse_model_wise"`.| `"kurtosis"` |55| `--metrics` | `str` | `"kurtosis"` | Metric used for analysis. Options: `"std"`, `"quantile"`, `"kurtosis"`, `"attention_mse"`, `"mse_model_wise"`.| `"kurtosis"` |
56-| `--calib_dataset` | `str` | `"boolq.jsonl"` | Path to the calibration dataset file. JSON and JSONL formats are supported, and the file must end with `.json` or `.jsonl`. The path can be an absolute or a relative path.|`/path/data.jsonl`|56+| `--calibration_dataset` | `str` | `"boolq.jsonl"` | Path to the calibration dataset file. JSON and JSONL formats are supported, and the file must end with `.json` or `.jsonl`. The path can be an absolute or a relative path.|`/path/data.jsonl`|
57-| `--topk` | `int` | `15` | Number of sensitive layers to output as Top K. This must be an integer greater than 0. The recommended range is 10 to 20.| `15` |57+| `--top_k` | `int` | `15` | Number of sensitive layers to output as Top K. This must be an integer greater than 0. The recommended range is 10 to 20.| `15` |
58| `--trust_remote_code` | `bool` | `False` | Whether to trust remote code. You must ensure security yourself. Options: `True`, `False`. If model loading depends on files outside the Transformers library, set `--trust_remote_code` to `True`, for example for DeepSeek-V3 series models.| `False` |58| `--trust_remote_code` | `bool` | `False` | Whether to trust remote code. You must ensure security yourself. Options: `True`, `False`. If model loading depends on files outside the Transformers library, set `--trust_remote_code` to `True`, for example for DeepSeek-V3 series models.| `False` |
59| `-h, --help` | - | - | CLI help information.| - |59| `-h, --help` | - | - | CLI help information.| - |
60 60 
@@ -217,8 +217,8 @@ msmodelslim analyze \
217 --model_type Qwen2.5-7B-Instruct \217 --model_type Qwen2.5-7B-Instruct \
218 --model_path ${model_path} \218 --model_path ${model_path} \
219 --metrics quantile \219 --metrics quantile \
220- --calib_dataset ${calib_dataset} \220+ --calibration_dataset ${calib_dataset} \
221- --topk 20 \221+ --top_k 20 \
222 --device cpu222 --device cpu
223```223```
224 224 
@@ -229,7 +229,7 @@ msmodelslim analyze \
229msmodelslim analyze \229msmodelslim analyze \
230 --model_type Qwen2.5-7B-Instruct \230 --model_type Qwen2.5-7B-Instruct \
231 --model_path ${model_path} \231 --model_path ${model_path} \
232- --pattern "*attention*" "*mlp*" \232+ --patterns "*attention*" "*mlp*" \
233 --metrics std233 --metrics std
234```234```
235 235 
@@ -240,10 +240,10 @@ msmodelslim analyze \
240 --model_type Qwen3-32B \240 --model_type Qwen3-32B \
241 --model_path ${model_path} \241 --model_path ${model_path} \
242 --device npu \242 --device npu \
243- --pattern "*.down_proj*" "*.o_proj*"\243+ --patterns "*.down_proj*" "*.o_proj*"\
244 --metrics kurtosis \244 --metrics kurtosis \
245- --calib_dataset ${calib_dataset} \245+ --calibration_dataset ${calib_dataset} \
246- --topk 15 \246+ --top_k 15 \
247 --trust_remote_code False247 --trust_remote_code False
248```248```
249 249 
@@ -60,7 +60,7 @@ For details about the parameters, see [Quick Quantization Parameters](../feature
60Quantize the Qwen2.5-7B-Instruct model in w8a8 mode by using the quick quantization feature:60Quantize the Qwen2.5-7B-Instruct model in w8a8 mode by using the quick quantization feature:
61 61 
62```bash62```bash
63-msmodelslim quant --model_path ${MODEL_PATH} --save_path ${SAVE_PATH} --device npu:0,1 --model_type Qwen2.5-7B-Instruct --quant_type w8a8 --trust_remote_code True63+msmodelslim quant --model_path ${MODEL_PATH} --save_path ${SAVE_PATH} --device npu --device_id 0 1 --model_type Qwen2.5-7B-Instruct --quant_type w8a8 --trust_remote_code True
64```64```
65 65 
66where66where
@@ -146,7 +146,7 @@ msmodelslim quant \
146 --save_path ${SAVE_PATH} \146 --save_path ${SAVE_PATH} \
147 --model_type DeepSeek-V4-Flash \147 --model_type DeepSeek-V4-Flash \
148 --quant_type w8a8 \148 --quant_type w8a8 \
149- --device npu:0 \149+ --device npu --device_id 0 \
150 --trust_remote_code True150 --trust_remote_code True
151```151```
152 152 
@@ -355,7 +355,7 @@ msmodelslim quant \
355 355 
356## 6. 异常处理356## 6. 异常处理
357 357 
358-- **量化命令执行失败(OOM)**:DeepSeek-V4-Flash W8A8 量化单卡即可完成,一般不会出现 OOM;若遇显存不足,请确认 `--device npu:0` 指定的 NPU 未被其他任务占用。358+- **量化命令执行失败(OOM)**:DeepSeek-V4-Flash W8A8 量化单卡即可完成,一般不会出现 OOM;若遇显存不足,请确认 `--device npu --device_id 0` 指定的 NPU 未被其他任务占用。
359- **Transformers 加载模型报错**:确认是否安装了 `transformers==4.48.2`,且模型权重路径正确。注意使用非 0731 版本的权重。359- **Transformers 加载模型报错**:确认是否安装了 `transformers==4.48.2`,且模型权重路径正确。注意使用非 0731 版本的权重。
360- **vLLM 服务启动失败**:本次实际排查动作依次为:检查 CANN 环境变量(`env | grep ASCEND`)、NPU 状态(`npu-smi info`),并确认 `--tensor-parallel-size 8` 与实际卡数一致。360- **vLLM 服务启动失败**:本次实际排查动作依次为:检查 CANN 环境变量(`env | grep ASCEND`)、NPU 状态(`npu-smi info`),并确认 `--tensor-parallel-size 8` 与实际卡数一致。
361 361 
@@ -253,7 +253,7 @@ msmodelslim quant \
253 --save_path ${SAVE_PATH} \253 --save_path ${SAVE_PATH} \
254 --model_type DeepSeek-V4-Pro \254 --model_type DeepSeek-V4-Pro \
255 --quant_type w4a8 \255 --quant_type w4a8 \
256- --device npu:0,1,2,3,4,5,6,7 \256+ --device npu --device_id 0 1 2 3 4 5 6 7 \
257 --trust_remote_code True257 --trust_remote_code True
258```258```
259 259 
@@ -417,7 +417,7 @@ msmodelslim quant \
417 --model_type DeepSeek-V4-Pro \417 --model_type DeepSeek-V4-Pro \
418 --model_path ${MODEL_PATH} \418 --model_path ${MODEL_PATH} \
419 --metrics kurtosis \419 --metrics kurtosis \
420- --topk 15420+ --top_k 15
421 ```421 ```
422 422 
423 分析结果按敏感度从高到低输出敏感层列表,日志中会附带可直接粘贴到量化配置的 YAML 片段。423 分析结果按敏感度从高到低输出敏感层列表,日志中会附带可直接粘贴到量化配置的 YAML 片段。
@@ -557,7 +557,7 @@ ais_bench \
557 557 
5584. **量化命令需在 msmodelslim 目录外执行**`msmodelslim quant` 命令需要在 `msmodelslim` 目录的父目录执行,否则可能因路径解析问题导致执行失败。适用边界:源码安装方式(`git clone` + `bash install.sh`)。5584. **量化命令需在 msmodelslim 目录外执行**`msmodelslim quant` 命令需要在 `msmodelslim` 目录的父目录执行,否则可能因路径解析问题导致执行失败。适用边界:源码安装方式(`git clone` + `bash install.sh`)。
559 559 
560-5. **DeepSeek-V4-Pro W4A8 量化需指定多卡**:W4A8 量化算法较为复杂,单卡量化时间较久,推荐通过 `--device npu:0,1,2,3,4,5,6,7` 指定 8 卡进行多卡量化,以缩短量化耗时。适用边界:DeepSeek-V4-Pro 等大参数量模型在 Atlas 800I A3 形态下的 W4A8 量化阶段(vLLM Ascend 0.22.1rc1 镜像)。560+5. **DeepSeek-V4-Pro W4A8 量化需指定多卡**:W4A8 量化算法较为复杂,单卡量化时间较久,推荐通过 `--device npu --device_id 0 1 2 3 4 5 6 7` 指定 8 卡进行多卡量化,以缩短量化耗时。适用边界:DeepSeek-V4-Pro 等大参数量模型在 Atlas 800I A3 形态下的 W4A8 量化阶段(vLLM Ascend 0.22.1rc1 镜像)。
561 561 
5626. **W4A8 混合量化策略**:DeepSeek-V4-Pro 的 W4A8 量化采用混合策略——路由专家使用 W4A8 动态量化(`ssz` 方法),共享专家和注意力层使用 W8A8 动态量化,在保证精度的同时有效降低模型大小和推理显存占用。适用边界:DeepSeek-V4-Pro W4A8 量化方案(Atlas 800I A3 形态)。5626. **W4A8 混合量化策略**:DeepSeek-V4-Pro 的 W4A8 量化采用混合策略——路由专家使用 W4A8 动态量化(`ssz` 方法),共享专家和注意力层使用 W8A8 动态量化,在保证精度的同时有效降低模型大小和推理显存占用。适用边界:DeepSeek-V4-Pro W4A8 量化方案(Atlas 800I A3 形态)。
563 563 
@@ -569,7 +569,7 @@ ais_bench \
569 569 
570- **适配器未生效(`--model_type` 无法识别)**:确认 `config/config.ini` 已注册 `deepseek_v4 = DeepSeek-V4-Flash, DeepSeek-V4-Pro`,并在修改后重新执行 `bash install.sh`,检查 `msmodelslim.egg-info/entry_points.txt` 中是否已生成 `DeepSeek-V4-Pro = msmodelslim.model.deepseek_v4.loader:DeepseekV4AdapterLoader`。570- **适配器未生效(`--model_type` 无法识别)**:确认 `config/config.ini` 已注册 `deepseek_v4 = DeepSeek-V4-Flash, DeepSeek-V4-Pro`,并在修改后重新执行 `bash install.sh`,检查 `msmodelslim.egg-info/entry_points.txt` 中是否已生成 `DeepSeek-V4-Pro = msmodelslim.model.deepseek_v4.loader:DeepseekV4AdapterLoader`。
571- **量化配置未匹配**:确认 `lab_practice/deepseek_v4/` 下 yaml 的 `metadata.verified_model_types` 包含 `DeepSeek-V4-Pro`,且 `metadata.label``--quant_type w4a8` 对应(`w_bit: 4``a_bit: 8`)。571- **量化配置未匹配**:确认 `lab_practice/deepseek_v4/` 下 yaml 的 `metadata.verified_model_types` 包含 `DeepSeek-V4-Pro`,且 `metadata.label``--quant_type w4a8` 对应(`w_bit: 4``a_bit: 8`)。
572-- **量化命令执行失败(OOM)**:DeepSeek-V4-Pro W4A8 量化单卡即可完成,实际工程场景下会开启多卡量化加速,一般不会出现 OOM;若遇显存不足,请确认 `--device npu:0,1,2,3,4,5,6,7` 指定的 NPU 未被其他任务占用。572+- **量化命令执行失败(OOM)**:DeepSeek-V4-Pro W4A8 量化单卡即可完成,实际工程场景下会开启多卡量化加速,一般不会出现 OOM;若遇显存不足,请确认 `--device npu --device_id 0 1 2 3 4 5 6 7` 指定的 NPU 未被其他任务占用。
573- **Transformers 加载模型报错**:确认是否安装了 `transformers==4.48.2`,且模型权重路径正确。573- **Transformers 加载模型报错**:确认是否安装了 `transformers==4.48.2`,且模型权重路径正确。
574- **vLLM 服务启动失败**:本次实际排查动作依次为:检查 CANN 环境变量(`env | grep ASCEND`)、NPU 状态(`npu-smi info`),并确认 `--tensor-parallel-size 16` 与多节点卡数一致;DeepSeek-V4-Pro 模型较大,需使用多节点部署(至少 2 个 A3 节点,16 卡/节点)。574- **vLLM 服务启动失败**:本次实际排查动作依次为:检查 CANN 环境变量(`env | grep ASCEND`)、NPU 状态(`npu-smi info`),并确认 `--tensor-parallel-size 16` 与多节点卡数一致;DeepSeek-V4-Pro 模型较大,需使用多节点部署(至少 2 个 A3 节点,16 卡/节点)。
575 575 
@@ -35,7 +35,7 @@
35| 输入 | 浮点权重 | [Kimi-K3](https://huggingface.co/moonshotai/Kimi-K3) | 权重文件完整 | 下载完成且哈希值匹配 |35| 输入 | 浮点权重 | [Kimi-K3](https://huggingface.co/moonshotai/Kimi-K3) | 权重文件完整 | 下载完成且哈希值匹配 |
36| 交付件 | 模型适配器代码 | [`msmodelslim/model/kimi_k3/`](../../../msmodelslim/model/kimi_k3/) | 适配器需实现量化流水线所需接口 | 命令行指定 `--model_type Kimi-K3` 可命中适配器 |36| 交付件 | 模型适配器代码 | [`msmodelslim/model/kimi_k3/`](../../../msmodelslim/model/kimi_k3/) | 适配器需实现量化流水线所需接口 | 命令行指定 `--model_type Kimi-K3` 可命中适配器 |
37| 交付件 | 量化最佳实践 | [`lab_practice/kimi_k3/kimi_k3_w4a8.yaml`](../../../lab_practice/kimi_k3/kimi_k3_w4a8.yaml) | 遵循[量化配置协议](../user_guide/usage_quick_quantization.md#5-量化配置协议详解) | 命令行指定 `--quant_type w4a8` 可匹配到该配置 |37| 交付件 | 量化最佳实践 | [`lab_practice/kimi_k3/kimi_k3_w4a8.yaml`](../../../lab_practice/kimi_k3/kimi_k3_w4a8.yaml) | 遵循[量化配置协议](../user_guide/usage_quick_quantization.md#5-量化配置协议详解) | 命令行指定 `--quant_type w4a8` 可匹配到该配置 |
38-| 交付件 | 量化权重目录 | 命令行参数 `--save_path` 指定保存位置 | 遵循[AscendV1 格式](../knowledge_base/quantization_format/ascendv1/ascendv1.md) | 量化权重精度测试达标 |38+| 交付件 | 量化权重目录 | 命令行参数 `--save_path` 指定保存位置 | 遵循[AscendV1 格式](../knowledge_base/quantization_format/ascendv1/ascendv1_usage.md) | 量化权重精度测试达标 |
39 39 
40## 4. 操作步骤40## 4. 操作步骤
41 41 
@@ -125,9 +125,9 @@
125 msmodelslim quant \125 msmodelslim quant \
126 --model_path ${MODEL_PATH} \126 --model_path ${MODEL_PATH} \
127 --save_path ${SAVE_PATH} \127 --save_path ${SAVE_PATH} \
128- --device npu:0,1,2,3,4,5,6,7 \128+ --device npu --device_id 0 1 2 3 4 5 6 7 \
129 --model_type Kimi-K3 \129 --model_type Kimi-K3 \
130- --config_path ${YAML_PATH} \130+ --config ${YAML_PATH} \
131 --trust_remote_code True131 --trust_remote_code True
132 ```132 ```
133 133 
@@ -198,7 +198,7 @@
198| --- | --- | --- | --- | --- |198| --- | --- | --- | --- | --- |
199| 步骤 1 | 开发并注册模型适配器 | `--model_type Kimi-K3` 可命中适配器 | 新增模型适配器 | 开发完成后需重新安装以使代码生效 |199| 步骤 1 | 开发并注册模型适配器 | `--model_type Kimi-K3` 可命中适配器 | 新增模型适配器 | 开发完成后需重新安装以使代码生效 |
200| 步骤 2 | 设计混合量化方案 | `kimi_k3_w4a8.yaml` | 新增量化实践配置 | 量化实践配置遵循[量化配置协议](../user_guide/usage_quick_quantization.md#5-量化配置协议详解) |200| 步骤 2 | 设计混合量化方案 | `kimi_k3_w4a8.yaml` | 新增量化实践配置 | 量化实践配置遵循[量化配置协议](../user_guide/usage_quick_quantization.md#5-量化配置协议详解) |
201-| 步骤 3 | 执行量化命令 | W4A8 量化权重 | 导出量化权重 | 导出件遵循[AscendV1 格式](../knowledge_base/quantization_format/ascendv1/ascendv1.md) |201+| 步骤 3 | 执行量化命令 | W4A8 量化权重 | 导出量化权重 | 导出件遵循[AscendV1 格式](../knowledge_base/quantization_format/ascendv1/ascendv1_usage.md) |
202| 步骤 4 | vLLM Ascend 部署 + AISBench 精度测评 | GPQA / OCRBench | 完成精度验证 | 精度达标 |202| 步骤 4 | vLLM Ascend 部署 + AISBench 精度测评 | GPQA / OCRBench | 完成精度验证 | 精度达标 |
203 203 
204### 5.2 经验总结204### 5.2 经验总结
@@ -56,7 +56,7 @@ msmodelslim quant \
56 --model_path ${MODEL_PATH} \56 --model_path ${MODEL_PATH} \
57 --save_path ${SAVE_PATH} \57 --save_path ${SAVE_PATH} \
58 --device npu \58 --device npu \
59- --config_path ${CONFIG_PATH} \59+ --config ${CONFIG_PATH} \
60 --trust_remote_code True60 --trust_remote_code True
61```61```
62 62 
@@ -88,15 +88,15 @@ msmodelslim quant \
88 88 
89**操作**89**操作**
90 90 
91-1. **生成配置并量化**:在量化配置 YAML 的 `process` 中依次替换离群值抑制处理器(算法、对称性、`alpha` 参数),得到 5 组实验配置(均搭配相同的 `linear_quant` 静态量化与 `save` 段),逐一执行量化命令(`--config_path` 与 `--save_path` 按算法区分)。各组算法配置要点如下(完整参数见算法文档):91+1. **生成配置并量化**:在量化配置 YAML 的 `process` 中依次替换离群值抑制处理器(算法、对称性、`alpha` 参数),得到 5 组实验配置(均搭配相同的 `linear_quant` 静态量化与 `save` 段),逐一执行量化命令(`--config` 与 `--save_path` 按算法区分)。各组算法配置要点如下(完整参数见算法文档):
92 92 
93- a. **Smooth Quant(初始配置)**:alpha 0.5、对称。详见[《Smooth Quant 算法》](../knowledge_base/quantization_algorithms/smooth_quant/smooth_quant.md)。93+ a. **Smooth Quant(初始配置)**:alpha 0.5、对称。详见[《Smooth Quant 算法》](../knowledge_base/quantization_algorithms/smooth_quant/usage_smooth_quant.md)。
94 94 
95- b. **Iterative Smooth(对称)**:对称/alpha:0.5 与 对称/alpha:0.9 两组仅 `alpha` 参数不同,其余配置相同(4 类子图)。详见[《Iterative Smooth 算法》](../knowledge_base/quantization_algorithms/iterative_smooth/iterative_smooth.md)。95+ b. **Iterative Smooth(对称)**:对称/alpha:0.5 与 对称/alpha:0.9 两组仅 `alpha` 参数不同,其余配置相同(4 类子图)。详见[《Iterative Smooth 算法》](../knowledge_base/quantization_algorithms/iterative_smooth/usage_iterative_smooth.md)。
96 96 
97 c. **Iterative Smooth(非对称/alpha:0.5)**:非对称仅支持 `norm-linear` 子图。97 c. **Iterative Smooth(非对称/alpha:0.5)**:非对称仅支持 `norm-linear` 子图。
98 98 
99- d. **Flex Smooth Quant**:alpha/beta 缺省自动搜索。详见[《Flex Smooth Quant 算法》](../knowledge_base/quantization_algorithms/flex_smooth_quant/flex_smooth_quant.md)。99+ d. **Flex Smooth Quant**:alpha/beta 缺省自动搜索。详见[《Flex Smooth Quant 算法》](../knowledge_base/quantization_algorithms/flex_smooth_quant/usage_flex_smooth_quant.md)。
100 100 
101 算法对比见[离群值抑制算法](../knowledge_base/quantization_algorithms/README.md#离群值抑制算法)。101 算法对比见[离群值抑制算法](../knowledge_base/quantization_algorithms/README.md#离群值抑制算法)。
102 102 
@@ -125,7 +125,7 @@ msmodelslim quant \
125 125 
126**操作**126**操作**
127 127 
128-1. **生成配置并量化**:在量化配置 YAML 的 `linear_quant` 处理器中,分别修改 `qconfig.act.scope`(`per_tensor`/`per_token`)与 `qconfig.weight.method`(`minmax`/`ssz`),组合出 4 组配置并逐一执行量化命令。`linear_quant` 处理器参数详见[《Linear Quant 算法》](../knowledge_base/quantization_algorithms/linear_quant/linear_quant.md),量化方法参数详见[MinMax](../knowledge_base/quantization_algorithms/minmax/minmax.md)、[SSZ](../knowledge_base/quantization_algorithms/ssz/ssz.md)。128+1. **生成配置并量化**:在量化配置 YAML 的 `linear_quant` 处理器中,分别修改 `qconfig.act.scope`(`per_tensor`/`per_token`)与 `qconfig.weight.method`(`minmax`/`ssz`),组合出 4 组配置并逐一执行量化命令。`linear_quant` 处理器参数详见[《Linear Quant 算法》](../knowledge_base/quantization_algorithms/linear_quant/usage_linear_quant.md),量化方法参数详见[MinMax](../knowledge_base/quantization_algorithms/minmax/usage_minmax.md)、[SSZ](../knowledge_base/quantization_algorithms/ssz/usage_ssz.md)。
129 129 
1302. **部署测评**:将每组量化产物部署后执行测评命令(AIME25),记录精度与量化耗时。1302. **部署测评**:将每组量化产物部署后执行测评命令(AIME25),记录精度与量化耗时。
1313. **汇总对比**:对比精度与量化时间,选择综合最优配置。1313. **汇总对比**:对比精度与量化时间,选择综合最优配置。
@@ -222,7 +222,7 @@ msmodelslim quant \
222 --model_type Qwen3-32B \222 --model_type Qwen3-32B \
223 --model_path ${MODEL_PATH} \223 --model_path ${MODEL_PATH} \
224 --device npu \224 --device npu \
225- --topk 20 \225+ --top_k 20 \
226 --metrics kurtosis226 --metrics kurtosis
227 ```227 ```
228 228 
@@ -177,7 +177,7 @@ msmodelslim quant --model_path ${MODEL_PATH} \
177 --save_path ${SAVE_PATH} \177 --save_path ${SAVE_PATH} \
178 --device npu \178 --device npu \
179 --model_type ${MODEL_TYPE} \179 --model_type ${MODEL_TYPE} \
180- --config_path ${CONFIG_PATH} \180+ --config ${CONFIG_PATH} \
181 --trust_remote_code False181 --trust_remote_code False
182```182```
183 183 
@@ -1386,7 +1386,7 @@ msmodelslim quant \
1386 --save_path ${SAVE_PATH} \1386 --save_path ${SAVE_PATH} \
1387 --device npu \1387 --device npu \
1388 --model_type Wan2.2-T2V-A14B \1388 --model_type Wan2.2-T2V-A14B \
1389- --config_path ${CONFIG_PATH} \1389+ --config ${CONFIG_PATH} \
1390 --trust_remote_code True1390 --trust_remote_code True
1391```1391```
1392 1392 
@@ -546,7 +546,7 @@ msmodelslim quant --model_path ${MODEL_PATH} \
546 --save_path ${SAVE_PATH} \546 --save_path ${SAVE_PATH} \
547 --device npu \547 --device npu \
548 --model_type ${MODEL_TYPE} \548 --model_type ${MODEL_TYPE} \
549- --config_path ${CONFIG_PATH} \549+ --config ${CONFIG_PATH} \
550 --trust_remote_code True550 --trust_remote_code True
551```551```
552 552 
@@ -44,7 +44,7 @@ msmodelslim quant \
44 --save_path ${SAVE_PATH} \44 --save_path ${SAVE_PATH} \
45 --model_type ${MODEL_TYPE} \45 --model_type ${MODEL_TYPE} \
46 --quant_type ${QUANT_TYPE} \46 --quant_type ${QUANT_TYPE} \
47- --device npu:0,1,2,3,4,5,6,747+ --device npu --device_id 0 1 2 3 4 5 6 7
48```48```
49 49 
50**说明**:多卡量化启用后会自动调用已适配支持的 DP、EP、DTS 等并行机制。50**说明**:多卡量化启用后会自动调用已适配支持的 DP、EP、DTS 等并行机制。
@@ -192,10 +192,10 @@ flowchart LR
192 --save_path ${save_path} \192 --save_path ${save_path} \
193 --model_type ${MODEL_TYPE} \193 --model_type ${MODEL_TYPE} \
194 --quant_type ${QUANT_TYPE} \194 --quant_type ${QUANT_TYPE} \
195- --device npu:0,1,2,3,4,5,6,7195+ --device npu --device_id 0 1 2 3 4 5 6 7
196 ```196 ```
197 197 
198- `--device npu:0,1,...` 指定参与量化的设备索引列表(`modelslim_v1` 服务支持该格式)198+ `--device npu --device_id 0 1 ...` 指定参与量化的设备索引列表。
199 199 
2003. 确认 runner 实际选择。`modelslim_v1``_choose_runner_type` 按以下规则决定执行管线(对应 [`quant_service.py`](https://gitcode.com/Ascend/msmodelslim/blob/master/msmodelslim/core/quant_service/modelslim_v1/quant_service.py)):2003. 确认 runner 实际选择。`modelslim_v1``_choose_runner_type` 按以下规则决定执行管线(对应 [`quant_service.py`](https://gitcode.com/Ascend/msmodelslim/blob/master/msmodelslim/core/quant_service/modelslim_v1/quant_service.py)):
201 201 
@@ -240,7 +240,7 @@ flowchart LR
240| `sync_base_operation` 等 | 跨 rank 统计量归约工具函数 | [dist_ops.py](https://gitcode.com/Ascend/msmodelslim/blob/master/msmodelslim/utils/distributed/dist_ops.py) |240| `sync_base_operation` 等 | 跨 rank 统计量归约工具函数 | [dist_ops.py](https://gitcode.com/Ascend/msmodelslim/blob/master/msmodelslim/utils/distributed/dist_ops.py) |
241| `support_distributed()` | Processor 分布式支持声明(基类默认 `False`) | [processor/base.py](https://gitcode.com/Ascend/msmodelslim/blob/master/msmodelslim/processor/base.py) |241| `support_distributed()` | Processor 分布式支持声明(基类默认 `False`) | [processor/base.py](https://gitcode.com/Ascend/msmodelslim/blob/master/msmodelslim/processor/base.py) |
242| `ascendv1_saver_distributed` | 分布式保存器(由 `ascendv1_saver` 自动转换) | [ascendv1_distributed.py](https://gitcode.com/Ascend/msmodelslim/blob/master/msmodelslim/core/quant_service/modelslim_v1/save/ascendv1_distributed.py) |242| `ascendv1_saver_distributed` | 分布式保存器(由 `ascendv1_saver` 自动转换) | [ascendv1_distributed.py](https://gitcode.com/Ascend/msmodelslim/blob/master/msmodelslim/core/quant_service/modelslim_v1/save/ascendv1_distributed.py) |
243-| `--device npu:0,1,...` | 多卡量化入口配置 | 《[一键量化使用说明](../../../user_guide/usage_quick_quantization.md)》 |243+| `--device npu --device_id 0 1 ...` | 多卡量化入口配置 | 《[一键量化使用说明](../../../user_guide/usage_quick_quantization.md)》 |
244 244 
245## 10. 产品形态与资源限制245## 10. 产品形态与资源限制
246 246 
@@ -159,7 +159,7 @@ for expert in range(expert_start, expert_end):
159| `resolve_expert_ep_range` / `_get_expert_range` | 本地专家范围解析:单进程返回全量,多进程按 `world_size` 连续分片,不可整除时报错 | [common/utils.py](https://gitcode.com/Ascend/msmodelslim/blob/master/msmodelslim/model/common/utils.py) |159| `resolve_expert_ep_range` / `_get_expert_range` | 本地专家范围解析:单进程返回全量,多进程按 `world_size` 连续分片,不可整除时报错 | [common/utils.py](https://gitcode.com/Ascend/msmodelslim/blob/master/msmodelslim/model/common/utils.py) |
160| `DistHelper` | 模块拓扑分类:`is_shared` / `is_local_only` / `get_shared_modules_slice` | [dist_helper.py](https://gitcode.com/Ascend/msmodelslim/blob/master/msmodelslim/utils/distributed/dist_helper.py) |160| `DistHelper` | 模块拓扑分类:`is_shared` / `is_local_only` / `get_shared_modules_slice` | [dist_helper.py](https://gitcode.com/Ascend/msmodelslim/blob/master/msmodelslim/utils/distributed/dist_helper.py) |
161| `DistributedAscendV1Saver` | 分布式保存:`local_only` 独占写出、共享模块分工、rank 0 合并 | [ascendv1_distributed.py](https://gitcode.com/Ascend/msmodelslim/blob/master/msmodelslim/core/quant_service/modelslim_v1/save/ascendv1_distributed.py) |161| `DistributedAscendV1Saver` | 分布式保存:`local_only` 独占写出、共享模块分工、rank 0 合并 | [ascendv1_distributed.py](https://gitcode.com/Ascend/msmodelslim/blob/master/msmodelslim/core/quant_service/modelslim_v1/save/ascendv1_distributed.py) |
162-| `--device npu:0,1,...` / `spec.runner` | 多卡量化入口(EP 在分布式初始化后生效) | 《[一键量化使用说明](../../../user_guide/usage_quick_quantization.md)》 |162+| `--device npu --device_id 0 1 ...` / `spec.runner` | 多卡量化入口(EP 在分布式初始化后生效) | 《[一键量化使用说明](../../../user_guide/usage_quick_quantization.md)》 |
163 163 
164## 10. 产品形态与资源限制164## 10. 产品形态与资源限制
165 165 
@@ -13,13 +13,13 @@
13- FP8 block 权重直接转换为 W8A8 MXFP8(自动路由串联)13- FP8 block 权重直接转换为 W8A8 MXFP8(自动路由串联)
14- INT4 分组量化权重反量化为 BF1614- INT4 分组量化权重反量化为 BF16
15 15 
16-**与常规一键量化的区别**:权重转换不需要校准数据、不需要 `model_type`、不需要 `quant_type`,仅通过 `--config_path` 指定转换配置。16+**与常规一键量化的区别**:权重转换不需要校准数据、不需要 `model_type`、不需要 `quant_type`,仅通过 `--config` 指定转换配置。
17 17 
18| 对比项 | 常规一键量化 | 权重转换(modelslim_convert) |18| 对比项 | 常规一键量化 | 权重转换(modelslim_convert) |
19|--------|--------------|-------------------------------|19|--------|--------------|-------------------------------|
20| 是否需要校准集 | 是(激活值统计等) | **否** |20| 是否需要校准集 | 是(激活值统计等) | **否** |
21| 是否需要 `model_type` | 必选 | **可选**(YAML 中 `apiversion: modelslim_convert` 时可省略) |21| 是否需要 `model_type` | 必选 | **可选**(YAML 中 `apiversion: modelslim_convert` 时可省略) |
22-| 是否需要 `quant_type` | 方式 1 需要 | **不需要**(须通过 `config_path` 指定转换配置) |22+| 是否需要 `quant_type` | 方式 1 需要 | **不需要**(须通过 `--config` 指定转换配置) |
23| 典型场景 | 浮点模型 → W8A8 等 | FP8 → BF16、BF16 → MXFP8、FP8 → MXFP8 等 |23| 典型场景 | 浮点模型 → W8A8 等 | FP8 → BF16、BF16 → MXFP8、FP8 → MXFP8 等 |
24 24 
25当前已注册的 IR 转换边包括:25当前已注册的 IR 转换边包括:
@@ -54,7 +54,7 @@
54| --- | --- | --- | --- | --- |54| --- | --- | --- | --- | --- |
55| 输入 | msModelSlim 工具 | 已安装环境 | 可执行 `msmodelslim` 命令 | `msmodelslim --help` 正常输出 |55| 输入 | msModelSlim 工具 | 已安装环境 | 可执行 `msmodelslim` 命令 | `msmodelslim --help` 正常输出 |
56| 输入 | 源权重目录 | 模型下载或本地路径 | HuggingFace 格式,含 `config.json``*.safetensors` | 可被读取,含 `model.safetensors.index.json` 或单文件权重 |56| 输入 | 源权重目录 | 模型下载或本地路径 | HuggingFace 格式,含 `config.json``*.safetensors` | 可被读取,含 `model.safetensors.index.json` 或单文件权重 |
57-| 输入 | 转换配置 YAML | `--config_path` 指定 | `apiversion: modelslim_convert`,含 `spec.linears`、`spec.save` 等 | 配置校验通过 |57+| 输入 | 转换配置 YAML | `--config` 指定 | `apiversion: modelslim_convert`,含 `spec.linears`、`spec.save` 等 | 配置校验通过 |
58| 交付件 | 转换后权重目录 | `--save_path` 指定路径 | 目标 IR 对应格式(ascend_v1 / huggingface) | 含完整权重文件,可被目标推理框架加载 |58| 交付件 | 转换后权重目录 | `--save_path` 指定路径 | 目标 IR 对应格式(ascend_v1 / huggingface) | 含完整权重文件,可被目标推理框架加载 |
59| 交付件 | 精度评估结果 | 用户记录 | 转换前后精度对比报告 | 精度在可接受范围内 |59| 交付件 | 精度评估结果 | 用户记录 | 转换前后精度对比报告 | 精度在可接受范围内 |
60 60 
@@ -109,13 +109,13 @@ msmodelslim --help
109 109 
110**操作**110**操作**
111 111 
112-权重转换复用一键量化 CLI 入口,通过 **`--config_path`** 指定 `modelslim_convert` 配置:112+权重转换复用一键量化 CLI 入口,通过 **`--config`** 指定 `modelslim_convert` 配置:
113 113 
114```bash114```bash
115msmodelslim quant \115msmodelslim quant \
116 --model_path ${MODEL_PATH} \116 --model_path ${MODEL_PATH} \
117 --save_path ${SAVE_PATH} \117 --save_path ${SAVE_PATH} \
118- --config_path ${CONFIG_PATH}118+ --config ${CONFIG_PATH}
119```119```
120 120 
121**参数说明**121**参数说明**
@@ -124,7 +124,7 @@ msmodelslim quant \
124|------|----------|------|124|------|----------|------|
125| `model_path` | 必选 | 源权重目录路径。 |125| `model_path` | 必选 | 源权重目录路径。 |
126| `save_path` | 必选 | 转换后权重保存路径。 |126| `save_path` | 必选 | 转换后权重保存路径。 |
127-| `config_path` | 必选 | YAML 转换配置路径,`apiversion` 须为 `modelslim_convert`。 |127+| `--config` | 必选 | YAML 转换配置路径,`apiversion` 须为 `modelslim_convert`。 |
128| `-h, --help` | 可选 | 命令行帮助信息。 |128| `-h, --help` | 可选 | 命令行帮助信息。 |
129 129 
130**注意事项**130**注意事项**
@@ -141,7 +141,7 @@ msmodelslim quant \
141msmodelslim quant \141msmodelslim quant \
142 --model_path ${MODEL_PATH} \142 --model_path ${MODEL_PATH} \
143 --save_path ${SAVE_PATH} \143 --save_path ${SAVE_PATH} \
144- --config_path ./qwen3_8b_fp8_to_bf16.yaml144+ --config ./qwen3_8b_fp8_to_bf16.yaml
145```145```
146 146 
147其中 `${MODEL_PATH}` 为含 FP8 block 权重(`.weight` + `.weight_scale_inv`)的源目录,配置文件见 [qwen3_8b_fp8_to_bf16.yaml](./qwen3_8b_fp8_to_bf16.yaml)。147其中 `${MODEL_PATH}` 为含 FP8 block 权重(`.weight` + `.weight_scale_inv`)的源目录,配置文件见 [qwen3_8b_fp8_to_bf16.yaml](./qwen3_8b_fp8_to_bf16.yaml)。
@@ -152,7 +152,7 @@ msmodelslim quant \
152msmodelslim quant \152msmodelslim quant \
153 --model_path ${MODEL_PATH} \153 --model_path ${MODEL_PATH} \
154 --save_path ${SAVE_PATH} \154 --save_path ${SAVE_PATH} \
155- --config_path ./qwen3_8b_bf16_to_mxfp8.yaml155+ --config ./qwen3_8b_bf16_to_mxfp8.yaml
156```156```
157 157 
158配置文件见 [qwen3_8b_bf16_to_mxfp8.yaml](./qwen3_8b_bf16_to_mxfp8.yaml)。158配置文件见 [qwen3_8b_bf16_to_mxfp8.yaml](./qwen3_8b_bf16_to_mxfp8.yaml)。
@@ -165,7 +165,7 @@ msmodelslim quant \
165msmodelslim quant \165msmodelslim quant \
166 --model_path ${MODEL_PATH} \166 --model_path ${MODEL_PATH} \
167 --save_path ${SAVE_PATH} \167 --save_path ${SAVE_PATH} \
168- --config_path ./qwen3_8b_fp8_to_mxfp8.yaml168+ --config ./qwen3_8b_fp8_to_mxfp8.yaml
169```169```
170 170 
171配置文件见 [qwen3_8b_fp8_to_mxfp8.yaml](./qwen3_8b_fp8_to_mxfp8.yaml)。171配置文件见 [qwen3_8b_fp8_to_mxfp8.yaml](./qwen3_8b_fp8_to_mxfp8.yaml)。
@@ -185,7 +185,7 @@ msmodelslim quant \
185 185 
186 | save.type | 典型目标 IR | 输出特征 |186 | save.type | 典型目标 IR | 输出特征 |
187 |-----------|-------------|----------|187 |-----------|-------------|----------|
188- | `ascend_v1` | `W8A8_MXFP8` | 生成 `quant_model_description.json`、`quant_model_weights*.safetensors` 等 AscendV1 量化权重,详见《[一键量化生成结果](../../quantization_format/ascendv1/ascendv1.md)》 |188+ | `ascend_v1` | `W8A8_MXFP8` | 生成 `quant_model_description.json`、`quant_model_weights*.safetensors` 等 AscendV1 量化权重,详见《[一键量化生成结果](../../quantization_format/ascendv1/ascendv1_usage.md)》 |
189 | `huggingface` / `compressed_tensors` | `FLOAT` | 生成 HF 风格 `config.json``model*.safetensors` 等,权重为 BF16 浮点 |189 | `huggingface` / `compressed_tensors` | `FLOAT` | 生成 HF 风格 `config.json``model*.safetensors` 等,权重为 BF16 浮点 |
190 190 
1912. 确认目标 IR 与保存格式匹配(MXFP8 → ascend_v1,FLOAT → huggingface)。1912. 确认目标 IR 与保存格式匹配(MXFP8 → ascend_v1,FLOAT → huggingface)。
@@ -468,7 +468,7 @@ spec:
468- 转换后权重可被目标推理框架成功加载。468- 转换后权重可被目标推理框架成功加载。
469- 精度评估结果在可接受范围内。469- 精度评估结果在可接受范围内。
470 470 
471-- 一键量化总体流程与常规量化配置:《[一键量化完整指南](usage.md)》471+- 一键量化总体流程与常规量化配置:《[一键量化完整指南](../../../user_guide/usage_quick_quantization.md)》
472- AscendV1 量化权重文件说明:《[一键量化生成结果](../../quantization_format/ascendv1/term_ascendv1.md)》472- AscendV1 量化权重文件说明:《[一键量化生成结果](../../quantization_format/ascendv1/term_ascendv1.md)》
473- 格式支持矩阵:《[格式支持矩阵](../../quantization_format/README.md)》473- 格式支持矩阵:《[格式支持矩阵](../../quantization_format/README.md)》
474 474 
@@ -529,4 +529,4 @@ route:
529| --- | --- | --- |529| --- | --- | --- |
530| 权重转换配置协议 | modelslim_convert YAML 配置详解 | [权重转换使用指南 - 配置协议](#6-转换配置协议详解) |530| 权重转换配置协议 | modelslim_convert YAML 配置详解 | [权重转换使用指南 - 配置协议](#6-转换配置协议详解) |
531| 格式支持矩阵 | 量化格式与存储格式说明 | [格式支持矩阵](../../quantization_format/README.md) |531| 格式支持矩阵 | 量化格式与存储格式说明 | [格式支持矩阵](../../quantization_format/README.md) |
532-| AscendV1 量化结果 | 一键量化生成结果说明 | [一键量化生成结果](../../quantization_format/ascendv1/ascendv1.md) |532+| AscendV1 量化结果 | 一键量化生成结果说明 | [一键量化生成结果](../../quantization_format/ascendv1/ascendv1_usage.md) |
@@ -522,7 +522,7 @@ msmodelslim quant \
522 --save_path ${SAVE_PATH} \522 --save_path ${SAVE_PATH} \
523 --device npu \523 --device npu \
524 --model_type ${MODEL_TYPE} \524 --model_type ${MODEL_TYPE} \
525- --config_path ${CONFIG_PATH}525+ --config ${CONFIG_PATH}
526```526```
527 527 
528**验证要点**528**验证要点**
@@ -558,7 +558,7 @@ msmodelslim quant \
558- **推理管线加载失败**:确认 Wan2.2 官方仓库已安装并加入 PYTHONPATH;确认 `wan``mindiesd` 等依赖可正常导入。558- **推理管线加载失败**:确认 Wan2.2 官方仓库已安装并加入 PYTHONPATH;确认 `wan``mindiesd` 等依赖可正常导入。
559- **浮点推理失败**:检查 `inference_config` 参数是否正确(size、frame_num、sample_steps、task 等);确认 task 与模型类型匹配。559- **浮点推理失败**:检查 `inference_config` 参数是否正确(size、frame_num、sample_steps、task 等);确认 task 与模型类型匹配。
560- **校准数据缺失**:检查 `enable_dump` 是否为 True,`dump_data_dir` 是否有写入权限;确认多专家模型的每个专家均有对应的 `calib_data` key。560- **校准数据缺失**:检查 `enable_dump` 是否为 True,`dump_data_dir` 是否有写入权限;确认多专家模型的每个专家均有对应的 `calib_data` key。
561-- **显存不足**:降低分辨率(`size`)或减少推理步数(`sample_steps`);减少校准样本数量。此外,若仍遇到显存不足,请确认 `--device npu:0` 指定的 NPU 未被其他任务占用。561+- **显存不足**:降低分辨率(`size`)或减少推理步数(`sample_steps`);减少校准样本数量。此外,若仍遇到显存不足,请确认 `--device npu --device_id 0` 指定的 NPU 未被其他任务占用。
562- **MindIE-SD 加载失败**:确认使用 `mindie_format_saver` 保存权重;确认多专家模型各专家子目录权重完整。562- **MindIE-SD 加载失败**:确认使用 `mindie_format_saver` 保存权重;确认多专家模型各专家子目录权重完整。
563 563 
564## 7. 附录564## 7. 附录
@@ -86,7 +86,7 @@ msmodelslim quant \
86 --save_path ${SAVE_PATH} \86 --save_path ${SAVE_PATH} \
87 --device npu \87 --device npu \
88 --model_type ${MODEL_TYPE} \88 --model_type ${MODEL_TYPE} \
89- --config_path ${CONFIG_PATH}89+ --config ${CONFIG_PATH}
90```90```
91 91 
92**参数说明**92**参数说明**
@@ -104,7 +104,7 @@ msmodelslim quant \
104- DiT 量化会首先运行浮点推理管线(可能耗时较长),生成校准数据后自动进入量化阶段。104- DiT 量化会首先运行浮点推理管线(可能耗时较长),生成校准数据后自动进入量化阶段。
105- 对于多专家模型(如 Wan2.2),校准数据会按专家名分别 dump 为 pth 文件。105- 对于多专家模型(如 Wan2.2),校准数据会按专家名分别 dump 为 pth 文件。
106- 可设置 `dump_config.enable_dump: False` 跳过浮点推理(仅适用于纯动态量化场景)。106- 可设置 `dump_config.enable_dump: False` 跳过浮点推理(仅适用于纯动态量化场景)。
107-- 不支持 `--quant_type` 方式,必须通过 `--config_path` 指定完整配置。107+- 不支持 `--quant_type` 方式,必须通过 `--config` 指定完整配置。
108 108 
109**参考配置示例**109**参考配置示例**
110 110 
@@ -171,7 +171,7 @@ curl -X POST ${INFERENCE_ENDPOINT} \
171- **校准数据缺失**:检查 `enable_dump` 是否为 True,`dump_data_dir` 是否有写入权限。171- **校准数据缺失**:检查 `enable_dump` 是否为 True,`dump_data_dir` 是否有写入权限。
172- **精度不达标**:尝试调整推理配置参数,增加校准样本数量,或参考《[量化精度调优指南](../../../user_guide/process_quantization_precision_tuning.md)》进行调优。172- **精度不达标**:尝试调整推理配置参数,增加校准样本数量,或参考《[量化精度调优指南](../../../user_guide/process_quantization_precision_tuning.md)》进行调优。
173- **量化速度较慢**:增加 `--device` 指定多卡,框架启用数据并行(DP)逐层量化,借助多卡并行显著提升量化效率。多卡 DP 的开启方式与配置详见[《多卡分布式量化示例》](../../../user_guide/usage_quick_quantization.md#333-示例3多卡分布式量化)。173- **量化速度较慢**:增加 `--device` 指定多卡,框架启用数据并行(DP)逐层量化,借助多卡并行显著提升量化效率。多卡 DP 的开启方式与配置详见[《多卡分布式量化示例》](../../../user_guide/usage_quick_quantization.md#333-示例3多卡分布式量化)。
174-- **显存不足**:若模型参数过大,单卡无法放置一层的权重,可在模型适配器中适配自动按卡切分专家(EP)功能,将模型切分后按卡加载,避免单卡显存溢出。EP 相关适配详见[《多卡量化适配指南》](../../parallel/multi-card_quantization_adaptation.md#多卡量化基本概念)。此外,若仍遇到显存不足,请确认 `--device npu:0` 指定的 NPU 未被其他任务占用。174+- **显存不足**:若模型参数过大,单卡无法放置一层的权重,可在模型适配器中适配自动按卡切分专家(EP)功能,将模型切分后按卡加载,避免单卡显存溢出。EP 相关适配详见[《专家并行机制使用指南》](../../parallel/expert_parallelism/expert_parallelism_guide.md)。此外,若仍遇到显存不足,请确认 `--device npu --device_id 0` 指定的 NPU 未被其他任务占用。
175 175 
176## 8. 术语176## 8. 术语
177 177 
@@ -180,7 +180,7 @@ curl -X POST ${INFERENCE_ENDPOINT} \
180| DiT 量化 | Diffusion Transformer 多模态生成模型训练后量化 | [DiT 量化词条](./term_diffusion_transformer_quantization.md) |180| DiT 量化 | Diffusion Transformer 多模态生成模型训练后量化 | [DiT 量化词条](./term_diffusion_transformer_quantization.md) |
181| 多专家量化 | 多专家 DiT 按专家分别校准和量化 | [DiT 量化词条 - 原理](./term_diffusion_transformer_quantization.md#3-原理) |181| 多专家量化 | 多专家 DiT 按专家分别校准和量化 | [DiT 量化词条 - 原理](./term_diffusion_transformer_quantization.md#3-原理) |
182| PTQ | 训练后量化 | [PTQ 总览](../README.md) |182| PTQ | 训练后量化 | [PTQ 总览](../README.md) |
183-| MindIE-SD 格式 | 昇腾多模态生成模型推理格式 | [一键量化生成结果](../../quantization_format/ascendv1/ascendv1.md) |183+| MindIE-SD 格式 | 昇腾多模态生成模型推理格式 | [一键量化生成结果](../../quantization_format/ascendv1/ascendv1_usage.md) |
184 184 
185## 9. 接口文档列表185## 9. 接口文档列表
186 186 
@@ -408,7 +408,7 @@ msmodelslim quant \
408 --save_path ${SAVE_PATH} \408 --save_path ${SAVE_PATH} \
409 --device npu \409 --device npu \
410 --model_type ${MODEL_TYPE} \410 --model_type ${MODEL_TYPE} \
411- --config_path ${CONFIG_PATH} \411+ --config ${CONFIG_PATH} \
412 --trust_remote_code False412 --trust_remote_code False
413```413```
414 414 
@@ -442,7 +442,7 @@ msmodelslim quant \
442## 6. 异常处理442## 6. 异常处理
443 443 
444- **模型加载失败**:检查 `config.ini` 中 ModelAdapter 和 ModelAdapterEntryPoints 的 key 是否一致。若不一致,配置不生效。444- **模型加载失败**:检查 `config.ini` 中 ModelAdapter 和 ModelAdapterEntryPoints 的 key 是否一致。若不一致,配置不生效。
445-- **显存不足(OOM)**:确认 `init_model` 中将 `num_hidden_layers` 临时设置为 1;确认 `generate_decoder_layer` 实现了按需加载而非全量加载。此外,若仍遇到显存不足,请确认 `--device npu:0` 指定的 NPU 未被其他任务占用。445+- **显存不足(OOM)**:确认 `init_model` 中将 `num_hidden_layers` 临时设置为 1;确认 `generate_decoder_layer` 实现了按需加载而非全量加载。此外,若仍遇到显存不足,请确认 `--device npu --device_id 0` 指定的 NPU 未被其他任务占用。
446- **权重加载错误**:若模型使用 FP8 权重,需在加载后调用反量化函数;检查 `get_state_dict` 的 prefix 是否与权重文件中的 key 一致。446- **权重加载错误**:若模型使用 FP8 权重,需在加载后调用反量化函数;检查 `get_state_dict` 的 prefix 是否与权重文件中的 key 一致。
447- **校准数据格式错误**:确认 `handle_dataset` 返回的数据格式与模型的 forward 签名匹配。447- **校准数据格式错误**:确认 `handle_dataset` 返回的数据格式与模型的 forward 签名匹配。
448 448 
@@ -97,7 +97,7 @@ msmodelslim quant \
97 --save_path ${SAVE_PATH} \97 --save_path ${SAVE_PATH} \
98 --device npu \98 --device npu \
99 --model_type ${MODEL_TYPE} \99 --model_type ${MODEL_TYPE} \
100- --config_path ${CONFIG_PATH} \100+ --config ${CONFIG_PATH} \
101 --trust_remote_code True101 --trust_remote_code True
102```102```
103 103 
@@ -163,7 +163,7 @@ curl -X POST ${INFERENCE_ENDPOINT} \
163- **量化失败**:检查日志中的错误信息,确认模型路径、`model_type` 与参数是否配置正确;若使用了多卡分布式逐层量化,需确认所用处理器(Processor)支持分布式执行——框架在启动时会统一校验并抛出不支持错误。163- **量化失败**:检查日志中的错误信息,确认模型路径、`model_type` 与参数是否配置正确;若使用了多卡分布式逐层量化,需确认所用处理器(Processor)支持分布式执行——框架在启动时会统一校验并抛出不支持错误。
164- **精度不达标**:参考《[量化精度调优指南](../../../user_guide/process_quantization_precision_tuning.md)》进行调优。164- **精度不达标**:参考《[量化精度调优指南](../../../user_guide/process_quantization_precision_tuning.md)》进行调优。
165- **量化速度较慢**:增加 `--device` 指定多卡,框架启用数据并行(DP)逐层量化,借助多卡并行显著提升量化效率。多卡 DP 的开启方式与配置详见[《多卡分布式量化示例》](../../../user_guide/usage_quick_quantization.md#333-示例3多卡分布式量化)。165- **量化速度较慢**:增加 `--device` 指定多卡,框架启用数据并行(DP)逐层量化,借助多卡并行显著提升量化效率。多卡 DP 的开启方式与配置详见[《多卡分布式量化示例》](../../../user_guide/usage_quick_quantization.md#333-示例3多卡分布式量化)。
166-- **显存不足**:若模型参数过大,单卡无法放置一层的权重,可在模型适配器中适配自动按卡切分专家(EP)功能,将模型切分后按卡加载,避免单卡显存溢出。EP 相关适配详见[《多卡量化适配指南》](../../parallel/multi-card_quantization_adaptation.md#多卡量化基本概念)。此外,若仍遇到显存不足,请确认 `--device npu:0` 指定的 NPU 未被其他任务占用。166+- **显存不足**:若模型参数过大,单卡无法放置一层的权重,可在模型适配器中适配自动按卡切分专家(EP)功能,将模型切分后按卡加载,避免单卡显存溢出。EP 相关适配详见[《专家并行机制使用指南》](../../parallel/expert_parallelism/expert_parallelism_guide.md)。此外,若仍遇到显存不足,请确认 `--device npu --device_id 0` 指定的 NPU 未被其他任务占用。
167 167 
168## 8. 术语168## 8. 术语
169 169 
@@ -473,7 +473,7 @@ msmodelslim quant \
473 --save_path ${SAVE_PATH} \473 --save_path ${SAVE_PATH} \
474 --device npu \474 --device npu \
475 --model_type ${MODEL_TYPE} \475 --model_type ${MODEL_TYPE} \
476- --config_path ${CONFIG_PATH} \476+ --config ${CONFIG_PATH} \
477 --trust_remote_code True477 --trust_remote_code True
478```478```
479 479 
@@ -507,7 +507,7 @@ msmodelslim quant \
507 507 
508## 6. 异常处理508## 6. 异常处理
509 509 
510-- **视觉编码器显存不足(OOM)**:降低校准图像分辨率,或减少校准图像数量;考虑使用多卡 DP 模式(`--device npu:0,1`)。此外,若仍遇到显存不足,请确认 `--device npu:0` 指定的 NPU 未被其他任务占用。510+- **视觉编码器显存不足(OOM)**:降低校准图像分辨率,或减少校准图像数量;考虑使用多卡 DP 模式(`--device npu --device_id 0 1`)。此外,若仍遇到显存不足,请确认 `--device npu --device_id 0` 指定的 NPU 未被其他任务占用。
511- **Processor 加载失败**:确认模型路径中包含 `preprocessor_config.json` 或类似的配置文件;对于不使用 Processor 的模型(如 InternVL),需使用 tokenizer 手动预处理。511- **Processor 加载失败**:确认模型路径中包含 `preprocessor_config.json` 或类似的配置文件;对于不使用 Processor 的模型(如 InternVL),需使用 tokenizer 手动预处理。
512- **视觉特征融合失败**:检查 `image_token_id` 是否正确;确认 `masked_scatter` 的维度匹配;对于 DeepStack 等特殊结构,需在特定层后注入视觉特征。512- **视觉特征融合失败**:检查 `image_token_id` 是否正确;确认 `masked_scatter` 的维度匹配;对于 DeepStack 等特殊结构,需在特定层后注入视觉特征。
513- **MoE 权重转换错误**:确认 3D 权重的 shape 和拆分逻辑与原始模型定义一致;检查 `moe_utils.py` 中的转换实现。513- **MoE 权重转换错误**:确认 3D 权重的 shape 和拆分逻辑与原始模型定义一致;检查 `moe_utils.py` 中的转换实现。
@@ -100,7 +100,7 @@ msmodelslim quant \
100 --save_path ${SAVE_PATH} \100 --save_path ${SAVE_PATH} \
101 --device npu \101 --device npu \
102 --model_type ${MODEL_TYPE} \102 --model_type ${MODEL_TYPE} \
103- --config_path ${CONFIG_PATH} \103+ --config ${CONFIG_PATH} \
104 --trust_remote_code True104 --trust_remote_code True
105```105```
106 106 
@@ -183,7 +183,7 @@ curl -X POST ${INFERENCE_ENDPOINT} \
183- **量化失败**:检查日志中的错误信息,确认模型路径、`model_type` 与参数是否配置正确;若使用了多卡分布式逐层量化,需确认所用处理器(Processor)支持分布式执行——框架在启动时会统一校验并抛出不支持错误。183- **量化失败**:检查日志中的错误信息,确认模型路径、`model_type` 与参数是否配置正确;若使用了多卡分布式逐层量化,需确认所用处理器(Processor)支持分布式执行——框架在启动时会统一校验并抛出不支持错误。
184- **精度不达标**:检查校准图像质量,尝试调整 `default_text` 使其与校准图像语义匹配,或参考《[量化精度调优指南](../../../user_guide/process_quantization_precision_tuning.md)》进行调优。184- **精度不达标**:检查校准图像质量,尝试调整 `default_text` 使其与校准图像语义匹配,或参考《[量化精度调优指南](../../../user_guide/process_quantization_precision_tuning.md)》进行调优。
185- **量化速度较慢**:增加 `--device` 指定多卡,框架启用数据并行(DP)逐层量化,借助多卡并行显著提升量化效率。多卡 DP 的开启方式与配置详见[《多卡分布式量化示例》](../../../user_guide/usage_quick_quantization.md#333-示例3多卡分布式量化)。185- **量化速度较慢**:增加 `--device` 指定多卡,框架启用数据并行(DP)逐层量化,借助多卡并行显著提升量化效率。多卡 DP 的开启方式与配置详见[《多卡分布式量化示例》](../../../user_guide/usage_quick_quantization.md#333-示例3多卡分布式量化)。
186-- **显存不足**:若模型参数过大,单卡无法放置一层的权重,可在模型适配器中适配自动按卡切分专家(EP)功能,将模型切分后按卡加载,避免单卡显存溢出。EP 相关适配详见[《多卡量化适配指南》](../../parallel/multi-card_quantization_adaptation.md#多卡量化基本概念)。此外,若仍遇到显存不足,请确认 `--device npu:0` 指定的 NPU 未被其他任务占用。186+- **显存不足**:若模型参数过大,单卡无法放置一层的权重,可在模型适配器中适配自动按卡切分专家(EP)功能,将模型切分后按卡加载,避免单卡显存溢出。EP 相关适配详见[《专家并行机制使用指南》](../../parallel/expert_parallelism/expert_parallelism_guide.md)。此外,若仍遇到显存不足,请确认 `--device npu --device_id 0` 指定的 NPU 未被其他任务占用。
187 187 
188## 8. 术语188## 8. 术语
189 189 
@@ -70,7 +70,7 @@
70| [W4A4 MX 动态量化](linear_layer_quantization/term_w4a4_mx_dynamic.md) | `W4A4MXDynamicPerBlockFakeQuantLinear` | MXFP4 per-block / per-block 动态 |70| [W4A4 MX 动态量化](linear_layer_quantization/term_w4a4_mx_dynamic.md) | `W4A4MXDynamicPerBlockFakeQuantLinear` | MXFP4 per-block / per-block 动态 |
71| [W4A4 MX 双 Scale 量化](linear_layer_quantization/term_w4a4_mx_dualscale.md) | `W4A4MXDynamicDualScaleFakeQuantLinear` | MXFP4 双 scale / per-block 动态 |71| [W4A4 MX 双 Scale 量化](linear_layer_quantization/term_w4a4_mx_dualscale.md) | `W4A4MXDynamicDualScaleFakeQuantLinear` | MXFP4 双 scale / per-block 动态 |
72| [W16A16S 量化](linear_layer_quantization/term_w16a16s.md) | `W16A16sLinear` | 16bit 权重/激活(含稀疏) |72| [W16A16S 量化](linear_layer_quantization/term_w16a16s.md) | `W16A16sLinear` | 16bit 权重/激活(含稀疏) |
73-| [SVDQuant](../quantization_algorithms/svdquant/svdquant.md) | `SVDResidualWrapper`([`svd_residual.py`](../../../../msmodelslim/ir/svd_residual.py),配合 linear_quant) | 低秩分解 + 残差低比特量化 |73+| [SVDQuant](../quantization_algorithms/svdquant/usage_svdquant.md) | `SVDResidualWrapper`([`svd_residual.py`](../../../../msmodelslim/ir/svd_residual.py),配合 linear_quant) | 低秩分解 + 残差低比特量化 |
74 74 
75> 注:prefill 与 decode 是 LLM 推理的两个阶段——prefill 一次处理整个输入 prompt(计算密集),decode 逐个生成 token(访存密集),详见[线性层量化](linear_layer_quantization/README.md)。75> 注:prefill 与 decode 是 LLM 推理的两个阶段——prefill 一次处理整个输入 prompt(计算密集),decode 逐个生成 token(访存密集),详见[线性层量化](linear_layer_quantization/README.md)。
76 76 
@@ -115,9 +115,9 @@ FA 量化**本质上是一个组合量化模式**,实际作用于注意力 **Q
115- [KVCache 量化](kv_cache_quantization/README.md):下位概念,针对 KVCache 的量化类别。115- [KVCache 量化](kv_cache_quantization/README.md):下位概念,针对 KVCache 的量化类别。
116- [FA 量化](fa_quantization/README.md):下位概念,KVCache 量化的进阶类别。116- [FA 量化](fa_quantization/README.md):下位概念,KVCache 量化的进阶类别。
117- [W8A8 静态量化](linear_layer_quantization/term_w8a8_static.md):下位概念,线性层量化中"权重/激活静态"的典型模式。117- [W8A8 静态量化](linear_layer_quantization/term_w8a8_static.md):下位概念,线性层量化中"权重/激活静态"的典型模式。
118-- 《[线性量化算法说明](../quantization_algorithms/linear_quant/linear_quant.md)》:配套术语,描述线性层量化模式的处理器实现。118+- 《[线性量化算法说明](../quantization_algorithms/linear_quant/usage_linear_quant.md)》:配套术语,描述线性层量化模式的处理器实现。
119-- 《[KVCache量化:缓存量化算法说明](../quantization_algorithms/kvcache_quant/kvcache_quant.md)》:配套术语,描述 KVCache 量化算法。119+- 《[KVCache量化:缓存量化算法说明](../quantization_algorithms/kvcache_quant/usage_kvcache_quant.md)》:配套术语,描述 KVCache 量化算法。
120-- 《[FA3量化:Flash Attention 3激活量化算法说明](../quantization_algorithms/fa3_quant/fa3_quant.md)》:配套术语,描述 FA 量化算法。120+- 《[FA3量化:Flash Attention 3激活量化算法说明](../quantization_algorithms/fa3_quant/usage_fa3_quant.md)》:配套术语,描述 FA 量化算法。
121 121 
122---122---
123 123 
@@ -126,5 +126,5 @@ FA 量化**本质上是一个组合量化模式**,实际作用于注意力 **Q
1261. Jacob B et al. Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference. CVPR 2018. https://arxiv.org/abs/1712.058771261. Jacob B et al. Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference. CVPR 2018. https://arxiv.org/abs/1712.05877
1272. Yao Z et al. ZeroQuant: Efficient and Affordable Post-Training Quantization for Large-Scale Transformers. NeurIPS 2022. https://arxiv.org/abs/2206.018611272. Yao Z et al. ZeroQuant: Efficient and Affordable Post-Training Quantization for Large-Scale Transformers. NeurIPS 2022. https://arxiv.org/abs/2206.01861
1283. Liu Z et al. KIVI: A Tuning-Free Asymmetric 2bit Quantization for KV Cache. ICML 2024. https://arxiv.org/abs/2402.027501283. Liu Z et al. KIVI: A Tuning-Free Asymmetric 2bit Quantization for KV Cache. ICML 2024. https://arxiv.org/abs/2402.02750
129-4. 《[线性量化算法说明](../quantization_algorithms/linear_quant/linear_quant.md)》129+4. 《[线性量化算法说明](../quantization_algorithms/linear_quant/usage_linear_quant.md)》
130-5. 《[AscendV1 格式说明](../quantization_format/ascendv1/ascendv1.md)》130+5. 《[AscendV1 格式说明](../quantization_format/ascendv1/ascendv1_usage.md)》
@@ -36,7 +36,7 @@
36| 类型 | 名称 | 来源或保存位置 | 格式或约束 | 验收方式 |36| 类型 | 名称 | 来源或保存位置 | 格式或约束 | 验收方式 |
37| --- | --- | --- | --- | --- |37| --- | --- | --- | --- | --- |
38| 输入 | 浮点模型目录 | 用户本地路径;一般自 ModelScope / Hugging Face 获取 | 含配置、权重分片及类别所需附属文件 | 路径有效,文件齐全,可被目标 `model_type` 加载 |38| 输入 | 浮点模型目录 | 用户本地路径;一般自 ModelScope / Hugging Face 获取 | 含配置、权重分片及类别所需附属文件 | 路径有效,文件齐全,可被目标 `model_type` 加载 |
39-| 交付件 | 最终量化配置 | 用户保存的收敛配置路径 | 符合对应配置协议 | 可被 `msmodelslim quant --config_path` 加载并复现交付权重 |39+| 交付件 | 最终量化配置 | 用户保存的收敛配置路径 | 符合对应配置协议 | 可被 `msmodelslim quant --config` 加载并复现交付权重 |
40| 交付件 | 最终量化权重目录 | 用户指定的输出目录 | 符合所选导出格式 | 文件齐全;符合所选导出格式约定 |40| 交付件 | 最终量化权重目录 | 用户指定的输出目录 | 符合所选导出格式 | 文件齐全;符合所选导出格式约定 |
41| 交付件 | 精度 / 性能对比结论 | 测评记录 | 含浮点基线、最终量化结果、是否达标 | 同口径可核对 |41| 交付件 | 精度 / 性能对比结论 | 测评记录 | 含浮点基线、最终量化结果、是否达标 | 同口径可核对 |
42 42 
@@ -47,7 +47,7 @@ msmodelslim quant \
47msmodelslim quant \47msmodelslim quant \
48 --model_path ${MODEL_PATH} \48 --model_path ${MODEL_PATH} \
49 --save_path ${SAVE_PATH} \49 --save_path ${SAVE_PATH} \
50- --device npu:0,1,2,3 \50+ --device npu --device_id 0 1 2 3 \
51 --model_type Qwen2.5-7B-Instruct \51 --model_type Qwen2.5-7B-Instruct \
52 --quant_type w8a8 \52 --quant_type w8a8 \
53 --trust_remote_code True \53 --trust_remote_code True \
@@ -64,7 +64,7 @@ msmodelslim quant \
64 --save_path ${SAVE_PATH} \64 --save_path ${SAVE_PATH} \
65 --device npu \65 --device npu \
66 --model_type ${MODEL_TYPE} \66 --model_type ${MODEL_TYPE} \
67- --config_path ${CONFIG_PATH} \67+ --config ${CONFIG_PATH} \
68 --trust_remote_code True \68 --trust_remote_code True \
69 --debug69 --debug
70```70```
@@ -36,7 +36,7 @@
36 36 
37## 4. 流程总览37## 4. 流程总览
38 38 
39-本流程端到端分为五个阶段:确认模型支持、下载浮点模型、确定量化方案与场景标签、执行一键量化、校验交付件。其中 `msmodelslim quant` 命令的7个参数在步骤1~6 中逐一确定:步骤1 确定 `--model_type` 与 `--quant_type`,步骤2 确定 `--model_path`,步骤3 确定 `--tag`,步骤4~6 依次添加 `--save_path`、`--device`、`--trust_remote_code` 并执行:39+本流程端到端分为五个阶段:确认模型支持、下载浮点模型、确定量化方案与场景标签、执行一键量化、校验交付件。其中 `msmodelslim quant` 命令的7个参数在步骤1~6 中逐一确定:步骤1 确定 `--model_type` 与 `--quant_type`,步骤2 确定 `--model_path`,步骤3 确定 `--tags`,步骤4~6 依次添加 `--save_path`、`--device`、`--trust_remote_code` 并执行:
40 40 
41```mermaid41```mermaid
42flowchart LR42flowchart LR
@@ -57,10 +57,10 @@ flowchart LR
57msmodelslim quant \57msmodelslim quant \
58 --model_path ${MODEL_PATH} \ # 浮点权重目录58 --model_path ${MODEL_PATH} \ # 浮点权重目录
59 --save_path ${SAVE_PATH} \ # 量化权重输出目录59 --save_path ${SAVE_PATH} \ # 量化权重输出目录
60- --device npu \ # 量化设备,如 npu、npu:0,1,2,360+ --device npu \ # 量化设备,如 npu、npu --device_id 0 1 2 3
61 --model_type ${MODEL_TYPE} \ # 已注册或支持矩阵中的模型名,大小写敏感61 --model_type ${MODEL_TYPE} \ # 已注册或支持矩阵中的模型名,大小写敏感
62 --quant_type ${QUANT_TYPE} \ # 量化类型,如 w8a862 --quant_type ${QUANT_TYPE} \ # 量化类型,如 w8a8
63- --tag ${TAG} \ # 场景标签,如 vLLM-Ascend Atlas_A2_Inference63+ --tags ${TAG} \ # 场景标签,如 vLLM-Ascend Atlas_A2_Inference
64 --trust_remote_code False # 仅可信模型必要时设为 True64 --trust_remote_code False # 仅可信模型必要时设为 True
65```65```
66 66 
@@ -112,11 +112,11 @@ msmodelslim quant \
112 112 
113### 步骤3:确定场景标签113### 步骤3:确定场景标签
114 114 
115-**目标**:确定目标推理场景(`--tag`),使工具能匹配到该场景下已验证的最佳实践配置。115+**目标**:确定目标推理场景(`--tags`),使工具能匹配到该场景下已验证的最佳实践配置。
116 116 
117**操作**117**操作**
118 118 
119-场景标签(`--tag`)用于告诉工具"量化后的模型将运行在什么环境",支持两类场景标签,每一类别可指定一种场景,多个标签用空格分隔。各取值说明如下:119+场景标签(`--tags`)用于告诉工具"量化后的模型将运行在什么环境",支持两类场景标签,每一类别可指定一种场景,多个标签用空格分隔。各取值说明如下:
120 120 
121| 标签类别 | 取值 | 说明 |121| 标签类别 | 取值 | 说明 |
122| --- | --- | --- |122| --- | --- | --- |
@@ -139,7 +139,7 @@ msmodelslim quant \
139 139 
140**输出**:确定的 `${TAG}`140**输出**:确定的 `${TAG}`
141 141 
142-**通过条件**:`--tag` 取值与目标推理环境一致。142+**通过条件**:`--tags` 取值与目标推理环境一致。
143 143 
144### 步骤4:添加量化权重的输出目录(必选)144### 步骤4:添加量化权重的输出目录(必选)
145 145 
@@ -173,7 +173,7 @@ msmodelslim quant \
173 173 
174> **可选:多卡分布式量化**174> **可选:多卡分布式量化**
175>175>
176-> 片上内存受限场景中,可指定多张 NPU 卡自动启用分布式逐层量化,将 `--device` 改为多卡即可,如 `--device npu:0,1,2,3`176+> 片上内存受限场景中,可指定多张 NPU 卡自动启用分布式逐层量化,将 `--device` 改为多卡即可,如 `--device npu --device_id 0 1 2 3`
177>177>
178> 多卡量化与逐层量化说明详见[一键量化完整指南](usage_quick_quantization.md#41-逐层量化及分布式逐层量化)。178> 多卡量化与逐层量化说明详见[一键量化完整指南](usage_quick_quantization.md#41-逐层量化及分布式逐层量化)。
179 179 
@@ -211,7 +211,7 @@ msmodelslim quant \
211 └── ${MODEL_TYPE}_best_practice.yaml # 本次量化的完整配置记录(可用于方案复现)211 └── ${MODEL_TYPE}_best_practice.yaml # 本次量化的完整配置记录(可用于方案复现)
212 ```212 ```
213 213 
214- 输出文件含义详见《[AscendV1 量化权重格式说明](../knowledge_base/quantization_format/ascendv1/ascendv1.md)》。214+ 输出文件含义详见《[AscendV1 量化权重格式说明](../knowledge_base/quantization_format/ascendv1/ascendv1_usage.md)》。
215 215 
216 > **注意**:不同导出格式的交付文件不同。如 compressed-tensors 格式没有 `quant_model_description.json`,量化元数据写入 `config.json``quantization_config` 字段,各格式的文件结构详见《[量化格式支持矩阵](../knowledge_base/quantization_format/README.md)》。216 > **注意**:不同导出格式的交付文件不同。如 compressed-tensors 格式没有 `quant_model_description.json`,量化元数据写入 `config.json``quantization_config` 字段,各格式的文件结构详见《[量化格式支持矩阵](../knowledge_base/quantization_format/README.md)》。
2172. **保存配置记录**:留存 `${SAVE_PATH}` 下生成的 `*_best_practice.yaml`,作为本次量化的复现依据与审计记录。2172. **保存配置记录**:留存 `${SAVE_PATH}` 下生成的 `*_best_practice.yaml`,作为本次量化的复现依据与审计记录。
@@ -228,7 +228,7 @@ msmodelslim quant \
228 228 
229## 7. 异常处置229## 7. 异常处置
230 230 
231-- **交互询问场景**:`--tag` 或 `--quant_type` 未命中已验证配置时,工具会询问是否采用推荐配置,确认场景与推荐配置匹配后按提示执行;231+- **交互询问场景**:`--tags` 或 `--quant_type` 未命中已验证配置时,工具会询问是否采用推荐配置,确认场景与推荐配置匹配后按提示执行;
232- **量化失败或 OOM**:先排查 NPU 状态(`npu-smi info`)与环境变量 `ASCEND_RT_VISIBLE_DEVICES` 是否指向有效空闲卡;显存不足(OOM)时改用空闲卡,或开启逐层量化、分布式逐层量化;232- **量化失败或 OOM**:先排查 NPU 状态(`npu-smi info`)与环境变量 `ASCEND_RT_VISIBLE_DEVICES` 是否指向有效空闲卡;显存不足(OOM)时改用空闲卡,或开启逐层量化、分布式逐层量化;
233- **模型加载报错**:确认 transformers 等依赖库版本与支持矩阵要求一致,必要时补充 `--trust_remote_code True`(仅限可信模型);233- **模型加载报错**:确认 transformers 等依赖库版本与支持矩阵要求一致,必要时补充 `--trust_remote_code True`(仅限可信模型);
234- **部署测评后精度异常**:量化权重已完成交付,但部署测评出现 badcase 或输出异常时,进入《[量化推理精度异常定位流程指南](process_quantization_accuracy_anomaly_locating.md)》定位异常位点,并按《[量化精度调优指南](process_quantization_precision_tuning.md)》调优后重新量化。234- **部署测评后精度异常**:量化权重已完成交付,但部署测评出现 badcase 或输出异常时,进入《[量化推理精度异常定位流程指南](process_quantization_accuracy_anomaly_locating.md)》定位异常位点,并按《[量化精度调优指南](process_quantization_precision_tuning.md)》调优后重新量化。
@@ -27,7 +27,7 @@ toc_depth: 3
27msmodelslim quant [ARGS]27msmodelslim quant [ARGS]
28```28```
29 29 
30-指定`--quant_type`参数时,系统将根据指定需求,在最佳实践库中匹配到最佳配置从而实施量化;指定`--config_path`参数时,将直接使用用户指定的配置,不会匹配最佳实践库。30+指定`--quant_type`参数时,系统将根据指定需求,在最佳实践库中匹配到最佳配置从而实施量化;指定`--config`参数时,将直接使用用户指定的配置,不会匹配最佳实践库。
31 31 
32**注意事项**32**注意事项**
33 33 
@@ -98,7 +98,7 @@ msmodelslim quant \
98 --save_path ${SAVE_PATH} \98 --save_path ${SAVE_PATH} \
99 --device npu \99 --device npu \
100 --model_type ${MODEL_TYPE} \100 --model_type ${MODEL_TYPE} \
101- --config_path ${CONFIG_PATH} \101+ --config ${CONFIG_PATH} \
102 --trust_remote_code ${TRUST_REMOTE_CODE}102 --trust_remote_code ${TRUST_REMOTE_CODE}
103```103```
104 104 
@@ -119,7 +119,7 @@ msmodelslim quant \
119msmodelslim quant \119msmodelslim quant \
120 --model_path ${MODEL_PATH} \120 --model_path ${MODEL_PATH} \
121 --save_path ${SAVE_PATH} \121 --save_path ${SAVE_PATH} \
122- --device npu:0,1,2,3 \122+ --device npu --device_id 0 1 2 3 \
123 --model_type ${MODEL_TYPE} \123 --model_type ${MODEL_TYPE} \
124 --quant_type w8a8 \124 --quant_type w8a8 \
125 --trust_remote_code True125 --trust_remote_code True
@@ -129,7 +129,7 @@ msmodelslim quant \
129 129 
130- `${MODEL_PATH}` 为原始浮点权重路径130- `${MODEL_PATH}` 为原始浮点权重路径
131- `${SAVE_PATH}` 为用户自定义的量化权重保存路径131- `${SAVE_PATH}` 为用户自定义的量化权重保存路径
132-- `--device npu:0,1,2,3` 指定使用4张NPU卡进行分布式量化132+- `--device npu --device_id 0 1 2 3` 指定使用4张NPU卡进行分布式量化
133- `${MODEL_TYPE}` 为模型类型,需与支持矩阵中的名称一致133- `${MODEL_TYPE}` 为模型类型,需与支持矩阵中的名称一致
134- `--quant_type w8a8` 指定量化类型为W8A8134- `--quant_type w8a8` 指定量化类型为W8A8
135- `--trust_remote_code True` 信任远程代码135- `--trust_remote_code True` 信任远程代码
@@ -199,10 +199,10 @@ spec:
199 199 
200```bash200```bash
201# 单卡逐层量化201# 单卡逐层量化
202-msmodelslim quant --device npu:0 ...202+msmodelslim quant --device npu --device_id 0 ...
203 203 
204# 多卡分布式逐层量化(自动启用 DP)204# 多卡分布式逐层量化(自动启用 DP)
205-msmodelslim quant --device npu:0,1,2,3 ...205+msmodelslim quant --device npu --device_id 0 1 2 3 ...
206```206```
207 207 
208#### 4.1.5 注意事项208#### 4.1.5 注意事项
@@ -728,7 +728,7 @@ multimodal_vlm_modelslim_v1是专门为多模态视觉语言模型(VLM)设
728 728 
729- 支持`dataset`字段配置校准数据集,支持三种使用方式:方式一 index.json/index.jsonl(推荐,支持多模态)、方式二 纯图像目录(后续不再演进)、方式三 图像目录+单个 json/jsonl(后续不再演进),详见下方 [dataset - 校准数据路径配置](#dataset---校准数据路径配置)729- 支持`dataset`字段配置校准数据集,支持三种使用方式:方式一 index.json/index.jsonl(推荐,支持多模态)、方式二 纯图像目录(后续不再演进)、方式三 图像目录+单个 json/jsonl(后续不再演进),详见下方 [dataset - 校准数据路径配置](#dataset---校准数据路径配置)
730- 支持`default_text`字段配置默认文本 prompt(方式二必填;方式一在条目缺 text 字段时使用)730- 支持`default_text`字段配置默认文本 prompt(方式二必填;方式一在条目缺 text 字段时使用)
731-- 默认 `runner: auto`:单卡走 layer_wise,多卡(如 `--device npu:0,1,...`)自动走 dp_layer_wise,与 modelslim_v1 对齐731+- 默认 `runner: auto`:单卡走 layer_wise,多卡(如 `--device npu --device_id 0 1 ...`)自动走 dp_layer_wise,与 modelslim_v1 对齐
732 732 
733#### 5.4.2 <span id="runner---量化调度器类型-vlm">runner - 量化调度器类型</span>733#### 5.4.2 <span id="runner---量化调度器类型-vlm">runner - 量化调度器类型</span>
734 734 
@@ -60,8 +60,8 @@ msmodelslim analyze attn \
60 --model_type ${MODEL_TYPE} \ # 已注册或支持矩阵中的模型名,大小写敏感60 --model_type ${MODEL_TYPE} \ # 已注册或支持矩阵中的模型名,大小写敏感
61 --model_path ${MODEL_PATH} \ # 浮点权重目录61 --model_path ${MODEL_PATH} \ # 浮点权重目录
62 --metrics ${METRICS} \ # 分析指标62 --metrics ${METRICS} \ # 分析指标
63- --calib_dataset ${CALIB_DATASET} \ # 校准集路径或工具内置短名称63+ --calibration_dataset ${CALIB_DATASET} \ # 校准集路径或工具内置短名称
64- --topk ${TOPK} \ # TopK 数量,默认 1564+ --top_k ${TOPK} \ # TopK 数量,默认 15
65 --device npu \ # 分析设备:npu / cpu65 --device npu \ # 分析设备:npu / cpu
66 --trust_remote_code False # 默认 False;仅可信模型必要时设为 True66 --trust_remote_code False # 默认 False;仅可信模型必要时设为 True
67```67```
@@ -60,8 +60,8 @@ msmodelslim analyze layer \
60 --model_path ${MODEL_PATH} \ # 浮点权重目录60 --model_path ${MODEL_PATH} \ # 浮点权重目录
61 --metrics ${METRICS} \ # 分析指标61 --metrics ${METRICS} \ # 分析指标
62 --quant_modules "*" \ # 参与对比的子模块通配,可多个;默认 "*"62 --quant_modules "*" \ # 参与对比的子模块通配,可多个;默认 "*"
63- --calib_dataset ${CALIB_DATASET} \ # 校准集路径或工具内置短名称63+ --calibration_dataset ${CALIB_DATASET} \ # 校准集路径或工具内置短名称
64- --topk ${TOPK} \ # TopK 数量,默认 1564+ --top_k ${TOPK} \ # TopK 数量,默认 15
65 --device npu \ # 分析设备:npu / cpu65 --device npu \ # 分析设备:npu / cpu
66 --trust_remote_code False # 默认 False;仅可信模型必要时设为 True66 --trust_remote_code False # 默认 False;仅可信模型必要时设为 True
67```67```
@@ -60,9 +60,9 @@ msmodelslim analyze linear \
60 --model_type ${MODEL_TYPE} \ # 已注册或支持矩阵中的模型名,大小写敏感60 --model_type ${MODEL_TYPE} \ # 已注册或支持矩阵中的模型名,大小写敏感
61 --model_path ${MODEL_PATH} \ # 浮点权重目录61 --model_path ${MODEL_PATH} \ # 浮点权重目录
62 --metrics ${METRICS} \ # 分析指标62 --metrics ${METRICS} \ # 分析指标
63- --pattern "*" \ # 待分析层名通配,可多个,空格分隔;默认 "*"63+ --patterns "*" \ # 待分析层名通配,可多个,空格分隔;默认 "*"
64- --calib_dataset ${CALIB_DATASET} \ # 校准集路径或工具内置短名称64+ --calibration_dataset ${CALIB_DATASET} \ # 校准集路径或工具内置短名称
65- --topk ${TOPK} \ # TopK 数量,默认 15;成组模块一并输出时实际条数可能 ≥ topk65+ --top_k ${TOPK} \ # TopK 数量,默认 15;成组模块一并输出时实际条数可能 ≥ top_k
66 --device npu \ # 分析设备:npu / cpu66 --device npu \ # 分析设备:npu / cpu
67 --trust_remote_code False # 默认 False;仅可信模型必要时设为 True67 --trust_remote_code False # 默认 False;仅可信模型必要时设为 True
68```68```
@@ -64,9 +64,9 @@ flowchart LR
64msmodelslim quant \64msmodelslim quant \
65 --model_path ${MODEL_PATH} \ # 浮点权重目录65 --model_path ${MODEL_PATH} \ # 浮点权重目录
66 --save_path ${SAVE_PATH} \ # 量化权重输出目录66 --save_path ${SAVE_PATH} \ # 量化权重输出目录
67- --device npu \ # 量化设备,如 npu、npu:0,1,2,367+ --device npu \ # 量化设备,如 npu、npu --device_id 0 1 2 3
68 --model_type ${MODEL_TYPE} \ # 已注册或支持矩阵中的模型名,大小写敏感68 --model_type ${MODEL_TYPE} \ # 已注册或支持矩阵中的模型名,大小写敏感
69- --config_path ${CONFIG_PATH} \ # 本指南步骤 3 编写的量化配置 YAML69+ --config ${CONFIG_PATH} \ # 本指南步骤 3 编写的量化配置 YAML
70 --trust_remote_code False # 仅可信模型必要时设为 True70 --trust_remote_code False # 仅可信模型必要时设为 True
71```71```
72 72 
@@ -182,7 +182,7 @@ msmodelslim quant \
182 182 
183**操作**183**操作**
184 184 
185-新模型接入阶段使用 `--config_path` 显式指定步骤 3 的配置,使用自定义配置时,量化结果由配置与适配自行保证,msModelSlim 不对未经验证的自定义配置效果负责。185+新模型接入阶段使用 `--config` 显式指定步骤 3 的配置,使用自定义配置时,量化结果由配置与适配自行保证,msModelSlim 不对未经验证的自定义配置效果负责。
186 186 
187```bash187```bash
188msmodelslim quant \188msmodelslim quant \
@@ -190,7 +190,7 @@ msmodelslim quant \
190 --save_path ${SAVE_PATH} \190 --save_path ${SAVE_PATH} \
191 --device npu \191 --device npu \
192 --model_type ${MODEL_TYPE} \192 --model_type ${MODEL_TYPE} \
193- --config_path ${CONFIG_PATH} \193+ --config ${CONFIG_PATH} \
194 --trust_remote_code False194 --trust_remote_code False
195```195```
196 196 
@@ -200,7 +200,7 @@ msmodelslim quant \
200- `--save_path`:量化产物输出目录。200- `--save_path`:量化产物输出目录。
201- `--device`:量化设备,如 `npu``npu:0,1,2,3`201- `--device`:量化设备,如 `npu``npu:0,1,2,3`
202- `--model_type`:步骤 2 注册的模型名,或支持矩阵中已有名称;大小写敏感。202- `--model_type`:步骤 2 注册的模型名,或支持矩阵中已有名称;大小写敏感。
203-- `--config_path`:步骤 3 编写的 YAML。203+- `--config`:步骤 3 编写的 YAML。
204- `--trust_remote_code`:仅当模型必须执行仓库内自定义代码且来源可信时设为 `True`204- `--trust_remote_code`:仅当模型必须执行仓库内自定义代码且来源可信时设为 `True`
205 205 
206**输出**:量化权重目录。206**输出**:量化权重目录。
@@ -363,7 +363,7 @@ DeepSeek-V3模型较大,且存在需要手动适配的点,为了避免浪费
363 --save_path ${save_path} \363 --save_path ${save_path} \
364 --model_type DeepSeek-V4-Pro \364 --model_type DeepSeek-V4-Pro \
365 --quant_type w8a8 \365 --quant_type w8a8 \
366- --device npu:0,1,2,3,4,5,6,7 \366+ --device npu --device_id 0 1 2 3 4 5 6 7 \
367 --trust_remote_code True367 --trust_remote_code True
368 ```368 ```
369 369 
@@ -375,7 +375,7 @@ DeepSeek-V3模型较大,且存在需要手动适配的点,为了避免浪费
375 --save_path ${save_path} \375 --save_path ${save_path} \
376 --model_type DeepSeek-V4-Pro \376 --model_type DeepSeek-V4-Pro \
377 --quant_type w4a8 \377 --quant_type w4a8 \
378- --device npu:0,1,2,3,4,5,6,7 \378+ --device npu --device_id 0 1 2 3 4 5 6 7 \
379 --trust_remote_code True379 --trust_remote_code True
380 ```380 ```
381 381 
@@ -134,7 +134,7 @@ msmodelslim quant \
134 --model_type GLM-5.1 \134 --model_type GLM-5.1 \
135 --quant_type w4a4c8 \135 --quant_type w4a4c8 \
136 --trust_remote_code True \136 --trust_remote_code True \
137- --tag vLLM_Ascend Ascend_950137+ --tags vLLM_Ascend Ascend_950
138```138```
139 139 
140- 其中`MODEL_PATH`为GLM-5.1模型的路径,`SAVE_PATH`为量化后的权重保存路径。140- 其中`MODEL_PATH`为GLM-5.1模型的路径,`SAVE_PATH`为量化后的权重保存路径。
@@ -35,7 +35,7 @@
35msmodelslim quant \35msmodelslim quant \
36 --model_path ${MODEL_PATH} \36 --model_path ${MODEL_PATH} \
37 --save_path ${SAVE_PATH} \37 --save_path ${SAVE_PATH} \
38- --device npu:0 \38+ --device npu --device_id 0 \
39 --model_type GLM-4.7-Flash \39 --model_type GLM-4.7-Flash \
40 --quant_type w8a8 \40 --quant_type w8a8 \
41 --trust_remote_code True41 --trust_remote_code True
@@ -35,7 +35,7 @@
35msmodelslim quant \35msmodelslim quant \
36 --model_path ${MODEL_PATH} \36 --model_path ${MODEL_PATH} \
37 --save_path ${SAVE_PATH} \37 --save_path ${SAVE_PATH} \
38- --device npu:0,1,2,3,4,5,6,7 \38+ --device npu --device_id 0 1 2 3 4 5 6 7 \
39 --model_type GLM-4.7 \39 --model_type GLM-4.7 \
40 --quant_type w8a8 \40 --quant_type w8a8 \
41 --trust_remote_code True41 --trust_remote_code True
@@ -117,7 +117,7 @@ python -c "from importlib.metadata import entry_points; print('Hy3' in {e.name f
117 --save_path ${save_path} \117 --save_path ${save_path} \
118 --device npu \118 --device npu \
119 --model_type Hy3 \119 --model_type Hy3 \
120- --config_path lab_practice/hy3/hy3_w8a8.yaml \120+ --config lab_practice/hy3/hy3_w8a8.yaml \
121 --trust_remote_code True121 --trust_remote_code True
122 ```122 ```
123 123 
@@ -127,7 +127,7 @@ python -c "from importlib.metadata import entry_points; print('Hy3' in {e.name f
127 127 
128- Q:指定 `--quant_type w8a8` 后未匹配到 `hy3_w8a8.yaml`,使用了 `default-w8a8` 怎么办?128- Q:指定 `--quant_type w8a8` 后未匹配到 `hy3_w8a8.yaml`,使用了 `default-w8a8` 怎么办?
129 129 
130-- A:请依次检查:(1)`--model_type` 是否为 **`Hy3`**;(2)是否已执行 `pip install -e .`;(3)`msmodelslim/lab_practice/hy3/hy3_w8a8.yaml` 是否存在。也可通过 `--config_path lab_practice/hy3/hy3_w8a8.yaml` 显式指定配置。130+- A:请依次检查:(1)`--model_type` 是否为 **`Hy3`**;(2)是否已执行 `pip install -e .`;(3)`msmodelslim/lab_practice/hy3/hy3_w8a8.yaml` 是否存在。也可通过 `--config lab_practice/hy3/hy3_w8a8.yaml` 显式指定配置。
131 131 
132- Q:量化时报 transformers 版本不匹配怎么办?132- Q:量化时报 transformers 版本不匹配怎么办?
133 133 
@@ -71,7 +71,7 @@ msmodelslim quant \
71 --model_path ./MiMo-V2-Flash-BF16/ \71 --model_path ./MiMo-V2-Flash-BF16/ \
72 --save_path ./MiMo-V2-Flash-w8a8/ \72 --save_path ./MiMo-V2-Flash-w8a8/ \
73 --model_type MiMo-V2-Flash \73 --model_type MiMo-V2-Flash \
74- --config_path lab_practice/mimo_v2/mimo-v2-flash-w8a8.yaml \74+ --config lab_practice/mimo_v2/mimo-v2-flash-w8a8.yaml \
75 --trust_remote_code True75 --trust_remote_code True
76```76```
77 77 
@@ -52,7 +52,7 @@ msmodelslim quant \
52 --device npu \52 --device npu \
53 --model_type MiniMax-M2.7 \53 --model_type MiniMax-M2.7 \
54 --quant_type w8a8 \54 --quant_type w8a8 \
55- --tag Ascend_950 \55+ --tags Ascend_950 \
56 --trust_remote_code True56 --trust_remote_code True
57```57```
58 58 
@@ -37,7 +37,7 @@ msmodelslim quant \
37 --device npu \37 --device npu \
38 --model_type LongCat-Flash-Chat \38 --model_type LongCat-Flash-Chat \
39 --quant_type w4a4 \39 --quant_type w4a4 \
40- --tag Ascend_950 \40+ --tags Ascend_950 \
41 --trust_remote_code True41 --trust_remote_code True
42```42```
43 43 
@@ -65,7 +65,7 @@ msmodelslim quant \
65 --save_path /path/to/wan2_1_14b_quantized_weights \65 --save_path /path/to/wan2_1_14b_quantized_weights \
66 --device npu \66 --device npu \
67 --model_type Wan2_1 \67 --model_type Wan2_1 \
68- --config_path /path/to/wan2_1_w8a8_dynamic.yaml \68+ --config /path/to/wan2_1_w8a8_dynamic.yaml \
69 --trust_remote_code True69 --trust_remote_code True
70```70```
71 71 
@@ -91,7 +91,7 @@ msmodelslim quant \
91 --save_path /path/to/wan2_1_quantized_weights \91 --save_path /path/to/wan2_1_quantized_weights \
92 --device npu \92 --device npu \
93 --model_type Wan2_1 \93 --model_type Wan2_1 \
94- --config_path /path/to/wan2_1_w8a8_dynamic.yaml \94+ --config /path/to/wan2_1_w8a8_dynamic.yaml \
95 --trust_remote_code True95 --trust_remote_code True
96```96```
97 97 
@@ -47,7 +47,7 @@ msmodelslim quant \
47 --save_path /path/to/gemma4_w8a8_weights \47 --save_path /path/to/gemma4_w8a8_weights \
48 --device npu \48 --device npu \
49 --model_type gemma-4-31B-it \49 --model_type gemma-4-31B-it \
50- --config_path lab_practice/gemma4/gemma4_w8a8.yaml \50+ --config lab_practice/gemma4/gemma4_w8a8.yaml \
51 --trust_remote_code True51 --trust_remote_code True
52```52```
53 53 
@@ -39,7 +39,7 @@ pip install -U fla-core
39msmodelslim quant \39msmodelslim quant \
40 --model_path ${model_path} \40 --model_path ${model_path} \
41 --save_path ${save_path} \41 --save_path ${save_path} \
42- --device npu:0,1,2,3,4,5,6,7 \42+ --device npu --device_id 0 1 2 3 4 5 6 7 \
43 --model_type Kimi-K3 \43 --model_type Kimi-K3 \
44 --quant_type w4a8 \44 --quant_type w4a8 \
45 --trust_remote_code True45 --trust_remote_code True
@@ -51,8 +51,8 @@ msmodelslim quant \
51msmodelslim quant \51msmodelslim quant \
52 --model_path ${model_path} \52 --model_path ${model_path} \
53 --save_path ${save_path} \53 --save_path ${save_path} \
54- --device npu:0,1,2,3,4,5,6,7 \54+ --device npu --device_id 0 1 2 3 4 5 6 7 \
55 --model_type Kimi-K3 \55 --model_type Kimi-K3 \
56- --config_path lab_practice/kimi_k3/kimi_k3_w4a8.yaml \56+ --config lab_practice/kimi_k3/kimi_k3_w4a8.yaml \
57 --trust_remote_code True57 --trust_remote_code True
58```58```
@@ -59,7 +59,7 @@ msmodelslim quant \
59 --device npu \59 --device npu \
60 --model_type MiniMax-M3 \60 --model_type MiniMax-M3 \
61 --quant_type w8a8 \61 --quant_type w8a8 \
62- --config_path lab_practice/minimax_m3/minimax_m3_w8a8.yaml \62+ --config lab_practice/minimax_m3/minimax_m3_w8a8.yaml \
63 --trust_remote_code True63 --trust_remote_code True
64```64```
65 65 
@@ -89,7 +89,7 @@ msmodelslim quant \
89 --device npu \89 --device npu \
90 --model_type Qwen2.5-VL-32B-Instruct \90 --model_type Qwen2.5-VL-32B-Instruct \
91 --quant_type w8a8 \91 --quant_type w8a8 \
92- --tag vLLM_Ascend Ascend_950 \92+ --tags vLLM_Ascend Ascend_950 \
93 --trust_remote_code True93 --trust_remote_code True
94```94```
95 95 
@@ -96,7 +96,7 @@ msmodelslim quant \
96 --device npu \96 --device npu \
97 --model_type Qwen3-VL-235B-A22B \97 --model_type Qwen3-VL-235B-A22B \
98 --quant_type w8a8 \98 --quant_type w8a8 \
99- --tag vLLM_Ascend Ascend_950 \99+ --tags vLLM_Ascend Ascend_950 \
100 --trust_remote_code True100 --trust_remote_code True
101```101```
102 102 
@@ -111,7 +111,7 @@ msmodelslim quant \
111 --device npu \111 --device npu \
112 --model_type Qwen3-VL-30B-A3B \112 --model_type Qwen3-VL-30B-A3B \
113 --quant_type w8a8 \113 --quant_type w8a8 \
114- --tag vLLM_Ascend Ascend_950 \114+ --tags vLLM_Ascend Ascend_950 \
115 --trust_remote_code True115 --trust_remote_code True
116```116```
117 117 
@@ -121,7 +121,7 @@ msmodelslim quant \
121 --save_path /path/to/qwen3_vl_4b_quantized_weights \121 --save_path /path/to/qwen3_vl_4b_quantized_weights \
122 --device npu \122 --device npu \
123 --model_type Qwen3-VL-4B-Instruct \123 --model_type Qwen3-VL-4B-Instruct \
124- --config_path lab_practice/qwen3_vl/qwen3_vl_4b_w8a8.yaml \124+ --config lab_practice/qwen3_vl/qwen3_vl_4b_w8a8.yaml \
125 --trust_remote_code True125 --trust_remote_code True
126```126```
127 127 
@@ -20,7 +20,9 @@ See the Mulan PSL v2 for more details.
20"""20"""
21 21 
22import argparse22import argparse
23+import subprocess # nosec B404
23import sys24import sys
25+from pathlib import Path
24from typing import List26from typing import List
25 27 
26import msmodelslim # noqa28import msmodelslim # noqa
@@ -28,11 +30,296 @@ from msmodelslim.cli.logo import print_logo
28from msmodelslim.core.const import DeviceType, QuantType30from msmodelslim.core.const import DeviceType, QuantType
29from msmodelslim.utils.config import msmodelslim_config31from msmodelslim.utils.config import msmodelslim_config
30from msmodelslim.utils.logging import get_logger, set_logger_level32from msmodelslim.utils.logging import get_logger, set_logger_level
31-from msmodelslim.utils.validation.conversion import convert_to_bool
32 33 
33FAQ_HOME = "gitcode repo: Ascend/msmodelslim, wiki"34FAQ_HOME = "gitcode repo: Ascend/msmodelslim, wiki"
34MIND_STUDIO_LOGO = "[Powered by MindStudio]"35MIND_STUDIO_LOGO = "[Powered by MindStudio]"
35 36 
37+_BOOL_TRUE_VALUES = frozenset(('true', 'yes', 'on'))
38+_BOOL_FALSE_VALUES = frozenset(('false', 'no', 'off'))
39+ 
40+ 
41+def _cli_convert_to_bool(value: str) -> bool:
42+ """
43+ CLI-only bool converter for --trust_remote_code.
44+ 
45+ Accepts the canonical ``true`` / ``false`` spellings (per the unified CLI
46+ spec) plus legacy ``True``/``False``, ``yes``/``no`` and ``on``/``off``.
47+ Raises ValueError so argparse produces a clean error instead of a traceback.
48+ """
49+ lowered = value.strip().lower()
50+ if lowered in _BOOL_TRUE_VALUES:
51+ return True
52+ if lowered in _BOOL_FALSE_VALUES:
53+ return False
54+ raise ValueError(f"value must be true/false (legacy True/False, yes/no, on/off are also accepted), got {value!r}")
55+ 
56+ 
57+# ---------------------------------------------------------------------------
58+# Deprecated aliases: legacy option spellings that actually existed in the
59+# original branch -> the canonical snake_case name. Only real legacy spellings
60+# are listed (no invented variants); using one triggers a one-time deprecation
61+# warning and they never appear in --help output.
62+# ---------------------------------------------------------------------------
63+DEPRECATED_ALIASES = {
64+ '--tag': '--tags',
65+ '--pattern': '--patterns',
66+ '--topk': '--top_k',
67+ '--calib_dataset': '--calibration_dataset',
68+ '--config_path': '--config',
69+}
70+ 
71+ 
72+def _repo_root() -> Path:
73+ """Return the msmodelslim repository root (dir containing .git or setup.py)."""
74+ cur = Path(__file__).resolve().parent
75+ for parent in cur.parents:
76+ if (parent / '.git').exists() or (parent / 'setup.py').exists():
77+ return parent
78+ return cur
79+ 
80+ 
81+def _get_version() -> str:
82+ """Return the installed package version, falling back to 'unknown'."""
83+ # 1) Prefer the metadata registered by the installed distribution.
84+ try:
85+ from importlib.metadata import version as _pkg_version # type: ignore
86+ 
87+ pkg_version = _pkg_version('msmodelslim')
88+ except Exception: # pragma: no cover - not installed as a package
89+ pkg_version = ''
90+ if pkg_version:
91+ return pkg_version
92+ # 2) Fall back to reading `__version__` from the repo setup.py without importing it
93+ # (importing setup.py has heavy build side effects we must avoid).
94+ import re as _re
95+ 
96+ setup_file = _repo_root() / 'setup.py'
97+ if setup_file.exists():
98+ try:
99+ match = _re.search(r'^\s*__version__\s*=\s*[\'"]([^\'"]+)[\'"]', setup_file.read_text(), _re.MULTILINE)
100+ except Exception:
101+ match = None
102+ if match:
103+ return match.group(1)
104+ return 'unknown'
105+ 
106+ 
107+def _get_git_hash() -> str:
108+ """
109+ Return the current git commit hash (>= 7 chars) or empty string.
110+ 
111+ Uses subprocess only to run ``git rev-parse HEAD`` with a fixed argument
112+ list, no shell and no user-controlled input (hence the nosec exemptions).
113+ """
114+ try:
115+ out = subprocess.check_output( # nosec B603, B607
116+ ['git', 'rev-parse', 'HEAD'],
117+ cwd=str(_repo_root()),
118+ stderr=subprocess.DEVNULL,
119+ )
120+ return out.decode().strip()[:12]
121+ except Exception:
122+ return ''
123+ 
124+ 
125+def _print_version() -> None:
126+ """Print the unified version banner (MindStudio CLI spec section 4.5)."""
127+ version = _get_version()
128+ git_hash = _get_git_hash()
129+ print_logo()
130+ sys.stdout.write(
131+ f"msmodelslim {version} ({git_hash})\n"
132+ "Copyright (C) 2026 Huawei Technologies Co., Ltd.\n"
133+ "License: Mulan PSL v2.\n"
134+ )
135+ if git_hash:
136+ sys.stdout.write(
137+ f"\nBuild Info:\n GitCommit : {git_hash}\n Repo : https://gitcode.com/Ascend/msmodelslim\n"
138+ )
139+ 
140+ 
141+class _UnifiedHelpFormatter(argparse.RawDescriptionHelpFormatter):
142+ """
143+ Help formatter implementing the unified CLI help layout (spec section 4.4):
144+ * fixed sections: Usage / Description / Required arguments /
145+ Optional arguments / Examples / Output;
146+ * shows the single long name and any single-char short options;
147+ * embeds enum choices directly in the signature as ``{a,b,c}``.
148+ """
149+ 
150+ def __init__(self, *args, **kwargs):
151+ super().__init__(*args, **kwargs)
152+ self._usage_args = None
153+ self._usage_prefix = None
154+ self._description_text = None
155+ self._epilog_text = None
156+ 
157+ def add_usage(self, usage, actions, groups, prefix=None):
158+ self._usage_args = (usage, actions, groups)
159+ self._usage_prefix = prefix
160+ super().add_usage(usage, actions, groups, prefix)
161+ 
162+ def add_text(self, text):
163+ if text is None:
164+ return
165+ if self._description_text is None:
166+ self._description_text = text
167+ else:
168+ self._epilog_text = text
169+ super().add_text(text)
170+ 
171+ def _metavar_formatter(self, action, default_metavar):
172+ if action.metavar is not None:
173+ result = action.metavar
174+ elif action.choices is not None:
175+ result = '{%s}' % ','.join(str(getattr(c, 'value', c)) for c in action.choices)
176+ else:
177+ result = default_metavar
178+ 
179+ def _format(tuple_size):
180+ return result if isinstance(result, tuple) else (result,) * tuple_size
181+ 
182+ return _format
183+ 
184+ def _format_action_invocation(self, action):
185+ opts = action.option_strings
186+ if not opts:
187+ return ''
188+ # Show only: single-char short options (e.g. -v) + the long name.
189+ short_opts = [s for s in opts if s.startswith('-') and not s.startswith('--')]
190+ long_opts = [s for s in opts if s.startswith('--')]
191+ display = short_opts + long_opts[:1]
192+ if not display:
193+ return ''
194+ if action.nargs == 0:
195+ return ', '.join(display)
196+ default = self._get_default_metavar_for_optional(action)
197+ args_string = self._format_args(action, default)
198+ return ', '.join('%s %s' % (s, args_string) for s in display)
199+ 
200+ @staticmethod
201+ def _indent_text(text, indent=' '):
202+ return '\n'.join(indent + line if line else line for line in text.splitlines())
203+ 
204+ def _format_action_section(self, heading, actions):
205+ """Render one argument section (heading + action lines) like argparse does."""
206+ if not actions:
207+ return ''
208+ root = self._Section(self, None, None)
209+ section = self._Section(self, root, heading)
210+ for action in actions:
211+ if action.help is not argparse.SUPPRESS:
212+ invocations = [self._format_action_invocation(action)]
213+ for subaction in self._iter_indented_subactions(action):
214+ invocations.append(self._format_action_invocation(subaction))
215+ self._action_max_length = max(
216+ self._action_max_length,
217+ max(len(invocation) for invocation in invocations) + self._current_indent,
218+ )
219+ section.items.append((self._format_action, [action]))
220+ return section.format_help()
221+ 
222+ def format_help(self):
223+ """Render help in the unified section layout (spec section 4.4.1)."""
224+ usage, actions, groups = self._usage_args
225+ # argparse 内部会用 format_help() 推导子命令的 prog 前缀(prefix=''),
226+ # 此时保持默认渲染;只有真实帮助输出(prefix=None)才使用统一标题。
227+ prefix = 'Usage:\n ' if self._usage_prefix is None else self._usage_prefix
228+ help_text = self._format_usage(usage, actions, groups, prefix)
229+ 
230+ if self._description_text:
231+ help_text += 'Description:\n' + self._indent_text(self._description_text) + '\n\n'
232+ 
233+ positionals = [a for a in actions if not a.option_strings]
234+ required = [a for a in actions if a.option_strings and a.required]
235+ optional = [a for a in actions if a.option_strings and not a.required]
236+ for heading, section_actions in (
237+ ('Positional arguments', positionals),
238+ ('Required arguments', required),
239+ ('Optional arguments', optional),
240+ ):
241+ help_text += self._format_action_section(heading, section_actions)
242+ 
243+ if self._epilog_text:
244+ help_text += self._epilog_text + '\n'
245+ return help_text
246+ 
247+ 
248+def _add_log_level_args(parser: argparse.ArgumentParser) -> None:
249+ """Add unified log-level / verbosity switches (CLI spec section 4.2.3.1)."""
250+ parser.add_argument(
251+ '--log_level',
252+ dest='log_level',
253+ default=None,
254+ choices=['debug', 'info', 'warning', 'error'],
255+ help='Log level [default: info]',
256+ )
257+ parser.add_argument(
258+ '-v',
259+ '--verbose',
260+ dest='verbose',
261+ action='store_true',
262+ help='Increase output verbosity (equivalent to --log_level debug)',
263+ )
264+ parser.add_argument(
265+ '-q',
266+ '--quiet',
267+ dest='quiet',
268+ action='store_true',
269+ help='Suppress non-error output (equivalent to --log_level error)',
270+ )
271+ 
272+ 
273+def _apply_log_level(args) -> None:
274+ """
275+ Resolve the effective log level:
276+ * --log_level wins if given explicitly;
277+ * otherwise --verbose/-v (or --debug) -> debug, --quiet/-q -> error;
278+ * otherwise fall back to the configured env default.
279+ """
280+ log_level = getattr(args, 'log_level', None)
281+ verbose = getattr(args, 'verbose', False)
282+ quiet = getattr(args, 'quiet', False)
283+ debug = getattr(args, 'debug', False)
284+ 
285+ if log_level is not None:
286+ set_logger_level(log_level)
287+ elif verbose or debug:
288+ set_logger_level('debug')
289+ elif quiet:
290+ set_logger_level('error')
291+ else:
292+ set_logger_level(msmodelslim_config.env_vars.log_level)
293+ 
294+ 
295+def _parse_timeout(value):
296+ """
297+ Parse the --timeout value.
298+ * Standard form: an integer number of seconds (per the unified CLI spec).
299+ * Legacy form: a duration string such as '1D', '2H', '3D4H' (handled
300+ downstream by convert_to_timedelta), kept for backward compatibility.
301+ """
302+ try:
303+ return int(value)
304+ except (TypeError, ValueError):
305+ return value
306+ 
307+ 
308+def _warn_deprecated(argv: List[str]) -> None:
309+ """Emit a one-time deprecation warning for any legacy option in argv."""
310+ seen = set()
311+ for token in argv:
312+ opt = token.split('=', 1)[0]
313+ if opt in DEPRECATED_ALIASES and opt not in seen:
314+ seen.add(opt)
315+ get_logger().warning(
316+ "Option %r is deprecated; use %r instead. "
317+ "The old spelling remains supported for backward compatibility "
318+ "but will be removed in a future release.",
319+ opt,
320+ DEPRECATED_ALIASES[opt],
321+ )
322+ 
36 323 
37def _normalize_analyze_argv(argv: List[str]) -> List[str]:324def _normalize_analyze_argv(argv: List[str]) -> List[str]:
38 """325 """
@@ -97,101 +384,295 @@ def _normalize_analyze_argv(argv: List[str]) -> List[str]:
97 return argv384 return argv
98 385 
99 386 
387+def _normalize_device_argv(argv: List[str]) -> List[str]:
388+ """
389+ Backward-compatible normalization for legacy `--device TYPE:IDX,IDX,...`.
390+ 
391+ The device option is split into `--device {npu,cpu}` plus `--device_id`.
392+ Legacy scripts that pass indices inline
393+ (e.g. `--device npu:0,1`) are translated to the canonical form with a
394+ one-time deprecation warning. An explicit `--device_id` option is left
395+ untouched (it takes precedence), and `analyze` is not affected because it
396+ never supported the colon format.
397+ """
398+ if not argv or argv[0] not in ('quant', 'tune'):
399+ return argv
400+ if not any(arg == '--device' or arg.startswith('--device=') for arg in argv):
401+ return argv
402+ if '--device_id' in argv:
403+ return argv
404+ 
405+ warned = False
406+ 
407+ def _warn_once(value: str) -> None:
408+ nonlocal warned
409+ if not warned:
410+ get_logger().warning(
411+ "Option '--device %s' is deprecated; use '--device %s --device_id %s' instead. "
412+ "The legacy device:index format remains supported for backward compatibility "
413+ "but will be removed in a future release.",
414+ value,
415+ value.split(':', 1)[0],
416+ value.split(':', 1)[1].replace(',', ' '),
417+ )
418+ warned = True
419+ 
420+ result = []
421+ i = 0
422+ while i < len(argv):
423+ arg = argv[i]
424+ if arg.startswith('--device='):
425+ value = arg.split('=', 1)[1]
426+ if ':' in value:
427+ _warn_once(value)
428+ type_str, idx_str = value.split(':', 1)
429+ result.extend(['--device', type_str, '--device_id'] + idx_str.split(','))
430+ else:
431+ result.append(arg)
432+ elif arg == '--device':
433+ result.append(arg)
434+ nxt = argv[i + 1] if i + 1 < len(argv) else None
435+ if nxt is not None and ':' in nxt and not nxt.startswith('-'):
436+ _warn_once(nxt)
437+ type_str, idx_str = nxt.split(':', 1)
438+ result.extend([type_str, '--device_id'] + idx_str.split(','))
439+ i += 1
440+ else:
441+ result.append(arg)
442+ i += 1
443+ return result
444+ 
445+ 
100def _is_help_request(argv: List[str]) -> bool:446def _is_help_request(argv: List[str]) -> bool:
101 """Check if the command line arguments contain help request."""447 """Check if the command line arguments contain help request."""
102 return '-h' in argv or '--help' in argv448 return '-h' in argv or '--help' in argv
103 449 
104 450 
451+def _is_version_request(argv: List[str]) -> bool:
452+ """Check if the command line arguments contain a version request.
453+ 
454+ Detects `--version` / `-V` anywhere in argv (including after a subcommand,
455+ e.g. `msmodelslim quant --version`), so the version banner is printed
456+ regardless of position and no stale argparse branch is needed.
457+ """
458+ return '--version' in argv or '-V' in argv
459+ 
460+ 
105def main():461def main():
462+ argv = sys.argv[1:]
463+ 
464+ # Handle version request before printing the startup logo / parsing.
465+ if _is_version_request(argv):
466+ _print_version()
467+ sys.exit(0)
468+ 
469+ # Emit deprecation warnings for legacy spellings before parsing.
470+ _warn_deprecated(argv)
471+ 
106 set_logger_level(msmodelslim_config.env_vars.log_level)472 set_logger_level(msmodelslim_config.env_vars.log_level)
107 473 
108 # Print logo at startup, except when help is requested474 # Print logo at startup, except when help is requested
109- if not _is_help_request(sys.argv[1:]):475+ if not _is_help_request(argv):
110 print_logo()476 print_logo()
111 477 
112 parser = argparse.ArgumentParser(478 parser = argparse.ArgumentParser(
113 prog='msmodelslim',479 prog='msmodelslim',
114- formatter_class=argparse.RawDescriptionHelpFormatter,480+ formatter_class=_UnifiedHelpFormatter,
115 description=f"MsModelSlim(MindStudio Model-Quantization Tools), "481 description=f"MsModelSlim(MindStudio Model-Quantization Tools), "
116 f"{MIND_STUDIO_LOGO}.\n"482 f"{MIND_STUDIO_LOGO}.\n"
117 "Providing functions such as model quantization and compression "483 "Providing functions such as model quantization and compression "
118 "based on Ascend.\n"484 "based on Ascend.\n"
119 f"For any issue, refer FAQ first: {FAQ_HOME}",485 f"For any issue, refer FAQ first: {FAQ_HOME}",
486+ epilog="Examples:\n"
487+ " msmodelslim quant --model_path ${MODEL_PATH} --save_path ${SAVE_PATH} --device npu "
488+ "--model_type Qwen2.5-7B-Instruct --quant_type w8a8 --trust_remote_code True\n"
489+ " msmodelslim analyze linear --model_path ${MODEL_PATH} --model_type Qwen2.5-7B-Instruct\n"
490+ " msmodelslim tune --model_path ${MODEL_PATH} --save_path ${SAVE_PATH} --config ${CONFIG} "
491+ "--device npu --model_type Qwen3-32B",
492+ )
493+ parser.add_argument(
494+ '--version',
495+ '-V',
496+ action='store_true',
497+ help='Show version information and exit',
120 )498 )
121 subparsers = parser.add_subparsers(dest='command', help='Available commands')499 subparsers = parser.add_subparsers(dest='command', help='Available commands')
122 500 
501+ # ------------------------------------------------------------------
123 # Quant command502 # Quant command
124- quant_parser = subparsers.add_parser('quant', help='Model quantization')503+ # ------------------------------------------------------------------
504+ quant_parser = subparsers.add_parser(
505+ 'quant',
506+ help='Model quantization',
507+ formatter_class=_UnifiedHelpFormatter,
508+ description='Quantize a model (W4A4/W8A8/etc.) and save the quantized weights.',
509+ epilog='Examples:\n'
510+ ' msmodelslim quant --model_path ${MODEL_PATH} --save_path ${SAVE_PATH} '
511+ '--device npu --model_type Qwen2.5-7B-Instruct --quant_type w8a8 --trust_remote_code True\n'
512+ ' msmodelslim quant --model_path ${MODEL_PATH} --save_path ${SAVE_PATH} '
513+ '--device npu --model_type ${MODEL_TYPE} --config ${CONFIG_PATH} --trust_remote_code ${TRUST_REMOTE_CODE}\n'
514+ 'Output:\n'
515+ ' Quantized model is written to the directory given by --save_path.',
516+ )
125 quant_parser.add_argument(517 quant_parser.add_argument(
126 '--model_type',518 '--model_type',
519+ dest='model_type',
520+ metavar='<MODEL_TYPE>',
127 required=False,521 required=False,
128 default=None,522 default=None,
129 help="Type of model to quantize (e.g. 'Qwen2.5-7B-Instruct'). "523 help="Type of model to quantize (e.g. 'Qwen2.5-7B-Instruct'). "
130- "Optional when --config_path uses apiversion modelslim_convert (weight convert needs only model_path).",524+ "Optional when --config uses apiversion modelslim_convert (weight convert needs only --model_path).",
525+ )
526+ quant_parser.add_argument(
527+ '--model_path',
528+ dest='model_path',
529+ metavar='<PATH>',
530+ required=True,
531+ type=str,
532+ help='Path to the original model',
533+ )
534+ quant_parser.add_argument(
535+ '--save_path',
536+ dest='save_path',
537+ metavar='<PATH>',
538+ required=True,
539+ type=str,
540+ help='Path to save the quantized model',
131 )541 )
132- quant_parser.add_argument('--model_path', required=True, type=str, help="Path to the original model")
133- quant_parser.add_argument('--save_path', required=True, type=str, help="Path to save quantized model")
134 quant_parser.add_argument(542 quant_parser.add_argument(
135 '--device',543 '--device',
544+ dest='device',
136 type=str,545 type=str,
137 default='npu',546 default='npu',
138- help="Target device specification for quantization. "547+ choices=[d.value for d in DeviceType],
J
Jjoejoezhou11 天前

【review】请确保保持兼容性,原命令行形式仍能执行

likedislike
chenruijie
11 天前 评论:
139- "Format: 'device_type' or 'device_type:index1,index2,...' "548+ help='Target device type for quantization [default: npu]',
140- "(e.g., 'npu', 'npu:0,1,2,3', 'cpu'). "549+ )
141- "Note: Format 'device_type:index1,index2,...' is only supported "550+ quant_parser.add_argument(
142- "when apiversion is 'modelslim_v1'. "551+ '--device_id',
143- "Default: 'npu' (single device)",552+ dest='device_id',
553+ nargs='*',
554+ type=int,
555+ metavar='<ID>',
556+ default=None,
557+ help='Device index (integer) to use for quantization, e.g. 0 or 0 1 2 3',
558+ )
559+ quant_parser.add_argument(
560+ '--config',
561+ '--config_path',
562+ dest='config_path',
563+ metavar='<FILE>',
564+ type=str,
565+ help='Explicit path to quantization config file',
566+ )
567+ quant_parser.add_argument(
568+ '--quant_type',
569+ dest='quant_type',
570+ type=QuantType,
571+ choices=QuantType,
572+ help='Type of quantization to apply',
144 )573 )
145- quant_parser.add_argument('--config_path', type=str, help="Explicit path to quantization config file")
146- quant_parser.add_argument('--quant_type', type=QuantType, choices=QuantType, help="Type of quantization to apply")
147 quant_parser.add_argument(574 quant_parser.add_argument(
148 '--trust_remote_code',575 '--trust_remote_code',
149- type=convert_to_bool,576+ dest='trust_remote_code',
577+ nargs='?',
578+ const=True,
579+ type=_cli_convert_to_bool,
150 default=False,580 default=False,
151- help="Trust custom code (bool type, must be True or False). "581+ metavar='<BOOL>',
152- "Please ensure the security of the loaded custom code file.",582+ help='Trust custom code loaded from the model directory '
583+ "[default: false]. Pass true/false explicitly for backward "
584+ "compatibility. Please ensure the security of the loaded custom code file.",
153 )585 )
154- quant_parser.add_argument("--debug", action="store_true", help="Enable debug mode for context recording")
155 quant_parser.add_argument(586 quant_parser.add_argument(
156- '--tag',587+ '--debug',
157- nargs='*',588+ action='store_true',
158- default=None,589+ help='Enable debug mode for context recording',
159- help="Optional tag to match configs with verified scenario tags (e.g. mindie Atlas_A2_Inference, vllm cpu). "
160- "User can add multiple tags; matching requires all tags to appear in the same scenario."
161- "If user specifies this parameter but does not provide a hardware type tag, the current device type will be matched automatically.",
162 )590 )
591+ quant_parser.add_argument(
592+ '--tags',
593+ '--tag',
594+ dest='tag',
595+ nargs='*',
596+ metavar='<TAG>',
597+ default=None,
598+ help="Optional tags to match configs with verified scenario tags (e.g. mindie Atlas_A2_Inference, vllm cpu). "
599+ "User can add multiple tags; matching requires all tags to appear in the same scenario. "
600+ "If this parameter is specified without a hardware type tag, the current device type is matched automatically.",
601+ )
602+ _add_log_level_args(quant_parser)
163 603 
604+ # ------------------------------------------------------------------
164 # Analyze command605 # Analyze command
165- analysis_parser = subparsers.add_parser('analyze', help='Model quantization sensitivity analyze tool')606+ # ------------------------------------------------------------------
607+ analysis_parser = subparsers.add_parser(
608+ 'analyze',
609+ help='Model quantization sensitivity analyze tool',
610+ formatter_class=_UnifiedHelpFormatter,
611+ description='Analyze quantization sensitivity by scope: linear | layer | attn.',
612+ epilog='Examples:\n'
613+ ' msmodelslim analyze linear --model_path ${MODEL_PATH} --model_type Qwen2.5-7B-Instruct\n'
614+ ' msmodelslim analyze layer --model_path ${MODEL_PATH} --model_type Qwen2.5-7B-Instruct '
615+ '--quant_modules lm_head\n'
616+ 'Output:\n'
617+ ' Analysis results are logged to the console/stdout.',
618+ )
166 619 
167 analyze_common_parser = argparse.ArgumentParser(add_help=False)620 analyze_common_parser = argparse.ArgumentParser(add_help=False)
168 analyze_common_parser.add_argument(621 analyze_common_parser.add_argument(
169- '--model_type', required=True, help="Type of model to analyze (e.g. 'Qwen2.5-7B-Instruct', 'Qwen-QwQ-32B')"622+ '--model_type',
170- )623+ dest='model_type',
171- analyze_common_parser.add_argument('--model_path', required=True, type=str, help="Path to the original model")624+ metavar='<MODEL_TYPE>',
172- analyze_common_parser.add_argument(625+ required=True,
173- '--device', type=DeviceType, default=DeviceType.NPU, choices=DeviceType, help="Target device type for Analysis"626+ help="Type of model to analyze (e.g. 'Qwen2.5-7B-Instruct', 'DeepSeek-V3')",
174 )627 )
175 analyze_common_parser.add_argument(628 analyze_common_parser.add_argument(
629+ '--model_path',
630+ dest='model_path',
631+ metavar='<PATH>',
632+ required=True,
633+ type=str,
634+ help='Path to the original model',
635+ )
636+ analyze_common_parser.add_argument(
637+ '--device',
638+ dest='device',
639+ type=DeviceType,
640+ default=DeviceType.NPU,
641+ choices=DeviceType,
642+ help='Target device type for Analysis [default: npu]',
643+ )
644+ analyze_common_parser.add_argument(
645+ '--calibration_dataset',
176 '--calib_dataset',646 '--calib_dataset',
647+ dest='calib_dataset',
648+ metavar='<FILE>',
177 type=str,649 type=str,
178 default='mix_calib.jsonl',650 default='mix_calib.jsonl',
179 help='Calibration dataset file path or filename in lab_calib directory. '651 help='Calibration dataset file path or filename in lab_calib directory. '
180- 'Supports .json and .jsonl formats (default: mix_calib.jsonl)',652+ 'Supports .json and .jsonl formats [default: mix_calib.jsonl]',
181 )653 )
182 analyze_common_parser.add_argument(654 analyze_common_parser.add_argument(
655+ '--top_k',
183 '--topk',656 '--topk',
657+ dest='topk',
658+ metavar='<N>',
184 type=int,659 type=int,
185 default=15,660 default=15,
186- help='Number of top layers to output for disable_names (default: 15, empirical value, for reference only)',661+ help='Number of top layers to output for disable_names [default: 15, empirical value, for reference only]',
187 )662 )
188 analyze_common_parser.add_argument(663 analyze_common_parser.add_argument(
189 '--trust_remote_code',664 '--trust_remote_code',
190- type=convert_to_bool,665+ dest='trust_remote_code',
666+ nargs='?',
667+ const=True,
668+ type=_cli_convert_to_bool,
191 default=False,669 default=False,
192- help="Trust custom code (bool type, must be True or False). "670+ metavar='<BOOL>',
193- "Please ensure the security of the loaded custom code file.",671+ help='Trust custom code loaded from the model directory '
672+ "[default: false]. Pass true/false explicitly for backward "
673+ "compatibility. Please ensure the security of the loaded custom code file.",
194 )674 )
675+ _add_log_level_args(analyze_common_parser)
195 676 
196 analysis_subparsers = analysis_parser.add_subparsers(dest='scope', help='Analyze scopes')677 analysis_subparsers = analysis_parser.add_subparsers(dest='scope', help='Analyze scopes')
197 analysis_subparsers.required = True678 analysis_subparsers.required = True
@@ -199,82 +680,176 @@ def main():
199 analysis_linear_parser = analysis_subparsers.add_parser(680 analysis_linear_parser = analysis_subparsers.add_parser(
200 'linear',681 'linear',
201 parents=[analyze_common_parser],682 parents=[analyze_common_parser],
202- help='Analyze individual linear layers; use --pattern to filter what gets listed',683+ help='Analyze individual linear layers; use --patterns to filter what gets listed',
684+ formatter_class=_UnifiedHelpFormatter,
685+ description='Analyze individual linear layers. Use --patterns to filter what gets listed.',
686+ epilog='Examples:\n'
687+ ' msmodelslim analyze linear --model_path ${MODEL_PATH} --model_type Qwen2.5-7B-Instruct\n'
688+ ' msmodelslim analyze linear --model_path ${MODEL_PATH} --model_type Qwen2.5-7B-Instruct '
689+ '--metrics std --patterns mlp*',
203 )690 )
204 analysis_linear_parser.add_argument(691 analysis_linear_parser.add_argument(
205 '--metrics',692 '--metrics',
693+ dest='metrics',
206 type=str,694 type=str,
207 choices=['std', 'quantile', 'kurtosis'],695 choices=['std', 'quantile', 'kurtosis'],
208 default='kurtosis',696 default='kurtosis',
209- help='Analysis metrics: std, quantile, kurtosis (default: kurtosis)',697+ help='Analysis metrics [default: kurtosis]',
210 )698 )
211 analysis_linear_parser.add_argument(699 analysis_linear_parser.add_argument(
212- '--pattern', nargs='*', default=['*'], help='Pattern list to filter displayed linear layers (default: ["*"])'700+ '--patterns',
701+ '--pattern',
702+ dest='pattern',
703+ nargs='*',
704+ metavar='<PATTERN>',
705+ default=['*'],
706+ help='Pattern list to filter displayed linear layers [default: ["*"]]',
213 )707 )
214 708 
215 analysis_layer_parser = analysis_subparsers.add_parser(709 analysis_layer_parser = analysis_subparsers.add_parser(
216 'layer',710 'layer',
217 parents=[analyze_common_parser],711 parents=[analyze_common_parser],
218 help='Analyze layer/block as a group; --quant_modules selects modules to include in pipeline config',712 help='Analyze layer/block as a group; --quant_modules selects modules to include in pipeline config',
713+ formatter_class=_UnifiedHelpFormatter,
714+ description='Analyze layer/block as a group. '
715+ '--quant_modules selects modules to include in the pipeline config.',
716+ epilog='Examples:\n'
717+ ' msmodelslim analyze layer --model_path ${MODEL_PATH} --model_type Qwen2.5-7B-Instruct\n'
718+ ' msmodelslim analyze layer --model_path ${MODEL_PATH} --model_type Qwen2.5-7B-Instruct '
719+ '--quant_modules lm_head',
219 )720 )
220 analysis_layer_parser.add_argument(721 analysis_layer_parser.add_argument(
221 '--metrics',722 '--metrics',
723+ dest='metrics',
222 type=str,724 type=str,
223 choices=['mse_model_wise', 'mse_layer_wise'],725 choices=['mse_model_wise', 'mse_layer_wise'],
224 default='mse_layer_wise',726 default='mse_layer_wise',
225- help='Analysis metrics: mse_model_wise, mse_layer_wise (default: mse_layer_wise)',727+ help='Analysis metrics [default: mse_layer_wise]',
226 )728 )
227 analysis_layer_parser.add_argument(729 analysis_layer_parser.add_argument(
228 '--quant_modules',730 '--quant_modules',
731+ dest='quant_modules',
229 nargs='*',732 nargs='*',
733+ metavar='<MODULE>',
230 default=['*'],734 default=['*'],
231- help='Quant modules list that maps to pipeline scope (default: ["*"])',735+ help='Quant modules list that maps to pipeline scope [default: ["*"]]',
232 )736 )
233 737 
234 analysis_attn_parser = analysis_subparsers.add_parser(738 analysis_attn_parser = analysis_subparsers.add_parser(
235 'attn',739 'attn',
236 parents=[analyze_common_parser],740 parents=[analyze_common_parser],
237 help='Analyze attention modules with mse metric (scope defaults to all attention modules)',741 help='Analyze attention modules with mse metric (scope defaults to all attention modules)',
742+ formatter_class=_UnifiedHelpFormatter,
743+ description='Analyze attention modules with the mse metric (scope defaults to all attention modules).',
744+ epilog='Examples:\n msmodelslim analyze attn --model_path ${MODEL_PATH} --model_type Qwen2.5-7B-Instruct',
238 )745 )
239 analysis_attn_parser.add_argument(746 analysis_attn_parser.add_argument(
240- '--metrics', type=str, choices=['mse'], default='mse', help='Analysis metrics: mse (default: mse)'747+ '--metrics',
748+ dest='metrics',
749+ type=str,
750+ choices=['mse'],
751+ default='mse',
752+ help='Analysis metrics [default: mse]',
241 )753 )
242 754 
755+ # ------------------------------------------------------------------
243 # auto tuning command756 # auto tuning command
244- tuning_parser = subparsers.add_parser('tune', help='Model quantization auto tuning tool')757+ # ------------------------------------------------------------------
758+ tuning_parser = subparsers.add_parser(
759+ 'tune',
760+ help='Model quantization auto tuning tool',
761+ formatter_class=_UnifiedHelpFormatter,
762+ description='Automatically tune quantization configs to satisfy the target accuracy.',
763+ epilog='Examples:\n'
764+ ' msmodelslim tune --model_path ${MODEL_PATH} --save_path ${SAVE_PATH} --config ${CONFIG} '
765+ '--device npu --model_type Qwen3-32B\n'
766+ ' msmodelslim tune --model_path ${MODEL_PATH} --save_path ${SAVE_PATH} --config ${CONFIG} '
767+ '--device npu --device_id 0 --timeout 3600\n'
768+ 'Output:\n'
769+ ' Tuning results are written to the directory given by --save_path.',
770+ )
245 tuning_parser.add_argument(771 tuning_parser.add_argument(
246 '--model_type',772 '--model_type',
773+ dest='model_type',
774+ metavar='<MODEL_TYPE>',
247 type=str,775 type=str,
248 default='default',776 default='default',
249- help="Type of model to quantize (e.g. 'Qwen2.5-7B-Instruct', 'Qwen-QwQ-32B')",777+ help="Type of model to quantize (e.g. 'Qwen2.5-7B-Instruct', 'Qwen3-32B')",
778+ )
779+ tuning_parser.add_argument(
780+ '--model_path',
781+ dest='model_path',
782+ metavar='<PATH>',
783+ required=True,
784+ type=str,
785+ help='Path to the original model',
786+ )
787+ tuning_parser.add_argument(
788+ '--save_path',
789+ dest='save_path',
790+ metavar='<PATH>',
791+ required=True,
792+ type=str,
793+ help='Path to save tuning results',
794+ )
795+ tuning_parser.add_argument(
796+ '--config',
797+ dest='config',
798+ metavar='<FILE>',
799+ required=True,
800+ type=str,
801+ help='Path to tuning config file',
250 )802 )
251- tuning_parser.add_argument('--model_path', required=True, type=str, help="Path to the original model")
252- tuning_parser.add_argument('--save_path', required=True, type=str, help="Path to save tuning results")
253- tuning_parser.add_argument('--config', required=True, type=str, help="Path to tuning config file")
254 tuning_parser.add_argument(803 tuning_parser.add_argument(
255 '--device',804 '--device',
805+ dest='device',
256 type=str,806 type=str,
257 default='npu',807 default='npu',
258- help="Target device specification for quantization. "808+ choices=[d.value for d in DeviceType],
259- "Format: 'device_type' or 'device_type:index1,index2,...' "809+ help='Target device type for tuning [default: npu]',
260- "(e.g., 'npu', 'npu:0,1,2,3', 'cpu'). "810+ )
261- "Note: Format 'device_type:index1,index2,...' is only supported "811+ tuning_parser.add_argument(
262- "when apiversion is 'modelslim_v1'. "812+ '--device_id',
263- "Default: 'npu' (single device)",813+ dest='device_id',
814+ nargs='*',
815+ type=int,
816+ metavar='<ID>',
817+ default=None,
818+ help='Device index (integer) to use for tuning, e.g. 0 or 0 1 2 3',
819+ )
820+ tuning_parser.add_argument(
821+ '--timeout',
822+ dest='timeout',
823+ type=_parse_timeout,
824+ metavar='<SECONDS>',
825+ default=None,
826+ help='Timeout for tuning, in seconds. '
827+ 'Legacy duration strings such as 1D, 2H, 3D4H are still accepted '
828+ 'for backward compatibility.',
264 )829 )
265- tuning_parser.add_argument('--timeout', type=str, default=None, help='Timeout for tuning, e.g. 1D, 2H, 3D4H')
266 tuning_parser.add_argument(830 tuning_parser.add_argument(
267 '--trust_remote_code',831 '--trust_remote_code',
268- type=convert_to_bool,832+ dest='trust_remote_code',
833+ nargs='?',
834+ const=True,
835+ type=_cli_convert_to_bool,
269 default=False,836 default=False,
270- help="Trust custom code (bool type, must be True or False). "837+ metavar='<BOOL>',
271- "Please ensure the security of the loaded custom code file.",838+ help='Trust custom code loaded from the model directory '
839+ "[default: false]. Pass true/false explicitly for backward "
840+ "compatibility. Please ensure the security of the loaded custom code file.",
272 )841 )
842+ _add_log_level_args(tuning_parser)
273 843 
274- argv = sys.argv[1:]844+ # 兼容旧设备写法:--device npu:0,1 → --device npu --device_id 0 1
845+ argv = _normalize_device_argv(argv)
275 if argv[:1] == ['analyze']:846 if argv[:1] == ['analyze']:
276 argv = _normalize_analyze_argv(argv)847 argv = _normalize_analyze_argv(argv)
277 args = parser.parse_args(argv)848 args = parser.parse_args(argv)
849+ 
850+ # Resolve the effective log level based on the unified log switches.
851+ _apply_log_level(args)
852+ 
278 if args.command == 'quant':853 if args.command == 'quant':
279 from msmodelslim.cli.naive_quantization.__main__ import main as quant_main854 from msmodelslim.cli.naive_quantization.__main__ import main as quant_main
280 855 
@@ -18,7 +18,9 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
18See the Mulan PSL v2 for more details.18See the Mulan PSL v2 for more details.
19-------------------------------------------------------------------------19-------------------------------------------------------------------------
20"""20"""
21+ 
21import os22import os
23+from datetime import timedelta
22from pathlib import Path24from pathlib import Path
23 25 
24from msmodelslim.app.auto_tuning import AutoTuningApplication26from msmodelslim.app.auto_tuning import AutoTuningApplication
@@ -57,10 +59,7 @@ def main(args):
57 practice_dir = get_practice_dir()59 practice_dir = get_practice_dir()
58 custom_practice_dir = msmodelslim_config.env_vars.custom_practice_repo60 custom_practice_dir = msmodelslim_config.env_vars.custom_practice_repo
59 custom_practice_path = Path(custom_practice_dir) if custom_practice_dir else None61 custom_practice_path = Path(custom_practice_dir) if custom_practice_dir else None
60- practice_manager = YamlPracticeManager(62+ practice_manager = YamlPracticeManager(official_config_dir=practice_dir, custom_config_dir=custom_practice_path)
61- official_config_dir=practice_dir,
62- custom_config_dir=custom_practice_path
63- )
64 dataset_dir = get_dataset_dir()63 dataset_dir = get_dataset_dir()
65 dataset_loader = FileDatasetLoader(dataset_dir)64 dataset_loader = FileDatasetLoader(dataset_dir)
66 vlm_dataset_loader = VLMDatasetLoader(dataset_dir)65 vlm_dataset_loader = VLMDatasetLoader(dataset_dir)
@@ -69,7 +68,7 @@ def main(args):
69 QuantServiceProxyConfig(apiversion="proxy"),68 QuantServiceProxyConfig(apiversion="proxy"),
70 dataset_loader,69 dataset_loader,
71 vlm_dataset_loader,70 vlm_dataset_loader,
72- context_factory=ContextFactory()71+ context_factory=ContextFactory(),
73 )72 )
74 model_factory = PluginModelFactory()73 model_factory = PluginModelFactory()
75 tuning_history_manager = YamlTuningHistoryManager()74 tuning_history_manager = YamlTuningHistoryManager()
@@ -89,6 +88,13 @@ def main(args):
89 )88 )
90 89 
91 device_type, device_indices = parse_device_string(args.device)90 device_type, device_indices = parse_device_string(args.device)
91+ if getattr(args, 'device_id', None):
92+ device_indices = list(args.device_id)
93+ 
94+ # --timeout is expressed in seconds; convert to timedelta when given as an int.
95+ timeout = args.timeout
96+ if isinstance(timeout, int):
97+ timeout = timedelta(seconds=timeout)
92 98 
93 app.tune(99 app.tune(
94 model_type=args.model_type,100 model_type=args.model_type,
@@ -97,6 +103,6 @@ def main(args):
97 plan_id=args.config,103 plan_id=args.config,
98 device=device_type,104 device=device_type,
99 device_indices=device_indices,105 device_indices=device_indices,
100- timeout=args.timeout,106+ timeout=timeout,
101- trust_remote_code=args.trust_remote_code107+ trust_remote_code=args.trust_remote_code,
102 )108 )
@@ -18,6 +18,7 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
18See the Mulan PSL v2 for more details.18See the Mulan PSL v2 for more details.
19-------------------------------------------------------------------------19-------------------------------------------------------------------------
20"""20"""
21+ 
21import os22import os
22from pathlib import Path23from pathlib import Path
23 24 
@@ -64,6 +65,8 @@ def main(args):
64 dataset_loader = FileDatasetLoader(dataset_dir)65 dataset_loader = FileDatasetLoader(dataset_dir)
65 vlm_dataset_loader = VLMDatasetLoader(dataset_dir)66 vlm_dataset_loader = VLMDatasetLoader(dataset_dir)
66 device_type, device_index = parse_device_string(args.device)67 device_type, device_index = parse_device_string(args.device)
68+ if getattr(args, 'device_id', None):
69+ device_index = list(args.device_id)
67 70 
68 # Create context persistence if debug mode is enabled71 # Create context persistence if debug mode is enabled
69 debug_info_persistence = None72 debug_info_persistence = None
@@ -80,7 +83,7 @@ def main(args):
80 83 
81 # 创建YAML量化配置导出器84 # 创建YAML量化配置导出器
82 quant_config_exporter = YamlQuantConfigExporter()85 quant_config_exporter = YamlQuantConfigExporter()
83- 86+ 
84 app = NaiveQuantizationApplication(87 app = NaiveQuantizationApplication(
85 practice_manager=practice_manager,88 practice_manager=practice_manager,
86 quant_service=quant_service,89 quant_service=quant_service,
@@ -97,5 +100,5 @@ def main(args):
97 quant_type=args.quant_type,100 quant_type=args.quant_type,
98 config_path=args.config_path,101 config_path=args.config_path,
99 trust_remote_code=args.trust_remote_code,102 trust_remote_code=args.trust_remote_code,
100- tag=getattr(args, 'tag', None)103+ tag=getattr(args, 'tag', None),
101 )104 )
@@ -0,0 +1,153 @@
1+#!/usr/bin/env python
2+# -*- coding: UTF-8 -*-
3+ 
4+"""
5+-------------------------------------------------------------------------
6+This file is part of the MindStudio project.
7+Copyright (c) 2025 Huawei Technologies Co.,Ltd.
8+ 
9+MindStudio is licensed under Mulan PSL v2.
10+You can use this software according to the terms and conditions of the Mulan PSL v2.
11+You may obtain a copy of Mulan PSL v2 at:
12+ 
13+ http://license.coscl.org.cn/MulanPSL2
14+ 
15+THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
16+EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
17+MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
18+See the Mulan PSL v2 for more details.
19+-------------------------------------------------------------------------
20+"""
21+ 
22+import argparse
23+from types import SimpleNamespace
24+from unittest import mock
25+ 
26+import pytest
27+ 
28+import msmodelslim.cli.__main__ as cli
29+ 
30+ 
31+class TestHelpFormatter:
32+ @staticmethod
33+ def _invocation(*opts, **kw):
34+ parser = argparse.ArgumentParser(formatter_class=cli._UnifiedHelpFormatter)
35+ parser.add_argument(*opts, **kw)
36+ return cli._UnifiedHelpFormatter(prog='prog')._format_action_invocation(parser._actions[-1])
37+ 
38+ def test_show_only_short_and_canonical(self):
39+ assert self._invocation('-v', '--verbose', '--old_verbose', action='store_true') == '-v, --verbose'
40+ assert self._invocation('--model_path', dest='model_path', metavar='<PATH>', type=str) == (
41+ '--model_path <PATH>'
42+ )
43+ 
44+ 
45+class TestCliConvertToBool:
46+ def test_valid_values(self):
47+ assert all(cli._cli_convert_to_bool(v) is True for v in ('true', 'yes', 'on', 'True'))
48+ assert all(cli._cli_convert_to_bool(v) is False for v in ('false', 'no', 'off', 'FALSE'))
49+ 
50+ def test_invalid_value(self):
51+ with pytest.raises(ValueError):
52+ cli._cli_convert_to_bool('maybe')
53+ 
54+ 
55+class TestParseTimeout:
56+ def test_seconds(self):
57+ assert cli._parse_timeout('3600') == 3600
58+ 
59+ def test_legacy_duration(self):
60+ assert cli._parse_timeout('1D2H') == '1D2H'
61+ 
62+ 
63+class TestWarnDeprecated:
64+ @staticmethod
65+ def _warn(argv):
66+ with mock.patch.object(cli, 'get_logger') as g:
67+ cli._warn_deprecated(argv)
68+ return g.return_value.warning
69+ 
70+ def test_legacy_spellings(self):
71+ for old, new in (
72+ ('--topk', '--top_k'),
73+ ('--calib_dataset', '--calibration_dataset'),
74+ ('--tag', '--tags'),
75+ ('--pattern', '--patterns'),
76+ ('--config_path', '--config'),
77+ ):
78+ w = self._warn(['quant', old, 'x'])
79+ assert w.call_count == 1
80+ assert w.call_args[0][1] == old
81+ assert w.call_args[0][2] == new
82+ 
83+ def test_dedup_and_canonical_silent(self):
84+ assert self._warn(['quant', '--topk', 'a', '--topk', 'b']).call_count == 1
85+ assert self._warn(['quant', '--top_k', '5']).call_count == 0
86+ 
87+ 
88+class TestApplyLogLevel:
89+ @staticmethod
90+ def _level(**kw):
91+ with mock.patch.object(cli, 'set_logger_level') as s:
92+ cli._apply_log_level(SimpleNamespace(**kw))
93+ return s.call_args[0][0]
94+ 
95+ def test_precedence(self):
96+ assert self._level(log_level='error', verbose=False, quiet=False, debug=False) == 'error'
97+ assert self._level(log_level=None, verbose=True, quiet=False, debug=False) == 'debug'
98+ assert self._level(log_level=None, verbose=False, quiet=True, debug=False) == 'error'
99+ assert self._level(log_level='warning', verbose=True, quiet=False, debug=False) == 'warning'
100+ 
101+ 
102+class TestArgvDetectors:
103+ def test_help_and_version_detection(self):
104+ assert cli._is_help_request(['quant', '--help'])
105+ assert cli._is_version_request(['quant', '--version'])
106+ assert not cli._is_help_request(['quant', '--version'])
107+ assert not cli._is_version_request(['quant', '--help'])
108+ 
109+ 
110+class TestNormalizeDeviceArgv:
111+ def test_space_form(self):
112+ assert cli._normalize_device_argv(['quant', '--device', 'npu:0,1,2,3']) == [
113+ 'quant',
114+ '--device',
115+ 'npu',
116+ '--device_id',
117+ '0',
118+ '1',
119+ '2',
120+ '3',
121+ ]
122+ 
123+ def test_equals_form(self):
124+ assert cli._normalize_device_argv(['tune', '--device=cpu:0']) == [
125+ 'tune',
126+ '--device',
127+ 'cpu',
128+ '--device_id',
129+ '0',
130+ ]
131+ 
132+ def test_canonical_and_missing_value_untouched(self):
133+ argv = ['quant', '--device', 'npu', '--device_id', '0', '1']
134+ assert cli._normalize_device_argv(argv) == argv
135+ assert cli._normalize_device_argv(['quant', '--device', '--model_path', 'm']) == [
136+ 'quant',
137+ '--device',
138+ '--model_path',
139+ 'm',
140+ ]
141+ 
142+ def test_explicit_new_args_win(self):
143+ argv = ['quant', '--device', 'npu:0,1', '--device_id', '2']
144+ assert cli._normalize_device_argv(argv) == argv
145+ 
146+ def test_analyze_untouched(self):
147+ argv = ['analyze', '--device', 'npu:0,1']
148+ assert cli._normalize_device_argv(argv) == argv
149+ 
150+ def test_warns_once(self):
151+ with mock.patch.object(cli, 'get_logger') as g:
152+ cli._normalize_device_argv(['quant', '--device', 'npu:0,1', '--device', 'cpu:2'])
153+ assert g.return_value.warning.call_count == 1