主题
交互示例的实现与验证边界
这批示例将“能检查状态变化”放在动画效果之前。没有自动启动播放,没有远程脚本和 API,也没有性能实测数据。按钮可用键盘操作;窄屏时控件换行,两个 P 的显示区域纵向排列;含文字回退、动态状态播报与 reduced-motion 样式。
模型边界
KV cache:稠密 decoder causal self-attention 的计数模型。prefill 长度 3,随后处理 8 个预先给定的 token。内存只计 K/V 张量有效数据;明确区别计算位置数、历史读取范围与真实耗时。支持 MHA/GQA/MQA 的 KV 头数选择,不声称模拟 MLA。
BPE:字符级固定教学词表及七条显式规则。词表与 ID 可全部检查,未知字符报错。演示已有规则的编码过程,不模拟训练;没有 GPT 兼容性声明。
GMP:固定状态脚本,不是真实调度器。每个 G 每一步恰好出现一次;P 与 M 一一配对,阻塞 M 不持有图中的 P。实际 Go 的随机选择、runnext、全局公平性、抢占、netpoll 与 GC 等不在模型中。
梯度下降:实际计算一元二次损失的梯度与有限步更新,学习率分界只适用于这个教学函数,不是通用训练处方。
反向传播:对小型标量计算图做拓扑排序、逆序梯度累加,并用中心差分独立检查;不运行 PyTorch,也不把一次图内累加混同多批次梯度累积。
注意力:实际计算可编辑 Q/K/V 的缩放点积、因果掩码、softmax 和加权输出;不声称这些小矩阵是训练模型的语义表示。
采样:计算温度与 top-k 后的概率,再按手动给定的 u 选择区间。严格 k 的并列规则及零温度分支是本例约定,显示概率不是抽样频数。
channel:JavaScript 状态机展示普通发送、接收、关闭、缓冲及 nil 阻塞语义;没有运行 Go,选择的交错与等待队列顺序不是 Go 调度承诺。
联合索引:在内存有序数组上用二分查找展示范围边界和剩余过滤;不是 B+ 树页访问或 MySQL 执行计划,不生成耗时或加速倍数。
Dropout:对最多六个权重枚举独立伯努利掩码,按各自概率计算期望;不把等权遍历当抽样,不对单次输出重新归一化。训练 p=1 被本例的保期望公式域排除,不代表 PyTorch 不支持该参数。
多头形状:跟踪逻辑元素编号经过reshape和transpose,显示遗漏换轴会怎样放错元素。模型不计算QKV、注意力或实际内存拷贝;D表示总投影宽度,要求整除H。
索引信号:演练一个已发现URL在robots许可、200/404/503、HTML noindex与canonical条件下能取得哪些证据。没有运行爬虫,不预测收录、规范选择、排名或等待时间;只有允许抓取且取得正常正文时才把HTML信号记为已读取。
可重复检查
在项目根目录运行 npm test 执行全部模型和组件测试。最初的 tests/interactive-models.test.mjs 覆盖 KV 计数与内存公式、BPE 还原输入与确定性 ID、空输入及未知字符、两种 GMP 场景中 G 唯一位置与 M/P 配对。
组件源文件位于 .vitepress/theme/interactive/。同目录的 models.mjs 及按概念拆分的模型文件不依赖 UI,useSteps.ts 负责可暂停的有限步骤播放,卸载时清理计时器。
依据
- Transformers cache explanation:每层历史 K/V 复用,新 token 的 query 仍读取历史 K/V。
- Hugging Face BPE course:训练得到词表与合并规则,编码时按规则顺序合并。
- Go runtime HACKING:G、M、P 的含义与资源关系。
- Go runtime proc.go:工作窃取、队列与调度路径。核对日期为 2026-10-14;链接指向可变化的官方当前源码,因此本文不依赖固定行号。
这份说明不代替构建与浏览器验收记录;后者以实际执行的检查结果为准。
新增模型的官方依据在各组件末尾就近列出,包括 PyTorch、micrograd 固定源码、原始注意力论文、Transformers 生成配置、Go 规范和 MySQL 联合索引文档。验证记录按提交保存;一次浏览器通过不自动覆盖后续改动。
context 取消传播与有效 deadline
所有节点在虚拟时间0创建。子级有效截止时刻取自身请求与父级截止时刻中更早的一个;父级取消影响后代,子级取消不会沿树向上或传到兄弟。模型按时间顺序结算到期事件,并显示结算后的 Done/Err,不模拟传播延迟、goroutine 调度或任务退出。
真实 CancelFunc 不等待工作完成,Done 关闭也可能晚于 cancel 返回。需要证明任务退出时,还应观察单独的完成信号。实验中的节点数量不代表 goroutine 或线程数量。依据:Context、WithDeadline、CancelFunc。
atomic 库存交错
两个请求共用一个整数库存,每个请求最多尝试预留一份。拆分方案将 Load、局部检查和 Add 分别展示;两个请求都通过检查后各扣一次,可使库存变负。正确使用原子访问不等于多个操作组成一笔原子业务事务。
CAS 方案只在库存仍等于读到的值时写入;失败后必须重新读取并检查。本例是单个整数、两次请求的可检查交错,不代表通用无锁算法、调度概率、公平性或性能结果。真实系统涉及多个字段时,需要另外证明整体约束。依据:Go 内存模型、sync/atomic、Int64.CompareAndSwap。
两份最小 Go 契约测试位于 tests/go,由官方 Go 1.27.2 工具链在 GitHub CI 单独执行 go test -race 与 go vet。它们使用明确的同步屏障,不靠 sleep 碰到交错;实际结果需查看对应提交的 go-contracts job,不能由浏览器或 Node 测试结果推断。
标签右移与损失掩码
标签实验把“输入来自哪一格”和“这个输出在预测谁”分开显示。完整序列右移一位后,提示的最后一格正好负责预测回答的第一格;仅回答监督应按目标角色决定,而不是照抄输入位置的 mask。真实 EOS 与补齐 PAD 即使使用同一个 ID,也有不同来源,不能只凭数值忽略二者。
演示使用小词表、固定 logits 及其计算出的概率,按实际被监督的位置计算负对数损失之和与平均值。更低的平均损失可能只是删掉了难预测的目标,不是模型能力提升。没有有效目标时显示无法平均,不把它计为零损失成功。loss mask 与 attention mask 分工不同;提示不被直接评分,仍可以作为回答的条件,因此不能推出提示 embedding 完全没有梯度。
依据:PyTorch 2.6.0 CrossEntropyLoss、GPT-2 labels接口。不同模型可能在 forward 内部移位;本实验展示数据契约,不要求把已经右移的标签再次交给内部移位路径。
批量生成逐行停止
采样选出候选 token 后,还需要决定哪些请求已经完成。实验固定非空且正确左填充的提示,仅演示逐行 finished、EOS、PAD 和长度上限:先把之前已结束的行替换成 PAD,再追加本步内容,最后更新结束状态。一个请求生成 EOS,不应截断其他尚未完成的请求。
本实验保存包含首次 EOS 的矩形缓冲区,并另外显示去掉终止符与后续补齐的有效回答。原章单条生成函数不把 EOS 拼进返回值,两者是明确不同的接口约定。输入里的 EOS、活跃行本轮生成的 EOS、完成后补入的 PAD 不能混为一谈。补 PAD 也不证明停止了这行的计算;动态压缩、连续批处理、KV cache 和吞吐不在本模型范围内。
依据:Transformers 4.57.1生成循环。对应章原脚本的 EOS 路径仅支持单条输入,新增批量实验是独立教学扩展,不代表已经修复上游程序。
Go select 就绪集合
已有 channel 实验解释单次发送、接收和关闭;本实验只处理 select 的接收分支。nil 分支不能执行,空的未关闭 channel 需要等待;有值或已关闭的接收可以进入候选集合。只有集合为空时,default 才可执行。没有 default 时应等待外部事件,而不是把阻塞误称为程序已经失败。
读者手动选择一个合法分支,是为了检查允许的执行路径,不是模拟 Go 的随机序列。Done 和数据同时就绪时,把 Done 写在前面并不提供优先承诺。关闭后不断接收零值,也不等于读到了新数据;在下一次进入 select 前把本地变量赋 nil,才会禁用该分支。等待中的 select 已经求值的操作数不能被同一等待者随意重选。
依据:Go select规范、接收表达式。不以有限次数的抽样证明公平,不模拟 CPU 占用、发送表达式副作用或运行时调度。
有效 token 加权梯度累积
同一组参数处,各微批次先累加有效 token 的损失和及其梯度,最后除以总有效 token 数,再更新一次。微批次均值的等权平均只有在有效计数相同等条件下才与此一致;单个空微批次不提供目标,全部为空时拒绝平均和更新。
实验用固定预测值 w 与逐项平方损失,只解释分母和梯度权重,不声称语言模型使用这个损失。真实语言模型的分布、dropout、数值误差、分布式归约与优化器状态另有约定。逐微批次更新会改变后续计算参数点,也不是这里的梯度累积。
padding 与最后有效列
实验从已给定的 attention mask 和各位置分数开始,比较最右有效列、有效个数减一、固定末列。个数不包含位置信息;左补齐 [0,0,1,1] 的最后有效位置是3,不能读成1。标准非空左补齐满足最后一列有效,因此符合 Transformers 4.57.1 普通生成路径的末列读取约定。
每列分数是明确标注的教学构造,不是模型语言预测。mask不会替调用者自动改取列表达式;全空行必须在索引前拒绝。中间缺口只检验索引,不能当模型合法输入的保证。找到正确列只解决当前读取,不证明右补齐的整个生成循环、position IDs或KV缓存都已正确。