本节摘要:124M 是不是"太小"?这个问题只有实验能回答。本节借 TinyStories(微软 2023 年工作:用强模型合成、仅用幼儿词汇的儿童故事语料)做镜子——论文口径的核心发现是:参数量低至百万级的小模型,在这种与自身容量匹配的语料上也能产出语法连贯、情节一致的英文故事。对本书的启示:小模型的能力边界主要不在参数量,而在"任务要求与模型容量的匹配度"。本节给出一套控制变量的实验设计(自变量:数据与规模;因变量:loss 加 5.1 探针;控制变量:步数、超参、模板、种子)、一张能力边界清单(小模型能做什么、做不了什么)、以及不重训基座也能跑的最小对照路径(TinyStories 当 SFT 数据,直接复用第 3 章管线)。规模实验的方法论比结论重要——它是你此后一切自训模型的体检流程。
阅读完本节,你应当能够:
TinyStories 的做法(论文口径):让 GPT-3.5/GPT-4 大批量生成儿童故事——词汇限于幼儿水平、情节简单、句式干净。核心发现:在这种语料上,百万级参数的小模型也能生成连贯、一致、有情节的英文故事——而同规模模型在海量通用语料上训练,只能产出语法破碎的文本。
对照 nanochat 的处境:124M 在 FineWeb-Edu(通用网页)上训练,是"小模型扛不匹配的大任务"——知识有限、推理弱是结构性的;TinyStories 证明的是另一头的可行性——把任务说窄,小模型就能发光。两个常见误会的解药都在这里:其一,"多喂点数据会不会更聪明"——容量匹配不上,loss 降了能力也长不出来(5.1 的对照读法);其二,"小模型没用"——场景说窄(儿童故事、固定格式生成、模板化客服),它完全胜任。
💡 TinyStories 与 5.1 的探针是天生一对:观察涌现的经典提示(Once upon a time...)本身就是儿童故事开场白——用故事语料训练、用故事探针测量,课程与量尺同构,涌现的台阶看得格外清楚。
| 角色 | 内容 | 说明 |
|---|---|---|
| 自变量 A:数据 | TinyStories vs FineWeb-Edu 等量采样 | 语料公开于 HuggingFace(规模以数据集卡为准) |
| 自变量 B:规模 | 124M vs 缩小配置(如约 30M:减层减宽) | 重训基座走《ht-gpt:从零搭建 GPT 训练与推理实战》训练章,本书不重讲 |
| 因变量 | loss 曲线 + 5.1 故事探针 + 5.2 题库分数 | 质性定量都测——只看 loss 会漏掉涌现 |
| 控制变量 | 步数、超参、模板、种子、探针题组 | 一次动两个,结论作废 |
另一条容易被忽略的控制变量:两组数据的 token 总量要对齐(见 8.1 的分词效率测量),否则"数据匹配度"的结论里混进了"数据量"的差异——单变量原则连数据预算也要管。
不重训基座的最小路径(本书范围内可完整跑通):把 TinyStories 包装成对话数据("讲一个小狗交朋友的故事"→ 一篇故事,messages 契约照旧),当 SFT 数据喂给 124M 基座——与 2.2 英文开源集的 SFT 形成"数据匹配度"对照:同模型、同超参、同探针,只有数据不同。
# tinystories_probe.py —— 故事探针对比(写法示意,探针纪律见 5.1) import torch from transformers import AutoModelForCausalLM, AutoTokenizer STORY_PROBES = [ # 固定提示:语言简单、情节开放,专测叙事能力 "Once upon a time there was a little girl named Lily.", "One day, a small dog found a big red ball.", ] def story_check(ckpt: str) -> None: tok = AutoTokenizer.from_pretrained(ckpt) model = AutoModelForCausalLM.from_pretrained(ckpt, dtype=torch.bfloat16) for p in STORY_PROBES: ids = tok(p, return_tensors="pt").input_ids # 基座式续写探针 torch.manual_seed(7) # 固定种子:数据是唯一变量 out = model.generate(ids, max_new_tokens=100, do_sample=True, temperature=0.7, top_p=0.9, pad_token_id=tok.eos_token_id) print(f"[{ckpt}] {tok.decode(out[0], skip_special_tokens=True)}\n") del model if __name__ == "__main__": story_check("runs/sft_124m_openhermes/final") # 对照组:通用指令数据 story_check("runs/sft_124m_tinystories/final") # 实验组:容量匹配数据
预期(示意假设,实验来裁决):TinyStories 组的故事语法连贯度与情节完整度显著更好;但 5.2 题库的事实问答两边都弱——窄语料买不来知识,匹配买的是"流畅",不是"博学"。
| 小模型(124M 量级)能做 | 做不了/不可靠 |
|---|---|
| 短篇连贯叙事(容量匹配语料上) | 事实准确性(知识密集问答会编) |
| 固定格式的生成(四行诗、清单) | 多步推理(算术、逻辑链) |
| 模板行为(会停、守身份、遵形式) | 长程一致(长文前后矛盾) |
| 语气与人设扮演 | 开放域闲聊不露馅——跨度一大就现形 |
清单的用法是双向的:对内,为模型挑任务(把交付场景说窄);对外,向使用者说清预期(它是"故事机/格式器",不是百科)。这也是 5.2 题库分层抽样时各层预期不同的原因——边界内的层应得高分,边界外的层考了也白考。
💡 边界清单也是产品文案:把"能做什么/做不了什么"写进 system 提示与使用说明——用户预期对了,"模型很笨"的投诉就少一半。8.1 的中文人设提示是同一件事的语言版。
要真正动"规模"这个自变量,需要重训基座——回《ht-gpt:从零搭建 GPT 训练与推理实战》的训练章调层数与宽度,产出多个基座后再各跑一遍第 2~3 章 SFT 与第 5 章评测。工程要点三条:一次只动一个规模维度(减层数或减宽度,不要同时动);所有配置共用同一种子与步数预算;每个基座都过 1.2 的验收脚本再进 SFT。这条完整路径超出本书主线,但本节的测量骨架(探针 + 题库 + 台账)在哪个规模上都成立——换规模不换量尺,跨规模的曲线才可比。
另一个省钱技巧:规模实验的预训练按 5.1 的探针提前收——涌现到位即可停,不必跑满步数预算;比较发生在"同等涌现水平"上比"同等步数"上更公平(附录 B 的省钱纪律同源)。
至此改造实验的两条路(换语言、换规模)都走过了——最后把目光投向 SFT 之后的世界:8.3 节在 RLHF 与 DPO 门前立一块路标。