针对Win10 Tensorflow-2.x 训练 线程冻结(假死、卡住、几个epoch后、中途停滞、CPU占用0%) 等问题的排查总结

2022.8.26 更新

本文描述了2021年10月1日之前的问题,对这个时间之后的问题无法保证具有绝对的参考意义。
为了节省各位看官的时间,将有效的措施总结如下:

  • 开启windows的GPU硬件加速后再训练
  • 降级或者升级驱动版本

遇到本文描述的类似问题,可以参考尝试上述两个步骤。若对过程和细节感兴趣,可以继续往下阅读。


2021.10.1更新

最近win平台训练又出现了一个大bug。训练程序多开时线程冻结的问题排查(已解决)

  1. 问题描述:win10-tf2.6-Py3.9-Cuda11.4-cudnn8.2-RTX3090执行我的深度学习算法时,进行线程多开并行训练,在训练的某个时刻,总是随机出现部分线程卡死(双开时,总是随机出现其中一个线程冻结)的现象,只留下一个训练线程。下面开始问题排查记录。
  2. 排除defender安全软件的文件防护扫描问题。即排除Antimalware Service Executable程序问题。
    • 原本以为程序只是在保存结果,写入到磁盘的时候卡死冻结,但是经过加入step输出计数,发现程序没有磁盘写入任务时也会卡死。
    • 关闭文件实时防护以停止Antimalware Service Executable,或者在文件实时防护中添加文件夹忽略,或者先添加忽略再关闭文件实时防护,或者换火绒安全软件替代defender、或者在火绒中关闭实时文件防护,训练程序的随机性卡死问题依旧。
    • 结合上述两点,足以说明不是安全软件的文件防护导致。
  3. 排除TF版本和cuda-cudnn版本问题,从tf2.6-avx2切换为官方编译版本(修改对应cuda-cudnn),或者切换为基于官方推荐的cuda-cudnn版本编译的avx版本,或者切换为tf2.5官方编译版本(修改对应cuda-cudnn)问题依旧出现。
  4. 排除内存压缩问题。无论开启、关闭内存压缩技术,问题都依旧。
  5. 排除GPU硬件加速问题。无论开启、关闭win10的GPU硬件加速,问题都依旧。关闭GPU硬件加速延缓了训练速度,还是应当保持开启。
  6. 排除代码自身问题。双开时,在VS-code窗口左右摆放终端没有仍和影响(心理向测试),卡死的线程在固定的两个双开的程序上随机出现。
  7. 怀疑驱动问题。进行驱动降级测试。可行驱动有457.30,466.77,471.41。而471.68与472.12都不可行。目前的驱动就是472.12。原因找到,目前稳定的最高驱动为471.41。

总结:测试中发现,在高于471.41的驱动版本下,我的算法程序运行时CPU占用较高,有7% 8%,而稳定版本的驱动下,我的算法程序运行时CPU占用较低,只有4% 5%,这可能时驱动问题的本质原因的一个端倪。


2020.12.22更新

我佛了,原始问题的一个合适的解决途径终于找到了,即一定要开GPU硬件加速
在这里插入图片描述
那我这些天的debug真是醉了

如果有想在Ubuntu20.04上用3090和TensorFlow2.4的同学
可以参考下载这个编译好的直接用tensorflow-2.4.0-cp38-cp38-linux_x86_64.whl


以下是原始问题(2020年12月22之前), 问题出现在 1.2 节

0.前言(事情很复杂)

事件背景:30系显卡出来后,需要针对8.6算力对TensorFlow2.x进行重新编译,才可顺畅使用,若非重新编译,每次运行都会进行一次预编译,极其浪费时间。一般的,大家会选择一下两种办法:

  1. 等官方编译发行到:PyPI 上,安装官方使用的环境,进行使用
  2. 自行编译,可以决定想要的Cuda和cudnn版本。一般会选择更加新的版本,获得一点点优化和提升。

