笔者由于工作原因需要使用LLM来完成一些网络安全相关的任务,但是笔者在调研后发现,目前讲解LLM的技术文章普遍集中于单个小点,而鲜有体系化讲解LLM使用的文章,因此,笔者准备从LLM使用者的角度出发,即不考虑LLM的训练与全参数微调等,仅仅是调用一个已训练好的LLM的api,系统化的讲解LLM的各种使用技巧------即提示工程。
什么是提示工程
提示工程用于开发和优化提示词(Prompt),帮助用户有效地使用语言模型。用户可利用提示工程来提高大语言模型处理复杂任务场景的能力,如问答和算术推理能力。开发人员可通过提示工实现大语言模型和其他生态工具的高效接轨。
提示工程不仅仅是设计和开发提示。它包含了一系列与LLMs交互、开发和理解LLMs能力的有用技能和技巧。
模型设置
再利用LLM的API时,我们可以配置一些参数来改进LLM的生成效果。比如温度(Temperature)、顶部概率(Top P)、最大长度(Max Length)、停止序列(Stop Sequences)、频率惩罚(Frequency Penalty)、存在惩罚(Presence Penalty)。那么这些参数究竟具有什么意义呢?
温度(Temperature)
定义与作用
Temperature参数用于调整语言模型生成文本的随机性。在生成结果时,模型并不是直接计算出生成的词,而是会计算出每个可能的下一个词的概率分布。如下图所示:
当你给模型输入一堆文本后,模型输出的是下一个单词的输出概率,然后经过一个采样策略来确定最终要输出的东西。Temperature参数实际上是在抽样策略阶段,对这些概率进行调整,以控制生成文本的多样性和可预测性。Temperature参数通常为一个从0到1的值。
- 高Temperature :增加生成文本的随机性,使得不太可能的词汇有更高的出现概率。这会导致生成的文本更加多样化和创造性,但同时也可能产生无意义或不连贯的文本。
- 低Temperature :减少随机性,使得更可能的词汇出现概率更高。这样生成的文本更加可预测和连贯,但可能缺乏创造性和多样性。
应用场景
- 创意写作 :在需要创意和新颖性的写作任务中,如诗歌、故事创作等,可以使用较高的Temperature值来激发模型的创造性。
- 正式文档 :在需要正式和准确信息的场合,如新闻报道、学术论文等,可以使用较低的Temperature值来确保生成文本的准确性和连贯性。
具体原理
在技术实现上,Temperature参数通过对模型输出的概率分布进行缩放来起作用。具体来说,对于每个可能的下一个词,模型计算出一个原始概率分布,然后使用以下公式进行调整:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> P adjusted ( w i ) = exp ( Temperature ⋅ log P ( w i ) ) ∑ j exp ( Temperature ⋅ log P ( w j ) ) P_{\text{adjusted}}(w_i) = \frac{\exp(\text{Temperature} \cdot \log P(w_i))}{\sum_j \exp(\text{Temperature} \cdot \log P(w_j))} </math>Padjusted(wi)=∑jexp(Temperature⋅logP(wj))exp(Temperature⋅logP(wi))
在这个公式中, <math xmlns="http://www.w3.org/1998/Math/MathML"> Temperature \text{Temperature} </math>Temperature代表Temperature参数, <math xmlns="http://www.w3.org/1998/Math/MathML"> P ( w i ) P(w_i) </math>P(wi)是模型计算出的原始概率, <math xmlns="http://www.w3.org/1998/Math/MathML"> log \log </math>log表示对数函数, <math xmlns="http://www.w3.org/1998/Math/MathML"> exp \exp </math>exp表示指数函数。通过这种方式,Temperature值改变了原始概率分布的"平滑度"。
这里我们举个例子:
假设我们有5个单词,分别为0-4,上图代表了这五个单词在不同的Temperature参数下的输出概率。Temperature参数越小,那么概率值越集中,或者说它放大了具有较大概率值的单词的概率 ,Temperature参数越大,概率值越平滑,或者说不同单词之间的概率值差别越小。
因此,temperature 的值越小,模型返回的结果越确定,模型会返回具有最大概率的词。如果调高该参数值,大语言模型可能会返回更随机的结果。因为加大Temperature参数相当于加大其他可能的单词的权重。
Top P
定义与作用
虽然我们在使用LLM的API时,会有一个top P参数,但这个参数实际上代表了一种概率分布截断技术,它允许模型在生成每个词时只考虑概率最高的一定比例的词汇。
具体来说,模型首先计算出所有可能的下一个词的输出概率,然后只从这个分布中累积概率最高的前P%的词中选择下一个词。这样,Top P采样在保持生成文本连贯性的同时,也为文本的多样性提供了空间。如下图所示:
- P值:P值决定了采样的严格程度。P值越高,采样的范围越广,生成的文本越倾向于多样性和随机性。P值越低,采样的范围越小,生成的文本越倾向于选择概率最高的词汇,从而更加连贯和可预测。
- 累积概率 :在Top P采样中,累积概率是指从概率分布的最高端 开始降序累加,直到达到P%的累积概率为止。只有累积概率能够达到P%的词汇才有资格被选中。
应用场景
- 多样性生成:在需要创造性和多样性的文本生成任务中,如创意写作、对话生成等,Top P采样可以帮助模型避免过早地陷入重复和固定的模式。
- 减少重复:在生成文本时,模型可能会重复相同的词汇或短语。通过使用Top P采样,可以减少这种重复现象,提高文本的自然度和可读性。
技术细节
假设我们有一个概率分布,其中包含了词汇的概率排名。Top P采样的步骤如下:
- 计算概率分布:模型为所有可能的下一个词计算概率分布。
- 降序排序:将这些概率从高到低进行排序。
- 累积概率:从最高的概率开始,累加这些概率,直到累积概率达到或超过预设的阈值P。
- 选择词汇:在累积概率达到P的词汇集合中随机选择一个词作为下一个词。
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> Cumulative Probability = ∑ i = 1 k P ( w i ) where k = min i ∣ ∑ j = 1 i P ( w j ) ≥ P \text{Cumulative Probability} = \sum_{i=1}^{k} P(w_i) \quad \text{where} \quad k = \min{i \mid \sum_{j=1}^{i} P(w_j) \geq P} </math>Cumulative Probability=i=1∑kP(wi)wherek=mini∣j=1∑iP(wj)≥P
在这个公式中: <math xmlns="http://www.w3.org/1998/Math/MathML"> P ( w i ) P(w_i) </math>P(wi) 表示第 <math xmlns="http://www.w3.org/1998/Math/MathML"> i i </math>i个词的概率。 <math xmlns="http://www.w3.org/1998/Math/MathML"> k k </math>k 是累积概率达到阈值 <math xmlns="http://www.w3.org/1998/Math/MathML"> P P </math>P时的最小词汇数量。 <math xmlns="http://www.w3.org/1998/Math/MathML"> i i </math>i 从1开始,表示概率最高的词。 <math xmlns="http://www.w3.org/1998/Math/MathML"> min \min </math>min 表示找到满足条件的最小 <math xmlns="http://www.w3.org/1998/Math/MathML"> i i </math>i值。
最大长度(Max Length)
最大长度用于控制模型生成的词的最大数量。指定最大长度有助于防止过长或不相关的响应,并控制模型的生成成本。
停止序列(Stop Sequences)
停止序列(Stop Sequences),是一种用于控制文本生成过程中何时停止生成的技术。这种技术特别重要,因为它可以帮助确保生成的文本在达到某个预定的结构或信息完整性后停止,避免生成无关或冗余的内容。例如,当你让LLM生成有序列表格式的内容时,你可以通过添加"11"作为停止序列,告诉模型生成不超过10个项目的列表。
定义与作用
停止序列是一段预定义的文本,用于指示模型在生成过程中应该停止进一步的文本输出。模型会在每个生成步骤中考虑停止序列作为潜在的输出。当模型预测到停止序列的概率足够高时,它会结束生成过程。
停止序列可以是一个特定的词、短语、符号或任何其他形式的标记,它们在文本生成的上下文中具有明确的含义。当模型遇到停止序列时,它会终止当前的文本生成过程。
停止序列的主要作用包括:
- 控制文本长度:通过设置停止序列,可以限制生成文本的最大长度,防止模型无限制地生成文本。
- 确保信息完整性:在某些应用场景中,如自动摘要或生成特定格式的文本,停止序列可以用来确保生成的文本包含所有必要的信息,并且在达到某个结构性的结束点后停止。
- 提高效率:在生成任务中,停止序列可以帮助减少不必要的计算资源消耗,因为模型知道在何时停止生成。
实现方式
停止序列可以通过以下几种方式实现:
- 显式定义 :在模型的输入中直接包含停止序列,例如在生成一段文本后添加特定的标记(如
<|endoftext|>
)。 - 条件生成:在模型的训练过程中,通过特定的条件或信号来训练模型识别何时应该停止生成文本。
- 后处理:在文本生成后,使用后处理算法来识别和截断文本,这种方法可能不如前两种方法精确。
频率惩罚(Frequency Penalty)
频率惩罚对模型输出的下一个词应用惩罚,频率惩罚的值与该词在响应和提示中出现的频率 成正比。频率惩罚越高,一个词再次出现的可能性就越小。这个设置通过给出现次数更多的词更高的惩罚来减少模型响应中词的重复。
定义与作用
频率惩罚用于影响模型在预测下一个词时的概率分布。当设置为正值时,频率惩罚会降低在响应中常见词 的出现概率,从而鼓励模型生成更少见或更创新的词汇。相反,当设置为负值时,模型会偏向于输出在响应中常见词,使得生成的文本更加倾向于使用训练数据中频繁出现的词汇。
工作原理
在文本生成过程中,模型会根据当前上下文计算下一个词的概率分布。频率惩罚通过调整这些概率来影响生成结果:
- 正频率惩罚:当模型预测一个词时,如果这个词在训练数据中出现得非常频繁,正的频率惩罚会降低这个词的相对概率,使得模型更倾向于选择其他不那么常见的词。
- 负频率惩罚:相反,负的频率惩罚会增加常见词的相对概率,使得模型更可能重复使用这些词。
技术细节
在技术实现上,不同模型可能使用不同的方法来实现频率惩罚,例如通过调整词汇的logits或者直接修改softmax函数输出的概率分布。但基本原理是类似的:
假设我们有一个词汇 <math xmlns="http://www.w3.org/1998/Math/MathML"> t i t_i </math>ti , <math xmlns="http://www.w3.org/1998/Math/MathML"> t i t_i </math>ti在已经生成的文本 <math xmlns="http://www.w3.org/1998/Math/MathML"> t < i t_{<i} </math>t<i中出现的频率为 <math xmlns="http://www.w3.org/1998/Math/MathML"> f ( t i , t < i ) f(t_i, t_{<i}) </math>f(ti,t<i),并且我们有一个频率惩罚参数 <math xmlns="http://www.w3.org/1998/Math/MathML"> α \alpha </math>α。 <math xmlns="http://www.w3.org/1998/Math/MathML"> P ( t i ∣ t < i ; θ ) P(t_i | t_{<i}; \theta) </math>P(ti∣t<i;θ)是词汇 <math xmlns="http://www.w3.org/1998/Math/MathML"> t i t_i </math>ti 在没有任何惩罚时的原始概率。那么,对于词汇 <math xmlns="http://www.w3.org/1998/Math/MathML"> t i t_i </math>ti 的调整后的概率 <math xmlns="http://www.w3.org/1998/Math/MathML"> P adj ( t i ∣ t < i ; θ , α ) P_{\text{adj}}(t_i | t_{<i}; \theta, \alpha) </math>Padj(ti∣t<i;θ,α) 可以通过以下方式计算:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> P adj ( t i ∣ t < i ; θ , α ) = P ( t i ∣ t < i ; θ ) ⋅ exp ( − α ⋅ f ( t i , t < i ) ) P_{\text{adj}}(t_i | t_{<i}; \theta, \alpha) = P(t_i | t_{<i}; \theta) \cdot \exp(-\alpha \cdot f(t_i, t_{<i})) </math>Padj(ti∣t<i;θ,α)=P(ti∣t<i;θ)⋅exp(−α⋅f(ti,t<i))
-
当α为正数时,表达式 <math xmlns="http://www.w3.org/1998/Math/MathML"> exp ( − α ⋅ f ( t i , t < i ) ) \exp(-\alpha \cdot f(t_i, t_{<i})) </math>exp(−α⋅f(ti,t<i))随着 <math xmlns="http://www.w3.org/1998/Math/MathML"> t i t_i </math>ti的出现频率 <math xmlns="http://www.w3.org/1998/Math/MathML"> f ( t i , t < i ) f(t_i, t_{<i}) </math>f(ti,t<i)的增加而减少。这导致过去出现频率更高的词的调整后的输出概率 <math xmlns="http://www.w3.org/1998/Math/MathML"> P a d j P_{adj} </math>Padj降低,有效地惩罚了重复。
-
如果α是负数,表达式 <math xmlns="http://www.w3.org/1998/Math/MathML"> exp ( − α ⋅ f ( t i , t < i ) ) \exp(-\alpha \cdot f(t_i, t_{<i})) </math>exp(−α⋅f(ti,t<i))对于出现频率更高的词将会增加,导致频繁出现的词的调整后概率 <math xmlns="http://www.w3.org/1998/Math/MathML"> P a d j P_{adj} </math>Padj提高。这种情况不会惩罚重复,而是奖励重复,使模型更有可能重复它已经生成的词。
存在惩罚(Presence Penalty)
存在惩罚也对重复的词应用惩罚,但与频率惩罚不同,对所有重复的词的惩罚是相同的。出现两次的词和出现10次的词受到相同的惩罚。这个设置防止模型在其响应中过于频繁地重复短语。
技术细节
存在惩罚可以通过调整给定单词或短语生成概率的方式来实现。设 <math xmlns="http://www.w3.org/1998/Math/MathML"> P adj ( t i ∣ t < i ; θ , β ) P_{\text{adj}}(t_i | t_{<i}; \theta, \beta) </math>Padj(ti∣t<i;θ,β) 为在给定前缀 t_{<i} 和模型参数 <math xmlns="http://www.w3.org/1998/Math/MathML"> θ \theta </math>θ 的条件下生成单词 <math xmlns="http://www.w3.org/1998/Math/MathML"> t i t_i </math>ti 的原始概率。存在惩罚调整后的概率 <math xmlns="http://www.w3.org/1998/Math/MathML"> P adj ( t i ∣ t < i ; θ , β ) P_{\text{adj}}(t_i | t_{<i}; \theta, \beta) </math>Padj(ti∣t<i;θ,β),其中 <math xmlns="http://www.w3.org/1998/Math/MathML"> β \beta </math>β 是存在惩罚系数,可以用以下公式表示:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> P adj ( t i ∣ t < i ; θ , β ) = P ( t i ∣ t < i ; θ ) ⋅ exp ( − β ⋅ 1 { t i ∈ t < i } ) P_{\text{adj}}(t_i | t_{<i}; \theta, \beta) = P(t_i | t_{<i}; \theta) \cdot \exp(-\beta \cdot \mathbb{1}{\{t_i \in t{<i}\}}) </math>Padj(ti∣t<i;θ,β)=P(ti∣t<i;θ)⋅exp(−β⋅1{ti∈t<i})
这里, <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 { t i ∈ t < i } \mathbb{1}{\{t_i \in t{<i}\}} </math>1{ti∈t<i} 是一个指示函数,如果 <math xmlns="http://www.w3.org/1998/Math/MathML"> t i t_i </math>ti 在 <math xmlns="http://www.w3.org/1998/Math/MathML"> t < i t_{<i} </math>t<i 中已经出现过,其值为 1;否则为 0。
因此,如果单词 <math xmlns="http://www.w3.org/1998/Math/MathML"> t i t_i </math>ti 已经在前面的文本中出现过,它被再次选择的概率 将乘以一个小于 1 的因子 <math xmlns="http://www.w3.org/1998/Math/MathML"> exp ( − β ) \exp(-\beta) </math>exp(−β),从而降低了这个单词的生成概率。