IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> paper_longformer1 -> 正文阅读

[人工智能]paper_longformer1

自顶向下,整体到细节

一、首先找到对应的是属于哪个范式的论文

机器学习(特征工程),神经网络(结构工程)、预训练(目标函数)、预训练提示预测(提示),每个范式都有相应的典型代表
目前预训练比较典型,分为,编码、解码、编码-解码
在这里插入图片描述

二、严格按照步骤执行

在这里插入图片描述

三 tokenizer也是整体到细节

一共这几个类型,每个都有相应的代表
在这里插入图片描述
sentencepiece wordpiece bpe

在这里插入图片描述
考虑到对外网的屏蔽直接在colab,本地写好代码直接上操作即可

tokenizer对齐

"""
colab上运行安装包
!pip install datasets transformers[sentencepiece] paddlenlp paddlepaddle-gpu paddlepaddle
"""

import paddlenlp
import transformers
import numpy as np


text = 'welcome to use paddlenlp'
torch_tokenizer = transformers.LongformerTokenizer.from_pretrained('allenai/longformer-base-4096')
torch_tokenizer_rt = transformers.RobertaTokenizer.from_pretrained('roberta-base')
paddle_tokenizer = paddlenlp.transformers.RobertaTokenizer.from_pretrained('roberta-wwm-ext')
torch_inputs = torch_tokenizer(text)
torch_inputs_rt = torch_tokenizer_rt(text)
paddle_inputs = paddle_tokenizer(text)
print(torch_inputs_rt)
print('*****************************************************')
print(torch_inputs)
print('*****************************************************')
print(paddle_inputs)

model对齐

import paddlenlp
import transformers
import torch
import paddle
import numpy as np

text = 'welcome to use paddlenlp'
torch_tokenizer = transformers.AlbertTokenizer.from_pretrained('albert-base-v2')
paddle_tokenizer = paddlenlp.transformers.AlbertTokenizer.from_pretrained('albert-base-v2')
torch_inputs = torch_tokenizer(text)
paddle_inputs = paddle_tokenizer(text)
torch_inputs = {k: torch.tensor([v]) for (k, v) in torch_inputs.items()}
paddle_inputs = {k: paddle.to_tensor([v]) for (k, v) in paddle_inputs.items()}

torch_model = transformers.AlbertModel.from_pretrained('albert-base-v2')
torch_model.eval()
torch_outputs_logits = torch_model(**torch_inputs)[0]
torch_array = torch_outputs_logits.cpu().detach().numpy()

paddle_model = paddlenlp.transformers.AlbertModel.from_pretrained('albert-base-v2')
paddle_model.eval()
paddle_outputs_logits = paddle_model(**paddle_inputs)[0]
paddle_array = paddle_outputs_logits.numpy()

diff = torch_array - paddle_array
print(np.amax(abs(diff)))

数据类型的各种直观的转换

各种数据类型的转换,一开始文本转换成id的类型,是python数据类型字典,列表这些
后面输入到模型需要把python数据类型转换成tensor数据类型
模型输出的还是tensor,最后转换成numpy数据类型做进一步比对运算

模型转换说明

都是字典而已

PyTorch和Paddle都是通过序列化和反序列化模型的 state dict (状态字典)来进行参数权重的存储和加载的。 state dict 从数据结构上来看就是一个字典(比如Python中的dict), 其中key是模型参数的名称(数据类型为string),而value则为key所对应的值(数据类型为Tensor)。 参数存储时,先获取目标对象的 state dict ,然后将 state dict 存储至磁盘; 参数载入时,先从磁盘载入保存的 state dict ,然后通过 set_state_dict() 方法配置到目标对象中。

只是一个名字

按照约定俗成的命名规则,Paddle框架保存的模型文件名一般后缀为 ‘.pdparams’ , PyTorch框架保存的模型文件名一般后缀为 ‘.pt’ 、 ‘.pth’ 或者 ‘.bin’ 。 虽然后缀并不影响模型的保存和加载,但我们一般都会遵循这个命名规范。

一个预训练模型的结构一定包含预训练阶段所有的模型结构,把预训练的任务弄清楚

pooler 模块
pooler模块在最后一层encoder之后,是我们对最后一层encoder输出的池化操作,

