【问题标题】:Keras shows no Improvements to training speed with GPU (partial GPU usage?!)Keras 没有显示使用 GPU 对训练速度的改进(部分 GPU 使用?!)
【发布时间】:2017-11-30 12:54:46
【问题描述】:

我正在尝试在我的 Jupyter Notebook 上的 AWS p2.xlarge 实例上的 GPU 而不是 CPU 上训练我的模型。我正在使用 tensorflow-gpu 后端(仅在 requirements.txt 中安装并提到了 tensorflow-gpu 而不是 tensorflow)。

与使用 CPU 相比,在这些实例上训练模型时,我没有看到任何速度提升,事实上,我获得的每个 epoch 的训练速度几乎与我在 4 核笔记本电脑 CPU 上获得的速度相同(p2.xlarge 也是有 4 个 vCPU 和一个 Tesla K80 GPU)。我不确定是否需要对代码进行一些更改以适应 GPU 可以提供的更快/并行处理。我正在为我的模型粘贴下面的代码:

model = Sequential()
model.add(recurrent.LSTM(64, input_shape=(X_np.shape[1], X_np.shape[2]),
                        return_sequences=True))
model.add(recurrent.LSTM(64, return_sequences = False))
model.add(core.Dropout(0.1))
model.add(core.Dense(3, activation='softmax'))
model.compile(loss = 'categorical_crossentropy', optimizer = 'rmsprop', metrics=['accuracy'])

model.fit(X_np, y_np, epochs=100, validation_split=0.25)

另外有趣的是,每次我使用nvidia-smi 检查 GPU 状态时,GPU 似乎都在利用其 50%-60% 的处理能力和几乎所有的内存(但当不使用时,两者分别下降到 0% 和 1MiB培训):

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 384.81                 Driver Version: 384.81                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla K80           On   | 00000000:00:1E.0 Off |                    0 |
| N/A   47C    P0    73W / 149W |  10919MiB / 11439MiB |     52%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      1665      C   ...ubuntu/aDash/MLenv/bin/python 10906MiB |
+-----------------------------------------------------------------------------+

另外,如果您想查看我在 Jupyter Notebook 中使用 GPU 的日志:

[I 04:21:59.390 NotebookApp] Kernel started: c17bc4d1-fa15-4b0e-b5f0-87f90e56bf65
[I 04:22:02.241 NotebookApp] Adapting to protocol v5.1 for kernel c17bc4d1-fa15-4b0e-b5f0-87f90e56bf65
2017-11-30 04:22:32.403981: I tensorflow/core/platform/cpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX AVX2 FMA
2017-11-30 04:22:33.653681: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:892] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2017-11-30 04:22:33.654041: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1030] Found device 0 with properties:
name: Tesla K80 major: 3 minor: 7 memoryClockRate(GHz): 0.8235
pciBusID: 0000:00:1e.0
totalMemory: 11.17GiB freeMemory: 11.10GiB
2017-11-30 04:22:33.654070: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1120] Creating TensorFlow device (/device:GPU:0) -> (device: 0, name: Tesla K80, pci bus id: 0000:00:1e.0, compute capability: 3.7)
2017-11-30 04:22:34.014329: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1120] Creating TensorFlow device (/device:GPU:0) -> (device: 0, name: Tesla K80, pci bus id: 0000:00:1e.0, compute capability: 3.7)
Device mapping:
/job:localhost/replica:0/task:0/device:GPU:0 -> device: 0, name: Tesla K80, pci bus id: 0000:00:1e.0, compute capability: 3.7
2017-11-30 04:22:34.015339: I tensorflow/core/common_runtime/direct_session.cc:299] Device mapping:
/job:localhost/replica:0/task:0/device:GPU:0 -> device: 0, name: Tesla K80, pci bus id: 0000:00:1e.0, compute capability: 3.7

2017-11-30 04:23:22.426895: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1120] Creating TensorFlow device (/device:GPU:0) -> (device: 0, name: Tesla K80, pci bus id: 0000:00:1e.0, compute capability: 3.7)

请提出可能是什么问题。非常感谢您看这个!

【问题讨论】:

  • 您也可以发布您的 CPU 使用情况吗?可能您的瓶颈是将数据输入模型的部分。
  • 你的数据集的大小(X_np 和 y_np 的形状)是多少?
  • @AbderrahimKitouni 34000x7x5(样本 x 时间步长 x 特征)用于 34000x1 的输入和目标

标签: tensorflow keras


【解决方案1】:

这是因为您使用的是 LSTM 层。

Tensorflow 对 LSTM 层的实现并不是那么好。原因可能是循环计算不是并行计算,而 GPU 非常适合并行处理。

我根据自己的经验证实了这一点:

  • 在我的模型中使用 LSTM 获得了可怕的速度
  • 决定测试去除所有LSTM的模型(得到一个纯卷积模型)
  • 由此产生的速度简直令人惊讶!!!

这篇关于使用 GPU 和 tensorflow 的文章也证实了这一点:

可能的解决方案?

您可以尝试使用新的CuDNNLSTM,它似乎是专门为使用 GPU 准备的。

我从未测试过它,但你很可能会得到更好的性能。

我还没有测试过的另一件事,我不确定它是出于这个原因而设计的,但我怀疑它是:你可以将unroll=True 放在你的 LSTM 层中。有了这个,我怀疑循环计算将被并行转换。

【讨论】:

  • 我有一段时间没有浏览 keras 文档,并检查了 cudnn 层是在 10 月添加的。我对我的数据进行了试驾,发现每个 epoch 的训练减少到三分之一,而没有做任何其他更改。将在一两天内对此进行更多检查。
【解决方案2】:

尝试在model.fit 中为batch_size 使用更大的值,因为默认值为32。增加它直到获得 100% 的 CPU 利用率。

根据@dgumo 的建议,您也可以将数据放入/run/shm。这是一个内存文件系统,它允许以最快的方式访问数据。或者,您可以确保您的数据至少驻留在 SSD 上。例如/tmp

【讨论】:

  • 同意。 LSTM 训练速度很慢,但增加批量大小应该会有很大帮助。您还可以尝试其他类型的循环层,例如 GRU 或新发布的SRU
【解决方案3】:

在您的案例中,瓶颈是向 GPU 传输数据和从 GPU 传输数据。加快计算速度(并最大化 GPU 使用率)的最佳方法是一次加载尽可能多的数据,因为你的内存可以容纳。由于您有足够的内存,您可以通过以下方式一次性放置所有数据:

model.fit(X_np, y_np, epochs=100, validation_split=0.25, batch_size=X_np.shape[0])

(您还应该在执行此操作时增加 epoch 的数量)。

但请注意,小批量有一些优势(例如,更好地处理局部最小值),因此您可能应该考虑在两者之间选择一个 batch_size。

【讨论】:

    猜你喜欢
    • 2018-08-14
    • 2021-03-17
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 2018-03-12
    • 2021-09-07
    相关资源
    最近更新 更多