生成式人工智能导论-Chap.4


本系列生成式人工智能导论博文基于国立台湾大学李宏毅老师发布的课程视频整理而来, 仅用作复习参考.
可以算是人工智能领域的入门课程.
需要明确的是, 李宏毅老师上传的课程已经是2024年的课程, 距今有两年的时间, 知识难免有过时的可能, 如果出现了这种情况, 博主会尽可能补足当前的状态.

生成式人工智能导论 Chap.4 语言模型的内里细节与评估方式

我们回顾下前几章中所说的:

  • 模型的本质是一个含有大量参数的函式, 其训练过程就是将这些参数确定的过程.
  • 函式的参数量过大, 需要使用一个特定的表示方式, 在当前, 通常使用 类神经网络 来表示它.

最出名的类神经网络我们也提到过, 相信对各位也耳熟能详: Transformer

4.1 Transformer 概述

模型的演进并非一步到位, 事实上, Transformer之前有很多别的模型架构, 例如RNN, Feed-forward Network等等. 不过限于本课程的导论性质, 我们只对当下最流行的Transformer进行简要介绍.

Transformer通过以下五层, 将输入转化为概率分布进行输出:

  1. Tokenization
  2. Input Layer
  3. Attention
  4. Feed Forward
  5. Output Layer

值得注意的是, 3与4这两层被并称为一个 Transformer Block , 而这一个结构事实上在一个类神经网络中具有多层, 模型会反复思考, 最终才能得到输出.

4.1.1 Tokenization

Tokenization这一层的目的是将输入的语句转化为Token Sequence. 简单来讲, 就是把我们的输入切成一段一段的, 这被切开的每一份叫做一个Token.

显然, 分割这个工作是需要相应的标准的 (就连split函数都需要传入切割参数呢, 你说是吧) , Tokenization也不例外, 它通过一个预先设定好的 Token list 来进行分割.

当然, 这个Token list怎么来呢? 方法比较五花八门. 比较常用的一个是通过一种叫 Byte Pair Encoding(BPE) 的方式, 通过大量文字以及前后文的关联连接性, 来得到Token list.

Tokenization

4.1.2 Input Layer

Input Layer的目的是让模型 理解 每一个Token都是什么意思.
欸, 怎么理解呢? 在机器学习中, 这个步骤在做的就是将每一个Token都变成一个Vector(向量), 这个过程也被我们称为 Embedding .

注: 从严谨性上来看, 我们应该使用Vector, 但实际上, 我们常常直接用Embedding来直接指代某个Token的对应向量, 只是一种习惯性表述.

为啥转化成向量, 模型就能理解词义了呢? 事实上, 原先一个Token的形式, 对机器而言只是一个标识, 但Embedding不同, 它能够被量化了, 这意味着机器可以通过计算向量间的距离来具体得知两个词的含义是否相近. 也相应地就是一种词义的理解工作.

Embedding

好, 现在的问题是, 每个Token对应的Embedding是从哪里来的呢?
相信各位应该很容易想到, 我们只要把Token list中所有的Token的Embedding提前算出来不就好了?
没错! 这个东西确实存在, 并且就叫做 Token Embedding , 它本质上就是一个映射表, 将每个Token映射到其对应的Embedding上. 至于这个东西怎么来, 就是我们训练时期的工作了.

实际上, 每个Token对应的Embedding正是组成我们模型中未知参数的一部分, 甚至可以说是一大部分.


到现在为止, 我们已经得到了一个句子中每个Token的Embedding, 但实际上, 还有个对于词义比较关键的东西, 我们没考虑:
这个Token在句子中的 位置 .

举个简单的例子:
“我爱你” 跟 “你爱我” . 如果不考虑这种位置信息, 这两句话在模型中就是同一个意思. (我靠, 这简直乱套了)

因此, 除了Token本身的Embedding之外, 还有一种Embedding需要加在我们的Input Layer中, 它被称为 Positional Embedding . 这种Positional Embedding可以人为预先定义, 当然, 也可以通过在训练过程中找出.

Positional Embedding

4.1.3 Transformer Block

Transformer Block的目的是让模型能够考虑上下文. 它接受来自上一层Input Layer的Embedding, 结合上下文信息将其转化为融合了上下文信息的Embedding, 这种Embedding也有个专属名词: Contextualized Token Embedding .

好, 现在来看看Transformer Block这两层里面究竟干了点啥.


Step 1 Attention Weight

这一步是将我们所要结合上下文的Token(Selected Token)与这个句子中的每一个其它Token都进行一步计算, 得到两个Token之间的相关性, 这个相关性也有个专有名词: Attention Weight .
这个Attention Weight的计算也是通过一个函数(小模型)来进行的, 这个小模型的参数也是我们训练得到的.

Attention.Attention Weight


