TRL documentation
Training with Jobs
Training with Jobs
Hugging Face Jobs lets you run training scripts on fully managed infrastructure—no need to manage GPUs or local environment setup.
In this guide, you’ll learn how to:
- Use TRL Jobs to easily run pre-optimized TRL training
- Run any TRL training script with uv scripts
For general details about Hugging Face Jobs (hardware selection, job monitoring, etc.), see the Jobs documentation.
Requirements
- A Hugging Face account with a positive credit balance. Jobs is pay-as-you-go—you only pay for the seconds you use.
- Logged in to the Hugging Face Hub (
hf auth login)
Using TRL Jobs
TRL Jobs is a high-level wrapper around Hugging Face Jobs and TRL that streamlines training. It provides optimized default configurations so you can start quickly without manually tuning parameters.
Example:
pip install trl-jobs trl-jobs sft --model_name Qwen/Qwen3-0.6B --dataset_name trl-lib/Capybara
TRL Jobs supports everything covered in this guide, with additional optimizations to simplify workflows.
Using uv Scripts
For more control, you can run Hugging Face Jobs directly with your own scripts, using uv scripts.
Create a Python script (e.g., train.py) containing your training code:
from datasets import load_dataset
from trl import SFTTrainer
dataset = load_dataset("trl-lib/Capybara", split="train")
trainer = SFTTrainer(
model="Qwen/Qwen2.5-0.5B",
train_dataset=dataset,
)
trainer.train()
trainer.push_to_hub("Qwen2.5-0.5B-SFT")Launch the job using either the hf jobs CLI or the Python API:
hf jobs uv run \
--flavor a100-large \
--with trl \
--secrets HF_TOKEN \
train.pyTo run successfully, the script needs:
- TRL installed: Use the
--with trlflag or thedependenciesargument. uv installs these dependencies automatically before running the script. - An authentication token: Required to push the trained model (or perform other authenticated operations). Provide it with the
--secrets HF_TOKENflag or thesecretsargument.
When training with Jobs, be sure to:
- Set a sufficient timeout. Jobs time out after 30 minutes by default. If your job exceeds the timeout, it will fail and all progress will be lost. See Setting a custom timeout.
- Push the model to the Hub. The Jobs environment is ephemeral—files are deleted when the job ends. If you don’t push the model, it will be lost.
You can also run a script directly from a URL:
hf jobs uv run \
--flavor a100-large \
--with trl \
--secrets HF_TOKEN \
"https://gist.githubusercontent.com/qgallouedec/eb6a7d20bd7d56f9c440c3c8c56d2307/raw/69fd78a179e19af115e4a54a1cdedd2a6c237f2f/train.py"To make a script self-contained, declare dependencies at the top:
# /// script
# dependencies = [
# "trl",
# "peft",
# ]
# ///
from datasets import load_dataset
from peft import LoraConfig
from trl import SFTTrainer
dataset = load_dataset("trl-lib/Capybara", split="train")
trainer = SFTTrainer(
model="Qwen/Qwen2.5-0.5B",
train_dataset=dataset,
peft_config=LoraConfig(),
)
trainer.train()
trainer.push_to_hub("Qwen2.5-0.5B-SFT")You can then run the script without specifying dependencies:
hf jobs uv run \
--flavor a100-large \
--secrets HF_TOKEN \
train.pyTRL training scripts are fully uv-compatible, so you can run a complete training workflow directly on Jobs. You can customize training with standard script arguments plus hardware and secrets:
hf jobs uv run \
--flavor a100-large \
--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_hubEvery .py example in the Examples Index declares its dependencies in a # /// script header, so it can be submitted to Jobs the same way (notebook-only examples cannot).
Docker Images
Jobs runs your script with uv, which installs the dependencies declared in its # /// script header into a fresh environment. The TRL your script imports therefore comes from that header, not from the image, and the examples above need no --image at all.
A Docker image with TRL preinstalled is available at huggingface/trl. Passing it to hf jobs uv run gives the job the image’s system layer, such as its CUDA toolchain, which matters for dependencies that compile against it:
hf jobs uv run \
--flavor a100-large \
--secrets HF_TOKEN \
--image huggingface/trl \
train.pyTo run the TRL that is installed in the image, use hf jobs run instead. It runs a command in the image directly, with no script header to resolve, so the image’s own TRL is what executes. The -- separates the command from the Jobs options, which is needed whenever the command itself takes options:
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-SFTThe image is published under three kinds of tag:
| Tag | Contents |
|---|---|
X.Y.Z | The TRL release of that version, built when that version is released |
latest | The most recent release |
dev | The main branch, rebuilt on every merge |
Use dev to run the development version, which is useful for trying a fix that has landed on main but is not released yet:
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-SFTTags only select what is installed in the image, so they matter for hf jobs run. With hf jobs uv run the version comes from the script header instead, and the tag makes no difference to which TRL is imported.
Combining the two, so that uv resolves the script header while some imports still come from the image, needs extra flags. See Reuse the image’s packages and add dependencies with UV for that form and the paths it requires.
Jobs runs on a Docker image from Hugging Face Spaces or Docker Hub, so you can also specify any custom image:
hf jobs uv run \
--flavor a100-large \
--secrets HF_TOKEN \
--image <docker-image> \
train.py