JOVANA
Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

大语言模型如何生成文本

在底层,聊天机器人是一次生成一个词元的,每一步都在一串概率上掷骰子。本文讲清这个循环是怎么运转的——以及为什么同一个提示会给出不同的回答。

一次一个词元

到现在你已经知道,大语言模型是一个Transformer,它在预训练阶段被训练去玩一个看似简单到不行的游戏:预测下一段文本。当你和它聊天时,它做的始终只有这一件事。模型从不会先在心里把整段话规划好再打出来。相反,它一次只生成一个词元,而它产出的每一个词元都会被重新喂回去,成为下一步输入的一部分。

一个词元(token)就是一小块文本——常常是一个单词,有时是像 "-ing" 这样的片段,或一个单独的字符——它由分词产生(你在前面见过像字节对编码这样的方案)。在每一步,模型读入到目前为止的全部文本,让它穿过自己的各层,输出的并不是一个词,而是为词表里*每一个*词元打的分——成千上万个数字。一个 softmax 把这些分数变成一个概率分布:一张列表,说着"下一个词元有 40% 的概率是「巴黎」,12% 是「这」,0.001% 是「香蕉」",如此覆盖整个词表。

这个循环——预测一个分布、挑一个词元、把它接上去、再重复——叫做自回归解码。"自回归"的意思无非是:每一个输出都依赖于模型自己之前的输出。文本从左到右地生长,就像一个只能选定下一个词、永远无法往前预看的写作者,直到一个特殊的"停止"词元出现,或者撞上长度上限为止。

context = tokenize(prompt)
while not done:
    scores = model(context)        # one score per vocab token
    probs  = softmax(scores / T)   # T = temperature
    next   = sample(probs)         # pick ONE token
    context.append(next)           # feed it back in
    done = (next == END) or len(context) > limit
解码循环的伪代码:预测、采样一个词元、接上、重复。

从一张概率清单到一个词

这里有个关键的缺口:模型递给你的是一个*分布*,可你需要的是恰好*一个*词元写下来。你怎么选,就叫做解码策略采样策略,它是独立于模型权重之外的另一个旋钮——你可以改它而不必重新训练任何东西。最简单的选法是贪婪解码:永远取那个概率最高的词元。听起来很稳妥,但它往往产出平淡、重复的文字,还可能卡进死循环("的的的")。

另一种做法是真正地采样:掷一个加权的骰子,每个词元被选中的机会就等于它的概率。这样一来,「巴黎」通常会赢,但并非总是,文字也因此有了多样性和生气。诀窍在于控制这枚骰子*有多爱冒险*,而这恰恰就是温度、top-k 和 top-p 让你能做的事。

温度、top-k 与 top-p

温度(temperature)在你抽取之前先重塑整个分布。注意上面循环里的 `scores / T`:把分数除以一个数 T 再做 softmax,会拉伸或压平这条曲线。低温(比如 0.2)让峰值更尖锐——最靠前的选项变得更有可能,于是输出聚焦而可预测。高温(比如 1.2)把一切压平,让稀有词元也有真正出头的机会,于是输出富有创意但更冒险。温度为 0 就退化成贪婪解码。这个旋钮就是温度采样

Top-ktop-p 走的是另一条路:在采样之前先*裁剪*这张清单,让骰子根本掷不到荒唐的词元上。Top-k 只保留概率最高的 k 个词元(比如前 40 个),其余全部清零。Top-p,又叫*核采样*(nucleus sampling),更聪明:它保留概率累加刚好达到 p(比如 0.9)的那一小撮最靠前的词元,再在其中采样。于是当模型很有把握时,top-p 可能只留下两三个候选;当它没把握时,就留下许多。这两种截断就是top-k 与 top-p 采样,实践中人们常把一个温度和一个 top-p 上限搭配着用。

上下文窗口:模型的全部世界

在每一步,模型都会读「到目前为止的全部文本」——但这能有多少,是有一道硬性天花板的。上下文窗口(也叫上下文长度)是模型一次能关注的词元数量上限:你的系统指令、对话历史、你粘贴进来的任何文档、以及正在生成的回复,全都共用这一份预算。现代模型的窗口从几千个词元到几十万个不等,但这个上限永远是有限的。

当一段对话长到超出窗口,最老的词元就会从边缘掉出去——模型字面意义上再也看不见它们了,这就是为什么一段长聊天似乎会"忘记"你开头说过的话。这个有限的窗口也是自注意力机制如此重要又如此昂贵的原因:每个词元都必须和其他每个词元相比较,所以上下文翻一倍,计算量大约要变成四倍。理解了窗口,就能解释许多真实表现,它也正是检索增强生成这类技术存在的理由——只把一个庞大知识库里最相关的那几片喂给模型,而不是一股脑全塞进去。

为什么输出会变——以及这究竟意味着什么

现在来回答那个著名的问题:同一个模型,同样的问题问两遍,你可能得到两个不同的答案。为什么?几乎总是因为采样。如果温度大于零,你就是在每一个词元处都掷那枚加权骰子,而早早的一次不同掷点,会把整句话引向一条不同的路。把温度设成 0(贪婪),模型就会变得*确定性*得多——不过即便如此,硬件在多个并行核心上累加浮点数时那点微小的数值差异,偶尔也会让一个势均力敌的抉择翻盘。

下面是诚实的那一部分,它纠正一个常见的误解。采样让文字*流畅而多样*,而不是*真实*。模型选的是在它的训练之下统计上可能的词元——它并没有一个单独的机制去核查这个说法是否正确。当最可能的接续恰好是假的,你就会得到一段自信、措辞工整的谬误:一次幻觉。调低温度能减少随机性,但它不会让模型更诚实;它只是让模型更可靠地重复它本来最可能说的话,无论对错。

再戳破两个迷思也有帮助。第一,模型并不"一次性尝试所有答案"——自回归解码严格地是一个词元接一个词元。第二,你看到的多样性并不是创造力或理解力在*涌现*的标志;它是一种你可以一路调到零的、刻意为之的随机性。这些模型真正令人惊讶之处——一个在巨大规模上训练出来的下一词元预测器,竟能翻译、能摘要、还能分步推理出它从未被明确教过的东西——来自训练的规模(参见缩放定律以及关于所谓涌现能力的争论),而不是来自你在生成时掷的那枚骰子。

把这些旋钮用起来

现在你掌握了全貌:Transformer 把上下文变成一张概率清单,采样策略把这张清单坍缩成一个词元,词元被接上,循环在一个有限的窗口里再次运行。你在生成时调的一切,都活在那个坍缩的步骤里。下面是选择设置的一份简短清单:

  1. 需要事实、代码、或任何要重复跑的东西?用低温度(0–0.3)和较紧的 top-p——可预测、聚焦、好测试。
  2. 想要头脑风暴、多样的措辞、或写小说?把温度提到 0.8–1.0,并把 top-p 放松到大约 0.95。
  3. 出现重复死循环或乱码?别盲目把温度往上拉——先加一个 top-k/top-p 截断,把不可能的词元裁掉。
  4. 长输入时撞上奇怪的容量限制?你很可能溢出了上下文窗口——精简历史,或改用检索,而不是把所有内容都粘进去。

有了这些,从原始概率到可读文章的这条路,就不再是个黑箱了。下一篇指南将完全走出文本,进入*扩散*模型和多模态模型如何生成图像——那是一个非常不同的解码故事,却建立在同一个想法之上:把一个学到的分布变成某种具体的东西。