迁移 GitHub CI 到 Hugging Face Jobs
速览
Hugging Face 推出 Jobs 服务,允许用户直接在其平台上运行 CI/CD 任务。本文详细介绍了从 GitHub Actions 迁移到 Hugging Face Jobs 的步骤,包括配置、环境变量和缓存等。这有助于开发者利用 Hugging Face 的 GPU 资源,并简化与模型训练、部署的集成。
AI 深度解读
背景
传统的 GitHub Actions CI 在方便之余也带来了诸多限制:默认的 runs-on: ubuntu-latest 虽然简单,但 GitHub 托管的运行器可能因维护而变慢或不可用,机器配置固定,且大多数开源项目难以直接启用 GPU 加速。对于像 Trackio 这样的项目,这些限制变得尤为明显:他们既需要可靠的 CPU 环境来运行基础单元测试和前端检查,又需要真正的 GPU 环境来测试依赖 CUDA 硬件的代码。为了同时满足这两类需求,Trackio 团队选择了一条新的路径:保留 GitHub Actions 作为 CI 编排层,但将作业实际执行迁移到 Hugging Face Jobs 上。
最终效果:Trackio 的 CI 现在运行在 Hugging Face Jobs 上,实时回传日志,CPU 作业的 CI 时间缩短了约 30%,并且能够启用全新的基于 GPU 机器的测试套件。
本文详细介绍了如何为任意 GitHub 仓库复现这一方案,并同时提供了面向人类的浏览器操作说明和面向智能体的 CLI 指令。
核心内容
1. Hugging Face Jobs 简介
Hugging Face Jobs 允许用户在 Hugging Face 的无服务器基础设施上运行命令或脚本,且支持几乎任意硬件规格。一个 Job 本质上包含:
- 要运行的命令
- 一个 Docker 镜像(来自 Docker Hub 或 Hugging Face Space)
- 一个硬件规格(例如 CPU、
t4-small、h200GPU 等) - 可选的环境变量和密钥
例如:
hf jobs run python:3.12 python -c "print('Hello world')"
或:
hf jobs uv run --flavor a10g-small "https://raw.githubusercontent.com/huggingface/trl/main/trl/scripts/sft.py"
这种设计天然适合 CI:CI 作业本身基于命令,运行在干净的环境里,并且往往需要精确选择硬件。对于机器学习库而言,GPU 场景尤其有吸引力——无需维护常驻的运行器,即可在真实 GPU 硬件上执行测试套件。
2. 连接 GitHub Actions 与 HF Jobs 的桥梁
关键步骤是将 GitHub Actions 与 HF Jobs 对接。为此 Hugging Face 团队创建了 huggingface/jobs-actions 这个轻量桥接工具,它可以将一个 GitHub Actions 作业转化为一个运行在 HF Job 内部的临时自托管运行器(ephemeral self-hosted runner)。
整体流程如下:
- 一个 Pull Request 触发 GitHub Actions 工作流。
- GitHub 将所有使用了未被满足的
runs-on标签(例如hf-jobs-cpu-upgrade或hf-jobs-t4-small)的作业放入队列,并通过 GitHub App 向调度器(Dispatcher)发送一个签名的workflow_job.queuedwebhook。 - 调度器 Space 验证 webhook,检查标签是否为
hf-jobs-*格式,生成一个短期有效的 GitHub Runner 注册令牌,然后启动一个匹配硬件的 HF Job。 - HF Job 启动一个临时的 GitHub Actions Runner,并使用该一次性令牌向仓库注册。
- GitHub 将队列中的作业分配给该 Runner,Runner 执行 CI 任务,将状态报告回 GitHub,完成后自动退出。
从 GitHub 的角度看,这只是一个自托管 Runner;从 Hugging Face 的角度看,这只是一个启动容器来执行仓库 GitHub Actions 工作流的 Job。
3. 部署调度器 Space
第一步需要创建调度器——一个小的 Docker Space,用于接收 GitHub 的 workflow_job webhook 事件并触发 HF Jobs。
浏览器操作:
- 访问
huggingface/jobs-actions-dispatcher,点击 “Duplicate this Space”。 - 设置 Owner(你的 HF 用户名或组织),Name(如
jobs-actions-dispatcher),Hardware 选择cpu-upgrade(生产环境建议,避免因无活动休眠导致 webhook 丢失;测试可用cpu-basic)。 - Space 构建完成后,打开它,页面会显示 GitHub App webhook URL,格式如:
https://YOUR-HF-NAMESPACE-jobs-actions-dispatcher.hf.space/webhook。
CLI 方式:
export HF_NAMESPACE=your-hf-user-or-org
export SPACE_ID="$HF_NAMESPACE/jobs-actions-dispatcher"
hf repo duplicate huggingface/jobs-actions-dispatcher "$SPACE_ID" \
--type space \
--flavor cpu-upgrade \
--exist-ok
export DISPATCHER_URL="https://${HF_NAMESPACE}-jobs-actions-dispatcher.hf.space"
4. 创建并安装 GitHub App
从调度器 Space 内部创建 GitHub App。该 App 需要权限来监听队列中的工作流作业并创建临时 Runner 注册令牌。
- 打开你的调度器 Space 首页(如
https://YOUR-HF-NAMESPACE-jobs-actions-dispatcher.hf.space),在设置表单中输入目标 GitHub 仓库(格式YOUR-GITHUB-ORG/YOUR-REPO)。 - 点击创建 GitHub App 按钮,为 App 命名(只要在你的 GitHub 账户或组织中可用即可)。
- 提交后,最终页面会显示如何通过
hfCLI 将 App 凭据上传到调度器 Space。
重要提示:您需要一个具有启动 Job 权限的 Hugging Face token(个人账户或组织),该 token 应作为 HF_TOKEN 密钥保存在调度器 Space 中。
最后,在同一个 GitHub 仓库上安装该 App(Trackio 示例中安装在 gradio-app/trackio 上)。
GitHub App manifest 流程仍基于浏览器,但智能体可跟随 Space 驱动的路径:
open "https://${HF_NAMESPACE}-jobs-actions-dispatcher.hf.space"
粘贴仓库名,点击创建,选择名称,按生成的 GitHub 指引操作。安装 App 后(对于 GitHub 组织,安装设置位于 https://github.com/organizations/YOUR-GITHUB-ORG/settings/installations),调度器 Space 即配置完成。
5. 配置计费命名空间(可选)
默认情况下,HF Jobs 在调度器 Space 所属的命名空间下计费。如果需要将费用计入不同的 Hugging Face 用户或组织,可以设置 Space 变量 HF_NAMESPACE:
export SPACE_ID=YOUR-HF-NAMESPACE/jobs-actions-dispatcher
hf spaces variables add "$SPACE_ID" -e HF_NAMESPACE=your-billing-namespace
hf spaces restart "$SPACE_ID"
注意:步骤 2 中设置的 token 应属于该命名空间。
6. 修改 GitHub Actions 工作流
实际工作流改动极小。原来使用 runs-on: ubuntu-latest 的地方,换成调度器支持的标签即可:
- CPU 测试:
runs-on: hf-jobs-cpu-upgrade - GPU 测试:
runs-on: hf-jobs-t4-small
对于任何希望在 HF Jobs 上运行的 GitHub Action,这 1 行改动就足够了。
示例最小工作流(CLI 创建):
mkdir -p .github/workflows
cat > .github/workflows/hf-jobs-test.yml <<'EOF'
name: HF Jobs Test
on:
pull_request:
push:
branches: [main]
workflow_dispatch:
jobs:
test:
runs-on: hf-jobs-cpu-upgrade
steps:
- uses: actions/checkout@v4
- run: echo "Hello from Hugging Face Jobs"
EOF
git add .github/workflows/hf-jobs-test.yml
git commit -m "Run CI on Hugging Face Jobs"
git push
7. 验证
从 CLI 验证:
gh run list --repo YOUR-GITHUB-ORG/YOUR-REPO --limit 5
hf jobs ps --namespace "$HF_NAMESPACE"
hf spaces logs "$SPACE_ID"
您应该能在 GitHub Actions 界面看到与常规作业一样的日志(例如 Trackio PR #565)。
