【科普】大模型应用的回复为什么是打字机的效果?
用户在使用由大模型驱动的应用时,例如ChatGPT(OpenAI)、Gemini(Google)、Deepseek、豆包(字节)和元宝(腾讯),常常会注意到一种引人入胜的“打字机效果”。文本似乎是一个字一个字(更准确地说,是一个token一个token)地逐渐显现,营造出一种类似人类实时打字的互动感和模型以人类似的方式即时生成响应的印象。虽然这种效果在用户界面上增强了交互体验,但它并非仅仅是一个视觉上的技巧,而是 大模型(LLM)底层文本生成方式的直接体现。 语言的基本单元——Token 要理解 LLM 如何产生这种“打字机效果”,首先需要认识到这些模型并非像人类那样直接处理词语,而是以更细粒度的单位——“token”为基础进行操作。文本可以按照不同的粒度进行切分和表示,这个过程称为 tokenization。之前写过一篇科普的文章《大模型中常说的 token 和 Tokenizer 是指什么?》专门介绍过这个知识,这里再稍微讲一下。 常见的 tokenization 方法包括:词语级别、字符级别和子词级别。词语级别的 tokenization 是最直观的方法,它根据空格和标点符号将文本分割成单独的词语。例如,“The quick brown fox jumps.”会被分割成。字符级别的 tokenization 则将文本中的每一个字符(包括字母、数字、空格和标点符号)都视为一个独立的 token。对于同样的句子,字符级别的 tokenization 会产生。 在现代LLM中,子词级别的 tokenization 是一种更为复杂且广泛应用的技术。这种方法旨在平衡词语级别和字符级别 tokenization 的优缺点,将词语分解成更小但更频繁出现的单元。例如,“unbreakable”可能会被分解成[“un”, “break”, “able”]。在子词tokenization的技术中,字节对编码(Byte-Pair Encoding, BPE)被包括 OpenAI、Gemini和 Deepseek 在内的许多主流 LLM 所采用。BPE 的优势在于能够有效地处理罕见词或词汇表外的词语,通过将它们分解成已知的子词来表示,同时还能减小模型的整体词汇量。在使用 LLM 时,用户输入的文本(即prompt)首先会经过 tokenization 处理,转换成模型能够理解的数字 token 序列。同样地,LLM 生成的输出也是一个 token 序列,需要通过 detokenization 的过程转换回人类可读的文本。 因此,用户所观察到的“打字机效果”本质上是这些生成的 token 被顺序地呈现或揭示的过程。根据 LLM 所采用的具体 tokenization 策略,在“打字”的每一个步骤中出现的可能是一个完整的词语、一个词语的片段(子词)甚至是单个字符。理解这一点对于解读模型的可视化输出至关重要。值得注意的是,由于不同的 LLM 可能使用不同的 tokenization 方法和维护着各自独特的 token 词汇表,因此在不同的平台之间可能会观察到“打字机效果”在粒度和视觉呈现上的细微差异。例如,一个模型可能倾向于以较大的文本块(完整的词语或频繁出现的子词)进行“打字”,而另一个模型由于采用了不同的 tokenization 策略,可能会呈现出更接近于逐字符出现的效果。另外,由于底层模型的输出直接与前端交互可能存在安全隐患问题,如暴露 API 密钥,通常采用“双重流式传输”模式,也就是 LLM 将数据流式传输到后端,然后后端再将数据重新流式传输到前端,大家最终看到的“打字机效果其实并不能真实的反映出底层 LLM 的 tokenization 策略。...