博客专栏

EEPW首页 > 博客 > RTX 40时代,给深度学习买的显卡居然能保值9年?仔细一算绷不住了(1)

RTX 40时代,给深度学习买的显卡居然能保值9年?仔细一算绷不住了(1)

发布人:机器之心 时间:2023-01-17 来源:工程师 发布文章
FP8 训练带来的速度提升可能要一统 AI 领域,但这是我要考虑的问题吗?


深度学习对于算力的要求很高,对于个人来说,GPU 的选择很大程度上决定了你的工作、学习体验。显卡既贵又复杂,如果想购买新的 GPU,哪些功能最重要?内存、核心、Tensor Core 还是缓存?如何做出性价比高的选择?每出一代新 GPU 这些问题就要重新审视一番。


近日,华盛顿大学在读博士 Tim Dettmers 通过一篇长文在 RTX 40 时代的背景下深入探讨了这些问题,此文一出就获得了陈天奇等人的转推。


图片


本文将解决常见的误解,让你直观地了解如何看待 GPU 并提供建议,帮你做出适合自己的选择。


这篇博文的结构如下:首先,我将解释是什么让 GPU 变快的,我将讨论 CPU 与 GPU、Tensor Core、内存带宽和 GPU 的内存层次结构,以及它们与深度学习性能的关系。我们将讨论新的 NVIDIA RTX 40 Ampere GPU 系列的独特功能。随后我们将针对不同的场景提出 GPU 推荐。


与深度学习相关性最高的 GPU 规格


本节按每个组件的重要性排序。Tensor Core 是最重要的,其次是 GPU 的内存带宽、缓存层次结构,然后才是 GPU 的纯算力 FLOPS。


Tensor Core


Tensor Core(张量核心)是执行非常高效的矩阵乘法的微核心。由于任何深度神经网络中最耗费算力的部分就是矩阵乘法,所以张量核心非常有用。它们非常强大,想搞深度学习,不推荐任何没有 Tensor Core 的 GPU。


这里展示一个简单的 A×B=C 矩阵乘法示例,其中所有矩阵的大小均为 32×32,计算模式在使用和不使用 Tensor Cores 时的样子。这是一个简化的示例,并不是编写高性能矩阵乘法内核的确切方式,但它具有所有基础知识。CUDA 程序员会把它作为第一个「草稿」,然后用双倍缓冲、寄存器优化、占用优化、指令级并行等概念逐步优化它,这里不会一一讨论。


要完全理解此示例,你必须了解循环的概念。如果处理器以 1GHz 运行,它每秒可以执行 10^9 个周期。每个循环代表一个计算机会。但大多数时候,操作需要的时间超过一个周期。笼统地说这里有一个队列,下一个操作需要等待上一个操作完成。这也称为操作的延迟。


以下是一些重要的操作延迟周期时间。这些时间数字每代 GPU 都不一样,这里的适用于缓存相对较慢的 Ampere GPU:


  • 全局内存访问(多至 80GB):~380 个周期

  • L2 缓存:~200 个周期

  • L1 缓存或共享内存访问(每个流式多处理器最多 128 kb):~34 个周期

  • 融合乘法和加法,ab+c (FFMA):4 个周期张量核心矩阵乘法:1 个周期


每个操作总是由一组 32 个线程执行,它的集合被称为线程 warp。warp 通常以同步模式运行 ——warp 中的线程必须相互等待。GPU 上的所有内存操作都针对 warp 进行了优化。例如,从全局内存加载以 32×4 字节的粒度发生,正好是 32 个浮点数,一个 warp 中的每个线程正好对应一个浮点数。我们最多可以在一个流式多处理器 (SM) 中拥有 32 个 warps = 1024 个线程,相当于一个 CPU 核心的 GPU。SM 的资源在所有活跃的 warp 之间分配。这意味着有时我们希望运行更少的 warp,以便每个 warp 拥有更多的寄存器 / 共享内存 / Tensor Core 资源。


