Hub Python Library documentation

Запуск и управление заданиями

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Запуск и управление заданиями

Hugging Face Hub предоставляет вычислительные ресурсы для рабочих процессов с ИИ и данными с помощью Jobs.

Общий обзор Jobs и ценообразования см. в документации Hub Jobs.

Задача выполняется на инфраструктуре Hugging Face и определяется командой для запуска (например, командой python), образом Docker из Hugging Face Spaces или Docker Hub, а также типом аппаратного обеспечения (CPU, GPU, TPU). В этом руководстве показано, как работать с задачами на Hub, в частности:

  • Запустите задание.
  • Проверьте статус задания.
  • Выберите оборудование.
  • Настройте переменные окружения и секреты.
  • Запуск скриптов UV.

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

Hugging Face Jobs доступны любому пользователю или организации с положительным кредитным балансом. Подробности см. в разделе Тарифы и биллинг для Jobs.

Командная строка Jobs

Используйте CLI hf jobs, чтобы запускать Jobs из командной строки, и передавайте --flavor, чтобы указать ваше оборудование.

hf jobs run запускает Jobs с использованием Docker-образа и команды, предоставляя привычный интерфейс, похожий на Docker. Представьте docker run, но для выполнения кода на любом оборудовании:

>>> hf jobs run --name hello-world python:3.12 python -c "print('Hello world')"
>>> hf jobs run --name gpu-check --flavor a10g-small pytorch/pytorch:2.6.0-cuda12.4-cudnn9-devel python -c "import torch; print(torch.cuda.get_device_name())"

Используйте hf jobs uv run для запуска локальных или удалённых скриптов UV:

>>> hf jobs uv run --name my-script my_script.py
>>> hf jobs uv run --name sft-training --flavor a10g-small "https://raw.githubusercontent.com/huggingface/trl/main/trl/scripts/sft.py"

Скрипты UV — это Python-скрипты, в которых зависимости указываются непосредственно в файле с помощью специального синтаксиса комментариев, описанного в документации UV.

Далее в этом руководстве мы рассмотрим Python API. Если же вы хотите просмотреть все доступные команды и параметры hf jobs, обратитесь к руководству по командной строке hf jobs.

Нужен интерактивный компьютер, а не задача типа «запусти и забудь» — например, для выполнения кода, сгенерированного ИИ, с запуском команд и передачей файлов? Ознакомьтесь с Sandboxes, созданными на основе Jobs.

Запуск задачи

Запускайте вычислительные задачи, определённые командой и образом Docker, на инфраструктуре Hugging Face (включая GPU и TPU).

Вы можете управлять только теми Jobs, которые принадлежат вам (в пространстве имён вашего имени пользователя), или Jobs из организаций, в которых у вас есть права на запись. Эта функция работает по модели оплаты по факту использования: вы платите только за секунды, которые используете.

run_job() позволяет выполнять любые команды на инфраструктуре Hugging Face:

# Directly run Python code
>>> from huggingface_hub import run_job
>>> run_job(
...     image="python:3.12",
...     command=["python", "-c", "print('Hello from the cloud!')"],
... )

# Use GPUs without any setup
>>> run_job(
...     image="pytorch/pytorch:2.6.0-cuda12.4-cudnn9-devel",
...     command=["python", "-c", "import torch; print(torch.cuda.get_device_name())"],
...     flavor="a10g-small",
... )

# Run in an organization account
>>> run_job(
...     image="python:3.12",
...     command=["python", "-c", "print('Running in an org account')"],
...     namespace="my-org-name",
... )

# Run from Hugging Face Spaces
>>> run_job(
...     image="hf.co/spaces/lhoestq/duckdb",
...     command=["duckdb", "-c", "select 'hello world'"],
... )

# Run a Python script with `uv` (experimental)
>>> from huggingface_hub import run_uv_job
>>> run_uv_job("my_script.py")

Важно: у заданий есть тайм-аут по умолчанию (30 минут), по истечении которого они автоматически останавливаются. Для длительных задач, таких как обучение моделей, обязательно установите собственный тайм-аут с помощью параметра timeout. Подробности — в разделе Настройка тайм-аута задания.

run_job() возвращает JobInfo, содержащий URL задания на Hugging Face, где можно отслеживать его статус и просматривать логи. Сохраните ID задания из JobInfo, чтобы управлять им:

>>> from huggingface_hub import run_job
>>> job = run_job(
...     image="python:3.12",
...     command=["python", "-c", "print('Hello from the cloud!')"]
... )
>>> job.url
https://huggingface.co/jobs/lhoestq/687f911eaea852de79c4a50a
>>> job.id
687f911eaea852de79c4a50a

