hf-sync:HuggingFace 与 ModelScope 上的模型&数据集搬运工

GitHub: hf-sync

痛点:从 HF 下载模型太痛苦了

从 HuggingFace 下载模型/数据集,网络体验一言难尽。要么得挂代理,要么得用镜像站,也不稳定。

而 ModelScope(魔搭)作为国内的模型托管平台,下载速度就快得多了。所以一个很自然的需求就出现了:把 HF 上的模型同步到 ModelScope,方便自己或者其他人下载。

那怎么同步呢?最直接的做法就是先下载到本地,再上传:

hf download org/model --local-dir ./model

然后:

modelscope upload org/model ./model

但是,还是由于网络问题,有时候根本下载不了,而且有的模型/数据集很大,完整的下载到本地也需要很大的存储空间。

hf-sync:一条命令的事

hf-sync 就是为了解决这个问题而生的。它的核心思路很简单:一个文件一个文件地搬——从源端下载一个文件,上传到目标端,再处理下一个。同一时刻只在本地暂存当前正在传输的文件,不需要把整个仓库完整地下载到本地再上传。

hf-sync sync hf:org/model ms:org/model

就这一行。剩下的交给它。

当然,hfmodelscope 自带的工具本身也有断点续传、增量下载这些能力,hf-sync 并不是在这些方面重新发明轮子。它真正解决的是跨平台同步这个场景下的问题:

  • 一条命令搞定:不用先下载再上传,不用手动操作两个工具
  • 不需要完整本地副本:一个文件一个文件地传,同一时刻只在本地暂存当前正在传输的文件,不用先把整个仓库完整地落盘
  • 增量同步:自动对比两端的文件列表和内容哈希,只传有变化的文件,模型更新了不用全量重传
  • 安全确认:写入前会显示同步计划让你确认,不会稀里糊涂覆盖东西
  • 镜像模式:加 --delete 让两端完全一致,类似 rsync --delete

安装

git clone https://github.com/r4ining/hf-sync.git
cd hf-sync
pip install -e .

需要 Python 3.9+,依赖 huggingface_hubmodelscope SDK。

基本用法

命令格式就一个模式:

hf-sync sync <source> <target>

sourcetarget 用前缀区分平台:

  • hf:org/model → Hugging Face 上的仓库
  • ms:org/model → ModelScope 上的仓库
  • /path/to/local/dir → 本地目录

认证

涉及写入操作时需要提供 token:

hf-sync sync hf:org/model ms:org/model \
--hf-token $HF_TOKEN \
--ms-token $MS_TOKEN

读公开仓库不需要 token,但往 HF 或 ModelScope 上写的时候必须给对应的 token,并且要有写权限。

实际例子

例子 1:把 HF 上的模型同步到 ModelScope

最常见的场景——你在 HF 上看到一个好模型,想在 ModelScope 镜像一份:

hf-sync sync hf:meta-llama/Llama-3.2-1B ms:your-namespace/Llama-3.2-1B

例子 2:同步数据集

hf-sync sync --repo-type dataset hf:TianxingChen/RoboTwin2.0 ms:your-namespace/RoboTwin2.0

例子 3:先预览再执行(dry-run)

不确定会传哪些文件?先跑一次 --dry-run

hf-sync sync hf:org/model ms:org/model --dry-run

它只会打印同步计划,确认没问题了,去掉 --dry-run 再跑一次。

例子 4:镜像模式——让两端完全一致

如果你希望目标仓库是源仓库的精确镜像(包括删除源端已经不存在的文件):

hf-sync sync hf:org/model ms:org/model --delete -y

--delete 会把目标端多余的文件也删掉,-y 跳过确认提示,适合放在脚本里定时跑。

例子 5:下载到本地目录

不想同步到另一个平台,只想下载到本地?把 target 换成本地路径就行:

hf-sync sync hf:org/model ./my-model

反过来,从本地上传也行:

hf-sync sync ./my-model ms:org/model

目标仓库不存在的话会自动创建(默认私有,加 --public 可以设为公开)。

例子 6:排除特定文件

不想同步某些大文件或临时目录:

hf-sync sync hf:org/model ms:org/model --exclude "data/" --exclude "*.bin"

--exclude 可以重复使用,支持 glob 模式和目录前缀。.gitattributes 默认就会被排除。

一些需要注意的事

hf-sync 是在你运行它的这台机器上做中转的,不是两个云平台之间直接传。所以:

  • 会占用本地网络流量,总流量大约是待同步文件总大小的 2 倍(下载 1x + 上传 1x)
  • 会占用一些磁盘空间,但只是当前并发传输的几个文件的临时缓存,不是整个仓库。峰值大约是并发文件大小之和
  • 速度受限于你的上下行带宽。上传带宽 20Mbps 的话,100GB 大约要 11 小时,这不是工具的问题,是物理限制

如果临时目录所在磁盘空间不够,可以设置环境变量 TMPDIR 指向更充足的目录:

export TMPDIR=/data/tmp
hf-sync sync hf:org/model ms:org/model

总结

传统做法hf-sync
先下载整个仓库到本地,再上传一个文件一个文件地搬,不需要完整本地副本
下载 100GB 模型占 100GB 磁盘峰值只占当前并发文件的大小
两步手动操作一条命令