Hub Python Library documentation

Ejecutar y gestionar Jobs

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Ejecutar y gestionar Jobs

El Hugging Face Hub ofrece recursos de cómputo para flujos de trabajo de IA y datos a través de Jobs.

Para una visión general de Jobs y precios, consulte la documentación de Hub Jobs.

Un trabajo se ejecuta en la infraestructura de Hugging Face y se define con un comando para ejecutar (por ejemplo, un comando de python), una imagen de Docker de Hugging Face Spaces o Docker Hub, y un tipo de hardware (CPU, GPU, TPU). Esta guía te mostrará cómo interactuar con los trabajos en el Hub, en especial:

  • Ejecutar un trabajo.
  • Comprueba el estado del trabajo.
  • Seleccione el hardware.
  • Configure las variables de entorno y los secretos.
  • Ejecuta scripts de UV.

Si deseas ejecutar y gestionar un trabajo en el Hub, tu máquina debe estar iniciada sesión. Si no es así, consulta esta sección. En el resto de esta guía, asumiremos que tu máquina tiene la sesión iniciada.

Hugging Face Jobs están disponibles para cualquier usuario u organización con un saldo de crédito positivo. Consulta Jobs pricing and billing para más detalles.

Interfaz de línea de comandos de Jobs

Use la CLI hf jobs para ejecutar Jobs desde la línea de comandos y pase --flavor para especificar su hardware.

hf jobs run ejecuta Jobs con una imagen de Docker y un comando mediante una interfaz similar a la de Docker. Piensa en docker run, pero para ejecutar código en cualquier hardware:

>>> 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())"

Use hf jobs uv run para ejecutar scripts UV locales o remotos:

>>> 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"

Los scripts de UV son scripts de Python que incluyen sus dependencias directamente en el archivo mediante una sintaxis de comentario especial definida en la documentación de UV.

Ahora, el resto de esta guía te mostrará la API de python. Si prefieres ver todos los comandos y opciones disponibles de hf jobs, consulta la guía sobre la interfaz de línea de comandos de hf jobs.

¿Necesitas una máquina interactiva en lugar de un trabajo de ejecución y olvido, por ejemplo, para ejecutar código generado por IA, con ejecución de comandos y transferencia de archivos? Echa un vistazo a Sandboxes, construido sobre Jobs.

Ejecutar un trabajo

Ejecuta Jobs de cómputo definidos con un comando y una imagen de Docker en la infraestructura de Hugging Face (incluidas GPUs y TPUs).

Solo puedes gestionar los Jobs que te pertenecen (bajo el espacio de nombres de tu nombre de usuario) o los de organizaciones en las que tienes permisos de escritura. Esta función es de pago por uso: solo pagas por los segundos que utilices.

run_job() te permite ejecutar cualquier comando en la infraestructura de 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")

Importante: Los trabajos tienen un tiempo de espera predeterminado (30 minutos), tras el cual se detienen automáticamente. Para tareas de larga duración, como el entrenamiento de modelos, asegúrate de configurar un tiempo de espera personalizado mediante el parámetro timeout. Consulta Configurar el tiempo de espera del trabajo para más detalles.

run_job() devuelve el JobInfo, que contiene la URL del trabajo en Hugging Face, donde puedes ver el estado del trabajo y los registros. Guarda el ID del trabajo de JobInfo para gestionar el trabajo:

>>> 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

Los trabajos se ejecutan en segundo plano. La siguiente sección te guía a través de inspect_job() para conocer el estado de un trabajo, fetch_job_logs() para ver los registros y fetch_job_metrics() para monitorear el uso de recursos.

Reintentar y volver a ejecutar un Job

Use attempts para reintentar un Job fallido. El número incluye el intento inicial, por lo que attempts=3 permite hasta dos reintentos. También funciona con run_uv_job, create_scheduled_job y 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 inicia un Job separado con un nuevo ID. Funciona con Jobs completados o fallidos y reutiliza la especificación guardada, incluidos los secretos y la configuración de hardware. También puedes ejecutar hf jobs rerun <job_id>.

Comprobar el estado del trabajo

# 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)

Espera a que los trabajos terminen

