分支⑦ 模型从哪来、怎么跑
这条分支站在什么位置: 前六条分支都默认「模型已经存在、能调」;这条分支讲那块地基本身——一个 LLM 是怎么造出来的(零件、训练、并行、数据),造好之后怎么跑得起、跑得快(推理引擎、量化、kernel),以及怎么量它好不好。29 个子库全部已有完整拆解(doc 在
../<id>/),本章是它们的地图与横向对比。
1. 这条分支是什么(第一性原理)
原始 LLM 是「一次性、无状态地预测下一段文字」的函数。这个函数不是天上掉下来的——它是一条模型生命周期管线的 产物:
零件 造出来 跑起来 量它
(能读懂的机制) (训练这条命) (推理这件工程) (评测本身)
autograd/BPE 预训练→后训练→规模化 kernel→KV cache→批调度 基准/嵌入质量
│ │ │ │
micrograd pytorch flash-attention lm-eval-harness
nanogpt/minbpe trl/peft/megatron vllm/sglang lighteval
llm-c/tinygrad datatrove/dolma llama-cpp sentence-t…
分支里的库,差别在管线的哪一段(零件/训练/推理/评测)、站在哪个抽象层(教学实现/生产框架/底层 kernel)、优化什么(可读性/吞吐/显存/可复现)。
2. 分支内有哪几种做法(流派)
- 零件课(从零可读):把一件大事压缩到一个下午能读完的尺寸——教学价值高于生产价值。
- 训练栈(造模型):底座框架 → 后训练方法库 → 大规模并行 → 数据管线,一层压一层。
- 推理服务(跑模型):注意力 kernel 打底,上面是 KV cache 管理 + 连续批调度的 serving 引擎。
- 模型评测 + 嵌入:评的是模型本身(与分支⑥ 评 agent 是不同问题);嵌入库把句子变成可检索的向量。
3. 对比矩阵(子库区别,逐格接地)
3.1 零件课:从零可读的最小实现
| 库 | 讲透什么 | 一句话差异 | 代码锚点 |
|---|---|---|---|
| micrograd | 反向传播的全部本质 | 约 90 行 Value 类:前向存局部链式法则闭包,反向按拓扑序倒调 | doc;micrograd/engine.py |
| nanogpt | GPT 训练循环 | 两个各约 300 行文件读完 decoder-only Transformer + DDP/混合精度/余弦 LR 全流程 | doc;model.py、train.py |
| minbpe | BPE 分词 | 约 500 行纯 Python:训练=反复合并最高频相邻字节对,编码=按合并表贪心重演 | doc;minbpe/basic.py、regex.py |
| nanochat | 全管线串讲 | tokenizer→预训练→SFT/RL→serve 装进一个仓库,--depth 一个旋钮按 scaling law 推出宽/批/LR | doc;scripts/base_train.py |
| llm-c | 手写 CUDA 训练 | GPT-2 预训练从 PyTorch 拆出来:约 1000 行纯 C CPU 参考 + 「一层一个文件」的手工 kernel | doc;train_gpt2.c、llmc/ |
| tinygrad | 可读张量框架 | 自我限制行数的完整栈:Tensor 是 UOp 薄壳,懒图切 kernel,编译器生成各后端源码 | doc;tinygrad/tensor.py、schedule/ |
怎么选: 入门读 micrograd→nanogpt→minbpe(各一个下午);想看「没有抽象遮掩的 GPU 训练」读 llm-c;想看「可读的生产级框架」读 tinygrad。
3.2 训练栈:造模型
| 库 | 管哪段 | 一句话差异 | 代码锚点 |
|---|---|---|---|
| pytorch | 底座 | Python 前端 → ATen 注册表 → dispatcher 按 dispatch key 选 kernel → autograd 引擎按图反向 | doc;torch/csrc/autograd/engine.cpp |
| transformers | 架构图书馆 | 507 个架构目录统一成单文件参考实现 + 三个共享底座(PreTrainedModel/GenerationMixin/Trainer) | doc;src/transformers/models/ |
| tokenizers | 分词 | 四段可组合流水线(Normalizer→PreTokenizer→Model→PostProcessor),Rust 核心逐字节对齐 | doc;tokenizers/src/ |
| hf-datasets | 数据装载 | Arrow 内存映射 + 按函数字节码算指纹的磁盘缓存,map/filter 第二次运行零成本命中 | doc;src/datasets/arrow_dataset.py |
| accelerate | 环境适配 | Borg 单例摸清进程拓扑,prepare() 给普通 PyTorch 对象包上分布式/混合精度外壳 | doc;src/accelerate/accelerator.py |
| trl | 后训练方法族 | SFT/DPO/KTO/GRPO/RLOO/蒸馏各自收进一个 Trainer,同一数据约定下逐行对比 | doc;trl/trainer/ |
| peft | 参数高效微调 | 44 种 PEFT 方法共用注册表,get_peft_model 一行把适配层按模块名注入任意 nn.Module | doc;src/peft/tuners/ |
| unsloth | 微调加速 | 不重写训练栈,把 transformers 的前向/反向逐个换成手写 Triton kernel + 手工 autograd | doc;unsloth/kernels/ |
| open-r1 | 训练配方 | 非框架:DeepSeek-R1 管线的开放复现配方库,薄胶水脚本串起 trl + vLLM + lighteval | doc;src/open_r1/ |
| torchtune | 原生微调 | 后训练写成能整篇读懂的普通 PyTorch 脚本,YAML _component_ 经 instantiate 递归装配 | doc;recipes/ |
| megatron-lm | 大规模并行 | 五维正交切分(TP/PP/DP/CP/EP)各落成通信原语与进程组,3D 并行的语汇策源地 | doc;megatron/core/ |
| deepspeed | 显存规模化 | ZeRO 三级分片把优化器状态/梯度/参数摊薄到 1/N,叠加 CPU/NVMe offload | doc;deepspeed/runtime/zero/ |
| megablocks | MoE 计算 | 变长专家输入重构成 block-sparse 矩阵或 grouped GEMM 两种规整形态,dropless | doc;megablocks/layers/ |
| olmo | 全公开预训练 | 代码+数据配方+全部中间 checkpoint+训练日志+复盘全公开,严肃的完整生命周期样本 | doc;olmo/ |
| datatrove | 数据管线 | 「读→过滤→去重→token 化」抽象成 Document 生成器链,FineWeb 的生产工具 | doc;src/datatrove/pipeline/ |
| dolma | 语料生产线 | 文档与标注分存:tagger 只写 attributes,mixer 最后按配置做 span 级外科手术 | doc;python/dolma/ |
怎么选: 理解机制从 trl/peft 进(方法间可直接对比);上规模看 megatron-lm(并行语汇)+ deepspeed(显存);做数据看 datatrove(管线抽象)与 dolma(标注先行);olmo 是「完整项目长什么样」的唯一全公开样本。
3.3 推理服务:跑模型
| 库 | 核心机制 | 一句话差异 | 代码锚点 |
|---|---|---|---|
| flash-attention | IO 感知 kernel | tiling + online softmax + 反向重计算,N×N 注意力矩阵从不落地 HBM,memory-bound 变 compute-bound | doc;flash_attn/ |
| vllm | KV cache 分页 | PagedAttention:OS 式「分页+引用计数+哈希缓存」管 KV cache,配 continuous batching 每步重组批 | doc;vllm/v1/ |
| sglang | 前缀共享 + 结构化输出 | RadixAttention 用基数树跨请求共享 KV 前缀;三进程 ZMQ 流水线;约束解码 FSM | doc;python/sglang/srt/ |
| llama-cpp | 本地推理全栈 | 纯 C/C++:ggml 张量库 + GGUF 格式 + K-quants 量化 + libllama + server 外壳 | doc;ggml/、src/ |
怎么选: 云端高吞吐 serving 选 vllm(生态最大)或 sglang(前缀共享/结构化输出强);本地/边缘跑 GGUF 用 llama-cpp;flash-attention 是它们共同踩着的 kernel 层,读它理解「为什么快」。
3.4 模型评测 + 嵌入
| 库 | 干什么 | 一句话差异 | 代码锚点 |
|---|---|---|---|
| lm-evaluation-harness | 模型基准 | YAML 任务注册表把每道题变成 loglikelihood/generate_until 请求,可复现流水线 | doc;lm_eval/tasks/ |
| lighteval | 模型基准(训练集成) | 声明式任务→Doc 样本→按采样方式聚类发后端;nanotron 后端可直评训练中的 checkpoint | doc;src/lighteval/ |
| sentence-transformers | 句子嵌入 | 「句子→向量」做成 nn.Sequential 模块链,in-batch negatives 对比损失;SPLADE/ColBERT 变体 | doc;sentence_transformers/ |
怎么选: 报分数用 lm-evaluation-harness(事实标准);训练中持续评 checkpoint 用 lighteval;要检索向量用 sentence-transformers(双塔入门,稀疏/多向量进阶)。注意它们评的是模型本身;评 agent(轨迹、工具使用、多轮)回分支⑥。
4. 模式与权衡
- 可读性与性能是这条分支的主轴。 零件课(90~500 行)讲透机制但算不动真的;生产库(pytorch/megatron)算得动但机制埋在工程里。学的时候从小的进,用的时候从大的进——两层之间的概念是一一对应的。
- 训练侧的分层是稳定的: 底座框架(pytorch)→ 架构库(transformers)→ 微调方法(trl/peft/torchtune)→ 规模化(megatron/deepspeed)。每层只跟自己上下两层打交道;选型时先定你在哪一层缺东西。
- 推理侧的取 舍是「通用 vs 贴身」。 vllm/sglang 做云端多租户吞吐,工程重;llama-cpp 做本地单用户延迟,牺牲吞吐换零依赖与量化极致。两条路线的 KV cache 哲学(分页 vs 基数树 vs cell 记账)值得对比读。
- 数据管线没有银弹,只有配比。 datatrove 与 dolma 都公开了完整配方——结论是「数据清洗」在预训练规模就是一连串具体的过滤/去重/混合决策,没有一步到位的魔法。
- 评模型与评 agent 是两套词汇。 模型基准(loglikelihood 比选项、perplexity、pass@k)与 agent 评测(轨迹判分、工具成功率)别混用;本章 3.4 与分支⑥ 各自管一摊。
5. 趋势
- 教学实现与生产实现对齐。 nanochat 这类「全管线最小可读仓库」正在把「读懂一切」的门槛降到一个人一个周末;它与生产栈(trl/vllm)的概念映射越来越一一对应。
- 后训练方法在 TRL 一家收编。 SFT/DPO/GRPO 同一接口共处,方法对比从「读三篇论文三个仓库」变成「同库逐行 diff」。
- 推理引擎的差异化从 kernel 转向调度。 注意力 kernel 收敛(flash-attention 成为公共底座),竞争点上移到前缀共享(radix)、结构化输出、PD 分离部署。
- 数据与评测成为新的护城河。 模型代码趋同后,数据配方(datatrove/dolma/olmo 全公开)与可复现评测(lm-eval/lighteval)成了「能不能复现一个模型」的真正瓶颈。
6. 代表作 + 深入
- 一个下午读懂一个机制 → micrograd(autograd)/ nanogpt(训练循环)/ minbpe(分词)。
- 把全管线串起来 → nanochat;再看 olmo 的「严肃项目完整生命周期」。
- 读懂生产框架 → pytorch(底座)→ transformers(生态)→ trl(后训练)。
- 上规模 → megatron-lm(并行语汇)+ deepspeed(显存)+ megablocks(MoE)。
- 推理引擎 → vllm(主线);对照 sglang 的前缀共享与 llama-cpp 的量化哲学;kernel 层读 flash-attention。
- 模型怎么量 → lm-evaluation-harness;训练中期评测接 lighteval。