大模型微調顯存內存節約方法

大模型微調時節約顯存和內存是一個至關重要的話題,尤其是在消費級GPU(如RTX 3090/4090)或資源有限的云實例上。下面我將從顯存(GPU Memory)內存(CPU Memory) 兩個方面,為你系統地總結節約策略,并從易到難地介紹具體技術。

核心問題:顯存和內存被什么占用了?

  • 顯存占用大頭

    1. 模型權重:以FP16格式存儲一個175B(如GPT-3)的模型就需要約350GB顯存,這是最主要的占用。
    2. 優化器狀態:如Adam優化器,會為每個參數保存動量(momentum)和方差(variance),這通常需要2倍于模型參數(FP16)的顯存。例如,對于70億(7B)參數的模型,優化器狀態可能占用 7B * 2 * 2 = 28 GB(假設模型權重占14GB FP16)。
    3. 梯度:梯度通常和模型權重保持同樣的精度(例如FP16),這又需要一份1倍的顯存。
    4. 前向傳播的激活值:用于在反向傳播時計算梯度,這部分占用與batch size和序列長度高度相關。
    5. 臨時緩沖區:一些計算操作(如矩陣乘)會分配臨時空間。
  • 內存占用大頭

    1. 訓練數據集:尤其是將整個數據集一次性加載到內存中。
    2. 數據預處理:tokenization、數據增強等操作產生的中間變量。

一、 節約顯存(GPU Memory)的策略

這些策略通常需要結合使用,效果最佳。

1. 降低模型權重精度(最直接有效)
  • FP16 / BF16 混合精度訓練:這是現代深度學習訓練的標配。

    • 原理:將模型權重、激活值和梯度大部分時間保存在FP16(半精度)或BF16(Brain Float)中,進行前向和反向計算,以節約顯存和加速計算。同時保留一份FP32的權重副本用于優化器更新,保證數值穩定性。
    • 節省效果顯著。模型權重和梯度占用幾乎減半。
    • 實現:框架(如PyTorch)自帶(torch.cuda.amp),或深度學習庫(如Hugging Face Trainer)只需一個參數 fp16=True 即可開啟。
  • INT8 / QLoRA 量化微調

    • 原理:將預訓練模型的權重量化到低精度(如INT8),甚至在使用QLoRA時量化到4bit,然后在微調時再部分反量化回BF16/FP16進行計算,極大減少存儲模型權重所需的顯存。
    • 節省效果極其顯著。QLoRA可以讓一個70B模型在單張48GB顯存卡上微調。
    • 實現:使用 bitsandbytes 庫和 peft 庫可以輕松實現。
2. 優化優化器和梯度(針對優化器狀態)
  • 使用內存高效的優化器
    • Adafactor, Lion, 或 8-bit Adam (bitsandbytes.optim.Adam8bit)。
    • 原理:這些優化器以不同的方式減少了動量、方差等狀態的存儲需求。例如,8-bit Adam將優化器狀態也量化到8bit存儲。
    • 節省效果顯著。可以節省大約 0.5~1倍 模型權重的顯存(原本需要2倍)。
3. 減少激活值占用
  • 梯度檢查點(Gradient Checkpointing)
    • 原理:在前向傳播時只保存部分層的激活值,而不是全部。在反向傳播時,對于沒有保存激活值的層,重新計算其前向傳播。這是一種 “用計算時間換顯存” 的策略。
    • 節省效果非常顯著。可以將激活值占用的顯存減少到原來的 1/sqrt(n_layers) 甚至更少,但訓練時間會增加約20%-30%。
    • 實現:在Hugging Face Transformers中,只需在 TrainingArguments 中設置 gradient_checkpointing=True
4. 降低計算過程中的開銷
  • 減少Batch Size和序列長度
    • 這是最直接但可能影響效果的方法。Batch Size和序列長度會線性影響激活值顯存占用。
  • 使用Flash Attention
    • 原理:一種更高效、顯存友好的Attention算法實現。它通過分塊計算避免存儲完整的 N x N 注意力矩陣,從而大幅減少中間激活值的顯存占用。
    • 節省效果顯著,尤其對于長序列任務。
    • 實現:需要安裝對應的庫(如 flash-attn),并確保你的模型支持。
