别让GPU摸鱼!榨干它!

摘要:随着人工智能发展,Scaling Law 越来越受认可。早期,人们依靠增加 GPU 数量提升模型性能。我们也知道,如今各大优秀模型如DeepSeek、Llama、Gemini厂商除了卷算力,也都开始在工程化、算法等方面进行优化,以便更高效地利用GPU资源,节省成本。本文将基于GPU结构与工作原理,解析 GPU 利用率、SM 效率、MFU的计算原理以及优化方式,助力从业者更好地提升 GPU 在大模型训练与推理过程中的效能。

1.GPU界的"摸鱼大师"现形记

有没有碰到这种情况?GPU服务器买回来或租回来后,发现训练速度慢,比理想中差得很远。

PS:放这张图的意思是希望各位IT从业者看官们可以干到退休: )

为什么会这样呢?因为GPU也会偷懒,就像办公室里总有员工对着电脑疯狂敲键盘,实际却在看剧。GPU也会用"100%利用率"的假动作,悄悄摸鱼!

别让GPU摸鱼!榨干它!_第1张图片

AI Infra团队Trainy在实操中发现,GPU利用率并不总是理解GPU性能的最佳指标。实际上,在不做任何计算的情况下读取/写入内存,就可达到100%的GPU利用率!

今天我们就来扒一扒AI圈内这个心照不宣的秘密:为什么你的GPU明明显示满负荷,实际却在偷懒?

你以为在终端输入nvidia-smi看到的GPU利用率就是真相?Too young,too simple!

2.防止摸鱼,理解GPU的工作原理很重要

2.1GPU的主要组成部分

别让GPU摸鱼!榨干它!_第2张图片

在Nvidia GPU中,主要的计算单元为流处理器(SP),也就是CUDA core,多个SP与其它单元共同组成SM(Kernel流多处理器),SM与其它DRAM动态随机存取存储器与L2缓存等共同组成了GPU。当然,不同架构的GPU结构不同。

SP(streaming processor):SP是SM内的最小计算单元,即常说的"CUDA核心"。每个SP可执行单精度浮点(FP32)或整数运算,但SP无法独立运行Kernel,必须通过SM的统一调度才能工作。

SM(Streaming Multiprocessor,简称SM):又称为流式多处理器,是GPU的核心,也就是Kernel,又称为GPU大核,它由一定数量的寄存器、一定数量的共享内存、指令缓存、特殊功能单元、SP等组成,是GPU的核心执行单元,负责管理线程调度、内存访问和计算资源。

SFU(Special Function Unit,特殊功能单元):是 GPU 中专门用于执行特定类型计算任务的功能模块,比如超越函数(如正弦、余弦、指数、对数等)的计算。SFU 的存在可以让 GPU 更高效地处理一些复杂的数学运算,将这些特殊功能从通用的计算单元中分离出来,有助于提高整体计算效率和性能,减少通用计算单元的负担,使 GPU 能够更快速地完成一些特定的复杂数学运算任务,从而更好地支持图形渲染、科学计算等各种需要高精度数学计算的应用。

Shared Memory(共享内存):是 GPU 中位于芯片上的一种高速内存区域,可供同一个多处理器(Multiprocessor)中的多个线程块(Thread Block)共享数据。其主要作用是方便线程之间进行数据通信和协作,减少对全局内存的访问,因为访问共享内存比访问全局内存具有更高的带宽和更低的延迟。例如,在进行并行计算时,多个线程可以将中间结果存储在共享内存中,然后其他线程可以直接从共享内存中读取这些数据,避免了重复从全局内存读取和写入,从而提高了计算效率,尤其适用于需要频繁进行数据交互和共享的并行算法。

I-Cache(指令缓存):是一种高速缓存存储器,用于存储 GPU 即将要执行的指令。其目的是减少指令获取的时间,提高 GPU 的执行效率。当 GPU 需要执行指令时,首先会在 I-Cache 中查找,如果找到所需指令(即命中),则可以快速从缓存中获取并执行,而无需从较慢的内存中读取指令,这大大加快了指令的执行速度。由于 GPU 通常需要处理大量的指令,I-Cache 可以有效地减少指令访问的延迟,使 GPU 能够更流畅地运行程序,提高整体性能,特别是对于那些具有较高指令重复率的程序或算法,I-Cache 的作用更加明显。

