# Jobsでのトレーニング

[![model badge](https://img.shields.io/badge/All_models-HF_Jobs-blue)](https://huggingface.co/models?other=hf_jobs,trl)

[Hugging Face Jobs](https://huggingface.co/docs/hub/jobs)は、Hugging FaceのGPU上でトレーニングを実行します。各実行ごとにハードウェアを選択し、実行された秒数分のみ課金されます。`--push_to_hub`を使用すると、トレーニングが完了した時点でモデルがHubにアップロードされます。

このガイドでは、次のことを学びます。

- 1つのコマンドでTRLの学習スクリプトを起動します
- ランを追跡して、その損失曲線を確認します
- …のファイルにハードウェア設定を指定して、独自のスクリプトを実行します
- チェックポイントを保存し、中断された実行を再開する
- 複数のGPUで学習

Jobsの一般的な仕組み（ハードウェアや料金体系を含む）については、[Jobsのドキュメント](https://huggingface.co/docs/hub/jobs)を参照してください。

## 要件

- 正の[クレジット残高](https://huggingface.co/settings/billing)を持つ Hugging Face アカウント。ジョブは従量課金制です。使用した秒数分のみ課金されます。
- Hugging Face Hub にログイン済み(`hf auth login`)

## 初回の実行

このコマンドは、TRL SFTスクリプトを使用して[Capybara](https://huggingface.co/datasets/trl-lib/Capybara)チャットデータセットで[Qwen2-0.5B-Instruct](https://huggingface.co/Qwen/Qwen2-0.5B-Instruct)をファインチューニングし、その後モデルをあなたのアカウントにプッシュします:

```bash
hf jobs uv run \
    --flavor a10g-small \
    --timeout 30m \
    --secrets HF_TOKEN \
    -- \
    https://raw.githubusercontent.com/huggingface/trl/refs/heads/main/trl/scripts/sft.py \
    --model_name_or_path Qwen/Qwen2-0.5B-Instruct \
    --dataset_name trl-lib/Capybara \
    --max_steps 100 \
    --output_dir Qwen2-0.5B-SFT \
    --push_to_hub
```

```python
from huggingface_hub import run_uv_job

run_uv_job(
    "https://raw.githubusercontent.com/huggingface/trl/refs/heads/main/trl/scripts/sft.py",
    flavor="a10g-small",
    timeout="30m",
    secrets={"HF_TOKEN": "hf_..."},
    script_args=[
        "--model_name_or_path", "Qwen/Qwen2-0.5B-Instruct",
        "--dataset_name", "trl-lib/Capybara",
        "--max_steps", "100",
        "--output_dir", "Qwen2-0.5B-SFT",
        "--push_to_hub",
    ],
)
```

It takes a few minutes and costs well under $1 on `a10g-small`. The options before `--` are for Jobs: the hardware, a time limit and the token used to push the model. `--secrets HF_TOKEN` sends the token you logged in with. In Python, pass the token itself. The arguments after the script URL go to the script. `hf jobs uv run` runs a Python script with [uv](https://docs.astral.sh/uv/guides/scripts/). `sft.py` lists its dependencies in a header at the top of the file, so Jobs installs TRL before the script starts. The Job stops when the script exits, and billing stops with it.

`--max_steps 100` はこの最初のランを短く保ちます。フルランではこれを削除してください。3エポック（スクリプトのデフォルト）は `a10g-small` で数時間かかるため、`--timeout` をそれに合わせて引き上げてください。例えば `--timeout 3h` のようにします。Jobs はタイムアウトに達するとランを停止します。デフォルトは30分です。`a100-large` のようなより大きな GPU では、より早く完了します。フレーバーとその価格については [Hardware](https://huggingface.co/docs/hub/jobs-pricing) を参照してください。

## 実行を追跡する

`hf jobs uv run` はログをストリーミング表示し、実行が終了するまでターミナルを保持します。Ctrl+C はログストリームのみを停止し、Job 自体は実行を続けます。`--detach` を追加すると、すぐに Job ID が返され、その後:

```bash
hf jobs logs -f <job_id>   # stream the logs
hf jobs ps                 # list your running Jobs
hf jobs inspect <job_id>   # status, and the error message if it failed
hf jobs cancel <job_id>    # stop it
```

詳細は、[ジョブの管理](https://huggingface.co/docs/hub/jobs-manage)を参照してください。

ロスカーブについては、TRLは[Trackio](trackio_integration)にログを出力します。ダッシュボード用のSpaceに名前を付けるには、`--`の前に`--env TRACKIO_SPACE_ID=<your-username>/trackio`を追加し、スクリプトURLの後に`--report_to trackio`を追加します。Spaceとメトリクスのバケットが存在しない場合、Trackioがそれらを作成します。どちらもデフォルトで公開されています。Transformersがサポートする他のトラッカーも使用できます。Weights & Biasesを使用するには、`--`の前に`--with wandb --secrets WANDB_API_KEY`を追加し、スクリプトURLの後に`--report_to wandb`を追加します。`--secrets WANDB_API_KEY`は、ローカル環境の`WANDB_API_KEY`から値を読み取ります。他の渡し方については、[環境変数とシークレット](https://huggingface.co/docs/hub/jobs-configuration#user-defined-environment-variables)を参照してください。

## 独自のスクリプトを実行する

トレーニングコードをPythonファイル（例: `train.py`）に記述します。ファイルの先頭に、TRLのスクリプトと同様に[スクリプトヘッダー](https://docs.astral.sh/uv/guides/scripts/#declaring-script-dependencies)として依存関係を列挙します。ジョブはスクリプトの開始前にこれらをインストールします:

```python
# /// script
# dependencies = [
#     "trl",
#     "peft",
# ]
# ///

from datasets import load_dataset
from peft import LoraConfig
from trl import SFTConfig, SFTTrainer

dataset = load_dataset("trl-lib/Capybara", split="train")

trainer = SFTTrainer(
    model="Qwen/Qwen2.5-0.5B",
    train_dataset=dataset,
    peft_config=LoraConfig(),
    args=SFTConfig(output_dir="Qwen2.5-0.5B-SFT", max_steps=100),
)
trainer.train()
trainer.push_to_hub()
```

次に、[`hf jobs` CLI](https://huggingface.co/docs/huggingface_hub/guides/cli#hf-jobs)またはPython APIで起動します:

```bash
hf jobs uv run \
    --flavor a10g-small \
    --timeout 30m \
    --secrets HF_TOKEN \
    train.py
```

```python
from huggingface_hub import run_uv_job

run_uv_job(
    "train.py",
    flavor="a10g-small",
    timeout="30m",
    secrets={"HF_TOKEN": "hf_..."},
)
```

ヘッダーのないスクリプトの場合、`--with` をパッケージごとに1回ずつ指定して、起動時に依存関係を列挙します: `--with trl --with peft` (Python では `dependencies=["trl", "peft"]`)。スクリプトは URL でもよく、GitHub raw リンク、Gist、またはパブリックな Hub リポジトリ内のファイルなどが該当します。

起動設定はスクリプト内に記述することもできます。ヘッダーの`[tool.hf-jobs]`テーブルで、ハードウェア、タイムアウト、シークレットを設定します:

```python
# /// script
# dependencies = [
#     "trl",
#     "peft",
# ]
#
# [tool.hf-jobs]
# flavor = "a10g-small"
# timeout = "30m"
# secrets = ["HF_TOKEN"]
# ///
```

`hf jobs uv run train.py` はオプションを必要としません。また、渡したオプションはスクリプトの内容を上書きします。スクリプトには実行に必要な情報がすべて含まれているため、GPU やタイムアウトを覚えておくことなく、スクリプトを共有したり、後で実行したりできます。`hf jobs uv run --dry-run train.py` は解決された設定を表示し、スクリプト由来の値にマークを付けます。このテーブルは `hf` CLI によってのみ読み取られ、`run_uv_job()` では無視されます。[スクリプト内で起動設定を定義する](https://huggingface.co/docs/hub/jobs-configuration#define-the-launch-config-in-the-script)を参照してください。

## 任意のTRLスクリプトを実行する

同じパターンは、すべてのTRLトレーナーのスクリプト（SFT、DPO、GRPO、報酬モデリングなど）および[Examples Index](example_overview#index)のスタンドアロンな`.py`例に適用されます。各スクリプトは、スクリプトのヘッダーに依存関係を宣言しています。隣接する他のファイルを読み込む例では、そのフォルダをJobにマウントする必要があります。[Local directories](https://huggingface.co/docs/hub/jobs-configuration#local-directories)を参照してください。ノートブック専用の例は、この方法では提出できません。スクリプトの引数は、ローカルでスクリプトを実行する場合と同じです。

## チェックポイントの保持

Jobが終了すると、タイムアウトに達した場合や失敗した場合を含む、そのJobのディスクは削除されます。長時間の実行では、チェックポイントをJobの外に保存し、Jobの終了後も保持されるようにしてください。

最もシンプルな方法は、チェックポイントが保存されるたびに、そのまま出力モデルのリポジトリにプッシュすることです：

```bash
hf jobs uv run \
    --flavor a10g-small \
    --timeout 3h \
    --secrets HF_TOKEN \
    -- \
    https://raw.githubusercontent.com/huggingface/trl/refs/heads/main/trl/scripts/sft.py \
    --model_name_or_path Qwen/Qwen2-0.5B-Instruct \
    --dataset_name trl-lib/Capybara \
    --output_dir Qwen2-0.5B-SFT \
    --push_to_hub \
    --save_steps 500 \
    --hub_strategy checkpoint
```

```python
from huggingface_hub import run_uv_job

run_uv_job(
    "https://raw.githubusercontent.com/huggingface/trl/refs/heads/main/trl/scripts/sft.py",
    flavor="a10g-small",
    timeout="3h",
    secrets={"HF_TOKEN": "hf_..."},
    script_args=[
        "--model_name_or_path", "Qwen/Qwen2-0.5B-Instruct",
        "--dataset_name", "trl-lib/Capybara",
        "--output_dir", "Qwen2-0.5B-SFT",
        "--push_to_hub",
        "--save_steps", "500",
        "--hub_strategy", "checkpoint",
    ],
)
```

`--hub_strategy checkpoint` を使用すると、オプティマイザーの状態を含む最新のチェックポイントが、リポジトリの `last-checkpoint` フォルダに保存されます。中断された実行を再開するには、リポジトリを新しい Job にマウントし、そのフォルダから再開します。スクリプトの URL の前に `--volume hf://<your-username>/Qwen2-0.5B-SFT:/previous` を、`--` の後に `--resume_from_checkpoint /previous/last-checkpoint` を追加して、同じコマンドを起動します。

モデルリポジトリの外に複数のチェックポイントを保持するには、代わりに[Storage Bucket](https://huggingface.co/docs/hub/storage-buckets)に書き出します。`hf buckets create <your-username>/checkpoints --private`でバケットを作成し、Jobにマウントして`--output_dir`をそこに指定します:

```bash
hf jobs uv run \
    --flavor a10g-small \
    --timeout 3h \
    --secrets HF_TOKEN \
    --volume hf://buckets/<your-username>/checkpoints:/checkpoints \
    -- \
    https://raw.githubusercontent.com/huggingface/trl/refs/heads/main/trl/scripts/sft.py \
    --model_name_or_path Qwen/Qwen2-0.5B-Instruct \
    --dataset_name trl-lib/Capybara \
    --output_dir /checkpoints/Qwen2-0.5B-SFT \
    --save_steps 500
```

```python
from huggingface_hub import Volume, run_uv_job

run_uv_job(
    "https://raw.githubusercontent.com/huggingface/trl/refs/heads/main/trl/scripts/sft.py",
    flavor="a10g-small",
    timeout="3h",
    secrets={"HF_TOKEN": "hf_..."},
    volumes=[Volume(type="bucket", source="<your-username>/checkpoints", mount_path="/checkpoints")],
    script_args=[
        "--model_name_or_path", "Qwen/Qwen2-0.5B-Instruct",
        "--dataset_name", "trl-lib/Capybara",
        "--output_dir", "/checkpoints/Qwen2-0.5B-SFT",
        "--save_steps", "500",
    ],
)
```

中断された実行を再開するには、`--resume_from_checkpoint /checkpoints/Qwen2-0.5B-SFT/checkpoint-<step>` を付けて同じコマンドを再度実行してください。詳細については、[処理しながらバケットに書き込む](https://huggingface.co/docs/hub/jobs-training#after-it-ends) およびマウントオプションについては [Volumes](https://huggingface.co/docs/hub/jobs-configuration#volumes) を参照してください。

> [!TIP]
> 各チェックポイントは、モデルとオプティマイザーの状態を保持しており、そのサイズはモデルのサイズの何倍にもなります。最新のもののみを保持するには、`--save_total_limit 2`を追加してください。`--push_to_hub`も渡す場合は、`--hub_model_id`を設定するか、リポジトリ名を出力パスの最後の部分に設定してください。

## 複数のGPU

複数のGPUを使用するフレーバーにより、実行時間を短縮できます。これには、`hf jobs run`を使用します。これはスクリプトではなくDockerイメージ内でコマンドを実行するもので、TRLとAccelerateがインストール済みの[`huggingface/trl`](https://hub.docker.com/r/huggingface/trl)イメージを使用します。その後、GPUごとに1つのプロセスを開始します。この方法は、TRLのスクリプトにも、ご自身の学習コードにも適用できます。

### TRLスクリプトの高速化

このガイドの冒頭で実行したSFTを、4つのGPUで:

```bash
hf jobs run \
    --flavor l4x4 \
    --timeout 30m \
    --secrets HF_TOKEN \
    huggingface/trl \
    -- \
    trl sft --nproc_per_node 4 \
    --model_name_or_path Qwen/Qwen2-0.5B-Instruct \
    --dataset_name trl-lib/Capybara \
    --max_steps 100 \
    --output_dir Qwen2-0.5B-SFT \
    --push_to_hub
```

```python
from huggingface_hub import run_job

run_job(
    image="huggingface/trl",
    command=[
        "trl", "sft", "--nproc_per_node", "4",
        "--model_name_or_path", "Qwen/Qwen2-0.5B-Instruct",
        "--dataset_name", "trl-lib/Capybara",
        "--max_steps", "100",
        "--output_dir", "Qwen2-0.5B-SFT",
        "--push_to_hub",
    ],
    flavor="l4x4",
    timeout="30m",
    secrets={"HF_TOKEN": "hf_..."},
)
```

[`trl` CLI](clis) は `torchrun` に `--nproc_per_node` を渡します。この値は、flavor の GPU 数、ここでは 4 つの L4 に設定します。各プロセスが独自のバッチを処理するため、実効バッチサイズはシングル GPU 実行時の 4 倍になります。この実行には数分かかります。`--max_steps` を指定しないと、3 エポック全体で約 1 時間かかるため、`--timeout` を例えば `2h` に引き上げてください。

### ご自身のスクリプト

TRLのスクリプトに限定されるわけではありません。`torchrun`でローカル実行できる学習コードは、イメージに必要なパッケージが含まれている限り、Jobsでも同じように実行できます。例えば、独自の報酬関数を含むGRPOスクリプトを`train_grpo.py`としてフォルダに保存し、そのフォルダをJobにマウントします。Jobsはフォルダをプライベートバケットにアップロードし、読み取り専用でマウントします:

```bash
hf jobs run \
    --flavor l4x4 \
    --timeout 30m \
    --secrets HF_TOKEN \
    --volume ./my-project:/code \
    huggingface/trl \
    -- \
    torchrun --nproc_per_node 4 /code/train_grpo.py
```

```python
from huggingface_hub import run_job, sync_job_volume

code = sync_job_volume("./my-project", "/code")
run_job(
    image="huggingface/trl",
    command=["torchrun", "--nproc_per_node", "4", "/code/train_grpo.py"],
    flavor="l4x4",
    timeout="30m",
    secrets={"HF_TOKEN": "hf_..."},
    volumes=[code],
)
```

スクリプトはイメージにTRLがインストールされた状態で実行されるため、スクリプトヘッダーは不要です。`GRPOTrainer`はデフォルトでtransformersを使用して補完を生成するため、vLLMサーバーなしで単一のJobで実行されます。より高速な生成については、[vLLM Integration](vllm_integration)を参照してください。次のセクションでは、`hf jobs run`がイメージを使用する方法を説明します。

## Dockerイメージ

Jobs は `uv` を使用してスクリプトを実行します。これにより、スクリプトの `# /// script` ヘッダーに宣言された依存関係が新しい環境にインストールされます。したがって、スクリプトがインポートする TRL はイメージではなくそのヘッダーから取得され、上記の `hf jobs uv run` の例には `--image` は一切不要です。

TRLがプリインストールされたDockerイメージは[huggingface/trl](https://hub.docker.com/r/huggingface/trl)で利用できます。`hf jobs uv run`にこれを渡すと、ジョブはイメージのシステムレイヤー、例えばCUDAツールチェーンなどを取得します。これに対してコンパイルされる依存関係がある場合に重要になります。

```bash
hf jobs uv run \
    --flavor a100-large \
    --secrets HF_TOKEN \
    --image huggingface/trl \
    train.py
```

```python
from huggingface_hub import run_uv_job

run_uv_job(
    "train.py",
    flavor="a100-large",
    secrets={"HF_TOKEN": "hf_..."},
    image="huggingface/trl",
)
```

イメージにインストールされているTRLを実行するには、代わりに`hf jobs run`を使用してください。これはスクリプトヘッダーの解決なしに、イメージ内でコマンドを直接実行するため、実行されるのはイメージ自身のTRLです。`--`はコマンドとJobsのオプションを区切るもので、コマンド自体がオプションを取る場合は常に必要です:

```bash
hf jobs run \
    --flavor a100-large \
    --secrets HF_TOKEN \
    huggingface/trl \
    -- \
    trl sft --model_name_or_path Qwen/Qwen2-0.5B-Instruct --dataset_name trl-lib/Capybara --output_dir Qwen2-0.5B-SFT
```

```python
from huggingface_hub import run_job

run_job(
    image="huggingface/trl",
    command=[
        "trl", "sft",
        "--model_name_or_path", "Qwen/Qwen2-0.5B-Instruct",
        "--dataset_name", "trl-lib/Capybara",
        "--output_dir", "Qwen2-0.5B-SFT",
    ],
    flavor="a100-large",
    secrets={"HF_TOKEN": "hf_..."},
)
```

イメージは3種類のタグで公開されます:

| タグ | 目次 |
| --- | --- |
| `X.Y.Z` | そのバージョンのリリース時にビルドされた、そのバージョンのTRLリリース |
| `latest` | 最新のリリース |
| `dev` | すべてのマージ時に再構築される`main`ブランチ |

開発版を実行するには`dev`を使用します。`main`にマージされたがまだリリースされていない修正を試す際に便利です。

```bash
hf jobs run \
    --flavor a100-large \
    --secrets HF_TOKEN \
    huggingface/trl:dev \
    -- \
    trl sft --model_name_or_path Qwen/Qwen2-0.5B-Instruct --dataset_name trl-lib/Capybara --output_dir Qwen2-0.5B-SFT
```

```python
from huggingface_hub import run_job

run_job(
    image="huggingface/trl:dev",
    command=[
        "trl", "sft",
        "--model_name_or_path", "Qwen/Qwen2-0.5B-Instruct",
        "--dataset_name", "trl-lib/Capybara",
        "--output_dir", "Qwen2-0.5B-SFT",
    ],
    flavor="a100-large",
    secrets={"HF_TOKEN": "hf_..."},
)
```

タグはイメージにインストールされる内容のみを選択するため、`hf jobs run` には影響します。一方、`hf jobs uv run` ではバージョンはスクリプトのヘッダーから取得されるため、どの TRL がインポートされるかはタグによって変わりません。

両方を組み合わせ、`uv`がスクリプトヘッダーを解決する一方で一部のインポートがイメージから提供されるようにするには、追加のフラグが必要です。その形式と必要なパスについては、[イメージのパッケージを再利用し、UVで依存関係を追加する](https://huggingface.co/docs/hub/jobs-images#reuse-the-images-packages-and-add-dependencies-with-uv)を参照してください。

Jobs は Hugging Face Spaces または Docker Hub の Docker イメージで実行されるため、カスタムイメージを指定することもできます:

```bash
hf jobs uv run \
    --flavor a100-large \
    --secrets HF_TOKEN \
    --image <docker-image> \
    train.py
```

```python
from huggingface_hub import run_uv_job

run_uv_job(
    "train.py",
    flavor="a100-large",
    secrets={"HF_TOKEN": "hf_..."},
    image="<docker-image>",
)
```

> [!NOTE]
> [TRL Jobs](https://github.com/huggingface/trl-jobs)ラッパーは、一部のモデルにプリセットされた設定でJobs上でTRLスクリプトを起動します。例えば、`trl-jobs sft --model_name Qwen/Qwen3-0.6B --dataset_name trl-lib/Capybara`のように使用できます。