对于以下两个示例,我们假设拥有相同的计算资源。对于这个 32×32 矩阵乘法的小例子,我们使用 8 个 SM(大约是 RTX 3090 的 10%)和每个 SM 8 个 warp。


要了解循环延迟如何与每个 SM 的线程和每个 SM 的共享内存等资源一起发挥作用,我们现在来看一下矩阵乘法的示例。虽然以下示例大致遵循了使用和不使用 Tensor Core 的矩阵乘法的计算步骤序列,但请注意,这些示例非常简化。矩阵乘法的真实案例涉及更大的共享内存块和略有不同的计算模式。


没有张量核的矩阵乘法


如果我们想要进行 A×B=C 矩阵乘法,其中每个矩阵的大小为 32×32,那么就要将重复访问的内存加载到共享内存中,因为它的延迟大约低五倍(200 周期对 34 周期)。共享内存中的内存块通常称为内存块或简称为块。使用 232 warp 可以并行地将两个 32×32 的浮点数加载到共享内存块中。我们有 8 个 SM,每个 8 warp,因此由于并行化,我们只需要执行一次从全局到共享内存的顺序加载,这需要 200 个周期。


要进行矩阵乘法,我们现在要从共享内存 A 和共享内存 B 加载一个包含 32 个数字的向量,并执行融合乘加 (FFMA)。然后将输出存储在寄存器 C 中。我们划分工作,使每个 SM 进行 8 次点积 (32×32) 来计算 C 的 8 个输出。为什么这恰好是 8(在旧算法中为 4)是非常技术性的。


