​5种常用于LLM的令牌遮蔽技术介绍以及Pytorch的实现

本文将介绍大语言模型中使用的不同令牌遮蔽技术,并比较它们的优点,以及使用Pytorch实现以了解它们的底层工作原理。

令牌掩码Token Masking是一种广泛应用于语言模型分类变体和生成模型训练的策略。BERT语言模型首先使用,并被用于许多变体(RoBERTa, ALBERT, DeBERTa…)。

而Text Corruption是一种更大的令牌遮蔽策略。在BART研究论文中,进行了大量实验来训练具有不同策略的编码器-解码器生成模型。

在进入正题之前,我们先介绍大型语言模型(llm)中掩码策略的背景

从监督到自监督

语言模型的初始训练中使用了大量文本,其目标是使模型学会正确地表示语言,并将这种知识隐式地存储在其参数权重中。

大量的文本必须具有用于训练的标签,因为必须在处理模型输入数据并使用参考数据之后计算损失(交叉熵)。但是注释如此大量的数据是不可行的。所以智能将问题从监督学习变为自动生成标签的自监督问题。

在这种情况下,被破坏的文本序列作为模型的训练输入,而所有或部分原始序列作为训练数据的标签。这样通过自动生成的标签,模型学习与每个训练示例关联的标签,就不需要手动的注释数据。

在Text Corruption中(特别是在Token Masking、Token Deletion和Text Infilling中),每个单词可能会按照固定概率(通常约为15-20%)进行遮蔽。这个概率保持较低,以便模型即使在序列被损坏的情况下也能学习每个句子的上下文。

还有一些技术,如Sentence Permutation 或Document Rotation,不会专注于按照一定概率遮蔽单词,我们后面会介绍。

在训练语言模型时,标签会根据是分类模型(仅编码器)还是生成模型(编码器-解码器)而变化。在分类模型中,使用的标签只关注输入中被遮蔽的区域。因此如果一个词在整个句子中被屏蔽,标签只是单个单词。而对于生成模型,由于模型必须能够连续生成文本,输出标签是初始未损坏的序列,关注整个序列本身。

环境配置

我们已经简要介绍了使用Text Corruption训练语言模型的一些背景知识,下面我们开始使用示例代码来介绍不同的Text Corruption技术。

我们将使用Stanza,一个由斯坦福NLP开发的库,其中包含不同的NLP工具,这些工具对我们的预处理非常有用。

 importstanza
 stanza.download('en')
 
 # Text used in our examples
 text="Huntington's disease is a neurodegenerative autosomal disease 
 resultsduetoexpansionofpolymorphicCAGrepeatsinthehuntingtingene. 
 Phosphorylationofthetranslationinitiationfactor4E-BPresultsinthe
 alterationofthetranslationcontrolleadingtounwantedproteinsynthesis
 andneuronalfunction. Consequencesofmutanthuntington (mhtt) gene
 transcriptionarenotwellknown. Variabilityofageofonsetisan
 importantfactorofHuntington's disease separating adult and juvenile types. 
 Thefactorswhicharetakenintoaccountare-geneticmodifiers, maternal
 protectioni.eexcessivepaternaltransmission, superiorageinggenes
 andenvironmentalthreshold. Amajorfocushasbeengiventothemolecular
 pathogenesiswhichincludes-motordisturbance, cognitivedisturbanceand
 neuropsychiatricdisturbance. Thediagnosisparthasalsobeentakencareof. 
 Thisincludesgenetictestingandbothprimaryandsecondarysymptoms. 
 ThepresentreviewalsofocusesonthegeneticsandpathologyofHuntington's 
 disease."
 
 
 # We will use a stanza model for getting each different sentence 
 # as an element of the list
 nlp=stanza.Pipeline('en', use_gpu=False)
 doc=nlp(text)
 sentences= [sentence.textforsentenceindoc.sentences]

Token Masking

令牌掩码用替换文本中的随机单词

这是从BERT引入的策略,它包括通过屏蔽随机单词来破坏输入序列,这些单词将在训练期间用作输出标签。