Задачи выполняются в фоновом режиме. В следующем разделе показано, как использовать inspect_job() для проверки статуса задачи, fetch_job_logs() для просмотра журналов и fetch_job_metrics() для мониторинга использования ресурсов.

Повторная отправка и перезапуск задачи

Используйте attempts для повторного запуска неудачного Job. В это число входит и первая попытка, поэтому attempts=3 позволяет сделать до двух повторных попыток. Это также работает с run_uv_job, create_scheduled_job и create_scheduled_uv_job.

>>> from huggingface_hub import rerun_job, run_job
>>> job = run_job(image="python:3.12", command=["python", "train.py"], attempts=3)
>>> job.retry
2

# Start a new Job with the same spec, including its retry setting
>>> new_job = rerun_job(job_id=job.id)

rerun_job запускает отдельный Job с новым ID. Он работает для завершённых или упавших Jobs и переиспользует сохранённую спецификацию, включая секреты и настройки оборудования. Также можно выполнить hf jobs rerun <job_id>.

Проверка статуса задания

# List your jobs (results are paginated and returned as an iterator)
>>> from huggingface_hub import list_jobs
>>> jobs = list_jobs()
>>> next(iter(jobs))
JobInfo(id='687f911eaea852de79c4a50a', created_at=datetime.datetime(2025, 7, 22, 13, 24, 46, 909000, tzinfo=datetime.timezone.utc), docker_image='python:3.12', space_id=None, command=['python', '-c', "print('Hello from the cloud!')"], arguments=[], environment={}, secrets={}, flavor='cpu-basic', status=JobStatus(stage='COMPLETED', message=None), owner=JobOwner(id='5e9ecfc04957053f60648a3e', name='lhoestq'), endpoint='https://huggingface.co', url='https://huggingface.co/jobs/lhoestq/687f911eaea852de79c4a50a')

# Materialize the iterator into a list
>>> all_jobs = [job for job in list_jobs()]

# List your running jobs
>>> running_jobs = list_jobs(status="RUNNING")

# Filter by one or more statuses and/or labels
>>> list_jobs(status=["RUNNING", "SCHEDULING"], labels={"env": "prod"})

# Inspect the status of a job
>>> from huggingface_hub import inspect_job
>>> inspect_job(job_id=job_id)
JobInfo(id='687f911eaea852de79c4a50a', created_at=datetime.datetime(2025, 7, 22, 13, 24, 46, 909000, tzinfo=datetime.timezone.utc), docker_image='python:3.12', space_id=None, command=['python', '-c', "print('Hello from the cloud!')"], arguments=[], environment={}, secrets={}, flavor='cpu-basic', status=JobStatus(stage='COMPLETED', message=None), owner=JobOwner(id='5e9ecfc04957053f60648a3e', name='lhoestq'), endpoint='https://huggingface.co', url='https://huggingface.co/jobs/lhoestq/687f911eaea852de79c4a50a')

# View logs from a job
>>> from huggingface_hub import fetch_job_logs
>>> for log in fetch_job_logs(job_id=job_id):
...     print(log)
Hello from the cloud!

# View resources usage metrics from a job
>>> from huggingface_hub import fetch_job_metrics
>>> for metrics in fetch_job_metrics(job_id=job_id):
...     print(metrics)
{
    "cpu_usage_pct": 0,
    "cpu_millicores": 2000,
    "memory_used_bytes": 929792,
    "memory_total_bytes": 17179869184,
    "rx_bps": 0,
    "tx_bps": 0,
    "gpus": {},
    "replica": "4dzsh"
}

# Cancel a job
>>> from huggingface_hub import cancel_job
>>> cancel_job(job_id=job_id)

Дождитесь завершения Jobs

Используйте wait_for_job(), чтобы заблокировать выполнение до тех пор, пока Job не достигнет конечного состояния (COMPLETED, CANCELED, ERROR или DELETED). Финальный объект JobInfo всегда возвращается — сбой Job не вызывает исключение — поэтому проверяйте job.status.stage, чтобы отреагировать на результат. Передайте список идентификаторов Job, чтобы ожидать завершение всей партии сразу.

>>> from huggingface_hub import run_job, wait_for_job
>>> job = run_job(image="python:3.12", command=["python", "-c", "print('hello')"])
>>> wait_for_job(job_id=job.id).status.stage
'COMPLETED'

# Run multiple jobs in parallel and wait for all of them to finish
>>> jobs = [run_job(image=image, command=command) for command in commands]
>>> finished_jobs = wait_for_job(job_id=[job.id for job in jobs], timeout=3600)

