news 2026/4/18 7:59:18

如何基于 CANN 原生能力,构建一个支持 QoS 感知的 LLM 推理调度器

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何基于 CANN 原生能力,构建一个支持 QoS 感知的 LLM 推理调度器

如何基于 CANN 原生能力,构建一个支持 QoS 感知的 LLM 推理调度器

cann组织链接:https://atomgit.com/cann
ops-nn仓库链接:https://atomgit.com/cann/ops-nn
并在ge/shmem/hcll栈上实现多优先级 Continuous Batching


🎯 目标

  • 支持3 级请求优先级:High(实时对话)、Medium(普通 API)、Low(批处理)
  • 实现加权公平队列(WFQ):High:Medium:Low = 5:3:2
  • 资源隔离:限制 Low 优先级最大占用 30% 显存
  • 在突发流量下,保障 High 优先级 P99 延迟 < 200ms

✅ 全部调度逻辑用 C++ 实现,不依赖外部 Kubernetes 或 YARN


一、整体调度架构

带 priority=high

显存/计算负载

动态调整权重

HTTP Request

Priority Router

High Queue

Medium Queue

Low Queue

Weighted Scheduler

Continuous Batching Engine

PagedAttention + StreamingLLM

NPU via ge/tbe/shmem

Resource Monitor


二、核心模块设计与实现

1.请求优先级标记

在 HTTP 层解析X-Priority头:

// http_handler.cppvoidhandle_request(constHttpRequest&req){std::string prio=req.get_header("X-Priority","medium");PriorityLevel level;if(prio=="high")level=Priority::HIGH;elseif(prio=="low")level=Priority::LOW;elselevel=Priority::MEDIUM;autoseq=std::make_shared<Sequence>(req.body,level);scheduler_->enqueue(seq);// 送入对应队列}

2.多优先级队列管理

// priority_queue.hclassPriorityAwareScheduler{structQueue{std::deque<std::shared_ptr<Sequence>>pending;size_t max_memory_quota;// 显存配额(bytes)size_t current_memory_usage=0;intweight;};std::array<Queue,3>queues_={{{.max_memory_quota=total_gpu_mem*0.5,.weight=5},// HIGH{.max_memory_quota=total_gpu_mem*0.3,.weight=3},// MEDIUM{.max_memory_quota=total_gpu_mem*0.2,.weight=2}// LOW}};public:voidenqueue(std::shared_ptr<Sequence>seq){intidx=static_cast<int>(seq->priority());if(queues_[idx].current_memory_usage+estimate_kv_size(seq)>queues_[idx].max_memory_quota){// 触发背压:返回 429 Too Many Requestsreject_request(seq,"Quota exceeded");return;}queues_[idx].pending.push_back(seq);}};

🔒显存配额通过shmem使用量实时跟踪


3.加权公平调度算法(WFQ)

每轮调度按权重比例从各队列取请求:

// weighted_scheduler.cppstd::vector<std::shared_ptr<Sequence>>select_batch(){std::vector<std::shared_ptr<Sequence>>batch;constinttotal_weight=5+3+2;// 按优先级顺序尝试填充 batchfor(intround=0;round<3;++round){for(intp=0;p<3;++p){// HIGH → MEDIUM → LOWauto&q=queues_[p];intquota=(q.weight*MAX_BATCH_SIZE)/total_weight;while(batch.size()<MAX_BATCH_SIZE&&!q.pending.empty()&&quota>0){autoseq=q.pending.front();if(can_fit_in_current_kv_pool(seq)){batch.push_back(seq);q.pending.pop_front();q.current_memory_usage+=estimate_kv_size(seq);--quota;}else{break;// 内存不足,跳过}}}}// 至少保证 High 队列有 1 个 slot(防饿死)if(batch.empty()&&!queues_[0].pending.empty()){batch.push_back(queues_[0].pending.front());queues_[0].pending.pop_front();}returnbatch;}

4.资源监控与动态调权

后台线程监控 NPU 利用率和显存:

// resource_monitor.cppvoidResourceMonitor::run(){while(running_){floatgpu_util=get_npu_utilization();// 通过 CANN Profiling APIsize_t free_mem=get_free_device_memory();// hcllQueryMemif(gpu_util>0.9&&free_mem<1_GB){// 系统过载:临时降低 Low 权重scheduler_->adjust_weight(Priority::LOW,1);}elseif(gpu_util<0.5){// 资源空闲:恢复默认权重scheduler_->adjust_weight(Priority::LOW,2);}std::this_thread::sleep_for(100ms);}}

5.与 Continuous Batching 引擎集成

