我在使用Hugging Face Transformers。我有一个预训练的编码器+解码器模型(Pegasus),我想按照这篇文章中描述的方法对其进行微调。
具体来说,他们使用了以下过程:
换句话说,他们在模型生成之前添加了一个手动提示。
我的问题与解码器的输入有关。具体来说,我想微调模型,使其接受提示(实体链),并从那时起生成摘要。
例如:
<s> [ENTITYCHAIN] Frozen | Disney [SUMMARY] $tok_1 $tok_2 $tok_3 ...=========================================== ^^^^^^ ^^^^^^ ^^^^^^这部分不是生成的 从这里开始生成
然而,正如您所预期的,模型会对实体链中的每个标记进行预测,而这些预测我并不需要。更重要的是,损失的计算也考虑了与实体链相关的预测。这显然破坏了训练的目的,因为这会使模型感到困惑,因为它应该学会只生成摘要,而不是实体链(实体链已经作为提示给出)。
正如我所说,我希望给解码器一个提示(实体链),并使其生成摘要,同时能够关注提示中的额外信息。当然,损失应该只在生成的标记之间计算,不包括提示标记。
通过查看模型文档,我似乎找不到这样做的选项。有什么想法吗?:)
回答:
PyTorch损失函数的一个惯例是,如果你在训练期间将标签设置为-100,损失函数将忽略该标记。查看文档以便安心。
这是一个最小的代码示例:
# 库import transformersfrom transformers import AutoTokenizer, AutoModelForSeq2SeqLMfrom copy import deepcopy# 获取标记器和模型checkpoint = 't5-small'tokenizer = AutoTokenizer.from_pretrained(checkpoint)model = AutoModelForSeq2SeqLM.from_pretrained(checkpoint)# 示例文本inp = 'Here is my input'outp = 'Here is my output'# 获取标记IDinp_ids = tokenizer(inp, return_tensors = 'pt').input_idsoutp_ids = tokenizer(outp, return_tensors = 'pt').input_ids# 计算损失loss = model(input_ids = inp_ids, labels = outp_ids).loss.item()print(loss)# 让我们将第一个标记设置为-100并重新计算损失modified_outp_ids = deepcopy(outp_ids)modified_outp_ids[0][0] = -100 # 第一个[0]是因为我们的批次中只有一个序列model_output = model(input_ids = inp_ids, labels = modified_outp_ids)print(model_output.loss.item())