文本生成解码策略 Beam Search, top_k, temperature

news2024/12/27 13:30:54

一、从Greedy Search到Beam Search

Greedy search是指在每个t时刻选择下一个词时,根据 wt=argmaxwP(w|w1:t−1)选择概率最高的词。

图片

以上图为例:

从单词“The”开始,算法在选择下一个词时,贪心的选择了概率最高的“nice”,进而,最终的生成词序列为(“The”,“nice”,“woman”),总概率为0.5×0.4=0.2

文章《https://blog.csdn.net/jarodyv/article/details/128994176》中列举了一个有趣的例子:

假设训练了一个描述个人生活喜好的模型,想让它来补全“我喜欢漂亮的___”这个句子。一般语言模型会按照下图的流程来工作:

图片

模型会查看所有可能的单词,并根据其概率分布从中采样,以预测下一个词。

假设模型的词汇量不大,只有:“大象”、“西瓜”、“鞋子”和“女孩”。通过下图的词汇概率可以发现,“女孩”的选中概率最高(p=0.664),“西瓜”的选中概率最低(p=0.032)。

图片

上面的例子中,很明显“女孩”最可能被选中,这就是 “贪心策略”,永远选择分数或概率最大的token,

图片

Greedy Search存在的一个最大的问题在于,只考虑了当前的高概率词,忽略了在当前低概率词后面的高概率词,还是这个例子,词“has”在词“dog”后面,条件概率高达0.9,但词“dog”的条件概率只排第二,所以greedy search错过了词序列“The”、“dog”、“has”。

具体实现:

import tensorflow as tf
from transformers import TFGPT2LMHeadModel, GPT2Tokenizer
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
# add the EOS token as PAD token to avoid warnings
model = TFGPT2LMHeadModel.from_pretrained("gpt2", pad_token_id=tokenizer.eos_token_id)
# encode context the generation is conditioned on
input_ids = tokenizer.encode('I enjoy walking with my cute dog', return_tensors='tf')
# generate text until the output length (which includes the context length) reaches 50
greedy_output = model.generate(input_ids, max_length=50)
print(tokenizer.decode(greedy_output[0], skip_special_tokens=True))

因此,为了避免错过隐藏的高概率词,Beam Search通过参数num_beams的配置,可以在每个时刻,记录概率最高的前num_beams个路径,在下一个时刻可以有多个基础路径同时搜索。

以num_beams=2为例,我们看下原理图:

图片

可以看到:

在t=1时,最大概率的路径是(“The”、“nice”),beam search同时也会记录概率排第二的路径(“The”、“dog”)。

在t=2时,beam search也会发现路径(“The”、“dog”、“has”)有0.36的概率超过了路径(“The”、“nice”、“women”)的概率0.2。

因此,两条路径中,找到了概率最高的路径,得到了更为合理的答案。

beam search生成的词序列比greedy search生成的词序列的综合概率更高,但是也不能保证是概率最高的词序列。

具体实现:

import tensorflow as tf
from transformers import TFGPT2LMHeadModel, GPT2Tokenizer
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
# add the EOS token as PAD token to avoid warnings
model = TFGPT2LMHeadModel.from_pretrained("gpt2", pad_token_id=tokenizer.eos_token_id)
# encode context the generation is conditioned on
input_ids = tokenizer.encode('I enjoy walking with my cute dog', return_tensors='tf')
# activate beam search and early_stopping
beam_output = model.generate(
    input_ids, 
    max_length=50, 
    num_beams=5, 
    early_stopping=True
)
print(tokenizer.decode(beam_output[0], skip_special_tokens=True))

不过,在开放领域生成任务的很多时候,beam search都不是最好的解码方式:

首先,beam search在做像是翻译和摘要这类可以大致预测生成长度的场景中表现还可以Murray et al. (2018)、Yang et al. (2018)。但是在像是对话和故事生成这类开放生成领域效果就差得多了。

其次,我们已经看到beam search经常会生成重复内容,在故事生成中,我们很难决定要不要n-gram惩罚,因为我们很难确定强制不要重复还是有重复会更好。

最后,就是文首所提到的,高水平的人类语言不会按照下一个词条件概率最高的方式排列,所以就需要在此基础上优化采样方式。

