0

我正在训练一个关于 tensorflow 的稀疏逻辑回归模型。这个问题专门针对推理部分。我正在尝试对 cpu 和 gpu 的推理进行基准测试。我在我当前的 GCE 盒子上使用 Nvidia P100 gpu(4 个芯片)。我是 gpu 的新手,很抱歉提出一些幼稚的问题。

该模型相当大~54k 操作(与 dnn 或 imagenet 模型相比,它被认为是大吗?)。当我记录设备放置时,我只看到 gpu:0 正在使用,其余的未使用?我在训练期间不做任何设备放置,但在推理期间我希望它以最佳方式放置和使用 gpu。我观察到的几件事:我的输入节点占位符(feed_dict)放在 cpu 上,所以我假设我的数据正在从 cpu 复制到 gpu?feed_dict 在幕后究竟是如何工作的?

1)如何将我想直接在 GPU 上运行预测的数据放置?注意:我的训练在具有多个 TB 的分布式 cpu 上运行,因此在训练期间我不能直接在我的图表中使用常量或变量,但我的推断我肯定可以有我想直接放在 gpu 上的小批量数据。我有办法做到这一点吗?2)由于我使用的是P100 gpu,我认为它与主机具有统一的内存,是否可以进行零拷贝并直接将我的数据加载到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 与 gpu 上的内核调用开销(我假设每次调用 sess.运行调用 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 是我唯一看到的时间我幼稚的基准测试表明,与 cpu 相比,gpu 的增益很小。增加给定 epoch 的批大小对 cpu 和 gpu 的时间影响最小,直到批大小 <= 10k。但是在从 10k -> 100k -> 200k 增加批量大小之后,时间也增加得非常快,即对于给定的时期,让我们说 10 个批量大小为 10、100、1k、10k,cpu 时间和 gpu 时间保持相当稳定~5- gpu 为 7 秒,cpu 为 0.48-0.96 秒(这意味着 sess.run 的开销比计算图形本身的开销要高得多?),但是随着批量大小的进一步增加,计算时间会以更快的速度增加,即对于 epoch 10 100k-> 200k gputime 从 11 -> 19 秒增加,cpu 时间也翻倍,为什么会这样?即使我只有一个 sess.run 似乎更大的批量大小,但在内部它将它分成更小的批量并调用 sess.run 两次,因为 epoch 20 batch size 100k 与 epoch 10 batch 200k 更匹配。

我怎样才能进一步改进我的推理,我相信我没有以最佳方式使用所有 gpus。关于如何更好地进行基准测试以获得更好的 cpu-> gpu 传输时间和图形计算从 cpu 移动到 gpu 的实际加速,有什么想法吗?如果可能的话,直接将数据更好地加载到 gpu 中?我可以仅在推理期间将一些节点放置到 gpu 以获得更好的性能吗?关于量化或优化推理图的想法?

改进基于 gpu 的推理的更多想法。可能是基于 xla 的优化或 tensrort ?我希望有高性能的推理代码在 gpu 上运行这些计算,而应用程序服务器在 cpu 上运行。

4

1 回答 1

0

信息来源之一是关于性能的 TensorFlow 文档,包括Optimizing for GPU and High Performance Models

也就是说,这些指南倾向于针对训练而不是批量推理,尽管某些原则肯定仍然适用。

我会注意到,除非您使用 DistributionStrategy,否则 TensorFlow 不会自动将操作放在多个 GPU(来源)上。

在您的特殊情况下,我认为 GPU 还没有经过很好的调整来执行您的模型所需的稀疏操作类型,所以我实际上并不希望它在 GPU 上做得那么好(如果您记录设备放置有可能在 CPU 上完成查找)。逻辑回归模型只有一个(稀疏)输入层和一个输出层,因此通常很少有数学运算。GPU 在进行大量矩阵乘法、卷积等时表现最为出色。

最后,我鼓励您使用 TensorRT 来优化您的图表,尽管对于您的特定模型,不能保证它会做得更好。

于 2018-05-17T05:34:01.463 回答