PyTorch张量维度不匹配RuntimeError:dump_embedding赋值报错如何解决
报错根因分析
这个错误的核心是赋值操作的左值weight[self.id_offset:self.id_offset+self.length,:]的第0维长度为0,但右值embeddings.detach()的第0维长度是5,二者维度不匹配。常见触发场景有两类:
self.length取值异常,被错误赋值为0或负数,导致self.id_offset : self.id_offset+self.length是一个空切片- 调用
resize_token_embeddings扩容后,self.decoder_original_embedding没有同步更新,仍然指向扩容前的小尺寸embedding层,self.id_offset超出了旧层的vocab大小,导致切片为空
修复步骤
第一步:新增dump_embedding参数校验
在函数入口增加边界检查,提前拦截非法参数,避免空切片赋值:
def dump_embedding(self, weight): # 基础参数合法性校验 assert self.length > 0, f"无效的prompt长度: {self.length}" vocab_size = weight.size(0) end_idx = self.id_offset + self.length assert end_idx <= vocab_size, f"Embedding越界: 偏移量={self.id_offset}, 长度={self.length}, 词表大小={vocab_size}" with torch.no_grad(): embeddings = self.forward(self.input_ids + self.id_offset) # 输出维度校验 assert embeddings.size(0) == self.length, f"生成的embedding长度{embeddings.size(0)}与预期长度{self.length}不匹配" weight[self.id_offset:end_idx,:] = embeddings.detach()
第二步:修正resize逻辑的同步操作
扩容token embedding后必须同步更新你持有的decoder_original_embedding引用,否则还是操作旧的小尺寸权重:
if self.decoder_prompt_encoder: required_vocab_size = self.decoder_prompt_encoder.id_offset + self.decoder_prompt_encoder.length current_vocab_size = self.decoder_original_embedding.num_embeddings if current_vocab_size < required_vocab_size: # 扩容token embedding层 self.underlying_model.resize_token_embeddings(required_vocab_size) # 同步更新持有的embedding引用,拿到扩容后的新权重 self.decoder_original_embedding = self.underlying_model.get_input_embeddings() self.decoder_prompt_encoder.dump_embedding(self.decoder_original_embedding.weight)
第三步:动态长度场景的兼容处理
如果你的prompt长度是动态的,偶尔会出现输出embedding长度与预期不匹配的情况,可以在赋值前增加维度对齐逻辑:
# 放在赋值操作之前,对齐第0维长度到self.length if embeddings.size(0) > self.length: embeddings = embeddings[:self.length] elif embeddings.size(0) < self.length: pad_len = self.length - embeddings.size(0) embeddings = torch.nn.functional.pad(embeddings, (0,0,0,pad_len), value=0)
内容的提问来源于stack exchange,提问作者Ahmad
相关产品推荐
相关产品推荐

