5.1 中期评测:故事生成与能力涌现


5.1 中期评测:故事生成与能力涌现

本节摘要:loss 曲线告诉你模型"平均猜词准不准",但说不清它"会不会讲一个有头有尾的故事"——这中间隔着一层台阶式的能力涌现。社区 walkthrough 在 nanochat 预训练途中反复用同一个"直升机故事"提示让模型续写,亲眼看着输出从乱码、成词、成句、复读到成段情节逐级点亮(社区实测口径)。本节把这套做法提炼成正式的中期评测方法:探针三固定纪律(固定提示、固定解码、固定长度)、基座与 SFT 两条涌现观察清单、以及与 3.2 节 loss 三阶段的对照裁决——loss 说"还在学",探针说"学成了什么",两张图放在一起,才敢做继续、回退还是收手的决定。

学习目标

阅读完本节,你应当能够:

  1. 说出 loss 回答不了、探针能回答的问题,并解释能力涌现为什么是台阶状的。
  2. 按"三固定"纪律为基座与 SFT 各设计一组探针任务。
  3. 用两条涌现观察清单给 checkpoint 分期,识别"学好了"与"学坏了"的信号。
  4. 把探针结果与 3.2 的 loss 三阶段对照,做出继续/回退/收手的判断。

一、loss 的盲区

loss 是全体验证 token 的平均交叉熵——一个数字概括百万次预测的平均误差。它有两个先天盲区:

问题 loss 的回答 为什么不够
模型会讲连贯的故事吗 只能给一个平均分 连贯是句与句之间的关系,单步猜词的误差累不出现象
能力是什么时候出现的 看不出来 涌现是台阶状的:某能力常在一段步数后突然可辨,loss 却平滑下降
该不该提前收手 val 拐点给一半答案 拐点说"开始背数据了",但"行为最好的那一格"还得看生成

社区 walkthrough 的直观发现(对 nanochat 预训练的公开复现日志):预训练 loss 从 10.4 一路降到 2.32(6,612 步,社区实测),曲线平滑得没有任何故事;但每隔一段就用同一个提示让模型写"直升机的故事",输出质量却在几个步数区间里明显跳档——loss 是平均数,能力是切片。中期评测就是定期切几片下来看。

二、探针任务设计:三固定

探针(probe):一组写死在脚本里、每隔若干 checkpoint 对模型跑一遍的固定生成任务。纪律是三固定:

  1. 固定提示:题组硬编码,一字不改——改一个词,前后对比全部作废;
  2. 固定解码:贪心解码(temperature=0),或固定种子 + 固定温度——4.2 的评测回归行早已立下此约定;
  3. 固定长度max_new_tokens 固定——长度本身也是观测量(模型何时停、会不会停)。

基座探针题组(预训练途中用,英文为主——FineWeb-Edu 喂出来的基座"母语"是英文):

探针 提示(示意) 观察什么
直升机故事 Once upon a time there was a little helicopter... 从乱码到情节的涌现主刻度(社区 walkthrough 同款)
常识补全 The sun rises in the ... 高频搭配是否形成
自由续写 截一段百科首句 题材漂移与复读倾向

SFT 探针题组(训练途中每几百步一次,3.2 已埋点):观察项直接取自 0.1 的行为差异三表现——事实问答(答完会停吗)、身份(你是谁)、指令("写一首四行小诗"是否照做)、多轮("第二句是什么意思"接得住指代吗)。