5. 分布式訓練策略(多卡或卸載)
  • 數據并行(Data Parallelism):多張GPU,每張存有完整的模型副本,處理不同的數據批次。這是最常見的方式,能增大有效Batch Size,但不減少單卡顯存占用。
  • 張量并行(Tensor Parallelism):將模型層的矩陣運算拆分到多個GPU上。例如,一個大的線性層,將其權重矩陣切分到4張卡上計算。能減少單卡模型權重存儲,但卡間通信開銷大。
  • 流水線并行(Pipeline Parallelism):將模型的不同層放到不同的GPU上。例如,前10層在GPU0,中間10層在GPU1,最后10層在GPU2。能極大減少單卡模型存儲
  • ZeRO(Zero Redundancy Optimizer)
    • 原理:DeepSpeed庫的核心技術。它將優化器狀態、梯度和模型參數在所有GPU間進行分區,而不是每張GPU都保留一份完整副本。需要時通過通信從其他GPU獲取。
    • ZeRO-Stage 1:分區優化器狀態
    • ZeRO-Stage 2:分區優化器狀態 + 梯度
    • ZeRO-Stage 3:分區優化器狀態 + 梯度 + 模型參數
    • 節省效果極其顯著。ZeRO-Stage 3幾乎可以將顯存占用隨GPU數量線性減少。
    • CPU卸載(Offload):ZeRO-Infinity等技術甚至可以將優化器狀態、梯度或模型參數卸載到CPU內存和NVMe硬盤,從而在單張GPU上微調超大模型。代價是通信速度慢。

二、 節約內存(CPU Memory)的策略

  1. 使用迭代式數據加載
    • 不要一次性將整個數據集加載到內存中。使用PyTorch的 DatasetDataLoader,它們會按需從磁盤加載和預處理數據。
  2. 使用高效的數據格式
    • 將數據集保存為parquetarrow(Apache Arrow)或tfrecord等高效二進制格式,而不是jsoncsv文本格式,加載更快,占用內存更小。
  3. 優化數據預處理
    • 使用多進程進行數據預處理(DataLoadernum_workers 參數),讓CPU預處理和GPU計算重疊進行,避免GPU等待CPU,從而間接提升GPU利用率。

實踐路線圖(從易到難)

對于個人開發者或資源有限的團隊,推薦按以下順序嘗試:

  1. 基礎必備三件套

    • 開啟混合精度訓練 (fp16=Truebf16=True)。
    • 使用梯度檢查點 (gradient_checkpointing=True)。
    • 使用內存高效優化器 (如 AdamW8bit)。

    僅這三步,就足以讓微調模型所需顯存減少 50% 或更多

  2. 進階:QLoRA + 上述技巧

    • 如果基礎三件套還不夠,使用 QLoRA
    • 它結合了4bit量化LoRA(低秩適配)分頁優化器等技術,是當前在單卡上微調大模型的首選方案
  3. 高級:分布式訓練框架

    • 如果你擁有多卡服務器,需要全參數微調超大模型,那么需要學習使用 DeepSpeed(配置ZeRO)或 FSDP(Fully Sharded Data Parallel,PyTorch的原生方案,類似ZeRO-3)。

總結對比表

策略主要節省對象節省效果實現難度額外開銷
混合精度 (FP16/BF16)模型權重、梯度顯著(~50%)幾乎無
梯度檢查點 (G-Checkpoint)激活值非常顯著增加計算時間 (~20%)
8-bit 優化器 (e.g., Adam8bit)優化器狀態顯著 (~50%)幾乎無
QLoRA (4bit + LoRA)模型權重、優化器狀態極其顯著輕微性能損失
DeepSpeed ZeRO (Stage 2/3)優化器狀態、梯度、模型參數極其顯著增加通信開銷
減少Batch Size/Seq Length激活值直接但有限可能影響效果
Flash Attention激活值 (Attention)顯著(長序列)

