被这个问题折腾了大半天,听歌的心情都没了…
你遇到过由GPU硬件引入的diff吗?欢迎一起讨论

一、问题起源

工作中我们常用T4 GPU + cuda10.0
突然有一天,产品部门计划下个项目部署在A10 卡上(F***)!
待程序在cuda11(为A10卡选择的cuda版本)编译、单元测试通过后,再测试TF模型精度时,发现在A10卡上掉点…啊啊啊

现象是:
CUDA11 + T4卡运行结果与CUDA10 + T4卡运行结果完全一致
但是:CUDA11 + A10卡 存在掉点…

二、写脚本测试

  1. 一开始我怀疑是opencv版本或者cuda版本引起的,也进行了多次验证,发现并没有问题…
  2. 业务pipeline调用关系比较复杂,同时也为了排除业务代码中前后处理可能引入的diff , 自己写了一个简单的测试脚本,分别在两种运行环境中跑:
import tensorflow as tf
a = tf.constant(0.11111323, shape=[10, 10], dtype=float)
b = tf.constant(0.52422333, shape=[10, 10], dtype=float)
c  = tf.matmul(a, b)
for i in range(1):
    c = tf.matmul(c, b)

print(c)

cuda11 + T4环境运行结果:
在这里插入图片描述

cuda11 + A10环境运行结果:
在这里插入图片描述

看到了吗?竟然是不一样的,问题逐渐明朗了
这基本就可以确定是GPU硬件带来的diff了

三、再读官方文档

为了确定是为什么T4和A10的结果不一致需要重新阅读官方文档,这个属实有点坑了…
A 10 官网介绍: https://www.nvidia.cn/data-center/products/a10-gpu/
A10 采用NVIDIA Ampere架构,我们接着看安培架构的说明,
在这里插入图片描述
介绍中说,Ampere架构采用了第三代Tensor core,采用全新精度标准 Tensor Float 32 (TF32) 与 64 位浮点 (FP64),以加速并简化人工智能应用,同时将 Tensor 核心效能拓展至高效能运算。
如果你足够敏感的话就会发现问题,TF32? 我们常用的是FP32啊
下面看一下两者的区别: 附上官网链接: https://blogs.nvidia.com/blog/2020/05/14/tensorfloat-32-precision-format/
在这里插入图片描述

发现问题了吗? TF32的精度比FP32低, 问题终于找到了…

稍等,严谨,最后再验证一下…
查阅Tensorflow release文档,enable_tensor_float_32_execution接口可以关闭TF32 ,使用下面的脚本分别再两种GPU上再测一遍:

import tensorflow as tf
## 关闭TF32优化
tf.config.experimental.enable_tensor_float_32_execution(False)

a = tf.constant(0.11111323, shape=[10, 10], dtype=float)
b = tf.constant(0.52422333, shape=[10, 10], dtype=float)
c  = tf.matmul(a, b)
for i in range(1):
    c = tf.matmul(c, b)

print(c)

cuda11 + T4计算结果:
在这里插入图片描述
cuda11 + A10计算结果:
在这里插入图片描述
done~~~~

另外:
在 Ampere 架构的 GPU 上,默认启用了 TF32 来进行计算加速。但是并不是每一个矩阵及卷积计算都一定会使用 TF32,跟输入数据类型,输入的形状等因素都有一定的关系。TF32 会尽可能的在合适的时候被使用。 如果想强制关闭 TF32,可以通过设置环境变量:

export NVIDIA_TF32_OVERRIDE=0

来命令所有的 Nvidia 计算库关闭 TF32。​

四、后记

总结: 这是新硬件引入的diff, 各种框架 tf/pytorch等都有是否打开该特性的开关。

看来,适配硬件时 对硬件的典型特性,尤其是新增的特性,应该给予更多的关注…
扩展阅读: 《从Ampere新特性TF32聊GPU浮点运算》

来首歌平复一下心情,欢快一点的吧: 빙고 (答对了) (by 거북이)

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