图片

二、从Beamsearch到Top-k固定采样

Beam Search每次会选择在Beam中最大概率的词汇,Top-k采样是对前面“贪心策略”的优化,它从排名前k的token种进行抽样,允许其他分数或概率较高的token也有机会被选中,以达到有一定机率不选最大概率的词,其核心思想在于:在解码的每个时间步从前k个概率最大的词中按它们的概率进行采样。

所以,我们称之为静态采样,如下图所示:

当K=6时,限制候选池是概率最高的前6个词,这6个词的集合被定义为Vtop−K。在第一轮他们占据全部概率的约2/3,而第二轮前6个词几乎占据了所有的概率。所以,我们避免了在第二轮生成奇怪的词,如(“not”、“the”、“small”、“told”、)。

图片

又如下图示例中,我们首先筛选似然值前三的token,然后根据似然值重新计算采样概率,通过调整k的大小,即可控制采样列表的大小。“贪心策略”其实就是k=1的top-k采样:

图片

但Top-k采样有个很大的问题,Top-K sampling不会根据下一个词的概率分布 ,动态调整候选池的大小。当条件概率非常集中的时候,会更倾向于选择top-k中的词,而当条件概率非常分散的时候,就不能选中top-k以外的词,这其实也是我们进行LDA话题聚类,kmeans聚类中经常遇到的问题。有选大了可能会采样出长尾词,导致语句不通顺,选小了又退化成了Beam Search:

图片

下面是具体实现:

import tensorflow as tf
from transformers import TFGPT2LMHeadModel, GPT2Tokenizer
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
# add the EOS token as PAD token to avoid warnings
model = TFGPT2LMHeadModel.from_pretrained("gpt2", pad_token_id=tokenizer.eos_token_id)
# encode context the generation is conditioned on
input_ids = tokenizer.encode('I enjoy walking with my cute dog', return_tensors='tf')
# activate beam search and early_stopping
# set seed to reproduce results. Feel free to change the seed though to get different results
tf.random.set_seed(0)
# set top_k to 10
sample_output = model.generate(
    input_ids, 
    do_sample=True, 
    max_length=50, 
    top_k=10
)
print(tokenizer.decode(sample_output[0], skip_special_tokens=True))

三、从Top-k固定采样到Top-p(Nucleus Sampling)动态采样

Top-k有一个缺陷,那就是“k值取多少是最优的”非常难确定。于是出现了动态设置token候选列表大小策略——即核采样(Nucleus Sampling)。

Nucleus Sampling,也称Top-p,在每个时间步,解码词的概率分布满足80/20原则或者说长尾分布,头部的几个词的出现概率已经占据了绝大部分概率空间,把这部分核心词叫做nucleus。

基于这样的观察,提出nucleus sampling,即给定一个概率阈值p,从解码词候选集中选择一个最小集Vp,使得它们出现的概率和大于等于p。然后再对Vp做一次re-scaling,本时间步仅从Vp集合中解码。

具体的,与限定在前K个词的采样不同的是,Top-p sampling会根据累计概率超过概率p时,从候选集选择个数最少的子集。通过这种方式,子集的大小可以动态的根据概率分布调整。

图片

这样的好处在于在不同时间步,随着解码词的概率分布不同,候选词集合的大小会动态变化,不像top-k sampling是一个固定的窗口大小。由于解码词还是从头部候选集中筛选,这样的动态调整可以使生成的句子在满足多样性的同时又保持通顺。

如下图所示,当p=0.92时,top-p sampling选择了累计概率超过92%的最少个数的子集,记为Vtop−p。在t=1中,子集包含了9个最可能的词,在t-2时,子集为前3个词,累计概率就超过92%。

图片

这也就说明,在条件概率分布分散,下一个词不易预测时,候选子集范围更大;在条件概率分布集中,下一个词容易预测时,候选子集范围更小。

下图更形象的展示了top-p值为0.9的Top-p采样效果:

图片

在top-p中,根据达到某个阈值的可能性得分之和动态选择候选名单的大小,top-p值通常设置为比较高的值,目的是限制低概率token的长尾。我们可以同时使用top-k和top-p。如果k和p同时启用,则p在k之后起作用。