Use wait_for_job() para bloquear hasta que un Job alcance una etapa terminal (COMPLETED, CANCELED, ERROR o DELETED). Siempre se devuelve el JobInfo final: un Job fallido no lanza una excepción, por lo que debe comprobar job.status.stage para actuar según el resultado. Pase una lista de IDs de Job para esperar a un lote completo a la vez.

>>> 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)

Lo mismo está disponible en la CLI con hf jobs wait, que finaliza con código 0 solo si todos los Jobs se completaron con éxito, lo cual es útil para encadenar comandos en scripts de shell o 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

Tenga en cuenta que un hf jobs run no desvinculado (o hf jobs uv run) también finaliza con un código no cero si el Job falla, por lo que hf jobs run ... && next-step encadena correctamente sin una espera explícita.

Selecciona el hardware

Existen numerosos casos en los que resulta útil ejecutar Jobs en GPUs:

  • Entrenamiento de modelos: Ajuste fino o entrenamiento de modelos en GPUs (T4, A10G, A100) sin gestionar la infraestructura
  • Generación de datos sintéticos: Genera conjuntos de datos a gran escala utilizando LLMs en hardware potente
  • Procesamiento de datos: Procesa conjuntos de datos masivos con configuraciones de CPU de alto rendimiento para cargas de trabajo paralelas
  • Inferencia por lotes: Ejecuta inferencia sin conexión en miles de muestras usando configuraciones de GPU optimizadas
  • Experimentos y benchmarks: Ejecuta experimentos de ML en hardware consistente para obtener resultados reproducibles
  • Desarrollo y depuración: Prueba el código de GPU sin configuración local de CUDA

Ejecuta trabajos en GPUs o TPUs con el argumento flavor. Por ejemplo, para ejecutar un trabajo de PyTorch en una 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",
... )

Al ejecutarlo, se mostrará la siguiente salida.

This code ran with the following GPU: NVIDIA A10G

Use esto para ejecutar un script de ajuste fino como trl/scripts/sft.py con 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",
... )

Para obtener una guía completa sobre la ejecución de trabajos de entrenamiento de modelos con TRL en la infraestructura de Hugging Face, consulte la documentación de TRL Jobs Training. Aborda recetas de ajuste fino, selección de hardware y mejores prácticas para entrenar modelos de manera eficiente.

Esta es la lista completa de hardware disponible para ejecutar Jobs:

namenombrecpuramalmacenamientoacceleratorcosto/mincosto/hora
cpu-basicBásico de CPU2 vCPU16 GB50 GB-$0.0002$0.01
cpu-upgradeMejora de CPU8 vCPU32 GB50 GB-$0.0005$0.03
cpu-performanceRendimiento de la CPU32 vCPU256 GB1024 GB-$0.0317$1.90
cpu-xlCPU XL16 vCPU124 GB1000 GB-$0.0167$1.00
t4-smallNvidia T4 - pequeño4 vCPU15 GB50 GB1x T4 (16 GB)$0.0067$0.40
t4-mediumNvidia T4 - medio8 vCPU30 GB100 GB1x T4 (16 GB)$0.0100$0.60
a10g-smallNvidia A10G - pequeño4 vCPU15 GB110 GB1x A10G (24 GB)$0.0167$1.00
a10g-largeNvidia A10G - grande12 vCPU46 GB200 GB1x A10G (24 GB)$0.0250$1.50
a10g-largex22x Nvidia A10G - grande24 vCPU92 GB1000 GB2x A10G (48 GB)$0.0500$3.00
a10g-largex44x Nvidia A10G - grande48 vCPU184 GB2000 GB4x A10G (96 GB)$0.0833$5.00
a100-largeNvidia A100 - grande12 vCPU142 GB1000 GB1x A100 (80 GB)$0.0417$2.50
a100x44x Nvidia A10048 vCPU568 GB4000 GB4x A100 (320 GB)$0.1667$10.00
a100x88x Nvidia A10096 vCPU1136 GB8000 GB8x A100 (640 GB)$0.3333$20.00
h200Nvidia H20023 vCPU256 GB3000 GB1x H200 (141 GB)$0.0833$5.00
h200x2Nvidia H20046 vCPU512 GB6000 GB2x H200 (282 GB)$0.1667$10.00
h200x4Nvidia H20092 vCPU1024 GB12000 GB4x H200 (564 GB)$0.3333$20.00
h200x8Nvidia H200184 vCPU2048 GB24000 GB8x H200 (1128 GB)$0.6667$40.00
rtx-pro-6000Nvidia RTX PRO 600023 vCPU256 GB475 GB1x RTX PRO 6000 (96 GB)$0.0458$2.75
rtx-pro-6000x2Nvidia RTX PRO 600046 vCPU512 GB950 GB2x RTX PRO 6000 (192 GB)$0.0917$5.50
rtx-pro-6000x4Nvidia RTX PRO 600092 vCPU1024 GB1900 GB4x RTX PRO 6000 (384 GB)$0.1833$11.00
rtx-pro-6000x8Nvidia RTX PRO 6000184 vCPU2048 GB3800 GB8x RTX PRO 6000 (768 GB)$0.3667$22.00
l4x11x Nvidia L48 vCPU30 GB400 GB1x L4 (24 GB)$0.0133$0.80
l4x44x Nvidia L448 vCPU186 GB3200 GB4x L4 (96 GB)$0.0633$3.80
l40sx11x Nvidia L40S8 vCPU62 GB380 GB1x L40S (48 GB)$0.0300$1.80
l40sx44x Nvidia L40S48 vCPU382 GB3200 GB4x L40S (192 GB)$0.1383$8.30
l40sx88x Nvidia L40S192 vCPU1534 GB6500 GB8x L40S (384 GB)$0.3917$23.50