这里,我一直以来都是选择后者,自行编译使用。自从解决了TF2.3.x在win10下的编译问题后,已经在TF2.3.x 使用了半年之久。下面总结一下TF2.3.x 在win10下对8.6算力的卡的编译问题:

  1. 官方环境仅支持cuda11.0 但是编译过的同学都知道,cuda11.0不支持8.6算力,自行编译会报错,提示一个和8.6算力相关的文件无法取得。这其中是否还有在cuda11.0下正确编译8.6算力的方法,我无从得知,但是似乎官方的编译是可以做到的,可我不会,以我会的角度,必须升级到至少cuda11.1 才可以
  2. TF2.3.0 TF2.3.1 在Win10、Cuda11.1、cudnn8.0.5 和python3.8.6下 是可以对8.6算力编译成功的,完全可以正常使用,所有的原来在7.5算力的卡下跑过的程序都完全正常运行。
  3. 但是,TF2.3.x 目前已经算旧版本了,尤其是混合精度部分,变化很大,而我的实验又必须使用混合精度,所以,即便TF2.3.x 可以正常使用,我还是要去TF2.4试试

1. TF2.4的编译与使用问题

TF2.4 吸取了TF2.3的问题经验,没有在Win10下报恶性的编译错误(不再需要自行修改文件等等),编译很顺畅。

1.1 编译问题

  1. Cuda11.0不支持8.6算力,编译失败
  2. Cuda11.1 依据官方教程,即可编译成功,Cudnn为8.0.5
  3. Cuda11.2 依据官方教程,即可编译成功,但是目前还没有出Cuda11.2对应的Cudnn,用的是Cuda11.1的cudnn8.0.5代替
  4. 编译过程中,CPU、内存会影响C++编译器,报一些很奇怪的编译器错误(因为我没法完全记录这个过程,编译器错误大致会出现很多地址,如果选择默认C++路径的话会是C:/Program File(x86)…然后直指编译器balabala)甚至蓝屏,编译时尽量不要超CPU和超内存,同时尽量减少计算机的使用,可以用 -j n 命令控制bazel的线程数 避免吃满线程。血泪教训的经验,我不知怎么解释,但是真的是事实。另外还有一个经验,如果两次编译,都在后半段报错,且报错的内容不一致,很可能没有错,只是超频了或者线程吃满影响编译器了。(我不知道我怎么说得出这么不专业的话的,希望专业人士可以解释一二,CPU和内存超频很多后,会报错,降频后编译正常成功,这就是我自己的事实依据。)

1.2 使用问题(大坑)

TF2.4在Win10下编译完成后,并没有如期可以正常使用。可以过官方的MNIST-demo,但是过不了很多自定义模型。以我自行设计的可以支持谱范数正则化和混合精度的层为例:

Layer特性SNMixed PrecisionActivationPadding
BatchNormkeras复刻×--
InstanceNorm自行实现×--
Densekeras复刻more-
Conv2dkeras复刻moremore
Conv2dTransposekeras复刻moremore
UpsamplingConv2d自行实现moremore
Conv3dkeras复刻moremore
Conv3dTransposekeras复刻moremore
UpsamplingConv3d自行实现moremore

这些自定义层并非完全不能通过测试,而是其中的某些层,在某些情况下,无法通过,出现卡死,线程冻结、假死、CPU占用为0%的一系列BUG现象,无法确保正常使用时不出错,一般的大型网络都会在若干个batch或者甚至一个batch都跑不完的情况下,被冻结而无法训练继续。这其中,自行设计的Conv3d在一定程度的测试下,几乎可以百分百出现BUG。
测试代码如下(很简漏,当时不会用单元测试工具):

layer = BaseLayers.Conv3D
layer0 = tf.keras.layers.Conv3D
input_shape_list=[]
args_list=[]
kwargs_list=[]

