transformers库使用--模型构建

1. GPT2相关模型

1.1 GPT2模型

  • transformers.GPT2Model

简介: 最原始的GPT2模型(bare GPT2),transformer输出的hidden_state后不接任何特殊的网络层。该模型继承PreTrainedModel

使用:

from transformers import GPT2PreTrainedModel, GPT2Model, GPT2Config
config = GPT2Config()
# config = GPT2Config.from_json_file(path) # 从json文件中加载配置
# config = GPT2Config.from_pretrained(model_dir)
# config = GPT2Config.from_dict(dict_obj) # 从字典加载

# transformer = GPT2Model.from_pretrained(model_dir) # 直接从指定保存的模型目录加载模型
transformer = GPT2Model(config) # 未加载预训练参数,需要用torch.load加载参数
transformer_outputs = transformer(
            input_ids,
            attention_mask=attention_mask,
            token_type_ids=token_type_ids,
            position_ids=position_ids,
            head_mask=head_mask,
            inputs_embeds=inputs_embeds,
        )

输入参数

forward(input_ids=None, 
		past_key_values=None, 
		attention_mask=None, 
		token_type_ids=None,
		position_ids=None, 
		head_mask=None, 
		inputs_embeds=None, 
		encoder_hidden_states=None, 
		encoder_attention_mask=None, 
		use_cache=None, 
		output_attentions=None, 
		output_hidden_states=None, 
		return_dict=None)
  • input_ids (torch.LongTensor of shape (batch_size, input_ids_length)) 输入序列中单词在词表中的索引
  • attention_mask (torch.FloatTensor of shape (batch_size, sequence_length), optional) 对padding的词(索引)进行mask,防止在padding的词上进行attention操作
  • token_type_ids (torch.LongTensor of shape (batch_size, input_ids_length) 用于标记输入的token是属于第一句话还是第二个句子,0代表当前单词属于第一句子,1表示属于第二句子
  • position_ids (torch.LongTensor of shape (batch_size, sequence_length), optional)
    输入句子每个单词在position embedding中的位置索引

返回值
transformer_outputs[0]是最后一层隐藏层(hidden state),其余的目前不清楚

源码解读
GPT2 Model source

# 片段1
if position_ids is None:
    position_ids = torch.arange(past_length, input_shape[-1] + past_length, dtype=torch.long, device=device)
    position_ids = position_ids.unsqueeze(0).view(-1, input_shape[-1])

从上面可以看出当不传入位置embedding时,会自动生成position embedding(相对位置),而对于attention_mask, token_type_ids参数必须自己传入

# 片段2
return BaseModelOutputWithPastAndCrossAttentions(
            last_hidden_state=hidden_states,
            past_key_values=presents,
            hidden_states=all_hidden_states,
            attentions=all_self_attentions,
            cross_attentions=all_cross_attentions,
        )

从上面这个片段中可以看出返回的只有hidden state, attention等信息,并没有loss等,而输入中也没有label, 所以此处GPT2Model仅仅是transformer模型,输出的是各个字词的编码,比较常用的是3.2GPT2LMHeadModel,它包含了语言模型

1.2 GPT2语言模型

  • transformers.GPT2LMHeadModel

简介: 在transformer输出的后面接了一个语言模型(一个与输入embedding的线性层)

输入参数:
forward(input_ids=None, past_key_values=None, attention_mask=None, token_type_ids=None, position_ids=None, head_mask=None, inputs_embeds=None, encoder_hidden_states=None, encoder_attention_mask=None, labels=None, use_cache=None, output_attentions=None, output_hidden_states=None, return_dict=None)

  • input_ids (torch.LongTensor of shape (batch_size, input_ids_length)) : 输入序列中单词在词表中的索引
  • attention_mask (torch.FloatTensor of shape (batch_size, sequence_length), optional) : 对padding的词(索引)进行mask,防止在padding的词上进行attention操作,Mask的值为0或1,1表示该词没有被mask,0表示该词被mask
  • token_type_ids (torch.LongTensor of shape (batch_size, input_ids_length): 用于标记输入的token是属于第一句话还是第二个句子,0代表当前单词属于第一句子,1表示属于第二句子
  • position_ids (torch.LongTensor of shape (batch_size, sequence_length), optional):
    输入句子每个单词在position embedding中的位置索引
  • labels (torch.LongTensor of shape (batch_size, sequence_length), optional): 语言模型的label,label可以设置成input_ids一样,它将会在模型内部进行转换成真正的label,但是indices从[-100, 0, …, vocabsize]中选择,所有被设置成-100的label会被忽略,将只会计算哪些不是-100的损失

返回值

  • loss (torch.FloatTensor of shape (1,))语言模型的损失(预测下一个单词) 当设置了输入参数label,才会返回该值
  • logits (torch.FloatTensor of shape (batch_size, sequence_length, config.vocab_size)) 语言模型的预测得分(softmax之前词表中每个词的得分)
  • hidden_states (tuple(torch.FloatTensor), optional) 是一个tuple, 一个是输出的embedding,另一个是每一层的输出)只有在输入参数output_hidden_states=True时才会被返回

使用实例

import torch
from transformers import GPT2Tokenizer, GPT2LMHeadModel

tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
model = GPT2LMHeadModel.from_pretrained('gpt2')

inputs = tokenizer("Hello, my dog is cute", return_tensors="pt")
outputs = model(**inputs, labels=inputs["input_ids"])
loss = outputs.loss
logits = outputs.logits

源码解读

loss = None
if labels is not None:
    # Shift so that tokens < n predict n
    shift_logits = lm_logits[..., :-1, :].contiguous()
    shift_labels = labels[..., 1:].contiguous()
    # Flatten the tokens
    loss_fct = CrossEntropyLoss()
    loss = loss_fct(shift_logits.view(-1, shift_logits.size(-1)), shift_labels.view(-1))

从上面可看到可以将label设置成label=input_ids, 因为在模型内部会重新将label进行shift操作得到真正的label

return CausalLMOutputWithCrossAttentions(
            loss=loss,
            logits=lm_logits,
            past_key_values=transformer_outputs.past_key_values,
            hidden_states=transformer_outputs.hidden_states,
            attentions=transformer_outputs.attentions,
            cross_attentions=transformer_outputs.cross_attentions,
        )

该片段展示了返回值

1.3 双头GPT2

  • GPT2DoubleHeadsModel

简介

该模型包含语言模型和多分类两个任务

输入参数

forward(input_ids=None, past_key_values=None, attention_mask=None, token_type_ids=None, position_ids=None, head_mask=None, inputs_embeds=None, mc_token_ids=None, labels=None, mc_labels=None, use_cache=None, output_attentions=None, output_hidden_states=None, return_dict=None, **kwargs)

大部分参数与GPT2中一样

  • mc_token_ids (torch.LongTensor of shape (batch_size, num_choices)) 每个输入序列用于分类的token id, 默认是最后一个token
  • labels (torch.LongTensor of shape (batch_size, sequence_length)) 语言模型的标签,可以设置成label=input_ids

源码解读

mc_loss = None
if mc_labels is not None:
    loss_fct = CrossEntropyLoss()
    mc_loss = loss_fct(mc_logits.view(-1, mc_logits.size(-1)), mc_labels.view(-1))
lm_loss = None
if labels is not None:
    shift_logits = lm_logits[..., :-1, :].contiguous()
    shift_labels = labels[..., 1:].contiguous()
    loss_fct = CrossEntropyLoss()
    lm_loss = loss_fct(shift_logits.view(-1, shift_logits.size(-1)), shift_labels.view(-1))

如上包含了多分类和语言模型的两个任务

return GPT2DoubleHeadsModelOutput(
            loss=lm_loss,
            mc_loss=mc_loss,
            logits=lm_logits,
            mc_logits=mc_logits,
            past_key_values=transformer_outputs.past_key_values,
            hidden_states=transformer_outputs.hidden_states,
            attentions=transformer_outputs.attentions,
        )

返回值如上,后续可以将lm_loss和mc_loss合并进行联合训练

2. BERT相关模型

2.1 transformers.BertModel(config, add_pooling_layer=True)

简介

这是最原始的bert模型,transformer输出hidden_states,后面没有接任何特殊任务。

输入参数

forward(input_ids=None, 
        attention_mask=None, 
        token_type_ids=None, 
        position_ids=None, 
        head_mask=None, 
        inputs_embeds=None, 
        encoder_hidden_states=None,
        encoder_attention_mask=None,
        past_key_values=None, 
        use_cache=None, 
        output_attentions=None,
        output_hidden_states=None, 
        return_dict=None)
  • input_ids (torch.LongTensor of shape (batch_size, sequence_length)) 输入序列的id
  • attention_mask (torch.FloatTensor of shape (batch_size, sequence_length), optional) 为了避免在padding token 上执行attention操作,可选数值为0或1,1表示该token不被mask, 0表示该token被mask
  • token_type_ids (torch.LongTensor of shape (batch_size, sequence_length), optional) 输入片段索引,指明哪个是输入序列的第一部分哪个是输入序列的第二部分(sequenceA sep sequenceB),可选数值为0或1,0表示sequenceA的token,1表示sequenceB的token
  • position_ids (torch.LongTensor of shape (batch_size, sequence_length), optional) 每个输入序列中字(词)的位置索引,可选数值[0, config.max_position_embeddings - 1]
  • inputs_embeds (torch.FloatTensor of shape (batch_size, sequence_length, hidden_size), optional) 可以不传如input_id,而直接传入一个输入序列的embedding

输出

  • last_hidden_state (torch.FloatTensor of shape (batch_size, sequence_length, hidden_size)) 模型最后一层的hidden-state
  • pooler_output (torch.FloatTensor of shape (batch_size, hidden_size)) 最后一层的hidden-state中对应的输入序列的第一个token,即【cls】对应的向量
  • 还有其他的返回,需要设定特定参数才能返回,具体参考BERTModel

参考

transformers各种模型参数及介绍

transformers各种预训练模型下载/模型仓库

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用Transformers自己训练一个模型,您需要进行以下步骤: 1. 准备数据:准备您的训练数据集,并将其整理为适合模型输入的格式。这可能涉及到数据清洗、分词、标记化等预处理操作。 2. 加载预训练模型:选择适合您任务的预训练模型,并使用`from_pretrained()`方法加载模型。您可以选择不同的模型架构(如BERT、GPT、RoBERTa等)和模型大小(如base、large等)。 3. 创建模型:根据您的任务类型,使用预训练模型构建一个适当的分类器、生成器或序列标注器等。您可以根据需要微调预训练模型的不同层。 4. 准备训练器:选择合适的优化器和损失函数,并设置训练时的超参数,如学习率、批量大小、训练迭代次数等。 5. 训练模型使用准备好的数据集和训练器进行模型训练。在每个训练迭代中,将数据输入模型,计算损失并进行反向传播更新模型参数。 6. 评估模型:在训练过程中或训练结束后,使用验证集或测试集评估模型的性能。这可以包括计算准确率、精确度、召回率、F1分数等指标。 7. 保存模型:在训练结束后,保存训练好的模型以便后续使用使用`save_pretrained()`方法将模型保存到磁盘上。 这是一个基本的训练流程示例。具体的实现可能因任务类型、数据集和需求而有所不同。Transformers提供了丰富的功能和示例代码,可以帮助您更轻松地进行模型训练。 如果您需要更详细的代码示例或有特定的问题,请告诉我,我将尽力提供帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值