下面是具体实现:

import tensorflow as tf
from transformers import TFGPT2LMHeadModel, GPT2Tokenizer
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
# add the EOS token as PAD token to avoid warnings
model = TFGPT2LMHeadModel.from_pretrained("gpt2", pad_token_id=tokenizer.eos_token_id)
# encode context the generation is conditioned on
input_ids = tokenizer.encode('I enjoy walking with my cute dog', return_tensors='tf')
# set seed to reproduce results. Feel free to change the seed though to get different results
tf.random.set_seed(0)
# deactivate top_k sampling and sample only from 92% most likely words
sample_output = model.generate(
    input_ids, 
    do_sample=True, 
    max_length=50, 
    top_p=0.92, 
    top_k=3
)
print(tokenizer.decode(sample_output[0], skip_special_tokens=True))

四、从动态采样到概率侧重缩放:tmperatue温度采样

上面所说的topk, top_p都是在动态选择不同词的范围,但并没有更改实际词出现的概率,那么,是否可以在出现上概率上也进行调节呢?例如,将高频和低频之间的概率拉大或者减少,也能够对多样性提供一些思路。

因此,tmperatue温度采样方式被踢出,

在概率模型中,logits扮演着能量的角色,可以通过将logits除以温度来实现温度采样,然后将其输入Softmax并获得采样概率,就是直接re-scale原有的解码词分布:

越低的温度(<1)使模型会对高频的选择更为偏向,而高于1的温度,则会缩小高频词和低频词之间的差距。

温度采样中的温度与玻尔兹曼分布有关,其公式如下所示:

图片

很相似,本质上就是在Softmax函数上添加了温度(T)这个参数。Logits根据我们的温度值进行缩放,然后传递到Softmax函数以计算新的概率分布。

其中t是一个超参数,取值范围[0,1),t的取值不同,解码词的概率分布也就更平缓或更两极分化。一定程度上也能通过设置不同的t达到与top-k sampling一样的效果。

下面是huggingface上的具体实现:

class TemperatureLogitsWarper(LogitsWarper):
    r"""
    :class:`transformers.LogitsWarper` for temperature (exponential scaling output probability distribution).

    Args:
        temperature (:obj:`float`):
            The value used to module the logits distribution.
    """

    def __init__(self, temperature: float):
        if not isinstance(temperature, float) or not (temperature > 0):
            raise ValueError(f"`temperature` has to be a strictly positive float, but is {temperature}")

        self.temperature = temperature

[DOCS]    def __call__(self, input_ids: torch.Tensor, scores: torch.Tensor) -> torch.Tensor:
        scores = scores / self.temperature
        return scores

同样的,我们以文章《https://blog.csdn.net/jarodyv/article/details/128994176》中举出的形象例子来理解下,

在“我喜欢漂亮的___”这个例子中,初始温度T=1,可以观察在出T取不同值的情况下,概率发生的变化:

图片

通过上图我们可以清晰地看到,随着温度的降低,模型愈来愈越倾向选择”女孩“;另一方面,随着温度的升高,分布变得越来越均匀。当T=50时,选择”西瓜“的概率已经与选择”女孩“的概率相差无几了。

图片

下面是使用huggingface的具体例子

import tensorflow as tf
from transformers import TFGPT2LMHeadModel, GPT2Tokenizer
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
# add the EOS token as PAD token to avoid warnings
model = TFGPT2LMHeadModel.from_pretrained("gpt2", pad_token_id=tokenizer.eos_token_id)
# encode context the generation is conditioned on
input_ids = tokenizer.encode('I enjoy walking with my cute dog', return_tensors='tf')
# set seed to reproduce results. Feel free to change the seed though to get different results
tf.random.set_seed(0)
# deactivate top_k sampling and sample only from 92% most likely words
sample_output = model.generate(
    input_ids, 
    do_sample=True, 
    max_length=50, 
    top_p=0.92, 
    top_k=3,
    temperature=1.5,
)
print(tokenizer.decode(sample_output[0], skip_special_tokens=True))

针对重复生成问题的ngrams重复惩罚机制

