文本生成模型解码策略和采样方法对比分析(13种)

本文主要探讨如下两个方面:

1、outputs = model.generate(**inputs, ...)

generate()中各个参数是什么含义?

2、我们的模型在文本生成的时候,最终的结果文本是如何产生的?常见的解码策略有哪些?

常用参数释义

max_new_tokens:要生成的token的最大数量。控制输出序列的大小,不包括提示符中的标记。

num_beams:>1就是束搜索,在每个时间步评估几个假设(hypotheses),并最终选择对于整个序列具有总体最高概率的假设。

do_sample:如果设置为 True ,就会启用诸如多项式采样、波束搜索多项式采样、Top-K采样和Top-p采样的解码策略。所有这些策略从整个词汇表的概率分布中选择下一个Token,并根据选择的策略调整。

num_return_sequences:序列候选数。仅可用于支持多个序列候选的解码策略。(贪婪搜索和对比搜索返回单个输出序列)

其他参数,例如top_k, top_p, penalty_alpha, temperature 等详见下文,后续更新详见:【小程序】

解码策略有哪些呢?

Greedy Search

贪婪搜索是从词汇表Vocab中取出具有最高条件概率的值。解码速度相对较快,但可能会错过全局概率最大的序列、缺少随机性,模型可能重复输出、容易复述训练数据,缺少了创造性。

generate() 默认使用贪婪搜索解码,参数 num_beams 为1并且 do_sample=False 。

greedy_outputs = model.generate(**inputs)

Beam Search

与贪婪搜索不同,波束搜索解码在每个时间步长保留若干Tokens,每次从若干候选Tokens中选取对于能使序列整体概率最大的Token,只需要在generate()参数中设置 num_beams>1 启用,early_stopping=True 使得当达到EOS Token时完成生成。

beam_outputs_ori = model.generate(**inputs, num_beams=5, early_stopping=True)

输出可能包括相同单词序列的重复。

beam_outputs_no_repeat = model.generate(**inputs, num_beams=5, no_repeat_ngram_size=2,early_stopping=True)

n-gram惩罚必须小心使用,可能生成的某个词,就需要多次出现,一旦设置就被限定了。

另外,我们可以选择最适合我们目标的Beams,比如num_beams取5个但返回3个,添加num_return_sequences参数:

beam_outputs_no_repeat_seq = model.generate(**inputs, num_beams=5, no_repeat_ngram_size=2,num_return_sequences=5, early_stopping=True)

Sampling

使用采样的语言生成不再是确定性的,设置 do_sample=True 并通过 top_k=0 停用Top-K采样。

sample_output = model.generate(**inputs, do_sample=True, max_length=50, top_k=0)

模型经常产生胡言乱语而且不连贯,可以通过设置 temperature 参数调整softmax输出的概率,增加高概率单词的可能性并降低低概率单词的可能性,使分布不那么随机。

sample_output_temperature = model.generate(**inputs, do_sample=True, max_length=50, top_k=0, temperature=0.7)

Top-K采样

sample_output_top_k = model.generate(**inputs, do_sample=True, max_length=50, top_k=10)

选出 Top K 个最可能的Token,在这K个样本上计算分布概率值。但一些单词可能是从非常尖锐的分布中采样的,有的单词却是从更平坦的分布中采样的。

Top-p(核)抽样

采样是从累积概率超过概率p的最小可能单词集合中进行选择,单词集合的大小(采样个数)可以根据下一个单词的概率分布动态地增加和减少。0 < top_p < 1 取值范围。

sample_output_top_p = model.generate(**inputs, do_sample=True, max_length=50, top_p=0.95, top_k=0)

Top-p也可以与Top-K结合使用,这可以避免排名非常低的单词,同时允许一些动态选择。为了获得多个独立采样的输出,我们可以设置参数 num_return_sequences > 1

sample_output_top_kp = model.generate(**inputs, do_sample=True, max_length=50, top_p=0.95, top_k=50, num_return_sequences=3)

