如果你有一個 GitHub 儲存庫並啟用了 GitHub Actions,你很可能使用 GitHub 代管執行器來進行持續整合 (CI)。這對許多專案來說是預設選項,因為它很簡單:新增一個工作流程,寫上 `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 儲存庫重現相同的設定。如果你正在使用代理,你可以參考這篇文章,因為我們為人類提供了基於瀏覽器的說明,同時也提供了命令列介面 (CLI) 指令。
讓我們從快速介紹 Hugging Face Jobs 開始!
什麼是 Hugging Face Jobs?
Hugging Face Jobs 讓你可以在 Hugging Face 的無伺服器基礎設施上運行命令或腳本,並支援幾乎任何硬體規格。一個 Job 本質上是:
一個要執行的命令
一個 Docker 映像檔,來自 Docker Hub 或 Hugging Face Space
一個硬體規格,例如 CPU、t4-small 或 h200 GPU
可選的環境變數和機密
例如,你可以運行:
`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 任務本身就是命令驅動的,已經在乾淨的環境中運行,並且通常受益於精確選擇合適的硬體。對於機器學習函式庫來說,GPU 的情況尤其引人注目:你可以在真實的 GPU 硬體上運行測試套件,而無需維護自己的常駐執行器。
關鍵步驟是將 GitHub Actions 連接到 HF Jobs,我們將在下面描述。
架構
為了這個設定,我們創建了 `huggingface/jobs-actions`,這是一個小型橋接器,它將一個 GitHub Actions 任務轉換為一個在 HF Job 內部運行的臨時自託管執行器。
完整的流程如下:
一個拉取請求觸發一個 GitHub Actions 工作流程。
GitHub 將任何 `runs-on` 標籤不可用的任務(例如 `hf-jobs-cpu-upgrade` 或 `hf-jobs-t4-small`)排入佇列,並透過 GitHub App 向派遣器發送一個簽名的 `workflow_job.queued` webhook。
派遣器 Space 驗證 webhook,檢查 `hf-jobs-*` 標籤,鑄造一個短期的 GitHub 執行器註冊權杖,並在匹配的硬體上啟動一個 HF Job。
HF Job 啟動一個臨時的 GitHub Actions 執行器,並使用該一次性權杖向儲存庫註冊。
GitHub 將待處理的工作流程任務分配給該執行器;執行器執行 CI 任務,將狀態回報給 GitHub,然後退出。
從 GitHub 的角度來看,這只是一個自託管執行器。從 Hugging Face 的角度來看,這只是一個啟動容器來運行儲存庫 GitHub Actions 中工作流程步驟的 Job。
步驟 1:複製派遣器 Space
你需要做的第一件事是派遣器。這是一個小型 Docker Space,它接收 GitHub `workflow_job` webhook 事件並響應地啟動 HF Jobs。
請先創建它,因為 GitHub App 需要一個 webhook 網址,而該網址來自 Space。這個 Space 應該在你的命名空間下,或在你擁有寫入權限的 Hugging Face 組織下。
網頁設定
前往 `huggingface/jobs-actions-dispatcher` 並點擊「Duplicate this Space」。
使用:
擁有者:你的 HF 使用者或組織
名稱:`jobs-actions-dispatcher`
硬體:`cpu-upgrade`
請使用 `cpu-upgrade` 進行實際的 CI,以便派遣器保持可用於 GitHub webhooks。`cpu-basic` 對於測試來說沒問題,並且可能有效,但它在不活動後可能會休眠;如果 GitHub 的 webhook 在它喚醒時到達,工作流程可能會永遠停留在佇列中。
建置完成後,打開你複製的 Space。你會看到一個顯示「Required Space secrets」的部分,你現在可以忽略它。登陸頁面應該會顯示你在下一步中需要的 GitHub App webhook 網址。它看起來會像這樣:
`https://YOUR-HF-NAMESPACE-jobs-actions-dispatcher.hf.space/webhook`
CLI 設定
如果你更喜歡使用代理或 CLI 工作流程來設定派遣器 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
接下來,從派遣器 Space 本身創建並安裝 GitHub App。這個 App 需要權限來監聽排入佇列的工作流程任務,並創建臨時的自託管執行器註冊權杖。
網頁設定
打開你複製的派遣器 Space:
`https://YOUR-HF-NAMESPACE-jobs-actions-dispatcher.hf.space`
在設定表單中,輸入你的 GitHub 儲存庫,其 CI 應該在 HF Jobs 上運行:
`YOUR-GITHUB-ORG/YOUR-REPO`
然後點擊按鈕創建 GitHub App。GitHub 會要求你為 App 選擇一個名稱;名稱可以是任何東西,只要它在你的 GitHub 帳戶或組織中可用即可。提交後,最後的畫面會確切告訴你如何使用 `hf CLI` 將 App 憑證上傳到派遣器 Space。
重要提示:你需要提供一個擁有啟動 Jobs 權限的 Hugging Face 權杖,該權杖應對應你的個人帳戶或應計費的組織。此權杖應儲存為派遣器 Space 中的 `HF_TOKEN` 機密。
最後,你將在你在 Space 中輸入的相同 GitHub 儲存庫上安裝 App。在 Trackio 的設定中,我們將其安裝在 `gradio-app/trackio` 上。
代理輔助設定
GitHub App 清單流程仍然是基於瀏覽器的,但代理可以遵循相同的 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:最終派遣器設定
此時,派遣器 Space 應該已配置完成。GitHub App 設定流程生成了上傳 App 憑證、webhook 機密和 Hugging Face 權杖到 Space 的命令。
預設情況下,HF Jobs 會在與派遣器 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 中設定的權杖應該與此命名空間相對應。
步驟 4:更改 runs-on
實際的工作流程變更很小。取代:
`runs-on: ubuntu-latest`
使用派遣器處理的其中一個標籤:
`runs-on: hf-jobs-cpu-upgrade`
對於 GPU 測試,請使用 GPU 標籤:
`runs-on: hf-jobs-t4-small`
對於任何你想在 HF Jobs 上運行的 GitHub Action,只需這 1 行更改即可!
步驟 5:測試
要從 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`
要從 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 的數據:
| 執行器設定 | 運行時間 | 與 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 上運行,並在 45 秒內通過,以 t4-small 的費率計算,成本不到一美分。
CPU 結果也令人鼓舞。使用正確的映像檔,Linux 測試任務比 GitHub 代管的基準更快。這表明 HF Jobs 可以成為一個實用的 CI 後端,特別是對於需要自訂映像檔或加速器的機器學習專案。
日誌是另一個驚喜。GitHub Actions 日誌很有用,但對於大型日誌來說,網頁使用者介面可能會很笨重。HF Jobs 日誌很容易從 CLI 獲取:
`hf jobs logs <job_id> > logs.txt`
這使得它們易於使用本地工具或編碼代理進行檢查。在我們的橋接器中,我們還將 GitHub Actions 任務日誌鏡像到 HF Job 日誌中,因此兩個系統都有足夠的資訊來調試運行。
最後,儘管 Trackio 的 CI 不需要它們,HF Jobs 也支援掛載儲存卷,如果你需要在 CI 中快速從 Hugging Face 加載資料集或模型,這會非常有幫助。
希望這能為你提供嘗試 HF Jobs 來運行 GitHub Actions 所需的一切!
