lstm 将不会使用 cuDNN 内核,因为它不符合标准。在 GPU 上运行时,它将使用通用 GPU 内核作为后备

Muh*_*ary 19 python lstm tensorflow databricks

我正在使用 GPU 在 Databricks 上运行以下 LSTM 代码

model = Sequential()
model.add(LSTM(64, activation=LeakyReLU(alpha=0.05), batch_input_shape=(1, timesteps, n_features), 
    stateful=False, return_sequences = True))
model.add(Dropout(0.2))
model.add(LSTM(32))
model.add(Dropout(0.2))
model.add(Dense(n_features))
model.compile(loss='mean_squared_error', optimizer=Adam(learning_rate = 0.001), metrics='acc')
model.fit(generator, epochs=epochs, verbose=0, shuffle=False)
Run Code Online (Sandbox Code Playgroud)

但不断出现以下警告

WARNING:tensorflow:Layer lstm will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU.
Run Code Online (Sandbox Code Playgroud)

它的训练速度比没有 GPU 时慢得多。我正在使用 DBR 9.0 ML(包括 Apache Spark 3.1.2、GPU、Scala 2.12),我是否需要任何其他库?

cha*_*255 33

CUDNN 具有专门加速 LSTM 和 GRU 层的功能。这些 GRU/LSTM 层只有满足特定标准才能加速。在您的情况下,问题是您正在使用 LeakyReLU 激活。CUDNN LSTM 加速仅在激活为 tanh 时才起作用。

引用文档(https://www.tensorflow.org/api_docs/python/tf/keras/layers/LSTM)

The requirements to use the cuDNN implementation are:

activation == tanh
recurrent_activation == sigmoid
recurrent_dropout == 0
unroll is False
use_bias is True
Inputs, if use masking, are strictly right-padded.
Eager execution is enabled in the outermost context.
Run Code Online (Sandbox Code Playgroud)

您的 LSTM 仍应在 GPU 上运行,但它将使用扫描和 matmul 操作构建,因此速度要慢得多。根据我的经验,CUDNN LSTM/GRU 加速效果非常好,以至于这两个层的运行速度都比 SimpleRNN 层(未由 CUDNN 加速)快,尽管该层要简单得多。


小智 7

这是 keras 库的创建者、tensorflow 框架的主要贡献者 Francois Chollet 在他的《Deep Learning with Python 2nd Edition》一书中关于 RNN 运行时性能的评价

\n
\n

参数很少的循环模型(如本章中的模型)在多核 CPU 上往往比在 GPU 上快得多,因为它们只涉及小型矩阵乘法,并且由于存在for 循环。但较大的 RNN 可以从 GPU 运行时中受益匪浅。

\n
\n
\n

当在 GPU 上使用带有默认关键字参数的 Keras LSTM 或 GRU 层时,您的层将利用 cuDNN 内核,这是 NVIDIA 提供的高度优化的低级底层算法实现。和往常一样,cuDNN 内核是喜忧参半:它们\xe2\x80\x99 很快,但不灵活\xe2\x80\x94 如果你尝试做任何默认内核不支持的事情,你将遭受戏剧性的减速,这更多或者更少迫使您坚持使用 NVIDIA 恰好提供的功能。例如,LSTM 和 GRU cuDNN 内核不支持循环 dropout,因此将其添加到层会强制运行时回退到常规 TensorFlow 实现,这在 GPU 上通常慢两到五倍(即使其计算成本是相同的)。

\n
\n
\n

当您无法使用 cuDNN 时,作为加速 RNN 层的一种方法,您可以尝试展开它。展开 for 循环包括删除循环并简单地将其内容内联 N 次。对于 RNN 的 for 循环来说,展开可以帮助 TensorFlow 优化底层计算图。然而,它也会大大增加 RNN\xe2\x80\x94 的内存消耗,因此,它\xe2\x80\x99 仅适用于相对较小的序列(大约 100 个步骤或更少)。另请注意,只有在模型提前知道数据中的时间步数的情况下(也就是说,如果将没有任何 None 条目的形状传递给初始 Input() ),您才能执行此操作。它的工作原理如下:

\n
\n
    inputs = keras.Input(shape=(sequence_length, num_features))\n    x = layers.LSTM(32, recurrent_dropout=0.2, unroll=True)(inputs)\n
Run Code Online (Sandbox Code Playgroud)\n