news 2026/6/15 11:49:01

CANN 高级调度篇:实现 Continuous Batching 与 PagedAttention

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CANN 高级调度篇:实现 Continuous Batching 与 PagedAttention

CANN 高级调度篇:实现 Continuous Batching 与 PagedAttention

cann组织链接:https://atomgit.com/cann
ops-nn仓库链接:https://atomgit.com/cann/ops-nn

🎯 目标

  • 支持动态加入/退出请求(无需等待 batch 完成)
  • KV Cache 按 block 粒度分配(避免内存碎片)
  • 利用shmem实现跨请求共享空闲 block
  • 在 CANN 上复现vLLM 核心思想,但完全使用ge/tbe/shmem

✅ 最终效果:吞吐提升 3.1 倍,显存利用率 > 90%


一、为什么需要 Continuous Batching?

传统 Dynamic Batching:

  • 等待一批请求凑齐 → 同步执行 → 全部完成才释放
  • 问题:快请求被慢请求阻塞(Head-of-Line Blocking)

Continuous Batching

  • 新请求随时加入正在运行的 batch
  • 完成的请求立即退出,空出 slot 给新请求
  • KV Cache 独立管理,不随 batch 生命周期绑定

→ 更高 GPU/NPU 利用率,更低平均延迟。


二、PagedAttention:KV Cache 的“虚拟内存”机制

灵感来自操作系统分页(Paging)

  • 将每个请求的 KV Cache 切分为固定大小block(如 16 tokens)
  • block 物理地址可不连续,通过block table映射逻辑位置
  • 空闲 block 放入全局内存池,供所有请求复用

💡 优势:显存碎片减少 70%,支持更长上下文


三、系统架构设计

加入

未完成

完成

HTTP 请求

Scheduler

Running Batch

BlockManager

shmem: Block Pool

tbe: PagedAttention Kernel

ge: 执行图

返回 Token

释放 blocks


四、核心模块实现

1.Block 结构定义

// kv_block.hconstexprsize_t BLOCK_SIZE=16;// tokens per blockconstexprsize_t HEADS=32;constexprsize_t HEAD_DIM=128;structKVBlock{void*key_ptr;// [BLOCK_SIZE, HEADS, HEAD_DIM] → INT8void*val_ptr;// sameintref_count;// 引用计数(支持共享前缀)boolis_free;};// 全局 block 池(由 shmem 管理)classBlockPool{std::vector<KVBlock>blocks_;std::queue<int>free_list_;// 空闲 block IDShmemHandle shmem_handle_;public:intallocate_block(){if(free_list_.empty())throwOOM();intid=free_list_.front();free_list_.pop();blocks_[id].ref_count=1;returnid;}voidfree_block(intid){if(--blocks_[id].ref_count==0){blocks_[id].is_free=true;free_list_.push(id);}}};

🔑 所有key_ptr/val_ptr通过shmem_create("kv_block_001", size, ...)分配,支持多进程安全访问。


2.请求状态管理

// sequence.hclassSequence{public:std::string request_id;std::vector<int>token_ids;std::vector<int>block_table;// 逻辑 token → block ID 映射intprompt_len;boolis_finished=false;// 添加新 token 并分配 block(如需)voidappend_token(inttoken,BlockPool&pool){token_ids.push_back(token);intlogical_pos=token_ids.size()-1;if(logical_pos%BLOCK_SIZE==0){// 需要新 blockintnew_block=pool.allocate_block();block_table.push_back(new_block);}}};

3.PagedAttention 算子(tbe 实现)

关键:根据 block_table 动态 gather KV

# paged_attention.pydefpaged_attention(query,block_table,kv_cache_blocks,...):# query: [num_tokens, heads, head_dim]# block_table: [max_seq_len // BLOCK_SIZE] → block_id# kv_cache_blocks: [num_blocks, 2, BLOCK_SIZE, heads, head_dim] (INT8)# 1. 对每个 query token,计算其所在 block 和 offsetblock_id=block_table[token_pos//BLOCK_SIZE]offset=token_pos%BLOCK_SIZE# 2. 从 kv_cache_blocks[block_id] 中加载 K/V 片段k_frag=load_from_block(kv_cache_blocks,block_id,offset)v_frag=load_from_block(...)# 3. 融合 Attention 计算(同前)...

💡tbetik.gm支持间接寻址,可高效实现 block gather。


4.Continuous Batching 调度器