生成成模型在实际的运行过程中,总会出现一些重复的例子,这是高频词选择的结果。为了解决重复问题,一个简单的方法是用n-grams惩罚,来自论文Paulus et al. (2017)和Klein et al. (2017)。

其基本思想在于:通常的n-grams惩罚通过配置下一个词重复出现n-gram的概率为0,来保证没有n-gram出现两次,实现原理如下所示:

def calc_banned_ngram_tokens(prev_input_ids: Tensor, num_hypos: int, no_repeat_ngram_size: int, cur_len: int) -> None:
    """Copied from fairseq for no_repeat_ngram in beam_search"""
    if cur_len + 1 < no_repeat_ngram_size:
        # return no banned tokens if we haven't generated no_repeat_ngram_size tokens yet
        return [[] for _ in range(num_hypos)]
    generated_ngrams = [{} for _ in range(num_hypos)]
    for idx in range(num_hypos):
        gen_tokens = prev_input_ids[idx].tolist()
        generated_ngram = generated_ngrams[idx]
        for ngram in zip(*[gen_tokens[i:] for i in range(no_repeat_ngram_size)]):
            prev_ngram_tuple = tuple(ngram[:-1])
            generated_ngram[prev_ngram_tuple] = generated_ngram.get(prev_ngram_tuple, []) + [ngram[-1]]

    def _get_generated_ngrams(hypo_idx):
        # Before decoding the next token, prevent decoding of ngrams that have already appeared
        start_idx = cur_len + 1 - no_repeat_ngram_size
        ngram_idx = tuple(prev_input_ids[hypo_idx, start_idx:cur_len].tolist())
        return generated_ngrams[hypo_idx].get(ngram_idx, [])

    banned_tokens = [_get_generated_ngrams(hypo_idx) for hypo_idx in range(num_hypos)]
    return banned_tokens

例如, 配置 no_repeat_ngram_size = 2时,可以使用huggingface加以实现:

import tensorflow as tf
from transformers import TFGPT2LMHeadModel, GPT2Tokenizer
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
# add the EOS token as PAD token to avoid warnings
model = TFGPT2LMHeadModel.from_pretrained("gpt2", pad_token_id=tokenizer.eos_token_id)
# encode context the generation is conditioned on
input_ids = tokenizer.encode('I enjoy walking with my cute dog', return_tensors='tf')
# activate beam search and early_stopping
beam_output = model.generate(
    input_ids, 
    max_length=50, 
    num_beams=5, 
    no_repeat_ngram_size=2, 
    early_stopping=True
)
print(tokenizer.decode(beam_output[0], skip_special_tokens=True))

六、针对重复生成问题的RepetitionPenalty重复惩罚

除了grams重复惩罚志气,还可以通过惩罚因子将出现过词的概率变小或者强制不使用重复词来解决。

其核心思想在于:对于之前出现过的词语,在后续预测的过程中,通过引入惩罚因子降低其出现的概率。

惩罚因子来自于同样广为流传的《CTRL: A Conditional Transformer Language Model for Controllable Generation》。

scores为cur-step的词表分布[batch,seq,vocab_size],指的是候选词汇集中每个词汇的概率值,input_ids为输入decoder的文本序列[batch,seq],则score则是获取当前已经生成文本序列的token概率,减少已经出现的token的概率, 将减少后的概率重分配到原始的cur-step词表分布中。

class RepetitionPenaltyLogitsProcessor(LogitsProcessor):
    r"""
    :class:`transformers.LogitsProcessor` enforcing an exponential penalty on repeated sequences.

    Args:
        repetition_penalty (:obj:`float`):
            The parameter for repetition penalty. 1.0 means no penalty. See `this paper
            <https://arxiv.org/pdf/1909.05858.pdf>`__ for more details.
    """

    def __init__(self, penalty: float):
        if not isinstance(penalty, float) or not (penalty > 0):
            raise ValueError(f"`penalty` has to be a strictly positive float, but is {penalty}")

        self.penalty = penalty

[DOCS]    def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> torch.FloatTensor:
        score = torch.gather(scores, 1, input_ids)

        # if score < 0 then repetition penalty has to be multiplied to reduce the previous token probability
        score = torch.where(score < 0, score * self.penalty, score / self.penalty)

        scores.scatter_(1, input_ids, score)
        return scores

其中,torch.gather(input,dim,index),input表示输入张量的值,dim表示输入张量的维度,index表示在维度上的具体索引。

torch.where()函数的作用是按照一定的规则合并两个tensor类型,例如,torch.where(a>0, a, b)表示满足条件返回a,否则返回b。

标准化的说,torch.where()函数的作用是按照一定的规则合并两个tensor类型。torch.where(condition,a,b)其中 输入参数condition:条件限制,如果满足条件,则选择a,否则选择b作为输出。注意:a和b是tensor.

>>> import torch
>>> a=torch.randn(3,5)
>>> a
tensor([[ 0.8416,  1.6152, -0.8635, -0.2283, -0.0522],
        [-1.1139,  0.4552,  1.5567,  0.8376,  0.1232],
        [-0.7011,  0.7474, -2.5362,  0.0333, -0.0081]])
>>> b=torch.ones(3, 5)
>>> b
tensor([[1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.]])
>>> torch.where(a>0, a, b)
tensor([[0.8416, 1.6152, 1.0000, 1.0000, 1.0000],
        [1.0000, 0.4552, 1.5567, 0.8376, 0.1232],
        [1.0000, 0.7474, 1.0000, 0.0333, 1.0000]])

下面的score计算公式表述,如果score<0,那么score变成score * self.penalty,如果大与0,则变成score / self.penalty,目的是让其得分更小。

score = torch.where(score < 0, score * self.penalty, score / self.penalty)

同样的,我们可以使用huggingface对其进行实现:

import tensorflow as tf
from transformers import TFGPT2LMHeadModel, GPT2Tokenizer
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
# add the EOS token as PAD token to avoid warnings
model = TFGPT2LMHeadModel.from_pretrained("gpt2", pad_token_id=tokenizer.eos_token_id)
# encode context the generation is conditioned on
input_ids = tokenizer.encode('I enjoy walking with my cute dog', return_tensors='tf')
# activate beam search and early_stopping
beam_output = model.generate(
    input_ids, 
    max_length=50, 
    num_beams=5, 
    no_repeat_ngram_size=2, 
    repetition_penalty=2,
    early_stopping=True
)
print(tokenizer.decode(beam_output[0], skip_special_tokens=True))

七、看针对多样性生成中huggingface中还有那些实现策略

当然,为了保证多样性生成,还有很多其他参数控制策略,包括长度、badwords等,下面总结了其中的22个参数及其释义,其中加粗的可以重点看看。

1、temperature (float, optional, defaults to 1.0): 用于调节下一个标记概率的值。

2、top_k (int, optional, defaults to 50): 用于top-k过滤的最高概率词汇标记的数量。

3、top_p (float, optional, defaults to 1.0) : 如果设置为float < 1,则只保留概率加起来达到top_p或更高的最小的最有可能的词汇集合进行生成。

4、typical_p (float, optional, defaults to 1.0): 局部典型性衡量在已经生成的部分文本的情况下,预测下一个目标标记的条件概率与预测下一个随机标记的预期条件概率的相似程度。如果设置为float < 1,则保留最小的、概率相加为typical_p或更高的局部典型标记的集合,用于生成。

5、epsilon_cutoff (float, optional, defaults to 0.0):如果设置为严格介于0和1之间的float,只有条件概率大于epsilon_cutoff的标记会被采样。在论文中,建议的值在3e-4到9e-4之间,取决于模型的大小。

6、eta_cutoff (float, optional, defaults to 0.0): Eta采样是局部典型采样和ε采样的混合体。如果设置为严格介于0和1之间的浮点数,只有当一个标记大于eta_cutoff或sqrt(eta_cutoff) * exp(-entropy(softmax(next_token_logits)))时,才会考虑它。后者是预期的下一个令牌概率,以sqrt(eta_cutoff)为尺度。在论文中,建议值从3e-4到2e-3不等,取决于模型的大小。更多细节见截断抽样作为语言模型去平滑。

7、diversity_penalty (float, optional, defaults to 0.0): 如果一个beam路径得分在某一特定时间产生了与其他组的任何beam路径相同的标记,这个值将从beam的分数中减去。请注意,多样性惩罚只有在分组beam搜索被启用时才有效。

