Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions apps/course/catalog.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
[
{
"id": "tokenization",
"order": 1,
"title": "文字怎样变成 Token?",
"outcome": "观察同一句话如何分成片段并映射为编号;区分字符、词和 Token。",
"status": "planned",
"route": null,
"published": false
},
{
"id": "embedding",
"order": 2,
"title": "编号怎样变成向量?",
"outcome": "跟踪查表得到的向量,并比较方向、距离与其教学边界。",
"status": "planned",
"route": null,
"published": false
},
{
"id": "attention",
"order": 3,
"title": "一个词如何参考其他词?",
"outcome": "从 QK 分数到因果遮罩、注意力权重与 V 的加权结果。",
"status": "planned",
"route": null,
"published": false
},
{
"id": "transformer",
"order": 4,
"title": "一层网络怎样更新表示?",
"outcome": "跟踪注意力、残差、归一化与前馈变换中的同一个向量。",
"status": "planned",
"route": null,
"published": false
},
{
"id": "token-choice",
"order": 5,
"title": "一个词,是怎样被选出来的?",
"outcome": "分数经过温度、指数和归一化,怎样得到一次选择。",
"status": "reviewed",
"route": "/learn/token-choice/",
"published": false
},
{
"id": "autoregression",
"order": 6,
"title": "为什么生成要一个 Token 接一个?",
"outcome": "把选中的 Token 接回上下文,区分重算与 KV 缓存的复用。",
"status": "planned",
"route": null,
"published": false
},
{
"id": "context",
"order": 7,
"title": "System Prompt 怎样进入上下文?",
"outcome": "查看消息、指令与窗口容量,理解裁剪、优先级和能力边界。",
"status": "planned",
"route": null,
"published": false
},
{
"id": "rag",
"order": 8,
"title": "检索怎样帮助模型回答?",
"outcome": "从文档切片、检索到带来源的上下文;区分找到、引用与答对。",
"status": "planned",
"route": null,
"published": false
},
{
"id": "skills-tools-mcp",
"order": 9,
"title": "Skill、工具和 MCP 分别做什么?",
"outcome": "用一次任务追踪操作说明、工具调用、协议与实际执行。",
"status": "planned",
"route": null,
"published": false
},
{
"id": "personal-agent",
"order": 10,
"title": "Personal Agent 怎样完成一件事?",
"outcome": "跟踪计划、行动、观察、记忆与结束条件,看到失败如何反馈。",
"status": "planned",
"route": null,
"published": false
}
]
3 changes: 3 additions & 0 deletions apps/site/learn/course.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

69 changes: 69 additions & 0 deletions apps/site/learn/token-choice/LESSON.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# 分数如何变成下一个 Token

这是一段从候选分数出发的单步采样解释。同一组候选依次经历温度缩放、指数权重、归一化与随机数定位;词卡和颜色贯穿全过程。数值按数学定义实时计算,移动与形变用于引导注意力。

## 可复用的用户请求

“用精细、克制的彩色空间图解,解释分数如何经过温度和 Softmax 变成下一词的选择。每次只讲一步,气泡跟随正在变化的对象,播放时收起配置;能暂停检查计算并调温度比较。”

## 50 秒的教学顺序

| 时间 | 当前问题 | 可观察证据 |
| --- | --- | --- |
| 0–8 秒 | 模型给出的分数是什么? | 四个候选和分数 `[3, 2, 1, 0]`,没有百分号 |
| 8–18 秒 | 温度改变什么? | 原始分数保留;`z/T` 和分差随 T 变化 |
| 18–27 秒 | 怎样得到正权重? | `exp(z/T)`,权重总和尚未归一化 |
| 27–36 秒 | 怎样得到概率? | 每项除以同一个总和;概率带合计 100% |
| 36–45 秒 | 如何按概率选择? | 固定种子生成的均匀随机数在 `[0,1)` 概率带上定位 |
| 45–50 秒 | 这次选择了什么? | 浮起的词卡与所落区间一致;不继续生成下一词 |

默认 T=0.8,`mat` 概率约为 71.8%。固定随机数 `u≈0.621868`,本次会选择 `mat`;将 T 改成 2,同一随机数会落入 `floor` 区间。这个对照能够隔离“分布改变”的效果。点击再次抽样时才更换抽样序号,温度与输入保持不变。

## 图形与数学的边界

四个候选是本页完整的人工教学词表,分数不是任何真实语言模型的预测结果。真实 tokenizer 可能把一个词拆成多个 token,本页词卡不承担分词教学。本节也不讲 logits 是如何由神经网络算出来的。

所有阶段都保持候选身份与颜色一致。厚度、遮挡、倒角与微阴影只形成层次;概率必须由前视长度编码,不能用透视造成数值大小错觉。指数权重若使用自动量程,应显示量程或“相对高度”提示。概率带中的区域不可为了放文字而人为拉宽。

