1. 动手之前,先想清楚你要算的是什么
做LoRA微调,很多人一上来就盯着显卡显存看,这个习惯得先纠正。显存只是算力估算的一部分,而且往往是最后一步才需要精确核算的指标。真正要算清楚的东西有三块:训练总计算量、显存占用峰值、训练耗时预估。这三块互相依赖,缺了一个,你买卡或者租云实例的时候就会踩坑,要么买小了训练到一半OOM,要么买大了多花冤枉钱。
我见过不少团队,拿着70B的模型要做LoRA微调,上来就按全量微调的方式租了8卡A100,结果实测发现单卡就能跑,硬是多花了三倍的云资源费用。也有人拿着7B的模型,笔记本4090硬扛,开了梯度检查点之后发现也能跑,但速度慢到怀疑人生,一个epoch要跑三天。这些情况的根源,都是没在动手之前把账算清楚。
先说结论性的东西:LoRA微调的算力占用,通常只有全量微调的10%到20%。这个数字不是我拍脑袋说的,而是由LoRA的设计原理决定的——它只训练注入到模型里的低秩矩阵, frozen掉绝大部分参数。但“只有全量微调的20%”这句话,落到具体项目里怎么换算成你需要的GPU数量和训练时长,需要一套系统的估算方法。
这篇文章要讲的,就是这套方法:从参数量的公式推导,到显存的逐项拆解,再到训练时长的估算,最后给真实的实战案例对照。不论你用的是Llama、Qwen还是其他开源模型,这套估算框架都能直接套用。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. LoRA训练算力估算的整体框架
2.1 为什么LoRA的算力需求比全量微调低这么多
要理解LoRA为什么省资源,先看它省在哪。全量微调时,模型的所有参数都要在反向传播中计算梯度并更新,7B模型就意味着70亿个参数都要参与优化器的状态维护和更新。而LoRA的做法是,把模型原有的权重全部冻结,只在特定的线性层旁边加上低秩分解的旁路矩阵,训练过程只更新这些旁路矩阵的参数。
具体来说,假设原始层权重是d乘以d的矩阵,LoRA在它旁边加一个d乘以r的矩阵A和r乘以d的矩阵B,其中r远小于d,通常取8、16、32。训练时原权重不动,只有A和B参与梯度计算和参数更新。这样一来,可训练参数量从d乘d降到了2乘以d乘以r,如果d是4096,r取16,那只有13万个参数要训练,而原层有1678万个参数,差了128倍。
但这并不意味着显存能省128倍,因为前向传播和反向传播还是要过完整模型,激活值的内存开销依然在。不过相比全量微调,省掉的是优化器状态、梯度状态中针对全量参数的那部分开销。这两块在混合精度训练里占比很大,所以整体显存能省到原来的20%左右是合理的。
2.2 估算流程:从模型规模倒推资源需求
算力估算不是凭感觉拍脑袋,而是有一个固定的思考路径。核心逻辑是从模型参数量出发,一步步推导出训练需要的计算量和显存量,再结合可用的硬件资源反推训练时间。这个流程可以概括为四步:
第一步,确认模型参数量和训练数据的token量。参数量从模型配置里能直接看到,比如Qwen2-7B就是70亿参数。训练数据量需要自己统计,文本数据直接去重后统计token数。
第二步,根据LoRA的配置算训练参数量。这里的配置包括LoRA作用的目标模块数、低秩矩阵的秩r,以及训练时冻结的比例。
第三步,用公式估算总计算量和显存峰值。
第四步,结合硬件参数反推训练时间,再决定是否调整batch size、序列长度、并行策略等。
这套流程的关键在于,每一步都有明确公式可套,不需要玄学,算出来的数字拿来和实测对比,误差基本在可控范围内。后面几章我会把每个公式拆开来讲。
3. 核心公式拆解:从参数量到显存占用的完整推导
3.1 参数量计算:一张表看清LoRA加了多少参数
算力估算的第一步永远是算参数量,这步错了后面全歪。全量模型参数量好说,看配置文件就行。关键是LoRA注入的参数怎么算。
假设模型有N个线性层被注入LoRA,每层的输入输出维度都是d,低秩矩阵的秩是r,那么每一层新增的参数是A矩阵:d乘以r,加上B矩阵:r乘以d,总共2乘以d乘以r。N层合计就是2乘以N乘以d乘以r。
举个例子,Qwen2-7B有28个自注意力层,每层的q_proj、k_proj、v_proj、o_proj四个线性层都可以注入LoRA,总共有112个注入点。如果秩取16,模型维度d是3584,那总的LoRA参数量是2乘以112乘以3584乘以16,大约是1284万参数。对比7B模型的全量参数,这个量级只占0.18%。
这里有个细节容易算错:有些模型的注意力层还有gate_proj、up_proj、down_proj这类FFN结构里的线性层,这些也可以注入LoRA。如果把这些也算进来,注入点数量会变多。实际项目中,我见过有人只注入注意力层的四个投影层,也有人把FFN层也加上,两者参数量能差将近两倍。所以算参数量的第一步,是明确你的target_modules到底选了哪些层。
下表列出常见配置下LoRA参数量的对比,方便你快速定位:
| 模型 | 参数量 | 注入层数 | LoRA秩 | LoRA参数量 | 占比 |
|---|---|---|---|---|---|
| Qwen2-1.5B | 1.5B | 96 | 16 | 约400万 | 0.27% |
| Qwen2-7B | 7B | 112 | 16 | 约1284万 | 0.18% |
| Llama-3-8B | 8B | 96 | 8 | 约800万 | 0.10% |
| Mistral-7B | 7B | 112 | 32 | 约2568万 | 0.37% |
3.2 显存估算公式:训练时显存到底花在哪儿
显存估算是最容易出问题的地方,因为很多人只算了模型权重的大小,忽略了优化器状态和激活值的开销。训练过程中的显存占用主要由四部分组成:模型权重、梯度、优化器状态、激活值
