去年底接了个活:把 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 倍提升。


下一步

  1. 先 profile——msprof 跑一遍,看瓶颈在哪
  2. 开 FlashAttention + PagedAttention——基操,不开亏 50%+
  3. 调 Batch——别无脑拉满,看场景选
  4. 试量化——精度敏感用 W8A16,不敏感上 W8A8C16
  5. 源码
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