8、repetition_penalty (float, optional, defaults to 1.0) :重复性惩罚的参数。1.0意味着没有惩罚。

9、encoder_repetition_penalty (float, optional, defaults to 1.0):对不在原始输入中的序列进行指数式惩罚。1.0意味着没有惩罚。

10、length_penalty (float, optional, defaults to 1.0):对长度的指数惩罚,用于beam search。它作为指数被应用于序列的长度,反过来又被用来划分序列的分数。由于分数是序列的对数可能性(即负数),length_penalty > 0.0会促进更长的序列,而length_penalty < 0.0会鼓励更短的序列。

11、no_repeat_ngram_size (int, optional, defaults to 0):如果设置为int > 0,所有该大小的ngrams只能出现一次。

12、bad_words_ids(List[List[int]], optional): 不允许生成的token id的列表。为了获得不应该出现在生成的文本中的词的标记ID,使用tokenizer(bad_words, add_prefix_space=True, add_special_tokens=False).input_ids,这个能用于敏感词过滤。

13、force_words_ids(List[List[int]] or List[List[List[int]]], optional):必须生成的标记ID的列表。如果给定的是List[List[int]],这将被视为一个必须包含的简单单词列表,与bad_words_ids相反。如果给定的是List[List[List[int]]],这将触发一个disjunctive约束,即可以允许每个词的不同形式。

14、renormalize_logits (bool, optional, defaults to False) :在应用所有的logits处理器或warpers(包括自定义的)之后,是否要重新规范化logits。强烈建议将此标志设置为 "True",因为搜索算法假定分数对数是正常化的,但一些对数处理器或翘曲器会破坏正常化。

15、constraints (List[Constraint], optional): 可以添加到生成中的自定义约束,以确保输出将包含使用Constraint对象所定义的某些令牌,并尽可能以最合理的方式进行。

16、forced_bos_token_id (int, optional, defaults to model.config.forced_bos_token_id):强制作为解码器_start_token_id之后第一个生成的令牌的id。对于像mBART这样的多语言模型非常有用,在这种情况下,第一个生成的标记需要是目标语言的标记。

17、forced_eos_token_id (Union[int, List[int]], optional, defaults to model.config.forced_eos_token_id) :当达到max_length时,强制作为最后生成的令牌的id。可以选择使用一个列表来设置多个序列结束的标记。

18、remove_invalid_values (bool, optional, defaults to model.config.remove_invalid_values) - 是否删除模型的可能nan和inf输出,以防止生成方法崩溃。注意,使用remove_invalid_values会减慢生成速度。

19、exponential_decay_length_penalty (tuple(int, float), optional): 这个Tuple在生成一定数量的标记后,增加一个指数级增长的长度惩罚。该元组应包括: (start_index, decay_factor),其中start_index表示惩罚开始的位置,decay_factor表示指数衰减的系数。

20、suppress_tokens (List[int], optional) :一个在生成时将被抑制的标记的列表。SupressTokens的logit处理器将把它们的log probs设置为-inf,这样它们就不会被采样了。

21、begin_suppress_tokens (List[int], optional): 一个将在生成之初被抑制的标记的列表。SupressBeginTokens日志处理器将把它们的日志probs设置为-inf,这样它们就不会被采样了。

22、forced_decoder_ids (List[List[int]], optional) :一对整数的列表,表示从生成索引到标记索引的映射,在采样前将被强制。例如,[[1, 123]]意味着第二个生成的标记将总是一个索引为123的标记。

总结

本文主要从原理、源码实现等几个方面,依次介绍从Greedy Search到Beam Search、从Beamsearch到Top-k固定采样、从Top-k固定采样到Top-p(Nucleus Sampling)动态采样、从动态采样到概率侧重缩放:tmperatue温度采样、针对重复生成问题的ngrams重复惩罚机制、针对重复生成问题的RepetitionPenalty重复惩罚、看针对多样性生成中huggingface中还有那些实现策略等7个方向的内容。

从中我们可以看到,其本质上都是在干预预训练模型在解码过程中下一次词的预测概率选择问题,从选择范围、缩放概率、重复惩罚、根据实际场景选择特定的词语等多个方面入手。不过,在实际的过程中,具体还需要我们进行实践,增强的理解。