Puedes obtener esta lista de forma programática ejecutando:

>>> hf jobs hardware

O usando la API de Python:

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

¡Listo! Ahora estás ejecutando código en la infraestructura de Hugging Face.

Montar un volumen

Monte un volumen en el disco de los Jobs usando una lista de Volume.

Puedes montar cualquier Repositorio de Hugging Face (modelo/conjunto de datos/espacio) o Storage Bucket. Por ejemplo:

  • montar un repositorio de modelos: Volume(type="model", source="openai/gpt-oss-120b", mount_path="/model")
  • montar un repositorio de datos: Volume(type="dataset", source="HuggingFaceFW/fineweb", mount_path="/data")
  • montar un bucket de almacenamiento: Volume(type="bucket", source="username/my-bucket", mount_path="/mnt")

Luego, puede usar el volumen montado como un directorio local:

>>> 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")],
... )

También puede escribir en un bucket montado, por ejemplo, para guardar puntos de control al entrenar un modelo:

>>> 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])

Por defecto, los buckets de almacenamiento montados tienen permisos de lectura y escritura. Esto resulta especialmente útil para los buckets de almacenamiento, que proporcionan un almacenamiento rápido y mutable para datos que cambian con frecuencia: los archivos pueden sobrescribirse o eliminarse en su ubicación original.

Use read_only=True para habilitar solo lectura: Volume(type="bucket", read_only=True, ...).

Montar datos locales

Para ejecutar un Job con datos de tu máquina, usa sync_job_volume(): sincroniza un directorio local con tu Storage Bucket jobs-artifacts (creado automáticamente si es necesario) y devuelve un Volume listo para montar:

>>> 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])

Cada directorio obtiene su propia carpeta estable en el bucket: volver a ejecutar sync_job_volume() en el mismo directorio solo sube archivos nuevos o modificados. El volumen se monta de solo lectura de forma predeterminada.

Para recuperar los archivos escritos por un Job, monte un volumen de lectura y escritura (también funciona un directorio de salida vacío) y síncronelo de vuelta cuando el Job termine:

>>> 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")

En la CLI, simplemente pase un directorio local como el lado de origen de -v:

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

Exponer los puertos del trabajo

Pase expose para hacer que un puerto de contenedor sea accesible a través del proxy de Jobs. El acceso requiere un token de HF con permiso de lectura en el espacio de nombres del Job. Use expose_public en su lugar para permitir el acceso sin autenticación:

>>> 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 y expose_public se pueden combinar. update_job_expose reemplaza la configuración completa de puertos en un Job en ejecución sin reiniciarlo: los puertos que no están en ninguna de las dos listas se cierran. Ambas opciones también están disponibles al crear Jobs UV y programados.

Conectarse a un trabajo mediante SSH

Pasa ssh=True a run_job() (o run_uv_job()) para que el contenedor del Job sea accesible a través de SSH. El punto de conexión SSH está disponible en el estado del 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'

Conéctese desde una terminal con hf jobs ssh <job_id> (o directamente con ssh <job_id>@ssh.hf.jobs):

