C 盘又飘红了。这种情况我经历过很多次,每次都想不通几十个 G 到底去了哪,查到最后十有八九是 Hugging Face 的缓存。玩本地模型的人应该都懂,transformers、diffusers 这些库每次加载模型都会往~/.cache/huggingface里塞东西,一个模型几个 G 起步,多试几个模型,C 盘直接报警。这篇文章就是一份完整的实战笔记,把安全清理 Hugging Face 缓存的原理、操作步骤和避坑点都讲清楚,适合所有本地跑模型、经常使用 AI 开源模型的读者参考。
我前前后后折腾了几轮,从定位缓存目录、理解目录结构,到用官方工具清理,最后把整个缓存迁移到 D 盘,整个过程花了一个多小时,C 盘从爆红边缘救回到剩下 60 多 G 可用空间。过程中也踩了不少坑,比如删错目录、环境变量没生效、迁移后路径失效等等,下面按复盘顺序一条一条写出来。
1. 先搞明白:Hugging Face 缓存到底在你电脑里存了什么
1.1 缓存目录到底在哪
很多人不知道缓存的位置,遇到磁盘空间告急,打开资源管理器对着 C 盘一通翻,却找不到占空间的元凶。Hugging Face 缓存的默认位置其实非常固定,在 Windows 上是C:\Users\你的用户名\.cache\huggingface,在 Linux 和 macOS 上则是~/.cache/huggingface。
这里有个小知识点:你在代码里调用from_pretrained()时,模型下载到本地后并不会直接保存在当前项目文件夹里,而是统一归集到这个缓存目录。也就是说,无论你从哪个项目路径加载模型,缓存都只会落到.cache/huggingface这一处。
如果你之前修改过环境变量,缓存的位置可能会换地方。常见环境变量有三个,优先级从高到低分别是:
| 环境变量 | 作用 |
|---|---|
HF_HOME | 设置 Hugging Face 缓存的根目录,范围最大 |
HF_HUB_CACHE | 只指定模型和数据集的缓存目录,会覆盖HF_HOME里的对应部分 |
TRANSFORMERS_CACHE | transformers 库专用的缓存目录,属于比较老的用法,新版本库也兼容它 |
我经常遇到读者问“为什么我设置了 HF_HOME 还是没生效”,这多半是因为进程没重启,或者你在代码里直接硬编码了缓存路径。Windows 下设置完环境变量后,必须重启终端和 Python 进程才能读到新值。
如果要快速查看当前缓存路径,可以直接在 Python 里执行几行代码:
import os from huggingface_hub import constants # 输出当前实际的 HF 缓存根目录 print(os.path.expanduser(constants.HF_HOME)) print(os.path.expanduser(constants.HF_HUB_CACHE))跑完之后,你会得到一个形如C:\Users\你的用户名\.cache\huggingface\hub的路径,这个hub目录下面全是各类模型和数据集的数据块。
1.2 目录结构解剖:blobs、snapshots、refs 各管什么
只看目录名“huggingface”,很多人会以为里面就是一堆模型文件夹。但打开cache\huggingface\hub后你会发现一堆命名类似models--username--model-name的文件夹,每个文件夹里面还套着三层小目录:blobs、snapshots、refs。
blobs:真实文件存放处,所有模型权重、配置文件、tokenizer 文件都以 SHA256 哈希命名存储在 blobs 里。snapshots:快照目录,里面是“给代码看的文件列表”,放着各种符号链接(Windows 下是快捷方式或者目录联接),它们指向 blobs 里的真实文件。refs:指针文件,记录某个分支或版本当前指向哪个快照。
为什么要做得这么绕?因为一个模型库在 Git 仓库里可能有多个版本,如果每个版本都完整复制一份权重文件,磁盘空间直接翻倍。采用“blobs 存真实文件、snapshots 存链接”的方式后,同一个底层文件只需物理存储一份,不同版本快照引用同一个 blob,既节省空间,又能在你切换仓库版本时实现高效复用。
你可能会问,既然采用了硬链接去重,为什么缓存还是占了这么多空间?答案很简单:你下载的模型太多了。每个模型权重动辄几个 G,比如常见的文本生成模型、扩散模型,一口气下载五六个,叠加起来轻松突破 30 到 40G。再加上除了hub缓存,还有 datasets、spaces 等不同用途的子目录,全部都默认放在用户账户下,C 盘自然越来越紧。
1.3 为什么占空间的总是 C 盘
这个问题其实很现实。绝大多数 Windows 电脑的 C 盘是系统盘,操作系统、软件安装目录、用户文件夹全在这里。Hugging Face 缓存走的是用户目录路线,默认就在C:\Users\用户名\下面,你去改环境变量之前,它只会往 C 盘塞东西。
还有一个容易被忽略的点:Python 虚拟环境里的库文件、pip 下载的安装包缓存也可能存在用户目录下。部分同学还会用到 diffusers 的 pipeline 下载、spaces 的仓库克隆,这些操作在最新版本的 huggingface_hub 上都会统一走~/.cache/huggingface这个目录体系。所以你会发现 C 盘剩余空间越来越小,看了一圈项目文件却都没多大,问题往往就出在这个用户级缓存目录。
想快速确认是不是它占了大量空间,可以在 Windows 终端里跑一行命令:
du -sh C:\Users\你的用户名\.cache\huggingface或者直接在资源管理器中右键查看该文件夹属性。实测下来但凡你平时下载模型比较多,这个目录大概率有 10G 以上,多的能到 50G 以上。
2. 动手之前,先想清这三个问题
2.1 哪些缓存能删、哪些要留
清理缓存不是简单地把huggingface文件夹一键删除就完事,关键看你后续还要不要用这些模型。
如果你只是临时跑一个 demo,跑完就不会再碰了,那可以直接删。删完后下次再下载,还是会重新占用空间,但这不叫“问题”,因为磁盘空间本来就是用于运行的。
如果你是频繁切换模型的开发者,某些常用模型删了之后每次都要重新下载,既浪费时间又消耗网络流量。这时候比较合理的做法不是删,而是把缓存迁移到空间更大的盘。比如 D 盘还有 200G,就把整个缓存目录搬过去,再用目录联接的方式让原路径继续可用,代码和模型加载逻辑完全不用改。
还需要留意一个细节:如果你用huggingface_hub的upload_folder或create_repo上传过自己的模型,hub 缓存目录里同样会残留本地上传的中间文件,这些文件通常也会占几百 M 到几个 G,平时容易被忽略。检查一下目录列表,凡是和你自己账号相关的models--你的名字--项目名,里面一般都有值得保留的本地状态,不要盲目全选删除。
2.2 如何判断哪些缓存正在被占用
删除缓存最怕遇到文件被占用。Windows 环境下,如果 Python 进程还持有模型文件句柄,无论你是用资源管理器还是命令行删除,都会弹“文件正在使用中”的提示。
所以操作前建议先做三件事:
- 把正在运行的 Python、Jupyter、ComfyUI 等可能加载模型的程序全部退出。
- 在任务管理器中检查是否还有 python.exe 进程残留,有的话先结束。
- 查看终端里是否还有正在等待模型加载的窗口,关闭后再继续。
这一步虽然看起来麻烦,但能省下大量排查时间。Linux 和 macOS 下文件占用提示相对少一些,但如果模型缓存所在磁盘是网络挂载盘,或者你刚好有 IDE 的索引进程在里面扫描,也可能出现类似问题。
2.3 删除还是迁移,怎么选
我遇到不少同学一看到缓存占用很大,第一反应就是“删”,其实删除和迁移应该看你后续的真实需求:
| 场景 | 建议方案 | 理由 |
|---|---|---|
| 模型已经没用,空间急需释放 | 直接清理 | 一劳永逸,不用保留无用数据 |
| 模型后续还会频繁使用,C 盘空间不够 | 迁移到其他盘 + 目录联接 | 保留模型,同时释放 C 盘 |
| 空间暂时够,但担心以后不够 | 先清理完全没用的缓存,再设置环境变量指向大容量盘 | 提前止损,避免后续再爆红 |
| 工作中需要指定绝对路径加载模型 | 迁移后创建目录联接,或修改代码路径 | 让原路径失效问题不影响使用 |
迁移还有一个隐藏优势:以后新下载的模型会直接落在 D 盘,只要你还设置了HF_HOME指向 D 盘的新位置,那么就算不同 Linux 发行版的用户目录结构千差万别,也不影响新的缓存写入。
3. 三种安全清理方案,从温和到彻底
3.1 方案一:用官方命令行工具 scan-cache 和 delete-cache
huggingface_hub 官方其实提供了一个比较完善的可视化缓存管理工具,用法很简单,前提是安装好 huggingface_hub 库:
pip install -U huggingface_hub然后执行:
huggingface-cli scan-cache这条命令会输出当前缓存目录里所有模型的名称、类型、占用空间大小和最近访问时间。输出结果里 Repo ID 一目了然,你可以先根据这份清单判断哪些模型对你已经没有价值。
确认后就可以执行:
huggingface-cli delete-cache执行后会进入交互模式,列出所有缓存条目,通过方向键和空格键勾选要删除的模型,最后回车确认即可。
如果你更喜欢脚本化处理,官方提供了一个 Python 接口,可以在代码里完成扫描和删除操作:
from huggingface_hub import scan_cache_dir, delete_cache # 扫描并打印当前所有缓存信息 cache_info = scan_cache_dir() for repo in cache_info.repos: print(repo.repo_id, repo.size_on_disk) # 选择要清理的 repo 后执行删除 delete_strategy = cache_info.delete_repo( *[r.repo_id for r in cache_info.repos if "旧模型名" in r.repo_id] ) delete_strategy.execute()官方删除策略的一大好处是它会自动识别并处理引用关系,blobs里正在被多个snapshots引用的文件不会被误删,孤儿文件会被单独整理出来待处理。相比手动找文件,这个方案安全系数高很多。
3.2 方案二:手动清理,精准删掉不需要的快照和孤儿文件
手动清理要根据目录结构动手。假设你已经确认某几个模型以后都不用了,可以直接把这些模型的整个models--xxx文件夹移除。比如:
# Windows CMD rmdir /s /q "C:\Users\你的用户名\.cache\huggingface\hub\models--unused-model" # Linux / macOS rm -rf ~/.cache/huggingface/hub/models--unused-model如果只想清理某模型的部分旧版本,保留当前使用的版本,就需要精细操作。打开对应模型的snapshots目录,里面通常有多个哈希命名的快照子目录。保留你正在用的那个分支对应的快照,删除其他快照。删除时要注意,快照里的文件其实是指向 blobs 的符号链接,删掉 symlink 并不会删除真实的权重文件。
真正的磁盘释放取决于 blobs 里的物理文件还会不会被其他快照引用。你删掉一个快照后,那个快照引用的 blob 可能变成“孤儿”状态。下一步可以看看整个blobs目录下哪些文件没有被snapshots里任何目录引用,手动删除这些内容。这个操作比较依赖经验,不太适合新手,但确实能更彻底地释放空间。
如果你确定整个huggingface目录都没有有用的东西了,直接删除整个目录当然可行。但我不建议新手一上来就整目录删,最好先通过scan-cache拿到清单,再决定保留范围。
3.3 方案三:迁移缓存到其他盘,根治“C 盘爆红”
如果空间需求不是一次性清除,而是希望以后模型都别往 C 盘写,那最根本的办法是迁移缓存目录,并让旧路径继续生效。Windows 下的操作路径如下。
先把旧的缓存目录整体搬到 D 盘,比如规划新位置为D:\hf_cache\huggingface:
:: 假设当前用户名是 currentuser :: 先确保没有 Python 进程占用缓存目录 move C:\Users\currentuser\.cache\huggingface D:\hf_cache\huggingface移动完成后,在原来的位置创建一个目录联接,让系统里其他程序依然可以按原路径访问:
mklink /J C:\Users\currentuser\.cache\huggingface D:\hf_cache\huggingface这里用的是目录联接而不是快捷方式。快捷方式对普通用户双击有效,但对程序来说路径仍然是原路径,不会自动解析到目标目录;目录联接则不同,等于告诉系统“这个路径实际指向另一个位置”,任何读写原路径的操作都会自动落到 D 盘。
如果你使用的是 Linux 或 macOS,可以用符号链接实现同样的效果:
mv ~/.cache/huggingface /data/hf_cache/huggingface ln -s /data/hf_cache/huggingface ~/.cache/huggingface另外,就算不迁移旧文件,你也可以直接设置环境变量让后续下载都落到其他盘。在 Windows 上执行:
setx HF_HOME "D:\hf_cache\huggingface"或者更细粒度一些:
setx HF_HUB_CACHE "D:\hf_cache\huggingface\hub" setx HF_DATASETS_CACHE "D:\hf_cache\huggingface\datasets"设置完环境变量之后,记得关闭并重新打开终端。如果你是在已经打开的编辑器或终端里测试,需要重启这些进程才能生效。
4. 实战复盘:一次完整的缓存清理与迁移过程
4.1 排查定位:看看磁盘空间到底被谁吃了
我收到的典型场景是这样的:C 盘剩余空间只有不到 3G,系统提示磁盘不足,一些日常操作卡顿明显。打开资源管理器,C 盘进度条已经接近满格。这时候第一件事就是找出占用大户。
我在终端里先定位了缓存目录的实际大小:
du -sh C:\Users\测试账号\.cache\huggingface输出显示这个目录占用了 72G。接着再细分看一下各模型的分布:
Get-ChildItem C:\Users\测试账号\.cache\huggingface\hub | ForEach-Object { $size = (Get-ChildItem $_.FullName -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum [PSCustomObject]@{ Name = $_.Name; SizeGB = [math]::Round($size / 1GB, 2) } } | Sort-Object SizeGB -Descending输出结果里排在前面的几个大模型,一个是扩散模型相关,文件夹名大概长这样models--someone--stable-diffusion-xxx,占了 30 多 G;另两个是文本生成类模型,各占 10 多 G;剩下的是各种小型 embedding 模型和数据集缓存。
我对照自己平时的使用习惯,确认了其中两个大模型已经很久没有用过了,另外那台机器平常主要是在做图像相关实验,几个文本模型确实属于“一次性下载后再没打开过”。这种背景下,我决定分三步走。
4.2 分步操作:先删无用缓存,再迁移整个仓库
第一步是使用官方清理工具先删除确认没用的模型条目。我在终端执行:
huggingface-cli delete-cache进入交互面板后,通过键盘上下移动选中不需要的模型条目,按空格键标选,最后回车确认。这一步清理掉了大约 41G 的缓存内容,全部来自那些已经不再使用的模型。
第二步是对剩余的模型做迁移,因为我知道剩下的这些内容虽然体积不大,但后续可能还要继续用。执行移动命令,从 C 盘搬到 D 盘:
move C:\Users\测试账号\.cache\huggingface D:\hf_cache\huggingface移动操作会持续几分钟,取决于缓存内文件数量和磁盘速度。这一步结束后,C 盘里的huggingface文件夹就不存在了。此时所有依赖该路径的代码都会找不到模型,所以立刻补充一个目录联接:
mklink /J C:\Users\测试账号\.cache\huggingface D:\hf_cache\huggingface命令执行完会有提示,说联接创建成功。我顺手打开资源管理器看了一下,原路径会显示一个带快捷方式标识的文件夹图标,点进去就是 D 盘的真实目录,非常符合预期。
第三步是设置环境变量,让以后新建的缓存不再回落到 C 盘。考虑到迁移前目录联接已经建立,其实旧路径已经指向 D 盘了,设置环境变量更多是兜底作用和方便管理。我执行了:
setx HF_HOME "D:\hf_cache\huggingface"命令返回成功。之后重新打开终端验证一下环境变量是否生效,再确认 python 进程是否读取到新路径:
import os from huggingface_hub import constants print(os.path.expanduser(constants.HF_HOME))输出显示D:\hf_cache\huggingface,符合预期。
4.3 清理后的验证:模型还能正常加载吗
迁移完成后最怕的就是代码找不到模型文件。我特意在本地写了一个很小的验证脚本,从缓存中加载一个之前常用的 embedding 模型:
from transformers import AutoTokenizer, AutoModel model_name = "某个之前缓存里已有的模型名" tokenizer = AutoTokenizer.from_pretrained(model_name, local_files_only=True) model = AutoModel.from_pretrained(model_name, local_files_only=True) print("模型加载成功,缓存路径指向:", model.name_or_path)这里加了local_files_only=True,意思是不允许联网重新下载。如果迁移成功,代码会直接从本地缓存读取文件;如果路径有问题,就会直接报错提示模型文件不存在。
实验跑完,模型很顺畅地加载了,证明目录联接生效,迁移是成功的。然后我再回到资源管理器看 C 盘可用空间,已经从爆红边缘恢复到了 60G 以上。
4.4 清理之后需要注意的细节
很多人以为清理完就万事大吉了,其实后面还有几个细节要留意。
一是删除缓存不会影响已经加载进内存的模型。如果你在删除前已经用某个模型生成了结果,项目文件不受影响,下次启动时只要模型没缓存就需要重新下载,但已经生成的内容都在你的项目里。
二是使用 Visual Studio Code 这类编辑器时,如果它一直保持某个文件夹被索引加载,删除大文件后资源管理器/磁盘空间指标可能不会立刻刷新。可以先关闭相关 IDE 的大文件夹窗口,避免索引进程持锁。
三是回收站问题。如果你直接在资源管理器里删除整个缓存文件夹,回收站仍然占空间,很多人以为删掉了,实际空间并没有释放。要彻底释放,记得再清空回收站,或者在命令行里用rmdir删除,这样不经过回收站。
5. 避坑速查表:这些问题我全都遇过
5.1 删除时提示文件被占用
只要 Python 进程还在运行,哪怕是后台 Jupyter 内核,删除缓存目录就会遇到“操作无法完成,因为文件已在另一个程序中打开”的弹窗。
排查办法:打开任务管理器,找到所有 python.exe、jupyter.exe 相关进程,逐个结束;再用资源监视器确认没有其他程序访问缓存路径。Linux 下可以使用lsof查看占用进程:
lsof | grep huggingface找到占用的 PID 后视情况结束进程,或者先重启开发环境再清理。
5.2 删完模型,下次跑代码又自动重新下载
这个不是“问题”,而是缓存机制的正常表现。你删除了本地的模型缓存文件,from_pretrained时库发现本地没有模型,就会重新下载。
要避免误删后重复下载,操作前把scan-cache的输出结果截图或保存一份,然后逐条确认哪几个模型还在用。只删除不用的模型目录,不要整目录直接删掉。
如果特别在意网络流量,还可以设置离线模式来测试缓存完整性:
set HF_HUB_OFFLINE=1这样代码不会尝试联网下载,如果缓存里有文件就不影响使用;没有文件会直接报错,这样你就能知道哪些模型还需要重新下载。
5.3 磁盘空间没释放,删除后还是红的
常见原因之一是回收站未清空,另一种情况是有些文件被系统悄悄延迟删除了。Windows 的文件系统对大目录删除通常会先标记后清理,磁盘空间可能需要等一小段时间才会更新。
可以直接重启电脑再查看。如果重启后确实释放了,那就是系统指标刷新延迟;如果还是没释放,重点检查C:\Users\用户名\.cache\huggingface下有没有残留的小文件或无权访问的目录,手动补删即可。
还有个冷门的原因是磁盘配额或 OneDrive 同步。如果你的用户目录被云同步接管,删除文件后云端可能还保留版本,本地会继续同步回来,导致空间反复占用。这种情况下需要先暂停云同步,再执行清理。
5.4 迁移后代码里的绝对路径失效
有一种情况是迁移前代码里写了绝对路径,比如:
model_path = "C:/Users/当前用户/.cache/huggingface/hub/models--xxx" model = AutoModel.from_pretrained(model_path)目录联接创建后,C:/Users/当前用户/.cache/huggingface依然能访问,所以这段代码不会失效。真正会失效的情况是你没有创建目录联接,只改了环境变量,代码里又用绝对路径指向了 C 盘旧目录。这时旧目录已经不存在,加载报错就是必然的。
改了环境变量但没生效的另一个坑是:你在 Python 脚本里先手动os.environ["HF_HOME"] = "D:/xxx",然后在同一进程里又使用 transformers,结果发现读取的还是旧路径。这是因为 huggingface_hub 在库导入的时候就已经确定了常量,后面改环境变量不一定能覆盖全部已缓存的值。最稳的做法是在每次启动 Python 前通过系统环境变量设置好,而不是在代码运行时临时改。
5.5 多个 Python 环境共用缓存,导致删了又出现
我用过很多虚拟环境,每个环境装的库版本不同,但同一个用户名下的缓存目录是全局共享的。也就是说,你在环境 A 里删除了某个模型,切到环境 B 一跑,发现模型又下载了一遍,缓存目录又恢复了体积。
如果想彻底处理,不要只在一个环境里清理,而是统一管理环境变量,让每个虚拟环境都指向同一个HF_HOME的持久化位置,然后在该位置做清理。比如在虚拟环境的 activate 脚本里设置:
export HF_HOME="$HOME/hf_storage"Windows 下就是在 activate.bat 里加一行set HF_HOME=D:\hf_cache\huggingface。这样不管用哪个虚拟环境,缓存位置都是同一个,清理一次就能全线生效。
5.6 只有 datasets 缓存占用大,模型缓存很小
不是所有的大空间占用都来自模型,我把huggingface目录拆开看后,发现datasets和hub是两个大头。datasets目录存放的是通过load_dataset()下载的数据文件,有些云端数据集一次下载就是几个 G 到几十个 G。
如果你用不到某些数据集,同样可以单独删除D:\hf_cache\huggingface\datasets下对应目录,或者设置HF_DATASETS_CACHE指向空间更大的位置。明白了这一点,才能在资源管理里准确判断空间被谁吃掉。
清理与预防的几点个人体会
这一通折腾之后,我最大的感受是“清理只是补救,预防才是根本”。日常使用模型时,最好一开始就把HF_HOME指向非系统盘,或者至少养成定期查看scan-cache的习惯。我现在每个月会固定跑一次扫描命令,看到占用超过预期就直接用官方工具清理,C 盘空间非常稳定。
另外还有一个我自己踩过的坑想分享一下:不要一时冲动把整个huggingface目录直接删除,因为里面除了模型,还可能有一些正在使用的工具产生的状态文件,比如上传脚本的临时状态、tokenizer 的自定义词表。删完再重建,虽然都能配置回来,但无谓浪费很多时间。
如果让我推荐一套组合拳,那就是“先scan-cache看清底细,再delete-cache完成删除,最后mklink /J迁移到其他盘”,这套流程既安全又高效。当然,操作之前务必备份好真正有价值的模型,毕竟重新下载再怎么快,也要付出时间和流量成本。