LLM 学习笔记 1——Transformer

该研究研究了,早该研究啦。整蛊的地方是我消耗最多 Token 的地方,居然是 SillyTavern……但也算是一个基础了。

LLM 整体架构

LLM 没有真正的魔法——它只是根据现有 token,预测下一个 token 是什么,就像代码的自动补全。它没有智能,它只是预测,但神奇的是,在参数量、数据量达到超大规模时,LLM 就像涌现出了智能,好像就懂了人类的逻辑思考了,连图灵测试都给你通过了。当然,也仅仅是好像而已。

这里的几个重点是:

  1. 这里没有“理解”,没有“意识”,只有统计——LLM 只是从全互联网的人类文本中总结出了某种黑箱般的模式,虽然我们还无法解释这背后究竟发生了什么
  2. LLM 根据整个上下文窗口(比如我们常说的 128K 上下文,1M 上下文)去进行预测,且有能力去明确之前的哪些上下文对当前的这次生成更重要(注意力机制)
  3. 对每个下一个 token,LLM 每次能预测出可能出现的所有 token 以及相关概率,但常通过一定的随机性去保证生成不枯燥(始终选择概率最高的 token 的话会太机械),温度是其中最常用的配置参数,温度越高,输出越灵活
  4. “涌现”——这种系统规模成长后(量变)突然出现在较小系统中不存在的新能力和行为(质变)称为涌现,它是意外,是黑箱,我们完全无法预测它何时会发生,也无法解释它。

注意力机制和推理流程

注意力机制是 Transformer 的灵魂——对每个 Token 的理解,都同时考虑到(或者说参考?)整个上下文的所有 Token 和这个 Token 的相关性。和这个 Token 相关性越高的 Token 就参与到这里的“理解”更多。

具体的来说,每个 Token 包含三个部分——Query,Key,Value(这里虽然说“包含”,但其实它们三者全是上下文相关的):

  • Query:我和什么相关(查询目标)
  • Key:什么和我相关(索引)
  • Value:我是谁(实际内容)

每个 Token,都由它的 Query 和其他 Token 的 Key,去计算出每个 Token 和它的相关性,而这个 Token 的用于推理的实际表示为所有输入 Token 的以相关性为权重的 Value 集合的加和。推理时,神经网络看到的输入就是这个加和,使用它去预测下一个 Token,然后重新计算相关性,注意力……

但实际使用下来我们知道还有一个所谓的 KV 缓存,它避免每次完全重新计算;KV 缓存的核心是只计算新 Token 的 Q,复用之前所有 Token 的 K 和 V,这个复用证明之前的 Token 的 K 和 V 仅和它及它之前的 Token 相关,后来的 Token 不会改变之前的 Token 的 K,V。

Q 呢?我们注意到,我们其实不需要计算所有 Token 的 Q——我们只需要使用最后一个 Token 的 Q 和其他 Token 的 Key 去得到相关性,再用这个相关性去加权 Value 然后加和去得到注意力,我们完全不需要其他 Token 的 Q。而 Q 的计算……假设我们的 Transformer 是单层的话,它来自于 Token 自己和模型既有的 Query 权重矩阵。

而训练的时候我们需要计算所有 Token 的 Q,但这个就没必要去学习了。

多模态怎么说?

多模态其实没啥特殊的,就是将图像、音频等和文字映射到同一个嵌入向量空间中,让它们能一起丢给 AI 让它去推理。

但多模态 AI 一般来说仅用于理解多模态,而不用于生成多模态(那是另一套东西)。实际上就没有相应的解码器存在。这是设计如此。

为何 LLM 采取对话的形式?

对话最为自然,谁都能用,过去的对话自然而然就是上下文(而且事实上正是对话才让它能够“表现为”智能……不然纯粹拿来写小说吗?),这是产品化的结果,在背后,对话的上下文仍旧会被转化为 Token 序列。

Role,File,Tool,思维链等是怎么引入的?

而要实现对话式,训练时需要进行特殊的处理,需要特殊的训练数据,比如使用特定的掩码去标识 System,Assistant,User 的对话首尾,System 消息被加权,以及 AI 仅预测 Assistant 回复而非去预测所有 Token。而 File,Tool,思维链等,也全是在训练时需要进行特殊的处理,需要特殊的训练数据。

为什么 LLM 会输出 Markdown?因为训练数据就长这样——训练数据被格式化为 Markdown。

关于幻觉(hallucination)

LLM 的背后归根结底是统计学,这会导致它会一本正经地胡说八道,写出一些看似合理但实则错误的内容以及前后不一致,而这是当前 LLM 架构必然带来的结构性的问题。我们希望 AI 说“我不知道”,但 AI 并未被训练地如此。

使用 RAG,联网搜索等可以一定程度上避免幻觉。

OpenAI Chat Completion API 参数

带着上面的理解,看看对话补全API的常用参数:

  • model:使用的模型,不同的模型对应不同的参数量,训练数据,上下文长度……
  • messages:对话消息,包含role信息,将被转换为token序列去作为输入
  • temperature:温度,温度用于调整下一个Token的概率分布,为1时表示保持训练时的原始分布,为0时贪心总是选择概率最高的
  • top_p:只从前 XX% 概率的Token中采样(将可选Token按概率降序排序,从前往后选择直到概率的和超过这个数,如 0.4, 0.3, 0.2, 0.05, 0.03, 0.02 这样有6个可选Token,0.9 的top_p会只选择 0.4, 0.3, 0.2 三个 token 作为候选(显然这里应该是先走top_p再走temperature,但一般只改 temperature,top_p锁定为1)
  • max_tokens:助手回复的最大长度(但设置这个可能会导致 AI 的回复被直接截断)
  • frequency_penalty: 惩罚整个上下文中出现次数多的Token的出现(出现越多惩罚越大,减少高频词)
  • presence_penalty: 惩罚整个上下文中已经出现的Token的出现(只要存在就有惩罚,鼓励使用全新词汇)

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 协议 ,转载请注明出处!