将 GitHub CI 迁移至 Hugging Face Jobs
速览
本文详细阐述了将持续集成(CI)流程从 GitHub Actions 迁移至 Hugging Face Jobs 的方法与步骤。这一迁移有助于开发者更紧密地整合模型训练、评估和部署环节,充分利用 Hugging Face 的硬件资源。通过简化基础设施管理,团队可以更专注于算法优化与模型迭代,提升 AI 开发效率。
AI 深度解读
将 GitHub CI 迁移至 Hugging Face Jobs:深度解读
背景
对于许多开源项目,尤其是涉及机器学习(ML)和深度学习的项目,持续集成(CI)环境的选择至关重要。传统的 GitHub Actions 默认使用 runs-on: ubuntu-latest,这虽然提供了便利性,但也存在明显的局限性:
- 资源限制:托管机器是通用的,缺乏针对特定硬件(如 GPU)的灵活支持。大多数开源项目难以直接启用 GPU 访问。
- 稳定性与速度:GitHub Actions 有时会出现维护停机或速度缓慢的情况。
- 硬件需求错位:以 Trackio 为例,他们既需要可靠的 CPU CI 用于基本单元测试和前端检查,又需要 GPU CI 来在真实的 CUDA 硬件上运行测试。
为了解决这些痛点,Trackio 构建了一种替代方案:保留 GitHub Actions 作为 CI 的控制中枢,但将具体的任务(Jobs)运行在 Hugging Face Jobs 的无服务器基础设施上。这一举措不仅将 CPU 任务的 CI 时间缩短了约 30%,还启用了一个全新的、基于 GPU 机器的测试套件。
核心内容
本文详细介绍了如何通过 huggingface/jobs-actions 这一桥梁工具,将 GitHub Actions 的工作流无缝迁移到 Hugging Face Jobs。其核心逻辑是将 GitHub Actions 任务转化为在 HF Jobs 上运行的临时自托管运行器(Self-hosted Runner)。
1. 什么是 Hugging Face Jobs?
Hugging Face Jobs 允许用户在几乎任何硬件配置下运行命令或脚本。一个 Job 主要由以下要素组成:
- 要运行的命令。
- Docker 镜像:来自 Docker Hub 或 Hugging Face Space。
- 硬件规格:如 CPU、
t4-small或h200GPU 等。 - 可选的环境变量和密钥。
例如,可以通过 CLI 运行:
hf jobs run python:3.12 python -c "print('Hello world')"
这种命令驱动、环境干净且硬件可定制的特性,使其成为 CI 任务的理想载体。
2. 架构流程:GitHub Actions 与 HF Jobs 的连接
huggingface/jobs-actions 实现了一个 Dispatcher(调度器)机制,完整流程如下:
- 触发:Pull Request 触发 GitHub Actions 工作流。
- 队列与通知:GitHub 将标记为
runs-on: hf-jobs-*(如hf-jobs-cpu-upgrade或hf-jobs-t4-small)的任务放入队列,并通过 GitHub App 向 Dispatcher 发送签名的workflow_job.queuedwebhook 事件。 - 验证与启动:Dispatcher Space 验证 webhook,检查
hf-jobs-*标签,生成一个短期的 GitHub 运行器注册令牌,并在匹配的硬件上启动一个 HF Job。 - 运行器注册:HF Job 启动一个临时的 GitHub Actions 运行器容器,并使用该一次性令牌向仓库注册。
- 执行与回报:GitHub 将挂起的工作流任务分配给该运行器;运行器执行 CI 任务,将状态报告回 GitHub,然后退出。
从 GitHub 的角度看,这只是一个自托管运行器;从 Hugging Face 的角度看,这只是一个启动容器来运行仓库中 GitHub Actions 步骤的 Job。
3. 实施步骤
第一步:创建 Dispatcher Space
Dispatcher 是一个小型 Docker Space,负责接收 GitHub 的 workflow_job webhook 事件并响应启动 HF Jobs。
- 操作:前往
huggingface/jobs-actions-dispatcher并点击 "Duplicate this Space"。 - 配置:
- Owner:你的 HF 用户或组织。
- Name:
jobs-actions-dispatcher。 - Hardware:务必选择
cpu-upgrade。虽然cpu-basic可用于测试,但它会在空闲后休眠,可能导致 GitHub webhook 到达时工作流永远处于排队状态。使用cpu-upgrade可确保 Dispatcher 始终可用。
- 获取 Webhook URL:Space 构建完成后,页面会显示类似
https://YOUR-HF-NAMESPACE-jobs-actions-dispatcher.hf.space/webhook的 URL。
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"
第二步:创建并安装 GitHub App
在 Dispatcher Space 中创建 GitHub App,该 App 需要权限来监听排队的工作流任务并创建临时的自托管运行器注册令牌。
- 打开你的 Dispatcher Space 页面。
- 在设置表单中输入目标 GitHub 仓库(如
YOUR-GITHUB-ORG/YOUR-REPO)。 - 点击创建 GitHub App 按钮。
- 在 GitHub 界面中为 App 命名并安装到指定仓库。
- 重要:你需要提供一个具有启动 Jobs 权限的 Hugging Face Token(对应你的个人账户或计费组织),并将其保存为 Dispatcher Space 的
HF_TOKEN密钥。
CLI 替代方案:
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,点击创建按钮,按提示操作
第三步:配置计费命名空间(可选)
默认情况下,HF Jobs 在 Dispatcher Space 所在的命名空间下启动。如果需要将费用分摊到不同的 HF 用户或组织,可以设置 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"
注意:第二步中设置的 Token 必须对应此命名空间。
第四步:修改 GitHub Actions 工作流
这是最简单的部分。只需将工作流文件中的 runs-on 标签从默认的 ubuntu-latest 更改为 Dispatcher 支持的标签。
- CPU 任务:
runs-on: hf-jobs-cpu-upgrade - GPU 任务:
runs-on: hf-jobs-t4-small(或其他 GPU 标签)
示例工作流文件:
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"
4. 验证
可以通过 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 的实时日志。
关键要点
- 硬件解耦:通过
huggingface/jobs-actions,开发者可以将 CI 的计算负载从 GitHub 的通用托管环境卸载到 Hugging Face 的无服务器基础设施,从而获得更灵活的硬件选择(包括 GPU)。 - Dispatcher 是关键:
jobs-actions-dispatcherSpace 充当了 GitHub 和 HF Jobs 之间的桥梁。它负责接收 webhook、验证身份、生成临时令牌并启动相应的 HF Job。 - 硬件选择需谨慎:Dispatcher Space 必须使用
cpu-upgrade规格,以避免因空闲休眠导致 webhook 丢失或工作流无限排队。 - 极简迁移:对于现有 GitHub Actions 工作流
