DeepSeek / Qwen 大模型在昇腾上的推理优化实战
【昇腾910B大模型部署优化实战】针对DeepSeek-V3和Qwen2.5-72B在昇腾910B集群的部署,发现初始吞吐仅为GPU的60%。通过系统优化实现276%性能提升,关键发现:1)CANN与CUDA优化逻辑差异大,需重构Attention计算和显存管理;2)FlashAttention+PagedAttention+W8A16量化组合使DeepSeek-V3吞吐从580TPS提升至218
去年底接了个活:把 DeepSeek-V3 和 Qwen2.5-72B 部署到昇腾 910B 集群上。客户说"GPU 上跑得好好的,换昇腾应该也行吧"。结果第一天就被砸懵——同样的模型、同样的 batch,昇腾上吞吐只有 GPU 的 60%。不是算力不够,是我根本没搞清楚 CANN 的优化逻辑和 CUDA 完全是两套体系。
很多人以为昇腾上跑大模型就是"把 CUDA 代码编译一下扔给 CANN",其实从 Attention 到显存管理,每个环节的优化路径都不一样。
工程经验:DeepSeek-V3 初次部署到昇腾 910B,未开优化时 decode 吞吐 580 TPS。开完 FlashAttention + PagedAttention + W8A16 量化,到 2180 TPS,涨了 276%。不是算力不够,是默认配置没打开昇腾的加速特性。
推理瓶颈:先 profile 再动手
一上来就改算子调参数,优化半天发现瓶颈在数据搬运。CANN 自带的 msprof 跑一次就知道瓶颈在哪:
我第一次 profile DeepSeek-V3:Attention 计算 38%、KV Cache 访存 27%、MoE Router+AllReduce 19%、其他 16%。
为什么 GPU 方案不能直接复用?GPU 上 Attention 占比通常 50%+,瓶颈在计算;昇腾 Cube 的 MAC 阵列算矩阵乘效率高,但 Vector 做逐元素运算的吞吐比 GPU 的 SM 低——softmax、scale 这些逐元素操作反而成瓶颈。GPU 优化 MatMul 就够;昇腾得同时优化计算和访存。
Attention 优化:FlashAttention 只是起点
ops-transformer 里的 FlashAttention 算子针对达芬奇架构做了 Cube/Vector 流水线优化:Cube 算 Q×K^T → Vector 算 scale+mask+softmax → Cube 算 P×V,中间数据走 L1 不落 HBM。
| 模型 | 未融合 | FlashAttention | 提升 |
|---|---|---|---|
| Qwen2.5-7B (seq=2048) | 34 tokens/s | 89 tokens/s | 162% |
| DeepSeek-V3-671B (seq=4096) | 580 TPS | 1420 TPS | 145% |
DeepSeek-V4 更激进——CSA(4倍压缩)和 HCA(128倍压缩)交替使用。128K 序列下 HCA 把 KV Cache 从 7.3GB 压到 57MB,TPOT < 10ms(950DT,16卡)。不压缩的 Full Attention 同场景 TPOT > 80ms。
工程经验:CSA/HCA 压缩率不是越大越好。128 倍压缩(HCA)长序列收益明显,但短序列(<4K)反而比 Full Attention 慢 12%——Compressor 本身有计算开销。我们的做法:前两层用 Window Attention(sliding_window=128),中间层按序列长度动态选 CSA 或 HCA。
KV Cache 优化:省显存是手段,涨 batch 才是目的
Qwen2.5-7B,FP16 下每个 token 的 KV Cache 约 57KB。seq=2048、batch=32 时光 KV Cache 就吃 3.6GB。
三条优化路:
PagedAttention:MindIE 推理引擎支持,KV Cache 分 block 按需分配,消碎片。
KV Cache 量化:INT8 存 KV Cache,显存省一半。910B 实测:3.6GB → 1.8GB,省出 1.8GB 多跑 16 个 batch。
KV Cache 压缩:DeepSeek-V4 的 HCA 128倍压缩,128K 序列 KV Cache 57MB。
很多人以为 KV Cache 优化就是省显存。真正的收益是省出的显存能跑更大 batch,更大 batch 吞吐更高。
工程经验:Qwen2.5-7B 在 910B 单卡,FP16 batch=8 吞吐 72 tokens/s;开 KV Cache 量化 + PagedAttention 后 batch 开到 32,吞吐 147 tokens/s。算力没变,显存够用了,batch 从 8 涨到 32,吞吐涨 104%。
算子融合:省 Task 调度开销
昇腾上每次算子下发走 ACL→GE→Runtime 调用链,开销 12-15μs。30 层 Transformer 几百次调用,光调度开销就 3-5ms。
CANN 的 graph-autofusion 自动融合框架:LayerNorm+MatMul、Softmax+Dropout+MatMul、GatingTopK 等。DeepSeek-V4 专门做了 SAS(统一 Window/Sparse/Compress Attention)、Compressor、HCPre/HCPost 融合 Kernel,已开源在 cann-recipes-infer。
工程经验:DeepSeek-V4 MoE 的 GatingTopK 融合前 router 输出落 HBM 再给 topk 读,融合后直接 L1 传数据,省一次 HBM 读写。单层省 18μs,40 层省 720μs。decode 每个token 快 0.7ms,1000 个token 差 0.7 秒。
显存管理 + Batch 调优
昇腾 HBM 管理跟 GPU 不一样。GPU 的 caching allocator 基本是"申请-使用-释放";昇腾的 DMA 引擎要求显存预分配、零碎片、复用中间 buffer。
实测带宽利用率:动态申请释放 35% → 预分配+复用 82%。910B 的 1.2TB/s 带宽,82% 是 984GB/s 可用,35% 只有 420GB/s——差一倍多。
Batch 调优也不是越大越好。batch 越大 Attention 的 S 矩阵越大,L1 装不下就溢出:
| batch | 吞吐 (tokens/s) | TTFT (ms) | 显存 (GB) |
|---|---|---|---|
| 4 | 52 | 78 | 16.8 |
| 8 | 72 | 120 | 20.1 |
| 32 | 147 | 380 | 39.2 |
| 64 | 138 | 720 | OOM |
batch=64 吞吐反而降——KV Cache swap 到 Host 内存。选 batch 看场景:在线对话 batch=4-8(TTFT<100ms),离线批处理 batch=16-32。我们的做法是动态 batch:短输入 batch=32,长输入 batch=8。
量化:最后一板斧
| 量化方案 | 适用芯片 | 精度损失 | 性能收益 |
|---|---|---|---|
| W8A16 | 910B, A3 | <0.5% | 吞吐+45%,显存-30% |
| W8A8C16 | A3 | <1% | 吞吐+85%,显存-45% |
| Hybrid FP8-MXFP4 | 950PR/DT | <1.5% | 吞吐+120%,显存-60% |
DeepSeek-V4 Flash 在 950DT(16卡,128K):Hybrid FP8-MXFP4 TPOT<10ms,FP16 约 35ms,3.5 倍提升。
下一步
- 先 profile——
msprof跑一遍,看瓶颈在哪 - 开 FlashAttention + PagedAttention——基操,不开亏 50%+
- 调 Batch——别无脑拉满,看场景选
- 试量化——精度敏感用 W8A16,不敏感上 W8A8C16
- 源码:
更多推荐




所有评论(0)