4. 深度学习模型部署与优化:关键考虑与实践策略
4.1 FLOPS TOPS
首先,我们来解释FLOPS和TOPS的含义:
FLOPS:是Floating Point Operations Per Second的缩写,意思是每秒浮点运算次数。它是衡量计算机或计算设备在每秒内执行的浮点运算次数的指标。通常用于表示处理器的计算性能。例如,1 TFLOPS表示每秒执行1万亿次浮点运算。
TOPS:是Tera Operations Per Second的缩写,意思是每秒运算次数。它与FLOPS类似,但通常用于衡量整数运算或混合型的运算能力,而不仅仅是浮点运算。
下面列出一个关于NVIDIA A100(基于发布时的公开资料)的性能参数表格。请注意,这些性能数字代表了理论上的峰值计算能力,实际应用中的性能可能会因为各种因素而有所不同。
参数 | 性能值 |
---|---|
Peak FP64 (双精度浮点性能) | 9.7 TFLOPS |
Peak FP32 (单精度浮点性能) | 19.5 TFLOPS |
Peak FP16 (半精度浮点性能) | 312 TFLOPS |
Tensor Performance (FP16) | 624 TOPS |
INT8 Performance | 1248 TOPS |
INT4 Performance | 2496 TOPS |
下面是Jetson Xavier AGX Volta的参数
参数 | Jetson Xavier AGX (Volta) |
---|---|
Core种类与数量 | |
CUDA cores | 512 |
Tensor cores | 64 |
SMs | 8 |
计算峰值 | |
FP32 | 1.4 TFLOPS |
FP16 | 11 TFLOPS |
INT8 | 22 TOPS |
带宽 | 137 GB/s |
频率 | 900MHz |
Tensor Performance (FP16): Tensor Core的半精度浮点性能,特别针对深度学习和AI应用进行了优化。
INT8 Performance: 8位整数性能,常用于某些深度学习工作负载。
INT4 Performance: 4位整数性能,适用于需要更高吞吐量但可以接受较低精度的应用。
这些数据提供了一个全面的视图,显示了A100在不同精度和数据类型下的性能。不同的应用和任务可能会根据其对计算精度和速度的需求来选择最适合的数据类型和运算模式。
4.2 FLOPs
这个容易弄混淆,这个只是衡量模型大小的指标,下面展示YOLOV5跟Swin Transformer的FLOPs
参数/模型 | YOLOv5 (640x640) | Swin Transformer (224x224) |
---|---|---|
Tiny/Small | YOLOv5s: ~3.5 GFLOPs | Swin Tiny: ~4.5 GFLOPs |
Medium | YOLOv5m: ~6.9 GFLOPs | Swin Small: ~8.7 GFLOPs |
Large | YOLOv5l: ~12.7 GFLOPs | Swin Base: ~17.3 GFLOPs |
Extra Large | YOLOv5x: ~17.4 GFLOPs | Swin Large: ~34.5 GFLOPs |
-
模型的规模与计算复杂性的关系:
- 对于每个模型系列(不论是YOLOv5还是Swin Transformer),当模型规模增加(从Tiny到Extra Large)时,计算复杂性(FLOPs)也相应增加。这很容易理解,因为更大的模型通常具有更多的层和参数,因此需要更多的计算。
-
模型输入尺寸的影响:
- YOLOv5的输入尺寸为640x640,而Swin Transformer的为224x224。即使如此,较小的Swin Transformer模型仍然具有相似或更高的FLOPs。这突显了Transformer结构相较于传统的卷积网络结构在计算上的密集性。
-
模型类型的不同:
- 正如前面提到的,YOLOv5是一个目标检测模型,而Swin Transformer主要设计用于图像分类。将这两者进行对比可能不完全公平,因为它们是为不同的任务优化的。不过,这个对比提供了一个关于不同模型和结构计算复杂性的大致感觉。
-
FLOPs与性能的关系:
- 虽然FLOPs提供了关于模型计算复杂性的信息,但它并不直接等同于模型的实际运行速度或效率。其他因素,如内存访问、优化技术、硬件特性等,都会影响实际性能。
- 同样,FLOPs也不直接等同于模型的准确性。有时,较小的模型经过适当的训练和优化可能会表现得相当好。
总的来说,这个表格提供了一个视觉上的对比,展示了两种不同模型结构在不同规模下的计算复杂性。但解释这些数据时,要考虑到模型的具体用途、设计目标和其他相关因素。
4.3 CUDA Core and Tensor Core
CUDA Core:
- 定义: CUDA Core 是 NVIDIA GPU 中用于执行浮点和整数运算的基本计算单元。
- 用途: CUDA Cores 主要用于通用的图形和计算任务,比如图形渲染、物理模拟和其他数值计算等。
Tensor Core:
- 定义: Tensor Core 是 NVIDIA 的一些新架构(如 Volta、Turing 和 Ampere)中引入的专门硬件单元,用于高效地执行深度学习中的矩阵运算。
- 用途: Tensor Cores 专门设计用于深度学习计算,尤其是进行大规模的矩阵乘法和加法操作,这些操作是神经网络训练和推理的核心。
简而言之,CUDA Core 是 GPU 的通用计算工作马,处理各种图形和计算任务,而 Tensor Core 则是为深度学习任务特别设计的高效计算单元。
A100 有 6912 个 CUDA Core,而只有 432 个 Tensor Core。尽管 Tensor Cores 的数量较少,但它们在处理特定的深度学习任务时非常高效。
设计目的:
CUDA Cores 是通用的计算单元,能够处理各种任务,包括图形、物理模拟和通用数值计算等。
Tensor Cores 则专门设计用于深度学习计算,尤其是矩阵乘法和累加操作。
性能:
单一的 CUDA Core 能够执行基本的浮点和整数运算。
每个 Tensor Core 能够在一个周期内处理一小块矩阵的乘法和累加操作(例如 4x4 或 8x8)。这使得它们在处理深度学习操作时非常高效。
使用场景:
当执行图形渲染或通用计算任务时,主要使用 CUDA Core。
当执行深度学习训练和推理任务时,尤其是使用库如 cuDNN 或 TensorRT 时,Tensor Cores 会被积极利用,以实现最大的计算效率。
使用 A100 作为例子,我们可以清楚地看到 NVIDIA 是如何通过结合 CUDA Cores 和 Tensor Cores 来提供高效的深度学习和通用计算性能的。
4.4 Roofline model
Roofline Model 是一个可视化工具,用于表征计算密集型应用的性能。它提供了一个框架,通过该框架,开发者可以理解应用的性能瓶颈,并与某个特定硬件的理论峰值性能进行对比。Roofline 模型的主要目标是提供对算法和硬件交互的深入了解,从而为优化提供指导。
Roofline模型基本上是一个图,其中:
- x轴: 计算与数据移动的比率,通常用“浮点运算次数/字节”表示。
- y轴: 性能,通常以“FLOPS”为单位。
在此图上有两个主要部分:
-
Roof: 这代表了硬件的性能上限。这是两部分组成的:
- 计算上限:这通常是以FLOPS为单位的峰值计算性能。
- 带宽上限:这是数据从主存储器移动到计算单元的最大速率。
-
Line:这表示应用或算法的性能。它的斜率由内存访问和浮点计算的比率决定。
通过观察算法在Roofline模型上的位置,开发者可以判断算法是受计算能力限制还是受带宽限制,并据此决定优化策略。
案例一: RTX 3080
案例二: Jetson Xavier AGX Volta
参数 | Jetson Xavier AGX (Volta) |
---|---|
Core种类与数量 | |
CUDA cores | 512 |
Tensor cores | 64 |
SMs | 8 |
计算峰值 | |
FP32 | 1.4 TFLOPS |
FP16 | 11 TFLOPS |
INT8 | 22 TOPS |
带宽 | 137 GB/s |
频率 | 900MHz |
也可以从这两个案例的对比看出来边缘端跟服务器端的区别,所以TensorRT CUDA的掌握就很重要, 能够使用这些SDK满足客户的需求也是我们求职的一个机会
4.3 模型部署的一些误区
模型性能与FLOPs
FLOPs, 即浮点运算次数, 通常被用来衡量模型的计算复杂性。然而,它并不足以完全描述模型的性能。尽管FLOPs反映了模型的计算负荷,但实际的推理速度和效率还受到其他因素影响。例如,访问内存、数据的转换和重塑,以及其他与计算无关但与深度神经网络操作相关的部分。此外,像前后处理这样的步骤,也可能占据显著的时间,尤其是在一些轻量级模型中。
TensorRT的局限性
TensorRT是NVIDIA提供的一个强大的工具,可以对深度学习模型进行优化以获得更好的推理性能。然而,它的优化能力并非没有局限。例如,某些低计算密度的操作,如1x1的conv,depthwise conv, 可能不会被TensorRT重构。有些操作,如果GPU不能优化,TensorRT可能会选择在CPU上执行。但开发者可以手动调整代码,使某些CPU操作转移到GPU。此外,如果遇到TensorRT尚不支持的算子,可以通过编写自定义插件来补充。
1x1 conv, depthwise conv 这些算子出现在mobileNet上面,Transformer的优化也是把最后的FC层用这两个算子去替换,他们虽然降低了参数量,但是减少了计算的密度。
CUDA Core与Tensor Core的选择考量
NVIDIA的最新GPU通常配备了CUDA Cores和Tensor Cores。虽然Tensor Cores专门为深度学习操作优化,但TensorRT不一定总是使用它们。实际上,TensorRT通过内核自动调优选择最优的内核执行方式,这可能意味着某些情况下INT8的性能比FP16还差。要有效利用Tensor Cores,有时需要确保tensor的尺寸为8或16的倍数。
前后处理的时间开销
在深度学习的应用中,前处理(如图像调整和归一化)和后处理(如结果解释)是不可或缺的步骤。然而,对于轻量级的模型,这些处理步骤可能比实际的DNN推理还要耗时。部分前后处理步骤由于其复杂逻辑不适合GPU并行化。但解决方案是将这些逻辑中的并行部分移至GPU或在CPU上使用优化库如Halide,这样可以提高某些任务,如模糊、缩放的效率。
很多时候在做YOLO的后处理的时候我们会喜欢把它放在GPU上面去做,这样会给人一种很快的感觉,但是这种并不是必要的,第一,GPU没有排序的功能,第二,YOLO系列我们使用阈值先过滤掉一大部分的时候剩下来的bbox已经是很少的了,也不见得说会快很多。
并不是TRT跑通了就结束了
创建并使用TensorRT推理引擎仅仅是优化流程的开始。为了确保模型达到最佳性能,开发者需要进一步对其进行基准测试和性能分析。NVIDIA提供了如nsys, nvprof, dlprof, Nsight等工具,这些工具可以帮助开发者精确地确定性能瓶颈、寻找进一步的优化机会以及识别不必要的内存访问。
总结
深度学习模型的部署与优化是一个综合性的过程,涉及多个关键考虑因素。FLOPs常被用作模型计算复杂性的指标,但实际性能受到其他因素如内存访问和数据处理的影响。虽然工具如TensorRT为模型提供了强大的优化,但其应用并非无限,有时需要开发者手动调整或补充。此外,选择CUDA Cores还是Tensor Cores、考虑前后处理的效率,以及进一步的性能分析和基准测试,都是确保模型在特定硬件上达到最佳性能的关键步骤。