《大模型基础》 -- 读后笔记
语言模型基础
语言是一套复杂的符号系统,由音韵,词法,句法组成,并且带有不同的语义,不同的组合可能代表同一意思,同样的组合在不同语境下可能代表不同的意思,
因为这种不确定性,所以语言是概率的,而且语言的概率性和认知的概率性有着密不可分的关系。语言模型就是为了准确预测语言符号的概率。
从ELIZA到GPT-4,模型经历了规则模型到统计模型,再到神经网络模型。
基于统计方法的统计模型
统计模型是基于语料库(corpus)进行语料统计和学习获得预测的能力。
n-grams 语言模型
基于马尔可夫假设和离散变量的极大似然估计给出的概率。
公式:长度为n的词序列为,通过依次统计n-grams对应的(n-1)grams的相对频率来计算w1:n概率,w1:n={w1,w2,w3…wn}代表了n个语言符号,可以是文本,也可以是音频等其他信息。
Pn−grams(w1:N)=∏i=nNC(wi−n+1:i)C(wi−n+1:i−1)
P_{n-grams}(w_{1:N})=\prod_{i=n}^N\frac{C(w_{i-n+1:i})}{C(w_{i-n+1:i-1})}
Pn−grams(w1:N)=i=n∏NC(wi−n+1:i−1)C(wi−n+1:i)
C 符号代表括号里的元素在出现的次数,n 是变量,代表对前n个词的进行考虑,如果i=1,那么就不对文本上下文进行考虑,分母是所有包含词的总数。例如:有五个句子在语料库,对文本{长颈鹿,脖子,长}进行n=2考虑。


我们可以看到这种方法是基于词的统计而来的,具有对未知文本的泛化能力的,但是对于n越大,其实这种能力越弱,因为相乘的结果是在逐渐向0趋近的。
n-grams 的统计学原理


假设求N个文本出现的概率如下,根据条件概率的链式法则,可以列出下列等式
P(wi:N)=P(w1)P(w2∣w1)P(w3∣w1:2)...P(wn∣w1:N−1)=∏i=1NP(wi∣w1:i−1)
P(w_{i:N})=P(w_1)P(w_2|w_1)P(w_3|w_{1:2})...P(w_n|w_{1:N-1})
=\prod_{i=1}^NP(w_i|w_{1:i-1})
P(wi:N)=P(w1)P(w2∣w1)P(w3∣w1:2)...P(wn∣w1:N−1)=i=1∏NP(wi∣w1:i−1)
P(w2|w1) 表示了w1文本出现的情况下,出现w2文本的概率。

我们知道根据n-grams的方式,wi 文本出现的概率只和前n个文本的出现条件有关,但是根据马尔科夫假设,我们可以将这个概率近似的等于前面从1到n的文本出现的条件下的概率,这样我们就能将n-grams计算方式里的每一项都用条件概率计算方式下的每一项替代,也就得到1.9里的结论。
bigrams 例子
假设语料库中共涵盖 M 个不同的单词,{wi,wj} 出现的概率为 P(wi,wj) , 对应出现的频率
为 C(wi,wj),则可以列出似然函数:
L(θ)=∏i=1M∏j=1MP(wi,wj)C(wi,wj)
L(\theta)=\prod_{i=1}^M\prod_{j=1}^MP(w_i,w_j)^{C(w_i,w_j)}
L(θ)=i=1∏Mj=1∏MP(wi,wj)C(wi,wj)
我们知道似然函数是通过结果推参数,而我们知道了 wi 和 wj 的出现概率 ,又有两个词出现的频率,我们通过将所有出现的词概率累乘,也就是得到了现在这个语料库里,这两个词出现的概率,构造似然函数后也就得到上面公式。但是我觉得这是不是没有考虑到重复的情况。化简过程如下图:


拓展:s.t. 这是数学优化的一个化简符号,代表 subject to ,意思是约束于,一般后面跟着就是约束条件,代表原函数在这个约束条件下求解。
基于RNN的语言模型
循环神经网络(Recurrent Neural Network, RNN)是一类网络连接中包含环路的神经网络的总称。通过历史状态循环积累实现未来预测,也就是基于历史规律。
RNN
神经网络分为前馈传播范式(FNN)和循环传播范式(RNN)。


