赞
踩
https://github.com/huggingface/transformers
这就是hugging face的库
Huggingface Transformers 是基于一个开源基于 transformer 模型结构提供的预训练语言库,它支持 Pytorch,Tensorflow2.0,并且支持两个框架的相互转换。框架支持了最新的各种NLP预训练语言模型,使用者可以很快速的进行模型的调用,并且支持模型further pretraining 和 下游任务fine-tuning
该库是使用 BERT 等预训练模型的最常用的库,甚至超过了google等开源的源代码。它的设计原则保证了它支持各种不同的预训练模型,并且有统一的合理的规范。使用者可以很方便的进行模型的下载,以及使用。同时,它支持用户自己上传自己的预训练模型到Model Hub中,提供其他用户使用。对于NLP从业者,可以使用这个库,很方便地进行自然语言理解(NLU) 和 自然语言生成(NLG)任务的SOTA模型使用
BertTokenizer
from transformers import BertTokenizer tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')在实例化之后,我们就可以使用tokenizer对原始文本进行分词。
from transformers import BertTokenizer tokenizer = BertTokenizer.from_pretrained('bert-large-uncased') tokenizer.tokenize("A Titan RTX has 24GB of VRAM!")因为BERT的tokenizer用的是wordpiece,所有有些词会被拆分成多个token,用##来表示其并非单独存在
也可以直接对原始文本进行编码。
inputs = tokenizer("A Titan RTX has 24GB of VRAM!")
在内部就会自己带着分词操作了
还有一种方法是
encode
方法,它接受一个字符串作为参数,并返回一个由token id组成的列表。例如:
encoded_input = tokenizer.encode("A Titan RTX has 24GB of VRAM!") print(encoded_input)即
tokenizer("I loved reading the Hunger Games!").input_ids = tokenizer.encode("I loved reading the Hunger Games!")其中,101和102分别表示BERT模型中的[CLS]和[SEP]标记,其余的数字则是对应单词在BERT词典中的编号。
将编码转换为原词
tokenizer.convert_ids_to_tokens(input_ids) 或 tokenizer.decode(input_ids)还可以decode_batch()
单个id的话
self.tokenizer.convert_ids_to_tokens([1144])
整体的话
查看当前tokenizer的特殊字符
直接print当前tokenizer即可
tokenizer获取指定字符的编号
self.tokenizer.convert_tokens_to_ids('[SEP]')
对多个句子编码
可以看到,会自动添加上[SEP], 而且token_type_ids会有0,1的区分
注意这里的多个句子,就必须是多个字符串,如果是多个句子拼成一个字符串的话,那还是当作一个句子
AutoTokenizer
transformers.AutoTokenizer
是 Hugging Face Transformers 库中用于加载和实例化各种类型的 Tokenizer 的工具类。它可以根据输入的模型名称或文件路径自动识别对应的预训练模型,并返回相应的 Tokenizer 对象。使用
AutoTokenizer
可以避免手动指定使用的 Tokenizer 类型,从而简化了代码开发过程。不然我们bert模型的tokenizer是BertTokenizer,要用GPT的话就是GPT2Tokenizer......
以下代码演示了如何使用
AutoTokenizer
实例化一个 BERT Tokenizer:
from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained('bert-base-uncased') = from transformers import BertTokenizer tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')这段代码会自动从 Hugging Face Model Hub 上下载并加载名为
bert-base-uncased
的预训练模型,然后返回对应的 BERT Tokenizer 对象。
AutoTokenizer
支持加载各种类型的 Tokenizer,包括但不限于 BERT、GPT、RoBERTa 等。只需要将所需的 tokenizer 名称传递给from_pretrained()
方法即可。另外,该工具类还支持从本地文件加载 tokenizer,只需要传递 tokenizer 文件的路径即可,例如:
tokenizer = AutoTokenizer.from_pretrained('/path/to/tokenizer/directory')
这样就可以从指定路径加载 tokenizer 文件并实例化对应的 Tokenizer 对象了。
BertConfig
使用
BertConfig
可以方便地创建自定义的 BERT 模型,例如可以通过修改其中的某些超参数来改变模型的性能、规模和训练速度等。以下是一个示例:
from transformers import BertConfig # 创建一个自定义的 BERT 模型配置 my_config = BertConfig( vocab_size=10000, hidden_size=256, num_hidden_layers=6, num_attention_heads=8, intermediate_size=1024, max_position_embeddings=512 ) # 使用自定义的配置创建 BERT 模型 my_bert_model = BertModel(config=my_config)在上面的代码中,我们通过传递一些超参数来实例化了一个
BertConfig
对象,并将其传递给BertModel
的构造函数中,从而创建了一个具有自定义配置的 BERT 模型。除了上述示例中的超参数外,
BertConfig
还支持许多其他的配置选项,如学习率、dropout 率、是否进行 LayerNorm 等。可以根据具体情况调整不同的参数,以满足实际应用需求。tie_encoder_decoder_weights
tie_encoder_decoder_weights()
是 Hugging Face Transformers 库中的一个函数,它可以将编码器和解码器权重关联起来,使得在训练过程中它们共享相同的权重。在机器翻译任务中,通常会使用序列到序列模型,其中编码器将源语言句子编码为一个固定大小的向量表示,然后解码器使用该向量表示生成目标语言句子。由于这些模型需要在不同的输入和输出之间共享参数,因此
tie_encoder_decoder_weights()
函数允许我们共享编码器和解码器的权重,以便在训练过程中减少参数数量并提高模型性能。
BertModel
BertModel就是定义Bert的
BertModel = word embedding + BertEncoder + Pooler
包的位置
from transformers import BertModel, BertTokenizer # 加载预训练模型和 tokenizer model = BertModel.from_pretrained('bert-large-uncased') tokenizer = BertTokenizer.from_pretrained('bert-large-uncased') # 处理输入文本并进行编码 text = "This is a test sentence." input_ids = tokenizer.encode(text, add_special_tokens=True, return_tensors='pt') #input_ids是[bs,l] # 使用 BertModel 对输入进行编码 outputs = model(input_ids) # ipdb> outputs.keys() # odict_keys(['last_hidden_state', 'pooler_output']) last_hidden_state = outputs.last_hidden_state #[bs,l,dim] #也可以写作 last_hidden_state = outputs['last_hidden_state'] pooler_output = outputs.pooler_output #[bs,dim] #也可以写作 pooler_output = outputs['pooler_output']pooler_output是什么
pooled_output = self.pooler(outputs.last_hidden_state)
self.pooler就是fc+tanh
forward过程就是
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: # We "pool" the model by simply taking the hidden state corresponding # to the first token. first_token_tensor = hidden_states[:, 0] pooled_output = self.dense(first_token_tensor) pooled_output = self.activation(pooled_output) return pooled_output所以,pooler_output就是cls token
swin的pooler是adaptive pooling
pooler_output就是last_hidden_state的adaptive pooling之后的结果
如果想要输出中间层的结果
from transformers import BertModel, BertTokenizer # 加载预训练模型和 tokenizer model = BertModel.from_pretrained('bert-large-uncased') #24层 tokenizer = BertTokenizer.from_pretrained('bert-large-uncased') # 处理输入文本并进行编码 text = "This is a test sentence." input_ids = tokenizer.encode(text, add_special_tokens=True, return_tensors='pt') #input_ids是[bs,l] # 使用 BertModel 对输入进行编码 outputs = model( input_ids, output_hidden_states=True, # 是否输出所有隐层状态 ) # ipdb> outputs.keys() # odict_keys(['last_hidden_state', 'pooler_output', 'hidden_states']) #outputs.hidden_states是tuple,len为24+1 last_hidden_state = outputs.last_hidden_state #[bs,l,dim] #也可以写作 last_hidden_state = outputs['last_hidden_state'] pooler_output = outputs.pooler_output #[bs,dim] #也可以写作 pooler_output = outputs['pooler_output']outputs.hidden_states为什么len是layer数+1
第0层是word embedding, 以后就是每层的输出
BertModel作为decoder
BERT原本只是encoder,当add_cross_attention设为True时,此时BertModel就相当于Transformer decoder了
from transformers import BertConfig, BertModel # 定义模型配置,启用交叉注意力 config = BertConfig.from_pretrained( 'bert-base-uncased', add_cross_attention=True ) # 初始化 BertModel 实例 model = BertModel(config) # 获取主序列和交叉序列的输入 input_ids_main = ... input_ids_cross = ... # 获取主序列和交叉序列的注意力掩码 attention_mask_main = ... attention_mask_cross = ... # 通过 BertModel 进行前向计算,并获取输出 outputs = model( input_ids=input_ids_main, attention_mask=attention_mask_main, cross_attention_input_ids=input_ids_cross, cross_attention_mask=attention_mask_cross )
BertPredictionHeadTransform
就是一个predict head, 即fc层
这个就是用来做mask重建的
from transformers import BertConfig, BertPredictionHeadTransform config = BertConfig.from_pretrained('bert-base-uncased') prediction_head = BertPredictionHeadTransform(config) hidden_states = ... # BERT 模型的输出 logits = prediction_head(hidden_states)BERT的attention mask
Bert因为每个句子的长度不一致,所以每个句子都会被padding成max_len的长度,然后用attention_mask标识出哪些位置是padding的
image_attention就全是1
#self.text_decoder是BertLMHeadModel decoder_output = self.text_decoder(decoder_input_ids, #[bs,30] attention_mask = text.attention_mask, encoder_hidden_states = image_embeds, #[bs,197,168] encoder_attention_mask = image_atts, #[bs,197] labels = decoder_targets, #[bs, 30] return_dict = True, )这里的 image_atts是全1
这里的text.attention_mask即padding mask
BertLMHeadModel
它只是在LM的基础上加一个fc head,进行预测
是作为decoder
BertLMHeadModel具有添加的语言建模头部,可用于微调预训练的BERT模型以适应特定的NLP任务,例如文本分类或语言生成。该头部由一个线性层组成,将BERT模型的隐藏状态映射到所建模语言的词汇空间。在微调过程中,头部的参数会被更新,以优化在下游任务上的性能
from transformers import BertTokenizer, BertLMHeadModel, BertConfig tokenizer = BertTokenizer.from_pretrained('bert-base-cased') config = BertConfig.from_pretrained("bert-base-cased") model = BertLMHeadModel.from_pretrained('bert-base-cased', config=config) inputs = tokenizer("Hello, my dog is cute", return_tensors="pt") #inputs是[bs,len]->[1,8] outputs = model(**inputs) #outputs是CausalLMOutputWithCrossAttentions # outputs.keys()->odict_keys(['logits']) # outputs.logits是[bs,len,vocab_size]->[1,8,28996] prediction_logits = outputs.logitsBertLMPredictionHead 和 BertLMHeadModel的区别
BertLMPredictionHead和BertLMHeadModel都是Bert模型的一部分,用于预测下一个词语。
BertLMPredictionHead是一个用于训练时的头结构(head),它接受Bert模型的输出,并将其传递给一个全连接层,该层将Bert模型的隐藏状态投影到词汇表大小的空间中,并使用softmax函数进行归一化。在预测下一个词语时,我们可以通过计算这个全连接层的softmax输出,从而得到下一个预测的词语。此外,BertLMPredictionHead还包括一些额外的辅助损失,比如预测掩码位置的损失等。
BertLMHeadModel则是一个完整的Bert模型加上一个BertLMPredictionHead头结构组成的模型。在这个模型中,Bert模型首先对输入文本进行编码,然后将其输出传递给BertLMPredictionHead头结构,从而生成下一个词语的预测。因此,如果你只需要预测下一个词语,可以使用BertLMPredictionHead,如果需要对整个文本序列进行预测,可以使用BertLMHeadModel。
总之,BertLMPredictionHead是一个用于训练阶段的头结构,它负责将Bert模型的输出转换为下一个词语的预测,而BertLMHeadModel是一个完整的Bert模型加上一个BertLMPredictionHead头结构,用于对整个文本序列进行预测
BertForMaskedLM
BertForMaskedLM
是 Hugging Face Transformers 库中的一个预训练模型类,用于掩码语言建模任务。该模型是基于 Google 的 BERT(Bidirectional Encoder Representations from Transformers)模型进行训练的,在多个自然语言处理任务上都取得了出色的结果。在掩码语言建模任务中,模型将输入句子中的某些单词替换为掩码符号
[MASK]
,并尝试预测这些单词的正确值。因此,对于给定的输入句子,输出将是每个掩码位置上可能的单词的概率分布。以下是使用
BertForMaskedLM
进行掩码语言建模的简单示例代码:
from transformers import BertTokenizer, BertForMaskedLM # 加载 BERT tokenizer 和 模型 tokenizer = BertTokenizer.from_pretrained('bert-base-uncased') model = BertForMaskedLM.from_pretrained('bert-base-uncased') # 给定句子,准备好输入 sentence = "I have a [MASK] named Charlie." input_ids = tokenizer.encode(sentence, return_tensors='pt') # 执行推断 (inference) ,得到预测分数分布 with torch.no_grad(): output = model(input_ids) # 解码预测分数分布,获取 top k 个预测标记及其概率 k = 5 probs = torch.nn.functional.softmax(output[0], dim=-1)[0] top_k = torch.topk(probs, k=k) for i, pred_idx in enumerate(top_k.indices): pred_prob = top_k.values[i] pred_token = tokenizer.convert_ids_to_tokens([pred_idx])[0] print("Top {} Prediction: '{}', Probability: {:2%}".format(i+1, pred_token, pred_prob.item()))在上述示例中,我们首先加载了 BERT tokenizer 和
BertForMaskedLM
模型,并使用 tokenizer 对输入句子进行编码。我们随后使用模型对编码后的输入执行推断 (inference),得到了每个掩码位置上可能的标记及其概率。最后,我们将获取的概率分布解码回实际的单词,并输出 top k 个预测标记及其概率。
BertLMHeadModel和BertGeneration的区别
在 Transformers 库中,
BertLMHeadModel
和BertGeneration
都是基于 BERT 模型的语言生成模型,但它们有一些不同之处。首先,
BertLMHeadModel
主要用于语言建模任务,它预测给定一个句子的下一个单词是什么,即给定前文,预测接下来的词汇。而BertGeneration
则是一个通用的文本生成模型,它可以生成一段指定长度的文本,而不是像BertLMHeadModel
那样只生成下一个单词。其次,
BertLMHeadModel
和BertGeneration
的输入和输出也有所不同。BertLMHeadModel
的输入是一个经过 BERT 编码器编码的文本序列,它的输出是预测下一个单词的概率分布,可以使用BertForMaskedLM
预测其中的一个词。而BertGeneration
的输入是一个编码器的输出,它的输出是一段指定长度的文本,可以使用BertTokenizer
将输出的 ids 转化为文本。另外,
BertGeneration
还支持更多的文本生成任务,例如根据一个指定的主题或者输入的提示文本生成一段连贯的文本,这些任务是BertLMHeadModel
不支持的。总之,
BertLMHeadModel
更适合于语言建模任务,而BertGeneration
则更通用,可以应用于各种文本生成任务。
BertGenerationDecoder
from transformers import AutoTokenizer, BertGenerationDecoder, BertGenerationConfig import torch tokenizer = AutoTokenizer.from_pretrained("google/bert_for_seq_generation_L-24_bbc_encoder") config = BertGenerationConfig.from_pretrained("google/bert_for_seq_generation_L-24_bbc_encoder") config.is_decoder = True model = BertGenerationDecoder.from_pretrained( "google/bert_for_seq_generation_L-24_bbc_encoder", config=config )
Swin Transformer
from transformers import AutoImageProcessor, SwinModel import torch import cv2 import numpy as np import requests url = r'http://images.cocodataset.org/val2017/000000039769.jpg' resp = requests.get(url, stream=True).raw image = np.asarray(bytearray(resp.read()), dtype="uint8") image = cv2.imdecode(image, cv2.IMREAD_COLOR) #[h,w,c] # import ipdb;ipdb.set_trace() image_processor = AutoImageProcessor.from_pretrained( "swin-tiny-patch4-window7-224" ) model = SwinModel.from_pretrained( "swin-tiny-patch4-window7-224" ) inputs = image_processor(image, return_tensors="pt") #inputs.pixel_value [bs,3,224,224] with torch.no_grad(): outputs = model( **inputs, output_hidden_states=True, ) # ipdb> outputs.keys() # odict_keys(['last_hidden_state', 'pooler_output', 'hidden_states', 'reshaped_hidden_states']) #outputs.last_hidden_state是[bs,49,768] #outputs.pooler_output是[bs.768] #outputs.hidden_states是tuple, len为5 # outputs.hidden_states[0]是[bs,3136,96] # outputs.hidden_states[1]是[bs,784,192] # outputs.hidden_states[2]是[bs,196,384] # outputs.hidden_states[3]是[bs,49,768] # outputs.hidden_states[4]是[bs,49,768] # 这里和原swin transformer不太一样 # outputs.hidden_states[0]只是embedding_output # embedding_output过swinencoder才得到[1]-[4]
VisionEncoderDecoderModel
from transformers import VisionEncoderDecoderModel self.imgcaption_model = VisionEncoderDecoderModel.from_encoder_decoder_pretrained( # "swin-base-patch4-window7-224-in22k", "swin-tiny-patch4-window7-224", "Bio_ClinicalBERT", ) self.imgcaption_model.config.eos_token = self.tokenizer.sep_token_id self.imgcaption_model.config.decoder_start_token_id = self.tokenizer.cls_token_id self.imgcaption_model.config.bos_token_id = self.tokenizer.cls_token_id self.imgcaption_model.config.pad_token_id = self.tokenizer.pad_token_id self.imgcaption_model.decoder.bos_token_id = self.tokenizer.cls_token_id self.imgcaption_model.decoder.decoder_start_token_id = self.tokenizer.cls_token_id self.imgcaption_model.decoder.eos_token_id = self.tokenizer.sep_token_id self.imgcaption_model.decoder.pad_token_id = self.tokenizer.pad_token_id pixel_values = batch['images'] outputs = self.imgcaption_model( pixel_values = pixel_values, #[bs,64,128] # attention_mask=padding_mask, #[bs,112] labels = batch["impression_caption_ids"], #[bs,112] decoder_attention_mask = batch["impression_attention_mask"], )也可以分拆开
from transformers import VisionEncoderDecoderModel self.imgcaption_model = VisionEncoderDecoderModel.from_encoder_decoder_pretrained( # "swin-base-patch4-window7-224-in22k", "swin-tiny-patch4-window7-224", "Bio_ClinicalBERT", ) self.imgcaption_model.config.eos_token = self.tokenizer.sep_token_id self.imgcaption_model.config.decoder_start_token_id = self.tokenizer.cls_token_id self.imgcaption_model.config.bos_token_id = self.tokenizer.cls_token_id self.imgcaption_model.config.pad_token_id = self.tokenizer.pad_token_id self.imgcaption_model.decoder.bos_token_id = self.tokenizer.cls_token_id self.imgcaption_model.decoder.decoder_start_token_id = self.tokenizer.cls_token_id self.imgcaption_model.decoder.eos_token_id = self.tokenizer.sep_token_id self.imgcaption_model.decoder.pad_token_id = self.tokenizer.pad_token_id pixel_values = batch['images'] captioning_encoder_outputs = self.imgcaption_model.get_encoder()( pixel_values = pixel_values, output_hidden_states=True, ) captioning_outputs = self.imgcaption_model( # pixel_values=pixel_values, #[bs,64,128] encoder_outputs = captioning_encoder_outputs, # attention_mask=padding_mask, #[bs,112] labels=batch["impression_caption_ids"], #[bs,112] decoder_attention_mask = batch["impression_attention_mask"], output_hidden_states = True, )既然可以分拆开,那也可以img encoder用我们自己的,即不用huggingface的
global_image_features, \ SwinBase_dict_features = self.img_encoder_q( batch["images"] ) global_image_features = self.global_image_projection_module(global_image_features) global_image_features_projection = F.normalize(global_image_features, dim=-1) last_hidden_state = self.global_image_projection_module(SwinBase_dict_features['SwinBase_8x'].reshape(-1,d)).reshape(batch_size,l,-1) captioning_encoder_outputs_ = BaseModelOutputWithPooling( last_hidden_state = last_hidden_state, pooler_output = global_image_features_projection, # hidden_states = captioning_encoder_outputs.hidden_states, ) captioning_outputs = self.imgcaption_model( encoder_outputs = captioning_encoder_outputs_, labels=batch["impression_caption_ids"], #[bs,112] decoder_attention_mask = batch["impression_attention_mask"], output_hidden_states = True, )
BaseModelOutput
from transformers.modeling_outputs import BaseModelOutput,BaseModelOutputWithPooling
保存模型
我们之前都是load huggingface上的模型权重,如果是想保存自己的 & 以后加载使用呢
# save model.save_pretrained("mybert2bert") # load model = EncoderDecoderModel.from_pretrained("mybert2bert")
RoBERTa相关
Hugging Face Transformers 是一个流行的自然语言处理库,它提供了一个易于使用的 API 来加载和使用预训练的语言模型。下面是一些关于 Hugging Face Transformers 中 RoBERTa 的函数的说明:
RobertaModel
: 这个函数用于加载预训练的 RoBERTa 模型。它返回一个RobertaModel
对象,可以用来获取模型的输出。
RobertaTokenizer
: 这个函数用于加载 RoBERTa 模型使用的词汇表,可以用于将文本转换成模型可以理解的形式。
RobertaForSequenceClassification
: 这个函数用于加载一个预训练的 RoBERTa 模型,用于文本分类任务。它使用一个线性层来将模型的输出映射到分类标签上。
RobertaForQuestionAnswering
: 这个函数用于加载一个预训练的 RoBERTa 模型,用于问答任务。它使用一个线性层来将模型的输出映射到答案的起始和结束位置。
RobertaForMaskedLM
: 这个函数用于加载一个预训练的 RoBERTa 模型,用于填空任务。它将模型的输出映射到词汇表中的一个词。这些函数可以帮助您使用 RoBERTa 模型来解决各种自然语言处理任务。
GPT相关
Hugging Face Transformers 是一个流行的自然语言处理库,它提供了一个易于使用的 API 来加载和使用预训练的语言模型。下面是一些关于 Hugging Face Transformers 中 GPT 的函数的说明:
GPT2Model
: 这个函数用于加载预训练的 GPT-2 模型。它返回一个GPT2Model
对象,可以用来获取模型的输出。
GPT2Tokenizer
: 这个函数用于加载 GPT-2 模型使用的词汇表,可以用于将文本转换成模型可以理解的形式。
GPT2LMHeadModel
: 这个函数用于加载一个预训练的 GPT-2 模型,用于生成任务(text generation)。它使用一个线性层来将模型的输出映射到词汇表上。
GPT2DoubleHeadsModel
: 这个函数用于加载一个预训练的 GPT-2 模型,用于问答任务。它使用两个线性层来将模型的输出映射到答案的起始和结束位置。
GPT2ForSequenceClassification
: 这个函数用于加载一个预训练的 GPT-2 模型,用于文本分类任务。它使用一个线性层将模型的输出映射到分类标签上。这些函数可以帮助您使用 GPT 模型来解决各种自然语言处理任务。
TextIteratorStreamer
实现LLMs流式输出
- TextStreamer: 能够在stdout中流式输出结果
- TextIteratorStreamer:能够在自定义loop中进行操作
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。