You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Keras多GPU环境下运行predict_generator生成VGG16瓶颈特征的问题

解决Keras 2.0.9中multi_gpu_model配合predict_generator的多GPU运行问题

哎,这个坑我之前也踩过!Keras 2.0.9的multi_gpu_model在处理predict_generator的时候确实有点“偷懒”——它虽然会把模型复制到各个GPU上,但默认实现会把所有预测结果先拉回CPU再合并,导致你看着GPU占用了,但实际计算全在CPU跑,速度慢得离谱。

不过不用太担心要重写整个predict_generator,有几个简便的小技巧能搞定这个问题:

1. 调整multi_gpu_model参数,关闭CPU合并

首先,调用multi_gpu_model时加上cpu_merge=False参数,强制让计算留在GPU上:

from keras.utils import multi_gpu_model

parallel_model = multi_gpu_model(your_vgg16_model, gpus=6, cpu_merge=False)

这个参数会让模型不再自动把GPU的计算结果拉回CPU合并,而是直接返回每个GPU的输出列表,从根源上避免CPU兜底计算。

2. 包装生成器,适配多GPU输入

因为cpu_merge=False时,模型期望输入是对应GPU数量的批量列表(每个元素对应一块GPU的输入数据),所以你需要给原始生成器套一层包装:

def multi_gpu_data_generator(original_generator, gpus=6):
    while True:
        # 每次获取gpus个批量的数据
        batches = [next(original_generator) for _ in range(gpus)]
        # 如果生成器只返回输入数据(比如生成瓶颈特征不需要标签),直接用batches即可
        # 如果生成器返回(inputs, labels),就提取inputs部分
        input_batches = [batch[0] for batch in batches]
        yield input_batches

这个包装后的生成器每次会吐出6个批量,分别喂给6块GPU,完美适配多GPU模型的输入要求。

3. 运行预测并合并结果

接下来调用predict_generator时,记得调整steps_per_epoch——现在每个step会处理6个批量,所以步数要改成原来的1/6(如果原来的步数是N,现在就用N // 6,保证总数据量一致):

# 假设原来的steps_per_epoch是total_samples // batch_size
new_steps = original_steps // 6
gpu_outputs = parallel_model.predict_generator(
    multi_gpu_data_generator(your_original_generator),
    steps=new_steps
)

# 合并所有GPU的输出结果,得到完整的瓶颈特征数组
final_features = np.concatenate(gpu_outputs, axis=0)

额外注意事项

  • 确保原始生成器的批量大小设置合理,避免单GPU批量过大导致显存溢出
  • 检查TensorFlow 1.x(Keras 2.0.9对应TF1.x版本)是否正确识别了所有6块GPU,可以用tf.test.is_gpu_available()确认
  • 如果数据集总数不是6的倍数,最后可能会有少量剩余数据,记得单独用单GPU处理这部分

亲测这个方法在Keras 2.0.9+TF1.12环境下有效,不用重写核心预测逻辑,只是做了一点包装和参数调整,应该能解决你的问题。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:14:06