在分类模型中,我们可以直接使用Huggingface的DataCollatorForLanguageModeling类来生成必要的标签,这样就可以训练像BERT或RoBERTa这样的模型。

 fromtransformersimportAutoTokenizer, DataCollatorForLanguageModeling
 importtorch
 
 defload_dataset_mlm(sentences, tokenizer_class=AutoTokenizer, 
                      collator_class=DataCollatorForLanguageModeling, 
                      mlm=True, mlm_probability=0.20):
     tokenizer=tokenizer_class.from_pretrained('google-bert/bert-base-uncased')
     inputs=tokenizer(sentences, return_tensors='pt', padding=True, 
                        truncation=True)
     
     # Random masking configuration
     data_collator=collator_class(
         tokenizer=tokenizer, 
         mlm=mlm,  
         mlm_probability=mlm_probability
     )
 
     """The collator expects a tuple of tensors, so you have to split 
     the input tensors and then remove the first dimension and pass it 
     to a tuple. """
     tuple_ids=torch.split(inputs['input_ids'], 1, dim=0)
     tuple_ids=list(tuple_ids)
     fortensorinrange(len(tuple_ids)):
         tuple_ids[tensor] =tuple_ids[tensor].squeeze(0)
     tuple_ids=tuple(tuple_ids)
     
     # Get input_ids, attention_masks and labels for each sentence.
     batch=data_collator(tuple_ids)
     returnbatch['input_ids'], inputs['attention_mask'], batch['labels']
 
 
 input_ids, attention_mask, labels=load_dataset_mlm(sentences)
 
 """
 input_ids[0]:
 tensor([  101, 16364,  1005,  1055,   103,  2003,  1037,   103, 10976,  3207,
           103, 25284,   103, 25426, 16870,  4295,  3463,  2349,  2000,   103,
          1997, 26572, 18078,  6187,  2290, 17993,  1999,  1996,  5933,  7629,
           103,   103,   102,     0,     0])
 
 attention_mask[0]:
 tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0])
 
 labels[0]:
 tensor([ -100,  -100,  -100,  -100,  4295,  -100,  -100, 11265,  -100,  -100,
          6914,  -100,  8285,  -100,  2389,  -100,  -100,  -100,  -100,  4935,
          -100,  -100,  -100,  -100,  -100,  -100,  -100,  -100,  -100,  -100,
          4962,  1012,  -100,  -100,  -100]))
 
 """

生成的inputs_ids对原始文本的每个标记都是整数。一个特殊的标记表示被屏蔽的单词(在BERT中,这个标记是103)。这个特殊的标记根据所使用的语言模型而变化,因此不同的标记器将返回注意掩码的不同标识符。

Huggingface还在模型中使用不同的操作分配唯一的令牌,因此用“-100”表示的令牌表示模型应该忽略它们。

对于像BART这样的生成模型,我们可以使用DataCollatorForLanguageModeling类实现令牌屏蔽策略。但是需要一些小的更改,以使标记适应生成模型。

 fromtransformersimportBartTokenizer, DataCollatorForLanguageModeling
 importtorch
 
 defload_dataset_mlm(sentences, tokenizer_class=BartTokenizer, 
                      collator_class=DataCollatorForLanguageModeling, 
                      mlm=True, mlm_probability=0.20):
     tokenizer=tokenizer_class.from_pretrained('facebook/bart-base')
     inputs=tokenizer(sentences, return_tensors='pt', padding=True, 
                        truncation=True)
     
     # Random masking configuration
     data_collator=collator_class(
         tokenizer=tokenizer, 
         mlm=mlm,  # True for Masked Language Modelling
         mlm_probability=mlm_probability  # Chance for every token to get masked
     )
 
     """The collator expects a tuple of tensors, so you have to split 
     the input tensors and then remove the first dimension and pass it 
     to a tuple. """
     tuple_ids=torch.split(inputs['input_ids'], 1, dim=0)
     tuple_ids=list(tuple_ids)
     fortensorinrange(len(tuple_ids)):
         tuple_ids[tensor] =tuple_ids[tensor].squeeze(0)
     tuple_ids=tuple(tuple_ids)
     
     # Get input_ids, attention_masks and labels for each sentence.
     batch=data_collator(tuple_ids)
     batch['labels'] =inputs['input_ids']
     returnbatch['input_ids'], inputs['attention_mask'],  batch['labels']
 
 input_ids, attention_mask, labels=load_dataset_mlm(sentences)
 
 """
 input_ids[0]:
 tensor([    0, 38831,  2577,  1054,    18,  2199,    16,    10, 14913, 28904,
          5777,  3693, 32226, 38868,  2199,   775,   528,     7,  2919,     9,
         48052,   636,   230,  3450, 35315,    11,     5, 50264, 50264, 50264,
             4,     2])
 
 attention_mask[0]:
 tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1])
 
 labels[0]:
 tensor([    0, 38831,  2577,  1054,    18,  2199,    16,    10, 14913, 28904,
          5777,  3693, 32226, 38868,  2199,   775,   528,     7,  2919,     9,
         48052,   636,   230,  3450, 35315,    11,     5,  8217, 24276, 10596,
             4,     2])
 """