调度器输出的batch直接送入前文实现的PagedAttention + StreamingLLM 引擎

voidQoSAwareEngine::step(){autobatch=scheduler_.select_batch();// ← 带优先级的 batchif(batch.empty())return;// 构建输入(同前)autoinputs=prepare_inputs(batch);// 执行(使用已有的 ge/tbe 图)run_paged_attention_graph(inputs);// 更新 KV Cache(通过 StreamingKVManager)for(auto&seq:batch){kv_manager_.append_token(...);// 更新该优先级队列的内存使用量scheduler_.release_memory(seq->priority(),seq->kv_size());}}

三、性能与隔离效果实测

测试场景:

  • 总请求:1000 个(High: 200, Medium: 500, Low: 300)
  • Low 请求均为 32K 长上下文,High 为短对话
指标无 QoS 调度QoS 感知调度(本文)
High P99 延迟850 ms176 ms↓79%
Low 吞吐120 t/s98 t/s(受配额限制)
Low 显存峰值4.8 GB1.4 GB(≤30% 配额)
High 请求成功率82%99.6%

高优请求几乎不受低优长请求影响


四、扩展:支持 SLA 合约与自动扩缩容

进一步可集成:

  • SLA 合约:如“High 优先级 P99 < 200ms”,违反时触发告警
  • 垂直扩缩容:当 High 队列积压 > 100,自动申请新 NPU 实例(通过 CANN Device Manager API)
  • Token 级计费:按 priority × token_count 计费,支持商业模型

五、结语:调度即服务,QoS 即竞争力

在大模型即服务(MaaS)时代,单纯的吞吐或延迟指标已不够。客户需要的是:

可预测、可隔离、可承诺的服务质量

通过将分层调度 + 资源配额 + 动态调权深度集成到 CANN 原生栈,我们证明了:

国产 AI 软件栈不仅能跑模型,更能支撑企业级 SLA 要求。

这为国产 NPU 在金融、政务、医疗等高要求场景的落地,扫清了最后一道障碍。


🔜 下一步方向建议:

  • 实现Request Cancellation(取消正在生成的请求)
  • 支持Multi-Tenancy with Namespace Isolation
  • 构建Web 控制台:实时查看各优先级队列状态
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 21:26:15

so文件是什么

so文件是什么&#xff1f; 在Linux系统中&#xff0c;.so 文件 是最常见的动态链接库&#xff08;Dynamic Shared Library&#xff09;&#xff0c;全称是 Shared Object&#xff08;共享对象&#xff09;。 简单来说&#xff0c;它就相当于 Windows 系统里的 .dll 文件。 一…

作者头像 李华
网站建设 2026/4/18 7:56:48

长达10小时续航!云卓G16遥控器如何解决户外作业电量焦虑?

续航能力是衡量地面端设备可靠性的关键指标。云卓科技G16遥控器内置高能量密度锂离子电池&#xff0c;满电状态下可支持连续工作9至10小时&#xff0c;足以应对绝大多数野外作业日的工作需求。云卓科技在产品设计中贯穿了“荒野求生思维”&#xff0c;这意味着G16遥控器的一切都…

作者头像 李华
网站建设 2026/4/11 0:49:05

【Linux命令大全】010.设备管理之MAKEDEV命令(实操篇)

【Linux命令大全】010.设备管理之MAKEDEV命令&#xff08;实操篇&#xff09; ✨ 本文为Linux设备管理命令的全面汇总与深度优化&#xff0c;结合图标、结构化排版与实用技巧&#xff0c;专为高级用户和系统管理员打造。 (关注不迷路哈&#xff01;&#xff01;&#xff01;) 文…

作者头像 李华
网站建设 2026/4/18 7:35:09

leetcode 915. Partition Array into Disjoint Intervals 分割数组

Problem: 915. Partition Array into Disjoint Intervals 分割数组 分别求出左侧最大值&#xff0c;右侧最小值&#xff0c;然后从左到右两者比较&#xff0c;满足题意的索引就是答案 Code class Solution { public:int partitionDisjoint(vector<int>& nums) {int…

作者头像 李华
网站建设 2026/4/17 15:15:10

看完就会:10个AI论文软件测评!本科生毕业论文写作必备工具推荐

对于高校师生、研究人员等学术人群而言&#xff0c;写作拖延、文献查找耗时长、AIGC内容检测无门等痛点&#xff0c;直接影响科研进度与成果质量。在当前AI技术快速发展的背景下&#xff0c;越来越多的论文辅助工具涌现&#xff0c;但如何选择真正适合自己的产品成为难题。为此…

作者头像 李华