>>> hf jobs ssh 68498e23210b3a4f4e6e2a23

Solo se permite el acceso a los usuarios con permisos de escritura en el espacio de nombres del Job (el creador del Job o los miembros de la organización propietaria), autenticados mediante una clave pública SSH registrada en https://huggingface.co/settings/keys.

Grupos de red

Pase network_group="<name>" a run_job() (o run_uv_job()) para que los Jobs en el mismo namespace y grupo de recursos puedan comunicarse entre sí en todos los puertos. Dentro de cada miembro, HF_NETWORK_GROUP_HOSTNAME se resuelve a todos los Jobs del grupo, y ${HF_NETWORK_GROUP_PREFIX}<alias> a los miembros que reclamaron un alias con 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'])

Los miembros son resolubles antes de estar listos, por lo que debe conectarse con reintentos. Los nombres y alias de grupo son alfanuméricos en minúsculas y guiones, con un máximo de 46 y 34 caracteres, respectivamente.

Configurar el tiempo de espera del trabajo

Los trabajos tienen un tiempo de espera predeterminado (30 minutos), tras el cual se detienen automáticamente. Es importante tenerlo en cuenta al ejecutar tareas de larga duración, como el entrenamiento de modelos.

Establecer un tiempo de espera personalizado

Puede especificar un valor de tiempo de espera personalizado usando el parámetro timeout al ejecutar un trabajo. El tiempo de espera se puede especificar de dos formas:

  1. Como un número (interpretado como segundos):
>>> 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. Como una cadena con unidades de tiempo:
>>> # 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

Unidades de tiempo admitidas:

  • s - segundos
  • m - minutos
  • h - horas
  • d - días

Uso de timeout con trabajos de UV

Para los trabajos de UV, también puedes especificar el tiempo de espera:

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

Si no especificas un tiempo de espera, se aplicará un tiempo de espera predeterminado a tu trabajo. Para tareas de larga duración, como el entrenamiento de modelos que pueden llevar horas, asegúrate de establecer un tiempo de espera adecuado para evitar terminaciones inesperadas del trabajo.

Supervisión de la duración de la tarea

Al ejecutar tareas largas, es buena práctica:

  • Estima la duración esperada de tu trabajo y configura un tiempo de espera con un margen de seguridad
  • Monitorea el progreso de tu trabajo a través de los registros
  • Comprueba el estado del trabajo para asegurarte de que no haya expirado
>>> 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)

Para más detalles sobre el parámetro de timeout, consulte la referencia de la API run_job.

Pasar variables de entorno y secretos

Puedes pasar variables de entorno a tu trabajo usando env y 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"},
... )

Variables de entorno integradas

Dentro del contenedor del trabajo, las siguientes variables de entorno están disponibles automáticamente:

VariableDescripción
JOB_IDEl identificador único del trabajo actual. Úselo para hacer referencia al trabajo de forma programática, por ejemplo, para almacenar las salidas en un conjunto de datos con un nombre único.
ACCELERATOREl tipo de acelerador disponible (p. ej., t4-medium, a10g-small, a100x4). Vacío si no hay acelerador.
CPU_CORESEl número de núcleos de CPU disponibles para el trabajo (p. ej., 2, 4, 8).
MEMORYLa cantidad de memoria disponible para el trabajo (p. ej., 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')}")
... """],
... )

Estas variables son útiles cuando necesitas crear identificadores únicos para las salidas, adaptar tu código según el hardware disponible o registrar información de recursos.

Etiquetas

Las etiquetas son pares clave=valor que adjuntan metadatos a un Job:

Usa name para facilitar la búsqueda e identificación de los Jobs en la interfaz. Los nombres son opcionales y no tienen que ser únicos:

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

Desde la CLI, pasa --name al crear un Job, o nombra un Job existente a través del comando labels:

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

hf jobs ls muestra una columna NAME y permite filtrar por nombre (un atajo para --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"},
... )

Si no se especifica un nombre, se deriva automáticamente a partir de la imagen de Docker o del script, junto con un hash corto (p. ej. python:3.12 foo --truc → python-3-12-1a2b3c4d). Desde la CLI, ese hash abarca el comando y la configuración de tiempo de ejecución resuelta (flavor, timeout, valores de entorno, …), por lo que la misma configuración siempre produce el mismo nombre, y cambiar una configuración —incluida una que provenga del encabezado [tool.hf-jobs] de un script— la modifica. Desde la API de Python, el hash solo abarca el comando.

Actualizar etiquetas

Use update_job_labels() para reemplazar las etiquetas de un trabajo existente. Esto reemplaza todas las etiquetas proporcionadas por el usuario:

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

Esto también funciona para trabajos programados con 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"})

Desde la CLI:

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

Para eliminar todas las etiquetas, pase --clear:

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

UV Scripts (Experimental)

¿Buscas scripts de UV listos para usar? Consulta la organización uv-scripts en el Hugging Face Hub, que ofrece una colección comunitaria de scripts de UV para tareas como entrenamiento de modelos, generación de datos sintéticos, procesamiento de datos y más.

Ejecuta scripts de UV (scripts de Python con dependencias integradas) en la infraestructura de 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"])

Los scripts de UV son scripts de Python que incluyen sus dependencias directamente en el archivo mediante una sintaxis de comentario especial. Esto los hace perfectos para tareas autónomas que no requieren configuraciones de proyecto complejas. Obtenga más información sobre los scripts de UV en la documentación de UV.

Incluya la configuración de lanzamiento con el script

Un script que solo se ejecuta correctamente en un entorno de ejecución específico puede incluir ese entorno en una tabla opcional [tool.hf-jobs] de su encabezado 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 se inicia a continuación con la imagen, el hardware y el intérprete adecuados, y --flavor, -e, … siguen sobrescribiendo lo que declara el script. Consulte la guía de la CLI para obtener la lista completa de claves y las reglas de fusión.

La tabla solo la lee la CLI hf: run_uv_job() y create_scheduled_uv_job() la ignoran y usan exactamente los argumentos que se les pasan. En otras palabras, run_uv_job("ocr.py") y hf jobs uv run ocr.py no ejecutan el mismo Job: la API de Python necesita que se pasen explícitamente image=, flavor=, …

Imágenes de Docker para scripts de UV

Aunque los scripts de UV pueden especificar sus dependencias de forma inline, las cargas de trabajo de ML suelen tener dependencias complejas. El uso de imágenes de Docker precompiladas con estas bibliotecas ya instaladas puede acelerar significativamente el inicio de los trabajos y evitar problemas de dependencias.

Por defecto, al ejecutar hf jobs uv run se utiliza la imagen astral-sh/uv:python3.12-bookworm. Esta imagen se basa en la distribución Python 3.12 Bookworm con uv preinstalado.

Puedes especificar una imagen diferente usando la bandera --image:

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

El comando anterior se ejecutará utilizando la imagen vllm/vllm-openai:latest. Este enfoque podría ser útil si estás utilizando vLLM para la generación de datos sintéticos.

Muchos marcos de inferencia proporcionan imágenes de docker optimizadas. A medida que uv se adopta cada vez más en el ecosistema de Python, más de estas imágenes también tendrán uv preinstalado, lo que significa que funcionarán al usar hf jobs uv run.

Tareas programadas

Programa y gestiona trabajos que se ejecutarán en la infraestructura de HF.

Use create_scheduled_job() o create_scheduled_uv_job() con un horario de @annually, @yearly, @monthly, @weekly, @daily, @hourly o una expresión de horario CRON (p. ej., "0 9 * * 1" para las 9:00 de cada lunes):

# 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")

Use los mismos parámetros que run_job() y run_uv_job() para pasar variables de entorno, secretos, timeout, etc.

Gestione los trabajos programados con list_scheduled_jobs(), inspect_scheduled_job(), suspend_scheduled_job(), resume_scheduled_job(), update_scheduled_job_schedule(), trigger_scheduled_job() y 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)

Activar trabajos con webhooks

Los webhooks le permiten escuchar nuevos cambios en repositorios específicos o en todos los repositorios que pertenecen a un conjunto particular de usuarios u organizaciones (no solo sus repositorios, sino cualquier repositorio).

Use create_webhook() para crear un webhook que active un Job cuando se produzca un cambio en un repositorio de 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"
)

El webhook activa el Job con la carga del webhook en la variable de entorno WEBHOOK_PAYLOAD. Puede encontrar más información sobre los webhooks en la documentación de webhooks.

Update on GitHub