希望這份詳細的總結能幫助你高效地微調大模型!根據你的硬件條件和任務需求,選擇合適的組合策略即可。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/97652.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/97652.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/97652.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux筆記12——shell編程基礎-6

字符截取命令一、cut命令功能:用于從文件或標準輸入中提取指定字段或列語法:cut [選項] 文件名-f:列號,提取第幾列,默認識別制表符分割出來的列(列號之間用,隔開)-d:分隔符&#xff…

高效瀏覽器標簽頁管理:Chrome擴展開發完全指南

Hi,我是前端人類學(之前叫布蘭妮甜)! 在信息過載的時代,瀏覽器標簽頁管理已成為提高工作效率的關鍵技能。本文將介紹如何開發一個功能完整的Chrome擴展,幫助用戶高效管理瀏覽器標簽頁,并探討其實…

從 WPF 到 Avalonia 的遷移系列實戰篇3:ResourceDictionary資源與樣式的差異與遷移技巧

從 WPF 到 Avalonia 的遷移系列實戰篇3:ResourceDictionary資源與樣式的差異與遷移技巧 我的GitHub倉庫Avalonia學習項目包含完整的Avalonia實踐案例與代碼對比。 我的gitcode倉庫是Avalonia學習項目。 文中主要示例代碼均可在倉庫中查看,涵蓋核心功能實現與優化方案…

基于Springboot的音樂媒體播放及周邊產品運營平臺(有報告)。Javaee項目,springboot項目。

