|
@@ -21,13 +21,13 @@ $$P(S)=P(w_1,w_2,…,w_m)=P(w_1)⋅P(w_2∣w_1)⋅P(w_3∣w_1,w_2)⋯P(w_m∣w_1
|
|
|
<p>图 3.1 马尔可夫假设示意图</p>
|
|
<p>图 3.1 马尔可夫假设示意图</p>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
-为了解决这个问题,研究者引入了**马尔可夫假设 (Markov Assumption)**。其核心思想是:我们不必回溯一个词的全部历史,可以近似地认为,一个词的出现概率只与它前面有限的 $n−1$ 个词有关,如图3.1所示。基于这个假设建立的语言模型,我们称之为 **N-gram模型**。这里的 "N" 代表我们考虑的上下文窗口大小。让我们来看几个最常见的例子来理解这个概念:
|
|
|
|
|
|
|
+为了解决这个问题,研究者引入了**马尔可夫假设 (Markov Assumption)** 。其核心思想是:我们不必回溯一个词的全部历史,可以近似地认为,一个词的出现概率只与它前面有限的 $n−1$ 个词有关,如图3.1所示。基于这个假设建立的语言模型,我们称之为 **N-gram模型**。这里的 "N" 代表我们考虑的上下文窗口大小。让我们来看几个最常见的例子来理解这个概念:
|
|
|
|
|
|
|
|
-- **Bigram (当 N=2 时)**:这是最简单的情况,我们假设一个词的出现只与它前面的一个词有关。因此,链式法则中复杂的条件概率 $P(w_i∣w_1,dots,w_{i−1})$ 就可以被近似为更容易计算的形式:
|
|
|
|
|
|
|
+- **Bigram (当 N=2 时)** :这是最简单的情况,我们假设一个词的出现只与它前面的一个词有关。因此,链式法则中复杂的条件概率 $P(w_i∣w_1,dots,w_{i−1})$ 就可以被近似为更容易计算的形式:
|
|
|
|
|
|
|
|
$$P(w_{i}∣w_{1},…,w_{i−1})≈P(w_{i}∣w_{i−1})$$
|
|
$$P(w_{i}∣w_{1},…,w_{i−1})≈P(w_{i}∣w_{i−1})$$
|
|
|
|
|
|
|
|
-- **Trigram (当 N=3 时)**:类似地,我们假设一个词的出现只与它前面的两个词有关:
|
|
|
|
|
|
|
+- **Trigram (当 N=3 时)** :类似地,我们假设一个词的出现只与它前面的两个词有关:
|
|
|
|
|
|
|
|
$$P(w_i∣w_1,…,w_{i−1})≈P(w_i∣w_{i−2},w_{i−1})$$
|
|
$$P(w_i∣w_1,…,w_{i−1})≈P(w_i∣w_{i−2},w_{i−1})$$
|
|
|
|
|
|
|
@@ -101,7 +101,7 @@ print(f"最后: P('datawhale agent learns') ≈ {p_datawhale:.3f} * {p_agent_giv
|
|
|
|
|
|
|
|
N-gram 模型虽然简单有效,但有两个致命缺陷:
|
|
N-gram 模型虽然简单有效,但有两个致命缺陷:
|
|
|
|
|
|
|
|
-1. **数据稀疏性 (Sparsity)**:如果一个词序列从未在语料库中出现,其概率估计就为 0,这显然是不合理的。虽然可以通过平滑 (Smoothing) 技术缓解,但无法根除。
|
|
|
|
|
|
|
+1. **数据稀疏性 (Sparsity)** :如果一个词序列从未在语料库中出现,其概率估计就为 0,这显然是不合理的。虽然可以通过平滑 (Smoothing) 技术缓解,但无法根除。
|
|
|
2. **泛化能力差:**模型无法理解词与词之间的语义相似性。例如,即使模型在语料库中见过很多次 `agent learns`,它也无法将这个知识泛化到语义相似的词上。当我们计算 `robot learns` 的概率时,如果 `robot` 这个词从未出现过,或者 `robot learns` 这个组合从未出现过,模型计算出的概率也会是零。模型无法理解 `agent` 和 `robot` 在语义上的相似性。
|
|
2. **泛化能力差:**模型无法理解词与词之间的语义相似性。例如,即使模型在语料库中见过很多次 `agent learns`,它也无法将这个知识泛化到语义相似的词上。当我们计算 `robot learns` 的概率时,如果 `robot` 这个词从未出现过,或者 `robot learns` 这个组合从未出现过,模型计算出的概率也会是零。模型无法理解 `agent` 和 `robot` 在语义上的相似性。
|
|
|
|
|
|
|
|
**(2)神经网络语言模型与词嵌入**
|
|
**(2)神经网络语言模型与词嵌入**
|
|
@@ -118,7 +118,7 @@ N-gram 模型的根本缺陷在于它将词视为孤立、离散的符号。为
|
|
|
<p>图 3.2 神经网络语言模型架构示意图</p>
|
|
<p>图 3.2 神经网络语言模型架构示意图</p>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
-如图3.2所示,在这个架构中,词嵌入是在模型训练过程中自动学习得到的。模型为了完成“预测下一个词”这个任务,会不断调整每个词的向量位置,最终使这些向量能够蕴含丰富的语义信息。一旦我们将词转换成了向量,我们就可以用数学工具来度量它们之间的关系。最常用的方法是**余弦相似度 (Cosine Similarity)**,它通过计算两个向量夹角的余弦值来衡量它们的相似性。
|
|
|
|
|
|
|
+如图3.2所示,在这个架构中,词嵌入是在模型训练过程中自动学习得到的。模型为了完成“预测下一个词”这个任务,会不断调整每个词的向量位置,最终使这些向量能够蕴含丰富的语义信息。一旦我们将词转换成了向量,我们就可以用数学工具来度量它们之间的关系。最常用的方法是**余弦相似度 (Cosine Similarity)** ,它通过计算两个向量夹角的余弦值来衡量它们的相似性。
|
|
|
|
|
|
|
|
$$\text{similarity}(\vec{a}, \vec{b}) = \cos(\theta) = \frac{\vec{a} \cdot \vec{b}}{|\vec{a}| |\vec{b}|}$$
|
|
$$\text{similarity}(\vec{a}, \vec{b}) = \cos(\theta) = \frac{\vec{a} \cdot \vec{b}}{|\vec{a}| |\vec{b}|}$$
|
|
|
|
|
|
|
@@ -175,13 +175,13 @@ king - man + woman 的结果向量: [0.9 0.2]
|
|
|
<p>图 3.3 RNN 结构示意图</p>
|
|
<p>图 3.3 RNN 结构示意图</p>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
-然而,标准的 RNN 在实践中存在一个严重的问题:**长期依赖问题 (Long-term Dependency Problem)**。在训练过程中,模型需要通过反向传播算法根据输出端的误差来调整网络深处的权重。对于 RNN 而言,序列的长度就是网络的深度。当序列很长时,梯度在从后向前传播的过程中会经过多次连乘,这会导致梯度值快速趋向于零(**梯度消失**)或变得极大(**梯度爆炸**)。梯度消失使得模型无法有效学习到序列早期信息对后期输出的影响,即难以捕捉长距离的依赖关系。
|
|
|
|
|
|
|
+然而,标准的 RNN 在实践中存在一个严重的问题:**长期依赖问题 (Long-term Dependency Problem)** 。在训练过程中,模型需要通过反向传播算法根据输出端的误差来调整网络深处的权重。对于 RNN 而言,序列的长度就是网络的深度。当序列很长时,梯度在从后向前传播的过程中会经过多次连乘,这会导致梯度值快速趋向于零(**梯度消失**)或变得极大(**梯度爆炸**)。梯度消失使得模型无法有效学习到序列早期信息对后期输出的影响,即难以捕捉长距离的依赖关系。
|
|
|
|
|
|
|
|
-为了解决长期依赖问题,**长短时记忆网络 (Long Short-Term Memory, LSTM)** 被设计出来^[3]^。LSTM 是一种特殊的 RNN,其核心创新在于引入了**细胞状态 (Cell State)** 和一套精密的**门控机制 (Gating Mechanism)**。细胞状态可以看作是一条独立于隐藏状态的信息通路,允许信息在时间步之间更顺畅地传递。门控机制则是由几个小型神经网络构成,它们可以学习如何有选择地让信息通过,从而控制细胞状态中信息的增加与移除。这些门包括:
|
|
|
|
|
|
|
+为了解决长期依赖问题,**长短时记忆网络 (Long Short-Term Memory, LSTM)** 被设计出来^[3]^。LSTM 是一种特殊的 RNN,其核心创新在于引入了**细胞状态 (Cell State)** 和一套精密的**门控机制 (Gating Mechanism)** 。细胞状态可以看作是一条独立于隐藏状态的信息通路,允许信息在时间步之间更顺畅地传递。门控机制则是由几个小型神经网络构成,它们可以学习如何有选择地让信息通过,从而控制细胞状态中信息的增加与移除。这些门包括:
|
|
|
|
|
|
|
|
-- **遗忘门 (Forget Gate)**: 决定从上一时刻的细胞状态中丢弃哪些信息。
|
|
|
|
|
-- **输入门 (Input Gate)**: 决定将当前输入中的哪些新信息存入细胞状态。
|
|
|
|
|
-- **输出门 (Output Gate)**: 决定根据当前的细胞状态,输出哪些信息到隐藏状态。
|
|
|
|
|
|
|
+- **遗忘门 (Forget Gate)** : 决定从上一时刻的细胞状态中丢弃哪些信息。
|
|
|
|
|
+- **输入门 (Input Gate)** : 决定将当前输入中的哪些新信息存入细胞状态。
|
|
|
|
|
+- **输出门 (Output Gate)** : 决定根据当前的细胞状态,输出哪些信息到隐藏状态。
|
|
|
|
|
|
|
|
### 3.1.2 Transformer 架构解析
|
|
### 3.1.2 Transformer 架构解析
|
|
|
|
|
|
|
@@ -199,8 +199,8 @@ king - man + woman 的结果向量: [0.9 0.2]
|
|
|
|
|
|
|
|
我们可以将这个结构理解为一个分工明确的团队:
|
|
我们可以将这个结构理解为一个分工明确的团队:
|
|
|
|
|
|
|
|
-1. **编码器 (Encoder)**:任务是“**理解**”输入的整个句子。它会读取所有输入词元(这个概念会在3.2.2节介绍),最终为每个词元生成一个富含上下文信息的向量表示。
|
|
|
|
|
-2. **解码器 (Decoder)**:任务是“**生成**”目标句子。它会参考自己已经生成的前文,并“咨询”编码器的理解结果,来生成下一个词。
|
|
|
|
|
|
|
+1. **编码器 (Encoder)** :任务是“**理解**”输入的整个句子。它会读取所有输入词元(这个概念会在3.2.2节介绍),最终为每个词元生成一个富含上下文信息的向量表示。
|
|
|
|
|
+2. **解码器 (Decoder)** :任务是“**生成**”目标句子。它会参考自己已经生成的前文,并“咨询”编码器的理解结果,来生成下一个词。
|
|
|
|
|
|
|
|
为了真正理解 Transformer 的工作原理,最好的方法莫过于亲手实现它。在本节中,我们将采用一种“自顶向下”的方法:首先,我们搭建出 Transformer 完整的代码框架,定义好所有需要的类和方法。然后,我们将像完成拼图一样,逐一实现这些类的具体功能。
|
|
为了真正理解 Transformer 的工作原理,最好的方法莫过于亲手实现它。在本节中,我们将采用一种“自顶向下”的方法:首先,我们搭建出 Transformer 完整的代码框架,定义好所有需要的类和方法。然后,我们将像完成拼图一样,逐一实现这些类的具体功能。
|
|
|
|
|
|
|
@@ -292,9 +292,9 @@ class DecoderLayer(nn.Module):
|
|
|
|
|
|
|
|
为了实现上述过程,自注意力机制为每个输入的词元向量引入了三个可学习的角色:
|
|
为了实现上述过程,自注意力机制为每个输入的词元向量引入了三个可学习的角色:
|
|
|
|
|
|
|
|
-- **查询 (Query, Q)**: 代表当前词元,它正在主动地“查询”其他词元以获取信息。
|
|
|
|
|
-- **键 (Key, K)**: 代表句子中可被查询的词元“标签”或“索引”。
|
|
|
|
|
-- **值 (Value, V)**: 代表词元本身所携带的“内容”或“信息”。
|
|
|
|
|
|
|
+- **查询 (Query, Q)** : 代表当前词元,它正在主动地“查询”其他词元以获取信息。
|
|
|
|
|
+- **键 (Key, K)** : 代表句子中可被查询的词元“标签”或“索引”。
|
|
|
|
|
+- **值 (Value, V)** : 代表词元本身所携带的“内容”或“信息”。
|
|
|
|
|
|
|
|
这三个向量都是由原始的词嵌入向量乘以三个不同的、可学习的权重矩阵 ($W^Q,W^K,W^V$) 得到的。整个计算过程可以分为以下几步,我们可以把它想象成一次高效的开卷考试:
|
|
这三个向量都是由原始的词嵌入向量乘以三个不同的、可学习的权重矩阵 ($W^Q,W^K,W^V$) 得到的。整个计算过程可以分为以下几步,我们可以把它想象成一次高效的开卷考试:
|
|
|
|
|
|
|
@@ -382,7 +382,7 @@ class MultiHeadAttention(nn.Module):
|
|
|
|
|
|
|
|
**3.1.2.3 前馈神经网络**
|
|
**3.1.2.3 前馈神经网络**
|
|
|
|
|
|
|
|
-在每个 Encoder 和 Decoder 层中,多头注意力子层之后都跟着一个**逐位置前馈网络(Position-wise Feed-Forward Network, FFN)**。如果说注意力层的作用是从整个序列中“动态地聚合”相关信息,那么前馈网络的作用从这些聚合后的信息中提取更高阶的特征。
|
|
|
|
|
|
|
+在每个 Encoder 和 Decoder 层中,多头注意力子层之后都跟着一个**逐位置前馈网络(Position-wise Feed-Forward Network, FFN)** 。如果说注意力层的作用是从整个序列中“动态地聚合”相关信息,那么前馈网络的作用从这些聚合后的信息中提取更高阶的特征。
|
|
|
|
|
|
|
|
这个名字的关键在于“逐位置”。它意味着这个前馈网络会独立地作用于序列中的每一个词元向量。换句话说,对于一个长度为 `seq_len` 的序列,这个 FFN 实际上会被调用 `seq_len` 次,每次处理一个词元。重要的是,所有位置共享的是同一组网络权重。这种设计既保持了对每个位置进行独立加工的能力,又大大减少了模型的参数量。这个网络的结构非常简单,由两个线性变换和一个 ReLU 激活函数组成:
|
|
这个名字的关键在于“逐位置”。它意味着这个前馈网络会独立地作用于序列中的每一个词元向量。换句话说,对于一个长度为 `seq_len` 的序列,这个 FFN 实际上会被调用 `seq_len` 次,每次处理一个词元。重要的是,所有位置共享的是同一组网络权重。这种设计既保持了对每个位置进行独立加工的能力,又大大减少了模型的参数量。这个网络的结构非常简单,由两个线性变换和一个 ReLU 激活函数组成:
|
|
|
|
|
|
|
@@ -420,12 +420,12 @@ class PositionWiseFeedForward(nn.Module):
|
|
|
|
|
|
|
|
这个操作由两个部分组成:
|
|
这个操作由两个部分组成:
|
|
|
|
|
|
|
|
-- **残差连接 (Add)**: 该操作将子模块的输入 `x` 直接加到该子模块的输出 `Sublayer(x)` 上。这一结构解决了深度神经网络中的**梯度消失 (Vanishing Gradients)** 问题。在反向传播时,梯度可以绕过子模块直接向前传播,从而保证了即使网络层数很深,模型也能得到有效的训练。其公式可以表示为:$\text{Output} = x + \text{Sublayer}(x)$。
|
|
|
|
|
-- **层归一化 (Norm)**: 该操作对单个样本的所有特征进行归一化,使其均值为0,方差为1。这解决了模型训练过程中的**内部协变量偏移 (Internal Covariate Shift)** 问题,使每一层的输入分布保持稳定,从而加速模型收敛并提高训练的稳定性。
|
|
|
|
|
|
|
+- **残差连接 (Add)** : 该操作将子模块的输入 `x` 直接加到该子模块的输出 `Sublayer(x)` 上。这一结构解决了深度神经网络中的**梯度消失 (Vanishing Gradients)** 问题。在反向传播时,梯度可以绕过子模块直接向前传播,从而保证了即使网络层数很深,模型也能得到有效的训练。其公式可以表示为:$\text{Output} = x + \text{Sublayer}(x)$。
|
|
|
|
|
+- **层归一化 (Norm)** : 该操作对单个样本的所有特征进行归一化,使其均值为0,方差为1。这解决了模型训练过程中的**内部协变量偏移 (Internal Covariate Shift)** 问题,使每一层的输入分布保持稳定,从而加速模型收敛并提高训练的稳定性。
|
|
|
|
|
|
|
|
**3.1.2.5 位置编码**
|
|
**3.1.2.5 位置编码**
|
|
|
|
|
|
|
|
-我们已经了解,Transformer 的核心是自注意力机制,它通过计算序列中任意两个词元之间的关系来捕捉依赖。然而,这种计算方式有一个固有的问题:它本身不包含任何关于词元顺序或位置的信息。对于自注意力来说,“agent learns” 和 “learns agent” 这两个序列是完全等价的,因为它只关心词元之间的关系,而忽略了它们的排列。为了解决这个问题,Transformer 引入了**位置编码 (Positional Encoding)**。
|
|
|
|
|
|
|
+我们已经了解,Transformer 的核心是自注意力机制,它通过计算序列中任意两个词元之间的关系来捕捉依赖。然而,这种计算方式有一个固有的问题:它本身不包含任何关于词元顺序或位置的信息。对于自注意力来说,“agent learns” 和 “learns agent” 这两个序列是完全等价的,因为它只关心词元之间的关系,而忽略了它们的排列。为了解决这个问题,Transformer 引入了**位置编码 (Positional Encoding)** 。
|
|
|
|
|
|
|
|
位置编码的核心思想是,为输入序列中的每一个词元嵌入向量,都额外加上一个能代表其绝对位置和相对位置信息的“位置向量”。这个位置向量不是通过学习得到的,而是通过一个固定的数学公式直接计算得出。这样一来,即使两个词元(例如,两个都叫 `agent` 的词元)自身的嵌入是相同的,但由于它们在句子中的位置不同,它们最终输入到 Transformer 模型中的向量就会因为加上了不同的位置编码而变得独一无二。原论文中提出的位置编码使用正弦和余弦函数来生成,其公式如下:
|
|
位置编码的核心思想是,为输入序列中的每一个词元嵌入向量,都额外加上一个能代表其绝对位置和相对位置信息的“位置向量”。这个位置向量不是通过学习得到的,而是通过一个固定的数学公式直接计算得出。这样一来,即使两个词元(例如,两个都叫 `agent` 的词元)自身的嵌入是相同的,但由于它们在句子中的位置不同,它们最终输入到 Transformer 模型中的向量就会因为加上了不同的位置编码而变得独一无二。原论文中提出的位置编码使用正弦和余弦函数来生成,其公式如下:
|
|
|
|
|
|
|
@@ -481,7 +481,7 @@ Transformer的设计哲学是“先理解,再生成”。编码器负责深入
|
|
|
|
|
|
|
|
无论是回答问题、写故事还是生成代码,本质上都是在一个已有的文本序列后面,一个词一个词地添加最合理的内容。基于这个思想,GPT 做了一个大胆的简化:**它完全抛弃了编码器,只保留了解码器部分。** 这就是 **Decoder-Only** 架构的由来。
|
|
无论是回答问题、写故事还是生成代码,本质上都是在一个已有的文本序列后面,一个词一个词地添加最合理的内容。基于这个思想,GPT 做了一个大胆的简化:**它完全抛弃了编码器,只保留了解码器部分。** 这就是 **Decoder-Only** 架构的由来。
|
|
|
|
|
|
|
|
-Decoder-Only 架构的工作模式被称为**自回归 (Autoregressive)**。这个听起来很专业的术语,其实描述了一个非常简单的过程:
|
|
|
|
|
|
|
+Decoder-Only 架构的工作模式被称为**自回归 (Autoregressive)** 。这个听起来很专业的术语,其实描述了一个非常简单的过程:
|
|
|
|
|
|
|
|
1. 给模型一个起始文本(例如 “Datawhale Agent is”)。
|
|
1. 给模型一个起始文本(例如 “Datawhale Agent is”)。
|
|
|
2. 模型预测出下一个最有可能的词(例如 “a”)。
|
|
2. 模型预测出下一个最有可能的词(例如 “a”)。
|
|
@@ -493,7 +493,7 @@ Decoder-Only 架构的工作模式被称为**自回归 (Autoregressive)**。这
|
|
|
|
|
|
|
|
你可能会问,解码器是如何保证在预测第 `t` 个词时,不去“偷看”第 `t+1` 个词的答案呢?
|
|
你可能会问,解码器是如何保证在预测第 `t` 个词时,不去“偷看”第 `t+1` 个词的答案呢?
|
|
|
|
|
|
|
|
-答案就是**掩码自注意力 (Masked Self-Attention)**。在 Decoder-Only 架构中,这个机制变得至关重要。它的工作原理非常巧妙:
|
|
|
|
|
|
|
+答案就是**掩码自注意力 (Masked Self-Attention)** 。在 Decoder-Only 架构中,这个机制变得至关重要。它的工作原理非常巧妙:
|
|
|
|
|
|
|
|
在自注意力机制计算出注意力分数矩阵(即每个词对其他所有词的关注度得分)之后,但在进行 Softmax 归一化之前,模型会应用一个“掩码”。这个掩码会将所有位于当前位置之后(即目前尚未观测到)的词元对应的分数,替换为一个非常大的负数。当这个带有负无穷分数的矩阵经过 Softmax 函数时,这些位置的概率就会变为 0。这样一来,模型在计算任何一个位置的输出时,都从数学上被阻止了去关注它后面的信息。这种机制保证了模型在预测下一个词时,能且仅能依赖它已经见过的、位于当前位置之前的所有信息,从而确保了预测的公平性和逻辑的连贯性。
|
|
在自注意力机制计算出注意力分数矩阵(即每个词对其他所有词的关注度得分)之后,但在进行 Softmax 归一化之前,模型会应用一个“掩码”。这个掩码会将所有位于当前位置之后(即目前尚未观测到)的词元对应的分数,替换为一个非常大的负数。当这个带有负无穷分数的矩阵经过 Softmax 函数时,这些位置的概率就会变为 0。这样一来,模型在计算任何一个位置的输出时,都从数学上被阻止了去关注它后面的信息。这种机制保证了模型在预测下一个词时,能且仅能依赖它已经见过的、位于当前位置之前的所有信息,从而确保了预测的公平性和逻辑的连贯性。
|
|
|
|
|
|
|
@@ -634,14 +634,14 @@ How are you?
|
|
|
|
|
|
|
|
### 3.2.2 文本分词
|
|
### 3.2.2 文本分词
|
|
|
|
|
|
|
|
-我们知道,计算机本质上只能理解数字。因此,在将自然语言文本喂给大语言模型之前,必须先将其转换成模型能够处理的数字格式。这个将文本序列转换为数字序列的过程,就叫做**分词 (Tokenization)**。**分词器 (Tokenizer)** 的作用,就是定义一套规则,将原始文本切分成一个个最小的单元,我们称之为**词元 (Token)**。
|
|
|
|
|
|
|
+我们知道,计算机本质上只能理解数字。因此,在将自然语言文本喂给大语言模型之前,必须先将其转换成模型能够处理的数字格式。这个将文本序列转换为数字序列的过程,就叫做**分词 (Tokenization)** 。**分词器 (Tokenizer)** 的作用,就是定义一套规则,将原始文本切分成一个个最小的单元,我们称之为**词元 (Token)** 。
|
|
|
|
|
|
|
|
**3.2.2.1 为何需要分词**
|
|
**3.2.2.1 为何需要分词**
|
|
|
|
|
|
|
|
早期的自然语言处理任务可能会采用简单的分词策略:
|
|
早期的自然语言处理任务可能会采用简单的分词策略:
|
|
|
|
|
|
|
|
-- **按词分词 (Word-based)**:直接用空格或标点符号将句子切分成单词。这种方法很直观,但会面临“词表爆炸”的问题。一个语言的词汇量是巨大的,如果每个词都作为一个独立的词元,词表会变得难以管理。更糟糕的是,模型将无法处理任何未在词表中出现过的词,例如 “DatawhaleAgent”。
|
|
|
|
|
-- **按字符分词 (Character-based)**:将文本切分成单个字符。这种方法词表很小(例如英文字母、数字和标点),不存在 OOV 问题。但它的缺点是,单个字符大多不具备独立的语义,模型需要花费更多的精力去学习如何将字符组合成有意义的词,导致学习效率低下。
|
|
|
|
|
|
|
+- **按词分词 (Word-based)** :直接用空格或标点符号将句子切分成单词。这种方法很直观,但会面临“词表爆炸”的问题。一个语言的词汇量是巨大的,如果每个词都作为一个独立的词元,词表会变得难以管理。更糟糕的是,模型将无法处理任何未在词表中出现过的词,例如 “DatawhaleAgent”。
|
|
|
|
|
+- **按字符分词 (Character-based)** :将文本切分成单个字符。这种方法词表很小(例如英文字母、数字和标点),不存在 OOV 问题。但它的缺点是,单个字符大多不具备独立的语义,模型需要花费更多的精力去学习如何将字符组合成有意义的词,导致学习效率低下。
|
|
|
|
|
|
|
|
为了兼顾词表大小和语义表达,现代大语言模型普遍采用**子词分词 (Subword Tokenization)** 算法。它的核心思想是:将常见的词(如 "agent")保留为完整的词元,同时将不常见的词(如 "Tokenization")拆分成多个有意义的子词片段(如 "Token" 和 "ization")。这样既控制了词表的大小,又能让模型通过组合子词来理解和生成新词。
|
|
为了兼顾词表大小和语义表达,现代大语言模型普遍采用**子词分词 (Subword Tokenization)** 算法。它的核心思想是:将常见的词(如 "agent")保留为完整的词元,同时将不常见的词(如 "Tokenization")拆分成多个有意义的子词片段(如 "Token" 和 "ization")。这样既控制了词表的大小,又能让模型通过组合子词来理解和生成新词。
|
|
|
|
|
|
|
@@ -876,15 +876,15 @@ print(response)
|
|
|
|
|
|
|
|
早期的研究更侧重于增加模型参数量,但 DeepMind 在 2022 年提出的“Chinchilla 定律”对此进行了重要修正^[10]^。该定律指出,在给定的计算预算下,为了达到最优性能,**模型参数量和训练数据量之间存在一个最优配比**。具体来说,最优的模型应该比之前普遍认为的要小,但需要用多得多的数据进行训练。例如,一个 700 亿参数的 Chinchilla 模型,由于使用了比 GPT-3(1750 亿参数)多 4 倍的数据进行训练,其性能反而超越了后者。这一发现纠正了“越大越好”的片面认知,强调了数据效率的重要性,并指导了后续许多高效大模型(如 Llama 系列)的设计。
|
|
早期的研究更侧重于增加模型参数量,但 DeepMind 在 2022 年提出的“Chinchilla 定律”对此进行了重要修正^[10]^。该定律指出,在给定的计算预算下,为了达到最优性能,**模型参数量和训练数据量之间存在一个最优配比**。具体来说,最优的模型应该比之前普遍认为的要小,但需要用多得多的数据进行训练。例如,一个 700 亿参数的 Chinchilla 模型,由于使用了比 GPT-3(1750 亿参数)多 4 倍的数据进行训练,其性能反而超越了后者。这一发现纠正了“越大越好”的片面认知,强调了数据效率的重要性,并指导了后续许多高效大模型(如 Llama 系列)的设计。
|
|
|
|
|
|
|
|
-缩放法则最令人惊奇的产物是“能力的涌现”。所谓能力涌现,是指当模型规模达到一定阈值后,会突然展现出在小规模模型中完全不存在或表现不佳的全新能力。例如,**链式思考 (Chain-of-Thought)**、**指令遵循 (Instruction Following)**、多步推理、代码生成等能力,都是在模型参数量达到数百亿甚至千亿级别后才显著出现的。这种现象表明,大语言模型不仅仅是简单地记忆和复述,它们在学习过程中可能形成了某种更深层次的抽象和推理能力。对于智能体开发者而言,能力的涌现意味着选择一个足够大规模的模型,是实现复杂自主决策和规划能力的前提。
|
|
|
|
|
|
|
+缩放法则最令人惊奇的产物是“能力的涌现”。所谓能力涌现,是指当模型规模达到一定阈值后,会突然展现出在小规模模型中完全不存在或表现不佳的全新能力。例如,**链式思考 (Chain-of-Thought)** 、**指令遵循 (Instruction Following)** 、多步推理、代码生成等能力,都是在模型参数量达到数百亿甚至千亿级别后才显著出现的。这种现象表明,大语言模型不仅仅是简单地记忆和复述,它们在学习过程中可能形成了某种更深层次的抽象和推理能力。对于智能体开发者而言,能力的涌现意味着选择一个足够大规模的模型,是实现复杂自主决策和规划能力的前提。
|
|
|
|
|
|
|
|
### 3.3.2 模型幻觉
|
|
### 3.3.2 模型幻觉
|
|
|
|
|
|
|
|
**模型幻觉(Hallucination)**通常指的是大语言模型生成的内容与客观事实、用户输入或上下文信息相矛盾,或者生成了不存在的事实、实体或事件。幻觉的本质是模型在生成过程中,过度自信地“编造”了信息,而非准确地检索或推理。根据其表现形式,幻觉可以被分为多种类型^[11]^,例如:
|
|
**模型幻觉(Hallucination)**通常指的是大语言模型生成的内容与客观事实、用户输入或上下文信息相矛盾,或者生成了不存在的事实、实体或事件。幻觉的本质是模型在生成过程中,过度自信地“编造”了信息,而非准确地检索或推理。根据其表现形式,幻觉可以被分为多种类型^[11]^,例如:
|
|
|
|
|
|
|
|
-- **事实性幻觉 (Factual Hallucinations)**: 模型生成与现实世界事实不符的信息。
|
|
|
|
|
-- **忠实性幻觉 (Faithfulness Hallucinations)**: 在文本摘要、翻译等任务中,生成的内容未能忠实地反映源文本的含义。
|
|
|
|
|
-- **内在幻觉 (Intrinsic Hallucinations)**: 模型生成的内容与输入信息直接矛盾。
|
|
|
|
|
|
|
+- **事实性幻觉 (Factual Hallucinations)** : 模型生成与现实世界事实不符的信息。
|
|
|
|
|
+- **忠实性幻觉 (Faithfulness Hallucinations)** : 在文本摘要、翻译等任务中,生成的内容未能忠实地反映源文本的含义。
|
|
|
|
|
+- **内在幻觉 (Intrinsic Hallucinations)** : 模型生成的内容与输入信息直接矛盾。
|
|
|
|
|
|
|
|
幻觉的产生是多方面因素共同作用的结果。首先,训练数据中可能包含错误或矛盾的信息。其次,模型的自回归生成机制决定了它只是在预测下一个最可能的词元,而没有内置的事实核查模块。最后,在面对需要复杂推理的任务时,模型可能会在逻辑链条中出错,从而“编造”出错误的结论。例如:一个旅游规划 Agent,可能会为你推荐一个现实中不存在的景点,或者预订一个航班号错误的机票。
|
|
幻觉的产生是多方面因素共同作用的结果。首先,训练数据中可能包含错误或矛盾的信息。其次,模型的自回归生成机制决定了它只是在预测下一个最可能的词元,而没有内置的事实核查模块。最后,在面对需要复杂推理的任务时,模型可能会在逻辑链条中出错,从而“编造”出错误的结论。例如:一个旅游规划 Agent,可能会为你推荐一个现实中不存在的景点,或者预订一个航班号错误的机票。
|
|
|
|
|
|
|
@@ -895,7 +895,7 @@ print(response)
|
|
|
1. **数据层面**: 通过高质量数据清洗、引入事实性知识以及强化学习与人类反馈 (RLHF) 等方式^[13]^,从源头减少幻觉。
|
|
1. **数据层面**: 通过高质量数据清洗、引入事实性知识以及强化学习与人类反馈 (RLHF) 等方式^[13]^,从源头减少幻觉。
|
|
|
2. **模型层面**: 探索新的模型架构,或让模型能够表达其对生成内容的不确定性。
|
|
2. **模型层面**: 探索新的模型架构,或让模型能够表达其对生成内容的不确定性。
|
|
|
3. **推理与生成层面**:
|
|
3. **推理与生成层面**:
|
|
|
- 1. **检索增强生成 (Retrieval-Augmented Generation, RAG)**^[14]^: 这是目前缓解幻觉的有效方法之一。RAG 系统通过在生成之前从外部知识库(如文档数据库、网页)中检索相关信息,然后将检索到的信息作为上下文,引导模型生成基于事实的回答。
|
|
|
|
|
|
|
+ 1. **检索增强生成 (Retrieval-Augmented Generation, RAG)** ^[14]^: 这是目前缓解幻觉的有效方法之一。RAG 系统通过在生成之前从外部知识库(如文档数据库、网页)中检索相关信息,然后将检索到的信息作为上下文,引导模型生成基于事实的回答。
|
|
|
2. **多步推理与验证**: 引导模型进行多步推理,并在每一步进行自我检查或外部验证。
|
|
2. **多步推理与验证**: 引导模型进行多步推理,并在每一步进行自我检查或外部验证。
|
|
|
3. **引入外部工具**: 允许模型调用外部工具(如搜索引擎、计算器、代码解释器)来获取实时信息或进行精确计算。
|
|
3. **引入外部工具**: 允许模型调用外部工具(如搜索引擎、计算器、代码解释器)来获取实时信息或进行精确计算。
|
|
|
|
|
|
|
@@ -914,7 +914,7 @@ print(response)
|
|
|
|
|
|
|
|
**从 LLM 基础到构建智能体:**
|
|
**从 LLM 基础到构建智能体:**
|
|
|
|
|
|
|
|
-这一章的LLM基础主要是为了帮助大家更好的理解大模型的诞生以及发展过程,其中也蕴含了智能体设计的部分思考。例如,如何设计有效的提示词来引导 Agent 的规划与决策,如何根据任务需求选择合适的模型,以及如何在 Agent 的工作流中加入验证机制以规避模型的幻觉等问题,其解决方案均建立在本章的基础之上。我们现在已经准备好从理论转向实践。在下一章,我们将开始探索智能体的核心构件,将本章所学的知识应用于实际的智能体设计之中。
|
|
|
|
|
|
|
+这一章的LLM基础主要是为了帮助大家更好的理解大模型的诞生以及发展过程,其中也蕴含了智能体设计的部分思考。例如,如何设计有效的提示词来引导 Agent 的规划与决策,如何根据任务需求选择合适的模型,以及如何在 Agent 的工作流中加入验证机制以规避模型的幻觉等问题,其解决方案均建立在本章的基础之上。我们现在已经准备好从理论转向实践。在下一章,我们将开始探索智能体经典范式构建,将本章所学的知识应用于实际的智能体设计之中。
|
|
|
|
|
|
|
|
## 参考文献
|
|
## 参考文献
|
|
|
|
|
|