0.8MB 跑通 Qwen|第 14-1 篇:大模型推理的连续批处理——iteration-level 调度思想

简介: 本系列《0.8MB跑通Qwen》聚焦ARM端零依赖纯C推理引擎,适配Qwen3-VL多模态模型,在RK3588上实测落地。本文详解iteration-level连续批处理:动态聚合多请求的decode步,单次前向服务多人,兼顾并发与确定性。(239字)

系列:《0.8MB 跑通 Qwen:从零实现 ARM 零依赖纯 C 推理引擎》(30 天 × 90 篇) | 适配模型:Qwen3-VL-8B-Instruct(千问3_VL_8B_Instruct)· Qwen3-VL-2B-Instruct · Qwen3-30B-A3B | 测试设备:RK3588(4×Cortex-A76 + 4×Cortex-A55,aarch64)

系列总纲:《0.8MB 跑通 Qwen》30 天 90 篇 · 总纲(阿里云社区)

上一篇:13-3《回退与收益边界:哪些场景 spec 才划算》 | 下一篇:14-2《单 SSE 流与串行队列:引擎的"单机守则"》

真机实测通过:本文实验已在 RK3588 板端实测完成(2026-09;方法学与原始记录见仓库 docs 与《实验脚本》目录)

一句话导读:连续批处理:真实服务是一堆请求同时进来,naive 排队串行会让第 8 个人等前面 7 个全部生成完——本篇讲推理引擎 iteration-level 按步合批的调度思想,把多个请求的 decode 步合并成一次前向。

关键词:手搓 Qwen 推理引擎、千问大模型推理、连续批处理、iteration-level、并发请求、Qwen3-VL、零依赖纯 C

导语:真实服务里请求是一批批同时来的,谁先谁后?naive 串行会让排在后面的人一直干等。本篇讲推理引擎的 iteration-level 调度思想:每一轮把想要下一步的请求凑成一个动态集合,共用一次权重读取,让「读一遍权重」同时服务多个人。

前 13 天都在优化"一个请求"。可真实服务是一堆请求同时进来:8 个用户各聊各的,谁先谁后?naive 做法是排队串行——第 8 个人要等前面 7 个全部生成完。Day 14 的三篇讲引擎的批处理:把多个请求的 decode 步合并成一次前向,让"读一遍权重"同时服务多个人。

1. 知识点:为什么 decode 可以"合批",而 naive 串行是浪费

decode 每步都在做同一件事:读一遍全部权重,给"当前 token"算下一步。第 13-1 说这是带宽瓶颈——但瓶颈恰恰意味着可以共享:

  • 8 个请求各自 decode:8 次前向 = 8 遍权重读取;
  • 把这 8 个请求的"当前步"拼成一个 mini-batch 做一次前向:1 遍权重读取,同时算出 8 个下一步。

只要 batch 内各请求的序列长度对齐(KV 各自独立、按请求索引),就能合并。这就是 iteration-level(按"步"而非按"请求")调度的核心:每一轮迭代,把所有想要下一步的请求凑齐,统一走一次前向。

两个关键工程点:

  1. 请求可以中途加入/离开:有人 3 轮就结束、有人要 30 轮——batch 不是固定 8 人小组,而是每轮动态集合(这区别于静态"一次处理一组请求"的 naive batching);
  2. 只在前向处合流:每个请求的 token 采样、SSE 流式输出仍是独立的——合批的是"算",不是"状态"。

2. 对应代码:引擎线程 + 每请求 worker 线程

线程模型写在 vllm_batch.c 文件头注释里(第 1–14 行),是全文最好的一张图:

/* Engine thread: the only caller of st_qwen_model_forward_batch. It polls
 * the node table for want_step nodes, runs ONE forward for the whole set
 * (weights read once per step), then bumps each node's done_epoch.
 *
 * Worker thread (per HTTP request): acquires a node (inference state),
 * prefills under the engine mutex, then per step: sample -> submit token ->
 * wait for done_epoch -> stream the decoded chunk. Requests join/leave the
 * batch freely; finished requests free their state back to the pool. */

两句话拆开:

  • 引擎线程(唯一调 st_qwen_model_forward_batch 的线程,第 218 行):轮询"哪些请求想要下一步"(want_step),凑成一个集合,跑一次前向(权重只读一遍),然后统一"发工资"(bump done_epoch)——每个等待的 worker 线程据此醒来继续;
  • 每请求一个 worker 线程:在引擎 mutex 下做 prefill,然后进入循环:采样自己的下一步 token → 提交进 batch → 等引擎线程的那次前向跑完(等 done_epoch)→ 把自己的 chunk 流式发给客户端。

这就是"批处理与 HTTP 协作"的答案(14-2 的承接):HTTP worker 只负责自己的请求,引擎线程独占推理前向,二者通过 want_step/done_epoch 握手,请求随时 join/leave(第 13 行原话),VB_MAX_BATCH = 32(第 29 行)封顶。

开关:--batch-max N(main.c 第 4935 行,默认 0=关)。引擎一次 decode 步现在要"喂多个 token"——对应的内核是 st_qwen_model_forward_batch,它在单 token 前向之外存在(第 9829 行起有批量 GQA/归一化 worker 的结构)。

3. 改动后果:8 个并发请求,批量 vs 串行(板端实测)

口径:RK3588 / Qwen3-VL-2B / 2026-09 / serve 贪婪 / --batch-max 8。8 个短问答请求(内容互不相同),先串行发(队列深度 1,batch 不生效),再8 线程同时发(batch 生效),同一服务进程、同一批 prompt。

模式 8 请求总耗时 备注
串行(--batch-max 8 服务,队列深度 1) 12.95 s batch 空转:每请求独立 decode,权重读 8 遍
8 并发(--batch-max 8) 20.93 s 引擎线程按步合批,但这批短问答反而更慢(见判读 2)
对照:8 并发(无 batch 服务) 10.48 s(≈同服务串行 11.35 s) 推理状态锁上排队:并发≈串行

判读:

  1. 输出全部逐字节一致(Blue / Tokyo / tea / Green / Paris / coffee / Purple / Berlin 各模式相同)——批量合批没有改变结果(14-3 讲 near-tie 边界);
  2. 这批短问答开 batch 反而更慢(20.93s vs 12.95s,+62%):请求各只有 2–6 个 token,合批的"权重只读一遍"红利没机会累积,反而让每轮都迁就批内最慢者(8 个请求同步进退、约 20s 一起收尾)。batch 的收益条件是 decode 步数足够多——仓库文档 优化配置与边界说明.md §3.6 的 1.7×(8B 长对话)与本节 2B 短问答的"+62%"都是真的,差别在场景;短问答要量过再开;
  3. 引擎日志的 batch_active(vllm_admin.c 第 389 行,批内请求数)在并发期间 >1——/admin/api/status 可抓活证据。

测量纪律:同批 8 个 chat 问答,串行基线在不同进程间测得 11.35–12.95 s(±~7% 抖动,Day 7 的老朋友);本文主对照 12.95 vs 20.93 是同服务进程内先后测得,结论方向不受抖动影响。

4. 学员调试任务

  • A 档(板端动手):复测第 3 节:--batch-max 8 起服务,用并发客户端发 8 个请求,再串行发同一批,记录两组总耗时与各自的输出;顺手 curl /admin/api/status 看并发期间的 batch_active。
  • B 档(纯读源码):读 vllm_batch.c 头注释(第 1–14 行)与引擎线程轮询(第 218 行附近),回答:① 为什么"权重只读一遍"在 decode 场景是收益而非负担?② 请求中途结束,引擎线程怎么知道这一轮不用等它?③ VB_MAX_BATCH=32 超了会怎样(提示:VB_SLOT_WAIT_MS 120s 的等待)?

预期输出:你能画出"引擎线程 ↔ N 个 worker 线程"的握手图(want_step → 一次 forward → done_epoch),并解释 batch 为什么是"动态集合"而非"固定小组"。

收尾

  • 本篇源码点名:vllm_batch.c(线程模型注释 1–14、引擎线程 218、VB_MAX_BATCH 29)、main.c(--batch-max 4935)、vllm_admin.c(batch_active 389)、vllm_safetensors.c(批量前向 9829+)。
  • 开源仓库:Kestrel-LLM (Gitee)(AGPL-3.0-or-later 或商业许可,二选一)
  • 下篇预告:批处理线程有了,可每个请求的 HTTP 流还是独立的——14-2 讲 serve 的"单机守则":为什么引擎坚持单 SSE 流 + 串行队列,批处理线程和 HTTP worker 并发乱配会发生什么。
