张量流推理运行时间在第一个数据点上较高,在后续数据点上减少

问题描述 投票:0回答:2

我正在使用 TensorFlow 对象检测模块中的模型之一运行推理。我在同一会话中循环测试图像并执行 sess.run()。然而,在分析这些运行时,我意识到与后续运行相比,第一次运行总是有更长的时间。

我找到了答案here,关于为什么会发生这种情况,但没有解决如何修复的解决方案。

我正在 Intel i7 CPU 上部署对象检测推理管道。一个 session.run()、1、2、3 和第四张图像的时间看起来像(以秒为单位):

1. 84.7132628
2. 1.495621681
3. 1.505012751
4. 1.501652718

只是我所尝试过的背景:

  • 我尝试使用 TensorFlow 提供的 TFRecords 方法作为示例这里。我希望它能更好地工作,因为它不使用 feed_dict。但由于涉及更多的 I/O 操作,我不确定它是否理想。我尝试在不写入磁盘的情况下使其工作,但总是出现一些有关图像编码的错误。

  • 我尝试使用 TensorFlow 数据集来提供数据,但我不确定如何提供输入,因为在推理过程中我需要为图中的“图像张量”键提供输入。关于如何使用它为冻结图提供输入有什么想法吗?

任何帮助将不胜感激!

TLDR:希望减少第一个图像的推理运行时间 - 出于部署目的。

tensorflow deep-learning object-detection object-detection-api pre-trained-model
2个回答
0
投票

尽管我发现第一次推理需要更长的时间,但显示的差异(84 Vs 1.5)似乎有点令人难以置信。您是否也在这个时间指标内计算加载模型的时间?难道这就是大时差造成的差异吗?拓扑有那么复杂吗,这个时间差是合理的吗?

我的建议:

  1. 尝试 Openvino:查看 Openvino 是否支持您正在处理的拓扑。众所周知,OpenVino 具有优化网络操作的能力,可以大幅加快推理工作负载的速度。此外,在大多数情况下,加载 openvino 模型所需的时间相对较短。

  2. 关于 TFRecords 方法,您能否分享确切的错误以及您在哪个阶段收到错误?

  3. 关于 Tensorflow 数据集,您可以查看 https://github.com/tensorflow/tensorflow/issues/23523https://www.tensorflow.org/guide/datasets。关于图中的“图像张量”键,我希望您最初的推理管道应该给您一些线索。


0
投票

TFLite 用户的潜在解决方案

对于那些在使用 TFLite 模型时遇到类似问题并发现自己想知道为什么第一次推理速度较慢的人:

实验#1:在分配张量的同时运行inside推理函数:

{'negative': 0.18444867432117462, 'neutral': 0.07744687795639038, 'positive': 0.738104522228241}
0.4845249652862549
{'negative': 0.18444867432117462, 'neutral': 0.07744687795639038, 'positive': 0.738104522228241}
0.10525012016296387
{'negative': 0.18444867432117462, 'neutral': 0.07744687795639038, 'positive': 0.738104522228241}
0.10430574417114258
{'negative': 0.18444867432117462, 'neutral': 0.07744687795639038, 'positive': 0.738104522228241}
0.1036217212677002
{'negative': 0.18444867432117462, 'neutral': 0.07744687795639038, 'positive': 0.738104522228241}
0.10476112365722656
{'negative': 0.18444867432117462, 'neutral': 0.07744687795639038, 'positive': 0.738104522228241}

如您所见,第一个推论比其余推论长约 5 倍。

实验#2:在分配张量的同时运行outside推理函数:

{'negative': 0.18444867432117462, 'neutral': 0.07744687795639038, 'positive': 0.738104522228241}
0.11817765235900879
{'negative': 0.18444867432117462, 'neutral': 0.07744687795639038, 'positive': 0.738104522228241}
0.10439515113830566
{'negative': 0.18444867432117462, 'neutral': 0.07744687795639038, 'positive': 0.738104522228241}
0.10450196266174316
{'negative': 0.18444867432117462, 'neutral': 0.07744687795639038, 'positive': 0.738104522228241}
0.10511517524719238
{'negative': 0.18444867432117462, 'neutral': 0.07744687795639038, 'positive': 0.738104522228241}
0.1056208610534668

确保不要为每个推理分配张量,而是只分配一次。

import tensorflow as tf
import numpy as np

# CORRECT WAY:
def init_interpreter_tflite(model_path: str) -> tf.lite.Interpreter:
    """Initializes tflite inference object, from model .tflite file"""
    interpreter = tf.lite.Interpreter(model_path=model_path)
    interpreter.allocate_tensors()
    input_details = interpreter.get_input_details()
    output_details = interpreter.get_output_details()
    result = {
        "interpreter": interpreter,
        "input_details": input_details,
        "output_details": output_details
    }
    return result

INTERPRETER_DICT = init_interpreter_tflite(MODEL_PATH)
# Process your image or data more generally
IMAGE_ARRAY = load_and_prepare_image(TEST_IMAGE) 


def predict(image_array: np.ndarray, interpreter_dict: dict):
    interpreter = interpreter_dict["interpreter"]
    input_details = interpreter_dict["input_details"]
    output_details = interpreter_dict["output_details"]
    interpreter.set_tensor(input_details[0]['index'], image_array)
    interpreter.invoke()
    predictions = interpreter.get_tensor(output_details[0]['index'])[0]
    return predictions


predictions = predict(
    image_array=IMAGE_ARRAY,
    interpreter_dict=INTERPRETER_DICT
)

# INCORECT WAY:
def predict(image_array: np.ndarray, model_path: str):
    interpreter = tf.lite.Interpreter(model_path=model_path)
    interpreter.allocate_tensors()
    input_details = interpreter.input_details()
    output_details = interpreter.output_details()
    interpreter.set_tensor(input_details[0]['index'], image_array)
    interpreter.invoke()
    predictions = interpreter.get_tensor(output_details[0]['index'])[0]
    return predictions

这在文档中并不明显:https://www.tensorflow.org/api_docs/python/tf/lite/Interpreter

TLDR; 使用 Tensorflow Lite 模型进行推理时,请确保在推理函数之外分配张量和输入/输出详细信息,而不是在每次推理期间分配。

© www.soinside.com 2019 - 2024. All rights reserved.