MT Issue(多线程发射):是指 GPU 能够同时发射多个线程进行并行执行的能力。GPU 具有大量的处理核心,通过 MT Issue 技术,可以让多个线程同时在不同的处理核心上开始执行,从而充分利用 GPU 的并行计算能力,提高计算吞吐量。例如,在处理图形渲染任务时,可能有多个顶点或像素需要同时进行计算,MT Issue 允许 GPU 同时启动多个线程来分别处理这些任务,实现并行计算,大大加快了图形渲染的速度。这种多线程发射机制是 GPU 实现高效并行计算的关键技术之一,能够充分发挥 GPU 在处理大规模数据并行任务时的优势。

C-Cache(数据缓存,通常指 Cache Memory 中的数据缓存部分):主要用于存储 GPU 处理过程中经常访问的数据。与 I - Cache 不同,C - Cache 侧重于缓存数据,而不是指令。它可以缓存从全局内存或其他内存区域读取的数据,当 GPU 后续需要再次访问相同数据时,可以直接从 C - Cache 中获取,而不必再次从较慢的内存中读取,从而提高数据访问的速度,减少内存访问延迟。C - Cache 通常具有分层结构,包括一级缓存(L1 Cache)和二级缓存(L2 Cache)等,不同层次的缓存具有不同的容量、访问速度和功能,以优化数据缓存的效率,适应不同类型的计算任务和数据访问模式,提高 GPU 在处理各种数据密集型任务时的性能。

ROP(Render Output Pipeline,渲染输出流水线): ROP 是 GPU 渲染流程中的最后一个阶段,主要负责将渲染好的图像数据输出到显示设备上。它承担着多项重要任务,包括颜色混合、深度测试与模板测试、像素操作以及最终的帧缓冲管理等。在颜色混合过程中,ROP 会根据不同的渲染状态和纹理信息,将新生成的像素颜色与帧缓冲区中已有的颜色进行混合,以实现各种特殊效果,如透明、半透明等。深度测试和模板测试则用于决定每个像素是否应该被绘制以及如何绘制,通过这些测试可以确保图像的正确显示顺序和遮挡关系,避免错误的渲染结果。ROP 对于保证渲染图像的质量和准确性至关重要。它能够高效地处理大量的像素数据,确保输出的图像在颜色、深度和透明度等方面都符合预期,为用户提供高质量的视觉体验。在现代 GPU 中,ROP 的性能直接影响到最终的渲染帧率和图像质量,尤其是在处理复杂场景和高分辨率图像时,其作用更加显著。

L2 Cache(二级缓存):位于 GPU 芯片上的一种高速缓存存储器,用于存储 GPU 在处理过程中频繁访问的数据和指令。它作为一级缓存(L1 Cache)和主内存(如 DRAM)之间的中间缓存层次,主要负责缓存从主内存中读取的数据块以及一些经过处理的中间结果。当 GPU 需要访问数据时,首先会在 L1 Cache 中查找,如果未命中,则会在 L2 Cache 中查找。由于 L2 Cache 的容量通常比 L1 Cache 大,能够存储更多的数据,因此可以提高数据的命中率,减少对主内存的访问次数,从而降低内存访问延迟,提高 GPU 的整体性能。L2 Cache 在 GPU 中起到了平衡性能和成本的重要作用。它能够有效地弥补 L1 Cache 容量有限的不足,同时又比直接访问主内存具有更高的速度和更低的延迟。通过在 L2 Cache 中缓存常用数据,可以减少 GPU 与主内存之间的数据传输量,提高数据访问效率,特别是在处理大规模数据和复杂计算任务时,L2 Cache 能够显著提高 GPU 的性能和响应速度,有助于提升整个图形处理和计算过程的流畅性。

DRAM(Dynamic Random - Access Memory,动态随机存取存储器): GPU 用于存储各种数据的主要内存类型,包括纹理数据、顶点数据、帧缓冲数据以及计算过程中的中间结果等。它具有较大的存储容量,可以满足 GPU 对大量数据的存储需求。DRAM 通过不断地刷新存储单元来保持数据的有效性,其工作原理是基于电容存储电荷来表示数据,由于电容会逐渐漏电,因此需要定期进行刷新操作,以确保数据的准确性。DRAM 为 GPU 提供了必要的存储空间,使得 GPU 能够在处理图形渲染、计算任务等过程中快速地读取和写入数据。它与 GPU 的其他组件密切协作,为图形处理单元(GPU)和计算单元提供所需的数据支持。尽管 DRAM 的访问速度相对 GPU 内部的缓存来说较慢,但由于其大容量和相对较低的成本,使其成为 GPU 存储系统中不可或缺的一部分。随着 GPU 性能的不断提高,对 DRAM 的带宽和容量要求也越来越高,高性能的 DRAM 对于充分发挥 GPU 的计算能力和图形处理能力至关重要。