cls 模块
cls模块是我们计算mlm(masked language model)和next sentence prediction(nsp)任务的结构。 'cls.predictions’开头的参数是我们做mlm任务时的参数,'cls.seq_relationship’开头的参数是我们做nsp预测任务时的参数。

pytorch模型参数是ordered_dict,paddle是dict

两者的存储是相似的,PyTorch里使用的是python中的ordered_dict来存储模型的参数状态, 在Paddle中则使用的是python中的dict来来进行存储。

paddle的线性层是和pytorch是互为转置的

bert.encoder.layer.0.intermediate.dense.weight 和 bert.encoder.layers.0.linear1.weight 这两个keys是相对应的一组参数名,但是他们的values形状却不相同;前者是 [3072, 768] , 后者是 [768, 3072] ,两者刚好是一个转置的关系。这是因为PyTorch对于 nn.Linear 模块的保存是将权重的shape进行转置后保存的。 所以在我们进行 state dict 转换的时候,需要注意做好shape的转换(例如将PyTorch模型里 nn.Linear层对应的参数权重转置处理后生成Paddle的参数权重)。

注意还存在参数一对多和多对一的情况

有些模型结构可能在实现时对参数的处理有差异导致存在参数的拆分或者合并等操作, 此时我们需要进行参数多对一或者一对多的映射,同时将对应的values拆分或者合并。

注意对齐是预测前向而已,一定要配置eval状态,排除dropout

前向精度的对齐十分简单,我们只需要保证两者输入是一致的前提下,观察得到的输出是否一致。 这里有几个注意事项,我们运行推理时需要打开eval模式,设置dropout为0等操作去除随机性造成的影响。

配置文件,就是相关的超参数配置是一样的

除了得到的模型权重文件,我们还需要准备模型配置文件。将模型权重文件(model_state.pdparams)和模型配置文件(model_config.json) 这两个文件放在同一个路径下,我们就可以进行模型前向精度的对齐验证,下面提供了bert模型对齐前向精度的代码示

pytorch是直接tokenizer就得到张量,可以直接输入模型

torch_inputs = torch_tokenizer(text, return_tensors="pt")
torch_outputs = torch_model(**torch_inputs)

paddle得到的是python dict类型,所以要做转换

paddle_inputs = paddle_tokenizer(text)
paddle_inputs = {k:paddle.to_tensor([v]) for (k, v) in paddle_inputs.items()}
paddle_outputs = paddle_model(**paddle_inputs)
{'input_ids': [0, 605, 42557, 7, 304, 21775, 8476, 39031, 2], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1]} <class 'transformers.tokenization_utils_base.BatchEncoding'>
*****************************************************
{'input_ids': [101, 12759, 8228, 11927, 10257, 8168, 11407, 10986, 102], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0]} <class 'dict'>

在这里插入图片描述

!wget https://cdn-lfs.huggingface.co/bert-base-uncased/097417381d6c7230bd9e3557456d726de6e83245ec8b24f529f60198a67b203a

在这里插入图片描述

通过上面的路径方式在colab上快速下载和验证,能达到1秒10多M

权重转换

import paddle
import torch
import numpy as np

torch_model_path = "pytorch_model.bin"
torch_state_dict = torch.load(torch_model_path)

paddle_model_path = "bert_base_uncased.pdparams"
paddle_state_dict = {}

# State_dict's keys mapping: from torch to paddle
keys_dict = {
    # about embeddings
    "embeddings.LayerNorm.gamma": "embeddings.layer_norm.weight",
    "embeddings.LayerNorm.beta": "embeddings.layer_norm.bias",

    # about encoder layer
    'encoder.layer': 'encoder.layers',
    'attention.self.query': 'self_attn.q_proj',
    'attention.self.key': 'self_attn.k_proj',
    'attention.self.value': 'self_attn.v_proj',
    'attention.output.dense': 'self_attn.out_proj',
    'attention.output.LayerNorm.gamma': 'norm1.weight',
    'attention.output.LayerNorm.beta': 'norm1.bias',
    'intermediate.dense': 'linear1',
    'output.dense': 'linear2',
    'output.LayerNorm.gamma': 'norm2.weight',
    'output.LayerNorm.beta': 'norm2.bias',

    # about cls predictions
    'cls.predictions.transform.dense': 'cls.predictions.transform',
    'cls.predictions.decoder.weight': 'cls.predictions.decoder_weight',
    'cls.predictions.transform.LayerNorm.gamma': 'cls.predictions.layer_norm.weight',
    'cls.predictions.transform.LayerNorm.beta': 'cls.predictions.layer_norm.bias',
    'cls.predictions.bias': 'cls.predictions.decoder_bias'
}


