Hub Python Library documentation

运行和管理任务

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

运行和管理任务

Hugging Face Hub 通过 Jobs 为 AI 和数据工作流提供计算资源。

有关 Jobs 和定价的总体概述,请参阅 Hub Jobs 文档。

任务在 Hugging Face 基础设施上运行,其定义包括要执行的命令(例如 python 命令)、来自 Hugging Face Spaces 或 Docker Hub 的 Docker 镜像,以及硬件类型(CPU、GPU、TPU)。本指南将展示如何与 Hub 上的任务进行交互,特别是:

  • 运行一个任务。
  • 检查任务状态。
  • 选择硬件。
  • 配置环境变量和密钥。
  • 运行 UV 脚本。

如果您想在 Hub 上运行和管理任务,您的机器必须处于已登录状态。如果尚未登录,请参阅此部分。在本指南的其余部分中,我们将假设您的机器已登录。

Hugging Face Jobs 面向任何拥有正数信用余额的用户或组织。有关详细信息,请参阅Jobs 定价与计费。

Jobs 命令行界面

使用 hf jobs CLI 从命令行运行 Jobs,并传入 --flavor 以指定您的硬件。

hf jobs run 使用 Docker 镜像和命令来运行 Jobs,其界面与 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 命令行界面指南。

如果需要一台交互式机器,而不是即发即忘的任务——例如,为了运行 AI 生成的代码,并支持命令执行和文件传输?请查看基于 Jobs 构建的Sandboxes。

运行任务

在 Hugging Face 基础设施(包括 GPU 和 TPU)上运行使用命令和 Docker Image 定义的 compute 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,其中包含 Hugging Face 上该 Job 的 URL,您可以在此查看 Job 状态和日志。 请保存 JobInfo 中的 Job ID 以管理该任务:

>>> 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() 监控资源使用情况。

重试并重新运行 Job

使用 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 会启动一个具有新 ID 的独立 Job。它适用于已完成或失败的 Job,并会复用已保存的 spec,包括 secrets 和硬件设置。你也可以运行 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)

等待任务完成

使用 wait_for_job() 阻塞,直到 Job 到达终止阶段(COMPLETED、CANCELED、ERROR 或 DELETED)。始终会返回最终的 JobInfo —— 失败的 Job 不会引发异常 —— 因此请检查 job.status.stage 以根据结果采取行动。传入 Job ID 列表可一次性等待整个批次。

>>> 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,它仅在所有 Job 均成功完成时以退出码 0 结束——非常适合在 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 可以正确链接,无需显式等待。

选择硬件

在以下多种场景中,在 GPU 上运行 Jobs 非常有用:

  • 模型训练:在 GPU(T4、A10G、A100)上微调或训练模型,无需管理基础设施
  • 合成数据生成:在高性能硬件上使用 LLM 生成大规模数据集
  • 数据处理:使用高 CPU 配置处理大规模数据集,以应对并行工作负载
  • 批量推理:使用优化的 GPU 配置对数千个样本运行离线推理
  • 实验与基准测试:在一致的硬件上运行机器学习实验,以获得可复现的结果
  • 开发与调试:无需本地 CUDA 环境即可测试 GPU 代码

使用 flavor 参数在 GPU 或 TPU 上运行任务。例如,要在 A10G GPU 上运行 PyTorch 任务:

# 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

使用此命令通过 UV 运行微调脚本,例如 trl/scripts/sft.py:

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

如需了解如何在 Hugging Face 基础设施上使用 TRL 运行模型训练任务的全面指南,请参阅 TRL Jobs 训练文档。该文档涵盖了微调方案、硬件选择以及高效训练模型的最佳实践。

以下是可用于运行 Jobs 的完整硬件列表:

