Files
deepseek-r1-kunlun-INT8/README.md
2026-10-30 17:29:26 +08:00

113 lines
6.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# DeepSeek-R1 昆仑芯 INT8 转换
针对完整 DeepSeek-R1/V3 架构检查点。
依据已安装的 `vllm==0.25.1`、`vllm-kunlun==0.25.1.dev0` 实现
## 输出策略
| 权重 | 输出类型 | 原因 |
|---|---|---|
| MLA q_a/q_b/kv_a/o 投影 | 逐输出通道 INT8 | 对接 KunlunScaledMMLinearKernel |
| 58 层 MoE 的 256 个路由专家 gate/up/down | 逐输出通道 INT8 | 对接 KunlunCompressedTensorsW8A8Int8MoEMethod |
| MLA kv_b_proj | 反量化 BF16 | 对接 MLA 的 BF16 W_UK_T/W_UV 拆分路径 |
| 前三层 Dense MLP | 反量化 BF16 | 真实样本逐通道 INT8 误差较大 |
| 共享专家 gate/up/down | 反量化 BF16 | 真实样本逐通道 INT8 误差较大 |
| Embedding、lm_head、norm、router、routing bias | 原样保留 | 保持源类型和值 |
| 第 62 层 MTP,即 model.layers.61 | 不包含 | 本脚本输出普通推理版本,num_nextn_predict_layers=0 |
输出 `compressed-tensors / int-quantized`,权重逐通道静态对称 INT8,激活逐 token 动态对称 INT8;无需校准集。BF16 例外通过量化配置的 ignore 明确声明,包括 vLLM 融合后的 gate_up_proj 名称。保持源张量名称,由 vLLM 完成 Q/KV A 投影、gate/up 的融合与专家权重切分。
```text
W[i,j] = W_fp8[i,j] * weight_scale_inv[i//128,j//128]
s[i,0] = max(abs(W[i,:])) / 127
W_int8[i,j] = clamp(round(W[i,j]/s[i,0]), -127, 127)
```
`weight_scale_inv` 保存的值用于乘法反量化,不能取倒数。
输出 INT8 scale 为 `weight_scale`,FP32,形状 `[out_features,1]`。
磁盘存 `absmax/127`,插件加载后自行乘 127,转换时不能提前乘。
BF16 例外输出 `BF16(FP8 * block_scale)`,删除原 block scale,不产生 INT8 scale。
全零 INT8 行使用 `q=0,s=1`。
脚本按源索引定位跨分片的 scale,逐分片、逐矩阵、分行处理;不加载整个模型,不分配 XPU,不修改原始模型。
预检逐项验证前 61 层的全部 MLA/Dense/共享及路由专家投影、矩阵形状、FP8 格式和 scale 网格。
## 使用
脚本已部署到:
```text
/mnt/data1/quant_tools/deepseek_r1_kunlun_int8/
```
预检不创建输出目录、不转换权重:
```bash
/opt/vllm_kunlun/bin/python \
/mnt/data1/quant_tools/deepseek_r1_kunlun_int8/convert_deepseek_fp8_to_int8.py \
--source /mnt/data1/deepseek-r1 \
--output /mnt/data1/deepseek-r1-INT8 \
--dry-run
```
开始全量转换:
```bash
/opt/vllm_kunlun/bin/python \
/mnt/data1/quant_tools/deepseek_r1_kunlun_int8/convert_deepseek_fp8_to_int8.py \
--source /mnt/data1/deepseek-r1 \
--output /mnt/data1/deepseek-r1-INT8 \
--threads 8
```
中断后在相同命令末尾添加 `--resume`。输出目录必须是独立空目录,或具有匹配的 `conversion_state.json`。默认 `--chunk-rows 1024`,恢复时必须与首次运行一致。每片先写临时文件,检查成功后重命名,再记录完成状态。完成时打印 `Complete` 并生成新配置、索引和 `conversion_report.json`,之后才可部署。
恢复时核实源配置和索引、源分片大小与时间戳;核实已完成输出分片大小、张量名称、类型、形状及 safetensors 文件结构。恢复检查不计算完整权重文件校验和。
2026-10-29 预检结果:45,032 个 FP8 矩阵,其中 44,788 个转 INT8,244 个转 BF16;160 个输出分片,预计张量数据 **631.84 GiB**。原始目录按真实张量计算为 641.29 GiB(含 MTP);源索引的 total_size 元数据偏大,脚本不使用该值估算转换空间。
## 首次部署参数
转换后可运行提供的启动示例:
```bash
bash /mnt/data1/quant_tools/deepseek_r1_kunlun_int8/serve_int8.sh
```
示例使用 TP=8、BF16、eager 模式、4096 上下文、单并发,每卡 KV cache 显式分配 4 GiB。
`VLLM_KUNLUN_ENABLE_INT8_BMM=0` 与 BF16 kv_b_proj 一致,不能设置为 1。
首测使用 TP,不沿用原命令中的 `--enable-expert-parallel`;当前 INT8 单体 MoE 路径的 EP 路由和专家重映射未验证。
这是准备好的初始参数,尚未完成完整模型启动或生成测试。
## 已完成的验证与范围
```bash
cd /mnt/data1/quant_tools/deepseek_r1_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/data1/deepseek-r1 \
--report sample_validation_mixed.json
```
- CPU 数值测试与合成检查点转换通过:包括跨分片 scale、非整块维度、全零行、BF16 例外、MTP 排除、配置/索引、断点恢复、源文件保护、拒绝覆盖和缺失投影检查。
- 当前插件的 CPU 配置/参数约定检查通过:MLA 融合投影的 INT8 内核、路由专家 INT8 MoE、scale 乘 127、BF16 ignore 配置和 MLA BF16 权重拆分。测试模拟 TP rank/size,不是完整引擎启动或 XPU 算子执行。
- 九个真实矩阵抽样通过:覆盖五类 MLA 投影、Dense MLP、共享专家、路由专家 gate/down。
初始 absmax INT8 基线中,Dense gate 样本 relative RMSE 为 10.10%,共享专家 gate 为 7.18%。将这两类投影改为 BF16 后,对应样本误差为 0.142% 和 0.152%;最终 INT8 样本误差约为 0.94%–1.99%,满足半个逐行量化步长的舍入误差界。相对误差均以 FP8 乘 block scale 后的 FP32 权重为参考;这些指标不代表任务准确率。
服务器上的 `sample_validation.json` 保存初始基线,`sample_validation_mixed.json` 保存最终策略结果。
这是从已量化 FP8 再转换的基线方案;全量转换、P800 推理及实际任务质量仍需分别验证。
## 2026-10-29 MLA 初始化问题及绕过
完整部署发现当前 FlashMLAImpl 缺少 vLLM 所要求的 forward_mha/forward_mqa,无法实例化。此前 CPU 权重准备检查未覆盖这个实例化步骤。权重无需重新转换。
新增 serve_int8_no_mla.sh,通过 VLLM_MLA_DISABLE=1 选择 DeepseekV2Attention 和昆仑芯普通 Attention,绕过不完整的 FlashMLA 接口;保持 TP=8、不启用 EP、eager、单并发、4096 上下文和每卡 4 GiB KV cache。关闭 MLA 增加 KV cache 开销,可能降低吞吐。该路径尚未经过完整模型启动和输出验证。
在容器内运行:
```bash
bash /mnt/data1/quant_tools/deepseek_r1_kunlun_int8/serve_int8_no_mla.sh
```