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

TensorFlow/Keras GPU利用率低求助:GPU仅15%、CPU达40%

解决TensorFlow/Keras GPU利用率低、CPU占用高的问题

看起来你已经做了基础的GPU绑定配置,但GPU利用率上不去、CPU占用高的问题通常不是单纯的“没指定GPU”,而是数据瓶颈、模型设计或TensorFlow配置细节导致的。下面是我整理的排查和解决步骤:

1. 先解决数据预处理的瓶颈(最常见原因)

CPU占用高、GPU闲得慌,大概率是数据加载和预处理的速度跟不上GPU的计算速度——GPU在等CPU喂数据,自然利用率上不去。

  • 替换原生Python生成器为tf.data.Dataset,它能更高效地利用CPU并行处理,还能预取数据:
    # 示例:用tf.data加载数据并优化
    train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
    # 并行预处理+打乱+分批+预取
    train_dataset = train_dataset.shuffle(buffer_size=10000) \
                                 .batch(batch_size) \
                                 .map(your_preprocess_func, num_parallel_calls=tf.data.AUTOTUNE) \
                                 .prefetch(tf.data.AUTOTUNE)
    
  • 避免在预处理中使用numpy或纯Python代码,全部替换为TensorFlow的原生张量操作(比如tf.math代替numpy,tf.image代替PIL),这样部分预处理可以offload到GPU。

2. 调大Batch Size,填满GPU计算核心

GPU的计算能力需要足够大的batch来“喂饱”核心,如果batch size太小,GPU大部分核心处于闲置状态,利用率自然低。

  • 逐步增大batch size,直到接近GPU内存上限(可以用tf.config.experimental.get_memory_info('GPU:0')查看实时内存占用)。
  • 如果内存不够,可以开启混合精度训练来节省显存,从而用更大的batch:
    tf.keras.mixed_precision.set_global_policy('mixed_float16')
    
    注意最后一层要输出float32,避免精度损失:output_layer = tf.keras.layers.Dense(num_classes, dtype='float32')

3. 检查模型是否有CPU绑定的操作

有些自定义层、损失函数或预处理步骤可能默认在CPU上运行,导致CPU占用高:

  • 检查所有自定义代码,确保用TensorFlow原生API实现(比如不要在损失函数里用for循环,改用tf.map_fn或向量化操作)。
  • 用tf.function装饰自定义训练步骤或自定义层,让TensorFlow将其编译为计算图,自动分配到GPU运行:
    @tf.function
    def train_step(x, y):
        with tf.GradientTape() as tape:
            predictions = model(x, training=True)
            loss = loss_fn(y, predictions)
        gradients = tape.gradient(loss, model.trainable_variables)
        optimizer.apply_gradients(zip(gradients, model.trainable_variables))
        return loss
    

4. 优化TensorFlow的GPU配置

你的现有配置已经指定了可见GPU,但可能缺少显存增长策略,或者版本有冲突:

  • 开启显存增长,避免TensorFlow一次性占满全部显存(这会导致其他进程无法使用GPU,也可能影响利用率):
    gpus = tf.config.experimental.list_physical_devices('GPU')
    if gpus:
        try:
            # 为每个GPU开启显存增长
            for gpu in gpus:
                tf.config.experimental.set_memory_growth(gpu, True)
            # 仅绑定第一个GPU
            tf.config.experimental.set_visible_devices(gpus[0], 'GPU')
            logical_gpus = tf.config.experimental.list_logical_devices('GPU')
            print(f"{len(gpus)} Physical GPUs, {len(logical_gpus)} Logical GPU")
        except RuntimeError as e:
            print(f"GPU配置错误: {e}")
    
  • 注意:TensorFlow 2.x之后,不需要单独安装tensorflow-gpu包,官方已经合并到tensorflow主包中。如果你同时装了tensorflow和tensorflow-gpu,可能会导致版本冲突,建议卸载tensorflow-gpu,重新安装对应版本的tensorflow,并确保CUDA、cuDNN版本与TensorFlow版本匹配。

5. 解决多GPU配置报错的问题

当设置CUDA_VISIBLE_DEVICES="0,1,2,3"时报错,可能是单个GPU故障、CUDA环境配置问题,或者TensorFlow多GPU识别失败:

  • 先单独测试每个GPU:分别设置CUDA_VISIBLE_DEVICES="0"、"1"、"2"、"3",看每个GPU是否能正常运行训练代码,排查是否有硬件或驱动问题。
  • 如果所有GPU都能单独工作,建议用TensorFlow的分布式策略来管理多GPU,而不是单纯设置环境变量:
    strategy = tf.distribute.MirroredStrategy(devices=["/GPU:0", "/GPU:1", "/GPU:2", "/GPU:3"])
    with strategy.scope():
        # 在策略范围内构建模型
        model = build_your_model()
        model.compile(optimizer='adam', loss='sparse_categorical_crossentropy')
    

最后验证

运行训练时,可以用nvidia-smi命令实时查看GPU利用率,同时观察CPU占用率是否下降。如果GPU利用率提升,说明之前的瓶颈在数据或模型设计;如果还是低,建议检查模型是否有大量小计算量的层(比如很多小的Dense层),这类层GPU的并行优势不明显,容易导致利用率低。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:15:02