{
  "note": "学习路线（英文模式用 title_en / sub_en / goal_en / label_en，资源换成 res_en，全部是英文资源）：每一站一句白话目标、本站对应的页面和深度（站内页面目前不能直接跳到某一层，链接打开页面，标签写明该去哪一层），再挂 2–4 个资源库里的条目（res 是 resources.json 的 id）。",
  "stages": [
    {
      "id": "surface", "no": "01", "title": "浮出水面", "sub": "大模型到底在做什么",
      "title_en": "The surface", "sub_en": "What an LLM actually does",
      "nodes": [
        { "id": "next-token", "title": "它只是在接龙", "goal": "大模型每一步只做一件事：看着前面的所有词元，给词表里每个词元打一个分，再从中抽一个出来。",
          "title_en": "It's just a word-chain game", "goal_en": "At every step an LLM does just one thing: look at all the tokens so far, give every token in the vocabulary a score, and draw one.",
          "site": [{ "label": "推理 · D1 黑箱", "label_en": "Inference · D1 Black box", "href": "../" }, { "label": "推理 · D2 结构", "label_en": "Inference · D2 Structure", "href": "../" }],
          "res": ["s-3b1b-llm", "i-3b1b-gpt", "s-hylee-2024"],
          "res_en": ["s-3b1b-llm-en", "i-3b1b-gpt-en", "s-karpathy-intro"] },
        { "id": "tokens", "title": "文字先变成词元", "goal": "模型看到的不是字，而是一串编号：一个词可能被切成几块，中文常常一两个字一块，连“对话”本身也被编成特殊词元。",
          "title_en": "Text becomes tokens first", "goal_en": "The model doesn't see characters, it sees a string of IDs: a word may be cut into several pieces, Chinese often goes one or two characters per piece, and even the chat structure is encoded as special tokens.",
          "site": [{ "label": "推理 · 聊天里的点选输入法（候选就是真实分词）", "label_en": "Inference · The chat's tap-to-type input (the candidates are real tokens)", "href": "../" }, { "label": "智能体 · D3 上下文", "label_en": "Agents · D3 Context", "href": "../agent/" }],
          "res": ["i-tiktokenizer", "i-tokenizer", "s-hf-course"],
          "res_en": ["i-tiktokenizer", "i-tokenizer", "s-hf-course-en"] },
        { "id": "sampling", "title": "概率与抽签", "goal": "模型给出的是概率，说出哪个词是掷骰子的结果：温度调高低，top-k 和 top-p 决定在哪些候选里抽。",
          "title_en": "Probabilities and a roll of the dice", "goal_en": "The model outputs probabilities; which word it says comes down to a roll of the dice. Temperature sharpens or flattens the odds, and top-k and top-p decide which candidates are in the draw.",
          "site": [{ "label": "推理 · D2 结构 · 采样", "label_en": "Inference · D2 Structure · Sampling", "href": "../" }],
          "res": ["i-explainer", "i-nucleus", "i-3b1b-gpt"],
          "res_en": ["i-explainer", "i-nucleus", "i-3b1b-gpt-en"] }
      ]
    },
    {
      "id": "inside", "no": "02", "title": "拆开一层", "sub": "Transformer 的内部",
      "title_en": "One layer down", "sub_en": "Inside the Transformer",
      "nodes": [
        { "id": "residual", "title": "嵌入与残差流", "goal": "每个词元先变成一条 1024 维的向量；28 层里每一层都只往这条向量上“加一点东西”，而不是替换它。",
          "title_en": "Embeddings and the residual stream", "goal_en": "Each token first becomes a 1,024-dimensional vector; each of the 28 layers only \"adds a little\" to that vector instead of replacing it.",
          "site": [{ "label": "推理 · D2 结构（嵌入）", "label_en": "Inference · D2 Structure (embedding)", "href": "../" }, { "label": "推理 · D3 层塔（残差流光柱）", "label_en": "Inference · D3 Layer tower (residual-stream beam)", "href": "../" }],
          "res": ["i-illustrated", "i-llm-viz", "i-hylee-tf"],
          "res_en": ["i-illustrated", "i-llm-viz", "i-build-gpt"] },
        { "id": "attention", "title": "注意力：Q、K、V", "goal": "每个词元用自己的 Q 去和前面每个词元的 K 打分，softmax 变成权重，再按权重把它们的 V 加起来。",
          "title_en": "Attention: Q, K, V", "goal_en": "Each token scores its Q against the K of every earlier token, softmax turns the scores into weights, and their Vs are added up with those weights.",
          "site": [{ "label": "推理 · D5 算子（注意力，16 个头可切换）", "label_en": "Inference · D5 Operators (attention, 16 switchable heads)", "href": "../" }, { "label": "多模态 · 注意力热力图", "label_en": "Multimodal · Attention heatmap", "href": "../multimodal/" }],
          "res": ["i-3b1b-attn", "i-mu-tf", "i-explainer"],
          "res_en": ["i-3b1b-attn-en", "i-annotated", "i-explainer"] },
        { "id": "ffn", "title": "前馈网络：带阀门的神经元", "goal": "注意力之后是 SwiGLU 前馈网络：3072 个神经元里只有一部分被明显点亮，模型记住的很多“知识”就存在这里。",
          "title_en": "Feed-forward: neurons with valves", "goal_en": "After attention comes the SwiGLU feed-forward network: only some of its 3,072 neurons clearly light up, and much of the \"knowledge\" the model remembers lives here.",
          "site": [{ "label": "推理 · D5 算子（神经元阵列）", "label_en": "Inference · D5 Operators (neuron grid)", "href": "../" }],
          "res": ["p-3b1b-facts", "i-llm-viz"],
          "res_en": ["p-3b1b-facts-en", "i-llm-viz"] },
        { "id": "norm-rope", "title": "位置、归一化与分组注意力", "goal": "RoPE 让模型分得清先后，RMSNorm 把数值稳在同一尺度，GQA 让几个查询头共用一组 K、V，省下一半 KV 缓存。",
          "title_en": "Position, normalization and grouped attention", "goal_en": "RoPE lets the model tell what came first, RMSNorm keeps the numbers on one scale, and GQA lets several query heads share one set of K and V, halving the KV cache.",
          "site": [{ "label": "推理 · D4 一层之内", "label_en": "Inference · D4 Inside a layer", "href": "../" }, { "label": "推理 · D5 算子（Q·K·V）", "label_en": "Inference · D5 Operators (Q·K·V)", "href": "../" }],
          "res": ["i-roformer", "i-qwen3", "i-aiayn"],
          "res_en": ["i-roformer", "i-qwen3", "i-aiayn"] },
        { "id": "madd", "title": "一次乘加，一个比特", "goal": "所有计算最后都落到 y = Σ x·w：一个输出是上千项乘积的和；每个权重存成 16 位的 bf16。",
          "title_en": "One multiply-add, one bit", "goal_en": "Every computation ends up as y = Σ x·w: one output is the sum of over a thousand products, and every weight is stored as a 16-bit bf16.",
          "site": [{ "label": "推理 · D6 一次乘加", "label_en": "Inference · D6 One multiply-add", "href": "../" }, { "label": "推理 · D7 比特", "label_en": "Inference · D7 Bits", "href": "../" }, { "label": "多模态 · D5 一次乘加", "label_en": "Multimodal · D5 One multiply-add", "href": "../multimodal/" }],
          "res": ["i-bf16", "i-llm-viz", "i-build-gpt"],
          "res_en": ["i-bf16", "i-llm-viz", "i-build-gpt"] }
      ]
    },
    {
      "id": "learn", "no": "03", "title": "它是怎么学会的", "sub": "预训练、优化、微调与对齐",
      "title_en": "How it learns", "sub_en": "Pretraining, optimization, fine-tuning, alignment",
      "nodes": [
        { "id": "loss", "title": "损失与梯度下降", "goal": "训练 = 算出答错了多少（交叉熵），再用反向传播求出每个权重的梯度，沿着让损失变小的方向挪一点。",
          "title_en": "Loss and gradient descent", "goal_en": "Training = measure how wrong the answer was (cross-entropy), use backpropagation to get every weight's gradient, then nudge each weight a little in the direction that lowers the loss.",
          "site": [{ "label": "训练 · D1 训练全程（损失曲线、损失地形）", "label_en": "Training · D1 Whole run (loss curve, loss landscape)", "href": "../train/" }, { "label": "训练 · D4 一个位置的交叉熵", "label_en": "Training · D4 Cross-entropy at one position", "href": "../train/" }],
          "res": ["t-3b1b-gd", "t-3b1b-bp", "s-d2l"],
          "res_en": ["t-3b1b-gd-en", "t-3b1b-bp-en", "s-d2l-en"] },
        { "id": "pretrain", "title": "预训练：从零训练一个小模型", "goal": "用几百万字的唐宋诗从零训练一个和 Qwen3 同构的小模型，看损失一路下降、写出来的诗越来越像样。",
          "title_en": "Pretraining: a small model from scratch", "goal_en": "Train a small model with Qwen3's architecture from scratch on a few million characters of Tang and Song poetry; watch the loss fall and the poems get better.",
          "site": [{ "label": "训练 · 唐宋诗小模型（D1 预训练全程）", "label_en": "Training · Tang & Song poetry model (D1 whole pretraining run)", "href": "../train/" }],
          "res": ["t-hylee-pre", "t-nanogpt", "t-minimind", "i-build-gpt"],
          "res_en": ["s-karpathy-intro", "t-nanogpt", "s-llms-scratch", "i-build-gpt"] },
        { "id": "adamw", "title": "优化器：AdamW", "goal": "看懂一个权重的一次更新：梯度的一阶矩、二阶矩、偏差校正、权重衰减，以及学习率的预热和退火。",
          "title_en": "The optimizer: AdamW", "goal_en": "Understand one update of one weight: the gradient's first and second moments, bias correction, weight decay, and the learning-rate warm-up and decay.",
          "site": [{ "label": "训练 · D3 更新", "label_en": "Training · D3 Update", "href": "../train/" }, { "label": "训练 · D4 细到一个数（写回的比特）", "label_en": "Training · D4 Down to one number (bits written back)", "href": "../train/" }],
          "res": ["t-d2l-adam", "t-adamw"],
          "res_en": ["t-d2l-adam-en", "t-adamw"] },
        { "id": "align", "title": "微调与对齐：SFT、RLHF、DPO", "goal": "预训练学会“说话”，SFT 教它按对话格式回答，偏好对齐再教它在两个回答之间挑更好的那个。",
          "title_en": "Fine-tuning and alignment: SFT, RLHF, DPO", "goal_en": "Pretraining teaches it to talk, SFT teaches it to answer in chat format, and preference alignment teaches it to pick the better of two answers.",
          "site": [{ "label": "训练 · D0 流水线", "label_en": "Training · D0 Pipeline", "href": "../train/" }, { "label": "训练 · Qwen3-0.6B 三步 SFT", "label_en": "Training · Qwen3-0.6B three-step SFT", "href": "../train/" }],
          "res": ["t-hylee-sft", "t-mu-instruct", "t-hf-rlhf", "t-dpo"],
          "res_en": ["t-hf-rlhf", "t-instructgpt", "t-dpo", "t-trl"] }
      ]
    },
    {
      "id": "see-act", "no": "04", "title": "看图与动手", "sub": "多模态与智能体",
      "title_en": "Seeing and doing", "sub_en": "Multimodal models and agents",
      "nodes": [
        { "id": "vit", "title": "把图片切成词元：ViT", "goal": "图片缩放后切成 16×16 像素的小块，每块变成一个向量，再像文字一样交给 Transformer。",
          "title_en": "Images as tokens: ViT", "goal_en": "The image is resized and cut into 16×16-pixel patches; each patch becomes a vector and goes into a Transformer, just like text.",
          "site": [{ "label": "多模态 · D3 逐层（切块、ViT 24 层）", "label_en": "Multimodal · D3 Layer by layer (patches, 24 ViT layers)", "href": "../multimodal/" }],
          "res": ["m-mu-vit", "m-vit", "m-cnn-explainer"],
          "res_en": ["m-vit", "m-cnn-explainer"] },
        { "id": "vlm", "title": "图文对齐：多模态大模型", "goal": "视觉编码器的输出经过 2×2 合并拼进对话，用 M-RoPE 标上时间、高、宽三个位置；生成每个字时，注意力会落回图上。",
          "title_en": "Images meet text: vision-language models", "goal_en": "The vision encoder's output is merged 2×2 and spliced into the conversation, with M-RoPE marking three positions — time, height, width. As each word is generated, attention falls back onto the image.",
          "site": [{ "label": "多模态 · D2 流水线", "label_en": "Multimodal · D2 Pipeline", "href": "../multimodal/" }, { "label": "多模态 · D3 逐层（M-RoPE、注意力热力图）", "label_en": "Multimodal · D3 Layer by layer (M-RoPE, attention heatmap)", "href": "../multimodal/" }],
          "res": ["m-mu-clip", "m-hf-vlms", "m-qwen2vl", "m-qwen3vl"],
          "res_en": ["m-hf-vlms", "m-clip", "m-qwen2vl", "m-qwen3vl"] },
        { "id": "agent", "title": "智能体：模型 + 工具 + 循环", "goal": "让模型在循环里调用工具、读回结果、决定下一步；每一圈都把整段上下文重新喂进去，所以越滚越长。",
          "title_en": "Agents: model + tools + loop", "goal_en": "Let the model call tools in a loop, read back the results and decide the next step. Every turn feeds the whole context back in, so it keeps getting longer.",
          "site": [{ "label": "智能体 · 修好失败的测试（D1 屏幕起）", "label_en": "Agents · Fix a failing test (from D1 Screen)", "href": "../agent/#fix-median" }, { "label": "智能体 · D2 循环 · D3 上下文", "label_en": "Agents · D2 Loop · D3 Context", "href": "../agent/" }],
          "res": ["a-hylee-agent", "a-hylee-context", "a-react", "a-mini-swe"],
          "res_en": ["a-effective", "a-ctx-eng", "a-react", "a-mini-swe"] }
      ]
    },
    {
      "id": "mind", "no": "05", "title": "模型心里有没有一个世界", "sub": "世界模型与可解释性",
      "title_en": "Is there a world inside?", "sub_en": "World models and interpretability",
      "nodes": [
        { "id": "lens-probe", "title": "逻辑透镜与线性探针", "goal": "把中间层直接接到输出头上，读出模型“此刻会说什么”；再用线性探针从隐状态里读出城市的经纬度。",
          "title_en": "Logit lens and linear probes", "goal_en": "Wire a middle layer straight to the output head to read what the model \"would say right now\"; then use a linear probe to read a city's latitude and longitude out of the hidden state.",
          "site": [{ "label": "推理 · D3 层塔（逻辑透镜）", "label_en": "Inference · D3 Layer tower (logit lens)", "href": "../" }, { "label": "世界模型 · 城市探针", "label_en": "World Models · City probe", "href": "../world/" }],
          "res": ["p-logit-lens", "p-hylee-2025", "w-space-time", "p-probes"],
          "res_en": ["p-logit-lens", "w-space-time", "p-probes"] },
        { "id": "dream", "title": "世界模型：在梦里学", "goal": "VAE 把画面压成几个潜变量，RNN 预测下一步会变成什么样；有了它，智能体可以在模型“想象”出来的世界里练习。",
          "title_en": "World models: learning in a dream", "goal_en": "A VAE squeezes each frame into a few latent variables and an RNN predicts what comes next; with that, an agent can practise inside the world the model imagines.",
          "site": [{ "label": "世界模型 · 在梦里玩", "label_en": "World Models · Play in the dream", "href": "../world/" }],
          "res": ["w-worldmodels", "w-hylee-ae", "w-weng-vae", "w-dreamerv3"],
          "res_en": ["w-worldmodels", "w-weng-vae", "w-dreamerv3"] },
        { "id": "circuits", "title": "电路与特征", "goal": "把模型拆成看得懂的部件：几个注意力头连成的“电路”，稀疏自编码器找出的“特征”，以及它们为什么会在那里。",
          "title_en": "Circuits and features", "goal_en": "Break the model into parts you can understand: \"circuits\" made of a few attention heads, \"features\" found by sparse autoencoders, and why they are there.",
          "site": [{ "label": "推理 · D5 算子（注意力汇聚）", "label_en": "Inference · D5 Operators (attention sink)", "href": "../" }],
          "res": ["p-framework", "p-monosemanticity", "p-tracing", "p-neuronpedia"],
          "res_en": ["p-framework", "p-monosemanticity", "p-tracing", "p-neuronpedia"] }
      ]
    },
    {
      "id": "diy", "no": "06", "title": "自己动手", "sub": "读论文、跑代码、做实验",
      "title_en": "Do it yourself", "sub_en": "Read papers, run code, experiment",
      "nodes": [
        { "id": "paper", "title": "读一篇原始论文", "goal": "学会一篇论文读三遍；从《Attention Is All You Need》开始，对照本站拆开的那一层逐段读。",
          "title_en": "Read an original paper", "goal_en": "Learn to read a paper in three passes; start with \"Attention Is All You Need\" and read it section by section next to the layer this site takes apart.",
          "site": [{ "label": "推理 · D4 一层之内（对照着读）", "label_en": "Inference · D4 Inside a layer (read alongside)", "href": "../" }],
          "res": ["s-mu-read", "i-aiayn", "i-mu-tf"],
          "res_en": ["s-keshav", "i-aiayn", "i-annotated"] },
        { "id": "hands-on", "title": "跑起来，改一改", "goal": "在自己电脑上跑通本页「动手试试」的片段，再用 nanoGPT 训一个自己的小模型：换一份语料、改一个超参数，看结果怎么变。",
          "title_en": "Run it, then change it", "goal_en": "Get this page's Hands-on snippets running on your own computer, then train your own small model with nanoGPT: swap in a different corpus, change one hyperparameter, and see what changes.",
          "site": [{ "label": "本页 · 动手试试", "label_en": "This page · Hands-on", "href": "#try" }],
          "res": ["t-nanogpt", "s-zero-to-hero", "s-happy-llm", "p-transformerlens"],
          "res_en": ["t-nanogpt", "s-zero-to-hero", "s-llms-scratch", "p-transformerlens"] }
      ]
    }
  ]
}