参考文献

1、https://finisky.github.io/nucleussampling/
1、https://blog.csdn.net/jarodyv/article/details/128994176
3、https://zhuanlan.zhihu.com/p/430961578?utm_id=0
4、https://huggingface.co/blog/how-to-generate

原文:如何让大模型生成解码阶段的结果更好:从Beam Search到top_k、top_p等参数的实现原理与脚本实现

其他文章:

文本摘要(六):生成任务中的采样方法 - 知乎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/899937.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023-8-15 差分

题目链接&#xff1a;差分 #include <iostream>using namespace std;const int N 100010;int n, m; int a[N], b[N];void insert(int l, int r, int c) {b[l] c;b[r 1] - c; }int main() {scanf("%d%d", &n, &m);for(int i 1; i < n; i)scanf…

“鸿蒙”商标被抢先注册,华为上诉失败,鸿蒙系统将被迫改名?

作为我国最著名的手机通讯企业之一&#xff0c;华为凭借着无与伦比的创新设计与可靠实用的用户体验&#xff0c;一度成为了国内最受欢迎的手机品牌。此外&#xff0c;华为手机在海外市场的销量也不遑多让&#xff0c;不仅质量优异&#xff0c;在通讯的稳定性与可靠性上&#xf…

韦东山老师 RTOS 入门课程(一)RTOS 介绍,熟悉裸机的汇编逻辑

韦东山老师 RTOS 入门课程 课程链接&#xff1a;韦东山直播公开课&#xff1a;RTOS实战项目之实现多任务系统 第1节&#xff1a;裸机程序框架和缺陷_哔哩哔哩_bilibili RTOS 介绍 裸机&#xff1a;固定顺序执行。 中断&#xff1a;可以一直专心做循环里的事情&#xff0c;直…

林【2017】

一、判断 二、单选 三、填空 四、应用 五、算法设计

C++笔记之左值与右值、右值引用

C笔记之左值与右值、右值引用 code review! 文章目录 C笔记之左值与右值、右值引用1.左值与右值2.右值引用——关于int&& r 10;3.右值引用——对比int&& r 10;和int& r 10;4.右值引用&#xff08;rvalue reference&#xff09;的概念 1.左值与右值 2.…

Jmeter 分布式性能测试避坑指南

在做后端服务器性能测试中&#xff0c;我们会经常听到分布式。那你&#xff0c;是否了解分布式呢&#xff1f;今天&#xff0c;我们就来给大家讲讲&#xff0c;在企业实战中&#xff0c;如何使用分布式进行性能测试&#xff0c;实战过程中&#xff0c;又有哪些地方要特别注意&a…

stm32单片机开关输入控制蜂鸣器参考代码(附PROTEUS电路图)

说明&#xff1a;这个buzzer的额定电压需要改为3V&#xff0c;否则不会叫&#xff0c;源代码几乎是完全一样的 //gpio.c文件 /* USER CODE BEGIN Header */ /********************************************************************************* file gpio.c* brief Thi…

【Azure API 管理】APIM如何实现对部分固定IP进行访问次数限制呢?如60秒10次请求

问题描述 使用Azure API Management, 想对一些固定的IP地址进行访问次数的限制&#xff0c;如被限制的IP地址一分钟可以访问10次&#xff0c;而不被限制的IP地址则可以无限访问&#xff1f; ChatGPT 解答 最近ChatGPT爆火&#xff0c;所以也把这个问题让ChatGPT来解答&#x…

Python可视化在量化交易中的应用(14)_Seaborn散点图

Seaborn中带回归线的散点图的绘制方法 seaborn中绘制散点图使用的是sns.scatterplot()函数&#xff1a; sns.scatterplot(x,y,hue,style,size,data,palette,hue_order,hue_norm,sizes,size_order,size_norm,markers,style_order,x_bins,y_bins,units,estimator,ci95,n_boot100…

wazuh部署

文章目录 1.ova文件获取2.VMware导入ova文件3.wazuh目录文件4.wazuh解析原理 1.ova文件获取 访问官网 https://wazuh.com/依次点击红色标注将文件下载到本地 2.VMware导入ova文件 直接打开下载到本地的ova文件 设置导入的位置和名称 初始密码账户为wazuh-user:wazuh …

