本文基于昇腾CANN和昇腾NPU,围绕 MindIE 大模型推理服务 技术展开。

跑通一次模型推理几行代码就够了。让 1000 个并发用户每人 200ms 内拿到回复——这件事比模型推理本身复杂得多。MindIE 是昇腾NPU上的大模型推理服务框架(LLM Serving),管请求排队、Batch 动态组装、KV Cache 分配和回收。


Continuous Batching:不等任何人

传统推理是静态 Batching——等凑够一批请求再一起跑。有人要生成 20 Token、有人要 200 Token——大家绑在一起,短 Token 等长 Token。

Continuous Batching 每步 Decode 重新组 Batch:本轮有 Token 要算的请求全部加入,算完一个 Token 检查——如果你生成了 EOS 就退出 Batch,下一批新请求补进来。跟 vLLM 在 GPU 上的思路一样,MindIE 在昇腾NPU上做了硬件适配。

Continuous Batching 的调度循环:

while True:
    # 1. 捞新请求填满 Batch
    while len(active) < max_batch and waiting:
        req = waiting.pop()
        prefill_kv = model.prefill(req.prompt)
        req.kv_cache = prefill_kv
        active.append(req)

    # 2. 组装当前 Batch 的输入(每人最后一个 Token)
    batch_inputs = [req.last_token for req in active]

    # 3. 一起 Decode——生成本轮 Token
    new_tokens = model.decode(batch_inputs)

    # 4. 检查完成
    for req, token in zip(active, new_tokens):
        req.output.append(token)
        if token == EOS or len(req.output) >= req.max_len:
            active.remove(req)       # 退出 Batch
            free_kv_cache(req)       # 释放 KV Cache

KV Cache 的 Block 级管理

Continuous Batching 的副作用是 KV Cache 碎片。请求随时加入退出,Cache 里留下大小不一的空洞。MindIE 用 Block 级分配解决:把 KV Cache 切成固定大小 Block(比如 256 Token 一块),请求按需申请 Block 数组。请求结束——所有 Block 一起释放——零碎片。

一个 128K 上下文的 KV Cache 分配约 512 个 256-Token Block。Block 大小选定后不变——太小管理开销大,太大浪费空间(短请求用不完一个 Block)。


Prefill Chunking:长 Prompt 不卡主

Continuous Batching 里遇到 5000 Token 的大 Prompt 时,Prefill 独占 NPU 十几 ms——所有人的 Decode 全部暂停。MindIE 的 Prefill Chunking 把长 Prompt 切成小段(比如每段 512 Token),分段喂——段和段之间穿插其他用户的 Decode。

无 Chunking:
  [Prefill 5000 tokens: 12ms,所有人等] → [Decode 混合]

有 Chunking(512 tokens/chunk):
  [Prefill 512t: 1.2ms] → [Decode 混合: 1ms]
  → [Prefill 512t] → [Decode]
  → ... 10 轮后 Prefill 完成
  → 长 Prompt 对其他人几乎无感知

在线推理的典型问题

KV Cache 耗尽。 高峰期大批请求进来,Cache 打满。MindIE 的解法是 Swapping——不活跃请求的 KV Cache 写到 CPU 内存,活跃时读回来。CPU ↔ NPU 的 PCIe 搬运算约 32GB/s——读回一个 128K 上下文的 KV Cache(~2GB)约 60ms。比重新 Prefill 慢,但比 OOM 强。

Batch Size 抖动。 Continuous Batching 下 Batch Size 随时变化,GPU/NPU 利用率跟着跳。MindIE 的调度器在 Batch 不满时不做立刻补充——等 0.5ms 再捞新请求,避免刚凑好 Batch 又有人退出。


参考仓库

cann-recipes-infer 推理 Recipes

Runtime 运行时

ATB Transformer 加速

CANN 学习中心

Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