То же самое доступно в CLI с помощью hf jobs wait, который завершается с кодом 0 только в том случае, если все Jobs успешно завершены — удобно для связывания команд в shell-скриптах или CI:

# Chain on success
hf jobs wait <job_id> && hf jobs run --detach python:3.12 python eval.py

# Wait for all currently running jobs
hf jobs ls -q | xargs hf jobs wait

Обратите внимание, что и не-отсоединённый hf jobs run (или hf jobs uv run) завершается с ненулевым кодом, если Job завершается с ошибкой, поэтому цепочка hf jobs run ... && next-step работает корректно без явного ожидания.

Выберите оборудование

Существует множество случаев, когда запуск Jobs на GPU полезен:

  • Обучение моделей: дообучение или обучение моделей на GPU (T4, A10G, A100) без управления инфраструктурой
  • Генерация синтетических данных: создание наборов данных большого масштаба с помощью LLM на мощном оборудовании
  • Обработка данных: обработка массивных наборов данных с конфигурациями с высокой загрузкой CPU для параллельных задач
  • Пакетный вывод: Запуск офлайн-вывода на тысячах образцов с использованием оптимизированных GPU-конфигураций
  • Эксперименты и бенчмарки: Проведение ML-экспериментов на едином оборудовании для воспроизводимых результатов
  • Разработка и отладка: тестирование GPU-кода без локальной установки CUDA

Запускайте задачи на GPU или TPU с помощью аргумента flavor. Например, чтобы запустить задачу PyTorch на GPU A10G:

# Use an A10G GPU to check PyTorch CUDA
>>> from huggingface_hub import run_job
>>> run_job(
...     image="pytorch/pytorch:2.6.0-cuda12.4-cudnn9-devel",
...     command=["python", "-c", "import torch; print(f'This code ran with the following GPU: {torch.cuda.get_device_name()}')"],
...     flavor="a10g-small",
... )

При запуске этого кода вы увидите следующий вывод!

This code ran with the following GPU: NVIDIA A10G

Используйте это для запуска скрипта дообучения, например trl/scripts/sft.py, с помощью UV:

>>> from huggingface_hub import run_uv_job
>>> run_uv_job(
...     "sft.py",
...     script_args=["--model_name_or_path", "Qwen/Qwen2-0.5B", ...],
...     dependencies=["trl"],
...     env={"HF_TOKEN": ...},
...     flavor="a10g-small",
... )

Для подробных рекомендаций по запуску задач обучения моделей с помощью TRL на инфраструктуре Hugging Face обратитесь к документации TRL Jobs Training. В ней описаны рецепты дообучения, выбор аппаратного обеспечения и лучшие практики для эффективного обучения моделей.

Вот полный список доступного оборудования для запуска Jobs:

nameкрасивое имяcpuramхранениеacceleratorстоимость/минстоимость/час
cpu-basicCPU Basic2 vCPU16 ГБ50 ГБ-$0.0002$0.01
cpu-upgradeОбновление CPU8 vCPU32 ГБ50 ГБ-$0.0005$0.03
cpu-performanceПроизводительность CPU32 vCPU256 ГБ1024 ГБ-$0.0317$1.90
cpu-xlCPU XL16 vCPU124 ГБ1000 ГБ-$0.0167$1.00
t4-smallNvidia T4 - малый4 vCPU15 ГБ50 ГБ1x T4 (16 ГБ)$0.0067$0.40
t4-mediumNvidia T4 - средний8 vCPU30 ГБ100 ГБ1x T4 (16 ГБ)$0.0100$0.60
a10g-smallNvidia A10G - малый4 vCPU15 ГБ110 ГБ1x A10G (24 ГБ)$0.0167$1.00
a10g-largeNvidia A10G - большой12 vCPU46 ГБ200 ГБ1x A10G (24 ГБ)$0.0250$1.50
a10g-largex22x Nvidia A10G - большой24 vCPU92 ГБ1000 ГБ2x A10G (48 ГБ)$0.0500$3.00
a10g-largex44x Nvidia A10G - большой48 vCPU184 ГБ2000 ГБ4x A10G (96 ГБ)$0.0833$5.00
a100-largeNvidia A100 - большой12 vCPU142 ГБ1000 ГБ1x A100 (80 ГБ)$0.0417$2.50
a100x44x Nvidia A10048 vCPU568 ГБ4000 ГБ4x A100 (320 ГБ)$0.1667$10.00
a100x88x Nvidia A10096 vCPU1136 ГБ8000 ГБ8x A100 (640 ГБ)$0.3333$20.00
h200Nvidia H20023 vCPU256 ГБ3000 ГБ1x H200 (141 ГБ)$0.0833$5.00
h200x2Nvidia H20046 vCPU512 ГБ6000 ГБ2x H200 (282 ГБ)$0.1667$10.00
h200x4Nvidia H20092 vCPU1024 ГБ12000 ГБ4x H200 (564 ГБ)$0.3333$20.00
h200x8Nvidia H200184 vCPU2048 ГБ24000 ГБ8x H200 (1128 ГБ)$0.6667$40.00
rtx-pro-6000Nvidia RTX PRO 600023 vCPU256 ГБ475 ГБ1x RTX PRO 6000 (96 ГБ)$0.0458$2.75
rtx-pro-6000x2Nvidia RTX PRO 600046 vCPU512 ГБ950 ГБ2x RTX PRO 6000 (192 ГБ)$0.0917$5.50
rtx-pro-6000x4Nvidia RTX PRO 600092 vCPU1024 ГБ1900 ГБ4x RTX PRO 6000 (384 ГБ)$0.1833$11.00
rtx-pro-6000x8Nvidia RTX PRO 6000184 vCPU2048 ГБ3800 ГБ8x RTX PRO 6000 (768 ГБ)$0.3667$22.00
l4x11x Nvidia L48 vCPU30 ГБ400 ГБ1x L4 (24 ГБ)$0.0133$0.80
l4x44x Nvidia L448 vCPU186 ГБ3200 ГБ4x L4 (96 ГБ)$0.0633$3.80
l40sx11x Nvidia L40S8 vCPU62 ГБ380 ГБ1x L40S (48 ГБ)$0.0300$1.80
l40sx44x Nvidia L40S48 vCPU382 ГБ3200 ГБ4x L40S (192 ГБ)$0.1383$8.30
l40sx88x Nvidia L40S192 vCPU1534 ГБ6500 ГБ8x L40S (384 ГБ)$0.3917$23.50

Вы можете получить этот список программно, выполнив:

>>> hf jobs hardware

Или с помощью Python API:

>>> from huggingface_hub import list_jobs_hardware
>>> list_jobs_hardware()

Всё готово! Теперь вы запускаете код на инфраструктуре Hugging Face.

Подключение тома

Подключите том на диск Jobs с помощью списка Volume.

Вы можете подключить любой репозиторий Hugging Face (модель/датасет/пространство) или Storage Bucket. Например:

  • подключить репозиторий модели: Volume(type="model", source="openai/gpt-oss-120b", mount_path="/model")
  • подключить репозиторий датасета: Volume(type="dataset", source="HuggingFaceFW/fineweb", mount_path="/data")
  • подключить хранилище: Volume(type="bucket", source="username/my-bucket", mount_path="/mnt")

Затем вы можете использовать смонтированный том как локальный каталог:

>>> from huggingface_hub import run_job, Volume
>>> job = run_job(
...     image="duckdb/duckdb",
...     command=["duckdb", "-c", "SELECT * FROM '/data/**/*.parquet' LIMIT 5"],
...     volumes=[Volume(type="dataset", source="HuggingFaceFW/fineweb", mount_path="/data")],
... )

Вы также можете записывать данные в смонтированное хранилище, например, для сохранения контрольных точек при обучении модели:

>>> from huggingface_hub import run_uv_job, Volume
>>> script = "my_sft.py"
>>> script_args = ["--output_dir", "/training-outputs/training-v3-final", ...]
>>> checkpoints_bucket = Volume(type="bucket", source="username/my-bucket", mount_path="/training-outputs")
>>> run_uv_job(script, script_args=script_args, volumes=[checkpoints_bucket])

По умолчанию смонтированные хранилища имеют права на чтение и запись. Это особенно полезно для хранилищ, которые обеспечивают быстрое изменяемое хранение данных, часто меняющихся — файлы можно перезаписать или удалить на месте.

Используйте read_only=True, чтобы включить режим только для чтения: Volume(type="bucket", read_only=True, ...).

Подключение локальных данных

Чтобы запустить Job на данных с вашего компьютера, используйте sync_job_volume(): он синхронизирует локальный каталог с вашим Storage Bucket jobs-artifacts (создаётся автоматически при необходимости) и возвращает готовый к монтированию Volume:

>>> from huggingface_hub import run_uv_job, sync_job_volume

# Upload ./training-data once...
>>> volume = sync_job_volume("./training-data", "/data")