Step 2 Weighted Sum

随后我们将计算出的相关性做一个带权加和, 计算出我们Attention层的最终输出:

Attention.Weighted Sum


Attention Matrix

我们会发现Attention这一层需要所有的Token两两计算出它们的Attention Weight, 这个计算过程可以跟线性代数中的矩阵一块来看:

Attention.Attention Matrix


更多…

事实上, 在实际运作时, 我们不会考虑下文, 也就是一个Token与其后面Token的相关性, 这一机制叫 Causal Attention .

此外, 关于相关性的计算, 往往也不会只通过一个小模型来计算. 这很好理解, 不同的词汇以不同的标准来看相关性显然是不同的. 事实上, 这种计算相关性的组数往往有8组甚至16组之多. 这个机制叫 Multi-head Attention .

显然, Multi-head Attention有了多组输出, 我们后面必须再加一个模块来将多组输出整合, 也就是Transformer Block中另一层Feed Forward要干的事情. Feed Forward本身也是一个模型, 其参数通过训练的过程确定下来, 会将多组来自Attention层的输出组合, 最终形成一个整合起来的Embedding.

而往往一个模型中会有很多很多这样的Transformer Block, 当然, 学术中为了简化称呼, 常常直接将一个Transformer Block成为一个Layer, 在经过很多层Layer的演算后, 最终的结果会被传给最下方一层, Output Layer.

4.1.4 Output Layer

Output Layer的目的是拿到最后一个Layer的输出, 并将其通过Linear Transform与Softmax两步, 形成一个关于词表的概率分布.

其中, Linear Transform负责将模型提取的抽象特征向量, 映射为词表中每一个词对应的原始分值, 又叫 Logits .
Softmax只负责将原始分值转化为总和为 1 的概率分布, 从而明确每个词作为下一个输出的具体可能性.

至此, 我们对Transformer有了一个简要的了解.

4.2 语言模型的可解释性

4.2.1 语言模型是黑盒吗?

在当前的普遍认知中, 我们所使用的大部分比较广为流传的语言模型, 如ChatGPT, Gemini, Claude等, 都是完全闭源的模型, 我们不知道其思考过程中做了什么, 我们也无法得知其具体参数. 许多人因此认为语言模型这个东西是完全的黑盒.

黑盒究竟该怎么定义是个问题. 是应当被商讨的.

第一种讨论角度集中于模型的开源程度, 即Transparency. 现有的语言模型有很多, 其中不乏像Llama, Gemma等样子的, 完全开源的模型, 但他们的开源也就局限于 知道模型的参数 . 也有些人认为, 我们不仅仅应当知道模型的参数, 同时也应当能够知道模型的具体训练资料与训练过程.(这一类模型当然也广泛存在, 但不太知名, 这里权且略过)

但更多人所言的 黑盒 , 其实集中于模型的思维过程不明确, 即Interpretable. 我们其实更喜欢能够被我们一眼看穿在做什么的模型, 换句话说, 我们更喜欢我们能够理解的推导过程. 而显然, LLM中一层层Transformer的叠加并不能让我们理解其中的含义, 从这点来看, LLM本身很难说是思维透明的.

第三种看法是人类能否理解语言模型的具体思考流程, 即Explainable. 事实上, 当前语言模型的 深度思考 功能已经提供了答案, 我们也许不知道它是怎样进行具体思维的, 但至少, 它能够通过这种直接输出的方式, 将它的思考流程给出来. 从这个角度上讲, 语言模型又确实能看作透明的.

本部分我们主要集中于第三点, 即可解释性.

4.2.2 可解释性的具体体现

从当前我们已知的知识上, 语言模型的可解释性包括:

  • 我们可以通过推理过程中的Transformer Block找到影响模型输出的关键输入.(找到哪些输入的Token与这个输出Token的相关性高)
  • 我们找到影响模型输出的关键训练资料(具体方法未知, 但以我们现在的初级了解, 我们至少能通过二分法来进行这个工作)
  • 我们可以通过对Embedding进行某些处理来探究其中的具体资讯(包括通过每一层的Transformer Block做分类器 / 通过降维算法将每个Embedding二维化等等)
  • 我们甚至可以用AI来解释AI

不过, 最简单的也就是我们上面所提到的: 直接问它就行…

4.3 怎么评估大型语言模型的能力?

4.3.1 评估集的选择

事实上, 利用相同的输入, 得到LLM的输出是非常常用的评估方式. 但问题是, LLM的输出是 不确定的 , 因此我们该怎么评估这种不确定的输出就变成了问题本身.

