
先把結(jié)論放前面C 盤爆紅這件事絕大多數(shù)時候不是你的手誤也不是 Windows 自己“抽風”而是你每次跑訓(xùn)練、跑推理時那些你以為“只在內(nèi)存里走了一圈”的模型權(quán)重其實已經(jīng)被悄悄寫進了用戶目錄下的緩存文件夾。Hugging Face下文簡稱 HF生態(tài)的緩存機制是我見過最容易讓 C 盤悄悄滿了的元兇之一。這篇筆記把我自己從“看到 C 盤剩余空間變成個位數(shù)”到“清理加遷移一次搞定”的過程完整復(fù)盤一下重點圍繞 Windows 環(huán)境同時照顧到 Linux 上的操作差異希望給同樣被磁盤空間折磨的你一條可以直接照做的路線。1. 為什么 C 盤說滿就滿HF 緩存的“隱形體積”到底藏在哪1.1 .cache 目錄結(jié)構(gòu)先搞清哪些東西真正吃空間要安全清理緩存第一步不是急著刪而是知道 HF 生態(tài)到底往你機器里寫了什么。默認情況下使用transformers、datasets、diffusers這類庫時下載好的模型、數(shù)據(jù)集緩存絕大多數(shù)都會落到當前用戶主目錄下的.cache/huggingface文件夾里。在 Windows 上這個路徑通常是C:\Users\你的用戶名\.cache\huggingface在 Linux / macOS 上則是~/.cache/huggingface這個目錄里面你最需要關(guān)注的是下面這幾類子目錄子目錄作用吃空間程度hub/存放transformers、diffusers等庫下載的模型權(quán)重和配置文件是體量最大的“元兇”極高動輒幾十 GBdatasets/存放datasets庫下載的數(shù)據(jù)集緩存包括 Arrow 格式的內(nèi)存映射文件、原始文件中等偏高modules/某些自定義模塊的緩存體積通常不大低token/、stored_*等保存登錄憑證、API Token 等信息極小但刪除后需要重新登錄經(jīng)常有人把.cache/huggingface和 Python 環(huán)境里的site-packages混為一談在這里鄭重提醒別搞混了。site-packages里裝的是庫代碼屬于 Python 環(huán)境的一部分刪掉緩存目錄不會影響庫是否可用只會讓模型需要重新下載而刪掉site-packages里的依賴包可能會讓整個環(huán)境崩潰。實際操作中我只清理.cache/huggingface絕不碰環(huán)境目錄。另外順帶說一句C:\Users\用戶名\.cache下面除了 HF 的緩存往往還躺著torch、pip的緩存很多人把 C 盤滿的鍋全部甩給 HF其實不是所有問題都出在它身上。pip cache purge、torch的hub緩存也需要定期看但本文不展開。1.2 一個模型為什么能占幾個 Gsnapshots、blobs、refs 三層結(jié)構(gòu)的真相走進hub目錄你會發(fā)現(xiàn)里面的文件夾命名很規(guī)律大概長這樣C:\Users\你的用戶名\.cache\huggingface\hub └── models--某個組織--某個模型名在models--組織名--模型名這個目錄內(nèi)部還藏著三個子目錄refs、snapshots、blobs。這三者的關(guān)系是理解緩存安全清理的核心中的核心。refs目錄里保存的是一組“指針”文件。比如refs/main文件內(nèi)容是一串 commit hash表示“當前模型的主分支指向哪個版本”。snapshots目錄按 commit hash 分文件夾里面保存的是模型文件的“目錄結(jié)構(gòu)快照”。你可以在這里看到config.json、model.safetensors、tokenizer.json這些熟悉的名字。blobs目錄保存的才是模型文件的真實二進制內(nèi)容文件名是一串原始哈希值沒有擴展名。為什么好好的緩存要拆成“快照 原件”兩層這是為了讓同一個模型的多個不同版本盡量復(fù)用同一份底層文件。假設(shè)你下載了模型 A 的 main 分支和某個 feature 分支兩個版本里只有config.json不同權(quán)重文件model.safetensors一樣那么blobs里其實只會存一份權(quán)重文件兩個snapshots目錄里的model.safetensors本質(zhì)上是同一個真實文件的兩個“入口”。理解這一點你就明白了兩件事直接刪整個models--某某模型目錄是安全且高效的因為它把三層結(jié)構(gòu)一起端掉。手動去刪blobs里的文件風險極高因為你很可能把其他版本還在用的權(quán)重文件一起干掉。在 Linux / macOS 上snapshots里的文件通常是符號鏈接指向blobs里的真實文件。而在 Windows 上情況有點復(fù)雜如果系統(tǒng)支持符號鏈接且權(quán)限滿足huggingface_hub也會創(chuàng)建鏈接但如果創(chuàng)建失敗它會退化成直接復(fù)制文件。這會導(dǎo)致同一個模型在 Windows 上占用翻倍這個問題后面還會單獨說。1.3 最容易忽略的“隱形占用”多版本、中斷殘骸與散落的本地緩存很多人以為“我下載過 3 個模型那緩存里撐死就是這 3 個模型的大小”實際情況遠比這個復(fù)雜。第一個隱形占用來自“同一模型的多版本下載”。比如為了對比效果下載了某個模型的 fp16 版本和 int8 版本或者同時拉取了 main 分支和某個實驗分支在scan-cache輸出里會顯示為同一個模型擁有多個revision體積自然成倍增加。模型作者更新權(quán)重后你重新執(zhí)行from_pretrainedHF 不會把舊版本自動刪掉而是生成一個新的快照舊快照繼續(xù)留在緩存里。第二個隱形占用來自“中斷殘骸”。訓(xùn)練腳本在下載到一半時被 CtrlC 終止或者網(wǎng)絡(luò)突然斷開blobs目錄里會殘留一批.incomplete結(jié)尾的臨時文件另外網(wǎng)絡(luò)請求 404 時 HF 會寫入一個.no_exist文件記錄“這個路徑不存在”。這些殘骸單個不大但累積起來也很可觀。第三個隱形占用來自“代碼里寫死的cache_dir”。有人會在from_pretrained里直接傳cache_dirC:/Users/xxx/.cache/huggingface有人會傳D:/tmp_cache導(dǎo)致同一個模型在不同路徑下被下載多份。這種散落緩存在scan-cache默認掃描路徑里根本看不到排查 C 盤異常增長時最容易漏掉。2. 動手清理前先把“安全邊界”劃清楚2.1 哪些文件刪了沒事哪些刪了讓你白等幾小時安全的清理原則不是“有空間就大膽刪”而是“先判斷緩存是否還被需要”。我自己總結(jié)了一張簡表分享給你參考類型處理方式理由長期不用的完整模型目錄可放心刪除再次使用時可重新下載.incomplete臨時文件可放心刪除下載中斷產(chǎn)物不可能被加載snapshots中的舊 revision可放心刪除如果不回滾到該版本留著只是占空間當前訓(xùn)練/推理服務(wù)正在使用的模型不要刪刪了會導(dǎo)致運行中任務(wù)報錯或重啟后重新下載多環(huán)境共用的模型謹慎另一個環(huán)境可能還沒緩存完整刪除后觸發(fā)再次下載token目錄建議保留刪掉后需要重新huggingface-cli login模型目錄中所有blobs不建議手動刪你無法一眼分辨它是否被多個快照引用拿“正在使用的模型”來說如果某個模型是你前兩天剛從 HF Hub 下載、之后每次跑推理都靠它出圖或出結(jié)果的清理前最好確認沒有定時任務(wù)、后端服務(wù)在持續(xù)調(diào)用它。我在實際工作中就見過一個定時任務(wù)本來只是低頻跑一次批處理結(jié)果清理緩存后直接把幾十 GB 的模型重新下載了一遍白白浪費了時間和流量。2.2 先量化再動手統(tǒng)計每個緩存子目錄的真實體積在刪任何東西之前第一步永遠是“看清楚到底誰在占空間”。HF 官方提供了一個非常實用的命令huggingface-cli scan-cache如果你的環(huán)境里沒有這個命令多半是huggingface_hub版本太舊升級一下即可pip install -U huggingface_hubscan-cache會把所有緩存條目按模型/數(shù)據(jù)集列出包括每個條目的磁盤占用、revision 數(shù)量、文件數(shù)量。但很多時候我們還想知道.cache/huggingface整個目錄到底多大以及hub、datasets各自占了多少錢。在 Linux 上很簡單du -sh ~/.cache/huggingface du -sh ~/.cache/huggingface/*在 Windows 上PowerShell 自帶命令也可以統(tǒng)計但文件數(shù)量多時非常慢Get-ChildItem $env:USERPROFILE\.cache\huggingface -Recurse -File | Measure-Object -Property Length -Sum如果緩存目錄里文件數(shù)量達到幾萬甚至幾十萬上面的 PowerShell 命令會卡到懷疑人生。我在 Windows 上更推薦用磁盤占用分析工具比如 WizTree 這類基于 NTFS 索引掃描的軟件快速定位或者用 Git Bash 里自帶的du命令。總之心里先有個賬本再動手。2.3 Windows 與 Linux 的差異硬鏈接、長路徑、權(quán)限帶來的三個坑同樣的操作在 Linux 上很順利到了 Windows 上卻可能踩出一片坑清理緩存時尤其明顯。第一個坑是“符號鏈接權(quán)限”。前面提到過HF 在下載模型后會在snapshots里創(chuàng)建指向blobs的符號鏈接。Windows 默認對普通用戶創(chuàng)建符號鏈接有較高要求如果huggingface_hub創(chuàng)建鏈接失敗它會退化成復(fù)制文件。同一個模型在別人機器上是 10 GB在你機器上可能占 20 GB。如果你發(fā)現(xiàn)自己機器上 HF 緩存特別“肥大”不妨檢查一下 Windows 開發(fā)者模式是否開啟以及當前用戶是否有創(chuàng)建符號鏈接的權(quán)限。第二個坑是“長路徑”。HF 模型的緩存目錄層級深加上模型名、commit hash、文件名之后很容易突破 Windows 傳統(tǒng)路徑 260 字符的限制導(dǎo)致刪除時報錯“指定路徑的文件名太長”。直接Remove-Item往往會卡死在某個子文件上刪一半停一半非常頭疼。第三個坑是“殺毒軟件和索引服務(wù)”。緩存目錄里有海量小文件Windows Defender 每次訪問都會掃一遍Windows Search 索引也會嘗試建立文件索引導(dǎo)致刪除操作慢到離譜CPU 占用還特別高。后面講清理步驟時我會給一個在 Windows 上更快更穩(wěn)的刪除方案。3. 實戰(zhàn)清理給 C 盤“瘦身”的四條路徑3.1 工具鏈第一步用 scan-cache 給緩存做一次“體檢”先跑一條命令看看緩存現(xiàn)狀huggingface-cli scan-cache輸出內(nèi)容大致如下我用自己的緩存做了一個簡化的示意REPO ID SIZE #FILES #REVISIONS some-org/some-model 12.3 GB 45 3 another-org/text-model 5.2 GB 8 2 datasets/some-dataset 3.1 GB 12 1只看列表還不過癮我經(jīng)常用 Python 再寫一個小腳本按占用大小排序輸出前 10 條這樣誰是大戶一目了然from huggingface_hub import scan_cache_dir cache_info scan_cache_dir() entries sorted( cache_info.repos, keylambda x: x.size_on_disk, reverseTrue, ) for entry in entries[:10]: print(f{entry.repo_id:60s} {entry.size_on_disk / 1024**3:8.2f} GB)這個腳本的好處是即使某個模型被多個 revision 拆分它也會按總體積匯總不至于被表面現(xiàn)象騙到。跑完這一步你已經(jīng)知道該清理誰的緩存了。3.2 精準刪除交互式 delete-cache 配合手動清理s huginface-cli提供了官方清理工具可以直接使用huggingface-cli delete-cache執(zhí)行后會進入交互式界面通過方向鍵選擇要刪除的緩存條目選中后回車確認。delete-cache的好處是它會自己處理三層結(jié)構(gòu)的關(guān)系并且能判斷某個 blob 是否仍被其他 revision 引用基本不存在簽錯文件的風險。如果你覺得交互式界面麻煩也可以直接指定模型目錄進行刪除。我個人的習慣是對于已經(jīng)確認不用的模型直接刪掉整個models--組織名--模型名目錄。例如Remove-Item C:\Users\你的用戶名\.cache\huggingface\hub\models--某個組織--某個模型名 -Recurse -Force但如果你擔心誤刪建議先把scan-cache的輸出存一份作為備份記錄例如huggingface-cli scan-cache hf-cache-manifest-2024-xx-xx.txt這樣即使刪錯了至少知道這個模型來自哪個倉庫、包含哪些文件重新下載時心里有底。3.3 徹底搬走把 HF 緩存整體遷移到其他分區(qū)的完整方案清理只能止血遷移才是根治。如果你有一塊數(shù)據(jù)盤比如 D 盤或 E 盤強烈建議把 HF 緩存整個遷過去。這一步做完之后新下載的模型再也不會碰系統(tǒng)盤。具體操作分三步走第一步創(chuàng)建目標目錄比如D:\HF_Cache\huggingface。第二步設(shè)置用戶級環(huán)境變量HF_HOME。推薦用 PowerShell 執(zhí)行[Environment]::SetEnvironmentVariable(HF_HOME, D:\HF_Cache\huggingface, User)這是“永久生效”級的設(shè)置設(shè)置完需要關(guān)閉并重新打開終端、IDE確保新進程能讀到新變量。當然也可以只設(shè)置更細粒度的變量例如HF_HUB_CACHED:\HF_Cache\hub HF_DATASETS_CACHED:\HF_Cache\datasets TRANSFORMERS_CACHED:\HF_Cache\transformers但如果設(shè)置了HF_HOME上面這些細分變量通常就不需要單獨設(shè)置了。注意變量設(shè)置必須發(fā)生在任何 HF 相關(guān)庫被 import 之前這一點寫代碼時尤其重要。第三步把舊緩存復(fù)制到新目錄。Windows 下建議用robocopy比文件資源管理器右鍵復(fù)制穩(wěn)定得多而且支持斷點續(xù)傳robocopy C:\Users\你的用戶名\.cache\huggingface D:\HF_Cache\huggingface /E /COPY:DAT /R:3 /W:5 /XJ參數(shù)說明/E復(fù)制所有子目錄包含空目錄/COPY:DAT復(fù)制數(shù)據(jù)、屬性、時間戳/R:3 /W:5表示單個文件失敗重試 3 次、每次等 5 秒/XJ排除目錄聯(lián)接Junction避免復(fù)制過程中被鏈接對象干擾。復(fù)制完成后建議先重啟終端然后隨便加載一個之前用過的模型確認它能直接命中新路徑下的緩存速度飛快。確認無誤后再刪除舊目錄Remove-Item C:\Users\你的用戶名\.cache\huggingface -Recurse -Force這里最關(guān)鍵的原則是先驗證再刪除。千萬不要反著來不要先刪后遷。3.4 代碼層面的兜底加載時指定緩存目錄拒絕默認路徑如果你不想設(shè)置全局環(huán)境變量或者你的項目需要在不同機器間切換路徑還有更可控的方式在代碼里顯式指定緩存目錄。最樸素的做法是每次加載模型時傳入cache_dir參數(shù)from transformers import AutoModel, AutoTokenizer model AutoModel.from_pretrained( 某個組織/某個模型名, cache_dirD:/HF_Cache/hub, )但這種方法有個問題如果多個腳本都忘了傳cache_dir模型又會回到默認緩存路徑。所以我更推薦在項目入口文件的頂部趁早設(shè)置環(huán)境變量import os os.environ[HF_HOME] D:/HF_Cache/huggingface # 注意這行必須放在任何 huggingface 庫 import 之前 from transformers import AutoModel如果項目里用了python-dotenv管理環(huán)境變量也要記得在 import 任何 HF 相關(guān)庫之前執(zhí)行l(wèi)oad_dotenv()否則環(huán)境變量生效時間可能晚于庫的初始化時機導(dǎo)致緩存路徑又回到默認值。不管是環(huán)境變量還是cache_dir改動之后都要檢查兩件事新路徑下是否有對應(yīng)的目錄生成舊的默認路徑是否還在持續(xù)增長。我曾經(jīng)改完環(huán)境變量后以為萬事大吉結(jié)果發(fā)現(xiàn)某個腳本里寫死了默認緩存路徑模型依然往 C 盤一路狂奔。4. 我踩過的幾個坑清理一時爽重跑兩行淚4.1 大坑一直接刪 cache 目錄幾十 GB 模型排隊重新下載有段時間 C 盤告急我圖省事直接用 PowerShell 把整個.cache/huggingface目錄刪掉了。當時想的是“反正沒在訓(xùn)練刪了以后再下載就行了多大點事”。結(jié)果下一次啟動推理服務(wù)時因為本地緩存已經(jīng)完全不存在代碼自動向遠端發(fā)起全量下載一個 7B 模型加上依賴文件硬生生把整盤數(shù)據(jù)重新拉了一遍。那段時間本來就是因為磁盤空間告急才清理結(jié)果網(wǎng)絡(luò)流量又爆炸了非常尷尬。后來我學乖了刪除前先scan-cache留檔確認哪些模型近期還在被使用刪除時盡量用目錄級別操作不要一刪刪全家如果是正在跑的服務(wù)在用還需要先停服務(wù)再清理。4.2 大坑二只刪 blobs 不刪 snapshots空間沒釋放干凈有一次我覺得blobs目錄下全是無擴展名的“垃圾文件”順手把里面看起來很大的文件刪了一批。結(jié)果空間確實釋放了不少但問題也隨之而來snapshots目錄里的鏈接文件依然指向那些已經(jīng)被刪除的blobs文件導(dǎo)致加載模型時報“文件不存在”。HF 檢查到緩存不完整又不知道應(yīng)該重新下載哪個文件表現(xiàn)非常詭異。這里要記住一個底層邏輯blobs里的文件可能是“多對一引用”的也就是多個snapshots文件同時指向同一個blobs文件。你刪它的時候認為它沒用實際上別的版本還在依賴它。這也是為什么 HF 推薦大家用交互式刪除工具而不要手動去清理底層文件。如果你已經(jīng)手刪了補救方案只有一個把對應(yīng)模型整個緩存目錄刪掉讓它重新下載。4.3 大坑三環(huán)境變量遷移后舊路徑還在繼續(xù)漲我以為設(shè)置了HF_HOME后所有新下載都會自動去新目錄結(jié)果發(fā)現(xiàn) C 盤還是在悄悄變滿。排查了一圈發(fā)現(xiàn)是下面這幾個原因疊加的結(jié)果某個腳本里寫了硬編碼cache_dir它指向的還是舊路徑某個 Jupyter Notebook 內(nèi)核在設(shè)置環(huán)境變量之前就已經(jīng)啟動老內(nèi)核進程里的環(huán)境變量根本沒更新datasets庫有時仍會讀取舊的 datasets 緩存環(huán)境變量跟HF_HOME的聯(lián)動依賴版本。排查方法其實很簡單開一個新的終端運行一行 Python 確認路徑取自哪里from huggingface_hub.constants import HF_HUB_CACHE print(HF_HUB_CACHE)如果輸出還是舊的 C 盤路徑說明環(huán)境變量沒有在正確層級設(shè)置或者有別的項目代碼覆蓋了環(huán)境變量。之后再全局搜一下項目代碼里有沒有cache_dir這些硬編碼能統(tǒng)一改環(huán)境變量就盡量統(tǒng)一。4.4 大坑四Windows 長路徑和殺毒掃描讓刪除過程卡到崩潰Windows 上刪除大規(guī)模 HF 緩存時我遇到的最大敵人不是磁盤空間而是刪除速度。一秒幾個文件一萬個文件就要跑半天中途還經(jīng)常因為路徑過長報錯。后來我學到一個很實用的招用robocopy鏡像一個空目錄反向清空目標目錄。操作思路是先創(chuàng)建一個空目錄然后運行robocopy D:\Empty_Dir C:\Users\你的用戶名\.cache\huggingface /MIR/MIR會把目標目錄鏡像成和源目錄一致由于源目錄為空目標目錄里所有多余文件和子目錄都會被清除。相比Remove-Item這種方式對長路徑的容忍度更高過程更穩(wěn)定是我在 Windows 上清理超大目錄的首選方案。同時把 HF 緩存目錄臨時加入 Windows Defender 的排除項可以在清理時顯著提升速度。不排除的話每一個小文件被刪除前都要過一遍查殺浪費時間不說還容易讓 CPU 飆到 100%。5. 從源頭減輕 C 盤負擔緩存上限、按需下載與例行檢查5.1 控制緩存總量別讓“反正有緩存”變成“緩存無限膨脹”HF 早期版本的下載邏輯是“有多少拉多少”目錄里幾乎沒有自動淘汰機制。所以僅僅清理一次還不夠要建立一個長期的“總量控制”意識。一種做法是合理利用環(huán)境變量限制緩存規(guī)模。較新版本的huggingface_hub已開始支持類似緩存配額的限制方式如果你愿意折騰可以在配置層面設(shè)置一個合理額度例如 20 GB 或 30 GB超過閾值后由庫自行淘汰最久未使用的部分。如果配置沒生效也沒有關(guān)系手動定期執(zhí)行scan-cache也足夠發(fā)現(xiàn)問題。另一種做法是在加載模型時使用local_files_onlyTrue強制使用本地緩存不自動聯(lián)網(wǎng)檢查遠端是否有新版本。我測試過這個參數(shù)不僅避免無謂的網(wǎng)絡(luò)請求還能防止因為你換了一臺機器、換了一個版本號導(dǎo)致已經(jīng)存在的緩存被重復(fù)下載。5.2 按需下載有些文件真的沒必要全部拉回來大模型的倉庫里往往同時存在pytorch_model.bin、model.safetensors、onnx格式、gguf量化文件等相同權(quán)重的不同打包形態(tài)。如果你只是用 PyTorch 做推理下載全套文件就是在浪費空間。使用snapshot_download時可以通過allow_patterns精確指定要下載的文件類型。例如from huggingface_hub import snapshot_download snapshot_download( 某個組織/某個模型名, allow_patterns[*.json, *.safetensors, tokenizer*], )這樣至少能過濾掉大量重復(fù)格式的權(quán)重文件。如果你平時只跑 CPU 推理甚至可以再精篩只保留 int8 或 int4 的量化模型文件省下來的空間相當可觀。如果你所在的是離線環(huán)境或者網(wǎng)絡(luò)不穩(wěn)定記得把HF_HUB_OFFLINE環(huán)境變量設(shè)成1讓所有加載操作都走本地緩存避免意外聯(lián)網(wǎng)觸發(fā)下載。5.3 每周 5 分鐘的例行檢查清單C 盤爆紅不是偶發(fā)事件而是一點點累積出來的結(jié)果。我現(xiàn)在基本每周會花幾分鐘做一次例行檢查順手分享給你這套檢查清單跑一次huggingface-cli scan-cache重點看占用最大的前 5 條檢查HF_HOME環(huán)境變量是否指向數(shù)據(jù)盤防止某次環(huán)境初始化后悄悄漂移回默認路徑用以下 PowerShell 腳本快速查看緩存總大小$cache $env:USERPROFILE\.cache\huggingface if (Test-Path $cache) { $size (Get-ChildItem $cache -Recurse -File -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum HF cache size: {0:N2} GB -f ($size / 1GB) }如果你的環(huán)境是多個 Conda 環(huán)境共享同一個 HF 緩存這條檢查就更有必要因為你無法保證每個環(huán)境都用了同一個HF_HOME。說到底把 C 盤從“爆紅”邊緣救回來不是一次大掃除就能一勞永逸的。關(guān)鍵是理解 HF 緩存的組織方式掌握安全清理的工具然后順手把默認路徑遷到數(shù)據(jù)盤。我現(xiàn)在的習慣已經(jīng)變成每次搭新環(huán)境第一件事就是把HF_HOME指到非系統(tǒng)盤每周末掃一眼緩存清單但凡看到某個模型目錄體積異常就先用scan-cache認個臉再決定刪不刪。這套流程跑下來C 盤基本處于穩(wěn)定可控的狀態(tài)再也沒被“神秘失蹤的剩余空間”搞得半夜加班。