详解Keras(tf)报错:"BaseCollectiveExecutor::StartAbort Unknown: Failed to get convolution algorithm"

今天用keras内置的VGG16跑模型时遇到了这个报错,在确定不是CUDA等环境版本问题后,矛头指向了是因为显存分配没搞好造成的。(我的电脑只有一块菜卡4G显存)

2020-05-08 00:59:24.206906: E tensorflow/stream_executor/cuda/cuda_dnn.cc:329] Could not create cudnn handle: CUDNN_STATUS_ALLOC_FAILED
2020-05-08 00:59:24.207493: E tensorflow/stream_executor/cuda/cuda_dnn.cc:329] Could not create cudnn handle: CUDNN_STATUS_ALLOC_FAILED
2020-05-08 00:59:24.207802: W tensorflow/core/common_runtime/base_collective_executor.cc:217] BaseCollectiveExecutor::StartAbort Unknown: Failed to get convolution algorithm. 
This is probably because cuDNN failed to initialize, so try looking to see if a warning log message was printed above.

解决办法:

在程序开头加上这段代码

import tensorflow as tf
config = tf.compat.v1.ConfigProto(allow_soft_placement=True)
config.gpu_options.per_process_gpu_memory_fraction = 0.3
tf.compat.v1.keras.backend.set_session(tf.compat.v1.Session(config=config))

来分析一下这段代码以及问题原因:

  • 众所周知,keras以TensorFlow做后台时,TensorFlow会默认吃掉所有可用的显存(即便此时没有用到做计算,这些显存也会显示占用来待命)

  • 第二行的0.3,意思是限制每个模型只能分配30%的显存,不允许吃掉所有。当然这是理论值,当实际开始计算时,如果需要,依然可以超出这个理论值。

为什么这样做可以:

下面是我程序开头实例化VGG16,第一处占用显存的地方,此时不加入上面的限制分配显存的代码,虽然此时还并未做任何计算,但是当这行运行完时,keras已经开始占用显存待命
在这里插入图片描述
在这里插入图片描述

此时注意,显示占用了3.1G,然后我们在控制台输出寻找一下
下面的三行提示可以看到,keras果然先试图占据4.00G,吃掉整个显卡,但是系统此时可能有别的程序在占用,或是window的什么神奇策略,总之不允许这样的情况发生。于是退而求其次,直到3.24G依然失败,继续退,到3.1G就成功了,所以也就有了上图中的占用。

在这里插入图片描述

下图中的代码,是我程序中第二处占用显存的地方,这里用开头的VGG16进行计算,但是我发现,报错就会出现在这一行,显存的占用会突然涨一下然后立刻报错停止。

在这里插入图片描述

于是我加上解决办法中写的限制代码,再次运行,这时候开头实例化VGG16后,显存的占用减少了,并且没有像第一次报分配显存失败的提示,这是因为加了限制,所以keras就自然不会去尝试吃掉整个卡。

在这里插入图片描述

然后继续运行到第二处,发现此时显存占用涨了0.4,这也就印证了开头说的,限制是可以适当突破的,并且此时程序不再报错顺利完成。
并且我多次改变限制值,发现只会影响开头VGG16实例化时占用的显存大小,而不会影响第二次占用时的大小,可能因为是计算确确实实需要这些吧。

在这里插入图片描述


希望你看懂了上面的过程,于是我们可以得出粗略结论,keras(tf)能够占用的显存首先受到系统等未知因素的限制(不人为添加限制的时候)。但是如果我们不人为加以限制的话,那么就会吃掉所有可用的空间,当第二次需要占用显存时,0.4就无处可分配了(此时加起来需要3.5),因为开头已经占用了很多。而人为加上限制,那么第二次占用时就有空间了。


以上理论仅仅是我试多次试验和观察得出的结果,虽然我多次观察到,在跑别的模型时,有的也能突破3.1G并顺利运行,因为我怀疑真正的可用空间大于3.1G,小于3.5G,可能因为模型差异等问题,所谓“不加限制时,吃掉全部显存“”也并不是绝对的。


欢迎留言讨论这个问题

原创文章 41 获赞 156 访问量 1万+

猜你喜欢

转载自blog.csdn.net/CxsGhost/article/details/105985955
今日推荐