TensorFlow/numPy 计算结果取决于处理器

tensorflow/numpy computations results depend on the processor

提问人:G.C. 提问时间:9/7/2023 最后编辑:G.C. 更新时间:9/8/2023 访问量:65

问:

编辑 (07/11/2023)

在评论中的各种评论之后,我们理解了我们获得的各种结果之间的部分差异。GPU 或 CPU 上的计算结果可能有所不同这一事实在用户 ken 在其评论中提供的参考中得到了令人信服的解释。 然而,在不同的CPU上执行计算时,其他一些差异并没有找到解释。 经过进一步的研究,很明显,问题不仅来自Tensorflow,还来自Numpy。

事实上,在我们的第一次测试中,我们使用的是 tensorflow 的随机生成器,但观察到这些生成器的结果已经略有不同,具体取决于我们使用的计算机。

由于我们专注于操作而不是数字生成,因此我们依赖于numpy的生成器,认为它们不依赖于所使用的处理器。

现在我们确信,事实上

  • 当操作数完全相同并且计算在不同的 CPU 上执行时,tensorflow 和 numpy 为相同的操作提供相同的结果,但
  • numpy 和 TensorFlow 随机生成器都提供依赖于 CPU 的值。

下面是一个例子:

np.random.seed(263)
print(np.random.randn(1))

在 I5-1135G7 和 I5-5357U 上,我们得到:

[1.5188843533672705]

在 Google Colab 的 Xeon 和 I7-8700 上,我们得到了

[1.5188843533672707]

(对于从 0 到 262 的所有其他种子,两个系统上的结果完全相同)

所以新的问题可能是:

为什么 numpy 和 tensorflow 随机生成器的行为会根据我们使用的计算机而有所不同?

编辑结束

在不同的计算机上进行完全相同的计算不一定会产生相同的结果。

这是一个最小且可重复的例子:

import tensorflow as tf
import numpy as np

np.random.seed(0)

numpy_numbers        = np.random.randn(100000)
tensorflow_numbers   = tf.convert_to_tensor(numpy_numbers)

numpy_sum      = np.sum(numpy_numbers)
tensorflow_sum = tf.reduce_sum(tensorflow_numbers)

print("hash of numpy_numbers      : ",np.sum([hash(x) for x in numpy_numbers]))
print("hash of tensorflow_numbers : ",np.sum([hash(x.numpy()) for x in tensorflow_numbers]))

print("Numpy sum      : ",tf.convert_to_tensor(numpy_sum))
print("Tensorflow sum : ",tensorflow_sum)

我们在各种计算机上尝试了此代码

  • 相同版本的 Python (3.10.12)
  • 相同版本的 Tensorflow (2.12.0)
  • 相同版本的 Numpy (1.23.5)

并观察到

  • 在给定的计算机上,结果始终相同
  • 在不同的计算机上,结果不同

例如,在 Google Colab 上,

  • 通过选择运行时类型“CPU”(Intel Xeon 2.20GHz),我们得到
hash of numpy_numbers      :  -2611790474163640565
hash of tensorflow_numbers :  -2611790474163640565

Numpy sum      :  tf.Tensor(157.670050812534, shape=(), dtype=float64)
Tensorflow sum :  tf.Tensor(157.67005081253396, shape=(), dtype=float64)
  • 通过选择运行时类型“GPU”(Tesla T4),我们得到
hash of numpy_numbers      :  -2611790474163640565
hash of tensorflow_numbers :  -2611790474163640565

Numpy sum      :  tf.Tensor(157.670050812534, shape=(), dtype=float64)
Tensorflow sum :  tf.Tensor(157.67005081253393, shape=(), dtype=float64)

问题:

这种现象的解释是什么?

我们的猜测:

我们得出了以下猜测:

Tensorflow 在给定一个大的总和要计算时,首先用第一个要求和的数字填充缓存,然后计算第一个部分总和,然后对以下数字执行相同的操作,直到所有数字都用完,最后将部分总和相加。

因此,将缺乏关联性,这取决于缓存的大小。

但这只是一个猜测,我们希望对真正发生的事情有一个坚定的了解。

python numpy tensorflow cpu-cache 关联性

评论

0赞 Jesse Sealand 9/7/2023
我喜欢这个问题。很明显,numpy 和是更准确的 tensorflow 和的四舍五入。我正在努力解决为什么 cpu 和 gpu 的总和在最后小数点后相差 3 位,这显然不是四舍五入。
0赞 Jesse Sealand 9/7/2023
我确实在 SO 上发现了类似的问题,但我也不认为这是一个明确的答案,但它深入探讨了同样的想法。
0赞 G.C. 9/7/2023
@JesseSealand感谢您的评论。事实上,在你分享的链接中已经注意到了这种现象,但即使点击其中的链接,我也无法找到明确的解释。
0赞 ken 9/7/2023
有几种方法可以计算总和。例如,Python 的内置 sum 函数只是从头部开始加法,而 numpy 的 sum 函数是一种称为成对的分而治之的方法。我不知道tensorflow是如何实现sum的,但由于你的比较是在CPU和GPU之间,而不是处理器之间,所以结果的差异很可能是由于计算方法的差异。相关问题

答: 暂无答案