每个输入标记都标记着与之对应的标记,无论它是否被屏蔽。这是因为与分类模型不同,模型必须能够基于给定给模型的序列生成文本序列。在BART的情况下,表示屏蔽的标记的ID是50264。

Token Deletion

使用标记删除 Token Deletion,模型必须学习确切的位置和缺失的词是什么,因此它必须比仅使用Token Masking学习更多的特征。

这种策略使用了一种不同的屏蔽方法。以一定的概率一个词从原始文本序列中被移除,因此模型必须找到缺失的单词及其位置。标准的屏蔽方法不会学习位置,因为屏蔽已经在模型的输入中指示

 deftoken_deletion(sentences, tokenizer_class=BartTokenizer, collator_class=DataCollatorForLanguageModeling, 
                  mlm=True, mlm_probability=0.20):
     tokenizer=tokenizer_class.from_pretrained('facebook/bart-base')
     inputs=tokenizer(sentences, return_tensors='pt', padding=True, truncation=True)
     
     data_collator=collator_class(
         tokenizer=tokenizer, 
         mlm=mlm,
         mlm_probability=mlm_probability
     )
 
     tuple_ids=torch.split(inputs['input_ids'], 1, dim=0)
     tuple_ids=list(tuple_ids)
     fortensorinrange(len(tuple_ids)):
         tuple_ids[tensor] =tuple_ids[tensor].squeeze(0)
     tuple_ids=tuple(tuple_ids)
 
     batch=data_collator(tuple_ids)
 
     # We use the initial inputs as labels
     batch['labels'] =batch['input_ids'].clone()
     
     # We remove tokens with mask identifier and thus make token deletion
     # Change the value to the mask identifier of the specific token model
     # It is necessary to know the identifier of the mask token for 
     # that specific model
     mask=batch['input_ids'] !=50264
     initial_size=batch['input_ids'].size(1)
     total_sentences=batch['input_ids'].size(0)
 
     # When we remove the specific token, we must fill with the padding 
     # token otherwise the tensor size is not respected.
     foriinrange(total_sentences):
         new_tensor=batch['input_ids'][i][mask[i]]
         new_tensor=F.pad(new_tensor, (0, initial_size-new_tensor.size(0)), value=1)
         batch['input_ids'][i] =new_tensor
         attention_mask=batch['input_ids'][i] ==1
         inputs['attention_mask'][i][attention_mask] =0
         
     returnbatch['input_ids'], inputs['attention_mask'], batch['labels']
 
 input_ids, attention_mask, labels=token_deletion(sentences)
 
 """
 input_ids[0]:
 tensor([    0, 38831,  2577,  1054,  2199, 14913, 28904,  3693, 32226, 38868,
          2199,   775,   528,     7,  2919,     9, 23404,   636,   230, 35315,
            11,     5, 24276, 10596,     4,     2,     1,     1,     1,     1,
             1,     1])
 
 attention_mask[0]:
 tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 0, 0, 0, 0, 0, 0])
 
 labels[0]:
 tensor([    0, 38831,  2577,  1054, 50264,  2199, 50264, 50264, 14913, 28904,
         50264,  3693, 32226, 38868,  2199,   775,   528,     7,  2919,     9,
         23404,   636,   230, 50264, 35315,    11,     5, 50264, 24276, 10596,
             4,     2])
 
 """