2.2GPU的计算原理

以下基于大模型训练的计算流程介绍GPU的计算原理。Kernel的执行单位是SM,而非单个SP。SM作为GPU的"计算引擎",负责将Kernel分解为线程块并调度到内部SP资源上执行。这种层级化设计(SM→SP)实现了计算任务的高效并行化,使得现代GPU在训练大模型时能达到每秒数百TB的计算吞吐量。

(1)数据加载与显存分配

主机-设备传输:训练数据首先从CPU内存通过PCIe总线(16-64GB/s)批量传输至GPU显存。现代GPU的HBM2显存容量可达80GB(如NVIDIA A100)或141(如NVIDIA H200),可存储完整的小批量训练数据(batch size)。

张量初始化:模型参数、优化器状态被分配为显存中的连续张量。例如1750亿参数的GPT-3模型,使用FP16混合精度时需至少350GB显存,需通过多GPU显存聚合技术存储。

(2)计算核心的任务分派

线程网格划分:CUDA将计算任务分解为网格(Grid),每个网格包含数千个线程块(Block)。以矩阵乘法为例,计算C=AB时,GPU将输出矩阵C划分为32x32的子块,每个线程块负责一个子块的计算。

指令发射:流多处理器(SM)将矩阵乘法的浮点指令派发至CUDA核心SP。每个SM在每个时钟周期可并发执行32个线程束(Warp)的指令,利用指令级并行隐藏延迟。

(3)多级内存协同计算

寄存器级计算:每个线程从全局显存加载输入数据至寄存器,执行乘加运算(FMA)。FP16张量核心可实现每秒312万亿次混合精度计算(H100)。

共享内存复用:当线程块需要共享数据时(如卷积核滑动窗口),将中间结果暂存于片上共享内存(每SM 192KB),访问延迟比全局显存低100倍。

全局同步写回:各线程块完成计算后,将结果原子写回全局显存。梯度计算阶段需要全局同步确保参数更新一致性。

(4)计算-通信流水线

前向传播流水线:当第N层的计算结果还在SM内处理时,第N+1层的输入数据已通过显存控制器预加载至共享内存。Ampere架构的异步执行能力可实现80%的计算单元利用率。

反向传播重叠:在计算损失函数梯度的同时,优化器参数更新操作通过独立硬件单元(如GPU上的独立INT32核心)异步执行。

多GPU梯度同步:通过NVLINK(900GB/s)或InfiniBand进行All-Reduce操作,各GPU的梯度张量在计算完成前即启动跨卡聚合。

(5)动态计算图优化

核融合技术:运行时编译器(如PyTorch的JIT)将相邻算子(如LayerNorm+GeLU)融合为单个GPU核函数,减少全局显存访问次数。

内存换速度优化:对Dropout等随机操作,在显存中预生成随机数掩码矩阵,通过张量核心执行按位运算,避免实时生成的计算开销。

稀疏计算加速:对MoE模型中的门控权重,利用Turing架构的结构化稀疏单元跳过零值计算,提升有效计算吞吐量3-5倍。

3.GPU利用率、SM效率、MFU模型FLOPS利用率

了解了GPU的原理后,下面我们介绍在GPU、SM、SP不同颗粒度上的算力利用率,就很好理解了。GPU利用率是从GPU单卡层面进行计算(当然也可以是单服务器或集群),SM效率是从流式多处理器SM(GPU核心)层面进行效率计算,MFU则是在SP(流处理器)层面计算利用率(浮点计算)。GPU利用率是概算,MFU是精算,SM效率介于两者中间。

3.1高GPU利用率(GPU-Util),可能是在摸鱼

别让GPU摸鱼!榨干它!_第3张图片

(GPU利用率飙高,但是可能只有个别SM在忙)

经常被硬件供应商拿来宣传的GPU利用率指标,用于衡量GPU卡级计算资源是否被充分利用,但GPU利用率并不能完全反映GPU的性能,因为GPU可能是在进行数据搬运、或者只有1个核心激活、亦或执行的是0浮点运算。

GPU利用率(GPU-Util):指的是基于时间片的活动比例(时间片占用率),根据NVIDIA的官方文档(NVML),GPU利用率(GPU-Util) 的定义为:在采样周期内,GPU上至少有一个内核(kernel即SM)处于执行状态的时间百分比。GPU-Util的计算依据是看资源是否被占用,而非资源是否满载(饱和度,Saturation),是从宏观角度衡量 GPU 在一段时间内实际使用的计算能力占总计算能力的比例。

