资讯详情

资讯详情

告别C盘爆红:Hugging Face缓存清理与迁移全攻略

先把结论放前面C 盘爆红这件事绝大多数时候不是你的手误也不是 Windows 自己“抽风”而是你每次跑训练、跑推理时那些你以为“只在内存里走了一圈”的模型权重其实已经被悄悄写进了用户目录下的缓存文件夹。Hugging Face下文简称 HF生态的缓存机制是我见过最容易让 C 盘悄悄满了的元凶之一。这篇笔记把我自己从“看到 C 盘剩余空间变成个位数”到“清理加迁移一次搞定”的过程完整复盘一下重点围绕 Windows 环境同时照顾到 Linux 上的操作差异希望给同样被磁盘空间折磨的你一条可以直接照做的路线。1. 为什么 C 盘说满就满HF 缓存的“隐形体积”到底藏在哪1.1 .cache 目录结构先搞清哪些东西真正吃空间要安全清理缓存第一步不是急着删而是知道 HF 生态到底往你机器里写了什么。默认情况下使用transformers、datasets、diffusers这类库时下载好的模型、数据集缓存绝大多数都会落到当前用户主目录下的.cache/huggingface文件夹里。在 Windows 上这个路径通常是C:\Users\你的用户名\.cache\huggingface在 Linux / macOS 上则是~/.cache/huggingface这个目录里面你最需要关注的是下面这几类子目录子目录作用吃空间程度hub/存放transformers、diffusers等库下载的模型权重和配置文件是体量最大的“元凶”极高动辄几十 GBdatasets/存放datasets库下载的数据集缓存包括 Arrow 格式的内存映射文件、原始文件中等偏高modules/某些自定义模块的缓存体积通常不大低token/、stored_*等保存登录凭证、API Token 等信息极小但删除后需要重新登录经常有人把.cache/huggingface和 Python 环境里的site-packages混为一谈在这里郑重提醒别搞混了。site-packages里装的是库代码属于 Python 环境的一部分删掉缓存目录不会影响库是否可用只会让模型需要重新下载而删掉site-packages里的依赖包可能会让整个环境崩溃。实际操作中我只清理.cache/huggingface绝不碰环境目录。另外顺带说一句C:\Users\用户名\.cache下面除了 HF 的缓存往往还躺着torch、pip的缓存很多人把 C 盘满的锅全部甩给 HF其实不是所有问题都出在它身上。pip cache purge、torch的hub缓存也需要定期看但本文不展开。1.2 一个模型为什么能占几个 Gsnapshots、blobs、refs 三层结构的真相走进hub目录你会发现里面的文件夹命名很规律大概长这样C:\Users\你的用户名\.cache\huggingface\hub └── models--某个组织--某个模型名在models--组织名--模型名这个目录内部还藏着三个子目录refs、snapshots、blobs。这三者的关系是理解缓存安全清理的核心中的核心。refs目录里保存的是一组“指针”文件。比如refs/main文件内容是一串 commit hash表示“当前模型的主分支指向哪个版本”。snapshots目录按 commit hash 分文件夹里面保存的是模型文件的“目录结构快照”。你可以在这里看到config.json、model.safetensors、tokenizer.json这些熟悉的名字。blobs目录保存的才是模型文件的真实二进制内容文件名是一串原始哈希值没有扩展名。为什么好好的缓存要拆成“快照 原件”两层这是为了让同一个模型的多个不同版本尽量复用同一份底层文件。假设你下载了模型 A 的 main 分支和某个 feature 分支两个版本里只有config.json不同权重文件model.safetensors一样那么blobs里其实只会存一份权重文件两个snapshots目录里的model.safetensors本质上是同一个真实文件的两个“入口”。理解这一点你就明白了两件事直接删整个models--某某模型目录是安全且高效的因为它把三层结构一起端掉。手动去删blobs里的文件风险极高因为你很可能把其他版本还在用的权重文件一起干掉。在 Linux / macOS 上snapshots里的文件通常是符号链接指向blobs里的真实文件。而在 Windows 上情况有点复杂如果系统支持符号链接且权限满足huggingface_hub也会创建链接但如果创建失败它会退化成直接复制文件。这会导致同一个模型在 Windows 上占用翻倍这个问题后面还会单独说。1.3 最容易忽略的“隐形占用”多版本、中断残骸与散落的本地缓存很多人以为“我下载过 3 个模型那缓存里撑死就是这 3 个模型的大小”实际情况远比这个复杂。第一个隐形占用来自“同一模型的多版本下载”。比如为了对比效果下载了某个模型的 fp16 版本和 int8 版本或者同时拉取了 main 分支和某个实验分支在scan-cache输出里会显示为同一个模型拥有多个revision体积自然成倍增加。模型作者更新权重后你重新执行from_pretrainedHF 不会把旧版本自动删掉而是生成一个新的快照旧快照继续留在缓存里。第二个隐形占用来自“中断残骸”。训练脚本在下载到一半时被 CtrlC 终止或者网络突然断开blobs目录里会残留一批.incomplete结尾的临时文件另外网络请求 404 时 HF 会写入一个.no_exist文件记录“这个路径不存在”。这些残骸单个不大但累积起来也很可观。第三个隐形占用来自“代码里写死的cache_dir”。有人会在from_pretrained里直接传cache_dirC:/Users/xxx/.cache/huggingface有人会传D:/tmp_cache导致同一个模型在不同路径下被下载多份。这种散落缓存在scan-cache默认扫描路径里根本看不到排查 C 盘异常增长时最容易漏掉。2. 动手清理前先把“安全边界”划清楚2.1 哪些文件删了没事哪些删了让你白等几小时安全的清理原则不是“有空间就大胆删”而是“先判断缓存是否还被需要”。我自己总结了一张简表分享给你参考类型处理方式理由长期不用的完整模型目录可放心删除再次使用时可重新下载.incomplete临时文件可放心删除下载中断产物不可能被加载snapshots中的旧 revision可放心删除如果不回滚到该版本留着只是占空间当前训练/推理服务正在使用的模型不要删删了会导致运行中任务报错或重启后重新下载多环境共用的模型谨慎另一个环境可能还没缓存完整删除后触发再次下载token目录建议保留删掉后需要重新huggingface-cli login模型目录中所有blobs不建议手动删你无法一眼分辨它是否被多个快照引用拿“正在使用的模型”来说如果某个模型是你前两天刚从 HF Hub 下载、之后每次跑推理都靠它出图或出结果的清理前最好确认没有定时任务、后端服务在持续调用它。我在实际工作中就见过一个定时任务本来只是低频跑一次批处理结果清理缓存后直接把几十 GB 的模型重新下载了一遍白白浪费了时间和流量。2.2 先量化再动手统计每个缓存子目录的真实体积在删任何东西之前第一步永远是“看清楚到底谁在占空间”。HF 官方提供了一个非常实用的命令huggingface-cli scan-cache如果你的环境里没有这个命令多半是huggingface_hub版本太旧升级一下即可pip install -U huggingface_hubscan-cache会把所有缓存条目按模型/数据集列出包括每个条目的磁盘占用、revision 数量、文件数量。但很多时候我们还想知道.cache/huggingface整个目录到底多大以及hub、datasets各自占了多少钱。在 Linux 上很简单du -sh ~/.cache/huggingface du -sh ~/.cache/huggingface/*在 Windows 上PowerShell 自带命令也可以统计但文件数量多时非常慢Get-ChildItem $env:USERPROFILE\.cache\huggingface -Recurse -File | Measure-Object -Property Length -Sum如果缓存目录里文件数量达到几万甚至几十万上面的 PowerShell 命令会卡到怀疑人生。我在 Windows 上更推荐用磁盘占用分析工具比如 WizTree 这类基于 NTFS 索引扫描的软件快速定位或者用 Git Bash 里自带的du命令。总之心里先有个账本再动手。2.3 Windows 与 Linux 的差异硬链接、长路径、权限带来的三个坑同样的操作在 Linux 上很顺利到了 Windows 上却可能踩出一片坑清理缓存时尤其明显。第一个坑是“符号链接权限”。前面提到过HF 在下载模型后会在snapshots里创建指向blobs的符号链接。Windows 默认对普通用户创建符号链接有较高要求如果huggingface_hub创建链接失败它会退化成复制文件。同一个模型在别人机器上是 10 GB在你机器上可能占 20 GB。如果你发现自己机器上 HF 缓存特别“肥大”不妨检查一下 Windows 开发者模式是否开启以及当前用户是否有创建符号链接的权限。第二个坑是“长路径”。HF 模型的缓存目录层级深加上模型名、commit hash、文件名之后很容易突破 Windows 传统路径 260 字符的限制导致删除时报错“指定路径的文件名太长”。直接Remove-Item往往会卡死在某个子文件上删一半停一半非常头疼。第三个坑是“杀毒软件和索引服务”。缓存目录里有海量小文件Windows Defender 每次访问都会扫一遍Windows Search 索引也会尝试建立文件索引导致删除操作慢到离谱CPU 占用还特别高。后面讲清理步骤时我会给一个在 Windows 上更快更稳的删除方案。3. 实战清理给 C 盘“瘦身”的四条路径3.1 工具链第一步用 scan-cache 给缓存做一次“体检”先跑一条命令看看缓存现状huggingface-cli scan-cache输出内容大致如下我用自己的缓存做了一个简化的示意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只看列表还不过瘾我经常用 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 拆分它也会按总体积汇总不至于被表面现象骗到。跑完这一步你已经知道该清理谁的缓存了。3.2 精准删除交互式 delete-cache 配合手动清理s huginface-cli提供了官方清理工具可以直接使用huggingface-cli delete-cache执行后会进入交互式界面通过方向键选择要删除的缓存条目选中后回车确认。delete-cache的好处是它会自己处理三层结构的关系并且能判断某个 blob 是否仍被其他 revision 引用基本不存在签错文件的风险。如果你觉得交互式界面麻烦也可以直接指定模型目录进行删除。我个人的习惯是对于已经确认不用的模型直接删掉整个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 缓存整体迁移到其他分区的完整方案清理只能止血迁移才是根治。如果你有一块数据盘比如 D 盘或 E 盘强烈建议把 HF 缓存整个迁过去。这一步做完之后新下载的模型再也不会碰系统盘。具体操作分三步走第一步创建目标目录比如D:\HF_Cache\huggingface。第二步设置用户级环境变量HF_HOME。推荐用 PowerShell 执行[Environment]::SetEnvironmentVariable(HF_HOME, D:\HF_Cache\huggingface, User)这是“永久生效”级的设置设置完需要关闭并重新打开终端、IDE确保新进程能读到新变量。当然也可以只设置更细粒度的变量例如HF_HUB_CACHED:\HF_Cache\hub HF_DATASETS_CACHED:\HF_Cache\datasets TRANSFORMERS_CACHED:\HF_Cache\transformers但如果设置了HF_HOME上面这些细分变量通常就不需要单独设置了。注意变量设置必须发生在任何 HF 相关库被 import 之前这一点写代码时尤其重要。第三步把旧缓存复制到新目录。Windows 下建议用robocopy比文件资源管理器右键复制稳定得多而且支持断点续传robocopy C:\Users\你的用户名\.cache\huggingface D:\HF_Cache\huggingface /E /COPY:DAT /R:3 /W:5 /XJ参数说明/E复制所有子目录包含空目录/COPY:DAT复制数据、属性、时间戳/R:3 /W:5表示单个文件失败重试 3 次、每次等 5 秒/XJ排除目录联接Junction避免复制过程中被链接对象干扰。复制完成后建议先重启终端然后随便加载一个之前用过的模型确认它能直接命中新路径下的缓存速度飞快。确认无误后再删除旧目录Remove-Item C:\Users\你的用户名\.cache\huggingface -Recurse -Force这里最关键的原则是先验证再删除。千万不要反着来不要先删后迁。3.4 代码层面的兜底加载时指定缓存目录拒绝默认路径如果你不想设置全局环境变量或者你的项目需要在不同机器间切换路径还有更可控的方式在代码里显式指定缓存目录。最朴素的做法是每次加载模型时传入cache_dir参数from transformers import AutoModel, AutoTokenizer model AutoModel.from_pretrained( 某个组织/某个模型名, cache_dirD:/HF_Cache/hub, )但这种方法有个问题如果多个脚本都忘了传cache_dir模型又会回到默认缓存路径。所以我更推荐在项目入口文件的顶部趁早设置环境变量import os os.environ[HF_HOME] D:/HF_Cache/huggingface # 注意这行必须放在任何 huggingface 库 import 之前 from transformers import AutoModel如果项目里用了python-dotenv管理环境变量也要记得在 import 任何 HF 相关库之前执行load_dotenv()否则环境变量生效时间可能晚于库的初始化时机导致缓存路径又回到默认值。不管是环境变量还是cache_dir改动之后都要检查两件事新路径下是否有对应的目录生成旧的默认路径是否还在持续增长。我曾经改完环境变量后以为万事大吉结果发现某个脚本里写死了默认缓存路径模型依然往 C 盘一路狂奔。4. 我踩过的几个坑清理一时爽重跑两行泪4.1 大坑一直接删 cache 目录几十 GB 模型排队重新下载有段时间 C 盘告急我图省事直接用 PowerShell 把整个.cache/huggingface目录删掉了。当时想的是“反正没在训练删了以后再下载就行了多大点事”。结果下一次启动推理服务时因为本地缓存已经完全不存在代码自动向远端发起全量下载一个 7B 模型加上依赖文件硬生生把整盘数据重新拉了一遍。那段时间本来就是因为磁盘空间告急才清理结果网络流量又爆炸了非常尴尬。后来我学乖了删除前先scan-cache留档确认哪些模型近期还在被使用删除时尽量用目录级别操作不要一删删全家如果是正在跑的服务在用还需要先停服务再清理。4.2 大坑二只删 blobs 不删 snapshots空间没释放干净有一次我觉得blobs目录下全是无扩展名的“垃圾文件”顺手把里面看起来很大的文件删了一批。结果空间确实释放了不少但问题也随之而来snapshots目录里的链接文件依然指向那些已经被删除的blobs文件导致加载模型时报“文件不存在”。HF 检查到缓存不完整又不知道应该重新下载哪个文件表现非常诡异。这里要记住一个底层逻辑blobs里的文件可能是“多对一引用”的也就是多个snapshots文件同时指向同一个blobs文件。你删它的时候认为它没用实际上别的版本还在依赖它。这也是为什么 HF 推荐大家用交互式删除工具而不要手动去清理底层文件。如果你已经手删了补救方案只有一个把对应模型整个缓存目录删掉让它重新下载。4.3 大坑三环境变量迁移后旧路径还在继续涨我以为设置了HF_HOME后所有新下载都会自动去新目录结果发现 C 盘还是在悄悄变满。排查了一圈发现是下面这几个原因叠加的结果某个脚本里写了硬编码cache_dir它指向的还是旧路径某个 Jupyter Notebook 内核在设置环境变量之前就已经启动老内核进程里的环境变量根本没更新datasets库有时仍会读取旧的 datasets 缓存环境变量跟HF_HOME的联动依赖版本。排查方法其实很简单开一个新的终端运行一行 Python 确认路径取自哪里from huggingface_hub.constants import HF_HUB_CACHE print(HF_HUB_CACHE)如果输出还是旧的 C 盘路径说明环境变量没有在正确层级设置或者有别的项目代码覆盖了环境变量。之后再全局搜一下项目代码里有没有cache_dir这些硬编码能统一改环境变量就尽量统一。4.4 大坑四Windows 长路径和杀毒扫描让删除过程卡到崩溃Windows 上删除大规模 HF 缓存时我遇到的最大敌人不是磁盘空间而是删除速度。一秒几个文件一万个文件就要跑半天中途还经常因为路径过长报错。后来我学到一个很实用的招用robocopy镜像一个空目录反向清空目标目录。操作思路是先创建一个空目录然后运行robocopy D:\Empty_Dir C:\Users\你的用户名\.cache\huggingface /MIR/MIR会把目标目录镜像成和源目录一致由于源目录为空目标目录里所有多余文件和子目录都会被清除。相比Remove-Item这种方式对长路径的容忍度更高过程更稳定是我在 Windows 上清理超大目录的首选方案。同时把 HF 缓存目录临时加入 Windows Defender 的排除项可以在清理时显著提升速度。不排除的话每一个小文件被删除前都要过一遍查杀浪费时间不说还容易让 CPU 飙到 100%。5. 从源头减轻 C 盘负担缓存上限、按需下载与例行检查5.1 控制缓存总量别让“反正有缓存”变成“缓存无限膨胀”HF 早期版本的下载逻辑是“有多少拉多少”目录里几乎没有自动淘汰机制。所以仅仅清理一次还不够要建立一个长期的“总量控制”意识。一种做法是合理利用环境变量限制缓存规模。较新版本的huggingface_hub已开始支持类似缓存配额的限制方式如果你愿意折腾可以在配置层面设置一个合理额度例如 20 GB 或 30 GB超过阈值后由库自行淘汰最久未使用的部分。如果配置没生效也没有关系手动定期执行scan-cache也足够发现问题。另一种做法是在加载模型时使用local_files_onlyTrue强制使用本地缓存不自动联网检查远端是否有新版本。我测试过这个参数不仅避免无谓的网络请求还能防止因为你换了一台机器、换了一个版本号导致已经存在的缓存被重复下载。5.2 按需下载有些文件真的没必要全部拉回来大模型的仓库里往往同时存在pytorch_model.bin、model.safetensors、onnx格式、gguf量化文件等相同权重的不同打包形态。如果你只是用 PyTorch 做推理下载全套文件就是在浪费空间。使用snapshot_download时可以通过allow_patterns精确指定要下载的文件类型。例如from huggingface_hub import snapshot_download snapshot_download( 某个组织/某个模型名, allow_patterns[*.json, *.safetensors, tokenizer*], )这样至少能过滤掉大量重复格式的权重文件。如果你平时只跑 CPU 推理甚至可以再精筛只保留 int8 或 int4 的量化模型文件省下来的空间相当可观。如果你所在的是离线环境或者网络不稳定记得把HF_HUB_OFFLINE环境变量设成1让所有加载操作都走本地缓存避免意外联网触发下载。5.3 每周 5 分钟的例行检查清单C 盘爆红不是偶发事件而是一点点累积出来的结果。我现在基本每周会花几分钟做一次例行检查顺手分享给你这套检查清单跑一次huggingface-cli scan-cache重点看占用最大的前 5 条检查HF_HOME环境变量是否指向数据盘防止某次环境初始化后悄悄漂移回默认路径用以下 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) }如果你的环境是多个 Conda 环境共享同一个 HF 缓存这条检查就更有必要因为你无法保证每个环境都用了同一个HF_HOME。说到底把 C 盘从“爆红”边缘救回来不是一次大扫除就能一劳永逸的。关键是理解 HF 缓存的组织方式掌握安全清理的工具然后顺手把默认路径迁到数据盘。我现在的习惯已经变成每次搭新环境第一件事就是把HF_HOME指到非系统盘每周末扫一眼缓存清单但凡看到某个模型目录体积异常就先用scan-cache认个脸再决定删不删。这套流程跑下来C 盘基本处于稳定可控的状态再也没被“神秘失踪的剩余空间”搞得半夜加班。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →