一、引言
在国产 XPU 上部署大模型,常被问一句"能不能跑"。这次项目的回答是:能跑,但从"能跑"到"跑好",隔着 28 个问题,分属 6 类。本文先画地图:问题长什么样、分布在哪里、哪里最容易翻车。
二、部署背景
单机 8×96G 昆仑芯 P800-OAM,vllm-kunlun,Qwen3.8-27B-INT8-W8A8-Dynamic(qwen3_5),原生 262144(256K)上下文,TP=8 单实例,OpenAI 兼容 API。模型 64 层:48 层 linear_attn(Gated DeltaNet/GDN,线性注意力,无 KV cache)+ 16 层 full_attention,MTP 权重内嵌;主战场在线性注意力算子。
三、28 个问题的六类地图
1. 环境/平台(4)
- 容器 8 卡映射:需先核对,否则 TP=8 初始化失败。
torch.xpu.device_count()返回 0 是误导:昆仑芯 torch251 为 CUDA 兼容模式,真实后端是torch.cuda。torch.acceleratormock 不可依赖,必须回到厂商适配路径。- 模型路径简写触发 HFValidationError,须给完整路径或仓库格式。
2. 版本兼容(4)
- kunlun_ops 0.1.58 与新源码不兼容:causal_conv1d 参数 + 11 缺失算子 + 3 KW_MISMATCH(issue #387 同款)。
- transformers 5.5.3 缺 max_pixels,必须降级 5.2.0。
- kunlun_ops 0.1.122 必须配 xmlir 1.0.0.1 的 20260428 版;0409 版缺 31 参 xfa::gated_delta_net。
- xmlir 升级后必须
XMLIR_DYNAMO_WORKAROUND=1,否则 torch.compile 在 make_tensors_stateful 上报 Unsupported。
3. 性能/正确性(4)
- 采样器
exponential_CPU fallback:256 batch×152K vocab 实测 4.89 s/step,GPU 占用 0%。 - prefix-caching 的 triton
batch_memcpykernel 在昆仑芯报CUDA_ERROR_NOT_SUPPORTED,改用指针视图copy_。 - KV 预算 OOM:
gpu-memory-utilization从 0.9 降到 0.75 才稳住。 - GDN 占 decode 89%,性能优化重点即线性注意力算子本身。
4. MTP 投机解码(8)
- eagle.py 与 vLLM 0.15.1 接口不匹配,共 11 个雷。
block_table_tensor_cpu属性缺失。- kunlun_ops 0.1.58 spec conv kernel 在 num_accepted=[1]、seq_len=2 时触发 illegal memory access。
- 两步 workaround 后并发接受率崩塌,根因是提前回滚 draft state 与 vllm
update_states冲突。 - xbfloat16 C1 符号缺失。
- 31 参 gated_delta_net 缺失。
- PR#423 假设 in-place 签名,与 0.1.122 实际 API 不符。
XMLIR_DYNAMO_WORKAROUND同为投机解码依赖项。
5. 算子深挖(4)
- 独立于官方、使用汇编编写的算子库和运行库(xspeedgate_ops)实现 recurrent,实测略低于 kunlun_ops。
- 纯 torch einsum 参考实现 batch=64 需 0.9 ms/层,官方融合 kernel 快 2-3 倍。
- low-rank GDN 的 UV state 是 sliding-window rank-1 缓存,非 SVD 分解;随机投影初始化失败,SVD 在 XPU 上 5 秒/次不可用。
- conv kernel 0.45 ms/层,是 recurrent 0.23 ms/层的 2 倍。
6. 基础设施(4)
pkill -f匹配到自身命令行导致自杀,是运维脚本里的一行"背刺"。- 服务
kill -9后 EngineCore/Worker 残留占显存,下次启动报 Free memory 不足。 - XCCL 通信队列损坏,卡对诊断定位出 4 张坏卡。
- TP=4 降级后 256 并发 1736 tok/s,反超 TP=8 的 1616 tok/s。
四、关键数据
权威口径 short 512/512×256 并发为 3201.71 output tok/s,稳态峰值 4851 tok/s。单流 decode 约 200 tok/s(端到端 overall 57)。MTP + FP16_FAST_OPT=3 后单流 55-59 tok/s(overall 口径)、256 并发 1609-1622 tok/s。XCCL allreduce 2.6MB 单轮 0.13 ms,约 19.3 GB/s。并发吞吐已经可看,单流延迟与算子边界仍待打磨。
五、结论
地图上的规律很清楚:版本配对是入口,算子缺口是主战场,投机解码是深水区,基础设施是暗坑。国产 XPU 生态的现状,就是"能跑"和"跑好"之间隔着大量版本配对、算子缺口、kernel 边界。后来者按这张地图走,至少知道下一脚会踩在哪里。
附:28 个问题速查表
| 分类 | 问题 | 结论 |
|---|---|---|
| 环境/平台 | 容器 8 卡映射 | 先核对映射 |
| 环境/平台 | torch.xpu.device_count()=0 | 真实后端 torch.cuda |
| 环境/平台 | torch.accelerator mock | 走厂商路径 |
| 环境/平台 | 模型路径简写 | 用完整路径 |
| 版本兼容 | kunlun_ops 0.1.58 | 与新源码不兼容 |
| 版本兼容 | transformers 5.5.3 | 降 5.2.0 |
| 版本兼容 | kunlun_ops 0.1.122 + xmlir | 须 20260428 版 |
| 版本兼容 | xmlir 升级 | XMLIR_DYNAMO_WORKAROUND=1 |
| 性能/正确性 | 采样器 exponential_ | CPU fallback 4.89s/step |
| 性能/正确性 | prefix-caching batch_memcpy | 改指针视图 copy_ |
| 性能/正确性 | KV 预算 OOM | 0.9→0.75 |
| 性能/正确性 | GDN 占 decode 89% | 主战场在 GDN |
| MTP | eagle.py vs vLLM 0.15.1 | 11 个接口雷 |
| MTP | block_table_tensor_cpu | 属性缺失 |
| MTP | spec conv kernel | illegal memory access |
| MTP | 两步 workaround 崩塌 | 与 update_states 冲突 |
| MTP | xbfloat16 C1 | 符号缺失 |
| MTP | 31 参 gated_delta_net | 依赖 xmlir 20260428 |
| MTP | PR#423 in-place 假设 | 与 0.1.122 API 不符 |
| MTP | XMLIR_DYNAMO_WORKAROUND | 投机解码同样依赖 |
| 算子深挖 | xspeedgate_ops recurrent | 略低于 kunlun_ops |
| 算子深挖 | torch einsum 参考 | 0.9ms/层,融合快 2-3 倍 |
| 算子深挖 | low-rank GDN UV state | rank-1 缓存,非 SVD |
| 算子深挖 | conv vs recurrent | conv 是 recurrent 2 倍 |
| 基础设施 | pkill -f | 匹配自身命令行自杀 |
| 基础设施 | kill -9 残留 | Free memory 不足 |
| 基础设施 | XCCL 队列损坏 | 定位 4 张坏卡 |
| 基础设施 | TP=4 反超 TP=8 | 1736 vs 1616 tok/s |