将 GitHub CI 迁移到 Hugging Face Jobs
Migrating Your GitHub CI to Hugging Face Jobs
Trackio 团队将 GitHub Actions CI 迁移至 Hugging Face Jobs,通过 dispatcher Space 桥接 GitHub webhook 与 HF Job 启动。CPU 任务使用 Playwright 镜像后,CI 时间从 1m40s 缩短至 1m10s(约快 30%);GPU 任务在 t4-small 上运行仅需 45s,成本不足一美分。该方案支持自定义 Docker 镜像与硬件配置,日志可通过 CLI 获取。
](https://huggingface.co/abidlabs)
如果你有一个 GitHub 仓库并启用了 GitHub Actions,你很可能使用 GitHub 托管的 runner 来做 CI。这是许多项目的默认选择,因为它很简单:添加一个 workflow,写上 runs-on: ubuntu-latest,GitHub 就会给你一台机器。
这个默认方案很方便,但也有局限。GitHub Actions 可能因维护而变慢或不可用,托管机器是通用的,而且 GPU 访问对大多数开源项目来说并不是随手可得的。对于 Trackio 来说,这些局限开始变得重要。我们既需要可靠的 CPU CI 来做基础单元测试和前端检查,也需要 GPU CI 来运行需要实际 CUDA 硬件的测试。
所以我们构建了一个替代方案:让 GitHub Actions 继续负责 CI,但将任务运行在 Hugging Face Jobs 上。
结果:Trackio 的 CI 现在运行在 Hugging Face Jobs 上,并实时流式返回日志,将我们的 CPU 任务 CI 时间缩短了约 30%,并启用了一套全新的在 GPU 机器上运行的测试套件!
在本文中,我们将逐步解释如何为你的 GitHub 仓库重现相同的设置。如果你在使用 agent,可以直接指向本文,因为我们同时提供了 CLI 指令和面向人类的浏览器操作说明。
让我们先快速介绍一下 Hugging Face Jobs!
什么是 Hugging Face Jobs?
Hugging Face Jobs 让你可以在 Hugging Face 的无服务器基础设施上运行命令或脚本,几乎支持任何硬件配置。一个 Job 本质上包含:
- 要运行的命令
- 一个 Docker 镜像,来自 Docker Hub 或 Hugging Face Space
- 一种硬件配置,例如 CPU 或
t4-small或h200GPU - 可选的环境变量和 secrets
例如,你可以运行:
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"
这使得 Jobs 天然适合 CI。CI 任务已经是命令驱动的,在干净的环境中运行,并且通常能从精确选择合适的硬件中受益。对于 ML 库来说,GPU 场景尤其有吸引力:你可以在真实的 GPU 硬件上运行测试套件,而无需维护自己始终在线的 runner。
关键步骤是将 GitHub Actions 连接到 HF Jobs,我们将在下面描述。
架构
对于这个设置,我们创建了 huggingface/jobs-actions,这是一个小型桥接工具,它将一个 GitHub Actions 任务转变为一个运行在 HF Job 内部的临时自托管 runner。
完整的流程如下:
- 一个 pull request 触发 GitHub Actions workflow。
- GitHub 将任何
runs-on标签不可用的任务(例如hf-jobs-cpu-upgrade或hf-jobs-t4-small)放入队列,并通过 GitHub App 向 dispatcher 发送一个签名的workflow_job.queuedwebhook。 - dispatcher Space 验证 webhook,检查是否存在
hf-jobs-*标签,生成一个短期的 GitHub runner 注册 token,并在匹配的硬件上启动一个 HF Job。 - HF Job 启动一个临时的 GitHub Actions runner,并使用该一次性 token 将其注册到仓库。
- GitHub 将挂起的 workflow 任务分配给该 runner;runner 执行 CI 任务,将状态报告回 GitHub,然后退出。
从 GitHub 的角度来看,这只是一个自托管 runner。从 Hugging Face 的角度来看,这只是一个启动容器来运行仓库 GitHub Actions 中 workflow 步骤的 Job。
步骤 1:复制 dispatcher Space
你首先需要的是 dispatcher。这是一个小型 Docker Space,用于接收 GitHub workflow_job webhook 事件并启动相应的 HF Jobs。
先创建这个,因为 GitHub App 需要一个 webhook URL,而这个 URL 来自该 Space。这个 Space 应该放在你自己的命名空间下,或者放在你有写入权限的 Hugging Face 组织下。
Web 设置
前往 huggingface/jobs-actions-dispatcher 并点击 Duplicate this Space。
使用:
Owner: 你的 HF 用户或组织
Name: jobs-actions-dispatcher
Hardware: cpu-upgrade
对于真正的 CI,使用 cpu-upgrade 以确保 dispatcher 能持续响应 GitHub webhook。cpu-basic 用于测试也可以,可能也能工作,但它会在不活动后休眠;如果 GitHub 的 webhook 在其唤醒期间到达,workflow 可能会永远处于排队状态。
构建完成后,打开复制的 Space。你会看到一个写着 "Required Space secrets" 的部分,暂时可以忽略。着陆页应该会显示下一步所需的 GitHub App webhook URL。它看起来像这样:
https://YOUR-HF-NAMESPACE-jobs-actions-dispatcher.hf.space/webhook
CLI 设置
如果你更倾向于使用 agent 或 CLI workflow 来设置 dispatcher Space:
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"
步骤 2:创建并安装 GitHub App
接下来,从 dispatcher Space 本身创建并安装 GitHub App。这个 App 需要权限来监听排队的 workflow 任务并创建临时的自托管 runner 注册 token。
Web 设置
打开你复制的 dispatcher Space:
https://YOUR-HF-NAMESPACE-jobs-actions-dispatcher.hf.space
在设置表单中,输入其 CI 应在 HF Jobs 上运行的 GitHub 仓库:
YOUR-GITHUB-ORG/YOUR-REPO
然后点击按钮创建 GitHub App。GitHub 会要求你为 App 选择一个名称;名称可以是任何内容,只要在你的 GitHub 账户或组织中可用即可。提交后,最终页面会明确告诉你如何使用 hf CLI 将 App 凭据上传到 dispatcher Space。
重要提示:你需要提供一个 Hugging Face token,该 token 具有启动 Jobs 的权限,对应于你的个人账户或应计费 Jobs 的组织。这个 token 应作为 HF_TOKEN secret 保存在你的 dispatcher Space 中。
最后,你需要在你在 Space 中输入的那个 GitHub 仓库上安装该 App。在 Trackio 的设置中,我们将其安装在 gradio-app/trackio 上。
Agent 辅助设置
GitHub App manifest 流程仍然基于浏览器,但 agent 可以遵循相同的 Space 驱动路径:
export HF_NAMESPACE=your-hf-user-or-org
export GITHUB_REPO=YOUR-GITHUB-ORG/YOUR-REPO
open "https://${HF_NAMESPACE}-jobs-actions-dispatcher.hf.space"
将 $GITHUB_REPO 粘贴到 Space 中,点击 GitHub App 创建按钮,选择任何可用的 App 名称,然后按照生成的 GitHub 说明操作。
App 创建后,从 App 设置页面将其安装到你的仓库。对于 GitHub 组织,安装设置位于:
https://github.com/organizations/YOUR-GITHUB-ORG/settings/installations
步骤 3:最终 dispatcher 设置
此时,dispatcher Space 应该已配置好。GitHub App 设置流程生成了将 App 凭据、webhook secret 和 Hugging Face token 上传到 Space 的命令。
默认情况下,HF Jobs 在与 dispatcher Space 相同的命名空间下启动。如果你希望将任务计费到不同的 Hugging Face 用户或组织,可以选择将 HF_NAMESPACE 设置为 Space 变量:
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 应对应于这个命名空间。
步骤 4:更改 runs-on
实际的 workflow 改动很小。将:
runs-on: ubuntu-latest
替换为 dispatcher 处理的标签之一:
runs-on: hf-jobs-cpu-upgrade
对于 GPU 测试,使用 GPU 标签:
runs-on: hf-jobs-t4-small
对于任何你想在 HF Jobs 上运行的 GitHub Action,只需要这一行改动!
步骤 5:测试
要从 CLI 添加一个最小的冒烟测试 workflow:
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
要从 CLI 验证:
gh run list --repo YOUR-GITHUB-ORG/YOUR-REPO --limit 5
hf jobs ps --namespace "$HF_NAMESPACE"
hf spaces logs "$SPACE_ID"
你应该能看到与常规 GitHub Action 类似的日志——例如,在这个 Trackio PR #565 中。
就是这样!
关于选择正确 Docker 镜像的说明
我们最初的 CPU 设置使用了 ubuntu:22.04,并在每次运行时安装缺失的系统包。这虽然可行,但比需要的慢。GitHub 的 ubuntu-latest 镜像默认包含大量开发者工具;而一个裸的 Ubuntu 镜像则没有。
对于 Trackio,UI 测试需要 Playwright 浏览器、Node、ffmpeg、sqlite、git 和常规的 Linux 构建依赖。Hugging Face Jobs 支持使用任何 Docker 镜像,所以我们切换到了 Microsoft Playwright 镜像,效果很好:
mcr.microsoft.com/playwright:v1.60.0-jammy
对于 GPU 任务,我们使用了:
nvidia/cuda:12.4.0-runtime-ubuntu22.04
结果
以下是 Trackio CI 的数据:
| Runner 设置 | 运行时间 | 与 GitHub 平均时间对比 |
|---|---|---|
GitHub ubuntu-latest 基线 |
1m40s |
基线 |
| HF Jobs CPU, Playwright 镜像 | 1m10s |
-30s,约快 30% |
HF Jobs GPU, t4-small 标签 |
45s |
无 GitHub 托管 GPU 基线 |
最大的收获是 GPU CI。Trackio 的 GPU 检查在 HF Jobs 上运行,耗时 45s,按 t4-small 费率计算,该时长成本不到一美分。
CPU 结果也令人鼓舞。使用正确的镜像,Linux 测试任务比 GitHub 托管的基线更快。这表明 HF Jobs 可以成为一个实用的 CI 后端,特别是对于需要自定义镜像或加速器的 ML 项目。
日志是另一个惊喜。GitHub Actions 日志很有用,但对于大型日志,Web UI 可能很重。HF Jobs 日志很容易从 CLI 获取:
hf jobs logs <job_id> > logs.txt
这使得它们很容易用本地工具或编码 agent 进行检查。在我们的桥接中,我们还将 GitHub Actions 任务日志镜像到了 HF Job 日志中,因此任一系统都有足够的信息来调试一次运行。
最后,虽然 Trackio 的 CI 不需要,但 HF Jobs 还支持挂载卷,如果你需要在 CI 中快速从 Hugging Face 加载数据集或模型,这会非常有用。
希望这能为你提供尝试使用 HF Jobs 运行 GitHub Actions 所需的一切!