GPT-2交叉熵损失掩码标签异常:注释代码为何不影响损失结果?
为何掩码部分标签不影响GPT-2的交叉熵损失计算?
我参考相关文档用GPT-2计算文本交叉熵损失,代码如下:
from transformers import GPT2LMHeadModel, GPT2TokenizerFast import torch from tqdm import tqdm model_id = "gpt2-large" model = GPT2LMHeadModel.from_pretrained(model_id) tokenizer = GPT2TokenizerFast.from_pretrained(model_id, cache_dir='.') encodings = tokenizer("She felt his demeanor was sweet and endearing.", return_tensors="pt") max_length = model.config.n_positions seq_len = encodings.input_ids.size(1) target_ids = encodings.input_ids.clone() #target_ids[:, :-seq_len] = -100 COMMENTED LINE with torch.no_grad(): outputs = model(encodings.input_ids, labels=target_ids) print(outputs.loss.item())
不管注释或取消注释target_ids[:, :-seq_len] = -100这行代码,输出的损失值始终为4.352320194244385。按官方说明,标签设为-100会被掩码忽略,损失仅针对有效标签计算,为什么结果不受影响?
问题原因
核心问题出在切片操作的逻辑上:
seq_len是当前输入序列的token长度,假设这里tokenize后输入序列长度为Ntarget_ids[:, :-seq_len]等价于target_ids[:, :-N],而target_ids本身的长度就是N,这个切片会选取前0个元素,也就是没有任何元素被选中- 所以这行赋值代码本质上没有修改
target_ids的任何内容,不管注释与否,target_ids都是原输入序列的克隆值,损失计算自然完全一致
如果想要实现“掩码部分标签”的效果,需要调整切片范围,比如如果想掩码前k个token,可以写成target_ids[:, :k] = -100,或者根据实际需求修改切片的起止位置。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

