Hub Python Library documentation
Запуск и управление заданиями
Запуск и управление заданиями
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 | красивое имя | cpu | ram | хранение | accelerator | стоимость/мин | стоимость/час |
|---|---|---|---|---|---|---|---|
cpu-basic | CPU Basic | 2 vCPU | 16 ГБ | 50 ГБ | - | $0.0002 | $0.01 |
cpu-upgrade | Обновление CPU | 8 vCPU | 32 ГБ | 50 ГБ | - | $0.0005 | $0.03 |
cpu-performance | Производительность CPU | 32 vCPU | 256 ГБ | 1024 ГБ | - | $0.0317 | $1.90 |
cpu-xl | CPU XL | 16 vCPU | 124 ГБ | 1000 ГБ | - | $0.0167 | $1.00 |
t4-small | Nvidia T4 - малый | 4 vCPU | 15 ГБ | 50 ГБ | 1x T4 (16 ГБ) | $0.0067 | $0.40 |
t4-medium | Nvidia T4 - средний | 8 vCPU | 30 ГБ | 100 ГБ | 1x T4 (16 ГБ) | $0.0100 | $0.60 |
a10g-small | Nvidia A10G - малый | 4 vCPU | 15 ГБ | 110 ГБ | 1x A10G (24 ГБ) | $0.0167 | $1.00 |
a10g-large | Nvidia A10G - большой | 12 vCPU | 46 ГБ | 200 ГБ | 1x A10G (24 ГБ) | $0.0250 | $1.50 |
a10g-largex2 | 2x Nvidia A10G - большой | 24 vCPU | 92 ГБ | 1000 ГБ | 2x A10G (48 ГБ) | $0.0500 | $3.00 |
a10g-largex4 | 4x Nvidia A10G - большой | 48 vCPU | 184 ГБ | 2000 ГБ | 4x A10G (96 ГБ) | $0.0833 | $5.00 |
a100-large | Nvidia A100 - большой | 12 vCPU | 142 ГБ | 1000 ГБ | 1x A100 (80 ГБ) | $0.0417 | $2.50 |
a100x4 | 4x Nvidia A100 | 48 vCPU | 568 ГБ | 4000 ГБ | 4x A100 (320 ГБ) | $0.1667 | $10.00 |
a100x8 | 8x Nvidia A100 | 96 vCPU | 1136 ГБ | 8000 ГБ | 8x A100 (640 ГБ) | $0.3333 | $20.00 |
h200 | Nvidia H200 | 23 vCPU | 256 ГБ | 3000 ГБ | 1x H200 (141 ГБ) | $0.0833 | $5.00 |
h200x2 | Nvidia H200 | 46 vCPU | 512 ГБ | 6000 ГБ | 2x H200 (282 ГБ) | $0.1667 | $10.00 |
h200x4 | Nvidia H200 | 92 vCPU | 1024 ГБ | 12000 ГБ | 4x H200 (564 ГБ) | $0.3333 | $20.00 |
h200x8 | Nvidia H200 | 184 vCPU | 2048 ГБ | 24000 ГБ | 8x H200 (1128 ГБ) | $0.6667 | $40.00 |
rtx-pro-6000 | Nvidia RTX PRO 6000 | 23 vCPU | 256 ГБ | 475 ГБ | 1x RTX PRO 6000 (96 ГБ) | $0.0458 | $2.75 |
rtx-pro-6000x2 | Nvidia RTX PRO 6000 | 46 vCPU | 512 ГБ | 950 ГБ | 2x RTX PRO 6000 (192 ГБ) | $0.0917 | $5.50 |
rtx-pro-6000x4 | Nvidia RTX PRO 6000 | 92 vCPU | 1024 ГБ | 1900 ГБ | 4x RTX PRO 6000 (384 ГБ) | $0.1833 | $11.00 |
rtx-pro-6000x8 | Nvidia RTX PRO 6000 | 184 vCPU | 2048 ГБ | 3800 ГБ | 8x RTX PRO 6000 (768 ГБ) | $0.3667 | $22.00 |
l4x1 | 1x Nvidia L4 | 8 vCPU | 30 ГБ | 400 ГБ | 1x L4 (24 ГБ) | $0.0133 | $0.80 |
l4x4 | 4x Nvidia L4 | 48 vCPU | 186 ГБ | 3200 ГБ | 4x L4 (96 ГБ) | $0.0633 | $3.80 |
l40sx1 | 1x Nvidia L40S | 8 vCPU | 62 ГБ | 380 ГБ | 1x L40S (48 ГБ) | $0.0300 | $1.80 |
l40sx4 | 4x Nvidia L40S | 48 vCPU | 382 ГБ | 3200 ГБ | 4x L40S (192 ГБ) | $0.1383 | $8.30 |
l40sx8 | 8x Nvidia L40S | 192 vCPU | 1534 ГБ | 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 при запуске задания. Тайм-аут можно задать двумя способами:
- В виде числа (интерпретируется как секунды):
>>> 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
... )- В виде строки с единицами времени:
>>> # 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-reporthf 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> --clearUV-скрипты (экспериментально)
Ищете готовые к использованию скрипты 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.
Дополнительную информацию о вебхуках можно найти в документации по вебхукам.