0.8MB 跑通 Qwen|第 15-3 篇:推理引擎单步走一次生成——token 循环与 KV 追加

简介: 本系列《0.8MB跑通Qwen》用纯C手搓零依赖推理引擎,实测RK3588板端运行Qwen3-VL多模型;本文以gdb单步追踪decode循环,直观展示“采样→前向→KV追加→停判”全过程,将大模型逐token生成钉在胶片上。(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 篇 · 总纲(阿里云社区)

上一篇:15-2《prefill 与 decode:两条路径为何分开》 | 下一篇:第 16 天《VQF 格式深潜 I:布局》

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

一句话导读:单步走一次生成:推理引擎把 N 次 decode 一次一次走给你看——每一步的 token id 是什么、KV 行长到哪、何时停下,本篇用 gdb 在板端录一段真实生成全过程,把"采样—前向—KV 追加"闭环钉在胶片上。

关键词:手搓 Qwen 推理引擎、千问大模型推理、token 循环、KV 追加、decode、GDB、Qwen3-VL、零依赖纯 C

导语:prefill 之后,真正的一个词一个词是怎么走出来的?本篇用 gdb 在 RK3588 板端录下一整段生成:每一次循环里 token id 如何变化、KV 缓存怎样一行行追加、又是何时因 EOS 停表——把「采样 → 前向 → KV 追加 → 判断停」这条闭环钉在胶片上。

15-2 用 gdb 抓到了"1 次 prefill + N 次 decode"的分叉。今天把 N 次 decode 一次一次走给你看:每一步 token id 是什么、KV 行长到哪、什么时候停——用 gdb 在板端录一段真实生成的全过程。

1. 知识点:decode 循环 = 采样 → 前向 → KV 追加 → 判断停

一次 decode 步在引擎里做四件事:

  1. 采样:从当前 logits 挑下一个 token(贪婪 = argmax,Day 13 的采样路径);
  2. 前向:把该 token 喂进去,跑 28 层(st_qwen_model_forward,Day 15-2);
  3. KV 追加:前向把这一位的 K/V 写进缓存并 cache_len++——KV 是"只追加"的;
  4. 判断停:若是 EOS/<|im_end|> 或到达 max_tokens,停止;否则回到 1。

所以 decode 的循环变量有两个:token 序号(输出里第几个词)与 KV 长度(缓存里第几行)——它们同步增长,因为每一个生成 token 都会在 KV 缓存里留下一行(它要成为后续 token 的"历史")。这正是 Day 8-3 说的"KV 是模型对已说内容的记忆",今天用数字把它钉死。

2. 对应代码:循环体三件套

decode_loop 的循环体(vllm_server.c 第 1105–1110 行):

gen++;                                   /* ① token 计数 +1 */
if (met && gen == 1) t_first = ...;      /* ② 首个 token 计时(TTFT 终点) */
st_qwen_model_forward(st, id);           /* ③ 前向 + KV 追加 */

st_qwen_model_forward 内部在层循环末尾做 KV 写入与 cache_len[l]++(vllm_safetensors.c 第 9336 行起);回到循环头,第 989 行前的采样代码从 st->logits 取 argmax——于是"采样→前向→追加→再采样"闭环成立。停止判断在循环体里(命中 eos_id / im_end 即 break,Day 13 的 emit_token 第 825 行)。

3. 改动后果:gdb 实录——从第 25 行 KV 走到第 31 行前停表

口径:RK3588 / 板端 Debug 构建 / 2026-09 / gdb 断在 st_qwen_model_forward,请求:"List the first six letters of the alphabet"。prefill 后缓存已有 25 行(prompt 25 token),随后 gdb 逐次打印每次 decode 入口的 token_id 与 seq_len/cache0。

TEXT>>>a b c d e f<<<            ← 模型最终输出

DEC token_id=64  seq_before=25 cache0=25    ← 第 1 个生成词 'a',从第 25 位开始
DEC token_id=293 seq_before=26 cache0=26    ← 'b'
DEC token_id=272 seq_before=27 cache0=27    ← 'c'
DEC token_id=294 seq_before=28 cache0=28    ← 'd'
DEC token_id=384 seq_before=29 cache0=29    ← 'e'
DEC token_id=282 seq_before=30 cache0=30    ← 'f'

判读(这是"单步走一次生成"的完整胶片):

  1. token id 每次都在变(64/293/272/294/384/282)——每一步采样的是上一步前向的新 logits,不是重复;它们对应输出 a b c d e f;
  2. seq_len 与 cache0 逐次 +1 且始终相等——KV 追加与 token 前进严格同步:第 25 行 KV 在写第 1 个词时被追加,第 26 行写第 2 个词……生成 6 个词 = KV 从 25 行长到 31 行(第 31 行正是 'f' 的位置,写完即停);
  3. 停在 6 个字母后:输出没有第 7 个词——模型在第 6 个词后的下一步采到了结束符(EOS/im_end),decode_loop break。这解释了"为什么每次请求 decode 的次数不固定"(15-2 任务 A 的答案:EOS 说了算,max_tokens 只是上限);
  4. 对照 Day 8-3 的 KV 布局:这 6 步每步的 K/V 行按 (token, 头) 落进缓存;注意力在每一步都会读这 25+step 行(Day 10 的稀疏在长上下文才划算,就在这层读上)。

诚实标注:这是 -O0 Debug 构建逐词打断的记录,只为展示结构与状态流;Release 下同样 6 步 decode 是几十毫秒(Day 10 表 B),Debug 下每步因 gdb 停表明显变慢——gdb 单步是显微镜,不是秒表。

4. 学员调试任务

  • A 档(板端动手):复刻第 3 节:Debug 构建 + gdb 断 st_qwen_model_forward,发"List the first four letters"(或任意短句),抄出每次命中的 token_id/seq/cache0 与最终输出,验证"KV 长度 = 生成词数"的关系;再把 max_tokens 设成 2,观察循环是不是真的只走 ≤2 步。
  • B 档(纯读源码):读 st_qwen_model_forward 尾部的 KV 写入(vllm_safetensors.c 第 9336 行起,层循环末 cache_len[l]++ 附近),回答:① KV 追加发生在层循环内还是外?为什么每层都要加?② 若某步采样到 EOS,为什么还要"已经写下的那行 KV"留在缓存里(提示:seq 已推进,客户端下一轮要 LCP)?③ seq_len 与 cache_len[0] 不一致可能意味着什么 bug?

预期输出:你能不看文档,用一段 gdb 输出复述"一次生成 = 1 次 prefill + N 次 decode,KV 行长 N 行",并说出停止条件的两个来源。

收尾

  • 本篇源码点名:vllm_server.c(decode_loop 循环体 1105–1110、停止判断 989/825)、vllm_safetensors.c(st_qwen_model_forward 9336、KV 追加)。
  • 开源仓库:Kestrel-LLM (Gitee)(AGPL-3.0-or-later 或商业许可,二选一)
  • 下篇预告:生成跑通了,回头看"权重长什么样"——Day 16 进入 VQF 格式深潜:那个 432B 的头部、页对齐 4096、dir_off=448,为什么字节要摆得这么讲究。
相关文章
|
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 篇:推理引擎里诚实的坑——哪些场景稀疏无收益,甚至负优化
本篇实测揭示稀疏注意力的真相:短上下文(&lt;1K)开`--sparse-attn`反成负优化!RK3588板端验证,详列8条“禁用清单”,每条附源码行号与实测数据。明确边界:q4 KV、推测解码、L3驱逐等均与稀疏互斥,并坦承`test-sparse`自检崩溃缺陷。(239字)
|
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天前
|
API 调度 C++
0.8MB 跑通 Qwen|第 14-1 篇:大模型推理的连续批处理——iteration-level 调度思想
本系列《0.8MB跑通Qwen》聚焦ARM端零依赖纯C推理引擎,适配Qwen3-VL多模态模型,在RK3588上实测落地。本文详解iteration-level连续批处理:动态聚合多请求的decode步,单次前向服务多人,兼顾并发与确定性。(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天前
|
人工智能 自然语言处理 文字识别
阿里云百炼自研大模型手册: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字)
|
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

热门文章

最新文章