TRL documentation
Обучение с помощью Jobs
Обучение с помощью Jobs
Hugging Face Jobs выполняет обучение на GPU Hugging Face. Вы выбираете оборудование для каждого запуска и платите только за секунды его работы. С флагом --push_to_hub обученная модель загружается в Hub по завершении.
В этом руководстве вы узнаете, как:
- Запустите скрипт обучения TRL одной командой
- Следите за запуском и наблюдайте за кривыми потерь
- Запустите собственный скрипт, в котором параметры оборудования указаны в файле
- Сохранение контрольных точек и возобновление прерванного запуска
- Обучение на нескольких GPU
Общую информацию о работе Jobs, включая оборудование и цены, см. в документации по Jobs.
Требования
- Аккаунт Hugging Face с положительным кредитным балансом. Работа с Jobs оплачивается по факту использования: вы платите только за секунды, которые используете.
- Выполнен вход в Hugging Face Hub (
hf auth login)
Первый запуск
Эта команда выполняет дообучение Qwen2-0.5B-Instruct на чат-датасете Capybara с помощью скрипта SFT из TRL, а затем загружает модель на ваш аккаунт:
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_hubfrom 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",
],
)Это занимает несколько минут и обходится значительно дешевле $1 на a10g-small. Опции перед -- относятся к Jobs: это оборудование, лимит времени и токен, используемый для загрузки модели. --secrets HF_TOKEN отправляет токен, с которым вы вошли в систему. В Python передайте сам токен. Аргументы после URL скрипта передаются в скрипт. hf jobs uv run запускает Python-скрипт с помощью uv. В sft.py зависимости перечислены в заголовке в начале файла, поэтому Jobs устанавливает TRL до запуска скрипта. Job останавливается, когда скрипт завершает работу, и тарификация прекращается вместе с ним.
--max_steps 100 сокращает время первого запуска. Уберите этот параметр для полного прогона: три эпохи, значение по умолчанию в скрипте, занимают несколько часов на a10g-small, поэтому увеличьте --timeout соответственно, например, --timeout 3h. Jobs останавливает выполнение, когда достигается тайм-аут, который по умолчанию составляет 30 минут. Более мощный GPU, например a100-large, завершает работу быстрее. См. Hardware для списка вариантов и их цен.
Следите за запуском
hf jobs uv run транслирует логи и удерживает терминал до завершения выполнения. Ctrl+C останавливает только поток логов: Job продолжает работать. Добавьте --detach, чтобы сразу получить ID Job, затем:
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Подробнее см. в разделе Управление заданиями.
Для кривых потерь TRL записывает данные в Trackio. Добавьте --env TRACKIO_SPACE_ID=<your-username>/trackio перед --, чтобы указать имя Space для панели управления, и --report_to trackio после URL скрипта. Trackio создаст Space и бакет для метрик, если они еще не существуют. По умолчанию оба являются публичными. Также поддерживаются другие трекеры, доступные в Transformers. Для Weights & Biases добавьте --with wandb --secrets WANDB_API_KEY перед -- и --report_to wandb после URL скрипта. --secrets WANDB_API_KEY считывает значение из переменной окружения WANDB_API_KEY в вашей локальной среде. О других способах передачи секретов см. в разделе переменные окружения и секреты.
Запустите собственный скрипт
Напишите код обучения в файле Python (например, train.py). Перечислите его зависимости в начале файла, в шапке скрипта, так же, как это делают скрипты TRL. Jobs устанавливает их перед запуском скрипта:
# /// 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()Затем запустите его с помощью CLI hf jobs или Python API:
hf jobs uv run \
--flavor a10g-small \
--timeout 30m \
--secrets HF_TOKEN \
train.pyfrom huggingface_hub import run_uv_job
run_uv_job(
"train.py",
flavor="a10g-small",
timeout="30m",
secrets={"HF_TOKEN": "hf_..."},
)Для скрипта без заголовка перечислите зависимости при запуске с помощью --with, указывая каждый пакет отдельно: --with trl --with peft (в Python это dependencies=["trl", "peft"]). Скриптом может быть и URL, например, прямая ссылка на GitHub, Gist или файл в публичном репозитории Hub.
Настройки запуска также можно указать в самом скрипте. Таблица [tool.hf-jobs] в заголовке задаёт параметры оборудования, тайм-аут и секреты:
# /// 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 показывает разрешённые настройки и отмечает значения, которые берутся из скрипта. Таблицу читает только CLI hf: run_uv_job() её игнорирует. См. Определение конфигурации запуска в скрипте.
Запустите любой скрипт TRL
Та же схема используется во всех скриптах тренера TRL (SFT, DPO, GRPO, reward modeling и других) и в автономных примерах .py в Индексе примеров. Каждый скрипт объявляет свои зависимости в заголовке. Пример, который читает другие файлы из той же папки, требует монтирования этой папки в Job. См. Локальные каталоги. Примеры, предназначенные только для ноутбуков, не могут быть отправлены таким способом. Аргументы скрипта те же, что и при локальном запуске.
Сохранять контрольные точки
Диск Job удаляется при завершении Job, в том числе при достижении тайм-аута или при сбое. Для длительных прогонов сохраняйте контрольные точки (checkpoints) за пределами Job, чтобы они сохранились после его завершения.
Самый простой способ — выкладывать каждый контрольный пункт в репозиторий выходной модели по мере его сохранения:
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 checkpointfrom 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 репозитория. Чтобы продолжить прерванный запуск, примонтируйте репозиторий в новое задание и возобновите работу из этой папки: запустите ту же команду, добавив --volume hf://<your-username>/Qwen2-0.5B-SFT:/previous перед -- и --resume_from_checkpoint /previous/last-checkpoint после URL скрипта.
Чтобы хранить несколько контрольных точек вне репозитория модели, записывайте их в Storage Bucket. Создайте его командой hf buckets create <your-username>/checkpoints --private, примонтируйте к Job и укажите его в параметре --output_dir:
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 500from 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>. Подробнее см. в разделах Запись в бакет по ходу работы и Тома (для опций монтирования).
Каждая контрольная точка содержит состояние модели и оптимизатора, что занимает в несколько раз больше места, чем сама модель. Добавьте
--save_total_limit 2, чтобы сохранять только последние. Если вы также передаёте--push_to_hub, задайте--hub_model_id, иначе репозиторий получит имя по последней части пути вывода.
Несколько GPU
Вариант с несколькими GPU сокращает время выполнения. Для этого используйте hf jobs run, который запускает команду в Docker-образе вместо скрипта, с образом huggingface/trl, в котором установлены TRL и Accelerate. Затем запустите по одному процессу на каждый GPU. Это работает для скриптов TRL и для вашего собственного кода обучения.
Ускорение скрипта TRL
Запуск SFT, описанный в начале этого руководства, на четырёх GPU:
hf jobs run \
--flavor l4x4 \
--timeout 30m \
--secrets HF_TOKEN \
huggingface/trl \
-- \
trl sft --num_processes 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_hubfrom huggingface_hub import run_job
run_job(
image="huggingface/trl",
command=[
"trl", "sft", "--num_processes", "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_..."},
)CLI trl передаёт --num_processes в accelerate launch. Установите его в количество GPU в выбранном варианте, здесь четыре L4. Каждый процесс обрабатывает собственную партию, поэтому эффективный размер партии в четыре раза больше, чем при запуске на одном GPU. Этот запуск занимает несколько минут. Без --max_steps все три эпохи занимают около часа, поэтому увеличьте --timeout, например до 2h.
Ваш собственный скрипт
Вы не ограничены скриптами TRL. Код обучения, который запускается локально с помощью accelerate launch, будет работать так же и в Jobs, если в образе присутствуют необходимые пакеты. Например, сохраните скрипт GRPO с собственной функцией вознаграждения как train_grpo.py в папке и подключите эту папку к Job. Jobs загружает папку в приватный бакет и подключает её только для чтения:
hf jobs run \
--flavor l4x4 \
--timeout 30m \
--secrets HF_TOKEN \
--volume ./my-project:/code \
huggingface/trl \
-- \
accelerate launch --num_processes 4 /code/train_grpo.pyfrom huggingface_hub import run_job, sync_job_volume
code = sync_job_volume("./my-project", "/code")
run_job(
image="huggingface/trl",
command=["accelerate", "launch", "--num_processes", "4", "/code/train_grpo.py"],
flavor="l4x4",
timeout="30m",
secrets={"HF_TOKEN": "hf_..."},
volumes=[code],
)Скрипт выполняется с установленным в образе TRL, поэтому заголовок скрипта не требуется. По умолчанию GRPOTrainer генерирует завершения с помощью transformers, поэтому это выполняется в одном Job без сервера vLLM. Для более быстрой генерации см. vLLM Integration. В следующем разделе объясняется, как hf jobs run использует образ.
Образы Docker
Jobs выполняет ваш скрипт с помощью uv, который устанавливает зависимости, объявленные в его заголовке # /// script, в новое окружение. Поэтому TRL, который импортирует ваш скрипт, берётся из этого заголовка, а не из образа, и в примерах hf jobs uv run выше вообще не нужен параметр --image.
Образ Docker с предварительно установленным TRL доступен по адресу huggingface/trl. Передача этого образа в hf jobs uv run позволяет задаче использовать системный слой образа, например, его CUDA-инструментальную цепочку, что важно для зависимостей, компилируемых с её использованием:
hf jobs uv run \
--flavor a100-large \
--secrets HF_TOKEN \
--image huggingface/trl \
train.pyfrom 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, что необходимо, если сама команда принимает опции:
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-SFTfrom 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_..."},
)Изображение публикуется с тремя типами тегов:
| Метка | Содержание |
|---|---|
X.Y.Z | Выпуск TRL этой версии, собранный в момент релиза данной версии |
latest | Самое свежее обновление |
dev | Ветка main, пересобираемая при каждом слиянии |
Используйте dev, чтобы запустить версию для разработки. Это полезно, если вы хотите протестировать исправление, которое уже добавлено в ветку main, но ещё не выпущено:
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-SFTfrom 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 для этого варианта и необходимых путей.
Jobs выполняется в Docker-образе из Hugging Face Spaces или Docker Hub, поэтому вы также можете указать любой пользовательский образ:
hf jobs uv run \
--flavor a100-large \
--secrets HF_TOKEN \
--image <docker-image> \
train.pyfrom huggingface_hub import run_uv_job
run_uv_job(
"train.py",
flavor="a100-large",
secrets={"HF_TOKEN": "hf_..."},
image="<docker-image>",
)Update on GitHubОбёртка TRL Jobs запускает скрипты TRL на Jobs с предустановленными конфигурациями для некоторых моделей, например
trl-jobs sft --model_name Qwen/Qwen3-0.6B --dataset_name trl-lib/Capybara.