大模型原理:从 token 到涌现能力
目标:建立一套能解释「大模型为什么这样表现」的模型。
会调 API 的人很多,能解释「为什么它答不对、为什么它在长上下文里变傻」的人很少 —— 后者才是能解决问题的人。
一、完整链路:一句话的旅程
循环直到任务完成或达到步数上限
关键认知:模型一次只产出一个 token。 你看到的整段回答,是一次次「预测下一个词」拼出来的。这解释了:
| 现象 | 原因 |
|---|---|
| 输出有延迟,且越长越慢 | 逐 token 生成,串行 |
| 开头慢、后面快(相对) | 首 token 要处理完整 prompt(prefill),之后每步只处理 1 个(decode) |
| 会说错但语气很肯定 | 它在做「最合理的续写」,不是「查证事实」 |
| 同样问题答案不同 | 采样有随机性(temperature > 0) |
二、Tokenizer:为什么模型数不对字数
文本被切成分词单元(token),一个中文汉字通常 1–2 个 token,英文单词可能拆成多个。
# 用 transformers 观察切分
from transformers import AutoTokenizer
tok = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B-Instruct")
ids = tok("人工智能正在改变世界")
print(len(ids["input_ids"]))
print(tok.convert_ids_to_tokens(ids["input_ids"]))这解释了几件事:
| 现象 | 原因 |
|---|---|
| 「strawberry 里有几个 r」容易错 | 它看到的是 token 片段,不是字符 |
| 中文字数计费比英文贵 | 中文 token 密度更低(同样内容 token 更多) |
| 生僻字/emoji 效果差 | 被拆成多个 token 或落到 <unk> |
| 上下文窗口按 token 算 | 不是按字数 |
估算:中文约 1 字 ≈ 1.5 token,英文约 1 词 ≈ 1.3 token,代码压缩率高。计费与显存都按 token 算。
三、预训练:它到底学了什么
训练目标只有一个:给定前文,预测下一个 token,用海量文本做自监督。
| 阶段 | 数据 | 学到 | 成本量级 |
|---|---|---|---|
| 预训练 | 数万亿 token 的网页/书籍/代码 | 语言、世界知识、推理模式 | 千万美元级 |
| 后训练(SFT) | 几十万条指令-回答 | 听懂指令、按格式回答 | 万美元级 |
| 对齐(RLHF/DPO) | 人类偏好对比数据 | 更有用、更安全、更符合偏好 | 万美元级 |
预训练是「读书」,后训练是「学规矩」。 你只能做后两步。
四、缩放律(Scaling Law):为什么要更大
经验规律:模型参数 N、数据量 D、算力 C 增加时,损失按幂律下降。
$$L \approx aN^{-\alpha} + bD^{-\beta} + L_\infty$$
推论(Chinchilla 结论):参数量与数据量应大致等比扩张,大约每 1 个参数配 20 个 token 是「计算最优」;但为了降低推理成本,现在更多用「过训练」(更多数据训更小模型)。
对你的实际意义:
| 结论 | 实践含义 |
|---|---|
| 小的提升需要成倍的资源 | 别指望「多训两天」有质变 |
| 数据质量比数量更关键 | 清洗 1% 的高质量数据常胜过堆 10% 网页 |
| 能力不是线性的 | 某些能力在规模阈值后突然出现(涌现) |
五、涌现能力:为什么小模型教不会
某些能力(多步推理、指令跟随、上下文学习)在规模较小的时候接近随机,越过某个体量后突然可用。
工程启示:
| 现象 | 应对 |
|---|---|
| 换小模型后「推理类任务」断崖式下降 | 不是 Prompt 的问题,是能力不存在。换回大模型或拆解任务 |
| 小模型做单步分类很准 | 用「小模型做窄任务 + 大模型做规划」的分层架构,成本大降 |
| 大模型能 few-shot 学会 | 小模型往往需要真正微调 |
六、上下文窗口:为什么「塞进去」不等于「用得上」
| 概念 | 含义 |
|---|---|
| 上下文窗口 | 单次请求能容纳的最大 token 数(如 128K) |
| 有效上下文 | 模型实际能可靠利用的长度,通常远小于标称值 |
「迷失在中间」(lost in the middle)现象:放在上下文首尾的信息被利用得好,中间的最容易被忽略。
工程应对:
| 做法 | 说明 |
|---|---|
| 关键信息前置或后置 | 系统提示与任务指令放头尾 |
| 分块处理 + 汇总 | 不要一次塞 200 页 |
| 检索优于堆砌 | 用 RAG 只放真正相关的片段 |
| 结构化标注 | 用 ### 文档1 这类分隔符明确边界 |
| 定期压缩对话 | 长会话做摘要而不是无限追加 |
七、采样参数:控制输出的四个旋钮
| 参数 | 作用 | 建议 |
|---|---|---|
temperature | 越低越确定,越高越发散 | 抽取/分类 0–0.3;创作 0.8–1.0 |
top_p | 从累计概率前 p 中采样 | 0.9(配 temperature 用) |
top_k | 只从概率前 k 个中采样 | 常用 40–50,一般不调 |
max_tokens | 输出上限 | 按场景设,避免话痨 |
frequency_penalty / presence_penalty | 抑制重复 | 长文生成时 0.1–0.5 |
stop | 停止序列 | 结构化输出必设 |
一条经验
需要可复现/可解析 → temperature=0(或极低)+ top_p=1 + 严格格式。需要创意 → 提高 temperature,但同时要接受不稳定性。
八、常见的「模型能力」误解
| 误解 | 实情 |
|---|---|
| 「它知道实时信息」 | 知识截止于训练数据,实时信息靠工具/检索 |
| 「它理解你在想什么」 | 它只看到你写的 token |
| 「它记得住上次对话」 | 无状态 API,每次都要带上下文 |
| 「它推理能力像人」 | 是在做模式续写,长链条推理容易断 |
| 「参数量大就一定好」 | 训练数据、指令微调质量、推理配置同样关键 |