对比搜索解码策略

对比搜索解码策略用于产生非重复但连贯的输出,启用和控制对比搜索的两个主要参数是 penalty_alpha 和 top_k :

Contrastive_outputs = model.generate(**inputs, penalty_alpha=0.6, top_k=4, max_new_tokens=50)

Multinomial sampling 多项抽样

多项式采样基于模型给出的整个词表上的概率分布随机选择下一个Token。启用多项式采样集 do_sample=True 和 num_beams=1 。

multinomial_sample_outputs = model.generate(**inputs, do_sample=True, num_beams=1, max_new_tokens=50)

Beam-search multinomial sampling

这种解码策略将波束搜索与多项式采样相结合,指定 num_beams 大于1,并设置 do_sample=True :

Beam_multinomial_outputs = model.generate(**inputs, num_beams=5, do_sample=True)

多样化波束搜索解码

多样化波束搜索解码策略生成更多样化的波束序列集合以供选择。主要参数: num_beams 和 num_beam_groups ,组间不同(要差异),组内使用常规beam search:

Diverse_Beam_outputs = model.generate(**inputs, num_beams=5, num_beam_groups=5, max_new_tokens=50)

结果对比

from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

# Windows和Linux上使用GPU
# device = "cuda" if torch.cuda.is_available() else "cpu"
# Mac 上使用 GPU加速:
device = "mps" if torch.backends.mps.is_built() else "cpu"

checkpoint = "bigscience/bloom-560m"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model = AutoModelForCausalLM.from_pretrained(checkpoint).to(device)

将输入Prompt转换成input_ids,送入到generate()中。

prompt = "神舟十五号载人飞行"
inputs = tokenizer(prompt, return_tensors="pt").to(device)

我们探索不同的参数控制对结果的影响(同一个模型,设置不同参数,输出对比):

greedy_outputs = model.generate(**inputs)

beam_outputs_ori = model.generate(**inputs, num_beams=5, early_stopping=True)

beam_outputs_no_repeat = model.generate(**inputs, num_beams=5, no_repeat_ngram_size=2,early_stopping=True)

beam_outputs_no_repeat_seq = model.generate(**inputs, num_beams=5, no_repeat_ngram_size=2,num_return_sequences=5,early_stopping=True)

sample_output = model.generate(**inputs, do_sample=True, max_length=50, top_k=0)

sample_output_temperature = model.generate(**inputs, do_sample=True, max_length=50, top_k=0, temperature=0.7)

sample_output_top_k = model.generate(**inputs, do_sample=True, max_length=50, top_k=10)

sample_output_top_p = model.generate(**inputs, do_sample=True, max_length=50, top_p=0.92, top_k=0)

sample_output_top_kp = model.generate(**inputs, do_sample=True, max_length=50, top_p=0.95, top_k=50, num_return_sequences=3)

Contrastive_outputs = model.generate(**inputs, penalty_alpha=0.6, top_k=4, max_new_tokens=50)

multinomial_sample_outputs = model.generate(**inputs, do_sample=True, num_beams=1, max_new_tokens=50)

Beam_multinomial_outputs = model.generate(**inputs, num_beams=5, do_sample=True)

Diverse_Beam_outputs = model.generate(**inputs, num_beams=5, num_beam_groups=5, max_new_tokens=50)

对应的结果输出:

