概要

在我们深度学习算法训练中最长出现的就是 GPU利用率偏低,甚至经常出现 nvidia-smi一打开,GPU利用率为0%,隔很久才跳动一次,这究竟是为什么呢?有什么解决办法吗?笔者为你一一揭晓答案!

训练流程分析

通常的训练流程

  1. 图片数据在磁盘上
  2. CPU把数据从磁盘加载到内存里,注意这里是CPU(不是GPU)把数据加载到内存(不是显存),所以这时候图片数据在内存里。
  3. CPU对数据进行预处理。
  4. 数据又内存转移到显存。
  5. GPU对数据进行模型前向推理。
  6. GPU计算loss。
  7. GPU对模型进行反向传播,并更新权重。
    这是一个完整的训练流程, 步骤2加载数据和步骤3数据预处理在CPU上执行,步骤4、5、6都在GPU上执行。GPU利用率较低,说明流程卡在了步骤2数据加载或步骤3预处理阶段,GPU一直在等CPU加载预处理数据,处于闲置状态,所以GPU利用率为0,偶尔等CPU加载预处理好,GPU执行一次,所以会出现GPU利用率为0%,隔很久才跳动一次这个现象。

解决办法

  1. 通常问题就是出在数据加载或预处理阶段。
    如果我们用 torch.dataloader() API, 一定要设置合理的num_worker数,如果你的训练机器是 72核CPU、8个GPU, 那个合理的num_worker数为9(72/8), 也就是一个worker数对应一个数据加载预处理thread,每个thread尽量分配一个CPU核。 优先这样调试下,看训练速度是否能缓解。
  2. 如果1没用缓解, 我们就详细分析一下各种数据格式数据的加载速度。
    普通图片加载、lmdb数据格式加载、tfrecord数据格式加载
    这里面推荐把数据做成用lmdb格式,这样读取数据的速度会加快,但无论哪种数据格式数据预处理仍在CPU上进行。尝试下,训练速度是否能缓解。
  3. 如果2仍然没有缓解, 说明问题可能出在步骤3数据预处理阶段, 那我们尝试下将 数据预处理步骤在GPU上执行, 这里推荐用nvidia的dali库, 具体实现参照官网例子, 可以将数据预处理这部分挪到GPU上进行。

小结

总结来说

  1. 先设置好torch.dataloader的num_worker数目。
  2. 数据格式处理下,最好用lmdb格式。
  3. 数据预处理阶段在GPU上执行, 推荐nvidia dali库。

优先级1>2>3
做到这些,能够解决我们训练中 99%的 训练速度慢问题, 和 GPU利用率偏低问题。
喜欢文章,关注公众号:人工智能私房菜

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