可以看到推导公式里,当前的隐变量就是上一个隐变量通过激活函数得到的结果,对比前馈可以看到,不同处就是激活函数里是否存在隐变量递归的关系。所以前馈神经网络很难进行历史信息考虑,除非将所有历史信息作为一个输入参数才行,这不现实。
由于 RNN 需要大量的矩阵联乘操作,容易引起梯度衰减或梯度爆炸问题。
假设有个损失函数 l(·) ,如果想要算出一个关于损失函数关于参数 Wh 的梯度,最大梯度下降法经常用到,梯度也就是对 Wh 的偏导,相当于斜率,上面推导公式知道 RNN 的激活函数里包含了大量的递推式,也就是包含了很多的联乘计算,如果当 Wh 的最大特征值大于1时,可能会导致梯度极大,而如果小于1则又会导致极小,也就是上面说的问题。
为了解决这个问题,GRU 和 LSTM 引入门控结构,取得了良好效果,成为主流的 RNN 网络架构。
基于RNN的模型
对词序列 {w1, w2, w3, …, wN },基于 RNN 的语言模型每次根据当前词 wi 和循环输入的隐藏状态 hi−1,来预测下一个词 wi+1 出现的概率,基于此即可推出整个词出现的概率。
P(wi+1)=P(wi+1∣wi,hi−1)=>P(wi:N)=∏i=1N−1P(wi+1∣wi,hi−1)
P(w_{i+1})=P(w_{i+1}|w_i,h_{i-1})=>P(w_{i:N})=\prod_{i=1}^{N-1}P(w_{i+1}|w_i,h_{i-1})
P(wi+1)=P(wi+1∣wi,hi−1)=>P(wi:N)=i=1∏N−1P(wi+1∣wi,hi−1)

例子
假设词表 D={吃,脖子,头部,长,疼,短},那么"长颈鹿脖子长"概率计算过程如下所示:

P(长颈鹿脖子长)=P(脖子|长颈鹿)*P(长|脖子, h1)=0.2 *0.6=0.12
对于这个预训练任务,我们可以采用交叉熵函数作为损失函数(补充知识)。
lCE(oi)=−Σd=1∣D∣I(w^d=wi+1)logoi[wi+1]=−logoi[wi+1]
l_{CE(o_i)}=-\Sigma_{d=1}^{|D|}I(\hat{w}_d=w_{i+1})logo_i[w_{i+1}]=-logo_i[w_{i+1}]
lCE(oi)=−Σd=1∣D∣I(w^d=wi+1)logoi[wi+1]=−logoi[wi+1]
I(x) 是指示函数,如果真实概率和计算概率相等为1,不相等为0。
那么假设训练集为 S,每个样本的长度都为 N,那么整个模型的损失就需要把所有的样本都计算在内做算术平均:
L(S,WI,WH,WO)=1N∣S∣∑s=1∣S∣∑i=1NlCE(oi,s)
L(S,W_I,W_H,W_O)=\frac{1}{N|S|}\sum_{s=1}^{|S|}\sum_{i=1}^{N}l_{CE(o_i,s)}
L(S,WI,WH,WO)=N∣S∣1s=1∑∣S∣i=1∑NlCE(oi,s)
oi,s 表示第 s 个样本的第 i 个词,通过自回归的范式下,将每个生成出来的词拼接上次的输入,作为下一次的模型输入,这样就能递归的完成一段文本的生成。但自回归有几个问题:1. 错误级联放大,对于生成错误的词后,拼接作为输入得到的结果也会错,这样错误会不断的放大;2. 串行效率低,由于递归的特性,难以并行加速。
所以引用了 “Teacher Forcing” 在预训练里使用,去解决这两个问题,方法就是让每次输出都和标准答案拼接,但这又引出了曝光偏差问题(模型训练过程和推理过程存在差异)。在此基础上Bengio等人提出 Scheduled Sampling 方法,让模型在训练过程中慢慢将自己生成的结果替换掉标准答案。
基于 Transformer 的语言模型
Transformer 是一类基于注意力机制(Attention)的模块化构建的神经网络结构,将一定数量的历史状态和当前状态同时输入,然
后进行加权相加,然后对未来状态进行预测。
Transformer
由两种模块组合构建的模块化网络结构:
- 自注意力(Attention)模块,由自注意力层(Self-Attention Layer)、残差连接(Residual Connections)和层正则化(Layer Normalization)组成;
- 全连接前馈(Fully-connected Feedforwad)模块,由全连接前馈层,残差连接和层正则化组成。

自注意力层:采用加权平均的思想,将前文信息叠加到现在状态上,在 Transformer 里会将输入编码成 query,key,value 三个部分,query 和 key 用来计算自注意力权重α,value 是输入的编码。
Attention(xt)=∑i=1tαt,ivi Attention(x_t) =\sum_{i=1}^t\alpha_{t,i}v_i Attention(xt)=i=1∑tαt,ivi
αt,i=softmax(sim(xt,xi))=sim(qt,ki)∑i=1tsim(qt,ki) \alpha_{t,i}=softmax(sim(x_t,x_i))=\frac{sim(q_t,k_i)}{\sum_{i=1}^tsim(q_t,k_i)} αt,i=softmax(sim(xt,xi))=∑i=1tsim(qt,ki)sim(qt,ki)
其中 sim() 函数是度量两个输入之间的相关程度,softmax 函数是对相关程度进行归一化,此外三个输入会乘上一个编码器的参数,用来控制微调效果。
qi=Wqxi,ki=Wkxi,vi=Wvxi q_i = W_qx_i, k_i = W_kx_i, v_i = W_vx_i qi=Wqxi,ki=Wkxi,vi=Wvxi

