从第一原理开始深度学习

2026-05-23 1 阅读 tosh
让深度学习从第一原则出发 因此,您希望提高深度学习模型的性能。你会如何完成这样的任务?通常,人们会求助于一些以前可能有效或在推文中看到的技巧。 “使用就地操作!将渐变设置为无!安装 PyTorch 1.10.0,但不安装 1.10.1!”可以理解为什么用户经常采取这种临时方法,在现代系统(特别是深度学习)上的表现通常感觉就像炼金术和科学一样。话虽如此,从第一原理出发的推理仍然可以消除大量的方法,从而使问题变得更容易解决。例如,通过深度学习在数据集上获得良好的性能也涉及大量的猜测。但是,如果您的训练损失远低于测试损失,那么您就处于“过度拟合”状态,并且如果您尝试增加模型的容量,那么您就是在浪费时间。或者,如果您的训练损失与验证损失相同,那么如果您尝试规范化模型,那么您就是在浪费时间。同样,您可以将深度学习机制的效率理解为由 3 个不同的组件组成。计算:GPU 计算实际浮点运算 (FLOPS) 所花费的时间 内存:在 GPU 内传输张量所花费的时间 开销:其他一切 就像训练 ML 模型一样,了解您所处的状态可以让您缩小重要优化范围。例如,如果您将所有时间都花在内存传输上(即您处于内存带宽限制状态),那么增加 GPU 的 FLOPS 将无济于事。另一方面,如果您将所有时间都花在执行大型 chonky matmuls(即受计算限制的机制)上,那么将模型逻辑重写为 C++ 以减少开销将无济于事。因此,如果您想让 GPU 保持正常运转,我们来讨论一下系统可能花费时间的三个组件:计算、内存带宽和开销。惨痛教训的背后是一大批工程师保持 GPU 高效运行。图片来自 Gwern 注意:本文的大部分内容将使用 GPU 和 PyTorch 作为示例(因为我在 PyTorch 团队工作),但这些原则几乎都适用于硬件和框架。计算 优化深度学习系统的一种观点是,我们希望最大化计算限制状态下的时间。您为所有 312 teraflops 支付了费用,理想情况下,您会获得这 312 teraflops。但是,为了让昂贵的矩阵乘法物有所值,您需要减少在其他部分花费的时间。但为什么要关注最大化计算而不是内存带宽呢?原因很简单 - 您可以减少开销或内存成本,但您(大多数情况下)无法在不更改正在执行的实际操作的情况下减少所需的计算。与内存带宽相比,计算增长的速度加剧了最大化计算利用率的难度。将此表视为 CPU FLOPS 倍增时间与内存带宽倍增时间的比较 考虑计算的一种方法是将其视为工厂。我们向工厂发送指令(开销),发送材料(内存带宽),所有这些都是为了保持工厂高效运行(计算)。因此,如果我们工厂提高效率的速度快于我们为其供应材料的速度,我们工厂就很难达到最高效率。即使我们工厂的规模 (FLOPS) 翻倍,但如果我们的带宽无法跟上,那么我们的性能也不会翻倍。除了意味着 ML 系统工程师的永久工作保障之外,利用我们的计算的日益困难也使得了解我们的瓶颈变得更加重要。另一份关于 FLOPS 的附录。现代机器学习加速器都拥有专门用于矩阵乘法的硬件,例如 Nvidia 的“Tensor Cores”。因此,如果您不进行矩阵乘法,则只能实现 19.5 teraflops,而不是规定的 312。请注意,这并不是 GPU 所独有的 - 事实上,TPU 甚至比 GPU 更不通用。事实上,GPU 在除矩阵乘法之外的所有操作上都慢得多,这一事实一开始可能看起来有问题 - 那么我们的其他运算符(如层范数或激活函数)呢?事实是,这些运算符只是 FLOPS 方面的舍入误差。例如,让我们看看本文中不同运算符类型的 FLOP 计数表,其中“张量收缩”= matmuls。您可以看到,我们的非 matmul 运算仅占 FLOPS 的 0.2%,因此我们的 GPU 计算非 matmul 运算速度慢 15 倍并不重要。但是,在这种情况下,归一化和逐点运算实际上分别比我们的 matmuls 减少了 250 倍和 700 倍的 FLOPS。那么为什么我们的非 matmul 操作花费的时间比应有的时间多得多呢?回到我们的类比,罪魁祸首通常是材料往返工厂所需的时间。换句话说