线性/全连接层用户指南
全连接层,也称为线性层,将每个输入神经元连接到每个输出神经元,常用于神经网络中。
图 1. 具有四个输入和八个输出神经元的小型全连接层示例。
三个参数定义了一个全连接层:批量大小、输入数量和输出数量。前向传播、激活梯度计算和权重梯度计算直接表示为矩阵-矩阵乘法。这三个参数如何映射到 GEMM 维度(通用矩阵乘法,背景知识请参阅NVIDIA 矩阵乘法背景用户指南)在不同框架中有所不同,但基本原理是相同的。为了便于讨论,我们采用 PyTorch 和 Caffe 使用的约定,其中 A 包含权重,B 包含激活。在 TensorFlow 中,矩阵的角色相反,但性能原理是相同的。
计算阶段 | M | N | K |
---|---|---|---|
前向传播 | 输出数量 | 批量大小 | 输入数量 |
激活梯度 | 输入数量 | 批量大小 | 输出数量 |
权重梯度 | 输入数量 | 输出数量 | 批量大小 |
GEMM 中矩阵的组成显示在图 2中。
图 2. 全连接层 (a) 前向传播、(b) 激活梯度和 (c) 权重梯度计算的等效 GEMM 的维度。
3.1. 输入特征和输出神经元计数
由于全连接层直接对应于 GEMM,因此它们的性能趋势与NVIDIA cuBLAS 中的典型平铺维度和性能中描述的趋势相同。更大的参数往往允许更好的并行化和效率;大小加倍的 GEMM 通常只需不到两倍的时间即可完成计算。
图 3. 更大的全连接层等效于更大的 GEMM,性能更好。NVIDIA A100-SXM4-80GB,CUDA 11.2,cuBLAS 11.4。
3.2. 批量大小
批量大小直接影响前向传播和激活梯度计算这两个训练阶段的平铺策略。对于这些阶段,输出矩阵维度包括批量大小,因此更大的批量大小会产生更多的平铺。当模型大小太小而无法充分利用 GPU 时,使用更大的批量大小进行训练是一种提高性能的选择。
对于权重梯度计算,输出矩阵的维度与权重相同,因此批量大小不会直接影响平铺计数。相反,此处的批量大小映射到 GEMM 的 K 维度;更大的批量大小可以提高每个权重梯度平铺的计算效率。图 15 显示了批量大小变化对具有 4096 个输入和 1024 个输出的全连接层的前向传播、激活梯度和权重梯度计算的性能影响。更大的批量大小可产生大约 250 TFLOPS 的交付性能。
图 4. 具有 4096 个输入、1024 个输出和不同批量大小的全连接层的 (a) 前向传播、(b) 激活梯度计算和 (c) 权重梯度计算的性能数据。NVIDIA A100-SXM4-80GB,CUDA 11.2,cuBLAS 11.4。
特别令人感兴趣的是其中一个维度非常小的 GEMM。例如,在 NVIDIA A100-SXM4-80GB 上,对于具有 4096 个输入和 4096 个输出的全连接层,对于批量大小为 128 及以下的情况,前向传播、激活梯度计算和权重梯度计算预计会受到内存带宽的限制(请参阅图 5)。
图 5. 具有 4096 个输入和 4096 个输出的全连接层的算术强度。批量大小为 128 及以下的情况在 NVIDIA A100 加速器上受到带宽限制。
更大的输入和输出数量在一定程度上提高了性能,但对于非常小的批量大小(例如 8 及以下),计算将始终受到带宽限制。有关受数学和带宽限制的计算的讨论,请参阅数学和内存边界。
4.1. 基础知识
Transformer 是一种流行的神经网络架构,用于序列到序列映射任务,例如自然语言翻译。它们使用编码器-解码器架构,大量使用注意力机制,既可以“自我注意”输入序列,也可以让解码器访问编码器的上下文。图 6 显示了完整的神经网络架构(Attention Is All You Need 2017 年论文,第 3 页)。
图 6. Transformer 神经网络架构,编码器和解码器中分别有 N 个宏层。宏层由一个或多个注意力层和一个前馈网络组成。
从性能的角度来看,与例如具有顺序依赖性的 RNN 架构不同,Transformer 从根本上并行处理输入序列中的所有标记。这使得 Transformer 非常适合高度并行的架构(例如 GPU),并导致大型 GEMM,通过一些简单的指导原则,可以充分利用 Tensor Core 加速。
4.2. 应用 Tensor Core 指南
4.2.1. 步骤 1:填充词汇表大小
考虑 Transformer 网络中的最终线性层,其输出数量等于词汇表大小,因为它将网络中的最终 SoftMax 层馈送,以生成词汇表中标记的概率分布。
如优化全连接层用户指南中所讨论的,此线性层的 M 等于词汇表大小,N 等于批量大小,K 等于输入特征大小(全部在前向传播中)。由于词汇表通常很大,因此这是一项繁重的计算,务必确保有效使用 Tensor Core。
图 7. 通过选择词汇表大小为 8 的倍数,在使用 (a) cuBLAS 版本 10.1 和 (b) cuBLAS 版本 11.0 时,性能都得到显着提升。投影层使用 1024 个输入和 5120 的批量大小。NVIDIA V100-SXM2-16GB GPU。
图 7 显示了当不考虑对齐时选择词汇表大小会发生什么。使用 FP16 数据,因此维度必须是 8 的倍数才能实现最佳对齐。当使用低于 11.0 的 cuBLAS 版本时,这一点最为重要(图 7 (a));在这种情况下,当词汇表大小不能被 8 整除 (V=33708) 时,无法应用 Tensor Core,并且性能会急剧下降到 NVIDIA CUDA® 核心所能维持的水平。只需添加四个填充标记(达到 V=33712)即可切换到 8 的倍数大小,并显着加速整体计算。当使用 cuBLAS 11.0 或更高版本时(图 7 (b)),性能影响不如那么极端,但选择与 8 的倍数对齐的词汇表大小仍然明显更有效率。有关对齐和效率的更多详细信息,请参阅Tensor Core 要求。
4.2.2. 步骤 2:选择 8 的倍数的批量大小
除了网络末端的投影层外,全连接层也是 Transformer 在网络所有其他部分(包括大型自注意力块和前馈块)中的主要构建块。如前所述,批量大小直接映射到此类层中 GEMM 维度之一 - 前向和激活梯度传递中的 N,权重梯度传递中的 K - 因此,填充到 8 的倍数的指南也适用于批量大小。
图 8. 通过将批量大小填充为 8 的倍数,在使用 (a) cuBLAS 版本 10.1 和 (b) cuBLAS 版本 11.0 时,全连接层的权重梯度计算都受益。显示了 Transformer 前馈网络中的第一个全连接层(4096 个输出,1024 个输入)。NVIDIA V100-SXM2-16GB GPU。
图 8 显示了填充批量大小对网络中一个全连接层的影响。在这里,我们选择了前馈块中的第一个层,这是一个具有 1024 个输入和 4096 个输出的全连接层。如图表所示,这是一个 8 的倍数规则不一定需要应用于所有三个 GEMM 维度的示例;前向和激活梯度传递在填充和不填充的情况下执行相同操作。另一方面,权重梯度传递显示了我们之前在投影 GEMM 上看到的相同性能差异。与该示例一样,对于低于 11.0 的 cuBLAS 版本(图 8 (a)),性能提升非常显着:对于 4095 个标记的批量大小,CUDA 核心用作后备,而 4096 个标记的批量大小则启用 Tensor Core 加速。当使用 cuBLAS 11.0 及更高版本时(图 8 (b)),性能提升不太极端,但仍然很显着。我们建议在 FP16 中训练时确保所有三个 GEMM 维度都是 8 的倍数,以便所有传递都将有效使用 Tensor Core。
4.2.3. 步骤 3:通过批量大小选择避免波量化
由于批量大小直接控制 MxN 输出矩阵的形状,并且 Tensor Core GEMM 通过平铺输出矩阵进行并行化,因此适当选择批量大小可用于减少平铺和波量化效应。
对于 Transformer,让我们再次考虑前馈块中的第一个层(4096 个输出,1024 个输入)。在此层中,输出矩阵的形状为 4096 x 批量大小。假设平铺大小为 256x128 作为示例,M=4096
维度产生垂直堆叠的 4096/256=16
个线程块平铺。在具有 80 个 SM 的 NVIDIA V100 GPU 上,如果线程块总数是 80 的倍数(或略低于),则波量化最小。因此,选择批量大小以在 N 维度中产生 n*80/16=n*5
个线程块平铺,可以实现最佳波量化。使用 256x128 线程块,通过选择批量大小 N=1*5*128=640
、N=2*5*128=1280
等来实现。图 9 说明了这在使用两个常用批量大小 2048 和 4096 时产生的影响。
图 9. 通过适当选择批量大小消除波量化,全连接层性能得到提升;在使用 (a) cuBLAS 版本 10.1 和 (b) cuBLAS 版本 11.0 时,改进效果相似。前馈块中的第一个全连接层作为示例显示。批量大小 2560 和 5120 在 80-SM NVIDIA V100 GPU 上产生 80 个线程块平铺的倍数。在权重梯度中,批量大小映射到 GEMM 的 K 参数,因此不控制输出矩阵的形状或对波量化产生任何直接影响。NVIDIA V100-SXM2-16GB GPU。
图表显示,选择无量化的批量大小(2560 而不是 2048,5120 而不是 4096)可以显着提高性能。特别是,值得注意的是,批量大小 2560(假设平铺大小为 256x128,产生 4 波,每波 80 个线程块平铺)实现了比更大的批量大小 4096 更高的吞吐量(512 个线程块平铺,平铺大小为 256x128 时为 6.4 波)。批量大小为 5120 的激活梯度实现了约 95 TFLOPS 的交付性能。对于权重梯度计算,批量大小映射到 GEMM 的 K 参数,因此不直接影响输出矩阵的大小和形状,也不影响创建的线程块平铺的数量。
声明
本文档仅供参考,不应被视为对产品的特定功能、状况或质量的保证。NVIDIA Corporation(“NVIDIA”)对本文档中包含信息的准确性或完整性不作任何明示或暗示的陈述或保证,并且对本文档中包含的任何错误不承担任何责任。NVIDIA 对因使用此类信息或因其使用而可能导致的任何专利或第三方其他权利的侵权行为的后果或使用不承担任何责任。本文档不构成对开发、发布或交付任何材料(下文定义)、代码或功能的承诺。
NVIDIA 保留随时对此文档进行更正、修改、增强、改进和任何其他更改的权利,恕不另行通知。
客户在下订单前应获取最新的相关信息,并应验证此类信息是否为最新且完整。
NVIDIA 产品根据 NVIDIA 标准销售条款和条件进行销售,除非 NVIDIA 和客户的授权代表签署的个别销售协议(“销售条款”)另有约定,销售条款在订单确认时提供。NVIDIA 特此明确反对将任何客户通用条款和条件应用于购买本文档中引用的 NVIDIA 产品。本文档未直接或间接形成任何合同义务。
NVIDIA 产品并非设计、授权或保证适用于医疗、军事、航空、航天或生命维持设备,也不适用于 NVIDIA 产品的故障或失灵可合理预期会导致人身伤害、死亡或财产或环境损害的应用。NVIDIA 对在上述设备或应用中包含和/或使用 NVIDIA 产品不承担任何责任,因此,此类包含和/或使用由客户自行承担风险。
NVIDIA 不作任何陈述或保证,保证基于本文档的产品将适用于任何特定用途。NVIDIA 不一定对每个产品的所有参数进行测试。客户全权负责评估和确定本文档中包含的任何信息的适用性,确保产品适合并满足客户计划的应用,并为应用执行必要的测试,以避免应用或产品出现默认情况。客户产品设计的缺陷可能会影响 NVIDIA 产品的质量和可靠性,并可能导致超出本文档中包含的附加或不同条件和/或要求。对于可能基于或归因于以下原因的任何默认、损坏、成本或问题,NVIDIA 不承担任何责任:(i) 以任何与本文档相悖的方式使用 NVIDIA 产品,或 (ii) 客户产品设计。
本文档未授予 NVIDIA 专利权、版权或本文档项下的其他 NVIDIA 知识产权的任何明示或暗示的许可。NVIDIA 发布的有关第三方产品或服务的信息不构成 NVIDIA 授予使用此类产品或服务的许可,也不构成 NVIDIA 对其的保证或认可。使用此类信息可能需要获得第三方的专利或其他知识产权项下的第三方许可,或获得 NVIDIA 的专利或其他知识产权项下的 NVIDIA 许可。
只有在事先获得 NVIDIA 书面批准的情况下,才允许复制本文档中的信息,并且复制必须未经修改且完全符合所有适用的出口法律和法规,并附带所有相关的条件、限制和声明。
本文档以及所有 NVIDIA 设计规范、参考板、文件、图纸、诊断程序、列表和其他文档(统称为“材料”)均按“原样”提供。NVIDIA 对材料不作任何明示、暗示、法定或其他方面的保证,并明确声明不承担所有关于不侵权、适销性和特定用途适用性的暗示保证。在法律未禁止的范围内,在任何情况下,NVIDIA 均不对任何损害(包括但不限于任何直接、间接、特殊、偶然、惩罚性或后果性损害,无论因何种原因造成,也无论责任理论如何)承担责任,即使 NVIDIA 已被告知可能发生此类损害。尽管客户可能因任何原因遭受任何损害,但 NVIDIA 对本文所述产品的对客户的累计总责任应根据产品的销售条款的规定予以限制。
Android、Android TV、Google Play 和 Google Play 徽标是 Google, Inc. 的商标。
商标
NVIDIA、NVIDIA 徽标、CUDA、Merlin、RAPIDS、Triton Inference Server、Turing 和 Volta 是 NVIDIA Corporation 在美国和其他国家/地区的商标和/或注册商标。其他公司和产品名称可能是与其相关的各自公司的商标。