Tabby 模型镜像实践:用 copy-to-modelscope 将 Hugging Face 模型同步到 ModelScope
【免费下载链接】tabbySelf-hosted AI coding assistant项目地址: https://gitcode.com/GitHub_Trending/tab/tabby
本文围绕 Tabby 仓库中的experimental/copy-to-modelscope实验性脚本模块展开,讲解如何把 Hugging Face 上的 Tabby 兼容模型(GGUF 权重)自动镜像到 ModelScope(魔搭)平台,以及 Tabby 侧如何通过环境变量从镜像源拉取模型。读完本文,你将掌握镜像脚本main.sh/sync.sh的完整执行流程、ModelScope 模型仓所需的README.md与configuration.json格式,以及消费端TABBY_DOWNLOAD_HOST、TABBY_HUGGINGFACE_HOST_OVERRIDE的底层下载逻辑。
为什么需要模型镜像
Tabby 是自托管的 AI 编程助手(Self-hosted AI coding assistant),模型权重默认托管在 Hugging Face 上。但在中国大陆地区,访问 Hugging Face 经常遇到网络问题。仓库的 CHANGELOG.md 中对此有明确说明:
Mainland Chinese users have been facing challenges accessing Hugging Face due to various reasons. The Tabby team is actively working to address this issue by mirroring models to a hosting provider in mainland China called modelscope.cn.
因此 Tabby 团队将模型同步镜像到国内托管平台 ModelScope(modelscope.cn),experimental/copy-to-modelscope目录中的脚本正是这一镜像工作的自动化实现。它解决的是“模型分发链路”问题:上游权重从 Hugging Face 出发,经过脚本同步到 ModelScope,最终由 Tabby 的下载模块(crates/tabby-download)按需拉取。
脚本模块总览
experimental/copy-to-modelscope目录下共三个文件:
| 文件 | 作用 |
|---|---|
| README.md | 模块说明:Scripts to copy huggingface model to modelscope |
| main.sh | 核心脚本:同步单个模型并推送到 ModelScope |
| sync.sh | 批量脚本:对一组模型循环调用main.sh |
main.sh的完整工作流为:克隆 ModelScope 目标仓库 → 浅克隆 Hugging Face 源仓库 → 用rsync同步内容 → 生成 ModelScope 必需的README.md与configuration.json→ 提交并通过 Git LFS 推送 → 清理临时目录。
使用前置条件
在执行脚本前,需要准备以下环境(均从脚本实际使用的命令推断):
- ModelScope 账号与 Access Token:用于向 ModelScope 仓库推送;Token 通常可在 ModelScope 账号设置中生成。
- git:用于克隆与推送(
main.sh使用git clone、git add、git commit、git push)。 - Git LFS:模型权重通常是大文件,脚本使用
git lfs push origin --all推送全部 LFS 对象,因此本机必须已安装并配置git-lfs。 - rsync:用于目录级增量同步。
- 目标仓库已存在:
main.sh通过git clone拉取的是 ModelScope 上已经建好的空仓库(仓库路径与模型 ID 对应),而不是新建仓库。
main.sh 逐段解析
1. 参数与用法校验
#!/bin/bash set -e MODEL_ID=$1 ACCESS_TOKEN=$2 usage() { echo "Usage: $0 <model_id> <access_token>" exit 1 } if [ -z "${MODEL_ID}" ]; then usage fi脚本接收两个位置参数:MODEL_ID(形如TabbyML/StarCoder-1B)和ACCESS_TOKEN(ModelScope 的推送凭证)。set -e保证任一步失败立即退出;当缺少MODEL_ID时打印用法并退出。注意这里只校验了第一个参数,ACCESS_TOKEN为空时会在后续克隆阶段报错。
2. 双向克隆:ModelScope 目标仓与 HF 源仓
git clone https://oauth2:${ACCESS_TOKEN}@www.modelscope.cn/$MODEL_ID.git ms_model --depth 1 || true git clone https://huggingface.co/$MODEL_ID hf_model --depth 1 || true- 第一个 clone 的目标是 ModelScope 仓库,脚本将凭据以
https://oauth2:<token>@...的形式内嵌在 URL 中(oauth2作为用户名、Token 作为密码),这是脚本采用的 ModelScope HTTPS 鉴权方式; - 第二个 clone 从
huggingface.co拉取同名模型仓; - 两个克隆均使用
--depth 1浅克隆,只取最新提交,避免拉取完整历史; - 末尾的
|| true用于容忍“本地目录已存在”等非致命错误,脚本随后会通过rsync --delete将本地ms_model目录校正为与源一致。
3. rsync 目录同步
echo "Sync directory" rsync -avh --exclude '.git' --delete hf_model/ ms_model/这是镜像的核心一步:
-a归档模式保留权限、时间戳等元信息,-v输出明细,-h人类可读;--exclude '.git'排除源仓库的 git 元数据,避免污染目标仓库;--delete删除目标目录中源没有的文件,保证ms_model/与hf_model/内容完全一致(增量同步)。
4. 生成 ModelScope 的 README.md
echo "Create README.md" cat <<EOF >ms_model/README.md --- license: other tasks: - text-generation --- # ${MODEL_ID} This is an mirror of [${MODEL_ID}](https://huggingface.co/${MODEL_ID}). [Tabby](https://github.com/TabbyML/tabby) is a self-hosted AI coding assistant, offering an open-source and on-premises alternative to GitHub Copilot. It boasts several key features: * Self-contained, with no need for a DBMS or cloud service. * OpenAPI interface, easy to integrate with existing infrastructure (e.g Cloud IDE). * Supports consumer-grade GPUs. EOF脚本为镜像仓生成一份新的README.md,包含:
- YAML frontmatter:
license: other(沿用非标准许可证声明)与tasks: text-generation(标注该模型用于文本生成任务),这是 ModelScope 模型页解析卡片信息的基础; - 镜像声明:明确指出本仓是 HF 原仓库的镜像;
- Tabby 项目简介:介绍其为自托管 AI 编程助手、开源且可本地部署、无需 DBMS 或云服务、提供 OpenAPI 接口、支持消费级 GPU 等特点(这段文案由脚本固定生成,属于项目宣传性描述)。
5. 生成 ModelScope 的 configuration.json
echo "Create configuration.json" cat <<EOF >ms_model/configuration.json { "framework": "pytorch", "task": "text-generation", "pipeline": { "type": "text-generation-pipeline" } } EOFconfiguration.json是 ModelScope 平台识别模型的关键配置文件,各字段含义如下:
| 字段 | 值 | 说明 |
|---|---|---|
framework | pytorch | 模型框架声明 |
task | text-generation | 模型任务类型:文本生成 |
pipeline.type | text-generation-pipeline | 平台推理流水线类型,用于在 ModelScope 上以文本生成流水线加载模型 |
6. 提交与推送(含重试逻辑)
push_origin() { git lfs push origin --all git push origin } set -x pushd ms_model git add . git commit -m "sync with upstream" || true while true; do push_origin && break done popd推送阶段的关键设计:
git lfs push origin --all将仓库内全部 Git LFS 大对象推送到远端,随后git push origin推送普通提交,两者合起来确保权重文件完整上库;git add .将 rsync 同步结果与生成的README.md、configuration.json一并暂存,git commit -m "sync with upstream"使用固定提交信息,|| true容忍“无变更可提交”的情况(例如两次同步之间上游没有更新);while true; do push_origin && break; done是无限重试循环:只要推送失败就不断重试,直到成功为止。从脚本行为看,这是为了对抗网络抖动而设计的“保证最终成功”策略;但也要注意,若网络持续不可用,该循环会一直阻塞,在 CI 等有超时约束的场景需要自行评估。
7. 清理临时目录
echo "Success!" rm -rf hf_model rm -rf ms_model同步成功后删除本地克隆的临时目录,避免残留占用磁盘。
批量同步:sync.sh 与模型清单
main.sh 一次只处理一个模型,sync.sh 将其包装为批量任务:
#!/bin/bash set -ex MODELS=$(cat <<EOF TabbyML/StarCoder-1B TabbyML/StarCoder-3B TabbyML/StarCoder-7B TabbyML/CodeLlama-7B TabbyML/CodeLlama-13B TabbyML/WizardCoder-3B EOF ) for i in $MODELS; do ./main.sh $i $1 done- 内置的模型清单包含 Tabby 常用的代码补全模型:
StarCoder系列(1B/3B/7B)、CodeLlama系列(7B/13B)与WizardCoder-3B; - 脚本第一个参数
$1即 ModelScope Access Token,会透传给每个main.sh; set -ex开启回显并在出错时立即终止;如需新增模型,直接在MODELS列表中添加即可。
消费端:Tabby 如何从镜像源拉取模型
镜像的最终目的,是让 Tabby 能从这个源下载模型。下载逻辑集中在 crates/tabby-download/src/lib.rs,通过两个环境变量控制:
pub fn get_download_host() -> String { std::env::var("TABBY_DOWNLOAD_HOST").unwrap_or_else(|_| "huggingface.co".to_string()) } pub fn get_huggingface_mirror_host() -> Option<String> { std::env::var("TABBY_HUGGINGFACE_HOST_OVERRIDE").ok() }TABBY_DOWNLOAD_HOST:指定从哪个托管源下载,默认huggingface.co;设置为modelscope.cn(或相应镜像域名)即可从 ModelScope 拉取;TABBY_HUGGINGFACE_HOST_OVERRIDE:把下载地址字符串中的huggingface.co直接替换为兼容镜像(如hf-mirror.com)。该变量在 CHANGELOG.md 中有记录:"Added an environment variableTABBY_HUGGINGFACE_HOST_OVERRIDEto overridehuggingface.cowith compatible mirrors (e.g.,hf-mirror.com)"。
核心筛选逻辑是 filter_download_address:
- 从模型注册表中取出该模型的
urls(或partition_urls)地址列表; - 找出包含
download_host的地址; - 若设置了
TABBY_HUGGINGFACE_HOST_OVERRIDE,则把该地址中的huggingface.co替换为镜像主机,得到最终下载地址; - 下载时先校验本地缓存,sha256 不匹配或文件缺失时会重新下载(对应
download_model_impl中的完整性检查逻辑,见 lib.rs)。
该逻辑在 lib.rs 的测试用例 中被验证:测试中设置TABBY_HUGGINGFACE_HOST_OVERRIDE=modelscope.co或TABBY_DOWNLOAD_HOST=modelscope.co后,断言筛选出的下载地址指向 modelscope 域名。这也说明 ModelScope 地址会被写入模型的urls列表,由下载模块按主机筛选命中。
关于环境变量的历史沿革:早期版本使用TABBY_REGISTRY=modelscope tabby download --model TabbyML/WizardCoder-1B指定 ModelScope 注册表(见 CHANGELOG.md),后续在 v0.5.5 中TABBY_REGISTRY被TABBY_DOWNLOAD_HOST取代(CHANGELOG.md)。以当前仓库代码为准,应使用TABBY_DOWNLOAD_HOST与TABBY_HUGGINGFACE_HOST_OVERRIDE。
镜像内容须符合 Tabby 模型目录规范
镜像脚本同步的是“完整模型仓”,而 Tabby 在消费时对模型目录有明确约定,见 MODEL_SPEC.md。一个最小可用的 Tabby 模型目录应包含:
tabby.json ggml/model-00001-of-00001.gguftabby.json提供模型元信息:prompt_template(可选,存在则视为支持 FIM 补全)、chat_template(可选,存在则可作为--chat-model使用);ggml/目录存放 llama.cpp 推理引擎使用的 GGUF 二进制,命名遵循model-{index}-of-{count}.gguf(索引从 1 开始),单文件模型默认命名为model-00001-of-00001.gguf。
模型注册表侧的数据结构定义在 crates/tabby-common/src/registry.rs:ModelInfo包含name、prompt_template、chat_template、urls、sha256、partition_urls(registry.rs);parse_model_id负责把org/model拆分为组织与模型名,缺省组织为TabbyML(registry.rs)。模型下载到本地后按~/.tabby/models/{org}/{model}/ggml/...布局存放,并在模型目录中落一份tabby.json(由save_model_info写入,见 registry.rs)。因此,镜像到 ModelScope 的模型仓需要保证tabby.json、GGUF 分片文件等结构完整,main.sh通过整仓rsync同步恰好保留了这一目录结构。
注意事项与扩展思路
- Token 安全:
main.sh将 Access Token 明文内嵌在 clone URL 中,命令执行历史与进程列表可能暴露凭据,建议仅在受控环境执行,并优先使用权限受限的只写 Token。 - 浅克隆与 LFS:
--depth 1只保留最新提交,配合git lfs push origin --all可推送全部 LFS 对象;若 ModelScope 平台要求特定 LFS 指针格式,需保证本机git-lfs配置正确。 - 重试循环:
while true无限重试适合人工/一次性同步,若接入定时任务或 CI,可考虑为push_origin增加最大重试次数与失败告警。 - 镜像后的消费验证:镜像完成后,可用
TABBY_DOWNLOAD_HOST=modelscope(域名按实际填写)执行tabby download --model <org>/<model>验证端到端链路,下载模块会按filter_download_address逻辑命中镜像地址并做 sha256 校验(参见 lib.rs 的完整性检查实现)。
通过以上流程,experimental/copy-to-modelscope形成了一条完整的模型分发链路:Hugging Face 上游 → 脚本同步(rsync + 元数据生成)→ ModelScope 托管 → Tabby 按主机筛选下载。该模块属于实验性质(位于experimental/目录),使用时应以当前仓库实际脚本行为为准。
【免费下载链接】tabbySelf-hosted AI coding assistant项目地址: https://gitcode.com/GitHub_Trending/tab/tabby
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考