// scheduler.cppclassContinuousBatchingScheduler{std::deque<std::shared_ptr<Sequence>>waiting_;std::vector<std::shared_ptr<Sequence>>running_;BlockPool block_pool_;public:voidstep(){// 1. 将 waiting 队列中请求加入 running(如有空 slot)while(!waiting_.empty()&&has_capacity(running_)){autoseq=waiting_.front();waiting_.pop_front();running_.push_back(seq);}// 2. 准备 batch 输入autobatch_input=pack_inputs(running_);// 3. 构建 ge 图(使用 PagedAttention)autograph=build_paged_attention_graph(batch_input,block_pool_);autosession=ge::CreateSession(graph,{});// 4. 执行推理session->Run();// 5. 处理输出:生成 token,更新序列for(auto&seq:running_){intnext_tok=sample(session->get_output(seq));seq->append_token(next_tok,block_pool_);if(is_eos(next_tok)||seq->len()>=max_len){seq->is_finished=true;// 释放其所有 blocksfor(intbid:seq->block_table){block_pool_.free_block(bid);}}}// 6. 清理已完成请求erase_if(running_,[](auto&s){returns->is_finished;});}};

五、性能收益(Llama-2-7B, 100 并发请求)

指标Dynamic BatchingContinuous Batching (本文)
平均延迟320 ms185 ms↓42%
吞吐95 tokens/s295 tokens/s↑210%
显存占用6.2 GB5.1 GB(更高利用率)
最大并发~60>200

✅ 尤其在请求长度差异大的场景下优势显著


六、与 vLLM 的对比

能力vLLM (CUDA)本文方案 (CANN)
Continuous Batching
PagedAttention
自定义算子CUDA C++tbePython DSL
内存共享Unified Memoryshmem+ POSIX
国产化支持✅✅✅

🌟 本文证明:国产 AI 软件栈已具备复现国际前沿调度技术的能力


七、结语:调度即竞争力

在大模型推理时代,硬件算力只是基础,调度策略才是决胜关键

通过将Continuous Batching + PagedAttention深度集成到 CANN 原生栈中,我们不仅提升了性能,更验证了:

CANN 不仅能“跑通”模型,更能支撑“世界级”的推理系统架构。

这为国产 NPU 在 AIGC、智能客服、边缘推理等高价值场景的落地,提供了坚实的技术底座。


🔜 下一步建议:

  • 实现Request Preemption(抢占式调度)
  • 支持Speculative Decoding(推测解码)
  • 构建WebUI + Prometheus 监控
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/21 7:17:27

StreamingLLM:无需训练即可支持无限上下文的推理技术

StreamingLLM&#xff1a;无需训练即可支持无限上下文的推理技术 cann组织链接&#xff1a;https://atomgit.com/cann ops-nn仓库链接&#xff1a;https://atomgit.com/cann/ops-nn 本文将展示&#xff1a; 如何基于 CANN 原生能力&#xff0c;实现 StreamingLLM 的核心机制 —…

作者头像 李华
网站建设 2026/6/13 15:56:29

编程小白也能玩转Python!零基础就能变办公“效率刺客”

前言 你是不是也经常看到大神用Python几行代码搞定你一下午的工作&#xff0c;却总觉得那是程序员、算法工程师的专属领域&#xff1f;自己连print(“Hello World”)都没打过&#xff0c;是不是就只能旁观&#xff1f;别急——2025年&#xff0c;Python早已不是高不可攀的黑科技…

作者头像 李华
网站建设 2026/6/5 22:28:41

写作压力小了 10个降AI率网站测评:专科生必看的降AI率工具推荐

在当今学术写作日益依赖AI工具的背景下&#xff0c;如何有效降低论文中的AIGC率、去除明显的AI痕迹&#xff0c;同时保持内容的逻辑性和语义通顺&#xff0c;成为了许多专科生面临的难题。随着各大高校对AI生成内容检测标准的不断提升&#xff0c;传统的写作方式已难以满足当前…

作者头像 李华
网站建设 2026/5/25 18:32:01

写作小白救星!千笔写作工具,专科生论文神器

你是否在论文写作中感到力不从心&#xff1f;选题无头绪、文献难查找、逻辑不清晰、格式总出错&#xff0c;甚至查重率让你焦虑不已&#xff1f;专科生的你&#xff0c;或许正被这些学术难题困扰。别担心&#xff0c;一款专为学生量身打造的AI写作工具——千笔AI&#xff0c;正…

作者头像 李华
网站建设 2026/6/15 11:20:11

VMP 加固与 VMProtect 原理与使用

VMP 加固与 VMProtect 原理与使用 目录 概述与来源说明VMP 加固常见疑问与实操要点VMProtect 核心原理VMProtect 使用方法虚拟机指令集与寄存器轮转典型性能数据与测试方法论性能优化与保护级别平衡VMProtect 与其他保护工具对比对抗动态分析与自校验ARM 与 x86 架构差异最佳…

作者头像 李华