# probe_checkpoints.py —— 对多个 checkpoint 跑固定探针题组(写法示意) import torch from transformers import AutoModelForCausalLM, AutoTokenizer PROBES = [ # 三固定之一:提示硬编码 {"role": "user", "content": "用两句话讲一个关于直升机的小故事。"}, {"role": "user", "content": "你是谁?"}, {"role": "user", "content": "写一首关于秋天的四行小诗。"}, ] def probe(ckpt: str) -> None: tok = AutoTokenizer.from_pretrained(ckpt) model = AutoModelForCausalLM.from_pretrained(ckpt, dtype=torch.bfloat16) for msg in PROBES: ids = tok.apply_chat_template([msg], tokenize=True, add_generation_prompt=True, return_tensors="pt") out = model.generate(ids, max_new_tokens=80, do_sample=False) # 三固定之二:贪心 text = tok.decode(out[0][ids.shape[1]:], skip_special_tokens=False) print(f"[{ckpt}] {msg['content'][:12]}... -> {text}") # 三固定之三:80 token del model if __name__ == "__main__": for ckpt in ["runs/sft_124m/checkpoint-200", "runs/sft_124m/checkpoint-600", "runs/sft_124m/final"]: probe(ckpt)

把输出按 checkpoint 顺序贴进一页文档,就是最便宜的能力成长日志——3.2 要求的"每几百步抽问固定问题",从此有脚本可依。

三、涌现观察清单

基座预训练阶段(对照社区 walkthrough 的直升机故事观察,分期位置随种子与数据浮动,示意口径):

生成样貌 直升机故事的样子
乱码期 无意义字符流 字母堆,无空格
成词期 高频英文单词,无语法 helicopter 一词反复出现但不成句
成句期 局部语法正确,句间无关 The helicopter was a helicopter. 式循环
复读期 单句/单段无限重复 同一句话写到 80 token 上限
成段期 句间连贯,有简单情节 有起因、动作、结尾,会自己停

SFT 阶段的清单(对照 0.1 三表现,出现顺序大体如下):

观察项 通过标准
格式期 special tokens 排布 输出不再以标记开头,回答后跟终止符
停止期 答完即停 不再顶到 max_new_tokens 上限
身份期 "你是谁" 以助手自居,不替用户编话
指令期 写诗/列举类任务 按指令的形式约束输出
多轮期 指代与追问 结合上文回答,不装失忆

⚠️ 涌现点不是里程碑:换种子、换数据,台阶会移位。清单的用途是分期与沟通,不是"loss 降到 X 必然会 Y"的预测表——把分期写死进自动流程,是过拟合评测的另一种形态。

四、与 loss 曲线对照

把 3.2 的 SFT loss 三阶段和探针放在同一横轴上:

loss 阶段(3.2) 探针典型表现 决策
快降区(前 ~10%) 格式与停止迅速到位(SFT);成词成句(基座) 正常,继续
平台区 内容质量缓慢爬升;探针进步停滞但 val 未升 再观察一个存档周期
过拟合区(train 降 val 升) 3.2 三征兆在探针上现形:复读、变短变小、逐字复述 回退上一个健康 checkpoint

交叉裁决的两条经验:

  1. loss 说"还在学"、探针说"学坏了"——听探针的。val loss 还没回升但探针已现复读,先回退:行为先坏、指标后坏是常态(3.2 的抽检伏笔正是为此)。
  2. loss 平、探针平:两证齐全才是真平台——这时该动的是数据或超参(回 2.2/3.2),不是更多步数。

本节要点回顾

  1. loss 是平均数、能力是切片:中期评测用"三固定"探针定期切片,直升机故事是社区 walkthrough 的经典刻度。
  2. 两条清单:基座看乱码→成词→成句→复读→成段;SFT 看格式→停止→身份→指令→多轮。
  3. 与 3.2 三阶段对照裁决:探针学坏了就回退,两平才是真平台——两张图合起来才做决定。

训练途中的观察能力有了;训练完成之后,"它到底会不会聊天"需要一张正式的记分牌——5.2 节搭 rubric、裁判与抽检表。


作者与出处
原作者: 灏天文库
整理: 灏天文库整理
本站整理收录,版权归原作者/开源协议所有;欢迎通过原文链接访问源仓库。
发布者: 作者: 灏天文库 转发
评论区 (0)
U