仓库源文站点原文


title: "深度学习性能瓶颈往往是内存带宽" categories:


首先是这篇文章

内容不再赘述, 下面是纲要和一些对原文的注解. 虽然文章用 Torch 和 GPU 举例, 但基本原理依然普适.

<details><summary><b>注</b><font color="deepskyblue"> (Show more »)</font></summary> <p>机器之心 <a href="https://zhuanlan.zhihu.com/p/485490532">编译</a> 过这篇文章, 但有些错误. 比如只看第一段, 前几句话还行, 但光最后一句就有两个技术错误: (1) 把 in-place 说成内置; (2) 梯度设置为 None 说成 0. 关于第 2 点可以参考 torch 文档 <a href="https://pytorch.org/tutorials/recipes/recipes/tuning_guide.html#use-parameter-grad-none-instead-of-model-zero-grad-or-optimizer-zero-grad">Use parameter.grad = None instead of model.zero_grad() or optimizer.zero_grad()</a>.</p></details>

简单介绍了模型耗时可以分为三部分

<!-- more -->

我们希望最大化利用 GPU 算力, 但实际上内存带宽才是瓶颈. 硬件层面, 每年内存带宽增速不及 FLOPS 增速, 导致这个问题更加严重.

简单起见, 文章只讨论了 GPU 内部数据转移带来的内存带宽开销, 并简单介绍了可以用算子融合降低带宽开销. 文章用 toy example 演示了什么时候受限于带宽, 什么时候瓶颈才是算力.

算子融合

也叫 kernel 融合

Overhead

最后文章提到虽然 PyTorch 等框架有额外调度开销, 但因为 CPU 和 GPU 并行, 只要 GPU 任务足够繁重, CPU 完成任务时间短, 那么 overhead 就不会成为瓶颈.

其他

NVIDIA 文档 开头就写了

Operating In Math-Limited Regime Where Possible

尽量让计算成为瓶颈.

另外要注意 nvidia-smi 中的 GPU-Util (不要读成 Volatile GPU-Util) 定义只是时间维度上的

It indicates the percent of GPU utilization i.e. percent of the time when kernels were using GPU over the sample period. Here, the period could be between 1 to 1/6th second.

只要时间段内有 一个 kernel 执行就会算上 util. 最简单的 例子: 写一个 1-block 的循环 kernel 就能把 GPU "利用率" 打到 100%, 但在空间层面上利用率很低.

混合精度训练