上图以三个输入{x1,x2,x3}为例介绍了自注意力机制。
全连接前馈层:全连接前馈层占据了 Transformer 近三分之二的参数,掌管着 Transformer 模型的记忆。其可以看作是一种 Key-Value 模式的记忆存储管理模块。全连接前馈层包含两层,两层之间由 ReLU 作为激活函数。设全连接前馈层的输入为 v, 全连接前馈层可由下式表示:
FFN(v)=max(0,W1v+b1)W2+b2
FFN(v) = max(0, W_1v + b_1)W_2 + b_2
FFN(v)=max(0,W1v+b1)W2+b2
其中,W1 和 W2 分别为第一层和第二层的权重参数,b1 和 b2 分别为第一层和第二层的偏置参数。其中第一层的可看作神经记忆中的 key,而第二层可看作 value。
层正则化层:该层会将输入 v 的每一个维度 vi 都执行层正则化操作,方便计算,用来加速神经网络训练过程并取得更好的性能,公式如下:
LN(vi)=α(vi−μ)δ+β(α,β是可学习参数;μ,δ是隐藏状态的均值和方差)
LN(v_i)=\frac{\alpha(v_i-\mu)}{\delta}+\beta (\alpha,\beta是可学习参数;\mu,\delta是隐藏状态的均值和方差)
LN(vi)=δα(vi−μ)+β(α,β是可学习参数;μ,δ是隐藏状态的均值和方差)
μ=1n∑i=1nvi,δ=1n∑i=1n(vi−μ)2
\mu=\frac{1}{n}\sum_{i=1}^nv_i , \delta=\sqrt{\frac{1}{n}\sum_{i=1}^n(v_i-\mu)^2}
μ=n1i=1∑nvi,δ=n1i=1∑n(vi−μ)2
残差链接层:可以有效解决梯度消失问题,将层正则化置于残差连接之后的网络结构被称为 Post-LN Transformer,置于之前称为 Pre-LN Transformer。
原始的 Transformer 采用 Encoder-Decoder 架构,编码器和解码器都采用6个layer做级联。解码器里的自注意力模块有两层,第一层叫自注意力模块,第二层叫交叉注意力模块,两层的输入不同。