手写模拟SpringBoot核心流程(一):实现极简一个SpringBoot——模拟SpringBoot启动过程

前言 Spring Boot 是一个开源的框架&#xff0c;用于简化 Spring 应用程序的开发和部署。它建立在 Spring Framework 的基础上&#xff0c;内置了web服务器——tomcat和jetty&#xff0c;使得 Spring 应用的构建变得更加快速、简单和可维护。 本文通过实现一个SpringBoot&…

Global Illumination_Exponential Variance Shadow Maps(EVSM)

最近工程中需要集成高质量阴影&#xff08;效率、效果&#xff09;&#xff0c;介于项目非循环渲染所以CSM无法使用&#xff0c;但动态建模中还需要快速增删改场景&#xff0c;阴影还必须重新生成&#xff0c;奈何之前简单SMPCF无法满足效率、效果要求&#xff0c;于是调研RVT等…

十、Linux的root用户、用户和用户组的问题

目录 1、Linux的root用户 &#xff08;1&#xff09;基础 &#xff08;2&#xff09;如何进入root模式 &#xff08;3&#xff09;如何给普通用户配置root权限&#xff1f; 注意点&#xff1a; 配置方法&#xff1a; 2、用户/用户组问题 &#xff08;1&#xff09;用户/用…

【网络安全必看】如何提升自身 WEB 渗透能力?

前言 web 渗透这个东西学起来如果没有头绪和路线的话&#xff0c;是非常烧脑的。 理清 web 渗透学习思路&#xff0c;把自己的学习方案和需要学习的点全部整理&#xff0c;你会发现突然渗透思路就有点眉目了。 程序员之间流行一个词&#xff0c;叫 35 岁危机&#xff0c;&am…

宁德时代与陕汽签署十年战略合作协议,助力商用车电动化进程

据报道&#xff0c;宁德时代新能源科技股份有限公司与陕西汽车控股集团有限公司已经签署了一项为期十年的战略合作协议。双方的合作旨在推动商用车电池技术的发展&#xff0c;并面向商用车全领域应用。 这次战略合作具有重要意义&#xff0c;为宁德时代和陕汽启动了全面合作的序…

iOS开发 - Swift Codable协议实战:快速、简单、高效地完成JSON和Model转换!

前言 Codable 是 Swift 4.0 引入的一种协议&#xff0c;它是一个组合协议&#xff0c;由 Decodable 和 Encodable 两个协议组成。它的作用是将模型对象转换为 JSON 或者是其它的数据格式&#xff0c;也可以反过来将 JSON 数据转换为模型对象。 Encodable 和 Decodable 分别定…

【数据结构】 单链表面试题讲解

文章目录 引言反转单链表题目描述示例&#xff1a;题解思路代码实现&#xff1a; 移除链表元素题目描述&#xff1a;示例思路解析&#xff1a; 链表的中间结点题目描述&#xff1a;示例&#xff1a;思路解析代码实现如下&#xff1a; 链表中倒数第k个结点题目描述示例思路解析&…

OpenFOAM的fvOptions

采用OpenFoam中的fvOptions /*--------------------------------*- C -*----------------------------------*\ |\\ / F ield | OpenFOAM: The Open Source CFD Toolbox\\ / O peration | Website: https://openfoam.org\\ / A n…

CentOS7.6安装mysql8.0.34

一、查看服务器相关信息 cat /etc/redhat-release cat /proc/version [rootlocalhost ~]# cat /etc/redhat-release CentOS Linux release 7.6.1810 (Core) [rootlocalhost ~]# cat /proc/version Linux version 3.10.0-957.el7.x86_64 (mockbuildkbuilder.bsys.centos.org) …

不用插拔网线鼠标点击自动切换网线和WIFI

因为之前在zf单位工作,政务内网需要插网线,而访问外网又需要连wifi,切换就需要拔掉网线插上网线很麻烦,旁边老哥教我了一手.bat程序自动切换方法, .bat文件代码如下: 以下代码的.bat文件执行后会切换到以太网,同时关闭掉wifi和以太网4 echo off %1 mshta vbscript:CreateObjec…