Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

hf-sync

在 HuggingFace 与 ModelScope 之间直接同步模型 / 数据集的命令行工具 —— 无需下载整个模型/数据集到本地。

为什么需要 hf-sync

对于在国内访问 Hugging Face 有网络困难的用户来说,从 ModelScope 下载模型 / 数据集会快得多。 因此,将 HF 上的模型 / 数据集同步到 ModelScope 是一个常见需求。

Hugging Face 和 ModelScope 各自提供了命令行工具(hfmodelscope), 可以分别下载和上传模型 / 数据集。但如果要用它们做跨平台同步,传统做法是先把完整仓库下载到本地, 再上传到目标平台:

  • 必须在本地磁盘上存放完整的仓库副本——一个 100GB 的模型就要占用 100GB 本地空间
  • 下载和上传是两个独立步骤,需要手动操作,无法一键完成

hf-sync 逐文件流式中转,不需要先将整个仓库完整的模型 / 数据集下载到本地再上传, 同一时刻仅在本地暂存当前正在传输的文件。同时提供增量同步、断点续传、并发传输等能力, 把跨平台同步简化为一条命令。

功能概览

  • 跨平台同步:HF ↔ ModelScope 双向同步模型 / 数据集
  • 同平台同步:HF → HF、MS → MS,用于仓库备份 / 改名 / 迁移
  • 本地目录支持:任一端可替换为本地目录,作为纯下载 / 上传工具使用(使用体验可能不如直接使用 hfmodelscope
  • 流式中转:逐文件流式传输,不需要在本地保留整个仓库的完整副本,同一时刻仅在本地暂存当前正在传输的文件
  • 增量同步:自动对比文件列表和内容哈希,仅传输新增 / 有变更的文件
  • 断点续传:大文件同步中断后可从上次位置继续下载,无需从头重传
  • 并发传输:默认 5 个文件并行传输,可通过 --concurrency 调整
  • 安全确认:写入前显示同步计划并要求手动确认,-y 可跳过
  • 镜像模式--delete 删除目标端多余文件,使两端完全一致(类似 rsync --delete
  • 预览模式--dry-run 仅打印同步计划而不实际传输
  • 路径排除--exclude 按 glob / 目录前缀排除特定文件

快速开始

安装

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

基本用法

# 跨平台同步模型(默认仓库类型)
hf-sync sync hf:<namespace>/<repo> ms:<namespace>/<repo>

# 同步数据集
hf-sync sync --repo-type dataset hf:<namespace>/<repo> ms:<namespace>/<repo>

# 反向同步同理
hf-sync sync ms:<namespace>/<repo> hf:<namespace>/<repo>

# 同平台同步(备份 / 迁移)
hf-sync sync hf:org/model hf:org/model-backup

# 下载到本地目录(任一端可替换为本地路径)
hf-sync sync hf:org/model /path/to/local/dir

# 从本地目录上传到 hf/ms(不存在则自动创建仓库)
hf-sync sync /path/to/local/dir ms:org/model

认证

hf-sync sync hf:org/model ms:org/model \
  --hf-token $HF_TOKEN \
  --ms-token $MS_TOKEN
  • --hf-token:访问 HF 上的 gated / 私有仓库时需要;当 HF 作为目标(写入端)时始终需要。
  • --ms-token:访问 ModelScope 私有仓库时需要;当 ModelScope 作为目标时始终需要。

作为下载 / 上传工具

source / target 只要不是 hf: / ms: 开头,就会被当作本地目录路径:

# 下载:hf/ms 上的仓库 -> 本地目录
hf-sync sync --repo-type dataset hf:TianxingChen/RoboTwin2.0 /path/to/local/dir

# 上传:本地目录 -> hf/ms(不存在则自动创建仓库)
hf-sync sync --repo-type dataset /path/to/local/dir hf:TianxingChen/RoboTwin2.0

本地目录一侧的注意事项:

  • 目录不存在时,作为下载目标会自动创建;作为上传源则要求目录已存在且非空。
  • 增量对比、--dry-run--force--delete--exclude--concurrency 等选项同样生效; 由于本地文件不计算内容哈希,增量对比按「路径 + 文件大小」判断。
  • --revision / --dst-revision 对本地目录一侧无意义,会被忽略。
  • source 和 target 不能同时是本地目录。

命令行参数

参数 说明 默认值
source 源引用:hf:<namespace>/<repo>ms:<namespace>/<repo>,或本地目录路径
target 目标引用,格式同上
--repo-type 仓库类型:modeldataset model
--hf-token Hugging Face 访问令牌
--ms-token ModelScope 访问令牌
--revision 源端分支 / 版本 HF 为 main,ModelScope 为 master
--dst-revision 目标端分支 / 版本 同上,按目标平台决定
--commit-message 目标仓库的提交信息 Sync via hf-sync
--force 忽略增量差异,强制重新上传所有文件
--delete 删除目标仓库中源端已不存在的多余文件,使两端完全一致
-c / --concurrency 同时并发传输的文件数 5
--dry-run 仅打印同步计划,不实际传输
--private 创建目标仓库时设为私有(默认行为,此参数用于显式声明)
--public 创建目标仓库时设为公开,覆盖默认的私有行为
-y / --yes 跳过覆盖 / 创建确认提示,直接执行
--exclude 排除指定路径 / glob / 目录不参与同步,可重复使用(如 --exclude data/)。.gitattributes 默认排除
-v / --verbose 输出详细日志

核心机制

增量同步

每次运行会先列出两端的文件列表。如果目标端已存在同名且内容哈希匹配的文件(或当某一端无法获取哈希时, 按文件大小匹配),则跳过该文件。仅传输新增 / 有变更的文件。使用 --force 可忽略增量差异强制重新上传 所有文件,使用 --dry-run 可仅预览同步计划而不实际传输。

.gitattributes 默认排除,因为该文件由各平台独立维护,同步会导致每次都重复上传。

临时文件与断点续传

hf-sync 的设计目标是不需要在本地保留整个仓库的完整副本,逐文件传输,同一时刻仅在本地暂存当前正在传输的文件。每个文件都会先写入本地临时文件(.part),完成后再交给目标端。

这些临时文件采用稳定路径(而非随机临时文件),因此如果同步中途中断(Ctrl-C、断网、进程崩溃等), 已下载的部分会保留在磁盘上,下次同步相同文件时可以从中断处续传(通过 HTTP Range 请求),而不是 重新下载。同步成功后临时文件会被自动删除;如果上传失败,会保留已下载的部分以便下次续传。

临时文件位置:

  • HF / ModelScope 作为目标端:位于系统临时目录下的 hf-sync-partial/ 子目录中
    • macOS:一般是 $TMPDIR/hf-sync-partial/(形如 /var/folders/xx/xxxxxxxx/T/hf-sync-partial/
    • Linux:一般是 /tmp/hf-sync-partial/
  • 本地目录作为目标端.part 文件就位于目标目录中对应文件的旁边(如 dir/model.safetensors.part),下载完成后自动替换为 dir/model.safetensors

如果临时目录所在磁盘空间不足以容纳单个最大文件,同步会失败;可以通过设置环境变量 TMPDIR 把它指向一个空间更充足的目录后再运行 hf-sync。同步结束后如果有残留的未完成断点续传文件, 命令行会输出警告提示其路径和占用空间,可手动删除以释放磁盘。

覆盖 / 创建确认

真正执行写入前(--dry-run 除外),hf-sync 会根据目标仓库是否已存在打印提示:

  • 目标仓库已存在 → 提示将新增 / 覆盖 N 个文件(默认不删除多余文件,除非加了 --delete
  • 目标仓库不存在 → 提示将创建该仓库并写入 N 个文件

随后要求手动输入 y / N 确认(大小写不敏感,直接回车默认为 N)。使用 -y / --yes 可跳过确认,适合脚本化场景。若没有文件需要同步(且未启用 --delete),则直接退出。

镜像模式(--delete

加上 --delete 后,会额外把「存在于目标、但源端已没有」的文件删除,让目标仓库与源仓库完全一致 (类似 rsync --delete)。

  • 确认提示会同时显示将新增 / 覆盖多少个文件、将删除多少个文件。
  • HF 作为目标:删除通过一次 create_commitCommitOperationDelete)完成,token 权限足够即可。
  • ModelScope 作为目标delete_files 目前要求 cookie 会话登录,仅凭 API token(ms-...) 可能返回 401。若遇到此问题,需要先用 modelscope login 完成一次浏览器登录, 或手动在 ModelScope 网页控制台删除多余文件。

⚠️ 带宽与网络依赖

hf-sync 是在运行它的这台机器上做中转的客户端工具:源端文件先下载到本机,再上传到目标端, 两个云平台之间没有直连通道。这意味着:

  • 会占用本地网络流量,且流量规模跟仓库总大小同一个量级。每个文件从源端下载一次到本地临时文件, 再从本地临时文件上传到目标端,本地总流量约为待同步文件总大小的 ~2 倍(源端下行 ~1x + 目标端 上行 ~1x)。
  • 会占用本地磁盘空间,峰值约为「当前并发传输的各文件大小之和」。每个文件在传输期间会在系统临时 目录下生成 .part 文件,上传成功后自动删除。如果临时目录所在磁盘空间不足,可通过环境变量 TMPDIR 指向更充足的目录。
  • 同步速度受限于本机的上下行带宽。上传带宽 20Mbps(~2.5MB/s)时, 光上传 100GB 就需要约 11 小时。hf-sync 默认并发 5 个文件以更好地利用带宽,但单文件较大时 瓶颈仍在单个传输流水线,并发主要在多文件场景下生效。
  • 传输中途 Ctrl-C 或断网时,已下载的部分会保留在本地 .part 文件中,下次运行相同文件时会通过 HTTP Range 请求从断点处续传,无需重新下载。已成功上传的文件会自动跳过。

About

在 HuggingFace、ModelScope 与本地之间同步模型/数据集

Resources

Stars

1 star

Watchers

0 watching

Forks

Contributors

Languages