Python 在GPU上加速TF/Keras LSTM文本生成?
tensorflow文本生成的官方示例()在如下定义的循环中运行。文本生成感觉很慢,根据NVTOP的说法,它只使用了可用GPU资源的一小部分(15-20%) 有没有关于如何加快文本生成的建议?快速查看cprofiler可以发现,90%的时间都花在单行Python 在GPU上加速TF/Keras LSTM文本生成?,python,performance,tensorflow,keras,Python,Performance,Tensorflow,Keras,tensorflow文本生成的官方示例()在如下定义的循环中运行。文本生成感觉很慢,根据NVTOP的说法,它只使用了可用GPU资源的一小部分(15-20%) 有没有关于如何加快文本生成的建议?快速查看cprofiler可以发现,90%的时间都花在单行predictions=model(input\u eval)上,因此我认为其他地方没有太多的收益 此外,Tensorflow/Keras文档建议调用函数,如下所示 这种方法是为在大规模输入下的性能而设计的。对于 一批适合的少量输入,直接使用调用
predictions=model(input\u eval)
上,因此我认为其他地方没有太多的收益
此外,Tensorflow/Keras文档建议调用函数,如下所示
这种方法是为在大规模输入下的性能而设计的。对于
一批适合的少量输入,直接使用调用
建议用于更快的执行,例如型号(x)或型号(x、,
培训(错误)
有没有关于如何加快文本生成的建议?通过同时生成多条线路,是否有可能更好地使用GPU
def generate_text(model, start_string):
# Evaluation step (generating text using the learned model)
# Number of characters to generate
num_generate = 1000
# Converting our start string to numbers (vectorizing)
input_eval = [char2idx[s] for s in start_string]
input_eval = tf.expand_dims(input_eval, 0)
# Empty string to store our results
text_generated = []
# Low temperatures results in more predictable text.
# Higher temperatures results in more surprising text.
# Experiment to find the best setting.
temperature = 1.0
# Here batch size == 1
model.reset_states()
for i in range(num_generate):
predictions = model(input_eval)
# remove the batch dimension
predictions = tf.squeeze(predictions, 0)
# using a categorical distribution to predict the character returned by the model
predictions = predictions / temperature
predicted_id = tf.random.categorical(predictions, num_samples=1)[-1,0].numpy()
# We pass the predicted character as the next input to the model
# along with the previous hidden state
input_eval = tf.expand_dims([predicted_id], 0)
text_generated.append(idx2char[predicted_id])
return (start_string + ''.join(text_generated))
不确定您是否可以加快生成。对于批量大小为1的输入,您正在对模型执行
num\u generate
转发调用。在训练期间,您可以对整个序列进行操作并计算其损失,在预测期间,每个新角色取决于先前生成的角色,并且生成函数不会并行运行
如果你想看到更高的GPU利用率,你可以调用predict对一批不同起始字符的输入进行预测——这与你关于“同时生成多行”的问题有关
您还可以尝试使用相同的起始字符并修改隐藏状态以输入到模型中,例如,查看批次的随机采样状态会产生什么,或从训练示例中提取该起始角色的隐藏状态向量,并用这些向量填充批次隐藏状态,以便您的模型与该初始角色的方向不同。为了加快处理速度,我有两个建议
GRU
层的unroll=True
。根据KerasGRU
,设置unroll=True
通过使用一些额外内存来减少一些计算。由于您的GPU消耗量非常少,您可能希望使用unroll=True
。使用此设置,您可能会注意到多达2倍的速度提升(取决于具体情况)。但是,如果输入序列太长,则应避免使用展开
GRU
层的文本生成架构在密集层之前。GRU
被赋予一个参数return\u sequences=True
。这会导致GRU
层将不必要的输出值传递给以下密集层
层,需要更多的计算。通常,仅当模型的下一层也是RNN层时,才应设置return\u sequences=True
。因此,请尝试设置参数return\u sequences=False
。这也可以提高性能
最后,
模型(x,training=False)
确实有效。我相信通过维护这三个问题,您可能会注意到显著的性能改进。如果您设置unroll=True
,那么将不会使用GRU的CUDNN实现。CUDNN实现比其他GPU实现快得多(大约10倍)。是的,你是对的。在大多数情况下,CUDNN的性能优于一般实现。但是,我注意到在某些情况下(我相信在大多数情况下),使用“展开”可以提高性能(我不知道为什么,但我经历过)。这就是为什么我已经添加了一个短语“(视情况而定)”。此外,我还记得在前面的一个问题上回答了这个问题。我经历了性能提升,提问的人也经历了。实际上,在我的例子中,使用unroll=True可以提高大约50%的速度。我正在运行一个conv net,后面是一个fc lstm层。您是否尝试将@tf.function
添加到此生成文本
函数?有一些问题需要解决才能使其正常工作,但这将使您从急于执行到图形执行,在图形执行中可以更好地进行编译。