PyTorch 矩阵乘法不考虑切片

PyTorch matrix multiplication does not respect slicing

提问人:Sasha 提问时间:9/4/2023 更新时间:9/4/2023 访问量:86

问:

我必须对转印器模型进行批量长输入,并注意到批处理和非批处理结果之间的差异,从而达到这一点。我最终隔离了我注意到的第一个差异,结果如下:

import torch

n = 20

vec = torch.rand(n, 20)
a = torch.rand(30, 20)

for i in range(1, n+1):
    print(i, torch.equal(
        torch.nn.functional.linear(vec, a)[:i],
        torch.nn.functional.linear(vec[:i], a)))

产生输出:

1 False
2 False
3 False
4 True
5 True
6 True
7 False
8 False
9 False
10 True
11 True
12 True
13 False
14 False
15 False
16 True
17 True
18 True
19 True
20 True

这只是一个操作,当多次组合时(如在转换器中),它可能会导致较大的发散,从而扩大 torch.allclose 输出 True 的 atol。这是为什么呢,能做些什么吗?

Python Pytorch 精密 拥抱面-变形金刚 手电筒

评论

1赞 Daraan 9/4/2023
无法重现此情况(在 CPU 上)仅获取 True 值。
2赞 Daraan 9/4/2023
也可能与火炬的矩阵乘法精度有关。在精度和速度之间有一个可选的权衡。
1赞 Daraan 9/4/2023
我刚刚用你的版本测试了它。所以火炬 1.12.1 只生成 True。切换到 1.13.1 会以相同的模式重现结果。Torch 2.0.1 输出:只有第一个为 False,其余的再次为 True。
1赞 ken 9/4/2023
当批处理大小为 1 时,Pytorch 会进行优化计算(也许是 SIMD?)。对于几乎所有模型,相同输入的推理结果对于批量大小 1 和 2 都是不同的。这就是为什么当 i == 1 时它是 False 的原因。对于 i >= 2,我不知道为什么。但是,我认为 pytorch 在这里也进行了一些优化,因为我在 numpy 中重新实现了此计算并且无法重现错误。
1赞 ken 9/5/2023
我能够通过交换和在您的代码中重现类似的东西。即,.有趣的是,它产生在哪里.如果我将其更改为 ,那么它会产生 where .因此,至少对于 而言,pytorch 似乎在 .但是,对于较大的形状,情况就不一样了。2.0.1+cpu2030vec = torch.rand(30, 30); a = torch.rand(20, 30)Truei >= 20a = torch.rand(25, 30)Truei >= 252.0.1input.shape[0] < weight.shape[0]

答:

0赞 Alexey Birukov 9/4/2023 #1

欢迎来到浮点运算的勇敢世界! 运算引入了舍入误差,矩阵乘法将它们累积到有效值。https://pytorch.org/docs/stable/notes/numerical_accuracy.html如果避免使用以下方法进行不精确的舍入float

vec = torch.floor (torch.rand(n, 20)*10)
a = torch.floor( torch.rand(30, 20)*10 )

你会得到所有的 -s。True

可能的解决方案是使用 .torch.isclose


戴尔

评论

0赞 Sasha 9/4/2023
您好,谢谢。我不确定你的答案是否与手头的确切问题超级相关,我相信这个问题更微妙。我说的是“批处理”计算(我认为 vec 是 n 个较小张量 vec[i] 的批次),原则上,理想情况下,无论我一次执行还是每批元素执行,计算都应该完全相同。我们在这里看到一个非常奇怪的 False/True 模式,具体取决于批处理元素的数量,这可能与引擎盖下的一些奇怪的优化谈话场所有关......
0赞 Alexey Birukov 9/4/2023
计算是相同的,但它们的顺序可能不是,这很重要。 制动关联定律。floats
0赞 Sasha 9/4/2023
对于不同的 I,VEC[i] 的计算之间没有交互,因此顺序应该无关紧要。
0赞 Alexey Birukov 9/4/2023
首先,for 仍然是矩阵。其次,即使将向量乘以矩阵,里面也有标量乘积,它的计算顺序由机器选择。n>0vec[:i]
0赞 Sasha 9/4/2023
如果你看到涉及的计算是什么,那么说,它是,简化,就像计算三个浮点数 a、b 和 c 的 ab 和 ac 一样。顺序应该无关紧要,理想情况下,如果 a、b 和 c 是确定性的,则结果应该是确定性的。然而,在这里我们看到(粗略地),要求计算机立即计算 (ab, ac) 并提取结果 ab(第一个坐标)给出的答案与要求它单独计算 ab 不同。