# Обучение моделей на Jobs

На этой странице показано, как дообучать и обучать модели на Jobs, используя скрипт библиотеки или собственный. Каждый пример ограничен коротким запуском, который завершается за несколько минут на одном A10G и обходится примерно в $0.10 вычислительных ресурсов. Job выполняется на машинах Hugging Face, поэтому он продолжает работу, даже если вы закроете терминал или ноутбук. Если вы ещё не запускали Job, раздел [Quickstart](./jobs-quickstart) описывает установку CLI, вход в систему и кредиты, необходимые для Job.

## Первый запуск

Эта команда выполняет дообучение классификатора изображений на 2000 изображений из набора [Food-101](https://huggingface.co/datasets/ethz/food101) и загружает его в ваше пространство имён на Hub примерно за три минуты:

```bash
hf jobs uv run --flavor a10g-small --timeout 30m -s HF_TOKEN -- \
  https://raw.githubusercontent.com/huggingface/transformers/main/examples/pytorch/image-classification/run_image_classification.py \
  --model_name_or_path google/vit-base-patch16-224-in21k \
  --dataset_name ethz/food101 \
  --do_train --do_eval \
  --remove_unused_columns False \
  --max_train_samples 2000 --max_eval_samples 500 --num_train_epochs 1 \
  --output_dir vit-food101 \
  --push_to_hub
```

Раздел [Transformers](#transformers) охватывает полный прогон и другие примеры скриптов.

## Как формируется задача обучения

Команда выше состоит из пяти частей, и каждая команда на этой странице имеет те же самые.

- **Что выполняется.** Либо uv-скрипт, запускаемый командой `hf jobs uv run`: это Python-скрипт, в котором зависимости объявлены в блоке комментариев в начале файла (`# /// script`, формат [PEP 723](https://peps.python.org/pep-0723/)), которые uv устанавливает в новое окружение. Пример такого скрипта приведён в разделе TRL. Либо Docker-образ библиотеки, запускаемый командой `hf jobs run`, который использует библиотеку, уже установленную в образе. Начинайте с uv-скрипта, если библиотека устанавливается через `pip`. Используйте образ, если библиотека поставляется с ним вместе с скомпилированными зависимостями, либо если её документация рекомендует именно это. О компромиссах см. [Использование Docker-образов](./jobs-images).
- **Токен.** По умолчанию задания не получают токен Hugging Face. Флаг `-s HF_TOKEN` передаёт ваш токен как секрет, что позволяет запуску загружать модель и читать ограниченные или приватные входные данные. Другие секреты передаются аналогичным образом, например `-s WANDB_API_KEY`.
- **Аппаратное обеспечение и время.** `--flavor` выбирает GPU. `--timeout` задаёт временной лимит, по умолчанию 30 минут. Запуск, достигший лимита, останавливается, поэтому установите `--timeout` выше ожидаемого времени выполнения. См. [Аппаратное обеспечение](./jobs-configuration#hardware-flavor) и [Временной лимит](./jobs-configuration#timeout).
- **A `--` between the `hf` flags and the script.** Flags before `--` are for `hf jobs`. After it come the script path and the script's own arguments. Without it, a script argument that shares a name with an `hf` flag, such as `--timeout` or `--token`, is taken by `hf`. In the image form, what follows `--` is the command to run in the container.
- **Куда сохраняется результат.** Каждая библиотека из списка ниже может отправить готовую модель в репозиторий на Hub, и в каждом примере показан соответствующий параметр. Для Transformers и TRL имя репозитория задаётся через `--output_dir`. Запуск также может записывать данные в смонтированное [ведро](./storage-buckets) по ходу работы, используя `-v` для монтирования его в контейнер. См. [После завершения](#after-it-ends).

**Ваш собственный код обучения.** Используйте простейшую форму, которая подходит:

- **Один файл.** Объявите зависимости в заголовке скрипта и запустите `hf jobs uv run train.py`. Пример показан в разделе TRL.
- **Папка проекта** с локальными импортами, файлом `pyproject.toml` или конфигурационными файлами. Команда `hf jobs uv run` загружает только файл скрипта, поэтому подключите папку. Подключение доступно только для чтения, поэтому команда копирует проект в записываемый каталог и запускает его там, как это было бы локально:

  ```bash
  hf jobs run --flavor a10g-small --timeout 30m -s HF_TOKEN \
    -v ./my-project:/code ghcr.io/astral-sh/uv:python3.12-bookworm -- \
    bash -c "cp -r /code /tmp/project && cd /tmp/project && uv run train.py --config configs/run.yaml"
  ```

  `uv run` устанавливает зависимости из `pyproject.toml` или заголовка скрипта, а локальные импорты и относительные пути работают без изменений. См. [Локальные каталоги](./jobs-configuration#local-directories).
- **Код, требующий системных пакетов или CUDA toolkit.** Соберите образ один раз и запускайте его с помощью `hf jobs run`. См. [Создание собственного образа с помощью Docker Space](./jobs-images#build-your-own-image-with-a-docker-space).

Скрипт также может содержать собственную конфигурацию запуска в таблице `[tool.hf-jobs]` в заголовке скрипта, как показано в разделе TRL. См. [Определение конфигурации запуска в скрипте](./jobs-configuration#define-the-launch-config-in-the-script). Те же команды доступны из Python в виде `run_uv_job()` и `run_job()`, о чём рассказано в разделе [Конфигурация](./jobs-configuration).

## Проверки перед длительным запуском

Прежде чем снимать ограничения, несколько проверок помогут избежать бесполезного запуска.

- **Сначала проведите smoke-тест.** Запустите команду с ограничением числа шагов на небольшой конфигурации, как показано в примерах на этой странице. Это подтвердит, что зависимости устанавливаются, данные загружаются, модель помещается в память и загрузка работает. Затем снимите ограничение и запустите полный прогон.
- **Проверьте, что данные помещаются на диск.** У каждой конфигурации есть фиксированный диск, указанный в столбце Ephemeral Storage на странице [Pricing and Billing](./jobs-pricing#pricing). Веса, датасет и сохранённые чекпоинты разделяют его. Если датасет слишком велик для диска, его можно стримить или смонтировать вместо загрузки. См. [Process Large Datasets](./jobs-large-datasets).
- **Оцените время выполнения.** Итоговые метрики `train_*` smoke-теста включают `train_steps_per_second`, а trainer выводит общее количество шагов при запуске. Вместе они позволяют определить время обучения для полного запуска. Установите `--timeout` с запасом выше этого значения, так как Job также тратит время на установку зависимостей и загрузку модели. Тарифы по flavor указаны в разделе [Pricing and Billing](./jobs-pricing).
- **На конфигурации с несколькими GPU запускайте по одному процессу на каждый GPU.** Конфигурации, оканчивающиеся на `x2`, `x4` или `x8`, предоставляют несколько GPU на одной машине. Убедитесь, что способ запуска использует их. Transformers и TRL требуют `accelerate launch`, как показано в разделе TRL. Axolotl делает это самостоятельно. Обычный запуск `python train.py` использует один GPU, а `Trainer` откатывается к `DataParallel`, что медленнее, чем один процесс на GPU.
- **Зафиксируйте версию, если планируете повторный запуск.** Зафиксируйте URL скрипта на конкретном коммите вместо `main`, а образ — на определённом теге вместо `latest`. Тогда при повторном запуске будет использовано то же программное обеспечение. URL скриптов ниже отслеживают ветку `main`, поэтому зафиксируйте коммит перед повторным запуском.
- **Сохраняйте контрольные точки длительных запусков** в смонтированное хранилище, чтобы таймаут или сбой не привели к потере результатов. См. [После завершения](#after-it-ends).

## Пока он выполняется

Команды `hf jobs run` и `hf jobs uv run` транслируют логи и удерживают терминал до завершения выполнения. Ctrl+C останавливает только поток логов. Job продолжает работать, пока не завершится или пока вы не остановите его с помощью `hf jobs cancel <job_id>`.

Для длительных запусков передайте `-d` (detach), чтобы сразу получить Job ID, затем следите за запуском с помощью `hf jobs logs -f <job_id>` и убедитесь, что GPU загружен, с помощью `hf jobs stats <job_id>`. После отсоединённого запуска `hf jobs wait <job_id>` блокируется до завершения Job и завершается с ненулевым кодом при ошибке, что необходимо для скриптов или циклов агента. Непрерывный запуск уже выполняет это. См. [Управление Job](./jobs-manage).

Журналы задач выводят значения потерь в виде текста. Для построения графиков укажите в тренерах экспериментальный трекер, например [trackio](https://huggingface.co/docs/trackio), а для хостингового трекера, такого как Weights & Biases, передайте его ключ как второй секрет.

## После его завершения

Диск Job удаляется при завершении Job, независимо от того, успешно он завершился, завершился с ошибкой или истекло время ожидания. Все, что вы хотите сохранить, необходимо выгрузить из контейнера до этого момента.

**Загрузите модель в репозиторий Hub.** У каждой библиотеки на этой странице есть соответствующий параметр: `--push_to_hub` для Transformers, TRL и Diffusers, `--output-repo` для скриптов Unsloth, `hub_model_id` в YAML-файле Axolotl. По завершении запуска библиотека загружает веса, токенизатор и сгенерированную карточку модели, в которой указаны базовая модель и аргументы обучения. Если репозиторий не существует, он будет создан. Чтобы сделать его приватным, сначала создайте его с помощью `hf repos create <name> --private`. Для этого требуется токен с правами на запись и создание в репозитории модели. В противном случае обучение дойдёт до конца, но загрузка завершится ошибкой.

**Записывайте данные в бакет по ходу работы.** Для запуска, который длится несколько часов, смонтируйте существующий [Storage Bucket](./storage-buckets) в режиме чтения и записи (создайте его с помощью `hf buckets create`) и укажите каталог вывода библиотеки на него. Чекпоинты сохраняются в бакет по мере их создания, поэтому таймаут или сбой не приведут к потере запуска, а следующий Job сможет продолжить работу с них. Тот же подход работает для результатов оценки, логов и любых других данных, кроме моделей.

```bash
hf jobs uv run --flavor a10g-large --timeout 8h -s HF_TOKEN \
  -v hf://buckets/your-username/checkpoints:/ckpt -- \
  train.py --output_dir /ckpt/run-01
```

Скрипты Transformers, TRL и Diffusers принимают `--output_dir`. Axolotl принимает `output_dir` в YAML. Если вы также передаёте `--push_to_hub`, установите также `--hub_model_id`, иначе репозиторий получит имя по последней части пути вывода (`run-01`). Чтобы продолжить прерванный запуск, снова смонтируйте тот же бакет и передайте опцию возобновления библиотеки, например `--resume_from_checkpoint` для `Trainer` в Transformers. См. [Тома](./jobs-configuration#volumes) для вариантов монтирования.

**Чтение журнала неудачного запуска.** Job, который завершился с ошибкой, сохраняет свои логи: `hf jobs logs <job_id>` работает после его завершения, а `hf jobs inspect <job_id>` возвращает итоговый статус и сообщение об ошибке. `hf jobs logs -f` завершается, когда поток логов прекращается, независимо от того, успешен ли был запуск, поэтому перед тем как считать, что всё прошло успешно, проверьте `inspect`.

## Transformers

Скрипты [примеров](https://github.com/huggingface/transformers/tree/main/examples/pytorch) в репозитории Transformers указывают свои зависимости в заголовке скрипта, поэтому они запускаются в Jobs напрямую по URL из GitHub. Аргументы, следующие за URL, передаются в скрипт. [Первый запуск](#a-first-run) использует скрипт классификации изображений.

Для полного запуска удалите из этой команды `--max_train_samples 2000 --max_eval_samples 500 --num_train_epochs 1`: три эпохи на 75 000 обучающих изображений Food-101 занимают около часа на `a10g-small`, что составляет примерно 1 доллар по тарифу этого типа, и обеспечивают точность 90%. Перед запуском увеличьте `--timeout` до `2h`. `--push_to_hub` загружает модель в ваше пространство имён, используя имя выходного каталога. Скрипты доступны для классификации текста, суммаризации, перевода, классификации токенов, распознавания речи и других задач.

## TRL

[TRL](https://huggingface.co/docs/trl) содержит готовые к запуску скрипты для каждого тренера (SFT, DPO, GRPO и других), каждый из которых объявляет собственные зависимости, поэтому они запускаются на Jobs прямо по URL, как скрипты Transformers. Эта команда выполняет дообучение небольшой модели на [наборе данных для чата](https://huggingface.co/datasets/trl-lib/Capybara):

```bash
hf jobs uv run --flavor a10g-small --timeout 30m -s 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
```

Это занимает около шести минут. Уберите `--max_steps` для полного запуска: три эпохи Capybara, значение по умолчанию в скрипте, занимают около 2 ч 20 мин на `a10g-small`, поэтому увеличьте `--timeout` вместе с ним. В собственной документации TRL используется `a100-large`, что быстрее.

Полное руководство, включая написание собственного скрипта TRL и запуск образа `huggingface/trl`, — это [Обучение с помощью Jobs](https://huggingface.co/docs/trl/jobs_training) в документации TRL.

Для нескольких GPU переключитесь на образ TRL, в который входит `accelerate`, и запустите по одному процессу на каждый GPU:

```bash
hf jobs run --flavor a10g-largex2 --timeout 30m -s HF_TOKEN huggingface/trl -- \
  accelerate launch --num_processes 2 -m trl.scripts.sft \
  --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
```

Без `--max_steps` полный прогон (три эпохи Capybara, значение по умолчанию в скрипте) занимает около 1 ч 35 мин на двух A10G.

Когда вы пишете собственный скрипт TRL, конфигурация запуска может перемещаться вместе с ним. Таблица `[tool.hf-jobs]` в заголовке задаёт тип, тайм-аут и секреты:

```python
# /// script
# dependencies = ["trl"]
#
# [tool.hf-jobs]
# flavor  = "a10g-small"
# timeout = "1h"
# secrets = ["HF_TOKEN"]
# ///
from trl import SFTConfig, SFTTrainer
...
```

`hf jobs uv run train.py` не требует флагов, а переданный флаг всё равно имеет приоритет. См. [Определение конфигурации запуска в скрипте](./jobs-configuration#define-the-launch-config-in-the-script).

## Unsloth

[Unsloth](https://unsloth.ai) предоставляет готовые к запуску скрипты в датасете [`unsloth/jobs`](https://huggingface.co/datasets/unsloth/jobs), по одному на каждую модельную семью. Они устанавливают Unsloth из заголовка своего скрипта и принимают датасет и репозиторий вывода в качестве аргументов:

```bash
hf jobs uv run --flavor a10g-small --timeout 30m -s HF_TOKEN -- \
  https://huggingface.co/datasets/unsloth/jobs/resolve/main/sft-lfm2.5.py \
  --dataset mlabonne/FineTome-100k \
  --max-steps 50 \
  --output-repo your-username/lfm-finetuned
```

Это занимает около пяти минут и загружает адаптер LoRA. Для полной эпохи замените `--max-steps 50` на `--num-epochs 1` и увеличьте значение `--timeout`. Пошаговое руководство — [Fine-tune with Unsloth on Jobs](https://huggingface.co/blog/unsloth-jobs) в блоге Hugging Face.

## Axolotl

[Axolotl](https://docs.axolotl.ai) принимает конфигурацию в формате YAML и запускается из собственного Docker-образа, поэтому в этом разделе используется `hf jobs run` с закреплённым тегом, а конфигурация синхронизируется из локального каталога с помощью `-v`. Сохраните конфигурацию из [Axolotl examples](https://github.com/axolotl-ai-cloud/axolotl/tree/main/examples) как `./configs/lora.yml` и добавьте ключи, показанные после команды. В этом примере используется `examples/phi/lora-3.5.yaml` — дообучение Phi-3.5-mini с помощью LoRA, без каких-либо изменений. В образ уже включена команда `axolotl`.

```bash
hf jobs run --flavor a10g-small --timeout 30m -s HF_TOKEN \
  -v ./configs:/configs \
  axolotlai/axolotl:0.19.0-py3.12-cu130-2.13.0 -- \
  axolotl train /configs/lora.yml
```

`-v ./configs:/configs` загружает локальный каталог `configs` в ваше приватное хранилище `jobs-artifacts` (создаётся при первом использовании) и монтирует его в контейнер в режиме только для чтения, так что YAML на вашем диске — это тот же YAML, который использует запуск. Выходные данные задаются в YAML. Эти ключи выгружают модель в конце запуска, а `max_steps` ограничивает количество шагов в этом пробном запуске:

```yaml
hub_model_id: your-username/my-adapter
hub_strategy: end
max_steps: 20
```

Это занимает около семи минут и загружает адаптер в `hub_model_id` как в приватный репозиторий. Уберите `max_steps` для полного прогона. Форматы тегов образов описаны в [гайде Axolotl по Docker](https://docs.axolotl.ai/docs/docker.html#sec-main-tags).

Для большего количества GPU измените flavor и ничего больше: на `a10g-largex4` `axolotl train` сам запускает по одному процессу на каждый GPU. DeepSpeed и FSDP в этом случае задаются ключами в YAML, что описано в [руководстве Axolotl по работе с несколькими GPU](https://docs.axolotl.ai/docs/multi-gpu.html).

Подробнее см. в [руководстве Hugging Face Jobs](https://docs.axolotl.ai/docs/hf-jobs.html) в документации Axolotl.

## Diffusers

Большинство [скриптов DreamBooth LoRA](https://github.com/huggingface/diffusers/tree/main/examples/dreambooth) в репозитории Diffusers объявляют свои зависимости в заголовке скрипта, поэтому они запускаются в Jobs напрямую по URL из GitHub, как и скрипты Transformers. Эта команда обучает LoRA для [FLUX.2 [klein] 4B](https://huggingface.co/black-forest-labs/FLUX.2-klein-4B) на пяти фотографиях собаки:

```bash
hf jobs uv run --flavor a10g-small --timeout 30m -s HF_TOKEN -- \
  https://raw.githubusercontent.com/huggingface/diffusers/main/examples/dreambooth/train_dreambooth_lora_flux2_klein.py \
  --pretrained_model_name_or_path black-forest-labs/FLUX.2-klein-4B \
  --dataset_name diffusers/dog-example \
  --instance_prompt "a photo of sks dog" \
  --resolution 512 --mixed_precision bf16 --guidance_scale 1 \
  --gradient_checkpointing --cache_latents \
  --optimizer adamW --use_8bit_adam --learning_rate 1e-4 \
  --max_train_steps 20 --seed 0 \
  --output_dir /tmp/out \
  --push_to_hub --hub_model_id your-username/klein-dog-lora
```

Это занимает около пяти минут и загружает LoRA. Для полноценного запуска увеличьте значение `--max_train_steps`; в [FLUX.2 README](https://github.com/huggingface/diffusers/blob/main/examples/dreambooth/README_flux2.md) используется 500. Остальные README в этой папке описывают остальные модели и варианты использования памяти. Проверьте начало скрипта на наличие блока `# /// script`: скрипты без него, например скрипт SDXL, требуют передачи зависимостей с помощью `--with`.

## Дальнейшие шаги

- Используйте [Serve Models](./jobs-serving), чтобы разместить обученную модель за временным конечным пунктом для запуска оценки или демонстрации. [Inference Endpoints](https://huggingface.co/docs/inference-endpoints) запускает конечный пункт, который работает постоянно.
- [Конфигурация](./jobs-configuration) для секретов, переменных окружения, томов и таблицы `[tool.hf-jobs]`, которая позволяет скрипту задавать собственные параметры и тайм-аут.
- [Управление заданиями](./jobs-manage) для просмотра списка, проверки, отладки и отмены заданий.
- [Обработка больших наборов данных](./jobs-large-datasets) для потоковой передачи и монтирования данных, которые не помещаются на диск.
- Используйте [Schedule Jobs](./jobs-schedule), чтобы запускать команду обучения по расписанию.
- [Примеры и учебные материалы](./jobs-examples) с материалами сообщества, включая дообучение моделей зрения и языка и потоковую загрузку больших наборов данных в процесс обучения.
- [Использование Jobs из агента для написания кода](./jobs-examples#coding-agent-skills): навык `hf` CLI позволяет Claude Code, Codex и Cursor запускать и отслеживать эти запуски за вас.

