当前位置: 首页 > news >正文

免费做网站公司小说章节收费网站建设

免费做网站公司,小说章节收费网站建设,网页制作怎么收费,深圳市专注网站建设经典神经网络(14)T5模型原理详解及其微调(文本摘要) 2018 年#xff0c;谷歌发布基于双向 Transformer 的大规模预训练语言模型 BERT#xff0c;而后一系列基于 BERT 的研究工作如春笋般涌现#xff0c;预训练模型也成为了业内解决 NLP 问题的标配。 2019年#xff0c;谷歌…经典神经网络(14)T5模型原理详解及其微调(文本摘要) 2018 年谷歌发布基于双向 Transformer 的大规模预训练语言模型 BERT而后一系列基于 BERT 的研究工作如春笋般涌现预训练模型也成为了业内解决 NLP 问题的标配。 2019年谷歌又提出预训练模型 T5(Text-to-Text Transfer Transformer)T5模型本质上来说是一个基于Transformer架构的encoder-decoder模型。T5模型将各种NLP任务都视为Text-to-Text任务也就是输入为Text输出也为Text的任务。 我们知道BERT相关的预训练语言模型在下游任务微调过程中都需要添加非线性层将模型的输出转化为任务指定的输出格式。但是T5不需要对模型做任何改动不需要添加任何非线性层唯一需要做的就是在输入数据前加上任务声明前缀。 T5模型刚发布时刷新了 Glue 榜单和 SuperGLUE 榜单直至今日还是这两个榜单的前10名。 https://gluebenchmark.com/leaderboard https://super.gluebenchmark.com/leaderboard 今天我们来了解下T5这个经典的模型。 论文链接https://arxiv.org/abs/1910.10683Github 链接https://github.com/google-research/text-to-text-transfer-transformer 1 T5模型简介 如下图所示T5(Text-to-Text Transfer Transformer)模型将翻译、分类、回归、摘要生成等任务都统一转成Text-to-Text任务从而使得这些任务在训练(pre-train和fine-tune)时能够使用相同的目标函数在测试时也能使用相同的解码过程。 T5模型在NLU和NLG上都具有出色表现能够完成翻译任务、文本分类、阅读理解、摘要生成任务等多种下游任务。 然而T5刚出来的时候我们可能没有什么存在感原因很简单没有中文版T5可用。 不过Google后面放出了多国语言版的T5mT5里边包含了中文语言。 论文链接mT5: A massively multilingual pre-trained text-to-text transformerHugging face链接https://huggingface.co/collections/google/mt5-release-65005f1a520f8d7b4d039509 另外国内还有一些公司利用T5模型使用了大量中文数据进行训练。 孟子T5预训练生成模型与T5结构相同但是不包含下游任务需要在特定任务上 Finetune 后使用。孟子T5预训练生成模型-中文-base iic在mt5模型基础上使用了大量中文数据进行训练并引入了零样本分类增强的技术。全任务零样本学习-mT5分类增强版-中文-base 1.1 T5模型网络架构 1.1.1 Encoder-Decoder结构 如下图所示目前基于Transformer的模型架构主要有Encoder-Decoder结构(传统的Transformer结构)、Language model结构 (GPT的结构)和Prefix LM结构(UniLM的结构)。 Encoder-Decoder结构Seq2Seq常用模型编码器输入中可以看到序列中包括自己的全部字符解码器的输出只能看到当前字符及之前的字符LM模型Encoder-Decoder中的Decoder部分单向结构每次只能看到当前及之前的部分基于前缀的语言模型Prefix LM前面一部分文本可以看到前缀部分所有内容后面剩下的内容只能看到自己及之前的内容。 如下图所示作者通过实验发现Encoder-decoder架构的模型效果最好所以T5模型本质上来说是一个基于Transformer的Encoder-decoder模型。 1.1.2 SentencePiece 把一个句子看作一个整体再拆成片段而没有保留天然的词语的概念。 SentencePiece不将空格视为分隔符而是将字符串作为其原始格式的输入使用BPE或ULM作为其分词器来构建词汇表。 下划线被引入代替了空格和句子开头特殊符号 from transformers import T5Tokenizermodel_dir rD:\\python\\models\\model-download\\iic\\nlp_mt5_zero-shot-augment_chinese-base tokenizer T5Tokenizer.from_pretrained(model_dir, legacyFalse) print(tokenizer.tokenize(Dont make the user feel stupid))# [▁Don, , t, ▁make, ▁the, ▁user, ▁feel, ▁stupid]中文可以看到一些多字词但有些词其实不符合一般的分词习惯 print(tokenizer.tokenize(笔画最多的汉字是龘(da)字))# 可以看到龘字经过tokenize变为0xE9, 0xBE, 0x98 # [▁, 笔, 画, 最多, 的, 汉, 字, 是, 0xE9, 0xBE, 0x98, (, da, ), 字]1.2 相对位置编码 不同于RNN、CNN等模型对于Transformer模型来说位置编码的加入是必不可少的因为纯粹的Attention模块是无法捕捉输入顺序的即无法区分不同位置的Token。为此我们大体有两个选择 1、将位置信息融入到输入中这构成了绝对位置编码的一般做法2、微调一下Attention结构使得它有能力分辨不同位置的Token这构成了相对位置编码的一般做法。 1.2.1 常规相对位置编码的可视化解释 Transformer中有两种常用的位置编码分别为绝对位置编码和相对位置编码。 我们先看常规相对位置编码的思路 论文链接https://arxiv.org/pdf/1803.02155 视频解释Self-Attention with Relative Position Representations – Paper explained 如下图假如有5个token其中一个token与其他所有位置包括自己在内的token之间存在一个权重。 如下图 w 0 w_0 w0​表示 x 4 x_4 x4​与自己的位置关系0表示与自己的距离 w 1 w_1 w1​表示向右移动一个位置 w − 1 w_{-1} w−1​表示向左移动一个位置。 x 3 x_3 x3​可以表示为下图所示 那么第一个到最后一个就可以分别表示为下图所示 如下图所示一共有9个不同的位置编码分别为 w − 4 , w − 2 , w − 3 , w − 1 , w 0 , w 1 , w 2 , w 3 , w 4 w_{-4}, w_{-2}, w_{-3}, w_{-1}, w_0, w_1, w_2, w_3, w_4 w−4​,w−2​,w−3​,w−1​,w0​,w1​,w2​,w3​,w4​。 我们可以用用标识对表示 我们可以使用一个阈值k例如k2当超过这个特定的阈值(就是下图中红色背景的部分) 即其他的position_embedding距离自身超过2个位置那么这些位置的position_embedding就和距离最近的position_embedding值一样。例如下图中 x 1 x_1 x1​的 w 3 w_3 w3​和 w 4 w_4 w4​就会变成 w 2 w_2 w2​其他同理。 1.2.2 常规相对位置编码的公式解释 下图是论文(https://arxiv.org/pdf/1803.02155)中给出的自注意力机制的公式其中 e i j e_{ij} eij​的计算方式采用的是Scaled Dot-Product 我们知道相对位置编码的做法就是微调一下Attention结构使得它有能力分辨不同位置的Token一般认为相对位置编码是由绝对位置编码启发而来考虑一般的带绝对位置编码的Attention(下面推导公式来源于苏神博客) Google论文(https://arxiv.org/pdf/1803.02155)中对上式进行了修改 通过上面的解释我们就很容易理解论文中下面的公式了 如下图左边所示是论文中提出的具体的截断方式。如下图右边所示通过在每个注意头之间共享相对位置表示来降低存储相对位置表示的空间复杂度。 分子第一项中我们的输入 x i x_i xi​的tensor的Shape为:(B, h, seq_length, d)它计算的是query和key的关系所以第一项的输出为(B, h, seq_length, seq_length)第二项的输出shape必须跟第一项一致。第二项中 a i j K a_{ij}^K aijK​表示的是 i j ij ij的相对位置编码从位置编码的Embeding向量table中去lookup得到的lookup后的shape为(seq_length, seq_length, da)转换下维度得到(seq_length, da, seq_length)其中原始位置编码lookup后的向量table我们用A来表示转换维度后我们用 A T A^T AT表示。 x i x_i xi​跟 W Q W^Q WQ相乘后得到tensor其shape为(B, h, seq_length, dz)转换下维度得到(seq_length, B, h, dz)再转换下得到(seq_length, B×h, dz)再跟 a i j K a_{ij}^K aijK​来相乘实质是跟 A T A^T AT相乘所以(seq_length, B×h, dz)和矩阵(seq_length, da, seq_length)相乘因此需要dzda得到(seq_length, B×h, seq_length)后reshape下得到(seq_length, B, h, seq_length)转置后shape为(B, h, seq_length, seq_length)这样就跟第一项对应起来了。 1.2.3 T5模型中的位置编码 我们先看下苏神博客中的内容分析下T5模型中相对位置编码公式的由来 T5采用了一个长距离不敏感的相对位置编码这一设计是考虑到远距离的单词依赖往往比较稀疏且不精细因此我们需要对周围单词的位置做精确的区分而远距离单词的位置变化则相对缓慢。如下图所示T5模型对相对位置进行了一个“分桶”处理将原始的relative position当成一个个小方块放置在顺序排列的桶中最后用方块所属的桶号来代替相对距离 在T5中num_buckets32max_distance128源码中将num_buckets/2的距离定义为近的分割线(对于双向attention是8对单向attention是16)低于这个数值的距离被认为是近的高于这个数值的距离被认为是远的。这个设计的思路其实也很直观就是比较邻近的位置(0-7)我们需要比较得精细一些所以给它们都分配一个独立的位置编码至于稍远的位置(比如8~11)我们不用区分得太清楚所以它们可以共用一个位置编码。距离越远共用的范围就可以越大直到达到指定范围再clip。 我们来看下transformers库中T5模型相对位置编码的实现 # transformers/models/t5/modeling_t5.py中的T5Attention类def compute_bias(self, query_length, key_length, deviceNone):Compute binned relative position biasif device is None:device self.relative_attention_bias.weight.devicecontext_position torch.arange(query_length, dtypetorch.long, devicedevice)[:, None]memory_position torch.arange(key_length, dtypetorch.long, devicedevice)[None, :] # 计算相对位置relative_position memory_position - context_position # shape (query_length, key_length)# 分桶处理relative_position_bucket self._relative_position_bucket(relative_position, # shape (query_length, key_length)bidirectional(not self.is_decoder),num_bucketsself.relative_attention_num_buckets,max_distanceself.relative_attention_max_distance,)# Embedding矩阵为self.relative_attention_bias nn.Embedding(self.relative_attention_num_buckets, self.n_heads)# look-up查找并进行维度转换values self.relative_attention_bias(relative_position_bucket) # shape (query_length, key_length, num_heads)values values.permute([2, 0, 1]).unsqueeze(0) # shape (1, num_heads, query_length, key_length)return values# 这里我们假设query_lengthkey_length128 # 那么相对位置矩阵为relative_position tensor([[ 0, 1, 2, ..., 125, 126, 127],[ -1, 0, 1, ..., 124, 125, 126],[ -2, -1, 0, ..., 123, 124, 125],...,[-125, -124, -123, ..., 0, 1, 2],[-126, -125, -124, ..., -1, 0, 1],[-127, -126, -125, ..., -2, -1, 0]]) # 分桶后relative_position_bucket tensor([[ 0, 17, 18, ..., 31, 31, 31],[ 1, 0, 17, ..., 31, 31, 31],[ 2, 1, 0, ..., 31, 31, 31],...,[15, 15, 15, ..., 0, 17, 18],[15, 15, 15, ..., 1, 0, 17],[15, 15, 15, ..., 2, 1, 0]]) relative_position_bucket[0] # 查看第一个双向attention近的分割线为8 tensor([ 0, 17, 18, 19, 20, 21, 22, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26,26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28,28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29,29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30,30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,31, 31]) relative_position_bucket[-1] # 查看最后一个双向attention近的分割线为8 # 就是比较邻近的位置(0~7)我们需要比较得精细一些所以给它们都分配一个独立的位置编码 # 至于稍远的位置(比如8~11)我们不用区分得太清楚所以它们可以共用一个位置编码。距离越远共用的范围就可以越大 tensor([15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13,13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12,12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10,10, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 8, 7, 6, 5, 4, 3, 2,1, 0])# look-up查找后 values shape(128, 128, 12) # 维度转换后 values shape(1, 12, 128, 128)# transformers/models/t5/modeling_t5.py中的T5Attention类def forward(self,hidden_states,maskNone,key_value_statesNone,position_biasNone,past_key_valueNone,layer_head_maskNone,query_lengthNone,use_cacheFalse,output_attentionsFalse,):......# 计算注意力分数scores torch.matmul(query_states, key_states.transpose(3, 2)) # equivalent of torch.einsum(bnqd,bnkd-bnqk, query_states, key_states), compatible with onnx op9if position_bias is None:if not self.has_relative_attention_bias:......else:# 计算相对位置编码 shape (1, num_heads, seq_length, key_length)position_bias self.compute_bias(real_seq_length, key_length, devicescores.device)if mask is not None:# seq_length key_length# 加上mask信息 mask shape (batch_size, 1, 1, seq_length)# position_bias shape (batch_size, n_heads, seq_length, seq_length)position_bias position_bias mask if self.pruned_heads:mask torch.ones(position_bias.shape[1])mask[list(self.pruned_heads)] 0position_bias_masked position_bias[:, mask.bool()]else:position_bias_masked position_bias# Note: 位置编码加在了注意力分数scores上scores position_bias_maskedattn_weights nn.functional.softmax(scores.float(), dim-1).type_as(scores) # (batch_size, n_heads, seq_length, key_length)......总结一下 1.3 T5模型的训练策略 1.3.1 训练数据集探索 作者对公开爬取的网页数据集Common Crawl进行了过滤 仅保留以终端标点符号即句号、感叹号、问号或结束引号结尾的文本行删除任何包含「污秽、下流或其他脏话字眼」的页面由于爬取到的很多页面包含「应启用 Javascript」的警告信息所以删除含有 Javascript 一词的所有文本行有些页面包含占位符「乱数假文」lorem ipsum所以删除出现「乱数假文」短语的所有页面有些页面会无意中含有代码。由于花括号「{」出现在很多编程语言中如网上广泛使用的 Javascript但不会出现在自然文本中所以删除所有含有花括号的页面为了删除数据集中的重复数据删除数据集中多次出现的任何三个句子中的两个。此外由于大多数下游任务都集中在英文文本上因此研究者使用 langdetect 来过滤掉所有未归类为英文的页面概率至少为 0.99。为了汇编基础数据集他们下载了自 2019 年 4 月开始网络爬取的文本并进行了过滤。这样产生的文本集合不仅比用于预训练的大多数数据集大几个数量级大约 750GB而且还包含非常干净自然的英文文本。研究者将此数据集称为「Colossal Clean Crawled Corpus」或简称 C4 语料库并将其作为 TensorFlow 数据集的一部分发布。 从上图实验结果可以看出 (1) C4比unfiltered C4效果好说明数据清洗的重要性 (2) WikipediaTBC在SGLUE上的效果比C4好主要是因为在SGLUE中的MultiRC任务得分很高MultiRC是一个阅读理解数据集其中的数据主要是小说书籍和TBC属于同一领域数据。由此说明预训练的数据集中包含一定的领域数据对下游该领域任务的性能提升有效 从上图中可以看出随着数据集不断缩小模型的性能逐渐下降说明大的模型很可能在小的数据集上发生了过拟合因此建议预训练模型还是尽可能使用大数据集。 1.3.2 无监督预训练目标探索 论文对无监督目标过程中所做的选择进行了探索从下面四个方面进行实验 1、自监督的预训练方法 语言模型式单向的从左到右依次预测典型代表为GPT-2模型BERT-style式像BERT模型一样随机破坏掉一部分内容然后进行还原顺序还原式将文本打乱然后进行还原 如上图所示给定句子“Thank you for inviting me to your party last week .”图中展示了针对不同的预训练目标模型的Input和Target样本的形式。 2、对文本一部分进行破坏时的策略 Mask法将被破坏token换成特殊符如[M];Replace span(小段替换)法可以把它当作是把上面 Mask 法中相[M]都合成了一个特殊符每一小段替换一个特殊符提高计算效率;Drop法没有替换操作直接随机丢弃一些字符。 其中Replace corrupted spans就是上上图中的noise replace spans目标 Drop corrupted tokens就是上上图中的noise, drop tokens目标。 结果表明这几种BERT-style预训练目标的变种效果差不多但是后两种方法不需要预测整个输入序列而仅需要预测被污染的部分因此预测的序列长度更短训练速度也更快。 3、对文本百分之多少进行破坏 4、对大概多长的文本段进行破坏 因此经过上述实验确定了T5模型的预训练方式如下 1.3.3 T5模型的微调 微调模型的所有参数可能会导致结果欠佳尤其是在资源匮乏的情况下。论文专注于两种替代的微调方法这些方法仅更新编码器-解码器模型的参数的子集。 Adapter layers。 在微调时保持大多数原始模型固定不变。在transformer每个块中前馈神经网络后添加dense-ReLU-denseblocks。新的前馈网络使得输出可以与输入维度匹配。 (这样就可以将它们插入网络而无需更改结构或参数)进行微调时仅更新适配器层和层归一化参数。这种方法的主要超参数是前馈网络的内部维数 d它改变了添加到模型中的新参数的数量。 Gradual unfreezing。 初始微调时只有最后一层的参数被更新训练一段时间后倒数第2层及其之后层的参数被更新直至整个网络的参数都被更新。 如下图所示所有参数一起更新效果是最好的但是缺点就是慢。 adapter layers可能是一种在较少参数上进行微调的有前途的技术只要将维度适当地缩放到任务大小即可假如任务数据量小的话d取小一些任务数据量大的话d取大一些。 Gradual unfreezing尽管在微调过程中确实提供了一定的加速但全局解冻会在所有任务中造成轻微的性能下降。因此通过更仔细地调整解冻时间表可以获得更好的结果。 1.3.4 T5模型的多任务学习 1) 多任务学习如何取样 大多数将多任务学习应用于NLP的应用都会添加特定于任务的分类网络或者为每个任务使用不同的损失函数。本论文的多任务学习仅将不同任务的数据集混合在一起。 若现在有无监督任务、有监督任务1、有监督任务2、有监督任务3一起训练时如何采样数据? 作者设置了三种采样方法 Examples-proportional mixing设任务的数据集大小为 e n , n ∈ 1 , . . . , N e_n,n∈1,...,N en​,n∈1,...,N采样时采样自第m个任务数据的概率为 r m m i n ( e m , K ) ∑ m i n ( e n , K ) r_m\frac{min(e_m,K)}{\sum min(e_n,K)} rm​∑min(en​,K)min(em​,K)​这里K是提前设定的参数Temperature-scaled mixing在第一个实验的基础上对求得的 r m r_m rm​再求 1 T \frac{1}{T} T1​方根当T1时即Examples-proportional mixing。T越大各个任务数据集采样越均衡Equal mixing各个任务数据采样概率相同。 2) 多任务学习微调 多任务学习微调先用多个任务进行预训练再对具体任务进行微调 实验一在Examples-proportional mixing 的人工混合数据集上预训练模型然后在每个单独的下游任务上对其进行微调实验二在相同的混合数据集上对模型进行预训练只是从该预训练混合物中省略了一项下游任务。然后我们在预训练中遗漏的任务上对模型进行微调。对于考虑的每个下游任务都会重复此步骤。这种方法为“leave-one-out”多任务训练实验三把无监督目标(即baseline的预训练目标)剔除对所有考虑的监督任务进行预训练。 如上图所示我们发现Multi-task pretrainingfine-tuning的效果和Unsupervised pre-training fine-tuning的效果差不多但是前者在预训练过程还能够监控下游任务的性能因此作者最后采用Multi-task pre-training。 1.4 最终选择 通过对各种对比实验的结果进行分析作者最终确定了训练T5模型的较优方案 无监督训练目标采用span-corruption目标类似SpanBERT的做法。预训练策略采用multi-task预训练方式(即无监督任务和有监督任务一起预训练)。 把前面的最佳方案组合在一起作者训练了Small、Base、Large、3B、11B五种T5模型。 模型LayersHidden SizeAttention Head参数量Small6512860MBase1276812220MLarge24102416770M3B241024323B11B24202812811B 1.5 mT5和Flan-T5模型 1.5.1 mT5模型 mT5仍是T5数据构造方式(C4数据集)但语料不再只限于英语而是扩大到101种语言其中就包括了中文、俄语等。模型结构是使用的T5.1.1版本相比于原始T5版本主要有如下升级 激活函数变更: Gated-GELU activation替代ReLU无标签数据不做dropoutembedding和分类层不做参数共享更大的d_model更小的num_heads和d_ff 1.5.2 Flan-T5模型 这里的Flan指的是Instruction finetuning即基于指令的微调。论文的核心贡献是提出一套多任务的微调方案Flan来极大提升语言模型的泛化性。如下图所示引入Flan微调方案可以很好提高语言模型在超大规模任务上的整体效果。 Flan微调的过程 第一步是收集一系列监督的数据 第二步将任务都转换成相同的“输入格式”喂给模型训练同时这些任务的输出也需要是统一的“输出格式”这样是为了使用单个语言模型来完成超过1800种不同的任务 如下图根据 “是否需要进行思维链推理 CoT” 以及 “是否需要提供示例Few-shot” 可将输入、输出划分成四种类型。 第三步就是微调过程。 将多个训练样本“打包”成一个训练样本这些训练样本直接会通过一个特殊的“结束token”进行分割。训练时候在每个指定的步数会在“保留任务”上进行模型评估保存最佳的checkpoint。尽管微调的任务数量很多但是相比于语言模型本身的预训练过程计算量小了非常多只有0.2%。 例如下面文章中的例子模型训练好之后可直接让模型做问答: 「模型输入」是Geoffrey Hinton和George Washington这两个人有没有交谈过在回答之前想一想原因。“ 「模型返回」是Geoffrey Hinton是一个计算机科学家出生在1947年而George Washington在1799年去世。所以这两个不可能有过交谈。所以答案时“没有”。 论文: Scaling Instruction-Finetuned Language Models 地址https://arxiv.org/abs/2210.11416模型Flan-T5 release - a google Collection 2 基于T5模型的微调(文本摘要) 我们这里基于澜舟科技开源的mengzi-t5-base做摘要生成。孟子T5与T5结构相同但是不包含下游任务需要在特定任务上 finetune 后使用。这里是自己实现文本摘要如果借助transformers库的组件会更加简单。 2.1 加载数据集 数据集地址https://huggingface.co/datasets/supremezxc/nlpcc_2017 我们看一条数据集 {title: 组图:黑河边防军人零下30℃户外训练,冰霜沾满眉毛和睫毛,防寒服上满是冰霜。, content: 中国军网2014-12-1709:08:0412月16日,黑龙江省军区驻黑河某边防团机动步兵连官兵,冒着-30℃严寒气温进行体能训练,挑战极寒,锻造钢筋铁骨。该连素有“世界冠军的摇篮”之称,曾有5人24人次登上世界军事五项冠军的领奖台。(魏建顺摄)黑龙江省军区驻黑河某边防团机动步兵连官兵冒着-30℃严寒气温进行体能训练驻黑河某边防团机动步兵连官兵严寒中户外训练,防寒服上满是冰霜驻黑河某边防团机动步兵连官兵严寒中户外训练,防寒服上满是冰霜官兵睫毛上都被冻上了冰霜官兵们睫毛上都被冻上了冰霜驻黑河某边防团机动步兵连官兵严寒中进行户外体能训练驻黑河某边防团机动步兵连官兵严寒中进行户外体能训练驻黑河某边防团机动步兵连官兵严寒中进行户外体能训练 }我们可以通过num参数控制数据集的数量进行训练。 微调澜舟科技开源的mengzi-t5-base做摘要生成数据集(只取5000条)nlpcc_2017: https://huggingface.co/datasets/supremezxc/nlpcc_2017model linkhttps://modelscope.cn/models/langboat/mengzi-t5-baselink: https://huggingface.co/Langboat/mengzi-t5-base孟子中文T5预训练生成模型与T5结构相同只有无监督数据训练不包含下游任务需要在特定任务上finetune后使用import os import platform import torch import torch.nn as nn from torch.utils.data import Dataset, DataLoader from datasets import load_from_disk from transformers import AdamW from transformers import T5Tokenizer, T5ForConditionalGeneration from logging_util import get_logger from rouge import Rougedevice cuda if torch.cuda.is_available() else cpu# 获取当前操作系统的名称 os_name platform.system() logger get_logger(model_namemengzi-t5-base)# 设置模型路径及数据集路径 if os_name Windows:model_dir rD:\python\models\langboat\meng_zi_t5data_dir rD:\python\datas\nlp_seq2seq\nlpcc_2017logger.info(当前执行环境是 Windows...) elif os_name Linux:model_dir r/root/autodl-fs/models/meng_zi_t5data_dir r/root/autodl-fs/data/nlp_ai/nlp_seq2seq/nlpcc_2017logger.info(当前执行环境是 Linux...) else:raise ValueError(当前执行环境不是 Windows 也不是 Linux)class Dataset(Dataset):def __init__(self, split, numNone):# 在线加载数据集(需外网环境)# dataset load_dataset(pathnlpcc_2017, splitsplit)# 我们可以将数据保存到本地磁盘下次利用load_from_disk直接从本地加载即可# dataset.save_to_disk(./nlpcc_2017)# 划分数据集为训练集和测试集dataset load_from_disk(dataset_pathdata_dir)# 选取4900条训练集、100条测试集split_dataset dataset.train_test_split(100, seed42)if num:# 离线加载数据集cpu环境取少量数据用来训练、测试模型dataset split_dataset[split].select(range(num))else:# 离线加载数据集dataset split_dataset[split]# 过滤掉太长的句子需要去掉CLS、SEPdef f(data):return len(data[content]) 512 - 2dataset dataset.filter(f)self.dataset datasetdef __len__(self):return len(self.dataset)def __getitem__(self, i):content self.dataset[i][content]title self.dataset[i][title]return content, title2.2 对数据集进行组装 主要就是在content前面加上特定的提示词然后调用tokenizer进行批处理 def get_collate_fn(tokenizer):def collate_fn(batch):contents [摘要生成: \n tup2[0] for tup2 in batch]original_labels [tup2[1] for tup2 in batch]# 特殊字符# 0 - pad# 1 - /s# 2 - unkinputs tokenizer(contents, max_length384, truncationTrue, return_tensorspt, paddingTrue)labels tokenizer(text_targetoriginal_labels, max_length64, truncationTrue, return_tensorspt, paddingTrue)return inputs, labelsreturn collate_fn2.3 构建模型 利用transformers库中的T5ForConditionalGeneration加载摘要生成的预训练模型 T5ForConditionalGeneration源码中实现了KV-cache有兴趣的可以阅读源码(主要是T5Attention中实现相对位置编码、KV-cache、以及门结构的前馈神经网络T5DenseGatedActDense的实现)。 T5模型中可以调用generate函数(transformers\generation\utils.py)这个函数中实现了8种采样的方法(如下代码所示)每种采样都有不同的配置参数具体可以看transformers\generation\configuration_utils.py中GenerationConfig类的参数解释。 # transformers\generation\configuration_utils.py class GenerationMode(ExplicitEnum):Possible generation modes, downstream of the [~generation.GenerationMixin.generate] method.# Non-beam methodsCONTRASTIVE_SEARCH contrastive_searchGREEDY_SEARCH greedy_searchSAMPLE sampleASSISTED_GENERATION assisted_generation# Beam methodsBEAM_SEARCH beam_searchBEAM_SAMPLE beam_sampleCONSTRAINED_BEAM_SEARCH constrained_beam_searchGROUP_BEAM_SEARCH group_beam_searchclass MengZiT5Model(nn.Module):def __init__(self):super().__init__()# 加载预训练模型self.model T5ForConditionalGeneration.from_pretrained(model_dir)def forward(self, inputs, labelsNone):# 1、encoder的input_ids和attention_maskinput_ids inputs[input_ids]attention_mask inputs[attention_mask]if labels is not None:# 2、decoder 的labelstrain_labels labels[input_ids].contiguous()train_labels_mask labels[attention_mask]# 3、decoder 的input_ids和attention_maskdecoder_input_ids train_labels.new_zeros(train_labels.shape)decoder_input_ids[..., 1:] train_labels[..., :-1].clone()decoder_attention_mask train_labels_mask.new_zeros(train_labels_mask.shape)decoder_attention_mask[..., 1:] train_labels_mask[..., :-1].clone()decoder_attention_mask[..., 0] 1# 4、送入模型进行预测outputs self.model(input_idsinput_ids, attention_maskattention_mask, decoder_input_idsdecoder_input_ids, decoder_attention_maskdecoder_attention_mask, labelstrain_labels)# 5、返回训练时候的Loss值return outputs.losselse:# 模型生成summary_ids self.model.generate(input_ids, num_beams4 # 束搜索法, no_repeat_ngram_size2 # 确保不重复, min_length10 # 长度限制, max_length64, early_stoppingTrue)# 将id转换为输出 summary_ids.shape [bs, length]outputs tokenizer.batch_decode(summary_ids, skip_special_tokensTrue)return outputs2.4 构造训练及测试函数 这里简单实现了模型的训练及评估的函数评估主要使用了指标rouge-1、rouge-2、rouge-l # 模型训练 def train(epochs, model, loader):model.to(device)lr 2e-5# 训练optimizer AdamW(model.parameters(), lrlr)model.train()for epoch in range(epochs):for step, (inputs, labels) in enumerate(loader):inputs inputs.to(device)labels labels.to(device)# 模型计算# [b, lens] - [b, lens, 8]loss model(inputs, labels)# 梯度下降loss.backward()optimizer.step()optimizer.zero_grad()if step % 10 0:print(fepoch {epoch}, step {step}, loss {loss:.4f})os.makedirs(./output, exist_okTrue)torch.save(model, ./output/meng_zi_t5_sft.pt)# 模型评估 def test():# 1、加载模型model_load torch.load(output/meng_zi_t5_sft.pt).to(device)model_load.eval()rouge Rouge()# 2、加载测试集test_loader DataLoader(datasetDataset(test),batch_size32,collate_fnget_collate_fn(tokenizertokenizer),shuffleFalse,drop_lastTrue)for step, (inputs, labels) in enumerate(test_loader):if step 2:breakwith torch.no_grad():# [b, lens] - [b, lens, 8]decode_preds model_load(inputs.to(device))decode_labels tokenizer.batch_decode(labels[input_ids].to(device), skip_special_tokensTrue)decode_preds [ .join(p) for p in decode_preds]decode_labels [ .join(l) for l in decode_labels]scores rouge.get_scores(decode_preds, decode_labels, avgTrue)r {rouge-1: scores[rouge-1][f],rouge-2: scores[rouge-2][f],rouge-l: scores[rouge-l][f],}logger.info(fsetp {step}, 评估结果\n{r})return rif __name__ __main__:# 1、加载分词器tokenizer T5Tokenizer.from_pretrained(model_dir, legacyFalse)# 2、加载训练数据train_loader DataLoader(datasetDataset(train),batch_size16,collate_fnget_collate_fn(tokenizertokenizer),shuffleTrue,drop_lastTrue)# 3、创建模型model MengZiT5Model()# 4、模型训练及评估train(epochs1, modelmodel, loadertrain_loader)test() # 模型评估# 5、对模型进行预测text 摘要生成: \n在经历了那段惊心动魄但又充满人情味的艰难时刻后32岁的埃里克森时隔1100天再次为国征战欧洲杯而且奉献了进球。丹麦队对垒斯洛文尼亚这场热度并不算高的小组赛首轮争夺因为一个人的出现得到了外界的关注他就是埃里克森。曼联中场在在第17分钟的进球帮助祖国球队取得了领先他也在经历上届欧洲杯的心脏骤停的遭遇之后实现了“王者归来”。尽管这次破门遗憾没能帮助丹麦队最终获得胜利但绰号“爱神”的埃里克森依然得到了全场乃至全世界球迷的祝福。inputs tokenizer(text, return_tensorspt)model_load torch.load(output/meng_zi_t5_sft.pt)model_load.eval()print(摘要内容\n, model_load(inputs))# 训练好的模型可以进行摘要生成 摘要内容[曼联32岁埃里克森时隔1100天再次为国征战欧洲杯,并奉献了进球。]3 mT5模型的推理 这里的mT5模型在下游任务上做了微调可以直接使用 model: iic/nlp_mt5_zero-shot-augment_chinese-baselink: https://modelscope.cn/models/iic/nlp_mt5_zero-shot-augment_chinese-base该模型在mt5模型基础上使用了大量中文数据进行训练并引入了零样本分类增强的技术使模型输出稳定性大幅提升。支持任务包含文本分类给定一段文本和候选标签模型可输出文本所属的标签。自然语言推理给定两段文本判断两者关系。阅读理解给定问题和参考文本输出问题的答案。问题生成给定答案和参考文本生成该答案对应的问题。摘要生成给定一段文本生成该文本的摘要。标题生成给定一段文本为其生成标题。评价对象抽取给定一段文本抽取该段文本的评价对象。翻译给定一段文本将其翻译成另一种语言。import torch import platform from transformers import T5Tokenizer, T5ForConditionalGeneration, T5Config# 获取当前操作系统的名称 os_name platform.system() device cuda:0 if torch.cuda.is_available() else cpu# 设置模型路径及数据集路径 if os_name Windows:model_dir rD:\\python\\models\\model-download\\iic\\nlp_mt5_zero-shot-augment_chinese-baseprint(当前执行环境是 Windows...) elif os_name Linux:model_dir r/root/autodl-fs/models/nlp_mt5_zero-shot-augment_chinese-baseprint(当前执行环境是 Linux...) else:raise ValueError(当前执行环境不是 Windows 也不是 Linux)# 1、加载tokenizer及预训练模型 tokenizer T5Tokenizer.from_pretrained(model_dir, legacyFalse) model T5ForConditionalGeneration.from_pretrained(model_dir) model.to(device)def t5inference(text, task_prefix, max_lengthNone, min_length1)::param text: 要生成摘要的文本:param task_prefix: 执行的任务:param max_length: 摘要的最大长度:return:# 准备前缀文本t5_prepared_text f{task_prefix}: textprint(input text: \n, t5_prepared_text)# 分词tokenized_text tokenizer.encode(t5_prepared_text, return_tensorspt).to(device)# 进行文本摘要# prepare_inputs_for_generationsummary_ids model.generate(tokenized_text,num_beams4, # 束搜索法no_repeat_ngram_size2, # 确保不重复min_lengthmin_length, # 长度限制max_lengthmax_length,early_stoppingTrue # 提前停止)# 将id转换为输出 summary_ids.shape [1, length]output tokenizer.decode(summary_ids[0], skip_special_tokensTrue)return outputdef t0():text “足球从未高于生死”这是3年前欧洲杯赛场上丹麦球员埃里克森心脏骤停时各路媒体报道该事件用的最多的表达。而在经历了那段惊心动魄但又充满人情味的艰难时刻后32岁的埃里克森时隔1100天再次为国征战欧洲杯而且奉献了进球。17日凌晨的欧洲杯小组赛埃里克森进球的那一刻感动和欣慰扑面而来。最终丹麦和斯洛文尼亚队1比1战平各取1分。丹麦队对垒斯洛文尼亚这场热度并不算高的小组赛首轮争夺因为一个人的出现得到了外界的关注他就是埃里克森。曼联中场在在第17分钟的进球帮助祖国球队取得了领先他也在经历上届欧洲杯的心脏骤停的遭遇之后实现了“王者归来”。尽管这次破门遗憾没能帮助丹麦队最终获得胜利但绰号“爱神”的埃里克森依然得到了全场乃至全世界球迷的祝福。output t5inference(text, task_prefix文本摘要, min_length20, max_length64)print(模型结果:\n, output)text 候选标签故事,房产,娱乐,文化,游戏,国际,股票,科技,军事,教育。文本内容他们的故事平静而闪光一代人奠定沉默的基石让中国走向繁荣。output t5inference(text, task_prefix文本分类, max_length64)print(模型结果:\n, output)text 如果日本沉没中国会接收日本难民吗output t5inference(text, task_prefix翻译成英文, max_length512)print(模型结果:\n, output)if __name__ __main__:# print(model.config)# print(model)t0()input text: 文本摘要: “足球从未高于生死”这是3年前欧洲杯赛场上丹麦球员埃里克森心脏骤停时各路媒体报道该事件用的最多的表达。而在经历了那段惊心动魄但又充满人情味的艰难时刻后32岁的埃里克森时隔1100天再次为国征战欧洲杯而且奉献了进球。17日凌晨的欧洲杯小组赛埃里克森进球的那一刻感动和欣慰扑面而来。最终丹麦和斯洛文尼亚队1比1战平各取1分。丹麦队对垒斯洛文尼亚这场热度并不算高的小组赛首轮争夺因为一个人的出现得到了外界的关注他就是埃里克森。曼联中场在在第17分钟的进球帮助祖国球队取得了领先他也在经历上届欧洲杯的心脏骤停的遭遇之后实现了“王者归来”。尽管这次破门遗憾没能帮助丹麦队最终获得胜利但绰号“爱神”的埃里克森依然得到了全场乃至全世界球迷的祝福。 模型结果:埃里克森:足球从未高于生死,爱神归来,为国征战input text: 文本分类: 候选标签故事,房产,娱乐,文化,游戏,国际,股票,科技,军事,教育。文本内容他们的故事平静而闪光一代人奠定沉默的基石让中国走向繁荣。 模型结果:文化input text: 翻译成英文: 如果日本沉没中国会接收日本难民吗 模型结果:will China accept Japanese refugees if Japan sinks?
http://www.dnsts.com.cn/news/137769.html

