图解索引
46 张离线 SVG 图。先看元素与坐标,再看完整计算流程。
新增:逐格拆解维度转换
进入完整维度图解与4组交互实验 →
逐行展示 ids=[2,0,4] 如何从 E[6,4] 读取三行,得到 X[1,3,4];输入索引数量与输出浮点元素数不同,查表不是 reshape。打开原图放大 ↗用完整 X[3,4] 和 W[4,8] 计算 Y[3,8],将 Q 的4列、K的2列、V的2列分别标色,解释收缩轴和 Linear.weight 的转置约定。打开原图放大 ↗编号0至11由 [1,3,4] 拆成 [1,3,2,2],再转置为 [1,2,3,2];逐 head 画出矩阵,并追踪编号2的三套坐标。打开原图放大 ↗完整展示一个 head 的 Q、K转置、分数、因果softmax、V和输出,区分第一次沿d求和和第二次沿Tk求和,给出可复算数值。打开原图放大 ↗Q的两个 [3,2] 头指向同一个 K/V 头;说明共享的是 K/V,不是注意力权重,也不要求物理复制共享张量。打开原图放大 ↗同一组12个编号分别按 transpose后合头与直接reshape排列,直观看见后者把不同 token 的值混到一行。打开原图放大 ↗放大一个token的12维gate_up,切为两个6维向量,实际计算SiLU与逐元素乘积,再经6×4矩阵投回hidden宽度。打开原图放大 ↗将长度3和2的两条请求从 padded [2,3,4] 收集到 [5,4],逐行标出来源,并用 cu_seqlens=[0,3,5] 恢复请求边界。打开原图放大 ↗T=5、block_size=2、block_table=[3,0,4] 时逐token计算逻辑块、偏移、物理块和slot,并将每个K分量填进物理池的格子。打开原图放大 ↗用完整小矩阵展示输入复制、输出列分片、concat,以及下游输入行分片产生同形partial后求和;权重采用数学[in,out]约定。打开原图放大 ↗课程概览图
15 · token 到 logits 的六个检查点。这是概念形状;框架常将变长 batch 压平为 [总 token 数,H]。
15 · Qwen3-0.6B 的投影宽度。数值来自模型 config 与 nano-vllm 的 Qwen3Attention;不使用 H/Hq 猜 head_dim。
16 · Attention 的三步,不要跳过中间量。Q/K 决定如何分配权重,V 提供要汇总的内容。
16 · 每个 query 有自己的一行概率。矩阵展示因果可见性,不是已经算出的概率。
17 · 完整序列的因果遮罩。上三角被屏蔽;对角线保留,因为当前位置用于预测下一 token。
17 · 缓存 chunk 必须带上位置偏移。[2,5] 的非方阵 mask 不能直接照搬从左上角开始的 tril。
18 · 4 个 Q 头,2 组 K/V。图是逻辑关系,kernel 不必真的把缓存 repeat 成4份。
18 · 三种配置保持 Q 头数为 8。固定 L、d、T、dtype 时,KV 容量之比为8:2:1。
19 · 一个二维对子上的 RoPE。只展示一个频率对子;真实 head 有 d/2 个不同频率。
19 · nano-vllm 的实际执行顺序。本地实现对 Q/K 旋转,不对 V 做这一步旋转。
20 · Pre-Norm attention 子层。公式是逻辑视图;内核融合可以延迟加法但要保持相同数据流。
20 · SwiGLU 的两条投影支路。逐 token 的通道变换;FFN 自身不沿 token 维混合信息。
21 · 缓存沿 token 轴增长。示意有效前缀增长;不是多个 decoder 层共用同一份 K/V。
21 · 一个 decode step 真正做的工作。最后刚采样的 token 已存在于 token_ids,但还没有自己的 KV。
22 · 朴素 attention 的中间矩阵。大中间矩阵在 HBM 中往返;这张图是朴素物化方案。
22 · FlashAttention 的分块视图。算法避免物化完整分数/概率矩阵;dense attention 的算术规模仍是二次。
23 · 生成采样的概念路径。top-k/top-p 是概念扩展;当前 nano-vllm 只实现 temperature 采样。
23 · 本地 sampler 的指数竞赛。等价理解为 argmin(e/p) 的指数竞赛;不等于 argmax(p)。
24 · 同一请求每轮经过相同的控制环。chunk 未完成时虽然 runner 返回候选,postprocess 不追加它。
24 · 不要混淆三种“进度”。真实数值见正文表;红线不是生成边界,计数器才是契约。
25 · 离散物理块承载连续逻辑序列。教学使用小块;实际默认块大小以config为准。
25 · 同一个物理块可经历的六个时刻。free 是可回收状态,不保证内容已经清零;仍可能命中缓存。
26 · 两条序列压平,不把序列边界抹掉。这是无缓存prefill;命中prefix后query长度与key长度不同。
26 · graph replay 使用预分配缓冲区。数据值与有效长度可变;捕获图的形状/地址合约必须满足。
27 · EngineCore 闭环与跨层契约。普通step仍会等待结果;non_block=True本身不等于下一轮已重叠执行。
27 · 三个边界分开看。异步与投机令三条进度暂时不同,输出返回后必须对账。
28 · 缓存身份需要比token子串更多信息。不同身份的请求不能仅因token子串相同就共享缓存。
28 · 最后一个token的logits边界。图的槽位采用B=4示意寻址;32-token例子的B=16见正文。
29 · 调度计划被翻译成执行元数据。假设无CP、无spec、单标准KV group;总输入6个,但候选输出最多3个。
29 · 不要把所有耗时塞进一个tok/s。图只给测量口径,不提供任何未实测吞吐数字。
30 · 请求从Python进入C++的路径。公开版本仍有prompt/decode阶段选择,不照搬vLLM的所有抽象。
30 · 公开README划出的系统边界。缺完整KV服务不等于没有本地KV缓存;支持矩阵以固定提交README为准。
31 · 非MegaMoE路径的数据往返。handle保存通信/排列上下文;不是把所有专家输出按物理顺序直接拼接。
31 · 平均负载掩盖最慢rank。这是解释热点的示意数据,非实际benchmark;EPLB策略还看多步历史和槽位容量。
32 · 置信度决定验证工作量,不直接决定接受。预测接受率与真正接受/拒绝是不同步骤。
32 · 确定性需要一组前提。该固定提交的配置配方,不代表跨硬件和跨版本无条件逐位一致。