调整大型预训练语言模型(这些模型通常包含数十亿个参数,如封装在权重矩阵 $W$ 中的那样)以通过全量微调来适应专门的下游任务,看起来是一种直接的方法。然而,这个过程需要更新模型中的每一个参数,因此会带来大量的资源需求。内存需求:GPU瓶颈训练大型模型几乎总是受限于图形处理单元(GPU)上的可用内存。全量微调需要同时在GPU内存中存储多个大型张量:模型权重 ($W$): 参数本身构成了基本的内存需求。对于一个有 $N$ 个参数的模型,以标准32位浮点精度(FP32)存储它们需要 $4N$ 字节。即使使用FP16或BF16等16位格式的混合精度,仍然需要 $2N$ 字节。对于像GPT-3这样拥有1750亿参数的模型,这意味着FP32下需要700GB,FP16/BF16下需要350GB,这远远超过了普通GPU的容量。梯度 ($\nabla W$): 在反向传播过程中,会为每个参数计算梯度。这些梯度通常与模型权重具有相同的维度,并需要相同的内存量(如果对梯度使用混合精度,则FP32下需要额外 $4N$ 字节,FP16/BF16下需要 $2N$ 字节)。优化器状态: Adam或AdamW等现代优化器会维护状态信息,以调整每个参数的学习率。例如,Adam为每个参数存储两个矩:第一矩(动量)和第二矩(方差)。如果这些矩以FP32存储,这将额外增加 $8N$ 字节(每个矩 $4N$ 字节)。即使使用8位优化器,仍然会增加可观的开销。在FP32中使用AdamW时,参数、梯度和优化器状态的总内存可迅速达到 $4N + 4N + 8N = 16N$ 字节。使用混合精度可能会将此减少到 $2N + 2N + 8N = 12N$ 字节(如果矩保持在FP32中),如果矩也被量化,则会更少。中间激活值: 前向传播为每个层生成激活值。在反向传播过程中需要这些激活值来计算梯度。激活值消耗的内存取决于批量大小、序列长度、模型隐藏维度以及层数。对于大型模型和长序列,激活值会消耗大量的内存,有时甚至超过权重和优化器状态所需的内存。激活检查点(或梯度检查点)等技术可以通过在反向传播时重新计算激活值而不是存储它们来减少内存消耗,但这会增加计算时间(通常增加约30%)。这些组件的结合意味着,即使是微调中等规模的模型(例如,70亿到130亿参数),也需要配备大内存容量(例如,40GB或80GB)的高端GPU,通常需要跨多个GPU进行分布式训练设置,这会增加通信开销和复杂性。{"layout": {"title": "全量微调的内存近似分解(FP16模型,Adam FP32状态)", "xaxis": {"title": "模型大小(十亿参数)"}, "yaxis": {"title": "估计内存(GB)"}, "barmode": "stack"}, "data": [{"type": "bar", "name": "模型权重 (FP16)", "x": ["7B", "13B", "70B"], "y": [14, 26, 140], "marker": {"color": "#4263eb"}}, {"type": "bar", "name": "梯度 (FP16)", "x": ["7B", "13B", "70B"], "y": [14, 26, 140], "marker": {"color": "#74c0fc"}}, {"type": "bar", "name": "优化器状态 (FP32)", "x": ["7B", "13B", "70B"], "y": [56, 104, 560], "marker": {"color": "#f76707"}}, {"type": "bar", "name": "激活值(可变)", "x": ["7B", "13B", "70B"], "y": [20, 40, 160], "marker": {"color": "#ffe066"}}]}全量微调使用混合精度(FP16)处理权重/梯度,并使用标准Adam(FP32状态)时的近似内存需求。激活值内存是示意性的,并随批量大小和序列长度而变化很大。请注意,即使对于较小的模型,总内存也超过了典型的单GPU容量。计算成本:时间和FLOPs除了内存,全量微调所需的计算量也极其庞大。每个训练步骤包括:前向传播: 将输入数据通过网络的所有层进行传播。反向传播: 使用反向传播为所有参数计算梯度。优化器更新: 根据梯度和优化器状态更新所有模型参数。主要成本来源于Transformer层内部的矩阵乘法(自注意力机制和前馈网络)。浮点运算次数(FLOPs)随参数数量、序列长度和批量大小的增加而显著增加。即使在强大的多GPU集群上,仅用大型数据集训练大型模型一个周期也可能需要数天或数周,这会产生可观的能源和硬件成本。存储成本:检查点与数量增长微调工作流程通常涉及定期保存模型检查点。大型模型的单个检查点,如果存储完整的权重集 $W$ (以及可能的优化器状态),可以占用数百GB甚至数TB的磁盘空间。此外,考虑您需要使基础模型适应多个不同任务或数据集的场景。全量微调需要为每个任务存储一份完整且独立的庞大模型权重副本。从存储角度来看,这很快变得难以管理,并阻碍了需要多个专用模型时的有效部署。如果一个700亿参数的模型检查点大约是140GB(在BF16中),那么为10个不同任务进行微调将仅最终权重就需要1.4TB的存储空间,还不包括中间检查点。这些与更新每个参数 $W$ 相关的内存、计算和存储难题,显然促使人们寻求更高效的适应技术。参数高效微调(PEFT)方法旨在显著降低这些成本,同时在下游任务上保持高性能,这构成了本课程的核心内容。