当使用Token Deletion训练BART时,长序列用于问答、摘要生成任务和会话任务会有一定的提高。

Text Infilling

文本填充 Text Infilling允许模型学习每个屏蔽位置可以有多少个单词。而先前的方法假设每个屏蔽位置只有一个单词。

Text Infilling与Token Masking类似,因为我们会以一定的概率在原始文本上使用屏蔽。但是不同之处在于屏蔽可以覆盖多个单词。在BART中,屏蔽是用泊松分布 lambda = 3 进行的;这意味着平均而言,每次对句子中的文本进行屏蔽时,会有三个单词被包含在一个单个的标记中,但由于这是一个概率分布,可能会有更多或更少的屏蔽单词。

我们将使用Numpy库和特定于我们的语言模型(在本例中是BART)的标记器来实现文本填充。

 importnumpyasnp
 fromtransformersimportBartTokenizer
 
 deftext_infilling(sentence, probability=0.2, poisson_lambda=3):
     # We'll use a binary mask to determine which words to replace
     mask=np.random.choice([0, 1], size=len(sentence), p=[1-probability, probability])
 
     # Now we'll replace the chosen words with a mask token
     # We'll also use a Poisson distribution to determine the length of the spans to mask
     foriinrange(len(mask)):
         ifmask[i] ==1:
             span_length=np.random.poisson(poisson_lambda)
             forjinrange(span_length):
                 ifi+j<len(sentence):
                     sentence[i+j] ="<mask>"
 
     infilled_sentence= []
     fortokeninrange(len(sentence)):
         ifsentence[token] =="<mask>":
             iftoken<len(sentence)-1:
                 ifsentence[token+1] =="<mask>":
                     continue
                 else:
                     infilled_sentence.append(sentence[token])
             else:
                 infilled_sentence.append(sentence[token])
         else:
             infilled_sentence.append(sentence[token])
     return" ".join(infilled_sentence)
 
 deftext_infilling_input(masked_sentences, sentences, tokenizer_class=BartTokenizer):
     tokenizer=tokenizer_class.from_pretrained('facebook/bart-base')
     inputs=tokenizer(masked_sentences, return_tensors='pt', padding=True, truncation=True)
     labels=tokenizer(sentences, return_tensors='pt', padding=True, truncation=True)
     returninputs['input_ids'], inputs['attention_mask'], labels['input_ids']
 
 input_ids, attention_mask, labels=text_infilling_input(masked_sentences, sentences)
 
 """
 input_ids[0]:
 tensor([    0, 50264,    16, 50264,  2199,   775,   528, 50264, 48052,   636,
         50264,  8217, 24276, 10596,     4,     2,     1,     1,     1,     1,
             1,     1,     1])
 
 attention_mask[0]:
 tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0])
 
 labels[0]:
 tensor([    0, 38831,  2577,  1054,    18,  2199,    16,    10, 14913, 28904,
          5777,  3693, 32226, 38868,  2199,   775,   528,     7,  2919,     9,
         48052,   636,   230,  3450, 35315,    11,     5,  8217, 24276, 10596,
             4,     2])
 
 """

Text Infilling比Token Deletion更能改善BART语言模型的结果,在问题回答、文本摘要和会话任务中提供更好的生成。

Sentence Permutation

语言模型的输入文本被分成随机重新排列的句子,模型需要找出原始的顺序。

