我正在训练一个关于 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 上运行。