渐变在拥抱脸模块中返回无

Posted

技术标签:

【中文标题】渐变在拥抱脸模块中返回无【英文标题】:Gradients returning None in huggingface module 【发布时间】:2021-02-25 14:30:01 【问题描述】:

我想从 pytorch/huggingface 模型中获取嵌入层的梯度。这是一个最小的工作示例:

from transformers import pipeline

nlp = pipeline("zero-shot-classification", model="facebook/bart-large-mnli")

responses = ["I'm having a great day!!"]
hypothesis_template = 'This person feels '
candidate_labels = ['happy', 'sad']
nlp(responses, candidate_labels, hypothesis_template=hypothesis_template)

我可以很好地提取 logits,

inputs = nlp._parse_and_tokenize(responses, candidate_labels, hypothesis_template)
predictions = nlp.model(**inputs, return_dict=True, output_hidden_states=True)
predictions['logits']   

模型返回一个我感兴趣的层。我尝试保留我感兴趣的单个 logit 的梯度和反向传播:

layer = predictions['encoder_hidden_states'][0]
layer.retain_grad()
predictions['logits'][0][2].backward(retain_graph=True)

但是,layer.grad == None 无论我尝试什么。模型的其他命名参数计算了它们的梯度,所以我不确定我做错了什么。如何获得encoder_hidden_​​states的grad?

【问题讨论】:

你能检查嵌入层是否可训练吗? @SergeyBushmanov 我不知道该怎么做,我确实检查了layer.requires_grad==True,但这是别的吗? Keras 层具有trainable 属性。我相信 tf/pytorch 应该存在类似的东西 不确定我是否误解了你的问题,但predictions['encoder_hidden_states'][0] 不是一层。它是一个层的输出。 @cronoik 这可能是我的误解。我想要输入 w.r.t 的梯度。最终的逻辑之一。理想情况下,如果有意义的话,这将是在热编码之后。 【参考方案1】:

我也对这个问题感到非常惊讶。尽管我从未使用过该库,但我还是进行了一些调试,发现问题出在库转换器上。问题来自line:

encoder_states = tuple(hidden_state.transpose(0, 1) for hidden_state in encoder_states)

如果您将其注释掉,您将获得仅带有一些尺寸转置的渐变。 这个问题与 here 提到的 Pytorch Autograd 在就地操作上表现不佳有关。

所以总结一下解决方案是在 modeling_bart.py 中评论第 382 行。

您将获得具有此形状的渐变 T x B x C 而不是 B x T x C,但您可以稍后根据需要重新调整它。

【讨论】:

就是这样!您找到它并提供了它失败的原因给我留下了深刻的印象。我要把这个带到拥抱脸论坛上,我认为如果没有疯狂的猴子补丁可能会很好。 是的,我认为这应该是一个“简单”的解决方法。 这似乎是导致问题的行,但它不是就地操作,所以我不确定解释是否有意义。也许是 PyTorch 问题? 嗨,我遇到了同样的问题,注释掉这一行并不能解决问题。更具体地说,我想获得 RoBERTa 模型中的梯度,它不会转置隐藏状态,layer.grad 仍然是 None。我是否错过了示例代码(在问题中)中的某些内容来获取渐变?我的变形金刚版本是 4.3.2。谢谢!

以上是关于渐变在拥抱脸模块中返回无的主要内容,如果未能解决你的问题,请参考以下文章

如何在拥抱脸模型中获得令牌的概率分布?

Jupyter 笔记本中的 ModuleNotFoundError 拥抱脸数据集

如何为拥抱脸重新下载标记器?

了解拥抱脸变形金刚

无法为拥抱脸变压器库安装 tensorflow

【译】在 React 中拥抱函数——无状态函数式组件及其重要性