5.模型采样/解码策略
5.1 贪心解码策略 (greedy decoding)
核心思想:
每一步取当前最可能的结果,生成最终结果。
调用model.generate()时,不设置任何超参数时采用此策略。
input_ids = tokenizer.encode(text, return_tensors='pt')
outputs = model.generate(input_ids)
具体原理:
参考第1节内容,生成的张量最后一维是词表(vocab)中各个词的概率,取argmax/max作为需要生成的词向量索引,生成下一个词。
优缺点:
-
生成的文本具有较好的语义连贯性
-
贪心解码策略对于相同的输入LLM模型,每次都会给出一样的回答,推理模式下所有参数都固定,不存在随机性。
5.2 温度采样策略 (temperature sampling)
核心思想:
温度采样策略 (temperature sampling) 是受统计热力学启发的,其中高温意味着更可能遇到低能态。
调用model.generate()时,超参数 temperature被设置时采用此策略。注:temperature=1时表示不使用此方式。
input_ids = tokenizer.encode(text, return_tensors='pt')
outputs = model.generate(input_ids, temperature=0.7)
具体原理:
参考3.2节内容。
temperature参数用于控制生成文本的随机性和多样性,其实是调整了模型输出的logits概率分布。
优缺点:
-
temperature较高接近1时,归一化后的概率分布越均匀,导致生成的文本更具随机性和多样性;
-
temperature较低接近0时,归一化后的概率分布越陡峭,倾向于选择概率最高的token,导致生成的文本更加确定和集中。
-
temperature大于1时,则随机性增大,有效信息降低,0则相当于只是用argmax/max贪心解码策略 ,inf则相当于均匀采样。
-
生成的文本的语义连贯性受影响,上下文比较矛盾。
-
容易生成奇怪的话,出现罕见词。
5.3 top-k采样策略 (top-k sampling)
核心思想:
top-k采样策略 (top-k sampling)对概率进行排序,然后将位置第k之后的概率转换成0。
调用model.generate()时,超参数 top_k 被设置时[1,2,3...]采用此策略。
input_ids = tokenizer.encode(text, return_tensors='pt')
outputs = model.generate(input_ids, top_k=5)
具体原理:
参考3.2节内容。
当top_k为2时,只取概率值前2的参与采样。
优缺点:
-
降低模型生成无意义或重复的输出的概率,提升长尾那部分概率的干扰,同时提高模型的生成速度和效率
-
但是k的大小不好选,因为不同的句子,概率分布的变化有很大的区别。
-
概率分布均衡时,K偏小容易丢失优质的词。
-
概率分布集中时,K偏大容易引入奇怪的词,和随机采样没区别。
5.4 top-p采样策略 (top-p sampling)
核心思想:
top-p采样策略 (top-p sampling) 也叫核采样策略 (Nucleus sampling)。该策略将token的概率按照递减的次序累加,直到累加的概率值超过了阈值p,则对之后的概率进行置0,在这些低于阈值的token中做采样。
调用model.generate()时,超参数 top_p 被设置时(0~1)采用此策略。注:top_p=1时表示不使用此方式。
input_ids = tokenizer.encode(text, return_tensors='pt')
outputs = model.generate(input_ids, top_p=0.9)
具体原理:
参考3.3节内容。
当top_p较高时,比如 0.9,这意味着前 90% 的概率的token会被考虑在采样中,会有更多的token参与采样,增加生成文本的多样性。
当top_p较低时,只有前 10% 最高概率的token会被考虑在采样中。
如下图,当top_p为0.1时,只有1个概率值参与采样预测,这样会限制生成文本的可能性,使生成的文本更加确定和集中。
优缺点:
-
当top-p设置非常小时,累加的概率没超过top-p,一般会强制至少选出一个token。 -
设置top-p后会在一个动态长度的范围里做采样,优点是可以排除一些概率不高的单词。
5.5 束搜索解码策略 (beam search)
核心思想:
束搜索策略 (beam search)尝试在广度优先基础上进行搜索空间的优化(类似于剪枝)达到减少内存消耗的目的。
调用model.generate()时,超参数 num_beams 大于 1 且 do_sample 等于 False 时采用此策略。
input_ids = tokenizer.encode(text, return_tensors='pt')
outputs = model.generate(input_ids, num_beams=5, do_sample=False)
具体原理:
参考3.4节内容。
步骤如下:
-
在每个生成步骤中,都保留着 top K(K 即 num_beams 参数的值) 个可能的候选单词。
-
这 K 个单词都做下一步 decoding,分别选出 top K,然后对这 K^2 个候选句子再保留前 K 个最可能的结果。
-
如果已经生成了结束符,则将其对应的结果保留下来。
-
重复上述过程直到生成所有的结果或达到最大长度。
例如,当num_beams等于5时,生成5个不同的结果。
优缺点:
-
生成的文本上具有较好的语义连贯性。
-
但是不具备多样性的生成能力,总是对最可能的单词进行采样,会生成出空洞、重复、前后矛盾的文本,最终的结果退化 (degenerate)为"我爱你爱我爱你爱我..."。
-
存在重复生成的风险。
5.6 组束搜索解码策略 (diverse beam search)
核心思路:
组束搜索解码策略 (diverse beam search)是一种束搜索(beam search)算法的改进,叫做Diverse Beam Search (DBS)。
旨在从候选序列中找到最佳的输出序列。该策略结合了贪婪搜索和全局搜索的优点,通过同时考虑多个候选序列,以期望找到全局最优解。
调用model.generate()时,超参数 num_beams 大于 1, num_beam_groups 大于 1 ,diversity_penalty大于0,do_sample 等于 False 时采用此策略。
input_ids = tokenizer.encode(text, return_tensors='pt')
outputs = model.generate(input_ids, num_beams=5, num_beam_groups=5, diversity_penalty=0.8, do_sample=False)
具体原理:
束搜索(beam search)生成的结果还是会过于相似的,DBS做了一些改进,核心就是分组机制。
在组束搜索中,首先生成多个候选序列,然后对这些序列进行评分。评分通常基于语言模型的概率、翻译模型的得分以及长度惩罚等因素。接着,根据这些得分,选择最有可能是最佳输出的几个序列作为下一步的候选。这个过程不断迭代,直到达到预先设定的终止条件,比如达到最大长度或者达到一定数量的候选序列。
组束搜索的主要优点在于能够在保证一定搜索效率的情况下,找到接近最优解的输出序列。然而,由于需要同时考虑多个候选序列,组束搜索也会带来一定的计算开销。因此,在实际应用中,需要根据任务的要求和计算资源的限制来选择合适的束宽(beam width)以平衡搜索效率和解码质量。
例如,当 num_beams=5,num_beam_groups=5,分成2个组,每个组里的beam可以相似,但组和组之间要有足够的多样性。
只用束搜索解码策略:
设定生成相同长度时,使用组束搜索解码策略,生成的语句明显产生多样性:
优缺点:
-
生成的文本上具有较好的语义连贯性。
-
存在重复生成的风险。
5.7 受限束搜索解码策略 (constrained beam search)
核心思想:
受限束搜索解码策略 (constrained beam search),核心思想还是束搜索解码 (beam search),只不过在搜索时加入了我们提供的词表,强制其生成我们提供的词表。
调用model.generate()时,超参数 constraints 不为 None 或 force_words_ids 不为 None,而且 num_beams 大于1(本质还是束搜索),do_sample为False,num_beam_groups为1 时采用此策略。
input_ids = tokenizer.encode(text, return_tensors='pt')
outputs = model.generate(input_ids, num_beams=5, num_beam_groups=1, force_words_ids=2025, num_return_sequences=10, do_sample=False)
具体原理:
参考3.4节内容。
加了限制词my之后,生成的序列中出现了限制词my。
优缺点:
-
有概论生成我们限定的词,具有较好语义连贯性。
-
多样性受限。
5.8 对比搜索解码策略 (contrastive search)
核心思想:
对比搜索解码策略 (contrastive search),2022年A Contrastive Framework for Neural Text Generation 论文中提出来的方法,具体细节可以看论文。
调用model.generate()时,超参数 penalty_alpha 大于 0 且top_k 大于 1 时采用此策略。这是一种引入对比度惩罚的搜索方法,penalty_alpha是惩罚因子参数。
input_ids = tokenizer.encode(text, return_tensors='pt')
outputs = model.generate(input_ids, top_k=5, penalty_alpha=0.8)
具体原理:
生成的token应该是从模型预测的最佳候选(top k)中而来;
在生成token时,当前token应该能与前面生成的内容保持对比性(或差异性),若当前生成的token 与之前的序列token相似度很大,就减少其整体概率值,进而减少它被解码出来的可能性,避免重复解码的问题。
优缺点:
-
缓解生成空洞、重复、前后矛盾文本的风险。
5.9 多项式采样策略 (Multinomial sampling)
核心思想:
多项式采样解码策略(Multinomial sampling),通过改变logits的参数(temperature,top_k,top_p等)从而实现生成文本的多样性。
调用model.generate()时,超参数 num_beams 等于 1 且 do_sample 等于 True 时采用此策略,也可以使用model.sample()。注 do_sample=False 表示不使用此方式。
input_ids = tokenizer.encode(text, return_tensors='pt')
outputs = model.generate(input_ids, num_beams=1, do_sample=True)
在Huggingface中,当 do_sample=False 时,temperature,top_k,top_p 这些参数是不能够被设置的,只有do_sample=True时才能够被设置。
UserWarning: `do_sample` is set to `False`. However, `temperature` is set to `0.5` -- this flag is only used in sample-based generation modes. You should set `do_sample=True` or unset `temperature`.
UserWarning: `do_sample` is set to `False`. However, `top_p` is set to `0.1` -- this flag is only used in sample-based generation modes. You should set `do_sample=True` or unset `top_p`.
UserWarning: `do_sample` is set to `False`. However, `top_k` is set to `20` -- this flag is only used in sample-based generation modes. You should set `do_sample=True` or unset `top_k`.
具体原理:
参考3.7节内容。
在生成下一个候选词时,选定一个采样范围进行随机采样,在采样范围的词只要概率不为0,就有可能采样到这个词。具体步骤如下:
-
首根据概率分布对应的概率,为每个可能结果分配一个抽样概率。这些抽样概率之和必须为1。
-
会生成一个随机数,然后根据抽样概率选择结果。抽样概率越高的结果,被选中的概率也就越大。
-
最终,被选中的结果就是这次抽样的输出。
多项式采样概率高的结果更有可能被选中,但不同于确定性的选择,每个结果仍然有一定的概率被选中。
进行多次文本生成得到不同的随机的结果(出现了采用之前策略没有生成过的句子):
优缺点:
-
在生成文本时具有一定的随机性,但又受到概率的控制,以便生成更加多样且符合概率分布的文本。
-
产生丰富、有趣、创新的文本,但可能会牺牲一些文本的准确性。
5.10 束搜索多项式采样策略 (beam search multinomial sampling)
核心思想:
束搜索多项式采样策略 (beam search multinomial sampling) 结合了束搜索解码策略(beam search)和多项式采样策略 (Multinomial sampling)两种策略。
调用model.generate()时,超参数 num_beams 大于 1 且 do_sample 等于 True 时采用此策略。
input_ids = tokenizer.encode(text, return_tensors='pt')
outputs = model.generate(input_ids, num_beams=5, do_sample=True)
具体原理:
此策略的实现方式就是在束搜索每一步,不在每一个束搜索中按照概率最大化选词,而是按照概率分布采样选词。
优缺点:
-
在生成文本时具有一定的随机性,但又受到概率的控制,以便生成更加多样且符合概率分布的文本。
-
产生丰富、有趣、创新的文本,但可能会牺牲一些文本的准确性。
5.11 辅助解码策略 (assisted decoding)
核心思想:
辅助解码策略 (assisted decoding) 是使用另一个模型(称为辅助模型)的输出来辅助生成文本,一般是借助较小的模型来加速生成候选 token,辅助模型必须具有与目标模型完全相同的分词器(tokenizer)
调用model.generate()时,参数 assistant_model 为辅助模型加载地址时采用此策略。
优缺点:
-
加速生成token。
6.总结
到目前为止的策略,可以分为两类:
-
确定性策略,如贪心解码策略 (greedy decoding)/束搜索解码策略 (beam search),这种策略在生成的文本上具有较好的语义连贯性,但是不具备多样性的生成能力,同时存在重复生成的风险。
-
随机采样策略,如温度采样策略 (temperature sampling)/top-k采样策略 (top-k sampling)/top-p采样策略 (top-p sampling)/对比搜索解码策略 (contrastive search)/多项式采样策略 (Multinomial sampling)/束搜索多项式采样策略 (beam search multinomial sampling),这种策略可以生成多样性的文本,但是在语义连贯性上无法保证。
reference
https://github.com/Glanvery/LLM-Travel
https://huggingface.co/docs/transformers/main/en/main_classes/text_generation#transformers.GenerationConfig
https://github.com/yxuansu/SimCTG
https://codingling.gitbook.io/study/basic-know/language-model/yu-yan-mo-xing-jie-ma-cai-yang-ce-lve
https://blog.csdn.net/weixin_44179676/article/details/109407547
https://arxiv.org/abs/1905.09751
https://github.com/huggingface/transformers/blob/v4.27.1/src/transformers/generation/utils.py
https://arxiv.org/abs/1610.02424
https://mp.weixin.qq.com/s/BuvLXx0ZItOvhno4XAUpTg
原文始发于微信公众号(TahirSec):AI | LLM模型推理生成与采样解码策略(二)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论