温度先缩放 logits,然后 Softmax 得到概率;原始 logits 不会被滑块改写。指数权重没有概率含义,必须完成归一化之后才显示百分比。提高温度使整体分布更平缓,不承诺每个较低排名候选概率都增加,也不承诺回答更正确。

累积概率区间采用左闭右开约定,边界上的 u 选择其右侧候选。随机数先确定,游标运动只展示这个数的位置。固定种子让暂停、倒退与重播可复现。多个抽样保持固定上下文;这是条件分布的重复实验,不是自回归续写。

## 实现与验证

纯模型位于 `model.mjs`,固定数据为只读常量,返回状态独立可修改。`compute(T)` 返回缩放分数、权重、权重和、概率、CDF 与熵;`sample(time, inputs)` 再加入章节、进度和采样结果。框架或渲染器只消费这些数据。

运行数学验证:

```sh
node apps/site/learn/token-choice/model.test.mjs
```

已经通过的计算检查包括 Python 独立黄金值、概率比恒等式、正权重、归一化、CDF 半开边界、温度与熵关系、两万次固定种子采样频率、43.2 秒的选择时点、正反向跳转和返回值隔离。

实际浏览器中的播放、布局、焦点、响应式和完成恢复由场景集成验证记录补充;纯模型测试不证明视觉或学习效果。

## 来源与范围

