79 lines
4.4 KiB
Markdown
79 lines
4.4 KiB
Markdown
|
|
# MiniMax-M2.7 FP8 转昆仑芯 INT8
|
|||
|
|
|
|||
|
|
依据安装版本:
|
|||
|
|
|
|||
|
|
- `vllm==0.25.1`,`vllm-kunlun==0.25.1.dev0`,仓库提交 `fbb6fa6`。
|
|||
|
|
- Linear:`KunlunScaledMMLinearKernel`。
|
|||
|
|
- MoE:`KunlunCompressedTensorsW8A8Int8MoEMethod`;保留专家 `w1/w2/w3` 的原始名称,由 vLLM 完成融合及 TP 切分。
|
|||
|
|
- 输出 `compressed-tensors / int-quantized`:逐输出通道对称 INT8 权重,逐 token 动态对称 INT8 激活,无需校准数据集。
|
|||
|
|
|
|||
|
|
转换关系:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
W_fp32[i,j] = W_fp8[i,j] * weight_scale_inv[i//128,j//128]
|
|||
|
|
s[i,0] = max(abs(W_fp32[i,:])) / 127
|
|||
|
|
W_int8[i,j] = clamp(round(W_fp32[i,j] / s[i,0]), -127, 127)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
尽管源 scale 名字有 `_inv`,其保存值用于乘法反量化,不能取倒数。全零行输出 `q=0,s=1`。
|
|||
|
|
输出 scale 名称为 `weight_scale`、FP32 类型、形状 `[out_features,1]`。
|
|||
|
|
磁盘保存 `absmax/127`;插件加载后自行乘 127 得到运行时 absmax,不能在转换时提前乘。
|
|||
|
|
|
|||
|
|
Embedding、lm_head、router gate、routing bias 和 norm 保留原始类型和值。脚本读取索引指定的张量,不会把目录里未被索引引用的旧分片一起导入。支持 scale 跨分片读取,分片内逐矩阵处理、矩阵内分行处理;不把完整模型加载进内存,不分配 XPU。
|
|||
|
|
|
|||
|
|
## 使用
|
|||
|
|
|
|||
|
|
脚本部署位置:
|
|||
|
|
`/mnt/disk0/models/MiniMax/quant_tools/minimax_m27_kunlun_int8/`。
|
|||
|
|
|
|||
|
|
预检只读取配置及所有索引分片的文件头,不写输出:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
/opt/vllm_kunlun/bin/python \
|
|||
|
|
/mnt/data0/models/MiniMax/quant_tools/minimax_m27_kunlun_int8/convert_fp8_to_int8.py \
|
|||
|
|
--source /mnt/data0/models/MiniMax/MiniMax-M2.7 \
|
|||
|
|
--output /mnt/data0/models/MiniMax/MiniMax-M2.7-INT8 \
|
|||
|
|
--dry-run
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
全量转换:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
/opt/vllm_kunlun/bin/python \
|
|||
|
|
/mnt/data0/models/MiniMax/quant_tools/minimax_m27_kunlun_int8/convert_fp8_to_int8.py \
|
|||
|
|
--source /mnt/data0/models/MiniMax/MiniMax-M2.7 \
|
|||
|
|
--output /mnt/data0/models/MiniMax/MiniMax-M2.7-INT8 \
|
|||
|
|
--threads 8
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
中断后用同一命令添加 `--resume`。已完成的分片会检查文件大小、张量名称、类型及形状后跳过;未完成分片重新计算。`--chunk-rows` 默认为 1024,如需调整,恢复时必须保持一致。源文件位置、大小、时间戳、模型配置或索引变化后会拒绝恢复。恢复检查不包含整文件数据校验和。
|
|||
|
|
|
|||
|
|
预检结果为 47,864 个 FP8 矩阵、125 个输出分片,预计张量数据 **214.63 GiB**;检查时磁盘剩余 352.09 GiB。转换需要独立输出目录,原始模型保持不变。每完成一个分片都会更新 `conversion_state.json`,最后生成新的配置、索引和 `conversion_report.json`。只有打印 `Complete` 后才启动模型。
|
|||
|
|
|
|||
|
|
转换完成后的首次服务验证可运行:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
bash /mnt/disk0/models/MiniMax/quant_tools/minimax_m27_kunlun_int8/serve_int8.sh
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
启动脚本使用 TP=4、BF16、8192 上下文和 eager 模式,先控制 KV cache 和图编译相关变量。服务启动及生成通过后再调整上下文和并发。
|
|||
|
|
|
|||
|
|
## 验证
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd /mnt/data0/models/MiniMax/quant_tools/minimax_m27_kunlun_int8
|
|||
|
|
/opt/vllm_kunlun/bin/python test_conversion.py
|
|||
|
|
/opt/vllm_kunlun/bin/python validate_kunlun_contract.py
|
|||
|
|
/opt/vllm_kunlun/bin/python validate_sample_weights.py \
|
|||
|
|
--source /mnt/data0/models/MiniMax/MiniMax-M2.7 \
|
|||
|
|
--report sample_validation.json
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- `test_conversion.py`:独立反量化参考值与半个量化步长误差界、全零行、非整块尺寸、非法 scale、跨分片转换、配置与索引、断点恢复、源文件不变及拒绝覆盖。
|
|||
|
|
- `validate_kunlun_contract.py`:使用小型 CPU 测试层、模拟 TP rank/world size,核实当前插件的配置匹配、Linear/MoE 内核选择、参数布局、scale 转换和忽略名单;不代表完整引擎加载或设备算子执行通过。
|
|||
|
|
- `validate_sample_weights.py`:真实 layer 0 的 Q/K/V/O 和 expert 0 的 w1/w2/w3,共七个矩阵,检查转换后的逐行舍入误差并记录 relative RMSE。
|
|||
|
|
|
|||
|
|
2026-10-29 完成上述三项验证,全部通过。七个真实矩阵相对于 FP8 乘 scale 后参考权重的 relative RMSE 为 0.85%–1.08%,全部满足半个逐行量化步长的舍入误差界。该指标仅衡量这些矩阵的二次量化误差。
|
|||
|
|
|
|||
|
|
这是从现有 FP8 权重再次量化得到的 absmax INT8 基线,并非从原始高精度权重直接量化。数学误差检查不代表任务质量评测;完整模型转换、P800 推理及任务精度仍需分别验证。
|