for torch_key in torch_state_dict:
    paddle_key = torch_key
    for k in keys_dict:
        if k in paddle_key:
            paddle_key = paddle_key.replace(k, keys_dict[k])

    if ('linear' in paddle_key) or ('proj' in  paddle_key) or ('vocab' in  paddle_key and 'weight' in  paddle_key) or ("dense.weight" in paddle_key) or ('transform.weight' in paddle_key) or ('seq_relationship.weight' in paddle_key):
        paddle_state_dict[paddle_key] = paddle.to_tensor(torch_state_dict[torch_key].cpu().numpy().transpose())
    else:
        paddle_state_dict[paddle_key] = paddle.to_tensor(torch_state_dict[torch_key].cpu().numpy())

    print("torch: ", torch_key,"\t", torch_state_dict[torch_key].shape)
    print("paddle: ", paddle_key, "\t", paddle_state_dict[paddle_key].shape, "\n")

paddle.save(paddle_state_dict, paddle_model_path)

在权重转换好的基础上,还有底层tokenizer和model代码已经编写完的情况下,就可以验证代码编写和权重转换是否正确了。

随机一个输入验证是否转换对齐

text = "Welcome to use paddle paddle and paddlenlp!"
torch_model_name = "bert-base-uncased"
paddle_model_name = "bert-base-uncased"

# torch output
import torch
import transformers
from transformers.models.bert import *

# torch_model = BertForPreTraining.from_pretrained(torch_model_name)
torch_model = BertModel.from_pretrained(torch_model_name)
torch_tokenizer = BertTokenizer.from_pretrained(torch_model_name)
torch_model.eval()

torch_inputs = torch_tokenizer(text, return_tensors="pt")
torch_outputs = torch_model(**torch_inputs)

torch_logits = torch_outputs[0]
torch_array = torch_logits.cpu().detach().numpy()
print("torch_prediction_logits shape:{}".format(torch_array.shape))
print("torch_prediction_logits:{}".format(torch_array))


# paddle output
import paddle
import paddlenlp
from paddlenlp.transformers.bert.modeling import *
import numpy as np

# paddle_model = BertForPretraining.from_pretrained(paddle_model_name)
paddle_model = BertModel.from_pretrained(paddle_model_name)
paddle_tokenizer = BertTokenizer.from_pretrained(paddle_model_name)
paddle_model.eval()

paddle_inputs = paddle_tokenizer(text)
paddle_inputs = {k:paddle.to_tensor([v]) for (k, v) in paddle_inputs.items()}
paddle_outputs = paddle_model(**paddle_inputs)

paddle_logits = paddle_outputs[0]
paddle_array = paddle_logits.numpy()
print("paddle_prediction_logits shape:{}".format(paddle_array.shape))
print("paddle_prediction_logits:{}".format(paddle_array))


# the output logits should have the same shape
assert torch_array.shape == paddle_array.shape, "the output logits should have the same shape, but got : {} and {} instead".format(torch_array.shape, paddle_array.shape)
diff = torch_array - paddle_array
print(np.amax(abs(diff)))

下游任务fine-tuning验证(可选)

当我们对齐前向精度时,一般来说我们的模型转换就已经成功了。我们还可以运行下游任务fine-tuning进行double check。 同样的,我们需要设置相同的训练数据,相同的训练参数,相同的训练环境进行fine-tuning来对比两者的收敛性以及收敛指标。这个就是复现原论文了。

一、复现这还是第一阶段,二、更改网络是第二阶段,三、自己创造网络结构就是第三阶段了

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章           查看所有文章
加:2021-09-12 20:40:43  更:2021-09-12 20:41:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 15:27:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码