基于Transformer的语言模型
基于这种架构上,我们可以设计多种预训练任务来训练模型,例如:BERT,T5,GPT-3等。与 RNN 语言模型相同,Transformer 也常用交叉熵函数作为损失函数,所以构造的损失函数一样,预训练也使用**“Teacher Forcing”**范式。不同的是Transformer 可以使用并行计算,但是并行输入导致网络模型规模也随着输入序列长度增长而平方次增长。
语言模型采样方法
语言模型的输出为一个向量,该向量的每一维代表着词典中对应词的概率,在采用自回归范式的文本生成任务中,语言模型将依次生成一组向量并将其解码为文本,将这组向量解码为文本的过程被成为语言模型解码,当前,两类主流的解码方法可以总结为1. 概率最大化方法; 2.随机采样方法。
概率最大化方法
了解了模型知识后我们知道,生成的文本概率是通过生成每个词的条件概率级联得到的,概率最大化解码方法目的是找到最大化的那个概率,生成可能性最高的文本。概率最大化方法很容易让文本缺乏新颖性,全是重复文本。
贪心搜索(greedy search)
基于贪心算法,在每次预测中都选择概率最大的那个词,但当前概率大的词有可能导致后续的词概率很小,这很容易陷入局部最优,难以达到全局最优。
波束搜索(beam search)
每次预测时都保留n个可能性最高的词,结束搜索时找到最优组合使得联合概率最大。
随机采样方法
在预测时加入随机性,用以增加生成文本的多样性,但并不是完全随机的方式,会选择可能性最高的几个词,然后再安装概率分布随机的采样。
Top-K 采样
每次预测时,选取 k 个概率最高的词作为候选词集合,然后对这些词进行 softmax 函数操作进行归一化,得到分布函数,然后根据该分布得到采样结果。但是如果候选词分布的方差较大时,可能会选到概率小的词导致胡言乱语,如果方差较小时代表候选词意思及其相似,但是选择候选词的数量固定,导致缺乏新颖性,所以提出了 Top-P 采样解决这个问题。
Top-P 采样(Nucleus 采样)
为了解决固定候选集所带来的问题,提出了该方法;设定一个 p 阈值,每次预测时都选择概率大于该阈值 p 的词作为候选词,后续和 Top-K 一样,归一化后得到分布函数,再得到采样结果;因为设定了阈值,所以排除了概率小的词,解决了胡言乱语的问题,而且没有设置一个固定数量的候选词,所以可以包含更多的候选词,增加文本的丰富度。
Temperature 机制
由于前两个采样方法随机性都是模型输出的候选词概率分布函数决定的,但是有些时候我们需要手动调整随机性,例如写文章的时候我们需要随机性更强,但是写代码时需要随机性弱一些,引入 Temperature 机制就为了解决这个问题,在解码的时候进行随机性调节;对 Softmax 函数中的自变量进行尺度变换,然后利用 Softmax 函数的非线性实现对分布的控制。
假设尺度变换的控制变量设置为 T ,对每个自变量都除上这个数,如果 T>0 ,那么候选词之间的概率差距会减小,导致分布更平坦,每个候选词的选择概率越相近,随机性更强,如果 T<0 ,那么候选词之间的概率差距会加大,概率大的会更大,导致概率高的候选词更容易被选中,那么随机性更弱。
语言模型的评测
当我们训练出一个模型后,我们需要对其生成能力进行一个评测,才能知道这个模型的性能好坏,评测的方法一般分为两类,第一类称为内在评测,不需要根据具体执行任务的结果来判断,直接通过模型输出的来评测;第二类称为外在评测,也就是我们让模型执行具体任务,根据执行的结果好坏来评价。
内在评测
测试文本通常由与预训练中所用的文本独立同分布的文本构成,不依赖于具体任务;最为常用的内部评测指标是困惑度(Perplexity),其度量了语言模型对测试文本感到“困惑”的程度。假设有一个测试文本,长度为 N,困惑度的计算如下:
PPL(Stest)=P(w1:N)−1N=∏i=1N1P(wi∣w<i)N
PPL(S_{test})=P(w_{1:N})^{-\frac{1}{N}}=\sqrt[N]{\prod_{i=1}^N\frac{1}{P(w_i|w_{<i})}}
PPL(Stest)=P(w1:N)−N1=Ni=1∏NP(wi∣w<i)1
可以看出这是对测试文本的联合概率密度进行了处理,概率越高则困惑度越小,概率越低困惑度越大,简单的说就是测试文本概率越高,那么模型对这个文本就越熟悉,由此我们可以就知道为什么要倒数一下了,是因为让值的变化更符合名称定义。我们也可以使用交叉熵的方式去改写困惑度公式,也可以自己设计一个算法公式,但是要注意让值的变化和原来一样就行。
外在评测
测试文本通常包括该任务上的问题和对应的标准答案,其依赖于具体任务,也分为两类。
基于统计指标的评测
也就是对比模型输出和标准答案,看契合程度;BLEU(BiLingual EvaluationUnderstudy) 和 ROUGE(Recall-Oriented Understudy for Gisting Evaluation) 是应用最为广泛的两种统计指标。
BLEU 用于评价机器翻译任务上的效果,采用了统计方法去计算生成的翻译与参考翻译间的重合程度,例如使用多层 n-grams 精度的几何平均。统计生成的文本里和答案重合的词数量占文本词总量的比例,然后再取 N 个 n-gram 精度的几何平均作为评测结果,例如:3-gram 结果就用 1-gram,2-gram,3-gram结果相乘再开 3 次根。
ROUGE 被提出用于评价模型在摘要生成任务上的效果,常用的 ROUGE 评测包含 ROUGE-N, ROUGE-L, ROUGE-W, 和ROUGE-S 四种,ROUGE-N 是基于 n-gram 的召回指标,公式和 BLEU 的一样。ROUGE-L 是基于最长公共子序列(Longest Common Subsequence, LCS)的召回指标,公式和 n-gram 的类似,只是这个用的统计是 LCS。ROUGE-W 是在 ROUGE-L 的基础上,引入对 LCS 的加权操作后的召回指标。ROUGE-S 是基于 Skip-bigram 的召回指标。
基于统计指标的方法还是太过死板,对于要求灵活性和多样性的文本时,没法较为准确的评测,所以提出基于语言模型的方法。
基于语言模型的评测
主要分为两类:1.基于上下文词嵌入(Contex-tual Embeddings)的评测方法,例如 BERTScore;2.基于生成模型的评测方法,例如 G-EVAL 。但是 BERTScore 依赖于参考文本,所以成本较大,而 G-EVAL 就不用。
BERTScore 是基于 BERT 计算出参考文本和生成文本每个词的上下文词嵌入向量,得到两个集合后就可以计算 BERTScore ,BERTScore 考虑了精度,召回,F1 度量三个指标,更接近人类评测结果。
G-EVAL 是让 GPT-4 模型,基于提示词工程,引导模型输出评测分数;评测步骤是在任务描述和评分标准的提示词上由 GPT-4 自己生成的思维链(Chain-of-Thoughts, CoT),生成后再将所有的内容都作为提示词给模型计算评分。

大语言模型架构
由于现在计算机资源和能力越来越强,导致现在现在模型有了质的飞跃,进入了大语言模型(Large Language Model, LLM)的新时代,凭借着庞大的参数量和丰富的训练数据,更是催生出了生成式人工智能(Artificial Intelligence Generated Content,
AIGC)。
大数据 + 大模型 → 新智能
由于现在大数据的发展,有海量的训练数据以及庞大的模型规模,所以衍生出的模型能力更强,泛化能力更广。

