Windows 上 tensorflow-gpu 出現 CUDNN_STATUS_BAD_PARAM 的解法

當我在 Windows 10 + CUDA 8.0 + cuDNN 6 + Tensorflow-gpu 1.3.0 環境下執行程式時,一直出現以下訊息

name: GeForce GTX 960
major: 5 minor: 2 memoryClockRate (GHz) 1.304
pciBusID 0000:01:00.0
Total memory: 2.00GiB
Free memory: 1.64GiB

...\core\common_runtime\gpu\gpu_device.cc:976] DMA: 0
...\core\common_runtime\gpu\gpu_device.cc:986] 0:   Y
...\core\common_runtime\gpu\gpu_device.cc:1045] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GeForce GTX 960, pci bus id: 0000:01:00.0)
...\stream_executor\cuda\cuda_dnn.cc:371] could not create cudnn handle: CUDNN_STATUS_NOT_INITIALIZED
...\stream_executor\cuda\cuda_dnn.cc:375] error retrieving driver version: Unimplemented: kernel reported driver version not implemented on Windows
...\stream_executor\cuda\cuda_dnn.cc:338] could not destroy cudnn handle: CUDNN_STATUS_BAD_PARAM
...\core\kernels\conv_ops.cc:672] Check failed: stream->parent()->GetConvolveAlgorithms( conv_parameters.ShouldIncludeWinogradNonfusedAlgo<T>(), &algorithms)

這個問題找了很久以後發現是 GPU 上的記憶體不夠,根據上圖可以發現總量 2 GB 的記憶體中只剩下 1.64 GB 的可用記憶體,因此只要在程式中限制記憶體使用量即可。

# 原本的
sess = tf.Session()
sess.run(init)

# 更改成
config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.7

sess = tf.Session(config=config)
sess.run(init)

強制將 GPU 記憶體使用量限制在 70% (1.4 GB),就可以解決這問題了。

#這是我寫過最快的一篇 Medium 文章了

補充

根據 TensorFlow 官方文件 中關於使用 GPU 相關的部分有提到,TF 預設在啟動時會盡可能的吃滿所有 GPU 可用的記憶體空間,藉此減少 memory fragmentation 的問題。

而看來正是因為這原因,當 GPU 記憶體不夠用時就容易出錯,所以有了兩種可能解決方法的設定

  1. per_process_gpu_memory_fraction 如同上面說到的方法,強制限制程式可用的記憶體比例,藉此避免初始 allocate 時出錯。
  2. allow_growth
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
session = tf.Session(config=config)

allow_growth 設為 True 時,程式只會 allocate 實際需要的記憶體空間,當需求更多時再次 allocate,直到可能造成更糟高的 memory fragmentation 為止,這作法的優點在於比較節省記憶體空間。

根據我自己嘗試的狀況來說,雖然我的 GPU 還有 82% 的可用記憶體,但是把 per_process_gpu_memory_fraction 設為 0.8(80%) 時依舊會出錯,因此只設定了 0.7(70%)。

allow_growth 對我來說沒有效果,但部份的人則相反,因此可能要注意 log 以及多嘗試幾個設定才會有效。

前幾天跟合作單位的人開 Machine Learning 相關的會議中,對方就說到「Train model 的 tuning 就像是煉金術一樣。

深感認同啊!