演示視頻: 基于Springboot的音樂媒體播放及周邊產品運營平臺(有報告)。Javaee項目,springboot項目。項目介紹: 采用M(model)V(view)C(controller&#xff09…

【項目思維】嵌入式產業鏈與技術生態

這篇文章深入解析嵌入式產業鏈與技術生態上下游關系,輔助建立嵌入式工程師職業發展認知。嵌入式行業并不是“寫單片機程序”那么簡單,而是一個 從芯片設計到系統集成再到最終產品落地 的復雜生態鏈。理解上下游價值鏈,有助于你成為系統型工程…

機器學習(講解)

一、引言:什么是監督學習?監督學習(Supervised Learning)是機器學習中最基礎且應用最廣泛的范式之一。其核心思想是利用已標記的數據(即輸入-輸出對)訓練模型,使其能夠對新的、未標記的數據進行…

使用 Bright Data Web Scraper API + Python 高效抓取 Glassdoor 數據:從配置到結構化輸出全流程實戰

使用 Bright Data Web Scraper API Python 高效抓取 Glassdoor 數據:從配置到結構化輸出全流程實戰 摘要 本文詳細介紹了如何使用 Bright Data 的 Web Scraper API 搭配 Python,實現對 Glassdoor 平臺信息的高效抓取。通過 API 請求構建器、反爬機制集成…

Burgan Bank Türkiye 如何借助 Elastic 改造可觀測性和安全性

作者:來自 Elastic Jon Ashley, Ido Friedman, Burak Dz Burgan Bank Trkiye Burgan Bank K.P.S.C. 是科威特項目公司 (KIPCO) 集團的子公司,成立于 1977 年,是中東和北非 (MENA) 地區最大的控股集團和重要銀行集團之一。 該銀行作為客戶的解…

LeetCode 165. 比較版本號 - 優雅Java解決方案

文章目錄LeetCode 165. 比較版本號 - 優雅Java解決方案題目描述示例分析示例 1示例 2示例 3算法思路Java實現方案方案一:雙指針法(推薦)方案二:優化的單次遍歷法可視化執行過程示例:compareVersion("1.2", &…

基于Kubernetes StatefulSet的有狀態微服務部署與持久化存儲實踐經驗分享

基于Kubernetes StatefulSet的有狀態微服務部署與持久化存儲實踐經驗分享 在傳統微服務架構中,大多數服務都是無狀態的(Stateless),可以通過 Deployment、ReplicaSet 等控制器實現水平自動擴縮容。但在生產環境中,仍有…

MySQL編程開發

變量系統變量:MySQL內置變量#查看所有系統變量show variables \G;#通過模糊查詢篩選變量show variables like “%path%”;全局變量:在所有終端中都生效;會話變量:在當前會話(本次登錄);#可以通過…

20250830_Oracle 19c CDB+PDB(QMS)默認表空間、臨時表空間、歸檔日志、閃回恢復區巡檢手冊

PDB 關業務,CDB 管底層;每天緊盯 PDB,必要時看 CDB。 一、CDB 與 PDB 的關系 Oracle 12c 以后引入 多租戶架構(Multitenant),分成兩類容器: 層級 名稱 作用 存儲內容 典型操作 CDB CDB$ROOT(容器數據庫) 數據庫實例的根容器 Oracle 元數據、系統表字典、公共用戶、PDB…

什么是MIPS架構?RISC-V架構?有什么區別?【超詳細初學者教程】

什么是MIPS架構?RISC-V架構?有什么區別?【超詳細初學者教程】 關鍵詞:MIPS架構,RISC-V架構,精簡指令集RISC,嵌入式系統,CPU架構對比,指令集架構,開源處理器&…

IDEA Spring屬性注解依賴注入的警告 Field injection is not recommended 異常解決方案

一、異常錯誤 在使用 IntelliJ IDEA 進行 Spring 開發時,當使用 Autowired 注解直接在字段上進行依賴注入時,IDE 會顯示黃色警告: Field injection is not recommended這個警告出現在以下代碼模式中: Service public class UserSe…

智能核心:機器人芯片的科技革新與未來挑戰

在人工智能與機器人技術深度融合的今天,機器人芯片作為驅動智能機器的“大腦”,正成為科技競爭的戰略制高點。這一微小卻至關重要的硬件,決定了機器人的計算能力、響應速度與智能水平,是機器人從“自動化”邁向“自主化”的關鍵所…

經典掃雷游戲實現:從零構建HTML5掃雷游戲

一、引言 掃雷是一款經典的單人益智游戲,起源于20世紀60年代,并在90年代隨著Windows操作系統的普及而風靡全球。本文將詳細介紹如何使用現代網頁技術(HTML、CSS和JavaScript)從零開始構建一個功能完整的掃雷游戲。我們將涵蓋游戲邏…

ccache編譯加速配置

ccache 介紹 ccache(“compiler cache”的縮寫)是一個編譯器緩存,該工具會高速緩存編譯生成的信息,并在編譯的特定部分使用高速緩存的信息, 比如頭文件,這樣就節省了通常使用 cpp 解析這些信息所需要的時間。 github :https://github.com/ccache/ccache home:https://c…

數據庫主鍵選擇策略分析

為什么不推薦使用數據庫自增主鍵?分庫分表問題:自增ID在分庫分表場景下會導致ID沖突需要額外機制(如步長設置)來保證全局唯一,增加系統復雜度安全性問題:自增ID容易暴露業務量(如訂單號連續)可能被惡意爬取數據分布式系統限制&…

線性代數理論——狀態空間的相關概念以及由系統的輸入輸出導出狀態空間描述

線性代數理論——狀態空間 狀態:動態系統的狀態就是指系統的過去、現在、將來的運動狀況,精確的說就是狀態需要一組必要而充分的數據來表明。 狀態變量:可以表達系統運動狀態的變量都是狀態變量。 狀態變量組:可以完全表征系統在時…

【GaussDB】排查應用高可用切換出現數據庫整體卡頓及報錯自治事務無法創建的問題

【GaussDB】排查應用高可用切換出現數據庫整體卡頓及報錯自治事務無法創建的問題 背景 某客戶在做應用程序的高可用切換測試,在應用程序中,收到了來自數據庫的報錯,不能創建自治事務 ERROR: autonomous transaction failed to create auton…