0.8MB 跑通 Qwen|第 14-2 篇:单 SSE 流与串行队列——推理引擎的"单机守则"

简介: 本系列《0.8MB跑通Qwen》聚焦ARM端零依赖纯C推理引擎,适配Qwen3-VL多尺寸模型(2B/8B/30B),基于RK3588实测。本文详解“单机守则”:推理状态串行锁定、SSE流独立输出、HTTP与推理线程职责分离,揭示为何默认串行是稳定前提而非性能缺陷。(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 篇 · 总纲(阿里云社区)

上一篇:14-1《连续批处理:iteration-level 调度思想》 | 下一篇:14-3《批处理正确性边界:margin 0.71 vs 0.032》

源码精读篇:本文为源码/方法论精读,无独立实测;文中数字均引述仓库 docs 的板端实测记录

一句话导读:单 SSE 流与串行队列:推理引擎的"单机守则"——不开 batch 时同来的请求在推理状态上串行,每个请求的输出走自己独立的一条 SSE 流,本篇讲这条守则为何是对的,以及乱配 HTTP worker 与推理并发会发生什么。

关键词:手搓 Qwen 推理引擎、千问大模型推理、SSE 流、串行队列、线程模型、Qwen3-VL、零依赖纯 C

导语:不开 batch 时,同时进来的请求其实在推理状态上依次排队;每个请求的输出则各走自己的一条 SSE 流。本篇讲这套「单机守则」为什么是对的:推理串行或按步合批、SSE 各管各的,以及把 HTTP worker 与推理并发乱配会踩到什么坑。

14-1 讲了批处理线程怎么把 8 个请求"凑成一次前向"。但真实引擎的默认形态其实更朴素:不开 batch 时,同时进来的请求在推理状态上串行;每个请求自己的输出是一条独立的 SSE 流。今天讲这套"单机守则"为什么是对的——以及"把 HTTP worker 与推理并发乱配"会发生什么。

1. 知识点:一个推理状态,一次只能算一个请求

先回到 Day 4 的教训:引擎的推理状态(KV、hidden、logits)是单份的(vllm_server.c 里 ctx->ist)。于是:

  • 不加 batch 时,两个请求同时到:谁先拿到推理状态的锁谁先算,另一个在队列里等——推理天然串行;
  • 这不可耻:单机、单模型、单用户级延迟目标下,串行 = 延迟可预测、无共享状态竞争;batch 是把串行换成"按步合并",是有意识地用复杂度换吞吐。

再看 HTTP 侧:每个请求的输出通过自己的 SSE(Server-Sent Events)流发给客户端——8 个并发请求 = 8 条独立的 HTTP 连接 + 8 条 SSE 流。SSE 与推理是两个层次:推理决定"什么时候算出下一个词",SSE 决定"这个词怎么流给谁"。两者不该互相踩踏。

2. 对应代码:serve 的线程分工

引擎的 serve 骨架(vllm_server.c)用几组线程各管一摊:

  1. HTTP worker(--threads,默认 8):accept 连接、读请求、路由(/health、/v1/chat/completions、/admin…);每个请求一个处理协程式流程;
  2. 推理状态锁:请求处理进 decode_loop 前要拿到推理状态(14-1 提过 prefill 在引擎 mutex 下)。没有 batch 时这里就是串行闸门;
  3. batch 引擎线程(--batch-max≥2 时,vllm_batch.c):14-1 的引擎线程,取代"请求自己独占推理状态"的模式——worker 改为提交 token、等 done_epoch;
  4. SSE 流式发送:decode_loop 每算出一个 chunk 就沿当前连接写出去(stream=true 时,vllm_server.c emit_token 第 834 行起拼 SSE 事件)。

"单机守则"落到代码就是三条纪律(文档 技术文档.md §2.2 的表述):

  1. 推理串行或按步合批,绝不并发读同一份 ist——否则 KV/hidden 互相踩(位级灾难);
  2. SSE 流每请求一条、写入只属于自己——流之间不共享可变缓冲;
  3. HTTP worker 只负责搬运,不碰推理内部状态——推理只由持有锁的路径或 batch 引擎线程驱动。

3. 改动后果:把并发乱配会怎样(思维实验 + 板端证据)

改动实验(别在板外真做,看代码推演):假设你在 HTTP worker 里直接调用"自己的一份推理状态"而不经过锁/不经过 batch 引擎——两个 worker 同时在写 KV、同时在改 hidden:后果是两个请求的中间状态互相覆盖,输出变成两个 prompt 的混合垃圾,甚至越界崩掉。引擎注释里那份"batch 与串行必须位级一致"的执念(14-3)正是为杜绝这类状态污染而设。

板端证据(不并发乱配,只看守则本身):同一批 8 个短 chat 问答(14-1 第 3 节),不开 --batch-max 时 8 并发总耗时 10.48s ≈ 同服务串行 11.35s——推理在状态锁上排队,并发没有换来任何聚合提速;开了 --batch-max 8 后这批短问答甚至更慢(20.93s,批内每轮迁就最慢者)。所以:默认形态的"串行"是守则的代价(延迟可预测、状态无竞争),batch 是守则内的提速手段——而且它对"长 decode 请求"才生效。

诚实标注:本文引用的三组耗时(串行 11.35s / 无 batch 并发 10.48s / batch 20.93s)均来自 14-1 的板端同批对照(2B 短问答);batch 在本场景是"更慢",不是"下降"——哪个方向取决于请求的 decode 长度,别把本文当"batch 必胜"的背书。若你在自己板子上观察到无 batch 并发时出现位级不一致,那多半是越过了第 2 节的三条纪律——那也是 14-3 讨论"为什么批量位级一致性不是普遍保证"的入口。

4. 学员调试任务

  • A 档(板端动手):对同一批 8 个请求,分别在不带 --batch-max 与带 --batch-max 8 的服务上做 8 并发,记录两种总耗时与全部输出,验证"不开 batch 并发≈串行、开 batch 才降"。
  • B 档(纯读源码):在 serve 代码里找出:① 推理状态锁在哪个文件哪一行(提示:找 decode_loop 进入前的 mutex);② SSE 事件在哪个函数拼装、每连接缓冲是否独立;③ batch 模式下 worker 线程"等 done_epoch"的代码在 vllm_batch.c 哪一段。回答:把 ② 的缓冲改成全局共享,会出现什么症状?

预期输出:你能讲清"推理锁 / batch 引擎线程 / SSE 流"三层各管什么,并解释为什么"默认串行"是单机守则而非性能缺陷。

收尾

  • 本篇源码点名:vllm_server.c(ctx->ist、decode_loop 900、SSE emit 820+)、vllm_batch.c(线程注释 1–14)、技术文档.md(§2.2)。
  • 开源仓库:Kestrel-LLM (Gitee)(AGPL-3.0-or-later 或商业许可,二选一)
  • 下篇预告:batch 把请求合批后,怎么保证"合批 ≠ 改变结果"?14-3 拆那条最诚实的边界:margin 0.71 vs 0.032——为什么批量位级一致性不是普遍保证。
相关文章
|
1天前
|
缓存 自然语言处理 安全
0.8MB 跑通 Qwen|第 11-1 篇:大模型推理中多轮对话的浪费——上一轮 prefill 算完就被扔了
本系列《0.8MB跑通Qwen》聚焦ARM端零依赖纯C推理引擎,实测RK3588平台高效运行Qwen3-VL多模态模型;核心突破是默认启用前缀KV复用,使多轮对话prefill耗时骤降27倍,显著消除历史重复计算,大幅提升端侧长会话效率。(239字)
|
1天前
|
调度 C++ 索引
0.8MB 跑通 Qwen|第 12-3 篇:复现 13.1×——推理引擎的跨进程恢复实测怎么做(含口径拆解)
本系列《0.8MB跑通Qwen》聚焦ARM端零依赖纯C推理引擎,实测RK3588平台运行Qwen3-VL多模型;详解跨进程KV恢复机制,揭示prefill/TTFT/wall三口径差异,13.1×加速比可复现、可验证。(239字)
|
1天前
|
缓存 内存技术
0.8MB 跑通 Qwen|第 9-2 篇:推理引擎的 flash_attn_single_q_q8_neon——单 q 单遍扫全 KV
本系列《0.8MB跑通Qwen》聚焦ARM零依赖纯C推理引擎,精读`flash_attn_single_q_q8_neon`内核:通过Q单次量化、q8 KV单遍扫描、在线softmax与尾部归一,显著降低带宽与内存开销,实现在RK3588等端侧设备高效运行Qwen3-VL系列模型。(239字)
|
1天前
|
人工智能 运维 IDE
阿里云Qoder CN是什么?Qoder CN全家桶包含哪些云产品?
阿里云Qoder CN(原通义灵码)是面向研发与办公的国产AI智能体全家桶,覆盖编码、办公、终端、云端及数字员工全场景,含Qoder CN、QoderWork CN、CLI、QoderWake CN、Cloud Agents CN和Mobile六大子产品,支持多模型、高合规、Credits统一计费。阿里云Qoder CN官网:https://t.aliyun.com/U/fEiOLV
|
1天前
|
人工智能 自然语言处理 数据可视化
阿里云万小智怎么样?真正的AI建站,实测一句话企业官网上线(成本15元)
阿里云万小智3.0是AI驱动的一站式建站工具,用户仅需用自然语言描述需求(如“创建科技公司官网”),AI即可自动生成完整网站,支持可视化编辑与AI对话优化,首站上线成本低至15元,操作便捷高效。
|
1天前
|
数据建模 网络安全
阿里云申请 SSL 证书需要多少钱?不同类型证书收费详解
阿里云SSL证书价格因品牌、验证等级(DV/OV/EV)及域名类型(单域/通配符/多域)差异显著:DV单域低至145.5元/6个月,OV/EV可达上万元/年;另享每年20张免费DV测试证书(3个月有效期)。实时价格以官网为准。
25 0
|
1天前
|
缓存 自然语言处理 安全
CLM 与后缀缓存复用:让模型自己管上下文
CLM(上下文语言模型)将上下文管理从外部规则升级为模型原生能力,支持像编辑文件一样重写、删除、重排上下文;配套SCR缓存复用技术,在性能持平下降低35%算力。论文尚未同行评审,代码开源但含非商用许可。
34 0
|
1天前
|
人工智能 弹性计算 自然语言处理
阿里云万小智 AI 建站标准版与高级版有什么区别?版本选购对比分析
阿里云万小智标准版(980元/年)与高级版(1980元/年)均支持AI建站、多语言、源码下载及安全防护;差异在于:高级版提供10G数据库(标准版1G)、100G创意存储(标准版10G)、明确2核2G+50M带宽ECS、3个备案码、不限邮件+自接短信、三倍AI灵感值,适合中高负载业务。
|
2天前
|
缓存 C++
0.8MB 跑通 Qwen|第 3-1 篇:推理引擎的 mmap 直挂——为什么权重加载可以只要一秒多
本文实测RK3588板端冷启动仅1.0–1.2秒,核心在于mmap直挂VQF权重文件:不全量读取,仅映射+校验头部,权重页由内核按需缺页加载,配合预量化布局,较safetensors全量读快33倍。(239字)
 0.8MB 跑通 Qwen|第 3-1 篇:推理引擎的 mmap 直挂——为什么权重加载可以只要一秒多
|
3天前
|
编译器 C语言
0.8MB 跑通 Qwen|第 2-1 篇:推理引擎的 C11 `_Static_assert`——让编译器守卫你的内存布局
本文详解C11 `_Static_assert` 在内存布局守卫中的关键作用:针对mmap直挂场景,通过编译期断言钉死VQF格式三结构体(200/432/64字节),杜绝因对齐差异导致的静默错位。真机RK3588实测验证,实现错误前移。
0.8MB 跑通 Qwen|第 2-1 篇:推理引擎的 C11 `_Static_assert`——让编译器守卫你的内存布局

热门文章

最新文章