GPU利用率的计算方法

  • 基于时间采样的统计方法 :这是较为常见的一种计算方式。通过对 GPU 的执行时间进行采样来估算利用率。例如,在特定的时间间隔内,检测 GPU 是否处于忙碌状态,将处于忙碌状态的采样次数与总采样次数的比值,即为 GPU 利用率。通常以百分比形式呈现。如在 100 个SM采样点中,检测到SM处于忙碌状态的有 80 个,那么 这块GPU 利用率就是 80%。
  • 通过性能计数器获取 :现代 GPU 通常配备了性能计数器,能够提供更精确的 GPU 利用率数据。这些计数器可以记录 GPU 各个单元(如 ALU、内存控制器等)的活动情况,然后根据这些活动数据计算出一个总体的 GPU 利用率。

3.2SM效率(Streaming Multiprocessor Efficiency)

由于GPU利用率只是判断是不是有SM在执行状态,不考虑在执行状态的SM的数量,类似判断一个杯子中是不是有水,有一滴水也作数,十滴水也是一样,这样就不能精确到各个SM,无法在GPU内部实现优化,这样看,GPU利用率不太准,只是从GPU层面(宏观)笼统判断。这里有一个更精确的指标SM效率。

SM 效率是指 GPU 中流多处理器(SM)内资源的利用效率,比如 CUDA 核心、共享内存等资源的使用效率,以及线程束执行的效率等。SM效率表示活跃的SM数量占总SM数量的百分比。例如,若GPU有100个SM,仅有10个在运行,则SM效率为10%,该指标相较GPU利用率更能反映GPU并行计算能力的真实利用率

以Nvidia H100 GPU为例,它有132个SM,每个SM有128个SP,总共提供了16896个SP。通过测算SM效率,我们可以确定CUDA核心是否在使用我们的流多处理器。例如,如果有一个CUDA kernel连续运行10秒,但只使用了1个SM,那么在H100上,这将记为100%的利用率,但SM效率将是1/132=0.7%。

3.3MFU(Model Floating - point Utilization):模型浮点运算利用率

由于SM效率是在SM层面做的统计,SM包括多个SP和其它缓存和特殊功能单元等,我们知道,对于大模型训练和推理的计算主要是浮点计算,浮点计算只有SP可以做。MFU就是用来统计最有效的模型浮点运算利用率(模型FLOPS利用率),类似电力上的有功功率。在Google的PaLM论文中这样介绍MFU:它是"观察到的吞吐量(每秒Token数)与系统在峰值FLOPS运行的理论最大吞吐量的比例"。MFU衡量的是在模型计算过程中,实际进行的浮点计算量与 GPU 理论上可进行的最大浮点计算量的比值,反映了 GPU 在模型浮点运算方面的资源利用程度。但它依赖于参数和框架,并且在预训练、监督微调阶段计算方法也不同,因此计算MFU相对困难,一般情况简单处理就用实测的Tokens/s值进行MFU的估算。

MFU通常这样计算:以观测吞吐量(tokens/s)与系统在峰值FLOPs下运行的理论峰值吞吐量的比值即:

4.让GPU"007"的秘籍

上边介绍了GPU利用率、SM效率、MFU的定义与计算方法,那么我们在实际应用过程中如何优化这些指标,尽可能让GPU真正实现"007"全时段的饱和工作呢?我们可以分别从GPU利用率(尽管GPU利用率可能不准,但也有一定参考作用且容易计算)、MFU、SM效率三个指标进行提升,以下是相关建议方法,当然,有些方法可以同时提高上述的两个或三个指标。

4.1如何提高GPU利用率

GPU的高效利用是深度学习任务加速的核心。以下为优化策略:

(1)数据加载优化:

使用多线程/多进程的DataLoader(如PyTorch的num_workers参数),并行加载数据以减少GPU等待时间。

启用异步数据预取(Prefetching),提前将数据从CPU传输到GPU。

优化数据预处理流程,将预处理任务移至CPU并行执行。

(2)计算与模型优化:

混合精度训练:使用FP16+FP32混合精度,结合Tensor Cores加速计算,减少显存占用。

增大Batch Size:根据显存容量调整批量大小,以充分利用GPU并行计算能力。

使用高效算子库:如cuDNN、cuBLAS等NVIDIA优化库,提升矩阵运算效率。

(3)硬件与系统优化:

多GPU并行:通过数据并行(DP)、模型并行(TP)或流水线并行(PP)扩展计算资源。

内存管理:减少CPU-GPU数据传输,使用梯度检查点(Gradient Checkpointing)节省显存。

升级硬件:选择高带宽显存的GPU(如A100/H100),并通过NVLink提升多GPU通信效率。