- [PyTorch Softmax 文档](https://docs.pytorch.org/docs/2.14/generated/torch.nn.Softmax.html):指数归一化定义。
- [Hugging Face TemperatureLogitsWarper](https://huggingface.co/docs/transformers/en/internal/generation_utils#transformers.TemperatureLogitsWarper):温度采样分布的调节。
- [Anatomy](https://github.com/wheresryan22/anatomy):用户已确认的视觉工艺参考。本场景重新设计数学对象,不沿用轮盘作为主体。

此教学样例只在受限值域内直接计算 `exp(z/T)`,最大指数输入为 7.5,因此有限且安全。用于任意 logits 的通用实现应减去输入最大值,再计算指数;此平移不改变最终概率。

## 本地完成记录(2026-10-25)

- 新绘制 SVG 数学对象;主体未复用 Anatomy 轮盘。沿用前版已认可的浅色阶、细线、倒角与候选配色。
- 完整50秒播放后进度为50/50,设置恢复。中途暂停在29.45秒,恢复后保持原位置继续。
- 桌面浏览器与390×844手机布局:图形、气泡和公式无交叠,概率标签通过真实区间中心的细线关联。
- 相同u=0.621868…,T=.8选mat,T=2选floor;浏览器显示与模型测试一致。
- 指数阶段明细:mat的原分数3,除以.8得到3.75,指数42.52,权重总和59.19,概率71.8%;浏览器核对通过。
- 通用Skill的旧脚手架检查器要求runtime/viewer.mjs、runtime/playback.mjs、templates/catalog.mjs,本场景使用网站原生SVG适配层,因此该结构检查不适用且未通过;没有添加空文件凑通过。替代的evals/verify-token-choice.mjs检查实际交付依赖、完整spec、数值量程和概率区间。
- 未验证真实手机硬件、屏幕阅读器实机、系统减少动态效果开关或不同浏览器引擎;减少动态效果逻辑已实现。未运行真实LLM,无语音。
- 构建:npm run build;独立文件:node scripts/bundle-token-choice.mjs。完整检查:npm test。

## 2026-10-26 发布教学评审

通过开发者教学适配评审,尚未进行真实学习者效果研究。加入完成后的“检验理解”:先预测固定分数和u不变、T从.8到2时的候选,再得到累计概率区间的因果反馈,最后回到同一组参数的图形验证。错误答案不是只显示叉号;说明mat上界.4551、floor上界.7311,以及u=.6219为何属于floor。

本轮实查:课程入口可进入该场景;桌面端错误/正确选择与回到图形后T=2、floor27.6%一致;390×844手机布局下学习题完整可读。`npm run check`覆盖既有机械模板约束、新场景的独立模型测试与课程清单检查。真实设备与屏幕阅读器仍未实查。
79 changes: 79 additions & 0 deletions apps/site/learn/token-choice/SCENE_SPEC.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{
"id": "token-choice",
"question": "模型已经给出候选分数后,温度、Softmax 和随机采样怎样得到下一个 Token?",
"audience": "希望逐步理解 AI 原理、没有概率论背景的读者",
"context": "the cat sat on the …",
"objects": [
{"id":"scores","meaning":"四个教学候选的原始 logits,保留候选身份与颜色","units":"无量纲分数"},
{"id":"temperature","meaning":"把每个原始分数除以同一温度 T","units":"无量纲"},
{"id":"weights","meaning":"exp(z/T) 给出的正权重,尚未归一化","units":"无量纲权重"},
{"id":"probability","meaning":"每个权重除以全部权重之和,概率带宽度正比于概率","units":"概率,合计 1 或 100%"},
{"id":"sampling","meaning":"0 到 1 的均匀随机数 u 在累积概率带上的位置","units":"无量纲,0 ≤ u < 1"},
{"id":"result","meaning":"u 所在区间对应的候选词卡","units":"候选索引"}
],
"relationships": [
"tokens = [mat, floor, bed, sofa];logits = [3, 2, 1, 0]",
"scaled_i = logits_i / T",
"weight_i = exp(scaled_i)",
"p_i = weight_i / sum_j(weight_j)",
"cdf_0 = 0;cdf_(i+1) = sum_(j≤i)(p_j);cdf_4 = 1",
"selected = i,当 cdf_i ≤ u < cdf_(i+1)",
"固定输入下调节温度不改变原始 logits;固定 seed 和 draw 不改变随机数 u"
],
"parameters": [
{"id":"temperature","min":0.4,"max":2,"default":0.8,"units":"无量纲"},
{"id":"seed","default":22,"units":"整数伪随机种子"},
{"id":"draw","default":0,"min":0,"units":"非负整数抽样序号"}
],
"outputs": ["scaled","weights","totalWeight","p","cdf","entropy","u","selected"],
"durationSeconds": 50,
"chapters": [
{"id":"scores","start":0,"end":8,"message":"分数不是概率"},
{"id":"temperature","start":8,"end":18,"message":"除以温度,缩放分数差异"},
{"id":"weights","start":18,"end":27,"message":"取指数,把分差变成权重之比"},
{"id":"probability","start":27,"end":36,"message":"归一化得到总和为 1 的概率"},
{"id":"sampling","start":36,"end":45,"message":"随机数在累积概率带上定位"},
{"id":"result","start":45,"end":50,"message":"显示这一次抽到的候选"}
],
"timeline": {
"sampler":"sample(time, {temperature, seed, draw})",
"selectionVisibleAtSeconds":43.2,
"numericState":"所有数值从同一组输入计算,几何变形插值不改变它们的数学定义",
"playback":"实际 elapsed time,支持暂停、继续、反向拖动、重播与结束恢复;隐藏标签页暂停",
"narration":"每次仅一条气泡跟随当前数学对象;颜色在所有阶段保持候选身份一致"
},
"invariants": [
"四个概率均为正且总和约为 1",
"全部 cdf 区间有序、无重叠,覆盖 [0,1)",
"log(p_i / p_j) = (z_i - z_j) / T",
"在这组不相等的 logits 上,提高 T 提高熵并降低最大概率",
"seed、draw、temperature 和 time 相同时,状态完全可重现",
"43.2 秒前 selected 为 null;之后与 inverse CDF 结果一致",
"对返回数组的修改不会污染后续 sample 或原始教学数据"
],
"simplifications": [
"四个词构成完整的教学词表;不是从真实模型词表截取的前四项,也不是线上模型输出",
"本节从已有 logits 开始,不讲 tokenizer、Embedding、Attention 或语言模型怎样产生这些分数",
"词卡用于展示教学候选,不声称它们在任何具体 tokenizer 中恰好各占一个 token",
"固定输入的单步采样,不把结果接到上下文进行下一轮自回归",
"不使用 top-k、top-p、重复惩罚或其他采样过滤器",
"受限的 logits 与 T 使直接计算 exp(z/T) 安全;通用实现需做最大值平移以防溢出",
"数值刻度必须明确:权重柱如自适应缩放,应标明最大值或相对高度;概率宽度始终按真实概率",
"游标移动用于揭示一个预先确定的伪随机数,不通过动画速度或物理运动决定选择",
"立体厚度与阴影只用于层次,数值长度在正视平面编码",
"高温不会保证每个低排名候选的概率都增大,也不意味着答案更正确"
],
"sources": [
{"url":"https://docs.pytorch.org/docs/2.14/generated/torch.nn.Softmax.html","supports":"指数归一化公式与输出概率和为 1"},
{"url":"https://huggingface.co/docs/transformers/en/internal/generation_utils#transformers.TemperatureLogitsWarper","supports":"正温度对采样分布的调节;温度与随机采样的关系"},
{"url":"https://github.com/wheresryan22/anatomy","supports":"已获用户认可的细线、等轴层次与克制配色工艺参考;本场景不复用原轮盘几何"}
],
"acceptance": [
"独立 Python 黄金值与 JavaScript 数学结果一致",
"概率归一化、指数权重、CDF 边界、温度熵关系、固定种子采样与反向跳转测试通过",
"在桌面和手机实际检查当前讲解对象、箭头和数值均清晰,无重叠或裁切",
"播放、暂停、继续、拖动、参数改变、再次抽样、重播及完成后的配置恢复均可观察验证",
"保留单一焦点;未讲到的计算与参数不会同时占据主视觉"
],
"untested": ["真实手机硬件性能与所有浏览器组合", "独立的学习效果实验"]
}
Loading
Loading