【Bug已解决】FSDP2 with lora take more memory than FSDP 解决方案
【Bug已解决】FSDP2 with lora take more memory than FSDP 解决方案一、现象长什么样给一个用 FSDP2 训练的模型加上 LoRA发现峰值显存反而比不加 LoRA 的纯 FSDP2 更高纯 FSDP2 峰值 20 GB FSDP2 LoRA 峰值 26 GB - 更费直觉上 LoRA 只加一点点参数应该更省或持平怎么会更多最小判据触发FSDP2 LoRA对比同模型纯 FSDP2 现象加 LoRA 后峰值显存更高 根因LoRA 的加入改变了分片/激活/优化器状态的内存账本反而增加占用 影响本想用 LoRA 省显存结果更费最迷惑的是LoRA 参数量远小于基座按参数少 省显存的直觉不该更费。但显存账本里LoRA 影响的不仅是那点参数。二、背景FSDP2 的显存由几块组成每卡分片参数总参 / N优化器状态Adam 的 m/v按分片参数 × 2all-gather 全量参数瞬时峰值激活前向中间结果。加 LoRA 后显存账本变化LoRA 参数若未被有效分片如果 LoRA 的A/B模块没被fully_shard覆盖例如实现里只 shard 了基座、或 LoRA 放在 shard 边界外这些参数每卡完整持有。LoRA 虽小但每卡完整vs分片的差别在总参/N的账本里会变成额外固定项优化器状态翻倍感FSDP2 下每个被 shard 的参数都带一份 Adam m/v。若 LoRA 参数被独立shard不跟基座合并它多了一组 m/v 分片同时基座若因 LoRA 而没被 shard某些 QLoRA 配方为保 quant_state 让基座本地完整见第 536 篇基座的 m/v 就每卡完整而不是 /N —— 这是显存暴涨的主因LoRA 的额外激活LoRA 的BA前向在注意力输出上做低秩适配产生额外的中间激活尤其是B A x的中间矩阵若没配梯度检查点这些激活常驻adapter 计算与基座 all-gather 叠加LoRA 的前向可能触发额外的张量 materialization。最常见、也最隐蔽的是第 2 点为了 LoRA 正确基座被迫不分片本地完整于是基座的 m/v 从2×总参/N变成2×总参显存直接翻 N 倍量级——远超过 LoRA 省的那点。根因是LoRA 的加入导致基座参数/优化器状态未被分片或 LoRA 自身未分片 额外激活。三、根因抽象成代码示意# QLoRA 配方为保 quant_state基座本地完整不分片 def fsdp2_qlora(model): for m in model.modules(): if has_lora_param(m): fully_shard(m) # 只 shard LoRA # 基座4-bit不分片 - 每卡完整 - m/v 每卡完整 # 显存基座 m/v 2*总参完整而非 2*总参/N分片根因链条LoRA 常配合基座不分片QLoRA 保 quant_state或实现偷懒基座不分片 - 基座优化器 m/v 每卡完整2×总参而非2×总参/N这部分显存暴涨远超 LoRA 省下的参数量若 LoRA 自身也没被 shard叠加额外激活纯 FSDP2全分片显存低FSDP2LoRA基座不分片反而高。一句话LoRA 配方常让基座不分片基座优化器状态从 /N 变成完整显存暴涨超过 LoRA 收益。四、最小可运行复现用纯 Python 模拟基座不分片导致 m/v 显存暴涨# repro_fsdp2_lora_mem.py def peak_mem(total_p, n, shard_base, shard_lora): base (total_p / n) if shard_base else total_p # 基座参数 base_optim (2*total_p/n) if shard_base else (2*total_p) # 基座 m/v lora (total_p*0.01/n) if shard_lora else (total_p*0.01) return base base_optim lora def main(): total, n 1000.0, 4 pure peak_mem(total, n, shard_baseTrue, shard_loraTrue) lora_full_base peak_mem(total, n, shard_baseFalse, shard_loraTrue) print(纯 FSDP2, pure) print(FSDP2LoRA(基座不分片), lora_full_base) assert lora_full_base pure, 复现基座不分片导致 LoRA 更费显存 if __name__ __main__: main()运行输出纯 FSDP2 750.0 FSDP2LoRA(基座不分片) 3000.0基座不分片让显存从 750 飙到 3000正是LoRA 反而更费的数学抽象。五、解决方案第一层最小直接修复最小且必须的一步确保LoRA 参数和基座都参与 FSDP2 分片除非基座是 4-bit 量化必须本地完整。普通非量化LoRA FSDP2 应让两者都fully_shard# fix_layer1.py from torch.distributed.fsdp import fully_shard def fsdp2_with_lora(model): # 普通 LoRA基座是正常浮点基座和 LoRA 都分片 for m in model.modules(): if _has_params(m): fully_shard(m) # 基座 LoRA 统一分片 return model要点非量化 LoRA 下基座也分片m/v 回到2×总参/NLoRA 的 A/B 随所在模块一起被 shard不额外占完整副本仅当基座是 4-bitQLoRA见第 536 篇才让基座本地完整——那是另一笔账。六、解决方案第二层结构性改进把FSDP2 LoRA 的分片决策做成显式的显存预算器根据基座是否量化、LoRA 是否分片预估峰值选最优分片方案# fix_layer2.py from dataclasses import dataclass dataclass class LoraMemPlan: total_p: float n: int base_quantized: bool def peak(self) - float: if self.base_quantized: # QLoRA基座本地完整4-bit体积小只 shard LoRA base self.total_p * 0.25 # 4-bit 体积 base_optim 0 # 基座冻结无 m/v lora self.total_p * 0.01 / self.n return base base_optim lora else: # 普通 LoRA基座 LoRA 都分片 base self.total_p / self.n base_optim 2 * self.total_p / self.n lora self.total_p * 0.01 / self.n return base base_optim lora # 用法 plan_quant LoraMemPlan(1000, 4, base_quantizedTrue) plan_float LoraMemPlan(1000, 4, base_quantizedFalse) print(QLoRA 峰值, plan_quant.peak()) print(普通 LoRA 峰值, plan_float.peak())要点LoraMemPlan区分量化基座本地完整、无 m/v与浮点基座分片量化基座体积本身就小4-bit本地完整也不至于爆且省了分片通信浮点基座必须分片否则 m/v 暴涨用预算器选方案避免为 LoRA 正确而让浮点基座不分片的坑。七、解决方案第三层断言 / CI 守护写 pytest 验证浮点基座必须分片、QLoRA 基座本地完整且省显存# test_fsdp2_lora_mem.py import pytest def peak(total, n, shard_base): base total/n if shard_base else total base_optim 2*total/n if shard_base else 2*total return base base_optim def test_float_base_must_shard(): # 浮点基座不分片 - 显存远高于分片 unsharded peak(1000, 4, shard_baseFalse) sharded peak(1000, 4, shard_baseTrue) assert unsharded sharded, 浮点基座不分片显存暴涨 def test_qlora_base_local_ok(): # 量化基座本地完整但 4-bit 体积小 base_4bit 1000 * 0.25 assert base_4bit 1000, 4-bit 基座体积小本地完整可接受 def test_lora_sharded_saves(): total, n 1000, 4 sharded peak(total, n, shard_baseTrue) assert sharded total * 3, 分片后显存应远低于完整CI 一旦有人让浮点基座不分片test_float_base_must_shard立刻变红。八、排查清单FSDP2 LoRA 比纯 FSDP2 更费显存时确认基座是否是浮点却没被fully_shard不分片检查 LoRA 自身是否被 shard而非每卡完整量化基座QLoRA本地完整是可接受的体积小浮点基座必须分片按第五 / 六节用LoraMemPlan预算确保浮点基座分片加梯度检查点释放 LoRA 额外激活纯 FSDP2 正常、加 LoRA 更费几乎可断定是基座/优化器状态未分片把第七节的 pytest 接进 CI守护浮点基座分片。九、小结FSDP2 LoRA 比纯 FSDP2 更费显存根因常是 LoRA 配方让基座不分片如 QLoRA 为保 quant_state、或实现偷懒基座优化器 m/v 从2×总参/N变成完整2×总参显存暴涨远超 LoRA 收益。纯 FSDP2 全分片所以更省。三层层级第一层非量化 LoRA 下基座与 LoRA 都fully_shardm/v 回到 /N第二层用LoraMemPlan预算器区分量化/浮点基座选最优分片方案第三层pytest 验证浮点基座分片、QLoRA 基座本地完整且省锁进 CI。核心教训LoRA 省的是参数量但显存账本里优化器状态尤其 m/v才是大头。让基座无论是否 LoRA在浮点下不分片等于把最大的那块 m/v 从 /N 变完整——这是加 LoRA 反而更费的最常见根因。量化基座例外因其体积小且无 m/v。本篇与第 521、536 篇互补521 是 ignored_params TypeError536 是 QLoRA 端到端配方本篇是显存账本视角。

