Bert模型forward函数返回字符串而非张量触发linear层TypeError问题排查
问题原因
Hugging Face Transformers 库从v3.x版本开始,预训练模型默认返回的是 BaseModelOutputWithPooling 这类类字典的dataclass对象,而非早期版本的元组。你直接用 pooled, cls_hs = self.bert(...) 语法拆包时,实际是在遍历该对象的属性键名,所以拿到的是last_hidden_state、pooler_output这类字符串,不是对应张量,传入线性层时自然触发类型错误。
解决方案
有两种常用修复方式:
- 方式1:调用模型时添加
return_dict=False参数,强制返回元组格式,适配你原来的拆包逻辑
把forward中的调用行修改为:# 元组顺序固定为 (last_hidden_state, pooler_output) pooled, cls_hs = self.bert(input_ids=inputs, attention_mask=mask, return_dict=False) - 方式2:直接通过属性名从返回的dataclass中取值,逻辑更清晰,不会因为顺序搞混出错
修改forward中的调用逻辑为:outputs = self.bert(input_ids=inputs, attention_mask=mask) # 按需取对应的张量 pooled = outputs.last_hidden_state # 所有token的最后一层隐藏态 cls_hs = outputs.pooler_output # <[BOS_never_used_51bce0c785ca2f68081bfa7d91973934]> token经过pooler层激活后的输出 # 如果需要原生未经过pooler全连接层的CLS向量,也可以手动取:cls_hs = outputs.last_hidden_state[:, 0, :]
额外注意点
你当前代码中还未定义self.softmax,后续运行到x = self.softmax(x)时会触发属性不存在错误,需要在__init__方法中添加定义:
self.softmax = nn.Softmax(dim=1)
内容的提问来源于stack exchange,提问作者Shorouk Adel
相关产品推荐
相关产品推荐

