cann-recipes-infer:DeepSeek 模型在昇腾上的推理部署实战
DeepSeek 系列模型自发布以来,凭借其卓越的推理能力和极具竞争力的性价比,迅速成为大模型落地部署的热门选择。DeepSeek-V2、DeepSeek-V3 等模型采用 MoE(Mixture of Experts)架构,在保持模型总参数量庞大的同时,每个 token 仅激活部分专家网络,实现了推理成本的大幅降低

背景与挑战
DeepSeek 系列模型自发布以来,凭借其卓越的推理能力和极具竞争力的性价比,迅速成为大模型落地部署的热门选择。DeepSeek-V2、DeepSeek-V3 等模型采用 MoE(Mixture of Experts)架构,在保持模型总参数量庞大的同时,每个 token 仅激活部分专家网络,实现了推理成本的大幅降低。
然而,将 DeepSeek 模型部署到昇腾 NPU 上进行高效推理,面临着一系列技术挑战:
MoE 架构的稀疏激活特性对推理框架提出了特殊要求。与传统 Dense 模型不同,MoE 模型在每个推理步骤中只激活少部分专家(如 DeepSeek-V2 中每 token 仅激活 2 个专家),这要求推理系统能够高效地管理和调度多个专家模块,避免专家之间的通信开销成为性能瓶颈。
显存管理压力同样不容忽视。尽管 MoE 架构通过稀疏激活降低了计算量,但所有专家的权重仍需常驻显存。以 DeepSeek-V2 为例,其总参数量达到 236B,即使采用量化技术,对显存的需求依然可观。
Attention 计算效率是影响推理性能的关键因素。DeepSeek 系列模型通常采用 MLA(Multi-head Latent Attention)或类似的注意力机制,这对 KV Cache 的管理和 Attention 算子的融合优化提出了更高要求。
昇腾CANN(Compute Architecture for Neural Networks)作为昇腾异构计算架构,提供了从驱动到上层框架的完整软件栈。cann-recipes-infer 仓库正是基于昇腾CANN,为 DeepSeek 等大模型提供了一套开箱即用的推理部署方案。
环境准备与依赖安装
在开始部署之前,需要准备昇腾 NPU 运行环境。本章节假设您已经具备一台配备 Ascend 910 处理器的服务器,并已完成昇腾CANN 基础驱动和固件安装。
1. 确认昇腾CANN 版本
cann-recipes-infer 对昇腾CANN 版本有明确要求。推荐使用昇腾CANN 7.0 及以上版本,以获得最佳的 MoE 模型支持。
# 查看昇腾CANN 版本
npu-smi info
执行上述命令后,您将看到 NPU 设备信息,包括驱动版本、固件版本等。请记录下这些信息,以便后续问题排查。
2. 安装 Python 依赖
cann-recipes-infer 基于 Python 开发,依赖多个开源库。建议使用 Conda 创建独立的虚拟环境,避免依赖冲突。
# 创建虚拟环境
conda create -n cann-infer python=3.9
conda activate cann-infer
# 安装 PyTorch (昇腾适配版)
# 注意:此处必须使用昇腾官方提供的 PyTorch 适配版本
pip install torch==2.1.0 torch-npu==2.1.0 -f https://download.pytorch.org/whl/cpu/torch_stable.html
代码解释:
- 第 2 行:创建 Python 3.9 的虚拟环境,命名为
cann-infer - 第 3 行:激活该虚拟环境
- 第 7 行:安装 PyTorch 2.1.0 及对应的昇腾 NPU 适配扩展
torch-npu
重要提醒:PyTorch 的版本必须与 torch-npu 版本严格匹配,否则会出现兼容性问题。昇腾官方通常会提供版本对应表,请务必参照官方文档进行安装。
3. 克隆 cann-recipes-infer 仓库
git clone https://atomgit.com/cann/cann-recipes-infer.git
cd cann-recipes-infer
pip install -r requirements.txt
代码解释:
- 第 1 行:从 AtomGit 克隆 cann-recipes-infer 仓库到本地
- 第 2 行:进入仓库目录
- 第 3 行:安装仓库指定的 Python 依赖包
依赖安装完成后,您可以在 cann-recipes-infer 目录下看到多个子目录,包括 models、kernels、configs 等,分别存放模型定义、算子实现和配置文件。
核心技术解析
cann-recipes-infer 针对 DeepSeek 模型的特性,实现了多项关键技术优化。本章节将深入解析这些技术的原理和实现方式。
EP 并行(Expert Parallelism)
MoE 模型的核心特点是稀疏激活,即每个 token 在前馈网络(FFN)层只经过少数几个专家的处理。EP 并行正是利用这一特性,将不同的专家分布到不同的 NPU 设备上,实现模型并行推理。
在 DeepSeek 模型中,EP 并行的实现涉及以下关键步骤:
-
专家分配:根据专家的索引,将其分配到不同的 NPU 设备。通常遵循负载均衡原则,尽量让每个设备承载的专家数量相近。
-
Token 路由:对于每个输入的 token,通过路由网络(Router Network)计算其应该发送给哪些专家。路由网络通常是一个简单的线性分类器,输出每个 token 对每个专家的亲和度分数。
-
跨设备通信:将 token 发送给对应的专家所在设备,并在计算完成后收集结果。这一过程通常使用 All-to-All 通信原语实现。
cann-recipes-infer 中 EP 并行的核心配置位于 configs/deepseek/ep_config.json:
{
"ep_size": 8,
"num_experts": 160,
"top_k": 2,
"capacity_factor": 1.25,
"expert_parallel_mode": "all_to_all",
"communication_dtype": "fp16"
}
配置解释:
- 第 2 行:
ep_size表示用于 EP 并行的 NPU 设备数量,此处为 8 卡并行 - 第 3 行:
num_experts表示模型中的专家总数,DeepSeek-V2 为 160 个专家 - 第 4 行:
top_k表示每个 token 激活的专家数量,DeepSeek-V2 中每个 token 激活 2 个专家 - 第 5 行:
capacity_factor表示每个设备允许处理的 token 容量因子,用于负载均衡 - 第 6 行:
expert_parallel_mode指定 EP 并行使用的通信模式,all_to_all表示使用 All-to-All 通信 - 第 7 行:
communication_dtype指定通信时使用的精度,使用 fp16 可降低通信带宽需求
EP 并行的优势在于显著降低了单个 NPU 设备的显存压力。假设模型有 160 个专家,分布在 8 个 NPU 上,每个 NPU 只需存储约 20 个专家的权重,显存占用降至原来的 1/8。
KV Cache 优化:PageAttention 与动态显存分配
在自回归生成模型中,KV Cache 是用于存储 Attention 计算中 Key 和 Value 张量的缓存机制。随着生成序列长度的增加,KV Cache 占用的显存会线性增长,成为推理性能的主要瓶颈之一。
cann-recipes-infer 引入了 PageAttention 机制,将 KV Cache 划分为固定大小的"页"(Page),通过动态显存分配的方式管理这些页。
PageAttention 的核心思想:
- 将 KV Cache 分割成多个固定大小的块(如每块存储 16 个 token 的 KV 值)
- 使用页表(Page Table)记录逻辑 token 位置到物理显存块的映射关系
- 当生成新 token 时,动态分配新的显存页;当 token 被截断或丢弃时,释放对应的显存页
这种机制避免了传统 KV Cache 管理中预先分配连续显存导致的碎片问题,提高了显存利用率。
在 cann-recipes-infer 中,PageAttention 的配置位于 configs/deepseek/model_config.json:
{
"use_paged_attention": true,
"block_size": 16,
"max_num_blocks": 2048,
"kv_cache_dtype": "fp16",
"enable_kv_cache_quant": false
}
配置解释:
- 第 2 行:启用 PageAttention 机制
- 第 3 行:每个显存块存储 16 个 token 的 KV Cache
- 第 4 行:最多允许分配 2048 个显存块,对应最大序列长度为 32768(2048 × 16)
- 第 5 行:KV Cache 的数据精度为 fp16
- 第 6 行:暂不启用 KV Cache 量化(量化可进一步降低显存占用,但可能轻微影响精度)
ATB 融合算子:提升 Attention 计算效率
ATB(Ascend Transformer Boost)是昇腾CANN 提供的 Transformer 加速库,专为优化 Transformer 系列模型的推理性能而设计。ATB 提供了多种融合算子,将多个计算密集型操作合并为单个算子执行,减少了内存读写和内核启动开销。
对于 DeepSeek 模型,ATB 提供了以下关键融合算子:
-
Attention 融合算子:将 QKV 投影、Attention 分数计算、输出投影等多个操作融合为一个算子,显著降低了 Attention 层的计算延迟。
-
MoE 融合算子:将专家路由、专家计算、结果加权求和等操作融合,减少了 MoE 层的通信和计算开销。
-
LayerNorm 融合算子:将 LayerNorm 与前后操作融合,降低数据搬运开销。
在 cann-recipes-infer 中,启用 ATB 融合算子的配置如下:
# configs/deepseek/enable_atb.py
from atb_speed import get_atb_speed_ops
# 启用 ATB Attention 融合算子
enable_atb_attention = True
# 启用 ATB MoE 融合算子
enable_atb_moe = True
# 配置 ATB 算子精度模式
atb_precision_mode = "fp16"
# 获取 ATB 融合算子
atb_ops = get_atb_speed_ops(
model_type="deepseek",
enable_attention=enable_atb_attention,
enable_moe=enable_atb_moe,
precision=atb_precision_mode
)
代码解释:
- 第 6 行:导入 ATB 算子获取接口
- 第 9 行:启用 ATB Attention 融合算子
- 第 12 行:启用 ATB MoE 融合算子
- 第 15 行:设置 ATB 算子精度模式为 fp16
- 第 17-22 行:调用
get_atb_speed_ops函数获取配置好的 ATB 融合算子,该函数会根据模型类型和启用的功能返回对应的算子列表
模型准备与转换
DeepSeek 模型最初通常以支持 CUDA 的 PyTorch 格式发布。要在昇腾 NPU 上运行,需要将其转换为昇腾CANN 支持的格式。cann-recipes-infer 提供了自动化的模型转换脚本。
1. 下载 DeepSeek 原始模型
# 使用 ModelScope 下载 DeepSeek-V2 模型
modelscope download --model deepseek-ai/deepseek-v2 --local_dir ./models/deepseek-v2
代码解释:
- 使用 ModelScope 工具下载 DeepSeek-V2 模型
--model指定模型名称--local_dir指定模型下载后的本地存储路径
2. 模型格式转换
下载完成后,需要将模型转换为昇腾 NPU 可用的格式。cann-recipes-infer 提供了 convert_model.py 脚本完成这一任务。
python convert_model.py \
--input_dir ./models/deepseek-v2 \
--output_dir ./models/deepseek-v2-npu \
--target_platform npu \
--precision fp16 \
--enable_moe_optimization
参数解释:
--input_dir:原始模型所在目录--output_dir:转换后模型的输出目录--target_platform:目标平台,此处为npu(昇腾 NPU)--precision:转换后的模型精度,使用 fp16 可在精度损失可接受的前提下提升推理速度--enable_moe_optimization:启用 MoE 专用优化,包括专家权重重排、路由算法优化等
转换过程会执行以下操作:
- 读取原始模型的权重文件(通常为
pytorch_model-*.bin或model.safetensors) - 将权重数据类型转换为目标精度(如 fp32 → fp16)
- 对 MoE 层的专家权重进行重排,优化内存访问模式
- 生成昇腾 NPU 专用的模型配置文件
- 将转换后的权重保存到输出目录
推理部署实战
完成环境准备和模型转换后,即可开始推理部署。cann-recipes-infer 提供了多种部署方式,包括本地部署、API 服务部署等。本章节以本地部署为例,演示如何启动 DeepSeek 模型的推理服务。
1. 编写推理配置文件
推理配置文件定义了模型路径、并行策略、KV Cache 设置等关键参数。在 cann-recipes-infer 中,配置文件采用 JSON 格式。
创建配置文件 configs/deepseek/infer_config.json:
{
"model": {
"model_path": "./models/deepseek-v2-npu",
"model_type": "deepseek_v2",
"vocab_size": 102400,
"hidden_size": 4096,
"intermediate_size": 11008,
"num_hidden_layers": 32,
"num_attention_heads": 32,
"num_key_value_heads": 32,
"max_position_embeddings": 163840,
"rope_theta": 10000
},
"parallel": {
"tensor_parallel_size": 1,
"pipeline_parallel_size": 1,
"expert_parallel_size": 8
},
"kv_cache": {
"use_paged_attention": true,
"block_size": 16,
"max_num_blocks": 2048
},
"atb": {
"enable_atb_attention": true,
"enable_atb_moe": true,
"precision_mode": "fp16"
},
"inference": {
"max_batch_size": 32,
"max_seq_len": 4096,
"do_sample": true,
"temperature": 0.7,
"top_p": 0.95,
"top_k": 50,
"repetition_penalty": 1.1
}
}
配置解释:
model 部分(第 3-14 行):
model_path:转换后的模型路径model_type:模型类型,此处为 DeepSeek-V2vocab_size:词表大小hidden_size:隐藏层维度intermediate_size:FFN 中间层维度num_hidden_layers:Transformer 层数num_attention_heads:Attention 头数num_key_value_heads:KV 头数(用于 Grouped Query Attention)max_position_embeddings:最大位置编码长度rope_theta:RoPE 位置编码的 theta 参数
parallel 部分(第 15-19 行):
tensor_parallel_size:张量并行度,此处为 1(不启用 TP)pipeline_parallel_size:流水线并行度,此处为 1(不启用 PP)expert_parallel_size:专家并行度,此处为 8(启用 8 卡 EP 并行)
kv_cache 部分(第 20-24 行):
- 配置与之前章节介绍的 PageAttention 设置相同
atb 部分(第 25-29 行):
- 配置与之前章节介绍的 ATB 融合算子设置相同
inference 部分(第 30-38 行):
max_batch_size:最大批次大小max_seq_len:最大生成序列长度do_sample:是否使用采样解码(否则使用贪婪解码)temperature:采样温度top_p:核采样参数top_k:Top-K 采样参数repetition_penalty:重复惩罚系数
2. 启动推理服务
使用 cann-recipes-infer 提供的 run_infer.py 脚本启动推理服务:
python run_infer.py \
--config configs/deepseek/infer_config.json \
--mode local \
--npu_devices 0,1,2,3,4,5,6,7
参数解释:
--config:指定推理配置文件路径--mode:部署模式,local表示本地部署(也支持api模式,提供 HTTP API 服务)--npu_devices:指定使用的 NPU 设备编号,此处使用 8 张 Ascend 910 卡
脚本启动后,会加载模型权重、初始化并行策略、预热 ATB 算子等。加载完成后,您可以在终端看到类似以下的日志输出:
[INFO] Loading model from ./models/deepseek-v2-npu...
[INFO] Model loaded successfully in 12.3 seconds.
[INFO] Initializing EP parallel with 8 NPU devices...
[INFO] EP parallel initialized. Experts distributed: 20 per device.
[INFO] Loading ATB fused operators...
[INFO] ATB operators loaded. Attention fusion: enabled, MoE fusion: Enabled.
[INFO] Warming up inference...
[INFO] Warmup completed in 3.7 seconds.
[INFO] DeepSeek-V2 inference service started. Ready to accept requests.
3. 执行推理请求
推理服务启动后,可以通过 Python 脚本或命令行工具发送推理请求。
创建测试脚本 test_infer.py:
# test_infer.py
from cann_recipes_infer import InferenceEngine
# 初始化推理引擎
engine = InferenceEngine(
config_path="configs/deepseek/infer_config.json"
)
# 准备输入提示
prompt = "请介绍一下昇腾CANN 的主要特点。"
# 执行推理
output = engine.generate(
prompt=prompt,
max_new_tokens=512,
temperature=0.7,
top_p=0.95,
stream=False
)
# 输出结果
print("模型输出:")
print(output)
代码解释:
- 第 4 行:从 cann-recipes-infer 导入推理引擎类
- 第 7-9 行:初始化推理引擎,传入配置文件路径
- 第 12 行:定义输入提示
- 第 15-21 行:调用
generate方法执行推理prompt:输入提示文本max_new_tokens:最大生成 token 数temperature、top_p:解码参数stream:是否使用流式输出(False表示非流式,一次性返回完整结果)
- 第 24-25 行:打印模型输出结果
运行测试脚本:
python test_infer.py
稍等片刻,您将看到模型生成的输出结果。
性能测试与优化
部署完成后,需要对推理性能进行测试,评估吞吐、延迟、显存占用等关键指标,并根据测试结果进行针对性优化。
性能测试工具
cann-recipes-infer 提供了 benchmark.py 脚本,用于自动化性能测试。
python benchmark.py \
--config configs/deepseek/infer_config.json \
--dataset ./datasets/test_prompts.json \
--num_samples 100 \
--warmup 10
参数解释:
--config:推理配置文件--dataset:测试数据集路径,包含多个测试提示--num_samples:测试样本数量--warmup:预热样本数量(预热阶段不计入性能统计)
性能指标解读
在 Ascend 910 八卡配置下,DeepSeek-V2 推理的典型性能指标如下:
| 指标 | 数值 | 说明 |
|---|---|---|
| 吞吐量(Throughput) | 约 1200-1500 tokens/s | 所有 NPU 设备合计每秒生成的 token 数 |
| 首 Token 延迟(TTFT) | 约 35-50 ms | 从发送请求到生成第一个 token 的时间 |
| 每 Token 延迟(TPOT) | 约 15-20 ms | 生成每个 token 的平均时间 |
| 显存占用(每卡) | 约 32-38 GB | 包括模型权重、KV Cache、临时激活值等 |
性能优化建议:
-
调整 EP 并行度:如果单卡显存占用过高,可以增加 EP 并行度(如从 8 卡增加到 16 卡),降低每卡存储的专家数量。
-
启用 KV Cache 量化:将
enable_kv_cache_quant设置为true,使用 int8 或 int4 量化 KV Cache,可显著降低显存占用,但可能轻微影响长序列生成质量。 -
优化 ATB 算子精度:如果推理任务对精度要求不高,可以尝试
precision_mode设置为fp16或bf16,相比 fp32 可获得更快的计算速度。 -
调整批次大小:增大
max_batch_size可提高吞吐量,但会增加显存占用和延迟。需要根据实际场景(如在线服务 vs 离线批处理)进行权衡。
典型应用场景
DeepSeek 模型在昇腾 NPU 上的推理部署,适用于多种应用场景。以下列举几个典型场景:
智能客服系统
在智能客服场景中,模型需要实时响应用户咨询,对首 Token 延迟(TTFT)要求较高。建议配置:
- 使用流式输出(
stream=True),提升用户感知的响应速度 - 适当降低
max_seq_len,减少显存占用 - 启用
repetition_penalty,避免生成重复回答
内容创作辅助
内容创作场景通常对生成质量要求较高,对延迟相对不敏感。建议配置:
- 使用较高的
temperature(如 0.8-1.0),增加生成多样性 - 增大
max_new_tokens,支持生成长篇文章 - 启用 KV Cache 量化,支持更长上下文窗口
代码生成与补全
代码生成场景对模型的语法正确性和逻辑推理能力要求较高。建议配置:
- 使用较低的
temperature(如 0.3-0.5),提高生成准确性 - 启用
top_p采样,过滤低概率 token - 增大
vocab_size对应的词表,确保代码特殊字符的正确编码
留个思考题
在阅读完本文后,您可以思考以下问题:
问题:在 EP 并行(Expert Parallelism)中,如果某个 NPU 设备上的专家被频繁激活(即出现"热门专家"),会导致该设备的负载显著高于其他设备,进而影响整体推理性能。请思考:cann-recipes-infer 是如何通过 capacity_factor 和动态专家重平衡机制来解决这一问题的?如果需要您设计一个优化的专家路由算法,会考虑哪些因素?
欢迎在评论区分享您的思考,或查阅 cann-recipes-infer 源码中的 routing_strategy.py 文件,了解具体的实现细节。
参考资料:
- cann-recipes-infer 仓库:https://atomgit.com/cann/cann-recipes-infer
- 昇腾CANN 官方文档:https://www.hiascend.com/document
- DeepSeek 官方仓库:https://github.com/deepseek-ai/DeepSeek-V2
- ATB(Ascend Transformer Boost)用户指南:昇腾社区文档中心
更多推荐




所有评论(0)