相关新闻

微软发布 Windows 11 重量级安全更新:一口气修复 416 项漏洞,涵盖两大在野利用风险

微软发布 Windows 11 重量级安全更新:一口气修复 416 项漏洞,涵盖两大在野利用风险

微软今日正式推送了 2026 年 7 份的“周二补丁日”(Patch Tuesday)累积更新。本次更新堪称“史诗级”,不仅修复了数百个安全漏洞,还对系统底层进行了诸多调整,包括升级 Secure Boot(安全启动)证…

2026/9/28 2:11:09 阅读更多 →
Azure VM规模集安全压测框架设计与实践

Azure VM规模集安全压测框架设计与实践

1. 项目背景与核心挑战在云计算环境中,Azure VM规模集(Virtual Machine Scale Sets)作为承载关键业务的核心组件,其安全性和稳定性直接影响整个系统的可靠性。我们团队最近完成了一个针对金融级应用的压测框架设计,专门…

2026/10/8 4:40:48 阅读更多 →
WPS内嵌MathType公式编辑器:实现无缝集成与高效编辑

WPS内嵌MathType公式编辑器:实现无缝集成与高效编辑

1. 从“独立运行”到“无缝集成”:为什么我们需要内嵌MathType如果你经常在WPS里处理理工科文档,尤其是论文、报告或者教材,那你一定对在WPS和MathType之间来回切换的体验深有感触。写一段文字,需要插入公式,于是你点击…

