【问题标题】:Bug when using TensorFlow-GPU + Python multiprocessing?使用 TensorFlow-GPU + Python 多处理时的错误?
【发布时间】:2017-12-20 14:38:15
【问题描述】:

当我使用 TensorFlow-GPU + Python 多处理时,我注意到一个奇怪的行为。

我已经实现了一个DCGAN,其中包含一些自定义项和我自己的数据集。由于我让 DCGAN 适应某些特征,因此我有训练数据和测试数据以进行评估。

由于我的数据集的大小,我编写了并发运行的数据加载器,并使用 Python 的 multiprocessing 预加载到队列中。

代码的结构大致是这样的:

class ConcurrentLoader:
    def __init__(self, dataset):
        ...

class DCGAN
     ...

net = DCGAN()
training_data = ConcurrentLoader(path_to_training_data)
test_data = ConcurrentLoader(path_to_test_data)

此代码在 TensorFlow-CPU 上运行良好在 TensorFlow-GPU TensorFlow-GPU 1.4.1 运行完全相同的代码时和 CUDA 9(截至 2017 年 12 月的 TF 和 CUDA 的最新版本)崩溃:

2017-12-20 01:15:39.524761: E tensorflow/stream_executor/cuda/cuda_blas.cc:366] failed to create cublas handle: CUBLAS_STATUS_NOT_INITIALIZED
2017-12-20 01:15:39.527795: E tensorflow/stream_executor/cuda/cuda_blas.cc:366] failed to create cublas handle: CUBLAS_STATUS_NOT_INITIALIZED
2017-12-20 01:15:39.529548: E tensorflow/stream_executor/cuda/cuda_blas.cc:366] failed to create cublas handle: CUBLAS_STATUS_NOT_INITIALIZED
2017-12-20 01:15:39.535341: E tensorflow/stream_executor/cuda/cuda_dnn.cc:385] could not create cudnn handle: CUDNN_STATUS_INTERNAL_ERROR
2017-12-20 01:15:39.535383: E tensorflow/stream_executor/cuda/cuda_dnn.cc:352] could not destroy cudnn handle: CUDNN_STATUS_BAD_PARAM
2017-12-20 01:15:39.535397: F tensorflow/core/kernels/conv_ops.cc:667] Check failed: stream->parent()->GetConvolveAlgorithms( conv_parameters.ShouldIncludeWinogradNonfusedAlgo<T>(), &algorithms) 
[1]    32299 abort (core dumped)  python dcgan.py --mode train --save_path ~/tf_run_dir/test --epochs 1

真正让我困惑的是,如果我只是删除test_data,则不会发生错误。因此,出于某种奇怪的原因,TensorFlow-GPU 1.4.1 和 CUDA 9 只使用一个 ConcurrentLoader,但是当多个加载器被初始化时会崩溃

更有趣的是(异常之后)我必须手动关闭 python 进程,因为 GPU 的 VRAM、系统的 RAM 甚至 python 进程在脚本崩溃后仍然保持活动状态。

此外,它必须与 Python 的 multiprocessing 模块有一些奇怪的联系,因为当我在 Keras 中实现 same 模型时(使用 TF 后端!)代码也运行得很好,有 2并发加载器。我猜 Keras 以某种方式在两者之间创建了一个抽象层,以防止 TF 崩溃。

我可能在哪里搞砸了 multiprocessing 模块,它会导致像这样的崩溃?

这些是在ConcurrentLoader 中使用multiprocessing 的代码部分:

def __init__(self, dataset):
    ...
    self._q = mp.Queue(64)
    self._file_cycler = cycle(img_files)
    self._worker = mp.Process(target=self._worker_func, daemon=True)
    self._worker.start()

def _worker_func(self):
    while True:
        ... # gets next filepaths from self._file_cycler
        buffer = list()
        for im_path in paths:
            ... # uses OpenCV to load each image & puts it into the buffer
        self._q.put(np.array(buffer).astype(np.float32))

...就是这样。

我在哪里写了“不稳定”或“非pythonic”multiprocessing 代码?我认为daemon=True 应该确保每个进程在主进程死亡后立即被杀死?不幸的是,此特定错误并非如此。

我是否在这里误用了默认的multiprocessing.Processmultiprocessing.Queue?我认为只需编写一个类,将批量图像存储在队列中并通过方法/实例变量访问它就可以了。

【问题讨论】:

    标签: python multithreading tensorflow multiprocessing


    【解决方案1】:

    我在尝试使用 tensorflow 和多处理时遇到了同样的错误

    E tensorflow/stream_executor/cuda/cuda_blas.cc:366] failed to create cublas handle: CUBLAS_STATUS_NOT_INITIALIZED
    

    但在不同的环境中 tf1.4 + cuda 8.0 + cudnn 6.0。 示例代码中的 matrixMulCUBLAS 工作正常。 我也想知道正确的解决方案! 并且引用 failed to create cublas handle: CUBLAS_STATUS_NOT_INITIALIZED on a AWS p2.xlarge instance 对我不起作用。

    【讨论】:

    • 经过几个小时的测试,我遇到了一件非常奇怪的事情:如果 tensorflow 是最后一次导入,并且初始化会话等等最后发生(在初始化数据加载器和所有其他东西之后)它可以工作.至少对于这个特定的 DCGAN。这让我想起了我不久前在 GitHub 上创建的 TensorFlow 问题:segmentation fault with tensorflow 0.8.0 and matplotlib #2085。这也是 TensorFlow 内部的一个错误:如果最后导入 TF,则工作正常,如果先导入 TF(与 matplotlib 等其他库一起),则会出现段错误
    • 如果您切换导入顺序(向下移动 TF)并尽可能晚地启用会话和内容,您的错误是否也消失了,您可以试试吗?
    • 仍然未能解决同样的问题。实际上,我正在尝试训练一个多代理系统(每个代理都有一个网络)。并且为了得到低相关性的批量数据,我使用多工作(multiprocessing)来收集数据。但是,它在这里停留了一整天..
    • @daniel451:我遇到了类似的问题,你能看看吗? stackoverflow.com/questions/54402154/…
    猜你喜欢
    • 2019-05-05
    • 2015-10-29
    • 1970-01-01
    • 1970-01-01
    • 2019-05-22
    • 2019-04-27
    • 2018-05-27
    • 1970-01-01
    • 2017-11-27
    相关资源
    最近更新 更多