很多人对大模型有个想当然的画像:它先在内部拟好完整答案,再一字一句吐出来。真实机制朴素得多——拿着已有上下文预测下一个 token,选一个接上去,新上下文再预测下一个,循环往复。理解这条生成链,一大半关于大模型的困惑都能解开。
一个训练目标,为什么长出多样能力
预训练把海量文本切成 token 序列,训练目标只有一句话:给定前文,提高真实下一个 token 的概率。目标简单、数据无限,却逼着模型把语法、事实关联、文体、任务模式统统压缩进参数——答问题时答案常出现在后文,写代码时后文受语法约束,续写故事时人物状态决定走向。一个目标,多种行为,这是「能续写」的红利;但能续写不等于知道事实,这个边界后面还会回来。
采样参数改变选择,不改变知识
模型输出的不是答案,是概率分布。贪心解码永远选概率最高的 token,稳定但容易复读;随机采样引入变化;temperature 调分布的尖锐程度,top-p 控制候选池宽度。
想直观看到分布,用兼容 OpenAI 接口的服务把 logprobs 参数打开,返回里每个位置带着前几个候选 token 及其概率——你会发现模型在术语、数字上的不确定是有形状的。同一组提示词把 temperature 从 0.2 拉到 1.2 各跑十次,统计输出方差,参数的作用立刻从文档描述变成体感。
不同推理栈的参数行为也有差异:Ollama 本地起服务、vLLM 批量推理、云端 API 三者的默认值与边界处理并不一致,压测报告里的结论换个栈未必复现,调参前先看当前栈的实现说明。
Token 是计费单位,不是文字单位
token 是 tokenizer 按词表切出的片段,和汉字、单词都不存在固定换算。中文、英文、代码、数字的切分粒度差异很大,两段「看起来一样长」的文本消耗的 token 数可能差出一倍。上下文窗口、账单、限流全按 token 走,做应用估算成本时用字符数乘系数是靠不住的,实测才准:
import tiktoken
enc = tiktoken.get_encoding("cl100k_base")
for text in ["大模型生成机制拆解", "Transformer attention Is All You Need", "SELECT * FROM users WHERE id=42;"]:
print(len(text), "字符 ->", len(enc.encode(text)), "token")
跑一遍就会看到:同一段中文按字或按词切,token 数随词表变化;代码里标点和标识符切碎后膨胀明显。三个常见栈的 tokenizer 也各不相同,跨栈迁移时成本模型要重做。
两个延伸机制
KV 缓存与首字延迟。 自回归生成的每一步都要对全部历史上下文做注意力计算,推理栈把中间结果缓存下来(KV cache),否则每生成一个 token 都重算一遍历史。这也是为什么上下文越长,首个 token 出现越慢——延迟主要花在预处理阶段,而不是逐字生成。
投机解码。 用一个小模型先猜若干个 token,大模型并行验证,猜对的直接采纳、猜错的部分重来。验证比生成便宜,所以总吞吐能提升,代价是需要一对对齐的大小模型。这套机制不影响输出分布,只影响速度——「更快」与「更准」在这里是两回事。
流畅与正确的鸿沟
预测下一个 token 优化的是文本概率,不是世界真值。一个听起来严丝合缝的回答,可能只是符合语言模式的概率路径。参数调得再稳,也不会凭空接入新的事实来源——要最新信息、精确数字或可追责结论,出路在数据和工具链:检索挂可信来源、关键数字走工具计算、高风险结论加人工审核。
生成长度也在悄悄影响质量:每多生成一个 token,就多一次把自身输出当上下文的机会,开头的小偏差可能被逐步放大。限制最大输出、要求结构化格式、关键步骤强制调工具,都是切断错误扩散的常用手段。
把「预测下一个 token」当成所有能力的共同底座,很多产品决策会清晰起来:评估不同模型,本质是在比同一套机制上的概率分布质量;而应用层的可靠性,永远要在机制之外自己搭。

评论0