大数据 + 大模型 → 能力增强
由于更多的数据,更大的规模能让模型能力更强,但是这都需要计算成本和存储需求,这就在模型设计时要找到一个平衡点,所以某些公司就提出了准则,例如:OpenAI 提出的 Kaplan-McCandlish 扩展法则以及 DeepMind 提出的 Chinchilla 扩展法则。
Kaplan-McCandlish 扩展法则
该法则由 OpenAI 团队提出,命名由两个成员名字组成,研究神经网络的性能与数据规模 D 以及模型规模 N 之间的函数关系。
L(D)=(DDc)αD,αD∼−0.095,Dc∼5.4×1013∣L(N)=(NNc)αN,αN∼−0.076,Nc∼8.8×1013
L(D)=(\frac{D}{D_c})^{\alpha_D},\alpha_D\sim-0.095,D_c\sim5.4\times10^{13} |
L(N)=(\frac{N}{N_c})^{\alpha_N},\alpha_N\sim-0.076,N_c\sim8.8\times10^{13}
L(D)=(DcD)αD,αD∼−0.095,Dc∼5.4×1013∣L(N)=(NcN)αN,αN∼−0.076,Nc∼8.8×1013
上面是研究结果,L(.) 是交叉熵损失函数,L(N) 代表数据规模固定,模型规模不同,L(D) 代表模型规模固定,数据规模不同,其值越小代表学习能力越强。
此外他们研究计算预算最优分配时,发现模型规模和数据规模影响模型效果最大,并且模型规模的增长速度应该略快于数据规模的增长速度,模型规模和数据规模的最优配置比例为增加预算的 0.73次方和0.27次方,例如总计算预算增加了 10 倍,模型规模应扩大约 10的0.73次方 = 5.37 倍,而数据规模应扩大约 1.86 倍。
Chinchilla 扩展法则
谷歌的 DeepMind 团队则提出不同的看法,他们根据实验研究提出最优配置应该是 0.46次方:0.54次方(模型规模:数据规模)结论,表明数据规模和模型规模同等重要,并且理想的数据集大小应该是模型规模的 20 倍。
大数据 + 大模型 → 能力扩展
随着模型训练数据规模以及参数数量的不断提升,在模型达到一定规模和复杂度后,有些能力很突然的就会显现,也被称为大语言模型的涌现能力,例如:上下文学习,常识推理,代码生成,逻辑推理。
大语言模型架构概览
在语言模型的发展历程中,Transformer 框架的问世代表着一个划时代的转折点,当前,绝大多数大语言模型均以 Transformer 框架为核心,并进一步演化出了三种经典架构,分别是 Encoder-only 架构,Decoder-only 架构以及 Encoder-Decoder 架构。
主流模型架构的类别
Encoder-only 架构:包含了三个部分,输入编码部分会通过被分词器(Tokenizer)将原始输入文本拆解为 Token 序列,随后通过词表和词嵌入(Embedding)矩阵映射为向量序列,然后为了保证单词的顺序信息,每个向量序列会被赋予位置编码。特征编码部分会将向量序列通过自注意力机制和前馈网络进一步提取和深化文本特征。任务处理部分会根据不同的任务特定编码和定制化设计。

Encoder-Decoder 架构:为了弥补 Encoder-only 架构在文本生成任务上的短板,Encoder-Decoder 架构在其基础上引入了一个解码器(Decoder),解码部分的分词器和输出文本只在训练阶段存在,自回归的红色虚线只在推理阶段存在。输出生成部分负责将特征解码后的向量转为词表上的概率分布,并从这个分布中采样最合适的 token 作为输出。

Decoder-only 架构:为了有效缩减模型的规模以及降低整体的计算复杂度,直接去掉编码器部分。

注意力矩阵:注意力矩阵是 Transformer 中的核心组件,用来计算输入序列中的各个 Tolen 之间的依赖关系,而上面三个架构的注意力矩阵都有所差异。Encoder-only 架构完全依赖整个输入序列的所有 Token ,当 token xi 转为上下文向量 yi 时,模型能综合利用所有的输入信息,这就是双向注意力机制。Encoder-Decoder 架构的注意力矩阵比较复杂,结合了自注意力,掩码自注意力,交叉注意力三种机制。Decoder-only 架构只依赖已经生成的历史 Token 信息,是单向注意力机制。
适用任务:由于 Encoder-only 架构能充分考虑到前后文信息,所以特别适合自然语言理解;Encoder-Decode 架构加了解码器,所以适合处理复杂的有条件生成任务;Decoder-only 架构只关注生成,所以非常适合无条件文本生成任务,现在市面上流行的大部分模型都是使用的该架构。
基于 Encoder-only 架构的大语言模型
BERT 模型以及其衍生模型,例如 ELECTRA 。预训练采用了静态掩码建模,也就是对输入文本故意遮挡某些词,让模型完形填空,然后通过对比正确答案调整参数配置,优化模型。
基于 Encoder-Decoder 架构的大语言模型
decoder 采用了掩码自注意力机制,仅以上文为条件得到下文,通过掩盖操作避免解码器得到了下文的信息。T5 和 BART 就是很具代表性的模型,这两个预训练都是通过掩码的方式破坏文本,然后再修复文本这种方式去学习知识。
基于 Decoder-only 架构的大语言模型
GPT 系列模型,LLaMA 系列模型,InstructGPT 是 ChatGPT 前身,通过引入人类反馈强化学习(Reinforcement Learning from Human Feedback, RLHF),提升模型的响应能力。
非 Transformer 架构
由于 Transformer 结构存在长序列处理问题,模型规模会随着输入序列长度平方增长,所以提出了 状态空间模型(State Space Model,SSM)和测试时训练(Test-Time Training,TTT)。
Prompt 工程
Prompt 工程简介
传统的自然语言处理研究遵循“预训练-微调-预测”范式,然而,随着语言模型在规模和能力上的显著提升,一种新的范式——“预训练-提示预测”应运而生,无需微调,只需要精心设计 Prompt 引导大模型即可,提示词的设计对模型的性能有着非常大的影响,这种专注于如何编写 Prompt 的技术,被称为 Prompt 工程。
定义:Prompt 是指用于指导生成式人工智能模型执行特定任务的输入指令,这些指令通常以自然语言文本的形式出现。

