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