「此路是我开」国产昆仑芯 P800 部署线性注意力大模型的 28 个问题

一、引言

在国产 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.accelerator mock 不可依赖,必须回到厂商适配路径。
  • 模型路径简写触发 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_memcpy kernel 在昆仑芯报 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 预算 OOM0.9→0.75
性能/正确性GDN 占 decode 89%主战场在 GDN
MTPeagle.py vs vLLM 0.15.111 个接口雷
MTPblock_table_tensor_cpu属性缺失
MTPspec conv kernelillegal memory access
MTP两步 workaround 崩塌与 update_states 冲突
MTPxbfloat16 C1符号缺失
MTP31 参 gated_delta_net依赖 xmlir 20260428
MTPPR#423 in-place 假设与 0.1.122 API 不符
MTPXMLIR_DYNAMO_WORKAROUND投机解码同样依赖
算子深挖xspeedgate_ops recurrent略低于 kunlun_ops
算子深挖torch einsum 参考0.9ms/层,融合快 2-3 倍
算子深挖low-rank GDN UV staterank-1 缓存,非 SVD
算子深挖conv vs recurrentconv 是 recurrent 2 倍
基础设施pkill -f匹配自身命令行自杀
基础设施kill -9 残留Free memory 不足
基础设施XCCL 队列损坏定位 4 张坏卡
基础设施TP=4 反超 TP=81736 vs 1616 tok/s