第一种简单的方式是直接将这个问题变得很确定, 比如使用 选择题评估集 .
有很多比较知名的选择题评估集. 奇怪的是, 不同的论文中, 同一个模型针对不同选择题评估集的准确率可能不同; 同样的选择题, 只是将选项变更为了不同的形式, 准确率也可能不同, 为什么?
语言模型是可以说出任何话的, 完全有可能这个语言模型刚刚好没有说出具体选项, 而是说出了选项所提及的内容, 这个时候, 判定标准反而变得模糊起来了.

就连选择题都有如此难办的评估标准, 放到翻译 / 摘要 / 编程这种问题上, 这个评估标准只会更加复杂.

比较常用的测试集合包括:
HLE (Humanity’s Last Exam)
SWE-bench Verified
FrontierMath
等等, 在此就不过多赘述.

4.3.2 评估方式的选择

让专业人员来做评估自然是最简单, 最有效的方式, 至少在今天, 我们还是可以相信人的选择. 此前的ChatBot Arena的排行榜, 就是最有效的例证.
问题还是成本, 如果将现在五花八门的模型全让人来进行评估, 成本太高了. 因此我们又双叒开始套娃, 我们能不能让语言模型自己来进行评估?

从结果上来看, 如果我们相信ChatBot Arena上的排行榜的话, 现今的语言模型完全能够胜任这样的工作.

4.4 大语言模型的安全性议题

时至今日, 即便大语言模型已经十分成熟, 但仍有蛮多的我们需要考虑的安全性相关忧虑.

4.4.1 语言模型仍然会犯错

我们通过前面的认识, 可以很明确的了解到, 由于LLM本质上在做接龙的工作, 它一定是会出现错误的.
这时候, 我们应该做些什么?

比较常见的做法是在 语言模型的输出层 和 与用户的交互层 之间单独添加一个 安全层. 我们可以向其中加入各种各样关于安全的功能, 比如事实查证, 有害内容检测, 敏感信息泄露等等…

当然, 事实上我们所加入的安全层, 其中有很多功能仍然需要依靠LLM来进行, 自然, 这些LLM也有可能会犯错.(笑

4.4.2 语言模型的偏见?

是这样的, 现今的世界中各种思潮流行, 因此保证语言模型能够对它搜寻到的事实进行客观陈述, 是一件十分重要的事情.
通常检测偏见的方式, 是通过变更同一个输入中的主体来达成的, 比如相同的一段输入, 将主体的性别 / 肤色 / 地域等等属性进行改变, 观察语言模型的输出是否能够做到同样客观.

当然, 偏见的存在有其必然性, 至于发现偏见后是否要真正处理, 这就不是我们需要关心的内容了.

4.4.3 如何确定一句话是不是LLM生成的?

LLM的发展使得人们获取知识的渠道得到大幅度的扩展, 但与此同时, 也催生了一大批垃圾文章的出现. 是的, 类似营销号相关的无良内容产出方, 已经完全用AI来进行它们的文本创作了.

针对LLM的检测方式由此成为了重要的需求, 尽管这并不是个简单的事情.
比较通用的方法, 是直接通过LLM的产出内容与人类的产出内容单独对一个LLM进行训练, 让这个LLM能够起到一个分类器的作用.
很遗憾的是, 这方面的工作被许许多多的工作者在2023年时就已经尝试过, 在那时, 通过这种方式来辨别文段的出处, 就已经是个比较困难的事情.

另一种方式是语言模型在生成的文段本身上加入 “水印” . 也就是说加入些人类不易察觉的, 但能被检测工具一眼看到的特殊结构.

4.4.4 LLM是不是被误导着做些奇怪的事情?

LLM也会被诈骗. 既然它是根据Prompt来进行接龙的, 那我们如果在Prompt上做手脚, 就有可能让它做出些不应当出现的举动.

这里有两个行为: Jailbreaking 和 Prompt Injection, 二者做的事情很类似, 都是通过Prompt让语言模型做不正确的事情.
二者的区别在于, 前者的攻击目标在语言模型本身, 通常后果比较严重; 而后者的攻击目标在语言模型构筑的应用, 只是会出现些不恰当的行为.

在2023年, Jailbreaking的主要方式是: (1) 使用LLM不太熟悉的语言从而让它忘记需要防御这件事; (2) 在危险命令后方加入肯定指令从而突破限制. (3) 试图通过额外资讯说服语言模型.
当然, 在2026年的今天, 各种Prompt Guard模型的出现使得这件事情变得更加困难, 想要成功也自然需要更加隐蔽的方式.

至于Prompt Injection, 方式要更加简单, 因为我们输入的就是Prompt的一部分. 我们只需要在我们的内容中加入一些希望LLM达成的目标即可.


这一章讲了些具体的细节, 包括答案生成的具体方式, Transformer, 以及相关的大语言模型能力评估的内容.

本篇内容就到这里~


文章作者: MUG-chen
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 MUG-chen !
  目录
加载中...