(4)监控与调优工具:

利用nvidia-smi或PyTorch Profiler实时监控GPU利用率与显存占用。

通过动态调整批量大小或框架自动优化(如PyTorch AMP)实现资源动态分配。

4.2如何提高SM效率

SM(Streaming Multiprocessor)效率的提升需从硬件资源调度、算法优化及监控分析等方面进行综合优化:

(1)并行度与负载均衡

动态任务分配:通过手动调度SM资源,将计算、通信和内存操作模块分离,使部分SM专注计算,另一部分处理通信任务,减少空闲时间例如,调整线程块(Block)和网格(Grid)大小,确保每个SM分配的线程数接近硬件上限(如A100每个SM支持2048线程)。

分块策略:将大型计算任务拆分为独立子任务,均匀分配给SM,避免资源倾斜。例如,在混合专家模型(MoE)中优化专家分配策略。

(2)内存访问优化

共享内存利用:将频繁访问的数据存入共享内存(Shared Memory),减少全局内存访问延迟。例如,矩阵乘法中使用共享内存缓存分块数据。

内存带宽管理:使用页锁定内存(Pinned Memory)加速CPU-GPU数据传输,减少SM等待。

(3)算法与内核设计

减少分支依赖:避免复杂分支逻辑,改用掩码运算或向量化操作,提升指令级并行(ILP)。

混合精度计算:使用FP16/FP8混合精度降低显存占用,提升计算吞吐量(需硬件支持)。

(4)监控与调优工具

性能剖析:利用NVIDIA Nsight Systems分析SM效率瓶颈,如内存节流(Stall Memory Throttle)或线程束未选中(Stall Not Selected)。

动态调整:根据实时负载调整线程块数量和内存分配策略。

(5)硬件与架构适配

异构计算:在支持Tensor Core的GPU(如A100/H100)上启用稀疏计算,优化高稀疏度场景的利用率。

通信优化:配置NVLink提升多GPU通信带宽,减少同步闲置。

4.3如何提高MFU(模型FLOPS利用率)

目前即便在顶尖计算卡上,多数大模型训练任务的MFU也只能达到35%-60%,还有很大的空间。如果能大幅提高MFU,则可节省数十亿美元的算力资源。

MFU衡量GPU计算资源的实际利用率,提升方法包括:

(1)减少无效计算:

避免冗余重计算,优化模型结构(如剪枝、量化)以降低计算量。

使用梯度累积(Gradient Accumulation)模拟大Batch Size,减少显存压力。

(2)优化通信效率:

分布式训练优化:采用流水线并行(Interleaved PP)和重叠通信(如DP Overlap),减少Bubble时间。

减少跨设备通信:通过张量并行(TP)优化参数分布,避免跨机通信带来的高延迟。

(3)硬件与框架协同:

选择支持高效通信的硬件(如NVLink互联的GPU集群),提升数据传输带宽。

使用高性能推理引擎(如TensorRT)或框架优化工具(如PyTorch的AMP)。

(4)稳定性保障:

定期保存检查点(Checkpointing),避免训练中断导致资源浪费。

优化集群调度策略,减少任务排队和资源争抢。

当然,以上只是列举的一小部分优化方法,在长期的实践中,不同厂家可能会创造出更优秀的优化算法和工程化工具和方法。

5.总结

GPU利用率、SM效率、MFU是从不同颗粒度来计算算力资源利用效率。它们之间其实没有谁更好,使用场景也不同,计算的越精确,需要投入的成本也越高,从业者应该按实际需要使用。

GPU 利用率是从宏观角度衡量 GPU 在一段时间内实际使用的计算能力占总计算能力的比例。侧重于从整体上评估 GPU 在系统中的资源利用状况,用于判断 GPU 是否存在资源瓶颈或闲置,以便进行系统级的任务调度和资源分配优化。

SM 效率是指 GPU 中流多处理器(SM)内资源的利用效率,比如 CUDA 核心、共享内存等资源的使用效率,以及线程束执行的效率等。SM 效率主要关注 GPU 内部微观层面计算资源的使用效率,有助于深入了解 GPU 架构特性和优化计算内核,该指标值容易获取

MFU 则是针对模型浮点计算而言,衡量的是在模型计算过程中,实际进行的浮点计算量与 GPU 理论上可进行的最大浮点计算量的比值,反映了 GPU 在模型浮点运算方面的资源利用程度。MFU 重点关注模型计算中浮点运算的资源利用情况,可帮助开发者针对模型特点优化计算过程,提高模型在 GPU 上的运行效率。

你可能感兴趣的:(技术干货,人工智能,gpu算力)