You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

TensorFlow-GPU预测速度慢于TensorFlow-CPU的问题求助

问题分析与解决方案

你的硬件配置(GTX 1080Ti + i7-7700K)理论上GPU推理应该更有优势,但出现反直觉的结果,主要是以下几个核心原因:

1. GPU初始化与模型加载的额外开销

你的计时代码从start=time.time()开始,随后才创建tf.Session——这意味着GPU的初始化(包括CUDA上下文创建、模型图加载到GPU显存)的时间都被算进了总耗时里。而CPU版本的Session初始化和模型加载开销要小得多,这部分差异直接拉低了GPU版本的整体速度。

2. 轻量模型的GPU并行优势未发挥

MobileNet_v1是为移动设备设计的轻量级模型,单张图片的推理计算量并不大。GPU的优势在于大规模并行计算,对于小计算量任务,数据在CPU和GPU之间的传输开销(把图片tensor传到GPU、把推理结果传回CPU)可能会超过GPU本身的计算加速收益。而你的i7-7700K是高性能桌面CPU,单线程处理轻量任务的效率很高,甚至可能比GPU更快。

3. 单样本重复推理而非批量推理

你现在是对同一张图片重复调用9次predict,但每次都是单样本输入。GPU擅长批量处理多个样本的并行计算,单样本的话,GPU的大量核心无法被充分利用,而CPU的多线程(或单线程)处理单样本的开销更低。


针对性解决方案

1. 分离初始化与推理的计时

把Session创建和模型准备的代码放在计时之外,只统计纯推理的时间,同时加入预热推理消除第一次编译开销:

# 先完成初始化和模型加载
with tf.Session(graph=graph) as sess:
    # 预热推理:消除第一次算子编译的额外开销
    predict('/home/4_bikes/test_images/bikerider4.jpg', sess)
    
    # 开始计时纯推理过程
    start=time.time()
    for _ in range(9):
        predict('/home/4_bikes/test_images/bikerider4.jpg',sess)
    stop=time.time()
    print('Time taken for prediction :: {}'.format(stop-start))

2. 改用批量推理

把9张图片打包成一个batch输入,让GPU并行处理,充分发挥其核心优势:

# 构造批量输入tensor
batch_t = []
img_path = '/home/4_bikes/test_images/bikerider4.jpg'
for _ in range(9):
    t = read_tensor_from_image_file(
        img_path, 
        input_height=input_height, 
        input_width=input_width, 
        input_mean=input_mean, 
        input_std=input_std)
    batch_t.append(t)
batch_t = np.concatenate(batch_t, axis=0)

# 单次批量推理
with tf.Session(graph=graph) as sess:
    # 预热
    sess.run(output_operation.outputs[0], {input_operation.outputs[0]: batch_t[:1]})
    
    start=time.time()
    results = sess.run(output_operation.outputs[0], {input_operation.outputs[0]: batch_t})
    stop=time.time()
    print('Time taken for batch prediction :: {}'.format(stop-start))

3. 优化GPU设置与版本检查

  • 确认Python2环境中的tensorflow-gpu版本与CUDA、cuDNN版本匹配(旧版本TF对GTX1080Ti的优化可能不足);
  • 开启GPU显存动态分配,避免初始化时的显存预分配开销:
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
with tf.Session(graph=graph, config=config) as sess:
    # 推理代码
  • 检查CPU版本是否启用了MKL优化(新版本TF-CPU默认会启用MKL,对Intel CPU的加速很明显),同时确保GPU版本开启了相应的优化选项。

4. 拆分步骤定位瓶颈

你可以在predict函数中给每个步骤单独计时,明确是数据传输、推理还是后续处理拖慢了速度:

def predict(file_name,sess):
    start_read = time.time()
    t = read_tensor_from_image_file(
        file_name, input_height=input_height, 
        input_width=input_width, input_mean=input_mean, 
        input_std=input_std)
    print(f"Image to tensor time: {time.time()-start_read:.4f}s")
    
    start_infer = time.time()
    results = sess.run(output_operation.outputs[0], {input_operation.outputs[0]: t})
    print(f"Inference + data transfer time: {time.time()-start_infer:.4f}s")
    
    start_post = time.time()
    results = np.squeeze(results)
    index=results.argmax()
    prediction=labels[index]
    bike_predictor = bike_classifier()
    if prediction == 'bikes':
        bike_predictor.predict(t)
    else:
        print('Predicted as :: unknown')
    print(f"Post-processing time: {time.time()-start_post:.4f}s")

内容的提问来源于stack exchange,提问作者Pratik Kumar

火山引擎 最新活动