# ...then run as many Jobs as you want against it
>>> run_uv_job("train.py", script_args=["--learning-rate", "0.01"], volumes=[volume])
>>> run_uv_job("train.py", script_args=["--learning-rate", "0.05"], volumes=[volume])

Каждая директория получает собственную стабильную папку в бакете: повторный запуск sync_job_volume() для той же директории загружает только новые или изменённые файлы. По умолчанию том монтируется в режиме только для чтения.

Чтобы получить файлы, записанные Job, примонтируйте том с правами на чтение и запись (подойдёт и пустой выходной каталог) и синхронизируйте его обратно после завершения Job:

>>> from huggingface_hub import run_uv_job, sync_bucket, sync_job_volume

>>> outputs = sync_job_volume("./outputs", "/outputs", read_only=False)
>>> job = run_uv_job("process.py", volumes=[outputs])

# ...once the Job completes, pull back the data:
>>> sync_bucket(f"hf://buckets/{outputs.source}/{outputs.path}", "./outputs")

В CLI просто передайте локальный каталог в качестве исходной стороны для -v:

>>> hf jobs uv run -v ./pdfs:/input -v ./md-out:/output:rw ocr.py

Открыть порты задания

Передайте expose, чтобы сделать порт контейнера доступным через прокси Jobs. Для доступа требуется токен HF с правами на чтение в пространстве имён Job. Вместо этого используйте expose_public, чтобы разрешить доступ без аутентификации:

>>> from huggingface_hub import run_job, update_job_expose
>>> job = run_job(
...     image="python:3.12",
...     command=["python", "-m", "http.server", "8000"],
...     expose_public=[8000],
... )
>>> job.expose_public
[8000]

# Keep the port exposed, but require an HF token from now on
>>> job = update_job_expose(job_id=job.id, expose=[8000])

# Close all exposed ports
>>> job = update_job_expose(job_id=job.id)

expose и expose_public можно использовать вместе. update_job_expose заменяет полную конфигурацию портов на работающем Job без его перезапуска: порты, отсутствующие в обоих списках, закрываются. Оба параметра также доступны при создании UV и scheduled Jobs.

Подключение к Job по SSH

Передайте ssh=True в run_job() (или run_uv_job()), чтобы сделать контейнер Job доступным по SSH. SSH-эндпоинт доступен в статусе Job:

>>> from huggingface_hub import run_job
>>> job = run_job(
...     image="python:3.12",
...     command=["sleep", "infinity"],
...     ssh=True,
... )
>>> job.status.ssh_url
'ssh://68498e23210b3a4f4e6e2a23@ssh.hf.jobs'

Подключитесь из терминала с помощью hf jobs ssh <job_id> (или напрямую с помощью ssh <job_id>@ssh.hf.jobs):

>>> hf jobs ssh 68498e23210b3a4f4e6e2a23

Доступ разрешен только пользователям с правами на запись в пространство имен задачи (создателю задачи или членам организации-владельца), аутентифицированным по SSH-публичному ключу, зарегистрированному на https://huggingface.co/settings/keys.

Группы сетей

Передайте network_group="<name>" в run_job() (или run_uv_job()), чтобы Jobs в одном и том же namespace и resource group могли взаимодействовать друг с другом на любом порту. Внутри каждого участника HF_NETWORK_GROUP_HOSTNAME разрешается в адрес каждого Job в группе, а ${HF_NETWORK_GROUP_PREFIX}<alias> — в участников, заявивших alias с помощью network_aliases=[...]:

>>> from huggingface_hub import run_job
>>> server = run_job(
...     image="python:3.12",
...     command=["python", "-m", "http.server", "8000"],
...     network_group="train",
...     network_aliases=["master"],
... )
>>> client = run_job(
...     image="python:3.12",
...     command=["sh", "-c", 'curl --retry 10 --retry-connrefused "http://${HF_NETWORK_GROUP_PREFIX}master:8000/"'],
...     network_group="train",
... )
>>> server.network
JobNetwork(group='train', aliases=['master'])

Участники разрешаются до того, как они будут готовы, поэтому подключайтесь с повторными попытками. Имена групп и псевдонимы — это строчные буквы, цифры и дефисы, максимум 46 и 34 символа соответственно.

Настройка тайм-аута задания

У заданий есть тайм-аут по умолчанию (30 минут), после которого они автоматически останавливаются. Это важно учитывать при выполнении длительных задач, таких как обучение моделей.

Настройка пользовательского тайм-аута

Вы можете указать собственное значение тайм-аута с помощью параметра timeout при запуске задания. Тайм-аут можно задать двумя способами:

  1. В виде числа (интерпретируется как секунды):