这里推荐 Scott Gray 关于矩阵乘法的博文 (https://github.com/NervanaSystems/maxas/wiki/SGEMM) 来理解这一点。


这意味着我们有 8 次共享内存访问,每次访问花费 34 个周期和 8 个 FFMA 操作(并行 32 个),每个操作花费 4 个周期。总的来说成本是:200 个周期(全局内存)+ 834 个周期(共享内存)+ 84 个周期(FFMA)= 504 个周期。


让我们看看使用 Tensor Cores 的周期成本。


用 Tensor Core 进行矩阵乘法


使用 Tensor Core,我们可以在一个周期内执行 4×4 矩阵乘法。为此我们首先需要将内存放入 Tensor Core。与上面类似,我们需要从全局内存(200 个周期)中读取并存储在共享内存中。要进行 32×32 矩阵乘法,我们需要进行 8×8=64 个 Tensor Core 运算。单个 SM 有 8 个 Tensor Core。因此,有了 8 个 SM 我们就有了 64 个 Tensor Core—— 这正是我们需要的数量!我们可以通过 1 次内存传输(34 个周期)将数据从共享内存传输到 Tensor Core,然后执行这 64 个并行 Tensor Core 操作(1 个周期)。


这意味着 Tensor Cores 矩阵乘法的总成本,在这种情况下是:200 个周期(全局内存)+ 34 个周期(共享内存)+ 1 个周期(Tensor Core)= 235 个周期。


因此,我们通过 Tensor Core 将矩阵乘法成本从 504 个周期减少到了 235 个周期。在这个简化的案例中,Tensor Cores 降低了共享内存访问和 FFMA 操作的成本。借助新的 Hooper (H100) 和 Ada(RTX 40 系)架构,我们还拥有可以进一步加速此操作的张量内存加速器 (TMA) 单元。


用 Tensor Core 和 TMA 进行矩阵乘法


TMA 单元允许将全局内存加载到共享内存中,而无需用完宝贵的线程资源。因此当 TMA 执行异步传输时,线程可以专注于共享内存和 Tensor Core 之间的工作,就像这样


TMA 从全局内存获取内存到共享内存(200 个周期)。数据到达后,TMA 就会从全局内存中异步获取下一个数据块。这样,线程从共享内存加载数据并通过张量核心执行矩阵乘法。线程完成后,它们等待 TMA 完成下一个数据传输,然后重复该序列。


由于异步性质,TMA 读取的第二个全局内存已经在线程处理当前共享内存块时进行。这意味着第二次读取仅需 200 – 34 – 1 = 165 个周期。


由于我们进行了多次读取,只有第一个内存访问会很慢,所有其他内存访问将与 TMA 部分重叠。因此平均而言,我们将时间减少了 35 个周期。


165 个周期(等待 TMA 完成)+ 34 个周期(共享内存)+ 1 个周期(Tensor Core)= 200 个周期。这又将矩阵乘法加速了 15%。


从这些示例中可以清楚地看出为什么下一个属性内存带宽对于配备 Tensor-Core 的 GPU 如此重要。由于全局内存是迄今为止使用 Tensor Core 进行矩阵乘法的最大周期成本,如果可以减少全局内存延迟,我们甚至可以拥有更快的 GPU。我们可以通过增加内存的时钟频率(每秒更多的周期,但也有更多的热量和更高的供电需求)或增加可以在任何时间传输的元素数量(总线宽度)来做到这一点。


内存带宽


我们已经知道 Tensor Core 是非常快的,事实上,它们大部分时间都处于空闲状态,因为它们正在等待内存从全局内存到达。例如,在使用巨大矩阵的 GPT-3 训练期间(模型越大,对 Tensor Core 越友好)我们的 Tensor Core TFLOPS 利用率约为 45-65%,这意味着即使对于大型神经网络也有大约 50% 时间处于闲置状态。


所以当比较两个有 Tensor Core 的 GPU 时,GPU 性能的最重要指标之一是它们的内存带宽。例如 A100 GPU 的内存带宽为 1,555 GB/s,而 V100 为 900 GB/s。因此,A100 与 V100 的加速比基本估计为 1555/900 = 1.73 倍。


L2 缓存 / 共享内存 / L1 缓存 / 寄存器


由于内存传输到 Tensor Core 是性能的限制因素,我们应当寻求更快的内存传输到 Tensor Cores 的方式。二级缓存、共享内存、一级缓存和使用的寄存器数量与该速度都是相关的。


为了执行矩阵乘法,我们利用了 GPU 的内存层次结构,从慢速全局内存到更快的 L2 内存,再到快速本地共享内存,再到快如闪电的寄存器。但是,内存越快,它就越小。


虽然从逻辑上讲,L2 和 L1 内存相同,但 L2 缓存更大,因此检索缓存行需要遍历的平均物理距离更大。你可以将 L1 和 L2 缓存视为有组织的仓库,可以在其中检索项目。你知道物品在哪里,但是对于较大的仓库来说,去那里平均需要更长的时间。这就是 L1 和 L2 缓存的本质区别:大 = 慢,小 = 快。


对于矩阵乘法,我们可以使用这种层次把结构分割开,用更快的内存块来执行快速的矩阵乘法。为此,我们需要将大矩阵乘法分块为更小的子矩阵乘法。这些块称为内存块,或通常简称为块(tile)。


我们在快速且接近流式多处理器 (SM,相当于 CPU 内核)的本地共享内存中对这些较小的块执行矩阵乘法。对于 Tensor Cores 则更进一步:我们获取每个块并将这些块的一部分加载到 Tensor Core 中,这些 Tensor Core 由寄存器直接寻址。L2 缓存中的矩阵内存块比全局 GPU 内存(GPU RAM)快 3-5 倍,共享内存比全局 GPU 内存快约 7-10 倍,而 Tensor Cores 的寄存器比全局 GPU 内存快约 200 倍。


拥有更大的块意味着我们可以重用更多的内存。事实上,你可以看到 TPU 的每个 Tensor Core 都有非常非常大的块。因此,TPU 可以在每次从全局内存传输时重用更多的内存,这使得它们在矩阵乘法方面比 GPU 更高效。


每个块大小取决于每个流式多处理器 (SM) 有多少内存,以及所有 SM 有多少二级缓存。我们在以下架构上有以下共享内存大小:


  • Volta (Titan V):128kb 共享内存 / 6 MB L2

  • Turing(RTX 20 系):96 kb 共享内存 / 5.5 MB L2

  • Ampere(RTX 30 系):128 kb 共享内存 / 6 MB L2

  • Ada(RTX 40 系):128 kb 共享内存 / 72 MB L2


显然 Ada 有很大的 L2 缓存,允许更大的块体量,这减少了全局内存访问。例如在 BERT large 在训练期间,任何矩阵乘法的输入和权重矩阵都可以很好地适合 Ada 的 L2 缓存,更早期的英伟达 GPU 则不然。因此,数据只需从全局内存加载一次,然后可通过 L2 缓存使用,使 Ada 的这种架构的矩阵乘法速度提高约 1.5-2.0 倍。对于较大的模型,训练期间的加速比较低,但存在某些最佳点可能会使某些模型更快。推理时,batch size 大于 8 也可以从更大的 L2 缓存中获益匪浅。


Ada / Hopper 架构的深度学习性能


英伟达已经在广泛的计算机视觉和自然语言理解任务中对 A100、V100 和 H100 进行了基准测试。不幸的是,英伟达的测试通过尽可能使用不同的 batch size 和 GPU 数量来确保这些数字不能直接比较,以支持 H100 更好的结果。因此从某种意义上说,基准数字部分是诚实的,部分是营销数字。你可能会争辩说使用更大的 batch size 是公平的,因为 H100/A100 有更多内存。尽管如此,为了比较 GPU 架构,我们应该评估具有相同 batch size 的无偏内存性能。


为获得无偏估计,我们可以通过两种方式扩展数据中心 GPU 结果:(1) 考虑 batch size 的差异,(2) 考虑使用 1 块 GPU 与 8 块 GPU 的差异。幸运的是,我们可以在英伟达提供的数据中找到对这两种偏差的估计。


将 batch size 加倍可将 CNN 网络的图像 / 秒吞吐量提高 13.6%。在我的 RTX Titan 上对 transformer 的相同问题进行了基准测试,结果令人惊讶地发现了完全相同的结果:13.5%—— 这似乎是一个可靠的估计。


随着我们在越来越多的 GPU 上并行化网络,我们会因为一些网络开销而损失性能。A100 8x GPU 系统具有比 V100 8x GPU 系统(NVLink 2.0)更好的网络(NVLink 3.0)—— 这是另一个第三方因素。直接看英伟达的数据我们可以发现,对于 CNN,8x A100 的系统比 8x V100 的系统开销低 5%。这意味着如果从 1x A100 提升到 8x A100 进行加速,比如得到了 7.00x,那么从 1x V100 到 8x V100 只能给你 6.67x 的加速。对于 transformer,这个数字是 7%。


使用这些数字,我们可以从英伟达提供的直接数据中估计一些特定深度学习架构的加速。与 Tesla V100 相比,A100 提供以下加速:


  • SE-ResNeXt101:1.43x

  • Masked-R-CNN:1.47x

  • Transformer(12 层,机器翻译,WMT14 en-de):1.70x


这些数字略低于计算机视觉的理论估计值。这可能是由于较小的张量维度、准备矩阵乘法所需的操作(如 img2col 或快速傅里叶变换,FFT)的开销,或者无法使 GPU 饱和的操作(最终层通常相对较小)。它也可能是特定架构(分组卷积)的产物。


实际 transformer 估计值非常接近理论估计值。这可能是因为巨大矩阵的算法非常简单。我将使用这些实际估算来计算 GPU 的成本效率。


需要注意的是,以上估算值适用于 H100、A100 和 V100 GPU。英伟达曾在「游戏用」的 RTX GPU 中偷偷降低了未宣布的性能:(1) 降低 Tensor Core 利用率,(2) 用于冷却的风扇,(3) 禁用点对点 GPU 传输。与完整的 Hopper H100 相比,RTX 40 系列可能存在未明确的性能下降。


*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。



关键词: 芯片

相关推荐

技术专区

关闭