在Sentence Permutation中,考虑适合模型输入序列的句子数量是至关重要的(在小型模型中,输入序列在512到1024之间)。在确定符合序列的句子数量之后,需要将它们分离到一个列表或数组中,并随机选择,而不重复其中任何一个。

 # It selects the first "number_sentences" within a given set of "sentences" 
 # and returns those sentences in a random order.
 defsentence_permutation(sentences, number_sentences):
     new_sentences=sentences[:number_sentences]
     random.shuffle(new_sentences)
     new_sentences=sentence_joiner(new_sentences)
     returnnew_sentences
 
 defpermuted_data_generation(sentences: list, total_sentences: int):
     training_sentences= []
     training_labels= []
     sentences_copy=sentences.copy()
     # We can apply sentence_permutation a number of times equal to the 
     # size of the list - 1 to get an example with each new sentence in 
     # the text, removing the oldest one.
     for_inrange(len(sentences)-total_sentences+1):
         new_sentences=sentence_permutation(sentences_copy, total_sentences)
         joined_sentences=sentence_joiner(sentences_copy[:total_sentences])
         sentences_copy=sentences_copy[1:]
         training_sentences.append(new_sentences)
         training_labels.append(joined_sentences)
 
     returntraining_sentences, training_labels
 
 
 defpermutation_training(sentences: list, sentences_labels: list, 
                          tokenizer_class=BartTokenizer, 
                          collator_class=DataCollatorForLanguageModeling, 
                         mlm=True, mlm_probability=0.0):
     # We get input_ids and attention mask from the permuted sentences
     input, attention_mask, _=load_dataset_mlm(sentences, tokenizer_class, collator_class, mlm, mlm_probability)
     
     # Labels from the original sentences
     labels, _, _=load_dataset_mlm(sentences_labels, tokenizer_class, collator_class, mlm, mlm_probability)
 
     returninput.squeeze(0), attention_mask.squeeze(0), labels.squeeze(0)
 
 input_ids, attention_mask, labels=permutation_training(training_sentences, training_labels_sentences)
 
 """
 input_ids[0]:
 tensor([    0, 38831,  2577,  1054,    18,  2199,    16,    10, 14913, 28904,
          5777,  3693, 32226, 38868,  2199,   775,   528,     7,  2919,     9,
         48052,   636,   230,  3450, 35315,    11,     5,  8217, 24276, 10596,
             4,  2585, 33430,  8457,     9, 41419,  8217,  1054,    36,   119,
         49491,    43, 10596, 37118,    32,    45,   157,   684,     4,  4129,
         33839,  4405, 35019,     9,     5, 19850, 34939,  3724,   204,   717,
            12, 21792,   775,    11,     5, 39752,     9,     5, 19850,   797,
           981,     7, 15067,  8276, 37423,     8, 46282,  5043,     4,     2])
 
 attention_mask[0]:
 tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1])
 
 labels[0]:
 tensor([    0, 38831,  2577,  1054,    18,  2199,    16,    10, 14913, 28904,
          5777,  3693, 32226, 38868,  2199,   775,   528,     7,  2919,     9,
         48052,   636,   230,  3450, 35315,    11,     5,  8217, 24276, 10596,
             4,  4129, 33839,  4405, 35019,     9,     5, 19850, 34939,  3724,
           204,   717,    12, 21792,   775,    11,     5, 39752,     9,     5,
         19850,   797,   981,     7, 15067,  8276, 37423,     8, 46282,  5043,
             4,  2585, 33430,  8457,     9, 41419,  8217,  1054,    36,   119,
         49491,    43, 10596, 37118,    32,    45,   157,   684,     4,     2])
 
 """

我们对于模型的每个数据输入,删除原始序列中出现的第一个句子,然后在执行基于要选择的固定句子数目的句子排列之前,将接下来的句子添加进去。这样虽然重新排列了输入序列中的句子,但保持了一个每个新例子中都会出现一个新的句子,并删除最旧的句子的上下文窗口。

Document Rotation

当旋转一个文档时,选择一个特定的词,并将其设定为起始词,而所有之前的词都被粘贴到文本的末尾。