相关文章:

  • 网站推广策划书的特点有哪些杭州商城型网站建设
  • 网站后台管理员密码跨境电商运营主要做什么
  • 做一网站需要多少钱企业网站怎么做百度
  • 东莞做网站推广公司有做销售产品的网站有哪些
  • 湖北省建设工程人力资源网站免费门户网站制作
  • 光明网站开发质监站网址
  • 玉林电信网站备案做医美设计的网站
  • 焦作网站开发wordpress对接公众号
  • 沙田镇网站建设公司wordpress上传ftp设置密码
  • 邹城市网站建设如何配置网站服务器
  • 做牛仔裤的视频网站南宁网站建设哪家公司实力
  • 网站建设龙头企业网站维护公司广州
  • 网站名称大全南通网站制作公司
  • ps做网站顶部手机平台软件开发
  • 网站右侧虚代码建筑局网站
  • 反钓鱼网站建设期建企业网站一般多少钱
  • wordpress免费网页建站wordpress 弹窗
  • 高端手机网站设计开锁换锁公司网站模板
  • 中企动力销售怎么样seo自动推广工具
  • 备案网站建设方案书360网站建设官网
  • 潍坊网站排名工程公司网站模板下载
  • 推荐5家知名什么是优化设计
  • 成都专业网站设计免费咨询企业网站备案案例
  • 如何做网站卖连接做算命类网站违法吗?
  • 网站运营指标重庆360网络推广
  • 上海市场监督管理局网站网站模板在线制作
  • 曹县做网站建设成都微信网站建设
  • 厦门双模网站wordpress同步微博评论
  • 建设企业网站管理系统目的WordPress卡密充值代码
  • 网站模板带后台下载关东建设有限公司网站