>>> from huggingface_hub import run_job
>>> job = run_job(
...     image="pytorch/pytorch:2.6.0-cuda12.4-cudnn9-devel",
...     command=["python", "train_model.py"],
...     flavor="a10g-large",
...     timeout=7200,  # 2 hours in seconds
... )
  1. В виде строки с единицами времени:
>>> # Using different time units
>>> job = run_job(
...     image="pytorch/pytorch:2.6.0-cuda12.4-cudnn9-devel",
...     command=["python", "train_model.py"],
...     flavor="a10g-large",
...     timeout="2h",  # 2 hours
... )

>>> # Other examples:
>>> # timeout="30m"    # 30 minutes
>>> # timeout="1.5h"   # 1.5 hours
>>> # timeout="1d"     # 1 day
>>> # timeout="3600s"  # 3600 seconds

Поддерживаемые единицы времени:

  • s - секунды
  • m - минуты
  • h - часы
  • d - дни

Использование timeout с заданиями UV

Для задач UV вы также можете указать тайм-аут:

>>> from huggingface_hub import run_uv_job
>>> job = run_uv_job(
...     "training_script.py",
...     flavor="a10g-large",
...     timeout="90m",  # 90 minutes
... )

Если вы не укажете тайм-аут, для вашей задачи будет применён тайм-аут по умолчанию. Для длительных задач, таких как обучение моделей, которые могут занимать часы, убедитесь, что вы задали подходящий тайм-аут, чтобы избежать неожиданного завершения задачи.

Мониторинг длительности выполнения задания

При выполнении длительных задач рекомендуется:

  • Оцените ожидаемую длительность выполнения задачи и установите тайм-аут с некоторым запасом
  • Отслеживайте ход выполнения задачи по журналам
  • Проверьте статус задания, чтобы убедиться, что оно не прервалось по таймауту
>>> from huggingface_hub import inspect_job, fetch_job_logs
>>> # Check job status
>>> job_info = inspect_job(job_id=job.id)
>>> if job_info.status.stage == "ERROR":
...     print(f"Job failed: {job_info.status.message}")
...     # Check logs for more details
...     for log in fetch_job_logs(job_id=job.id):
...         print(log)

Для получения подробной информации о параметре timeout см. справочник API run_job.

Передача переменных окружения и секретов

Передавать переменные окружения в вашу задачу можно с помощью env и secrets:

# Pass environment variables
>>> from huggingface_hub import run_job
>>> run_job(
...     image="python:3.12",
...     command=["python", "-c", "import os; print(os.environ['FOO'], os.environ['BAR'])"],
...     env={"FOO": "foo", "BAR": "bar"},
... )
# Pass secrets - they will be encrypted server side
>>> from huggingface_hub import run_job
>>> run_job(
...     image="python:3.12",
...     command=["python", "-c", "import os; print(os.environ['MY_SECRET'])"],
...     secrets={"MY_SECRET": "psswrd"},
... )

Встроенные переменные окружения

Внутри контейнера задания автоматически доступны следующие переменные окружения:

ПеременнаяОписание
JOB_IDУникальный идентификатор текущей задачи. Используйте его для программной ссылки на задачу, например, для сохранения результатов в наборе данных с уникальным именем.
ACCELERATORТип доступного ускорителя (например, t4-medium, a10g-small, a100x4). Пусто, если ускоритель отсутствует.
CPU_CORESКоличество ядер CPU, доступных для задачи (например, 2, 4, 8).
MEMORYОбъем памяти, доступный для задания (например, 16Gi, 32Gi).
# Access job environment information
>>> from huggingface_hub import run_job
>>> run_job(
...     image="python:3.12",
...     command=["python", "-c", """
... import os
... print(f"Job ID: {os.environ.get('JOB_ID')}")
... print(f"Accelerator: {os.environ.get('ACCELERATOR', 'none')}")
... print(f"CPU cores: {os.environ.get('CPU_CORES')}")
... print(f"Memory: {os.environ.get('MEMORY')}")
... """],
... )

Эти переменные полезны, когда вам нужно создавать уникальные идентификаторы для результатов, адаптировать код в зависимости от доступного оборудования или записывать информацию о ресурсах в журнал.

Метки

Метки — это пары ключ=значение, которые добавляют метаданные к Job:

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

>>> from huggingface_hub import run_job
>>> run_job(name="daily-report", image="python:3.12", command=["python", "report.py"])

Из CLI передайте --name при создании Job или задайте имя существующему Job с помощью команды labels:

>>> hf jobs run --name daily-report python:3.12 python report.py
>>> hf jobs labels <job_id> --name daily-report

