为什么要向词汇表添加token?
在大多数情况下,您不会从头开始训练一个大型语言模型,而是在新数据上微调现有模型。通常,新数据集和自然语言任务使用新的或不同的领域特定词汇。例如,法律或医疗文件。虽然目前模型一起使用的子词tokenizers能够处理基本上任意的token,但这并不是最优的。这些tokenizers一般是透过切分更小的sub token来处理未知的新词。这样可以处理文本,但以这种方式一些特殊涵义的词汇可能不够精准,而且整体token长度会变长,从而降低模型的效率。因此将新的领域特定令牌添加到tokenizers和模型中,可以更快地进行微调,并更好地捕获数据中的信息。
from transformers import AutoTokenizer, AutoModel
# 选择模型类型
model_type = "roberta-base"
tokenizer = AutoTokenizer.from_pretrained(model_type)
model = AutoModel.from_pretrained(model_type)
# 新令牌
new_tokens = ["new_token"]
# 检查令牌是否已在词汇表中
new_tokens = set(new_tokens) - set(tokenizer.vocab.keys())
# 将令牌添加到令牌器词汇表中
tokenizer.add_tokens(list(new_tokens))
# 为新令牌添加新的随机嵌入
model.resize_token_embeddings(len(tokenizer))
扩展词汇表的详细步骤
首先,我们需要从huggingface中定义和加载模型。
from transformers import AutoTokenizer, AutoModel
model_type = "roberta-base"
tokenizer = AutoTokenizer.from_pretrained(model_type)
model = AutoModel.from_pretrained(model_type)
在下一步中,我们需要准备一组新token并检查它们是否已在tokenizers的词汇表中。我们可以使用tokenizer.vocab
获取令牌器的词汇映射。这是一个字典,以token为键,以索引为值。所以我们这样做:
new_tokens = ["new_token"]
new_tokens = set(new_tokens) - set(tokenizer.vocab.keys())
现在,我们可以使用令牌器的add_tokens
方法来扩展词汇表。
tokenizer.add_tokens(list(new_tokens))
作为最后一步,我们需要向模型的embedding matrix中添加新的embedding。我们可以通过使用词汇表中的令牌数量(包括新添加的令牌)调用模型的resize_token_embeddings
方法来完成。
model.resize_token_embeddings(len(tokenizer))
embedding matrix将在末尾添加新初始化的向量。使用这些新的未训练的embedding可能已经有用,但通常需要进行至少一些微调步骤。