Prompt 工程的定义:又称提示工程,是指设计和优化用于与生成式人工智能模型交互的 Prompt 的过程。

良好设计的提示词通常由任务说明、上下文、问题、输出格式四个基本元素组成。
Prompt 分词向量化
提示词输入到大模型中,会通过分词器将其分为 token 序列,然后再向量化,向量化的过程也叫嵌入过程。

上图可以看到‘浣’字被两个特殊字符表示,这是因为为了压缩词表空间,采用 token 组合表达各种稀有字符。
分词器依赖分词算法,例如 BBPE ,BPE , WordPiece 等。例如 BBPE 的流程:
- 初始化词表:首先,将所有字符按照其底层编码拆分为若干字节,并将这些单字节编码作为初始词表的 Token。
- 统计词频:接下来,统计词表中所有 Token 对(即相邻 Token 的组合)的出现频率。在初始阶段,Token 对即为相邻字节的组合。
- 合并高频 Token 对:然后,选择出现频率最高的 Token 对,将其合并成一个新的 Token 并加入词表。
- 迭代合并:重复步骤 2 和步骤 3,不断迭代合并,直至达到预设的词表大小或达到指定的合并次数。
上下文学习
上下文学习(In-Context Learning, ICL)是一种通过构造特定的 Prompt,来使得语言模型理解并学习下游任务的范式,这些特定的 Prompt 中可以包含演示示例,任务说明等元素。
上下文学习根据样本的数量分为多种形式:零样本(Zero-shot)、单样本(One-shot)和少样本(Few-shot)。
演示示例选择
演示示例在引导大语言模型理解任务中扮演着重要作用,选择的标准主要依靠相似性和多样性来看。
直接检索 :直接检索通过将候选示例和待解决问题间进行编码,然后通过相似性来排序,选择靠前的几个示例,代表性方法就是 KATE ,利用 RoBERTa 将其编码,然后通过计算两个的向量余弦相似度,对二者的相似度进行评分。
聚类检索 :为了解决直接检索的多样性不足问题,该方法先采用聚类,将候选示例分为多个簇,然后从每个簇里面选一个相似性最高的示例,代表性方法就是 Self-Prompting ,采用 K-Means 算法聚类。
迭代检索 :首先选相似度最高的示例,然后再通过问题和已选的示例,动态选择下一个示例,也就是根据情况选则,代表性方法是 RetICL ,基于 LSTM 的检索器内部状态选择。
思维链
为了提高模型处理复杂问题的能力,提出了思维链的提示词方式,思维链提示(Chain-of-Thought,CoT)通过模拟人类解决复杂问题时的思考过程,引导大语言模型在生成答案的过程中引入一系列的中间推理步骤。