hf jobs ls отображает столбец NAME и позволяет фильтровать по имени (это сокращение для --label name=NAME):

>>> hf jobs ls -a --name daily-report
# Pass extra metadata with Labels
>>> from huggingface_hub import run_job
>>> run_job(
...     image="python:3.12",
...     command=["python", "-c", "import os; print(os.environ['MY_SECRET'])"],
...     labels={"my-label": "my-value", "foo": "bar"},
... )

Если имя не указано, оно формируется автоматически на основе образа Docker или скрипта, а также короткого хэша (например, python:3.12 foo --truc → python-3-12-1a2b3c4d). При запуске из CLI этот хэш учитывает команду и разрешённые параметры среды выполнения (flavor, timeout, значения переменных окружения и т. д.), поэтому одна и та же конфигурация всегда приводит к одному и тому же имени, а изменение любого параметра — в том числе из заголовка [tool.hf-jobs] в скрипте — меняет его. В Python API хэш учитывает только команду.

Обновить метки

Используйте update_job_labels(), чтобы заменить метки на существующей задаче. Это заменяет все пользовательские метки:

>>> from huggingface_hub import update_job_labels
>>> update_job_labels(job_id=job_id, labels={"env": "prod", "team": "ml"})

Это также работает для запланированных задач с update_scheduled_job_labels():

>>> from huggingface_hub import update_scheduled_job_labels
>>> update_scheduled_job_labels(scheduled_job_id=scheduled_job_id, labels={"env": "staging"})

Из CLI:

>>> hf jobs labels <job_id> --label env=prod --label team=ml
>>> hf jobs scheduled labels <scheduled_job_id> --label env=staging

Чтобы удалить все метки, передайте --clear:

>>> hf jobs labels <job_id> --clear

UV-скрипты (экспериментально)

Ищете готовые к использованию скрипты UV? Загляните в организацию uv-scripts на Hugging Face Hub, где собрано сообществом множество скриптов UV для таких задач, как обучение моделей, генерация синтетических данных, обработка данных и многое другое.

Запуск скриптов UV (Python-скриптов с встроенными зависимостями) на инфраструктуре HF:

# Run a UV script (creates temporary repo)
>>> from huggingface_hub import run_uv_job
>>> run_uv_job("my_script.py")

# Run with GPU
>>> run_uv_job("ml_training.py", flavor="gpu-t4-small")

# Run with dependencies
>>> run_uv_job("inference.py", dependencies=["transformers", "torch"])

# Run a script directly from a URL
>>> run_uv_job("https://huggingface.co/datasets/username/scripts/resolve/main/example.py")

# Run a command
>>> run_uv_job("python", script_args=["-c", "import lighteval"], dependencies=["lighteval"])

Скрипты UV — это Python-скрипты, в которых зависимости указаны непосредственно в файле с помощью специального синтаксиса комментариев. Это делает их идеальными для автономных задач, не требующих сложной настройки проекта. Подробнее о скриптах UV см. в документации UV.

Включите конфигурацию запуска в скрипт

Скрипт, который корректно выполняется только в определённой среде выполнения, может указать эту среду в необязательной таблице [tool.hf-jobs] в заголовке PEP 723:

# /// script
# requires-python = ">=3.11"
# dependencies = ["vllm", "datasets"]
#
# [tool.hf-jobs]
# image   = "vllm/vllm-openai:unlimited-ocr"
# flavor  = "l4x1"
# python  = "/usr/bin/python3"
# secrets = ["HF_TOKEN"]
# ///

hf jobs uv run ocr.py запускает скрипт с нужным образом, аппаратным обеспечением и интерпретатором, при этом --flavor, -e, … по-прежнему переопределяют параметры, объявленные в скрипте. Полный список ключей и правила слияния описаны в руководстве по CLI.

Таблица используется только CLI hf: run_uv_job() и create_scheduled_uv_job() игнорируют её и используют ровно те аргументы, которые им переданы. Иными словами, run_uv_job("ocr.py") и hf jobs uv run ocr.py не запускают один и тот же Job — в Python API необходимо явно передавать image=, flavor=, …

Docker-образы для скриптов UV

Хотя скрипты UV могут указывать свои зависимости непосредственно в тексте, рабочие нагрузки ML часто имеют сложные зависимости. Использование предварительно собранных образов Docker, в которые эти библиотеки уже установлены, может значительно ускорить запуск задач и избежать проблем с зависимостями.

По умолчанию при запуске hf jobs uv run используется образ astral-sh/uv:python3.12-bookworm. Этот образ основан на дистрибутиве Python 3.12 Bookworm с предварительно установленным uv.