***************** greedy *******************************
神舟十五号载人飞行。 航天员在飞行过程中,由于受到外界环境的影响
*****************beam_outputs_ori **********************
神舟十五号载人飞行器,是我国自主研制的第一艘载人航天飞行器
*****************beam_outputs_no_repeat ****************
神舟十五号载人飞行器,是我国自主研制的第四代大型航天器。
*****************beam_outputs no_repeat num_return_sequences ***********
0: 神舟十五号载人飞行器,是我国自主研制的第四代大型航天器。
1: 神舟十五号载人飞行器,是我国自主研制的第四代航天器。该
2: 神舟十五号载人飞行器,是我国自主研制的第四代航天器。它
3: 神舟十五号载人飞行器,是我国自主研制的第四代大型航天飞机。
4: 神舟十五号载人飞行器,是我国自主研制的第四代航天器。 
*****************sample_output激活采样 **************************************************
神舟十五号载人飞行的同时,二舱实验舱目前已抵达九号接收装置,创下了中国同类客舱全球纪录,意味着中国将在不久的将来把常规客舱也陆续送上四号。 这次飞行片段展现上
*****************sample_output_temperature *************************
神舟十五号载人飞行。 特殊装备之一:双马甲 特殊装备之二:双超电磁炮 特殊装备之三:双飞翼直升机 特殊装备之四:双双飞翼直升机 特殊装备之
*****************sample_output_topk ********************
神舟十五号载人飞行,是我国目前唯一的自主制造、自装、自运、自试的高科技飞行器。自研制完成之后,其载人飞行能力达到了世界同类型飞行器最高水平,并实现了从
*****************sample_output_top_p ********************
神舟十五号载人飞行类火星模拟器取得了令人瞩目的成就,实现了短时间内把人从舟型上顺利地带离太空中,最后降落到火星表面,让广大科学家为人类制造离地(即行)
*****************sample_output top_k 和 top_p **********
0: 神舟十五号载人飞行任务的最后一课,这艘飞船载人进入一个又一个复杂环境,每一次飞行任务都是一次大难不死的小升华。
从最初的尝试到这次的失败,我甚至不敢相信。“啊
1: 神舟十五号载人飞行。 同年,美国斯坦福大学组织了一个由21名专家组成的太空飞人小组,在环球寻找生命。 1952年2月10日,美国航天局发射了火星探索器,第一次飞人太空
2: 神舟十五号载人飞行和火星探测等任务)。航天工业自主研制的“海基”探月工程飞船是首批由中国航天工业有限责任公司自主研制的高质量“海基”探月工程飞船,具有较高的飞行性能
*****************Contrastive search 对比搜索 *************
神舟十五号载人飞行。 航天员王亚伟在飞行中。 航天员王亚伟在飞行中。 航天员王亚伟在飞行中。 航天员王亚伟在飞行中。 航天员王亚伟在飞行中
*****************Multinomial sampling 多项抽样 ************
神舟十五号载人飞行实验车。

我司拥有一批经验丰富、精湛的工程技术人员团队,能够根据客户不同的客户需求,根据施工现场的特殊状况,结合客户现场环境状况的细微差别,为客户量身定做,提供更加
*****************Beam-search multinomial sampling **********
神舟十五号载人飞行器。该飞行器是由中国航天科技集团公司自主研制
***************** Diverse beam search **********************
神舟十五号载人飞行。 航天员在飞行过程中,由于受到外界环境的影响,身体出现了一些不适,但航天员仍坚持飞行,并最终成功完成了任务。 航天员在飞行过程中,由于受到外界环境的影响,身体出现了一些不适,

本文对比分析了model.generate()中不同参数对结果产出的影响,分析了常见13种解码和采样策略的特点和使用情况。

参考文档:

https://huggingface.co/docs/transformers/v4.29.1/en/generation_strategies

https://github.com/yxuansu/SimCTG

https://colab.research.google.com/github/huggingface/blog/blob/main/notebooks/115_introducing_contrastive_search.ipynb#scrollTo=8a749495

https://github.com/yxuansu/Contrastive_Search_Is_What_You_Need

https://huggingface.co/blog/introducing-csearch#41-deteriminstic-methods

https://huggingface.co/blog/how-to-generate

https://github.com/jsksxs360/How-to-use-Transformers/tree/main/src

原创文章。转载请注明: 作者:JiangYuan 网址: https://www.icnma.com
Like (0)
JiangYuan管理
Previous 11/10/2024 21:21
Next 07/03/2023 21:52

猜你想看