在 CoT 核心思想的指引下,出现了各种提示词方法,按推理方式归纳出了三种模式:按部就班、三思后行和集思广益。
按部就班:一步接着一步的推理,遵循一条逻辑连贯的路线走。三思后行 :每一步都停下来估当前的情况,然后选择最优的下一步执行。集思广益:生成多条推理路径并得到多个结果,然后整合这些结果,得到一个更为全面和准确的答案。
Zero-Shot CoT :通过简单的提示词,如“Let’s think step by step”,引导模型自行生成一条推理链。
Auto CoT :在上面一个的基础上添加了示例,通过聚类技术从题库里找到和用户提问一类的问题,然后借助 Zero-Shot CoT 方式生成推理链,形成示例。
拆解,衍生,评估,搜索 :这是三思后行的四种方法,第一种就是一步一步拆解问题;第二种就是根据提供的样本或提示的下一步推理方向考虑;第三种就是评分投票决定推理节点是否合理;第四种就是通过搜索算法找到解决方案的路径。
提示词技巧
在写提示词时,要注意用词明确,问题和说明需要简洁了当,并且格式清晰明了,缩进整齐,这样才能让模型准确理解分析。
可以使用心理暗示方式,让模型扮演什么角色,然后根据这个角色回答问题,能让模型回答更准确,更专业。
情景带入可以让回答更加丰富且有深度,我们可以通过让模型处于某些历史背景,专业知识等信息下让模型回答。
参数高效微调
由于模型训练的知识有限,所以对于垂直领域,需要进行下游任务适配才能提高模型性能,主流的下游任务适配方法:上下文学习,指令微调。
上下文学习是利用模型的能力,设计提示词让模型利用提示词里上下文的知识来回答,但是性能还是存在差距。
指令微调是将指令数据集给到大模型,训练模型,增加推理能力,泛化能力,但是需要较大的计算资源。
监督微调是在给定指令和输入的情况下,通过顺序预测输出中的每个 token 来训练模型。
简介: 参数高效微调目的主要是尽量减少模型参数的调整,从而提高微调的效率,主流的 PEFT 方法可以分为三类,参数附加方法,参数选择方法,低秩适配方法。目前比较主流的就是 Hugging-Face 的 HF-PEFT 框架。
参数附加方法
在模型结构中附加新的、较小的可训练模块,微调时,仅微调这些新加入的模块,这些模块通常称为适应层,典型方法包括:适配器微调(Adapter-tuning)、提示微调(Prompt-tuning)、前缀微调(Prefix-tuning) 和 代理微调(Proxy-tuning)。
模块可以加在输入,模型,输出。加在输入:将额外参数附加到输入嵌入中,其中最经典的方法是 Prompt-tuning 。加在模型:将额外参数加在预训练模型的隐藏层中,经典的方法有 Prefix-tuning 、Adapter-tuning 和 AdapterFusion 。
参数选择方法
仅选择模型的一部分参数进行微调,而冻结其余参数,典型的方法包括:BitFit 、Child-tuning 以及 FishMask 。
参数选择可以分为两类,基于规则的方法和基于学习的方法。基于规则就是根据人类专家的经验,确定哪些参数应该被更新。基于学习的方法则是模型自动的选择部分参数更新。
低秩适配方法
通过低秩矩阵来近似原始权重更新矩阵,并冻结原始参数矩阵,仅微调低秩更新矩阵,典型方法是:LoRA 是经典的低秩适配方法,后续有 AdaLoRA 、DyLoRA 以及 DoRA 。
LoRA 仅微调部分低秩参数,因此具有很高的参数效率,同时不会增加推理延迟,在训练后可以将 LoRA 参数与模型参数分离,所以 LoRA 还具有可插拔性。LoRA 的可插拔特性使其能够封装为被多个用户共享和重复使用的插件。
但是 LoRA 对于复杂的下游任务还是存在性能差距,所以进一步提出以下方式来改进:1. 打破低秩瓶颈,增加 LoRA 的秩,例如 ReLoRA 的合并和重置方法。2. 动态秩分配,例如 AdaLoRA 将参数更新矩阵参数化为奇异值分解(SVD)的形式,再通过奇异值剪枝动态调整不同层中 LoRA 模块的秩。3. 训练过程优化,例如 DoRA (权重分解低秩适应) 提出约束梯度更新,侧重于更新参数的方向变化。
模型编辑
模型有些时候会出现错误答案,可能存在偏见、毒性、知识错误等问题。为了解决问题可以考虑重新预训练和微调,但是这两种方法都有其局限性,耗费时间资源,并且可能导致模型过拟合和灾难性遗忘,不太适合这种变化性强,容易改变的知识,所以模型编辑出现了。
模型编辑的目的是让模型输出期望结果,同时不影响其他无关输出。

书中将模型编辑的性质归纳为五个方面,分别为准确性(Accuracy)、泛化性(Generality)、可迁移性(Portability)、局部性(Locality)和高效性(Efficiency),可以从这五个方面去量化模型编辑后的性能。
模型编辑经典方法

知识缓存类似于重新设置一个外部数据库,在门控发现是特定问题相关时,就用这个外部的知识库;而附加参数就和微调一样,在模型的隐藏层里添加额外的参数调整模型,流行的就是 T-Patcher 方法;元学习法就是让模型自己学习如何更新参数,更新哪些参数;而定位编辑就是通过某些判断方法去评判哪些参数需要更新,直接修改这些参数,流行的就是 ROME 方法。
书中这部分后面的内容我已经有些看不懂了,需要深入了解学习 transformor 后再来看这书,应该会有更深层次的理解了。
检索增强生成
简介 :通过检索和整合外部知识来增强大语言模型生成文本的准确性和丰富性;由于模型知识可能存在偏差和实效性,或者没有某些方面的知识,导致幻觉问题,所以需要检索正确的知识作为提示词提供给模型来回答。
组成 :RAG 通常集成了外部知识库(Corpus)、信息检索器(Retriever)、生成器(Generator,即大语言模型)等多个功能模块。核心优势在于不需要对大语言模型的内部知识进行更新,便可改善大语言模型的幻觉现象,提高生成质量。
检索增强生成架构
检索器和生成器的协作方式对性能影响最显著。
分类:黑盒架构和白盒架构,区别在于是否微调生成器的参数。