Вы можете указать другой образ с помощью флага --image:

hf jobs uv run \
 --flavor a10g-large \
 --image vllm/vllm-openai:latest \
...

Команда выше будет выполнена с использованием образа vllm/vllm-openai:latest. Этот подход может быть полезен, если вы используете vLLM для генерации синтетических данных.

Многие фреймворки для инференса предоставляют оптимизированные docker-образы. Поскольку uv всё чаще используется в экосистеме Python, всё больше таких образов будут поставляться с предустановленным uv, что позволит им работать при использовании hf jobs uv run.

Планируемые задачи

Планируйте и управляйте задачами, которые будут выполняться на инфраструктуре HF.

Используйте create_scheduled_job() или create_scheduled_uv_job() с расписанием @annually, @yearly, @monthly, @weekly, @daily, @hourly или выражением CRON-расписания (например, "0 9 * * 1" для 9:00 каждый понедельник):

# Schedule a job that runs every hour
>>> from huggingface_hub import create_scheduled_job
>>> create_scheduled_job(
...     image="python:3.12",
...     command=["python",  "-c", "print('This runs every hour!')"],
...     schedule="@hourly"
... )

# Use the CRON syntax
>>> create_scheduled_job(
...     image="python:3.12",
...     command=["python",  "-c", "print('This runs every 5 minutes!')"],
...     schedule="*/5 * * * *"
... )

# Schedule with GPU
>>> create_scheduled_job(
...     image="pytorch/pytorch:2.6.0-cuda12.4-cudnn9-devel",
...     command=["python",  "-c", 'import torch; print(f"This code ran with the following GPU: {torch.cuda.get_device_name()}")'],
...     schedule="@hourly",
...     flavor="a10g-small",
... )

# Schedule a UV script
>>> from huggingface_hub import create_scheduled_uv_job
>>> create_scheduled_uv_job("my_script.py", schedule="@hourly")

Используйте те же параметры, что и в run_job() и run_uv_job(), чтобы передать переменные окружения, секреты, таймаут и т. д.

Управляйте запланированными заданиями с помощью list_scheduled_jobs(), inspect_scheduled_job(), suspend_scheduled_job(), resume_scheduled_job(), update_scheduled_job_schedule(), trigger_scheduled_job() и delete_scheduled_job():

# List your active scheduled jobs
>>> from huggingface_hub import list_scheduled_jobs
>>> list_scheduled_jobs()

# Only list scheduled jobs with the given labels
>>> list_scheduled_jobs(labels={"env": "prod"})

# Inspect the status of a job
>>> from huggingface_hub import inspect_scheduled_job
>>> inspect_scheduled_job(scheduled_job_id=scheduled_job_id)

# Suspend (pause) a scheduled job
>>> from huggingface_hub import suspend_scheduled_job
>>> suspend_scheduled_job(scheduled_job_id=scheduled_job_id)

# Resume a scheduled job
>>> from huggingface_hub import resume_scheduled_job
>>> resume_scheduled_job(scheduled_job_id=scheduled_job_id)

# Change future run times without recreating the scheduled job
>>> from huggingface_hub import update_scheduled_job_schedule
>>> updated = update_scheduled_job_schedule(scheduled_job_id=scheduled_job_id, schedule="0 9 * * 1")
>>> updated.schedule
'0 9 * * 1'

# Trigger a scheduled job to run right now (does not change the schedule)
>>> from huggingface_hub import trigger_scheduled_job
>>> job = trigger_scheduled_job(scheduled_job_id=scheduled_job_id)
>>> job.url

# Delete a scheduled job
>>> from huggingface_hub import delete_scheduled_job
>>> delete_scheduled_job(scheduled_job_id=scheduled_job_id)

Запуск задач с помощью вебхуков

Webhooks позволяют отслеживать новые изменения в конкретных репозиториях или во всех репозиториях, принадлежащих определенному набору пользователей/организаций (не только ваши репозитории, а любые).

Используйте create_webhook(), чтобы создать вебхук, который запускает Job при изменении в репозитории Hugging Face:

from huggingface_hub import create_webhook

# Example: Creating a webhook that triggers a Job
webhook = create_webhook(
    job_id=job_id,
    watched=[{"type": "user", "name": "your-username"}, {"type": "org", "name": "your-org-name"}],
    domains=["repo", "discussion"],
    secret="your-secret"
)

Вебхук запускает Job, передавая полезную нагрузку вебхука в переменной окружения WEBHOOK_PAYLOAD. Дополнительную информацию о вебхуках можно найти в документации по вебхукам.

Update on GitHub