input_shape = [[4,64,65,66,1]]
filters=[1,4]
kernel_size=[[3,3,3]]
strides=[[1,1,1],[2,2,2]]
padding=["SAME","VALID"]
use_bias=[True]
kernel_initializer='ones'
bias_initializer='zeros'
activation=["relu","leaky_relu","linear",None,"sigmoid","tanh"]
spectral_normalization=[True,False]
iter_k=[1,3,5]
approach = ["sparse_matrix"]
for item1 in input_shape:
    for item2 in filters:
        for item3 in kernel_size:
            for item4 in strides:
                for item5 in padding:
                    for item6 in use_bias:
                        for item7 in activation:
                            for item8 in spectral_normalization:
                                for item9 in iter_k:
                                    for item10 in approach:
                                        input_shape_list.append(item1)
                                        args_buf=[]
                                        args_list.append(args_buf)
                                        kwargs_buf = {}
                                        kwargs_buf["filters"]=item2
                                        kwargs_buf["kernel_size"]=item3
                                        kwargs_buf["strides"]=item4
                                        kwargs_buf["padding"]=item5
                                        kwargs_buf["use_bias"]=item6
                                        kwargs_buf["kernel_initializer"]='ones'
                                        kwargs_buf["bias_initializer"]='zeros'
                                        kwargs_buf["activation"]=item7
                                        kwargs_buf["spectral_normalization"]=item8
                                        kwargs_buf["iter_k"]=item9
                                        kwargs_buf["approach"]=item10
                                        kwargs_list.append(kwargs_buf)
result=test_func(layer=layer,layer0=layer0,policy_list=policy_list,input_shape_list=input_shape_list,args_list=args_list,kwargs_list=kwargs_list,file_name="./test_24_logs/test_conv3d.txt")
print(result)
if result:
    print(result)
    recode[str(BaseLayers.Conv3D)]={"passed"}
else:
    print(result)
    recode[str(BaseLayers.Conv3D)]={"failed"}
print(recode)

运行时,会遇到如下三种情况之一

  1. 线程假死、卡住,此时运行的python控制台无法ctrl+C结束,对应CPU占用为0%
  2. F .\tensorflow/core/kernels/conv_2d_gpu.h:714] Non-OK-status: GpuLaunchKernel( SwapDimension1And2InTensor3UsingTiles<T, NumThreads, TileShortSide, TileLongSide>, total_tiles_count, NumThreads, 0, d.stream(), input, input_dims, output) status: Internal: unspecified launch failure 的报错,对应CPU占用也为0%,但一段时间后,可以自行结束
  3. 正常通过,几乎没出现过。

截图参考
情况1 假死
情况1
情况2 报错
在这里插入图片描述
以上的情况,都是在不修改代码,而是先后运行测试程序下的考证,随机出现,没有规律。
后来,单步调试该问题,发现并没有出错,于是脑洞一开
加上一个延时,模拟单步调试的过程,代码如下

def test_func(layer,layer0,policy_list,input_shape_list,args_list,kwargs_list,training=None,file_name=None):
    if (len(input_shape_list)!=len(args_list))or(len(input_shape_list)!=len(kwargs_list)):
        raise ValueError("!!! Can not test because of mismatching args")
    n = len(input_shape_list)
    data=open(file_name,'w+') 
    print(layer,file=data)
    print(layer0,file=data)
    for i in range(n):
        time.sleep(0.1)#给每次测试加上0.1秒延迟
        ... 
        ...

发现,以上的情况1 情况2再也没有遇到过。截图为证
在这里插入图片描述

1.3 后续

现象总结为,自定义层测试时出现线程冻结、假死、CPU占用为0% 或者 Non-OK-status的报错,给测试代码加上延时,解决上述问题,但是拖长了运行时间,得不偿失。

显而易见:

  1. 并非自定义层的写法问题。
  2. 可能是TF2.4的问题
  3. 可能是Cuda的问题
  4. 可能是Cudnn的问题
  5. 可能是Win10的问题
  6. 可能是驱动的问题。但是TF2.3.x则不会如此,如果是驱动问题,也无法断定哪个版本可行。
  7. 可能是新卡的问题

为了缩小范围,我针对6.1算力的1080重新编译了TF2.4 问题依旧。那么可以大概率的确定,不是新卡的问题,旧卡也会出现一样的情况。如果是驱动问题,那为何TF2.3就可行呢。退回最原始的驱动456.38,新的报错接踵而至,但是是一样的位置
在这里插入图片描述

2 Linux下尝试TF2.4尝试

在Ubuntu20.04下,驱动455.23,Cuda11.1,cudnn8.0.5和GCC9.3下,编译安装Python3.8.6后,再次针对8.6算力编译了TF2.4。情况如下:

  1. 编译通过(编译过程中出现的都是小问题,轻松解决)
  2. 测试通过
  3. 正常运行所有原先的TF程序!!!终于可以开始新的科研了。

如果有想在Ubuntu20.04上用3090和TensorFlow2.4的同学
可以下载这个编译好的直接用tensorflow-2.4.0-cp38-cp38-linux_x86_64.whl

但并不能止于此
回望目前的问题,如果说是谷歌团队的问题,为何在LINUX下可以正常编译、使用呢?因为没有修改任何源码部分。如果说是驱动的问题,Win10下若干版本驱动也没有OK的情况。如果是新卡的问题,旧卡为何还是一样的错误呢?如果是Cuda和Cudnn的版本问题,同版本Linux却可行。

所以目前的总结是,WIN10下,驱动、cuda、cudnn TF2.4 和操作系统之间,一定存在某个BUG,让TF2.4 出现上述问题。

另外,目前也见过很多Pytorch出现相似表象的问题,但Pytorch的编译使用我不熟悉,希望这些问题的本质是一致的,可以被尽快解决,大家早日用上好用的工具,别再泥坑里陷下去了。

  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论
您好!对于 TensorFlow-GPU 的验证,您可以按照以下步骤进行操作: 1. 首先,确保您的计算机已经安装了适当的 NVIDIA 显卡驱动程序,并且支持 CUDA 和 cuDNN。您可以在 NVIDIA 的官方网站上找到相应的驱动程序和支持的 CUDA 版本。 2. 接下来,安装适用于 TensorFlow-GPU 的 CUDA 工具包。您可以从 NVIDIA 的开发者网站上下载并安装与您的显卡驱动程序兼容的 CUDA 版本。 3. 安装 cuDNN 库,这是用于加速深度神经网络训练的 NVIDIA 库。您需要从 NVIDIA 的开发者网站上下载并安装与您安装的 CUDA 版本兼容的 cuDNN 版本。 4. 创建一个虚拟环境(可选),并在其中安装 TensorFlow-GPU。您可以使用 conda、virtualenv 或者其他工具来创建和管理虚拟环境。 5. 在虚拟环境中使用 pip 命令安装 TensorFlow-GPU。例如,使用以下命令可以安装 TensorFlow-GPU 2.0 版本: ``` pip install tensorflow-gpu==2.0 ``` 6. 安装完毕后,您可以通过导入 TensorFlow 库并执行一些简单的代码来验证 GPU 是否正常工作。例如,您可以尝试运行以下代码: ```python import tensorflow as tf # 检查 GPU 是否可用 print(tf.test.is_gpu_available()) # 打印 GPU 设备名称 print(tf.config.list_physical_devices('GPU')) ``` 如果输出结果显示 GPU 可用,并列出了您的 GPU 设备信息,则说明 TensorFlow-GPU 已成功安装并与 GPU 正常配合工作。 请注意,确保您的硬件和软件配置符合 TensorFlow-GPU 的要求,并且按照官方文档提供的指南进行操作。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纯洁的小火车

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值