【问题标题】:Why is the per sample prediction time on Tensorflow (and Keras) lower when predicting on batches than on individual samples?为什么在批量预测时,Tensorflow(和 Keras)上的每个样本预测时间比对单个样本的预测时间要短?
【发布时间】:2018-10-11 16:59:25
【问题描述】:

我正在使用经过训练的模型进行预测(仅限 CPU)。我观察到在 Tensorflow 和带有 Tensorflow 后端的 Keras 上,与单个样本相比,当使用一批样本时,每个样本的预测时间要短得多。此外,每个样本的时间似乎随着批量大小的增加而下降,直到内存施加的限制。例如,在纯 Tensorflow 上,单个样本的预测需要 ~ 1.5 秒,在 100 个样本上是 ~ 17 秒(每个样本时间 ~ 0.17 秒),在 1000 个样本上是 ~ 93 秒(每个样本时间 ~ 0.093 秒) )。

这是正常行为吗?如果是这样,是否对此有直观的解释?我想这可能与初始化图表有关,但我需要澄清一下。另外,为什么随着我们增加预测样本的数量,每个样本的时间会下降?在我的用例中,我必须预测单个样本何时可用。所以,很明显,如果事情是这样工作的,我会在速度方面损失很多。

提前感谢您的帮助。

编辑:我正在添加一个最小的工作示例。我的模型有一个图像输入和 4 个矢量输入,产生 4 个输出。我将所有输入初始化为 0 以进行速度测试(我猜实际值对速度无关紧要?)。初始化时间和推理时间分别计算。我发现初始化时间是推理时间的一小部分(100 个样本约为 0.1 秒)。

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import time
import numpy as np
import tensorflow as tf

t00=time.time()
graph = tf.Graph()
graph_def = tf.GraphDef()

with open("output_graph.pb", "rb") as f:
    graph_def.ParseFromString(f.read())
with graph.as_default():
    tf.import_graph_def(graph_def)

# One image and 4 auxiliary scalar inputs
img_input_layer ="input"
qp4_input_layer ="qp4"
qp3_input_layer ="qp3"
qp2_input_layer ="qp2"
qp1_input_layer ="qp1"
input_name = "import/" + img_input_layer
qp4_input_name = "import/" + qp4_input_layer
qp3_input_name = "import/" + qp3_input_layer
qp2_input_name = "import/" + qp2_input_layer
qp1_input_name = "import/" + qp1_input_layer



input_operation_img = graph.get_operation_by_name(input_name)
input_operation_qp4 = graph.get_operation_by_name(qp4_input_name)
input_operation_qp3 = graph.get_operation_by_name(qp3_input_name)
input_operation_qp2 = graph.get_operation_by_name(qp2_input_name)
input_operation_qp1 = graph.get_operation_by_name(qp1_input_name)

output_operation=[]

for i in range(4):
    output_operation.append(graph.get_operation_by_name("import/" + "output_"+str(i)).outputs)

#Initializing dummy inputs
n=100 # Number of samples for inference
img=np.zeros([n,64, 64,1])
qp4=np.zeros([n,1, 1,1])
qp3=np.zeros([n,2, 2,1])
qp2=np.zeros([n,4, 4,1])
qp1=np.zeros([n,8, 8,1])
t01=time.time()
print("Iniialization time",t01-t00)

t0=time.time()
with tf.Session(graph=graph) as sess:
    results = sess.run(output_operation,
                       {input_operation_img.outputs[0]: img, input_operation_qp4.outputs[0]: qp4, input_operation_qp3.outputs[0]: qp3,  input_operation_qp2.outputs[0]: qp2,  input_operation_qp1.outputs[0]: qp1})

    # print(results)
t1 = time.time()
print("Inference time", t1-t0)

【问题讨论】:

    标签: python performance tensorflow keras runtime


    【解决方案1】:

    这在很大程度上取决于模型工具、部署方法和接口——您都没有提供,甚至没有描述。在我的实践中,常见的原因包括:

    • 模型初始化时间:您是否以某种方式为每个批次“唤醒”模型?如果按照您的建议,为每个请求重新初始化模型,那么开销在您的时间中所占的比例并不大,这让我有些惊讶。
    • 接口开销:样本如何进入/离开模型?这是在 HTTP 请求中,您需要为每个请求而不是每个样本付出通信成本?
    • 简单模型 I/O 时间:如果您的模型一次读取整个批次,则打开和访问输入通道的延迟时间可能是延迟的主要因素。

    您需要做一些工作来诊断根本原因。到目前为止,您只有三个数据点;我建议多收集一些。你能适应时代的图表吗?是否有任何提示系统限制的跳转,例如输入缓冲区大小?您能否使用一些分析代码来检测您的模型,以找出模型中存在哪些滞后,以及系统开销中存在哪些滞后?

    尝试将您的模型部署为服务;当它已经加载到内存中、初始化并且只是等待下一个输入时会发生什么?您的请求界面有多少延迟时间?

    这些调查的结果将向您展示您可以从使用模型中的设计更改中获得哪些好处。

    【讨论】:

    • 我已经编辑了我的问题,为我的模型添加了一个最小的工作示例。在您提到的 3 点中,似乎它大部分时间都花在了初始化和运行会话上。从 protobuf 文件加载模型并将输入初始化为虚拟值只需要一小部分时间。我是否应该假设模型初始化时间是导致速度变慢的主要原因?
    • 是的,这就是您所说的:会话设置和模型初始化是您的问题。一个行业指标是您可以在指定的时间延迟(以毫秒表示)内处理的请求的比例。如果您的部署必须每次都创建一个新会话并重新加载数据,那么您将无法满足这些期望。常见的解决方案是将模型部署为服务:为任何传入请求保持启动和初始化。
    • 酷。我想您提到了 TF 服务,还是有另一种方法将模型部署为服务?不过,这可能是一个不同的问题。
    • 是的,将模型部署为服务是一个不同的问题;您需要先阅读该主题,因为一般的“我如何部署我的模型”对于 SO 来说是相当离题的。有很多方法可以做到这一点,但通过已建立的 TF 流程可能对您来说是最简单的途径。
    【解决方案2】:

    是的,这完全正常。发生这种情况是因为当您在 GPU(甚至多核 CPU)上进行推理时,增加批量大小可以更好地利用 GPU 并行计算资源,从而减少批量中每个样本的时间。如果您使用小批量大小,那么您正在浪费 GPU 中可用的计算资源。

    This paper 描述了相同的效果,其中一张图包含显示每张图像的推理时间与批量大小的关系图。它显示的效果与您看到的相同。

    【讨论】:

    • 但我只使用 CPU 进行推理,尽管模型是使用 GPU 训练的。我想你所说的也适用于 CPU 推理?不过,论文中显示的图表确实很有帮助,感谢您的参考。
    • @user6240174 是的,它也适用于多核 CPU
    猜你喜欢
    • 2018-09-13
    • 1970-01-01
    • 2021-07-07
    • 2023-02-22
    • 2018-11-13
    • 2013-07-13
    • 1970-01-01
    • 1970-01-01
    • 2020-02-20
    相关资源
    最近更新 更多