我正在训练一个关于张量流的稀疏逻辑回归模型。该问题具体涉及推理部分。我正在尝试对cpu和gpu进行基准测试。我在我目前的GCE盒子上使用Nvidia P100 gpu(4个模具)。我是gpu的新手,很抱歉天真的问题。
该模型相当大〜54k操作(与dnn或imagenet模型相比它被认为是大的吗?)。当我记录设备放置时,我只看到正在使用的gpu:0,其余的未使用?我不会在训练期间进行任何设备放置,但在推理期间,我希望它能够最佳地放置和使用gpu。 我观察到的一些事情:我的输入节点placehoolder(feed_dict)放在cpu上,所以我假设我的数据是从cpu复制到gpu的? feed_dict如何正好在幕后工作?
1)如何在gpu上直接放置我想要运行预测的数据?注意:我的训练运行在具有多TB的分布式cpu上,所以我在训练期间不能直接在我的图形中使用常量或变量,但我推断我肯定会有小批量的数据,我会直接放在gpu上。我有办法实现这个目标吗? 2)由于我使用的是P100 gpu,我认为它与主机有统一的内存,是否有可能有zerocopy并直接将我的数据加载到gpu中?我怎么能从python,java和c ++代码中做到这一点。目前我使用来自各种谷歌来源的feed_dict我认为根本不是最佳的。 3)是否有一些工具或分析器可用于查看我的代码如何:
for epoch_step in epochs:
start_time = time.time()
for i in range(epoch_step):
result = session.run(output, feed_dict={input_example: records_batch})
end_time = time.time()
print("Batch {} epochs {} :time {}".format(batch_size, epoch_step, str(end_time - start_time)))
花费了多少时间1)cpu到gpu数据传输2)会话运行开销3)gpu利用率(目前我定期使用nvidia-smi来监控 4)cpu vs gpu上的内核调用开销(我假设sess.run的每个invokation调用1个内核调用对吗?
我目前的替补标记结果: CPU:
Batch size : 10
NumberEpochs TimeGPU TimeCPU
10 5.473 0.484
20 11.673 0.963
40 22.716 1.922
100 56.998 4.822
200 113.483 9.773
Batch size : 100
NumberEpochs TimeGPU TimeCPU
10 5.904 0.507
20 11.708 1.004
40 23.046 1.952
100 58.493 4.989
200 118.272 9.912
Batch size : 1000
NumberEpochs TimeGPU TimeCPU
10 5.986 0.653
20 12.020 1.261
40 23.887 2.530
100 59.598 6.312
200 118.561 12.518
Batch size : 10k
NumberEpochs TimeGPU TimeCPU
10 7.542 0.969
20 14.764 1.923
40 29.308 3.838
100 72.588 9.822
200 146.156 19.542
Batch size : 100k
NumberEpochs TimeGPU TimeCPU
10 11.285 9.613
20 22.680 18.652
40 44.065 35.727
100 112.604 86.960
200 225.377 174.652
Batch size : 200k
NumberEpochs TimeGPU TimeCPU
10 19.306 21.587
20 38.918 41.346
40 78.730 81.456
100 191.367 202.523
200 387.704 419.223
一些值得注意的观察: 随着批量增加,我看到我的gpu利用率增加(它使用的唯一gpu达到100%,有没有办法告诉tf使用其他gpu) 在批量大小200k是唯一一次我看到我的天真基准测试显示gpu与cpu相比有微小的收益。 增加给定时期的批量大小对cpu和gpu的时间影响最小,直到批量大小<= 10k。但在此之后,批量增加10k - > 100k - &gt; 200k的时间也增加得相当快,即对于给定的时代让我们说10批量大小10,100,1k,10k的cpu时间和gpu时间保持相当稳定~gpu为5-7秒,cpu为0.48-0.96秒(含义sess.run比计算图形本身具有更高的开销?),但是进一步增加批量大小,计算时间以更快的速率增加,即对于时期10 100k-> 200k gputime从11增加到&gt; 19秒和cpu时间也加倍,为什么呢?似乎更大的批量大小,即使我只有一个sess.run,但在内部它将它分成更小的批次并调用sess.run两次,因为epoch 20批量大小100k与epoch 10批次200k更紧密匹配..
如何进一步改进我的推理,我相信我并没有最佳地使用所有gpus。 是否有任何想法可以更好地进行基准测试,以便更好地分解cpu->的时间;从cpu移动到gpu的图形计算的gpu传输和实际加速? 如果可能零拷贝到gpu,直接加载数据更好? 我可以在推理期间将一些节点放到gpu中以获得更好的性能吗? 关于量化或优化推理图的想法?
更多改进基于gpu的推理的想法。可能是基于xla的优化还是紧张?我希望有高性能的推理代码在应用程序服务器在cpu上运行时在gpu上运行这些计算。
答案 0 :(得分:0)
一个信息来源是关于效果的TensorFlow文档,包括Optimizing for GPU和High Performance Models。
尽管如此,这些指南倾向于针对培训而不是批量推断,但肯定有一些原则仍然适用。
我会注意到,除非您使用的是DistributionStrategy,否则TensorFlow不会自动将操作放在多个GPU上(source)。
在你特别的情况下,我不相信GPU已经很好地调整了你的模型所需的稀疏操作类型,所以我真的不希望它在GPU上做得那么好(如果您在那里记录设备放置,则有可能在CPU上完成查找)。逻辑回归模型只有(稀疏)输入层和输出层,因此通常只有很少的数学运算。 GPU在进行大量矩阵乘法,卷积等时表现最佳。
最后,我建议您使用TensorRT来优化您的图表,但对于您的特定型号,我们并不能保证它能做得更好。