当磁盘空间不足导致 Safetensors 转换失败时,通常需要先确认转换脚本实际把临时文件写到了哪个挂载点,再通过环境变量或脚本参数把它重定向到空间充足的目录。临时目录重定位本身不是性能优化,而是让转换任务能在当前磁盘布局下跑完的搬移动作。
磁盘不足时先找到转换过程实际使用的临时目录,优先用环境变量(如 TMPDIR、HF_HOME)重定向到空间充足的挂载点,并确保目标目录可写且不是 noexec。操作后用 df 和文件监控确认脚本确实写到了新位置。若脚本自身不认这些变量,再考虑用软链接或 bwrap 类工具做隔离。
先判断临时目录落在哪里
转换脚本通常会先读取环境变量 TMPDIR,如果没有设置,就会退回系统的 /tmp。Safetensors 转换过程中既会有临时模型文件,也可能有缓存下载文件,后者更多受 HF_HOME 或 HF_HUB_CACHE 影响。建议先查看当前环境里已经生效的变量:
echo "TMPDIR=$TMPDIR"
echo "HF_HOME=$HF_HOME"
echo "HF_HUB_CACHE=$HF_HUB_CACHE"
再用 df 检查各挂载点的剩余空间,明确是哪个目录不够用了。如果脚本已经启动了一半,也可以用lsof -p <pid> | grep -i tmp来观察它实际打开的临时文件路径,但注意普通用户可能看不到其他用户的进程。
重定向临时目录的常用做法
最直接的是在启动命令前导出 TMPDIR 和 HF 相关缓存变量,指向一个剩余空间足够的目录。例如当前可用空间在 /data 下,可以这样启动:
export TMPDIR=/data/tmp
export HF_HOME=/data/hf_home
export HF_HUB_CACHE=/data/hf_home/hub
mkdir -p /data/tmp /data/hf_home
python <转换脚本> `--input` ... `--output` ...
如果是在 Docker 容器内运行,需要把宿主机的目录挂载进容器并同步设置环境变量:
docker run -e TMPDIR=/data/tmp \
-e HF_HOME=/data/hf_home \
-v /data:/data \
<镜像> python <转换脚本> ...
需要注意:不是所有脚本都尊重 TMPDIR。有些脚本会显式调用tempfile.mkdtemp(dir=/特定路径),这种写法会直接忽略环境变量。遇到这种情况,可以检查转换脚本的启动入口或者传入参数的帮助信息(python <转换脚本> `--help`),看它是否提供了类似`--temp`_dir、`--cache`_dir的参数。
验证重定向是否生效
设置完环境变量后,不要直接跑全量转换,先用一个小模型或只跑一段流程验证。启动脚本前记录目标目录的大小:
du -sh /data/tmp /data/hf_home
脚本运行后再次观察,看目录是否增长。更直接的办法是临时把目标目录挂到监控位置,或者用 find 查找最近生成的文件:
find /data/tmp -type f -mmin -5 2>/dev/null | head
如果目标目录始终没有新文件,而原 /tmp 还在增长,说明脚本没有读取 TMPDIR,这时需要回看脚本是否硬编码了临时路径。
边界与风险
重定向临时目录只解决空间问题,不改变转换逻辑。目标目录的权限必须当前用户可写,且如果后续脚本要直接执行临时文件中的程序,挂载点不能带 noexec 选项。不要把临时目录放到 NFS 等网络存储上,除非能接受明显更慢的写入速度和断连风险。如果 /tmp 本身是 tmpfs(内存盘),把它改到普通磁盘虽然会减少内存占用,但会增加磁盘 I/O,两个方案应结合已有硬件条件判断。
最后要说明一个常见误区:如果空间不足已经发生,临时目录重定位只能避免下一次任务失败。已经堆积在 /tmp 里的旧临时文件不会自动清理,需要任务结束后手动删除,否则后续仍可能再次撞上空间上限。建议定期清理自动生成的临时模型文件,再看是否需要重定向。