如果要应用Document Rotation,必须考虑到每个批次使用的维度。在应用填充的情况下,这个填充不能与文档的其余部分一起旋转,而是必须保持其原始位置,同时整个文档旋转。

 defsentence_joiner(sentences: list):
   return' '.join(sentences)
 
 # With this function we gather as many sentences as we want to form the input data to the tokenizer.
 defrotated_data_generation(sentences: list, total_sentences: int):
   training_sentences= []
   sentences_copy=sentences.copy()
   for_inrange(len(sentences)-total_sentences+1):
     new_sentences=sentences_copy[:total_sentences]
     new_sentences=sentence_joiner(new_sentences)
     sentences_copy=sentences_copy[1:]
     training_sentences.append(new_sentences)
   returntraining_sentences
 
 # Apply this function over the rotated sentences from previous function
 defdocument_rotation_training(sentences, tokenizer_class=BartTokenizer):
   tokenizer=tokenizer_class.from_pretrained('facebook/bart-base')
   tokens=tokenizer(sentences, return_tensors='pt', padding=True, truncation=True)
   tokens['input_ids'] =tokens['input_ids'].squeeze(0)
   tokens['labels'] =tokens['input_ids'].clone()
 
   iterations=tokens['input_ids'].size(0)
   foriinrange(iterations):
     # Get the attention mask and convert to list
     attention_mask=tokens['attention_mask'][i].tolist()
     # Calculate the position where padding starts
     if0inattention_mask:
       padding_start_position=attention_mask.index(0)
     else:
       padding_start_position=False
     # We take into account the position of the padding so as not to rotate it along with the rest of the document.
     ifpadding_start_position:
       random_token=torch.randint(1, padding_start_position-1, (1,))
       tokens['input_ids'][i] =torch.cat((tokens['input_ids'][i][0].unsqueeze(0), #initial token
                                       tokens['input_ids'][i][random_token.item():padding_start_position-1], #from random to padding
                                       tokens['input_ids'][i][1:random_token.item()], #from 1 to random
                                       tokens['input_ids'][i][padding_start_position-1:-1],
                                       tokens['input_ids'][i][-1].unsqueeze(0)), 0)
                                         
     # If there is no padding, we rotate the document without taking the padding into account.
     else:
       random_token=torch.randint(1, tokens['input_ids'].size(0)-1, (1,))
       tokens['input_ids'][i] =torch.cat((tokens['input_ids'][i][0].unsqueeze(0), #initial token
                                       tokens['input_ids'][i][random_token.item():-1], #from random to end
                                       tokens['input_ids'][i][1:random_token.item()],
                                       tokens['input_ids'][i][-1].unsqueeze(0)), 0)
   returntokens['input_ids'], tokens['attention_mask'].squeeze(0), tokens['labels']
 
 data=rotated_data_generation(sentences, 3)
 input_ids, attention_mask, labels=document_rotation_training(data)
 
 """
 input_ids[2]:
 tensor([    0,  2433,    61,    32,   551,    88,  1316,    32,    12,  4138,
         15557, 47605,     6, 22835,  2591,   939,     4,   242, 10079, 38422,
          9235,     6, 10295, 22540, 14819,     8,  3039, 11543,     4,   347,
         37347,  8457,     9, 41419,  8217,  1054,    36,   119, 49491,    43,
         10596, 37118,    32,    45,   157,   684,     4, 41058,  4484,     9,
          1046,     9, 23808,    16,    41,   505,  3724,     9, 18073,    18,
          2199, 18246,  4194,     8, 13430,  3505,     4,    20,     2,     1,
             1,     1,     1,     1,     1,     1,     1,     1,     1,     1])
 
 attention_mask[2]:
 tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0])
 
 labels[2]:
 tensor([    0,   347, 37347,  8457,     9, 41419,  8217,  1054,    36,   119,
         49491,    43, 10596, 37118,    32,    45,   157,   684,     4, 41058,
          4484,     9,  1046,     9, 23808,    16,    41,   505,  3724,     9,
         18073,    18,  2199, 18246,  4194,     8, 13430,  3505,     4,    20,
          2433,    61,    32,   551,    88,  1316,    32,    12,  4138, 15557,
         47605,     6, 22835,  2591,   939,     4,   242, 10079, 38422,  9235,
             6, 10295, 22540, 14819,     8,  3039, 11543,     4,     2,     1,
             1,     1,     1,     1,     1,     1,     1,     1,     1,     1])
 
 """

类似于序列排列,我们可以在每个数据输入中移除最旧的句子,并添加一个新句子,从而保持上下文窗口。

总结

本文介绍了讨论了训练语言模型的不同的令牌掩码。虽然这些都是比较常见的方法,但是大多数模型只使用了Token Masking。

对于短文本序列来说,Sentence Permutation 和Document Rotation技术可能没有帮助甚至会降低准确率。而Token Masking、Token Deletion和Text Infilling 在短文本和长文本序列中都可以使用。

https://avoid.overfit.cn/post/1b9d2c9d6b9a4bacbe6fa906c23aee7f

作者:Fabio Yáñez Romero

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python|enumerate

enumerate可以用来列举可遍历的对象 # 假设我们有一个列表 fruits [apple, banana, cherry] # 使用enumerate()函数遍历列表 for index, fruit in enumerate(fruits): print(f"Index: {index}, Fruit: {fruit}")# 假设我们想要从1开始计数 for index, fru…

使用ADO.NET访问数据库

目录 访问数据库的步骤 &#xff11;、建立数据库 &#xff12;、设置链接参数 &#xff08;1&#xff09;web网页和数据库连接的方法一 &#xff08;2&#xff09;web网页和数据库连接的方法二 &#xff13;、建立链接对象 &#xff14;、显示数据库 &#xff15;、数…

第十五讲:C语言内存函数

目录 1、C语言内存函数 1.1、memcpy函数的使用和模拟 1.2、memmove函数的使用和模拟 1.3、memset函数的使用 1.4、memcmp函数的使用 1、C语言内存函数 注意&#xff1a;下面这些函数的使用要包含头文件&#xff1a;string.h 1.1、memcpy函数的使用和模拟 函数声明为&am…

echarts 条形图(柱状图)多个图例按钮默认高亮一个,且只能高亮一个

核心&#xff1a;给图例按钮添加点击事件 myChart.on("legendselectchanged", function (params) {let selected {功率柜: true,母线柜: false,充电桩终端: false,网络柜: false,};for (let key in selected) {if (key ! params.name) {myChart.setOption({legend:…

vue3使用jsQR解析二维码

1.了解jsQR jsQR是一个纯javascript脚本实现的二维码识别库,不仅可以在浏览器端使用,而且支持后端node.js环境。jsQR使用较为简单,有着不错的识别率。 2.效果图 3.二维码 4.下载jsqr包 npm i -d jsqr5.代码 <script setup> import {ref } from vue import jsQR fr…

视频图像的两种表示方式YUV与RGB(1)

了解过计算机图形图像学的该知道&#xff0c;可用RGB和YUV两种方式表示图像像素&#xff0c;视频由一帧一帧的图像组成&#xff0c;每一张图片是一个一个的像素点组成&#xff0c;既然有两种表示像素的方法&#xff0c;那就一起解一下两种表示方式的异同及优缺点。 RGB像素 这…

【PPT技巧】如何取消PPT的密码保护?

PPT文件有两种密码&#xff0c;一种是打开密码、一种是修改权限。今天分享这两种密码如何取消。 首先需要告知大家的是&#xff0c;密码的取消需要输入正确的密码。 打开密码的取消&#xff0c;我们需要先输入密码&#xff0c;打开文件&#xff0c;然后点击文件 – 信息 – 保…

os.listdir()bug总结

今天测试出一个神奇的bug&#xff0c;算是教训吧&#xff0c;找了两天不知道问题在哪&#xff0c;最后才发现问题出现在这 原始文件夹显示 os.listdir()结果乱序 import os base_path "./file/"files os.listdir(base_path)print(files)问题原因 解决办法(排序) …

YOLOv8全网独家改进: 小目标 |新颖的多尺度前馈网络(MSFN) | 2024年4月最新成果

💡💡💡本文独家改进:多尺度前馈网络(MSFN),通过提取不同尺度的特征来增强特征提取能力,2024年最新的改进思路 💡💡💡创新点:多尺度前馈网络创新十足,抢先使用 💡💡💡如何跟YOLOv8结合:1)放在backbone后增强对全局和局部特征的提取能力;2)放在detect…

解密项目管理专业术语:十大名词背后的实战技巧