知识检索
优化检索过程,提升检索的效果和效率,对改善 RAG 的性能具有重要意义。
数据采集和预处理能提高数据质量,提高检索的效率和准确性;让模型生成文档的标题,然后把这个标题作为文档检索的索引,通过这种方式,可以增强文档与用户查询的匹配度;通过同义改写,使用不同方式的提问,将获得的答案合并和去重处理,从而
形成一个更大的相关文档集合;使用分治的理念能将复杂的问题分解到某些具体的问题上,综合这些答案得到成一个更加全面和深入的最终答案;让模型生成问题的背景文档,然后再将这些文档作为上下文内容检索,提高检索结果的相关性和丰富性。
分类 :检索器可分为判别式检索器和生成式检索器两类;
1. 判别式检索器 :判别式检索器通过判别模型对查询和文档是否相关进行打分;判别式检索器通常分为两大类:稀疏检索器和稠密检索器。稀疏检索器利用离散的、基于词频的文档编码向量进行检索,典型的技术包括 TF-IDF 和 BM25 等,而稠密检索器则利用神经网络生成的连续的、稠密向量对文档进行检索,大概可以分为两类:交叉编码类、双编码器类。

1. 生成式检索器 :将知识记忆在模型的参数里,然后让模型自己生成和查询相关的文档。
检索效率增强
1. 相似度索引算法 :在向量检索中,常用的索引技术主要分成三大类:基于空间划分的方法、基于量化方法和基于图的方法。基于空间划分的方法:常见的就是树的索引方法(KD 树和 Ball 树),基于哈希的方法(局部敏感哈希 LSH );基于图的方法就是以向量为节点,根据向量的距离或相似性为边建立邻近图(NSW 、IPNSW 和 HNSW );基于量化的方法就是将高维向量空间划分为多个子空间,然后在每个子空间聚类得到量化的索引( OPQ,IVFPQ )。
2. 常见软件库介绍 :Faiss 工具库,支持多种索引算法,包括但不限于上面介绍的几种,但是在数据存储、管理、分布式支持和安全性措施等方面功能有限;向量数据库适合更复杂的 RAG 应用场景。

检索结果重排
重排方法主要分为两类:基于交叉编码的方法和基于上下文学习的方法。
实践与应用
搭建简单的RAG系统:使用 LangChain 和 LLamaIndex 框架搭建。
典型应用:智能体 和 多模态垂直领域应用。
课外知识
交叉熵损失函数
交叉熵损失函数常用于分类任务中,能很好的兼顾梯度下降的学习速度和正确样本以及错误样本之间的差异性,在一个样本集中存在两个概率分布,p(x) 为真实分布,q(x) 为非真实分布,基于真实分布,我们可以计算样本集的信息熵:
H(p)=−Σxp(x)logp(x)
H(p)=-\Sigma_xp(x)logp(x)
H(p)=−Σxp(x)logp(x)
负对数项代表了样本集的信息量,我们将q(x)替换真实分布得到交叉熵函数:
H(p,q)=−Σxp(x)logq(x)
H(p,q)=-\Sigma_xp(x)logq(x)
H(p,q)=−Σxp(x)logq(x)
信息熵
又称香农熵,用于量化信息的不确定性或者平均值(也称作信息量的期望),公式:
H(x)=−Σi=1npilog2pi
H(x)=-\Sigma_{i=1}^np_ilog_2p_i
H(x)=−Σi=1npilog2pi
马尔可夫假设以及马尔可夫链
马尔可夫假设:它假设了不符合独立事件,关联事件之间也依然存在概率,而计算方法就是马尔可夫链,我们也称为条件概率。
极大似然估计
似然:对于独立同分布的离散变量和符合同分布的连续随机变量,我们一般是已知每次的概率,然后求解某个结果出现的概率是多少,但是似然函数其实是通过已知某个结果的概率,然后求解什么样的情况可能会出现该结果,这种配置情况就是模型参数特征。
例如:有三个框,每个框里都有小球并且不同框的小球颜色不同,现在假设:a,b,c三个框里分别有红色,绿色,蓝色小球,但是每个框的具体数量并不清楚,我拿了五个小球,结果是2个红的,1个绿的,2个蓝的,而通过构造似然函数去求解每个框里可能出现多少球,这就是似然函数的目的。
极大似然:对上面的例子,我们可能求解出很多种情况,我们可以找到一个最有可能导致这种结果出现的情况,这就是极大似然。
构造似然函数:以独立同分布样本为例,先求得单个样本xi的概率P,由于样本独立,所以联合概率为各个样本的概率乘积。
L(θ)=∏i=1NP(X=xi;θ)
L(\theta)=\prod_{i=1}^NP(X=x_i;\theta)
L(θ)=i=1∏NP(X=xi;θ)
求解过程:首先列出似然函数,然后将似然函数取对数,转为加法,之后对函数求偏导,找到导数为0的极大点。
参考链接
极大似然估计:https://blog.csdn.net/weixin_41888257/article/details/82314114
LateX符号大全:https://zhuanlan.zhihu.com/p/657644820
交叉熵损失函数:https://www.cnblogs.com/BlairGrowing/p/15032046.html
信息熵:https://zhuanlan.zhihu.com/p/1893728991170520935
更多推荐


所有评论(0)