name友好名称cpuram存储accelerator成本/分钟每小时成本
cpu-basicCPU 基础2 个 vCPU16 GB50 GB-$0.0002$0.01
cpu-upgradeCPU 升级8 个 vCPU32 GB50 GB-$0.0005$0.03
cpu-performanceCPU 性能32 个 vCPU256 GB1024 GB-$0.0317$1.90
cpu-xlCPU XL16 个 vCPU124 GB1000 GB-$0.0167$1.00
t4-smallNvidia T4 - 小型4 个 vCPU15 GB50 GB1x T4 (16 GB)$0.0067$0.40
t4-mediumNvidia T4 - 中等8 个 vCPU30 GB100 GB1x T4 (16 GB)$0.0100$0.60
a10g-smallNvidia A10G - 小型4 个 vCPU15 GB110 GB1x A10G (24 GB)$0.0167$1.00
a10g-largeNvidia A10G - 大型12 个 vCPU46 GB200 GB1x A10G (24 GB)$0.0250$1.50
a10g-largex22x Nvidia A10G - 大型24 个 vCPU92 GB1000 GB2x A10G (48 GB)$0.0500$3.00
a10g-largex44x Nvidia A10G - 大型48 个 vCPU184 GB2000 GB4x A10G (96 GB)$0.0833$5.00
a100-largeNvidia A100 - 大型12 个 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

您可以通过运行以下命令以编程方式获取此列表:

>>> hf jobs hardware

或者使用 Python API:

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

就是这样!你现在已经在 Hugging Face 的基础设施上运行代码了。

挂载卷

使用 Volume 列表在 Jobs 的磁盘上挂载卷。

您可以挂载任何 Hugging Face 仓库(模型/数据集/空间)或 存储桶。例如:

  • 挂载模型仓库: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():它会将本地目录同步到您的 jobs-artifacts Storage Bucket(如有需要会自动创建),并返回一个可直接挂载的 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 代理使容器端口可访问。访问需要具有该 Job 命名空间读取权限的 HF token。若要允许无需身份验证即可访问,请改用 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 和定时 Job 时,这两个选项也可用。

SSH 到作业

将 ssh=True 传递给 run_job()(或 run_uv_job()),即可通过 SSH 访问该 Job 的容器。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

只有对 Job 命名空间具有写入权限的用户(即 Job 创建者或所有者组织的成员)才被允许进入,并通过在 https://huggingface.co/settings/keys 注册的 SSH 公钥进行身份验证。

网络组

将 network_group="<name>" 传递给 run_job()(或 run_uv_job()),以便同一命名空间和资源组中的 Jobs 能够在所有端口上相互访问。在每个成员内部,HF_NETWORK_GROUP_HOSTNAME 会解析为组内的所有 Job,而 ${HF_NETWORK_GROUP_PREFIX}<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 - 天

在 UV 作业中使用 timeout

对于 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 参数的更多详细信息,请参阅 run_job API 参考。

传递环境变量和密钥

您可以使用 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 可以更轻松地在 UI 中查找和识别 Job。名称是可选的,且无需唯一:

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

在 CLI 中,创建 Job 时传入 --name,或通过 labels 命令为现有 Job 命名:

>>> 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、超时、环境变量值等),因此相同的配置始终生成相同的名称,而更改任何设置——包括来自脚本 [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"})

从命令行:

>>> 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 脚本?请查看 Hugging Face Hub 上的 uv-scripts 组织,它提供了一个社区脚本合集,涵盖模型训练、合成数据生成、数据处理等多种任务。

在 HF 基础设施上运行 UV 脚本(带有内联依赖项的 Python 脚本):

# 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 文档。

将启动配置与脚本一起发布

仅在特定运行时上才能正确运行的脚本,可以在其 PEP 723 头部的可选 [tool.hf-jobs] 表中携带该运行时:

# /// 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 指南。

该表格仅由 hf CLI 读取:run_uv_job() 和 create_scheduled_uv_job() 会忽略该表格,并严格使用传入的参数。换句话说,run_uv_job("ocr.py") 和 hf jobs uv run ocr.py 不会 运行相同的 Job —— Python API 需要显式传入 image=、flavor= 等参数。

用于 UV 脚本的 Docker 镜像

虽然 UV 脚本可以内联指定其依赖项,但机器学习工作负载通常具有复杂的依赖关系。使用已预装这些库的预构建 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 点):

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

通过 Webhook 触发任务

Webhooks 允许你监听特定仓库上的新变更,或监听属于特定用户/组织集合的所有仓库(不仅限于你自己的仓库,而是任意仓库)。

使用 create_webhook() 创建一个 webhook,当 Hugging Face 仓库中发生更改时触发 Job:

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

Webhook 会触发 Job,并将 webhook 负载存储在环境变量 WEBHOOK_PAYLOAD 中。 您可以在 Webhooks 文档 中了解有关 Webhook 的更多信息。

Update on GitHub