cann-recipes-infer 新 LLM 模型合入指南:功能精度验证与仓库规则约束的完整 Checklist
【免费下载链接】cann-recipes-infer本项目针对LLM与多模态模型推理业务中的典型模型、加速算法,提供基于CANN平台的优化样例项目地址: https://gitcode.com/cann/cann-recipes-infer
本文基于 docs/common/new_model_checklist.md 整理,将 cann-recipes-infer 仓库中新 LLM 模型的合入流程拆解为可执行的两大部分:功能与精度验证(离线/在线推理、KV Cache 管理、Packed Sequence、npugraph_ex 图模式与数据集评分),以及版本统一、环境变量、YAML 自定义字段、量化、命名、公共代码修改等仓库规则约束。读完本文后,你可以在接入一个新模型时,逐项核对模型目录结构、YAML 配置、Cache 适配与文档产物是否满足仓库的合入标准。
一、功能与精度验证
Checklist 的第一部分回答“这个模型在当前框架上到底跑没跑对、跑得好不好”,共包含基础接入、KV Cache 管理、Packed Sequence、npugraph_ex 图模式、Online 推理和数据集评分六个环节。
1. 基础接入:模型目录结构与最小 YAML 集合
基础接入包含两个检查项:
- 检查环境版本,验证模型在对应
README.md中声明的环境下功能和精度正常; - 参考框架对模型的接口契约,在
models/<model_name>/下提供模型实现、配置类、README 文档和 YAML 示例。
从仓库内现有模型(如 models/deepseek_r1)的目录组织看,一个合入标准的模型目录通常形如:
models/<model_name>/ ├── config/ # 启动用 YAML 配置,含 <model_name>_pd/ 在线配置子目录 ├── models/ # 模型实现(configuration_xxx.py / modeling_xxx.py 等) ├── utils/ # 权重转换等辅助脚本 ├── README.md # 用户视角的完整使用文档 └── requirements.txt # 依赖声明YAML 配置是模型与框架之间的主要契约,其字段语义由 InferenceConfig 配置指南 定义。Checklist 要求每份 YAML 至少覆盖以下字段:
| 字段 | 说明 |
|---|---|
model_config.model_name | 模型名,用于 tokenizer 加载与模型目录定位 |
model_config.model_path | 权重路径,必须使用占位符(见规则约束部分) |
model_config.exe_mode | 执行模式,可选eager/ge_graph/npugraph_ex,默认eager |
data_config.input_truncated_len | 最大输入序列长度,默认 256,超长 prompt 被截断 |
scheduler_config.batch_size | 全局总 Batch Size,必须为attn_dp_size的整数倍 |
scheduler_config.max_new_tokens | 最大生成 token 数,默认 32 |
scheduler_config.max_prefill_tokens | 单次 prefill batch 的 prompt token 预算,为 0 时按input_truncated_len * batch_size_per_dp_rank计算 |
parallel_config.world_size | 总进程数 |
parallel_config.attn_tp_size、moe_tp_size、embed_tp_size、lmhead_tp_size等 | 按模型实际切分方式配置各层 TP 并行数 |
以仓库中最典型的参考配置 decode_r1_rank_16_16ep_a8w8.yaml 为例,可以看到上述字段与模型特有参数的完整组织方式:
model_config: model_name: "deepseek_r1" model_path: "/data/models/origin/DeepSeek-R1-W8A8" with_ckpt: True # [False, True] exe_mode: "npugraph_ex" # ["eager", "npugraph_ex", "ge_graph"] enable_static_kernel: False # [False, True] Only takes effect in npugraph_ex mode. enable_profiler: False force_eplb: False enable_cache_compile: False custom_params: enable_mla_prolog: True enable_multi_streams: True enable_superkernel: False moe_chunk_max_len: 65536 micro_batch_mode: 0 data_config: dataset: "LongBench" # ["default", "LongBench"] input_truncated_len: 256 parallel_config: world_size: 16 attn_tp_size: 1 dense_tp_size: 1 moe_tp_size: 1 embed_tp_size: 16 lmhead_tp_size: 16 scheduler_config: block_size: 128 max_new_tokens: 100 max_prefill_tokens: 256 batch_size: 64配置好 YAML 后,在 executor/scripts/set_env.sh 中填入各节点 IP(IPs),即可通过统一入口脚本拉起离线推理验证功能:
bash executor/scripts/infer.sh --model deepseek_r1 --mode offline --yaml decode_r1_rank_16_16ep_a8w8.yaml2. KV Cache 管理:框架托管与模型自维护二选一
按 KV Cache 管理设计文档,框架支持两种 Cache 使用方式,新模型二选一:
| 维度 | KVCacheManager管理(推荐) | 模型自行维护 Cache |
|---|---|---|
| 启用条件 | 模型返回ModelCacheInfo元信息 | 模型不返回ModelCacheInfo |
| 初始化入口 | ExecutionEngine._init_cache_manager() | ModelWorker.init_kvcache() |
| Cache 分配 | allocate_cache_tensors()根据CacheEntry分配 | model.init_cache(device)或 legacycache_unit分配 |
| 索引 | 框架提供block_table/slot_mapping | 模型按request_offset、position_ids等自行计算 |
| 调度准入 | allocate_slots()检查 block 是否足够 | 不做 KV slot 准入 |
| 请求释放 | KVCacheManager.free(request_id) | 无统一请求级释放 |
| 适用场景 | online/offline 推理、Paged Attention | 仅 offline、特殊 Cache 布局、暂不接入 Paged Attention |
选择KVCacheManager时,实现落在 executor/core/kv_cache/ 的三层结构中:KVCacheManager做请求级协调与跨 attention 类型的一致性预检查,SingleTypeKVCacheManager负责单一 attention 类型(Full / Sliding Window / Mamba)的逻辑块规划与回收,BlockPool负责物理 block 的发放与回收。调度层通过allocate_slots(request_id, computed_tokens, num_new_tokens, ...)申请块,请求结束由free(request_id)统一释放。
需要特别注意:Online 推理强制依赖框架托管的 Cache 管理(PD 两侧的 KV 传输依赖KVCacheManager.get_contiguous_buf_infos()导出物理 cache 布局),因此如果模型后续要支持 online,必须选择KVCacheManager方式。
3. Packed Sequence:多请求不等长场景的功能与精度验证
Checklist 要求:参考 Packed Sequence 机制设计文档,并在多请求 batch(batch_size_per_dp_rank > 1)且序列不等长的场景下验证功能与输出精度。
框架侧与模型侧的接口约定(见 框架接口契约)是:
- 框架将当前 step 的输入按请求顺序组织为一维
input_ids: [T](T 为批内有效 token 总数),并提供逐 token 对齐的position_ids; ForwardMetaData携带is_prefill、actual_seq_lengths_kv/q(含 cu/list 变体)、block_table、slot_mapping等元数据,模型必须按长度元数据识别请求边界,不能把整个 packed 输入当作一个请求处理;- 模型返回的 logits 按请求组织:Prefill 为
[B, 1, vocab](先取每请求最后位置再算 lm_head),Decode 为[B, q_len, vocab](未启用 MTP 时q_len = 1,启用时q_len = next_n + 1)。
之所以必须验证不等长多请求场景,是因为当batch_size_per_dp_rank > 1时框架才真正走到 packed 拼接路径,padding 缺失下的边界计算、position_ids 对齐、prefill 末位取 logits 等环节都可能暴露问题。
4. npugraph_ex 图模式优化
Checklist 对图模式给出四条硬性验证项:
- 至少有一份 YAML 启用
model_config.exe_mode: npugraph_ex(如 decode_r1_rank_16_16ep_a8w8.yaml); npugraph_ex在 warmup 阶段的首次编译功能正常;- 正式推理时 decode 阶段能直接复用 warmup 编译的图执行,不能出现重编译;
- 使能 MTP 时,主模型和 MTP 模型都能正常编译。
从 executor 架构文档 的图编译流程看,上述要求对应框架的固定时序:ExecutionEngine.warm_up()先执行一次 dummy prefill,随后在 dummy decode 之前调用ModelWorker.compile_model()编译 decode 阶段的执行图,eager 模式则跳过编译。这解释了 checklist 为何强调“decode 复用 warmup 编译的图”——如果模型输入 shape 非静态,warmup 与正式 decode 的形状不一致会触发重编译,使图模式收益失效;接口契约中也明确要求“模型需保证输入 shape 静态”。
5. Online 推理(推荐):先 offline 后 online,交付 PD 双端配置
Online 推理采用 Prefill-Decode 分离部署,设计细节见 online 推理设计文档与 executor 架构文档的在线推理流程。Checklist 的四个检查项:
- 先 offline 后 online:online 必须依赖框架托管的 Cache 管理,且模型必须在 offline 模式下跑通后再适配 online 功能;
- 交付 PD 默认配置:在
models/<model_name>/config/下提供<model_name>_pd/prefill.yaml与<model_name>_pd/decode.yaml,脚本按models/<MODEL>/config/${MODEL}_pd/{prefill,decode}.yaml的默认路径拼接; - 单角色服务验证:拉起 prefill 或 decode 单角色,验证服务正常启动;
- 全链路验证:跑通 prefill/decode/router 全链路,验证请求精度正常。
以 models/deepseek_r1/config/deepseek_r1_pd/prefill.yaml 为例,可以看到 PD 配置的典型写法——prefill 端各层全 TP(attn_tp_size/moe_tp_size/embed_tp_size均为 16),max_new_tokens只取 1,体现 prefill 倾向 TP 的并行策略:
model_config: model_name: "deepseek_r1" model_path: "/data/models/DeepSeek-R1-W8A8" with_ckpt: True exe_mode: "eager" parallel_config: world_size: 16 attn_tp_size: 16 dense_tp_size: 16 moe_tp_size: 16 embed_tp_size: 16 lmhead_tp_size: 16 scheduler_config: block_size: 128 max_prefill_tokens: 8192 max_new_tokens: 1 batch_size: 8启动时在set_env.sh中配置PREFILL_IPS/DECODE_IPS(首个 IP 为该角色实例 leader,Prefill 首节点额外承载 Router 与 Bootstrap server),然后在各节点执行:
# 各 Prefill 节点 bash executor/scripts/infer.sh --model <name> --mode online --pd-role prefill # 各 Decode 节点 bash executor/scripts/infer.sh --model <name> --mode online --pd-role decode服务拉起后,Router 运行在 Prefill 实例 node 0 的 8000 端口(executor/online/router.py 中常量ROUTER_HTTP_PORT指定),可先以单请求验证接口:
curl -s -X POST http://localhost:8000/v1/chat/completions \ -H 'Content-Type: application/json' \ -d '{"model":"default","messages":[{"role":"user","content":"hello"}],"max_tokens":10,"temperature":0.6,"top_p":0.95,"top_k":10,"logprobs":true,"top_logprobs":5,"seed":42}'6. 数据集评分(推荐):evalscope 端到端精度测评
框架提供 OpenAI 兼容接口(/v1/completions、/v1/chat/completions),Checklist 要求跑数据集精度测评(例如 GSM8K)得到正常评分,以验证新模型在online 服务形态下的端到端精度:
evalscope eval \ --model default \ --api-url http://localhost:8000/v1 \ --datasets gsm8k \ --eval-batch 32 \ --generation-config '{"max_tokens":65535}'请求方式详见 executor 架构文档的请求方式一节。仓库内 benchmark/evalscope_scripts/eval_longbench.py 提供了基于 evalscope 的自定义评测脚本示例(继承ModelAPI适配服务端 ChatTemplate 与截断余量),可作为接入新数据集评测的参考。
二、规则约束
Checklist 的第二部分约束模型的接入方式,确保新模型符合仓库规范。以下逐条说明并给出仓库内的对应证据。
1. 版本统一
复用仓库多数 LLM 模型的环境依赖,非必要不新增第三方库。以 DeepSeek-R1 的环境准备 为基准:
- CANN 版本:
CANN 9.0.0(开发套件包 + 二进制算子包); - Ascend Extension for PyTorch(torch_npu):
v26.0.0,对应 PyTorch2.8.0; - Python:仅支持
3.11; - 第三方库版本以 models/deepseek_r1/requirements.txt 为准(如
torch==2.8.0、transformers==5.0.0、datasets==3.6.0、compressed-tensors==0.6.0等)。
2. 环境变量
- 复用框架已有环境变量,不自行定义等价开关。例如日志级别统一使用
CANN_RECIPES_LOG_LEVEL——框架在 executor/utils/logging_config.py 中通过os.environ.get("CANN_RECIPES_LOG_LEVEL", "INFO")读取,setup_logging()是全部入口(executor/online/server.py、executor/model_runner.py、executor/offline/infer.py)统一的根日志配置点; - 确需新增环境变量时,必须在模型
README.md中说明其含义、取值范围与默认行为。
3. 文档规范
- 用户指导文档放在
models/<model_name>/README.md,技术优化点文档放在docs/models/<model_name>/下(例如 docs/models/deepseek_r1); README.md必须站在用户视角还原完整使用流程(环境准备、权重转换、推理执行等),步骤无缺失或错误,可被其他开发者复现;- 影响用户界面的修改(尤其是量化、版本、参数相关指导)必须同步刷新文档。
4. YAML 配置与自定义字段
- 模型特有配置统一收敛到
model_config.custom_params字典中,仅对本模型生效,不得改动data_config、parallel_config、scheduler_config等公共配置字段(参考上文 DeepSeek-R1 的enable_mla_prolog、moe_chunk_max_len等字段均位于custom_params下); custom_params中每个字段都需在模型README.md中解释含义与取值;- YAML 数量尽量精简,不因单一开关差异复制多份近似 YAML——MTP 与非 MTP 可共用同一份 YAML,不同量化类型(如 W8A8、W8A8C8)也可共用;
model_config.model_path等路径使用占位符(如your_model_path),不硬编码本地真实路径或敏感信息。
5. 量化控制
- 量化方式统一由模型权重
config.json中的quantization_config决定(框架自动解析),不通过 YAML 字段或额外开关控制; - 支持的量化类型(如 W8A8、W4A16、W8A8C8)及对应权重转换方式需在
README.md中说明并提供转换脚本。可参考 models/deepseek_r1/utils/weight_convert.sh:以--quant_mode区分bfloat16/w8a8c16/w8a8c8等转换目标。
6. 命名规范
模型名称统一使用下划线命名,且三处保持一致:models/<model_name>/模型目录、docs/models/<model_name>/文档目录、model_config.model_name字段(例如gpt_oss、deepseek_r1)。这一约定保证目录名、YAML 字段与在线 PD 配置默认路径(${MODEL}_pd/prefill.yaml)三者能互相推导。
7. 公共框架代码修改
- 非必要不修改框架公共代码(即非
models/目录代码);涉及公共代码修改时,须确认能兼容库上所有已接入模型,避免破坏公共链路; - 新增配置参数时,需分别在代码和 InferenceConfig 参数文档 中补充注释,说明语义信息和默认值;新增接口或修改公共流程时,需在代码中补充注释说明。
8. 代码风格与提交
库代码统一使用logging.getLogger(__name__),不在库代码中调用logging.basicConfig,避免覆盖setup_logging()建立的根日志配置(这一点在 InferenceConfig 指南的日志配置一节 中也有明确约定)。
9. License 与外部代码引用
- 引用外部代码需正确标注 license,注明来源与许可证类型;
- 新增模型的 LICENSE 建议使用 Apache 2.0 或 MIT,并按实际情况标注版权信息。
三、合入前快速自检
| 环节 | 关键检查项 | 参考依据 |
|---|---|---|
| 基础接入 | 目录齐备(实现/配置类/README/YAML);YAML 覆盖model_name、model_path、exe_mode、input_truncated_len、batch_size、max_new_tokens、max_prefill_tokens、world_size及切分参数 | YAML 示例、配置指南 |
| KV Cache | 选择KVCacheManager(推荐)或自维护;online 场景必须前者 | kv_cache_design.md |
| Packed Sequence | batch_size_per_dp_rank > 1且序列不等长场景功能精度正常 | packed_sequence_design.md |
| npugraph_ex | 至少一份 YAML 启用;warmup 编译正常;decode 无重编译;MTP 双模型可编译 | executor_design.md 图编译流程 |
| Online | offline 先行;<model>_pd/prefill.yaml+decode.yaml齐备;单角色与全链路验证通过 | online_inference_design.md |
| 数据集评分 | GSM8K 等数据集经 online 服务获得正常评分 | evalscope 示例脚本 |
| 规则约束 | 版本对齐 CANN 9.0.0 / torch 2.8.0 / python 3.11;环境变量、custom_params、量化、命名、日志规范、License 逐项满足 | deepseek_r1/README.md、requirements.txt |
按上述两部分逐项验证并留痕后,新模型即可满足 cann-recipes-infer 仓库的合入标准:功能与精度上跑通 offline/online 双形态,工程上完全对齐仓库的目录、配置与文档规范。
【免费下载链接】cann-recipes-infer本项目针对LLM与多模态模型推理业务中的典型模型、加速算法,提供基于CANN平台的优化样例项目地址: https://gitcode.com/cann/cann-recipes-infer
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考