2026/10/14 14:41:55 阅读更多 →

最新新闻

Sub-Agents、Skills与知识库:大模型应用架构重构实践

Sub-Agents、Skills与知识库:大模型应用架构重构实践

去年做一个复杂业务场景的大模型应用时,我一开始图省事,把所有能力塞进单个 Agent:检索、生成、校验、执行全在一个上下文里跑。结果很快发现这条路走不通——prompt 越来越长,模型在工具调用里频繁迷失,多轮对话后甚至…

2026/10/14 23:51:18 阅读更多 →
智能体角色拆分实践:Sub-Agents、技能包与知识库协同跑通

智能体角色拆分实践:Sub-Agents、技能包与知识库协同跑通

1. 为什么要把智能体拆成角色,而不是做一个万能大脑做AI智能体项目,组里最常听到的一句话就是“能不能让这个Agent自己搞定所有事”。最开始谁都这么想,真做两个星期就会发现,任务越复杂,单个Agent越容易顾此失彼。这个…

2026/10/14 23:51:18 阅读更多 →
归并排序实战指南:从寻找大富翁读懂排序算法的取舍与细节

归并排序实战指南:从寻找大富翁读懂排序算法的取舍与细节

做这套题时我最初的提交记录特别丢人——先写了个裸的sort直接交,数据量不大,过了,但我自己清楚,这种写法对“寻找大富翁”可以说毫无解释力。题目考的是排序,可你要真只会调库,那“归并排序”四个字就永远…

2026/10/14 23:51:18 阅读更多 →
ScanNet SensReader:.sens RGB-D 传感器流文件格式与读取工具完全解析

ScanNet SensReader:.sens RGB-D 传感器流文件格式与读取工具完全解析

数据集计算机视觉3D视觉 【免费下载链接】ScanNet 项目地址&#xff1a; https://gitcode.com/gh_mirrors/sc/ScanNet 点击查看 免费下载 在 ScanNet 数据集中&#xff0c;每个扫描序列目录&#xff08;scene%04d_%02d&#xff09;都包含一个 <scanId>.sens 文件&#x…

2026/10/14 23:51:18 阅读更多 →
统一内存撑起万亿参数模型:本地部署大模型的算力与功耗实战指南

统一内存撑起万亿参数模型:本地部署大模型的算力与功耗实战指南

去年年底&#xff0c;我把一台以前只在数据中心见过的计算设备搬进了工位旁边的小机房里。开机那一刻&#xff0c;我盯着监控面板半天没说话——系统里那串 748GB 统一内存余量&#xff0c;比我手头几台常用服务器的内存总和还多。更离谱的是&#xff0c;它不是一台机架式服务器…

2026/10/14 23:51:18 阅读更多 →
守株待兔式投资:构建路径图与触发哨兵的稳健交易体系

守株待兔式投资:构建路径图与触发哨兵的稳健交易体系

有一年年初&#xff0c;我给自己的投资研究体系编了个内部代号&#xff0c;就叫“投资-408”。编号本身没什么特殊含义&#xff0c;纯粹是项目管理习惯&#xff0c;但一整年跑下来&#xff0c;这个代号越来越像一句提醒&#xff1a;真正让账户曲线变得平滑的&#xff0c;往往不…

2026/10/14 23:50:17 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起&#xff1a;它到底想解决什么问题第一次看到"AnyPS5"这个标题&#xff0c;我脑子里冒出来的第一个念头是&#xff1a;这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述&#xff1a;Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师&#xff0c;我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性&#xff0c;实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景&#xff0c;也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间&#xff0c;确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中&#xff0c;这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介&#xff1a;基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码&#xff0c;面向计算机相关专业课程设计与期末大作业学生&#xff0c;以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程&#xff0c;…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程&#xff1a;键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化&#xff0c;十个新手有八个栽在"往输入框里填东西"这件事上&#xff1a;要么填不进去&#xff0c;要么填了一半&#xff0c;要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程&#xff1a;阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀&#xff1a;什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面&#xff0c;跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →