記事一覧に戻る

Abubakar Abid's avatar

GitHubリポジトリをお持ちで、GitHub Actionsを有効にしている場合、CIにはGitHub-hostedランナーを利用していることが多いでしょう。これは多くのプロジェクトでデフォルトとなっています。理由はシンプルだからです。ワークフローを追加し、runs-on: ubuntu-latestと記述するだけで、GitHubがマシンを提供してくれます。

このデフォルトは便利ですが、制限もあります。GitHub Actionsはメンテナンスで遅くなったり停止したりすることがあり、ホストされるマシンは汎用的で、GPUへのアクセスはほとんどのオープンソースプロジェクトにとって簡単に利用できるものではありません。Trackioでは、これらの制限が問題になりました。基本的なユニットテストやフロントエンドチェックのための信頼性の高いCPU CIと、実際のCUDAハードウェアで実行する必要があるテストのためのGPU CIの両方が必要でした。

そこで代替案を構築しました。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 HubやHugging Face SpaceからのDockerイメージ
  • CPUやt4-smallh200 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ジョブはすでにコマンド駆動型で、クリーンな環境で実行され、適切なハードウェアを正確に選択することで恩恵を受けます。MLライブラリでは、GPUのケースが特に魅力的です。常に稼働する自前のランナーを維持することなく、実際のGPUハードウェア上でテストスイートを実行できます。

重要なステップは、GitHub ActionsをHF Jobsに接続することです。以下で説明します。

アーキテクチャ

このセットアップでは、huggingface/jobs-actionsを作成しました。これはGitHub Actionsのジョブを、HF Job内で実行される一時的なセルフホスト型ランナーに変換する小さなブリッジです。

完全なフローは以下のようになります:

  1. プルリクエストがGitHub Actionsワークフローをトリガーします。
  2. GitHubは、runs-onラベルが利用できないジョブ(例:hf-jobs-cpu-upgradehf-jobs-t4-small)をキューに入れ、GitHub Appを通じてディスパッチャに署名付きのworkflow_job.queued webhookを送信します。
  3. ディスパッチャSpaceはwebhookを検証し、hf-jobs-*ラベルを確認し、短期間のGitHubランナー登録トークンを発行し、一致するハードウェアでHF Jobを開始します。
  4. HF Jobは一時的なGitHub Actionsランナーを起動し、そのワンショットトークンを使用してリポジトリに登録します。
  5. GitHubは保留中のワークフロージョブをそのランナーに割り当て、ランナーはCIジョブを実行し、GitHubにステータスを報告して終了します。

GitHubの観点からは、これは単なるセルフホスト型ランナーです。Hugging Faceの観点からは、リポジトリのGitHub Actionsからワークフローステップを実行するコンテナを起動するJobに過ぎません。

ステップ1:ディスパッチャSpaceを複製する

最初に必要なのはディスパッチャです。これはGitHubのworkflow_job webhookイベントを受信し、応答してHF Jobsを起動する小さなDocker Spaceです。

GitHub Appにはwebhook URLが必要で、そのURLはSpaceから提供されるため、まずこれを作成します。このSpaceは、あなた自身の名前空間または書き込みアクセス権を持つHugging Face組織の下に置く必要があります。

Webセットアップ

huggingface/jobs-actions-dispatcherにアクセスし、このSpaceを複製をクリックします。

image

以下を使用します:

Owner: あなたのHFユーザーまたは組織
Name: jobs-actions-dispatcher
Hardware: cpu-upgrade

実際のCIではcpu-upgradeを使用し、ディスパッチャがGitHub webhookに対して常に利用可能にします。cpu-basicはテストには適していますが、おそらく動作しますが、非アクティブになるとスリープする可能性があります。GitHubのwebhookが起動中に到着すると、ワークフローは永久にキューに留まる可能性があります。

ビルド後、複製したSpaceを開きます。「Required Space secrets」というセクションが表示されますが、今は無視できます。ランディングページには、次のステップで必要なGitHub App webhook URLが表示されます。以下のような形式です:

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には、キューに入れられたワークフロージョブをリッスンし、一時的なセルフホスト型ランナー登録トークンを作成する権限が必要です。

Webセットアップ

複製したディスパッチャ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の認証情報をディスパッチャSpaceにアップロードする方法が正確に表示されます。

重要な注意:Jobの起動権限を持つHugging Faceトークンを提供する必要があります。これは個人アカウントまたはJobの請求先となる組織に対応するものです。このトークンは、ディスパッチャ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にアップロードするコマンドを生成しました。

image

デフォルトでは、HF JobsはディスパッチャSpaceと同じ名前空間の下で起動されます。異なるHugging Faceユーザーまたは組織にJobを請求したい場合は、オプションで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-hosted GPUのベースラインなし

最大の利点はGPU CIでした。TrackioのGPUチェックはHF Jobs上で実行され、45sで合格し、その期間のt4-small料金で1セント未満のコストでした。

CPUの結果も励みになりました。適切なイメージを使用することで、LinuxテストジョブはGitHub-hostedベースラインよりも高速でした。これは、HF Jobsがカスタムイメージやアクセラレータを必要とするMLプロジェクトにとって、実用的なCIバックエンドになり得ることを示唆しています。

ログも嬉しい驚きでした。GitHub Actionsのログは有用ですが、Web UIは大規模なログには重くなることがあります。HF JobsのログはCLIから簡単に取得できます:

hf jobs logs <job_id> > logs.txt

これにより、ローカルツールやコーディングエージェントで簡単に検査できます。私たちのブリッジでは、GitHub ActionsジョブログをHF Jobログにミラーリングしたため、どちらのシステムも実行のデバッグに十分な情報を得ることができました。

最後に、TrackioのCIには必要ありませんでしたが、HF Jobsはボリュームのマウントもサポートしており、CIの一部としてHugging Faceからデータセットやモデルをすばやくロードする必要がある場合に非常に役立ちます。

これで、GitHub Actionsを実行するためにHF Jobsを試すために必要なすべてが揃ったことを願っています!