[Bert] 提取特征之后训练模型报梯度图错误
报错:
RuntimeError: stack(): functions with out=… arguments don’t support automatic differentiation, but one of the arguments requires grad.
或者
RuntimeError: Trying to backward through the graph a second time (or directly access saved tensors after they have already been freed). Saved intermediate values of the graph are freed when you call .backward() or autograd.grad(). Specify retain_graph=True if you need to backward through the graph a second time or if you need to access saved tensors after calling backward.
原因:
训练模型的时候,输入数据x,y不应该requires_grad,而bert模型输出的embeddings默认是requires_grad的,所以会报错。
解决方法:
提取完embeddings之后,使用 embeddings.detach()
解除绑定就行了。
最后的代码:
from transformers import BertTokenizer, BertModel
class BertFeatureExtractor:
def __init__(self):
self.tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
self.model = BertModel.from_pretrained('bert-base-chinese')
def extract_features(self, text: str):
inputs = self.tokenizer(text, return_tensors="pt")
if len(inputs["input_ids"]) > 512:
inputs["input_ids"] = inputs["input_ids"][:512]
inputs["attention_mask"] = inputs["attention_mask"][:512]
outputs = self.model(**inputs)
return outputs.last_hidden_state[:,0,:]
feat = feat.detach()