具有不同嵌入大小的特定训练模型上的 resize_token_embeddings

tw0*_*930 3 word-embedding pytorch bert-language-model huggingface-transformers huggingface-tokenizers

我想问一下如何改变训练模型的嵌入大小。

我有一个训练有素的模型models/BERT-pretrain-1-step-5000.pkl。现在,我正在向标记器添加一个新标记[TRA],并尝试使用resize_token_embeddings相关标记。

from pytorch_pretrained_bert_inset import BertModel #BertTokenizer 
from transformers import AutoTokenizer
from torch.nn.utils.rnn import pad_sequence
import tqdm

tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
model_bert = BertModel.from_pretrained('bert-base-uncased', state_dict=torch.load('models/BERT-pretrain-1-step-5000.pkl', map_location=torch.device('cpu')))

#print(tokenizer.all_special_tokens) #--> ['[UNK]', '[SEP]', '[PAD]', '[CLS]', '[MASK]']
#print(tokenizer.all_special_ids)    #--> [100, 102, 0, 101, 103]

num_added_toks = tokenizer.add_tokens(['[TRA]'], special_tokens=True)
model_bert.resize_token_embeddings(len(tokenizer))  # --> Embedding(30523, 768)
print('[TRA] token id: ', tokenizer.convert_tokens_to_ids('[TRA]'))  # --> 30522
Run Code Online (Sandbox Code Playgroud)

但我遇到了错误:

AttributeError: 'BertModel' object has no attribute 'resize_token_embeddings'
Run Code Online (Sandbox Code Playgroud)

我认为这是因为model_bert(BERT-pretrain-1-step-5000.pkl)我有不同的嵌入大小。我想知道是否有任何方法可以适应我修改后的标记器的嵌入大小以及我想用作初始权重的模型。

多谢!!

cro*_*oik 5

resize_token_embeddings是一个huggingface 转换器方法。您正在使用的 BERTModel 类pytorch_pretrained_bert_inset不提供此类方法。看代码,好像他们之前复制了huggingface的BERT代码。

您可以等待 INSET 的更新(也许创建 github 问题)或编写自己的代码来扩展 word_embedding 层:

from torch import nn 

embedding_layer = model.embeddings.word_embeddings

old_num_tokens, old_embedding_dim = embedding_layer.weight.shape

num_new_tokens = 1

# Creating new embedding layer with more entries
new_embeddings = nn.Embedding(
        old_num_tokens + num_new_tokens, old_embedding_dim
)

# Setting device and type accordingly
new_embeddings.to(
    embedding_layer.weight.device,
    dtype=embedding_layer.weight.dtype,
)

# Copying the old entries
new_embeddings.weight.data[:old_num_tokens, :] = embedding_layer.weight.data[
    :old_num_tokens, :
]

model.embeddings.word_embeddings = new_embeddings
Run Code Online (Sandbox Code Playgroud)