最近,我阅读了Jay关于GPT-2 (http://jalammar.github.io/illustrated-gpt2/)的博文,其中我发现有一点非常清晰:他解释说,GPT-2的译码器一次只处理一个输入令牌,只主动处理最后一个输入令牌,过去的令牌已经保存在内存中,“被动地”重用,不进行重新评估。
根据我对转换器体系结构的理解,我的印象是解码器重新评估每一代生成的每个令牌。这是GPT-2解码器之间的区别,还是“经典”转换器的译码器也是这样工作的?
从直觉上讲,我认为在每次迭代中重新评估一切都会更有意义,因为单词之间可能出现新的依赖关系,在开始时不存在,如果过去处理过的单词被被动地重复使用,就不会被考虑在内。
我希望我说得通,有GPT2架构知识的人能帮我澄清这一点吗?
发布于 2020-04-03 00:16:08
我的理解是,变压器解码器和变压器编解码模型通常以GPT-2的方式工作,也就是说,生成序列中的表示被计算一次,然后在以后的步骤中重复使用。但你是正确的,这不是唯一的方式可以做的事情。我们可以重新计算部分生成序列中的所有标记的表示,使用对到目前为止生成的序列中的标记的完全自我关注(这样做没有数学上的障碍--这类似于对部分生成序列中的单词序列运行典型的转换器编码器)。
但据我所知,从文献中可以看出,这种额外的计算并不常见。我认为至少有两个原因。首先,正如其他人所指出的,在计算上使用先前时间步骤中的计算表示要便宜一些(尽管这会导致不同的结果,而且我在任何论文中都没有看到过经验的比较)。第二,它与训练的方式相匹配。在训练过程中,自我注意掩蔽的一个结果是,输出位置i的表示是使用输出位置的表示( <= i)来计算的。这意味着在训练期间,每个层的输出位置I只有一个表示。这与使用我们讨论的标准方法在推理时发生的情况相匹配,这是在GPT-2中使用的。
如果我们想要训练一个模型,其中一个输出位置的表示是根据所有可用的输出表示来计算的(当然总是不包括那些尚未“生成”的输出表示),那么我们需要在训练期间计算每个输出位置的多个表示,每个可能的不完全正确的上下文一个。例如,如果我们在大小为512的窗口上训练语言模型,我们必须为第一个单词计算(大约) 512表示,一个对应于在窗口中生成每个后续单词的损失。这将导致一个非常大的计算图表和缓慢的训练。然而,它可能会更好地工作,因为它会带来更丰富的输出表示,所以请尝试并让我们知道。:)
发布于 2020-03-25 16:22:52
过去的令牌内部状态在GPT-2和任何其他转换器解码器中都被重用.
例如,在fairseq的转换器实现中,这些先前的状态是在参数TransformerDecoder.forward incremental_state中接收的(参见源代码)。
请记住,解码器中的自我注意块中有一个掩码,它阻止预测和中间状态处理与当前的位置相等或大于当前的位置,这意味着即使在每一个解码步骤重新计算它们,内部状态也不会改变。
更新:当然,从技术上讲,在将来的令牌中重新计算过去的令牌是可能的,但是,在重新计算过去的令牌之后,您将如何处理未来的令牌呢?你会重新计算它们吗?这是一个完全不同的动物,它已经在某种程度上被研究,并被称为“迭代精化”。在文章“确定性非自回归神经序列的迭代求精建模”中可以找到一个例子。AFAIK,这种方法没有在自回归模型中研究过,只是在非自回归模型中进行了研究。
https://datascience.stackexchange.com/questions/70222
复制相似问题