项目管理是一门综合学科&#xff0c;涵盖了一系列方法、技能和工具。今天为大家带来项目管理的十大专业术语&#xff0c;它们分别是项目范围、利益相关者管理、工作分解结构&#xff08;WBS&#xff09;、里程碑、风险管理、资源分配、关键路径法&#xff08;CPM&#xff09;、…

漏洞挖掘 | 从信息收集到登录后台

通过信息收集进网站后台 记录一次通过简单的信息收集获取账号信息后进入后台的经过。打开思路&#xff0c;利用我们所有能够捕获的信息并串联起来。 0X0 开始&#xff1a; 打开网站发现是一个登录网站 随便输入账号密码&#xff0c;发现有用户名枚举&#xff1a; 0X1 获取ic…

SuperMap GIS基础产品FAQ集锦(202403)

一、SuperMap GIS基础产品桌面GIS-FAQ集锦 问题1&#xff1a;【iDesktop】安装了idesktop 11i&#xff0c;现想进行插件开发&#xff0c;根据安装指南安装SuperMap.Tools.RegisterTemplate.exe&#xff0c;运行多次均失败 【问题原因】该脚本是之前老版本针对VS2010写的&…

蓝桥杯-外卖店优先级

代码及其解析 #include<bits/stdc.h> using namespace std; const int N100010;int order[N]; //order[id] 第id号店上一次的订单,记录的是时间 int prior[N]; //prior[id] 第id号店的优先级 int flag[N]; //flag[id] 第id号店在不在优先缓存中struct node{int…

【RHEL】redhat yum 报错: not registered to Red Hat Subscription Management.

【RHEL】redhat yum 报错: not registered to Red Hat Subscription Management. 问题描述解决方法参考博客&#xff1a; 问题描述 使用redhat7用yum install -y dos2unix命令时出现这个错误 This system is not registered to Red Hat Subscription Management. You can use …

CAXA电子图版2020版 下载地址及安装教程

CAXA电子图板是一款由国内软件公司CAXA开发的专业CAD&#xff08;计算机辅助设计&#xff09;软件。它主要用于绘制和编辑各种类型的二维图纸和工程图纸&#xff0c;广泛应用于建筑、机械、电气和电子等行业。 CAXA电子图板具有以下主要功能和特点&#xff1a; 二维绘图&…

seo调优

SEO 网站地图&#xff1a;sitemap.xmlrobots.txtxxx.com/www.xxx.com 解析到服务器&#xff0c;xxx.com 301 到 www.xxx.comhttps百度站点管理标题描述关键词标签语义化内链外链死链链接html结尾友情链接前端架构 注意&#xff1a;已收录链接&#xff0c;禁止改变链接地址 ro…

C语言——文件管理

文件&#xff1a;即磁盘上的文件&#xff0c;使用文件可以将数据直接存放在电脑的硬盘上&#xff0c;做到数据持久化。 在程序设计中&#xff0c;按文件的功能划分&#xff0c;将文件分为程序文件与数据文件 程序文件 程序文件包括源文件&#xff08;.c&#xff09;&#xff0…

Ubuntu20.04连接不了无线网

1.首先查看网卡型号 lspci Network controller显示的就是网卡型号 也可以使用如下命令 lspci -nnk | grep 0280 -A3 2.找到对应的驱动并下载安装 我的电脑的网卡型号为Realtek Semiconductor Co., Ltd. Device b852&#xff0c;则采用如下命令安装&#xff1a; sudo ap…

vue3+Ts+Ant Design Vue +天地图组件封装

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来Vue3TsAntDesign-Vue组件天地图组件的封装 示例图 首先,在index.html引入天地图资源,vue3选择v4版本 <script src"http://api.tianditu.gov.cn/api?…

Python零基础从小白打怪升级中~~~~~~~流程控制语句

第三节&#xff1a;Python的流程控制语法 一、Python条件语句的语法 if 条件1:条件1成立执⾏的代码一条件1成⽴执⾏的代码二...... elif 条件2&#xff1a;条件2成立执⾏的代码三条件2成立执⾏的代码四...... ...... else:以上条件都不成⽴&#xff0c;执行的代码五以上条件都…