Hub Python Library documentation

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

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v2.4.0).
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