相关文章
|
1天前
|
存储 缓存 C++
0.8MB 跑通 Qwen|第 9-1 篇:推理引擎的 KV 也量化——q8 KV 把缓存与 decode 带宽压到一半
本系列手搓零依赖纯C推理引擎,仅0.8MB即可在RK3588上跑通Qwen3-VL多模型。本文详解q8 KV量化:将f16 KV压至INT8,按token每头独立定标,缓存与decode带宽降低约48%,兼顾精度与效率,f32仅作调试探针。
|
1天前
|
缓存 NoSQL 区块链
0.8MB 跑通 Qwen|第 15-3 篇:推理引擎单步走一次生成——token 循环与 KV 追加
本系列《0.8MB跑通Qwen》用纯C手搓零依赖推理引擎,实测RK3588板端运行Qwen3-VL多模型;本文以gdb单步追踪decode循环,直观展示“采样→前向→KV追加→停判”全过程,将大模型逐token生成钉在胶片上。(239字)
|
1天前
|
安全 索引
0.8MB 跑通 Qwen|第 12-2 篇:推理引擎的磁盘 KV 快照格式——0.47 GB 从哪来
本系列《0.8MB跑通Qwen》聚焦ARM端零依赖纯C推理引擎,实测RK3588上部署Qwen3-VL多模态模型。本文详解0.47GB磁盘KV快照格式:64字节头+token IDs+28层F32原样KV,逐字段对账到字节级,诠释“宁大勿错”的可靠性设计。(239字)
|
1天前
|
C++
0.8MB 跑通 Qwen|第 10-3 篇:推理引擎里诚实的坑——哪些场景稀疏无收益,甚至负优化
本篇实测揭示稀疏注意力的真相:短上下文(<1K)开`--sparse-attn`反成负优化!RK3588板端验证,详列8条“禁用清单”,每条附源码行号与实测数据。明确边界:q4 KV、推测解码、L3驱逐等均与稀疏互斥,并坦承`test-sparse`自检崩溃缺陷。(239字)
|
1天前
|
运维 Kubernetes 数据安全/隐私保护
K8s 劝退?那是你打开方式不对
本文用大白话讲透K8s核心逻辑:从“手动运维”到“声明式自治”的思维跃迁,结合Pod、Deployment、Service等概念,直击传统运维痛点。通过真实故障对比,展现K8s如何自动恢复服务——你只定义目标,它负责执行与兜底。(239字)
26 1
|
1天前
|
弹性计算 固态存储
阿里云服务器8核16G配置ECS实例规格族、收费标准及2026最新价格参考
本文详解阿里云8核16G云服务器ECS的2026年最新价格,涵盖经济型e、计算型c9i、通用型u2a等多规格族的按小时/月/年/3年/5年计费标准,并说明公网带宽与系统盘(ESSD等)费用组成。阿里云服务器ECS官网:https://t.aliyun.com/U/AZBUsA
|
1天前
|
设计模式 SQL 安全
【第三部分:第一个 Agent 应用】14. 开发一个完整的企业知识助手:从 RAG 到 Agent
本文以企业知识助手为综合实践,整合 RAG、Agentic RAG、Tool Calling、MCP、Memory、State、Structured Output、权限控制、引用溯源与 Trace/Eval 等能力,说明企业知识助手如何从“知识库问答”升级为能够连接业务系统、理解上下文并执行真实任务的 Enterprise Agent。文章重点介绍权限感知检索、Metadata、业务 Tool、长期记忆、人工确认和可观测评估等生产级能力,并结合 BaseMetas EKA 架构说明企业知识与 Agent 如何协同落地。
35 0
|
1天前
|
人工智能 自然语言处理 文字识别
阿里云百炼自研大模型手册:Qwen、万相、HappyHorse、CosyVoice 能力梳理
阿里云自研AI模型涵盖文本、视觉、语音、音视频及向量等全模态,以通义千问Qwen系列为核心,包括Qwen3.8-Max、Qwen-VL、通义万相、CosyVoice等,均通过百炼平台提供API服务。
|
1天前
|
人工智能 JSON API
从零打通 MCP 访问创世虚拟世界CRM的 3D 数据,我搭了一个可直接调用的演示站
作者把创世虚拟世界CRM(创世Genesis,自部署 3D 虚拟世界)的 AI Agent 通道(HTTP + WebSocket + JSON 约定)封装成 8 个 MCP 工具(discover/enter/observe/say/walk_to/follow/chat_history/leave),stdio 版已上 npm 与官方 MCP Registry,随后为零安装补了 Streamable HTTP 远端点。本文实录打通过程:stdout 纯净性、initialize 必填字段、Mixed Content 协议陷阱、官方 SDK 拖入 34 包后的零依赖重写、GET 400 被目
|
1天前
|
人工智能 自然语言处理 文字识别
阿里云百炼自研大模型大全:Qwen 系列、音视频、向量重排序模型汇总
阿里云百炼平台汇聚Qwen系列大模型及音视频、图像、语音、向量等全模态自研AI模型,涵盖文本生成、多模态理解、AIGC创作、语音处理与智能决策,一站式提供API服务。(239字)

热门文章

最新文章