Hub Python Library documentation

Управление вашим Space

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

Управление вашим Space

В этом руководстве мы рассмотрим, как управлять средой выполнения вашего Space (секреты, аппаратное обеспечение и тома) с помощью huggingface_hub.

Поиск по Spaces

Вы можете искать Spaces на Hub с помощью семантического поиска с использованием search_spaces(). Для запросов из нескольких слов используется поиск на основе эмбеддингов, а для запросов из одного слова — полнотекстовый поиск.

>>> from huggingface_hub import search_spaces
>>> results = list(search_spaces("generate image"))
>>> results[0]
SpaceSearchResult(id='mrfakename/Z-Image-Turbo', title='Z Image Turbo', sdk='gradio', likes=2867, ...)

Вы можете отфильтровать результаты по SDK или тегам:

>>> results = search_spaces("chatbot", sdk="gradio", filter="mcp-server")

Или через CLI:

>>> hf spaces search "generate image"
>>> hf spaces search "chatbot" --sdk gradio --limit 5

Простой пример: настройка секретов и оборудования.

Ниже приведен пример создания и настройки Space на Hub от начала до конца.

Создайте Space на Hub

>>> from huggingface_hub import HfApi
>>> repo_id = "Wauplin/my-cool-training-space"
>>> api = HfApi()

# For example with a Gradio SDK
>>> api.create_repo(repo_id=repo_id, repo_type="space", space_sdk="gradio")

Статические Spaces бесплатны для всех. Spaces на базе Gradio и Docker работают на вычислительных ресурсах: для бесплатного оборудования cpu-basic требуется подписка (PRO для пользователей, Team или Enterprise для организаций), тогда как для платного оборудования достаточно наличия биллинга (способа оплаты и предоплаченных кредитов). Без подписки создание, дублирование или перемещение Space на базе Gradio или Docker на cpu-basic завершается ошибкой оплаты (HTTP 402). Подробности см. в разделе тарифы.

Создание Space из шаблона

Вместо того чтобы начинать с пустого Space, вы можете создать новый Space на основе одного из официальных шаблонов, доступных на Hub (например, JupyterLab, чат-бот на Gradio, приложение на Streamlit и т. д.). Список доступных шаблонов можно получить с помощью list_space_templates(), после чего передать repo_id шаблона (или его краткое name) в качестве параметра space_template функции create_repo(). Обратите внимание, что space_sdk по-прежнему обязателен: шаблон заполняет файлы, а SDK устанавливает метаданные карточки.

>>> from huggingface_hub import HfApi
>>> api = HfApi()

# List available templates
>>> for template in api.list_space_templates():
...     print(f"{template.name} ({template.repo_id})")
Streamlit (streamlit/streamlit-template-space)
JupyterLab (SpacesExamples/jupyterlab)
chatbot (gradio-templates/chatbot)
...

# Create a Space from a template, by repo id or by short name
>>> api.create_repo(repo_id=repo_id, repo_type="space", space_template="SpacesExamples/jupyterlab")
>>> api.create_repo(repo_id=repo_id, repo_type="space", space_template="JupyterLab")

Некоторые шаблоны рекомендуется делать приватными (например, JupyterLab). Если вы явно не задаёте видимость, такие Spaces автоматически создаются как приватные.

Из CLI то же самое доступно через hf spaces templates и hf repos create --template:

# List available templates
>>> hf spaces templates
NAME            REPO_ID                                        SDK    PREFERRED_PRIVATE
--------------- ---------------------------------------------- ------ -----------------
Streamlit       streamlit/streamlit-template-space             docker
JupyterLab      SpacesExamples/jupyterlab                      docker ✔
Argilla         argilla/argilla-template-space                 docker
Livebook        livebook-dev/livebook                          docker
...

# Create a Space from a template
>>> hf repos create my-jupyterlab --type space --template jupyterlab

Дублирование Space

Это может оказаться полезным, если вы хотите создать новый Space на основе существующего, а не начинать с нуля. Это также полезно, если вы хотите контролировать конфигурацию и настройки публичного Space. Подробности см. в duplicate_repo().

>>> api.duplicate_repo("multimodalart/dreambooth-training", repo_type="space")

Загрузите ваш код с помощью предпочитаемого вами решения

Вот пример загрузки локальной папки src/ с вашего компьютера в ваш Space:

>>> api.upload_folder(repo_id=repo_id, repo_type="space", folder_path="src/")

На этом этапе ваше приложение уже должно работать на Hub! Однако вы можете дополнительно настроить его с помощью секретов и более мощного оборудования.

Настройка секретов и переменных

Вашему Space могут потребоваться секретные ключи, токены или переменные для работы. Подробнее см. в документации. Например, HF-токен для загрузки набора данных изображений в Hub после его генерации из вашего Space.

>>> api.add_space_secret(repo_id=repo_id, key="HF_TOKEN", value="hf_api_***")
>>> api.add_space_variable(repo_id=repo_id, key="MODEL_REPO_ID", value="user/repo")

Вы можете получить список существующих секретов и переменных. Значения секретов доступны только для записи, поэтому возвращаются только ключи, описания и метки времени последнего обновления:

>>> api.get_space_secrets(repo_id=repo_id)
{'HF_TOKEN': SpaceSecret(key='HF_TOKEN', description=None, updated_at=datetime.datetime(...))}
>>> api.get_space_variables(repo_id=repo_id)
{'MODEL_REPO_ID': SpaceVariable(key='MODEL_REPO_ID', value='user/repo', description=None, updated_at=...)}

Секреты и переменные также можно удалить:

>>> api.delete_space_secret(repo_id=repo_id, key="HF_TOKEN")
>>> api.delete_space_variable(repo_id=repo_id, key="MODEL_REPO_ID")

Внутри вашего Space секреты доступны в виде переменных окружения (или через Streamlit Secrets Management, если используется Streamlit). Не нужно запрашивать их через API!

Любое изменение конфигурации вашего Space (секреты или оборудование) приведёт к перезапуску вашего приложения.

Бонус: задайте секреты и переменные при создании или дублировании Space!

Секреты и переменные можно задать при создании или дублировании пространства:

>>> api.create_repo(
...     repo_id=repo_id,
...     repo_type="space",
...     space_sdk="gradio",
...     space_secrets=[{"key": "HF_TOKEN", "value": "hf_api_***"}, ...],
...     space_variables=[{"key": "MODEL_REPO_ID", "value": "user/repo"}, ...],
... )
>>> api.duplicate_repo(
...     from_id=repo_id,
...     repo_type="space",
...     space_secrets=[{"key": "HF_TOKEN", "value": "hf_api_***"}, ...],
...     space_variables=[{"key": "MODEL_REPO_ID", "value": "user/repo"}, ...],
... )

Настройка оборудования

По умолчанию ваш Space работает на бесплатном оборудовании cpu-basic (для Spaces на базе Gradio и Docker требуется подписка, см. выше). Вы можете обновить оборудование, чтобы запустить его на GPU. Для обновления вашего Space необходим способ оплаты и предоплаченные кредиты (или грант сообщества). Подробнее см. в документации.

# Use `SpaceHardware` enum
>>> from huggingface_hub import SpaceHardware
>>> api.request_space_hardware(repo_id=repo_id, hardware=SpaceHardware.T4_MEDIUM)

# Or simply pass a string value
>>> api.request_space_hardware(repo_id=repo_id, hardware="t4-medium")

Обновление оборудования не выполняется мгновенно, так как ваш Space должен быть перезагружен на наших серверах. В любой момент вы можете проверить, на каком оборудовании работает ваш Space, чтобы убедиться, что ваше запрос был выполнен.

>>> runtime = api.get_space_runtime(repo_id=repo_id)
>>> runtime.stage
"RUNNING_BUILDING"
>>> runtime.hardware
"cpu-basic"
>>> runtime.requested_hardware
"t4-medium"

Теперь у вас полностью настроенное пространство. Не забудьте вернуть пространство на cpu-basic, когда закончите его использовать.

Бонус: запросите оборудование при создании или дублировании Space!

Обновлённое оборудование будет автоматически назначено вашему Space после его сборки.

>>> api.create_repo(
...     repo_id=repo_id,
...     repo_type="space",
...     space_sdk="gradio",
...     space_hardware="cpu-upgrade",
...     space_sleep_time="7200", # 2 hours in secs
... )
>>> api.duplicate_repo(
...     from_id=repo_id,
...     repo_type="space",
...     space_hardware="cpu-upgrade",
...     space_sleep_time="7200", # 2 hours in secs
... )

Отслеживание вашей квоты ZeroGPU

Spaces ZeroGPU работают на общих GPU, выделяемых по запросу. Каждый раз, когда вы используете Space ZeroGPU (через интерфейс или его API), из вашей личной квоты вычитается определённое время работы GPU, которая периодически сбрасывается. Если вы разрабатываете приложение, агента или MCP-сервис на базе Spaces ZeroGPU, вы можете отслеживать своё использование с помощью get_zero_gpu_quota(). Значения выражаются в секундах GPU.

>>> quota = api.get_zero_gpu_quota()
>>> quota
ZeroGpuQuota(base=2400, remaining=1810, resets_at=datetime.datetime(2026, 9, 30, 9, 12, 3, tzinfo=datetime.timezone.utc), overquota_used=0)
>>> if quota.remaining < 60:
...     print(f"Less than 1 minute of ZeroGPU left. Quota resets at {quota.resets_at}.")

resets_at равно None, если вы не использовали ZeroGPU с момента последнего сброса. Если вы используете токен с тонким уровнем доступа, он должен иметь разрешение «Billing > Read billing usage and payment method status». Та же информация доступна из CLI с помощью hf spaces zero-gpu quota.

После исчерпания квоты пользователи PRO, Team и Enterprise могут продолжать использовать ZeroGPU Spaces, расходуя предоплаченные кредиты. Кредиты можно приобрести в разделе настроек биллинга. Подробнее см. в разделе Расширение квоты с помощью кредитов.

Приостановка и возобновление вашего Space

По умолчанию, если ваш Space работает на обновлённом оборудовании, он никогда не останавливается. Однако, чтобы избежать списаний, вы можете приостановить его, когда он не используется. Это можно сделать с помощью pause_space(). Приостановленный Space будет неактивен, пока владелец Space не перезапустит его, либо через интерфейс, либо через API с помощью restart_space(). Подробнее о режиме приостановки см. в этом разделе

# Pause your Space to avoid getting billed
>>> api.pause_space(repo_id=repo_id)
# (...)
# Restart it when you need it
>>> api.restart_space(repo_id=repo_id)

Ещё один вариант — установить тайм-аут для вашего Space. Если ваш Space неактивен дольше заданного тайм-аута, он перейдёт в спящий режим. Любой посетитель, открывший ваш Space, запустит его снова. Вы можете установить тайм-аут с помощью set_space_sleep_time(). Подробнее о спящем режиме см. в этом разделе.

# Put your Space to sleep after 1h of inactivity
>>> api.set_space_sleep_time(repo_id=repo_id, sleep_time=3600)

Примечание: если вы используете оборудование ‘cpu-basic’, вы не можете настроить время сна. Ваше Space будет автоматически приостановлено после 48 часов бездействия.

Бонус: установите время сна при запросе оборудования

Обновлённое оборудование будет автоматически назначено вашему Space после его сборки.

>>> api.request_space_hardware(repo_id=repo_id, hardware=SpaceHardware.T4_MEDIUM, sleep_time=3600)

Бонус: задайте время сна при создании или дублировании Space!

>>> api.create_repo(
...     repo_id=repo_id,
...     repo_type="space",
...     space_sdk="gradio",
...     space_hardware="t4-medium",
...     space_sleep_time="3600",
... )
>>> api.duplicate_repo(
...     from_id=repo_id,
...     repo_type="space",
...     space_hardware="t4-medium",
...     space_sleep_time="3600",
... )

Отладка неработающего Space с помощью чтения его журналов

Если сборка Space завершается ошибкой или он аварийно завершает работу во время выполнения, логи, которые обычно просматриваются в браузере, также доступны программно через fetch_space_logs(). Это особенно полезно в скриптах или агентных рабочих процессах, где открытие браузера невозможно.

# Drain the currently available run logs and return immediately (like `docker logs`)
>>> for line in api.fetch_space_logs(repo_id=repo_id):
...     print(line, end="")

# Read the container build logs instead (useful when the Space is stuck in BUILD_ERROR)
>>> for line in api.fetch_space_logs(repo_id=repo_id, build=True):
...     print(line, end="")

# Stream run logs in real time until the server closes the stream (Ctrl-C to stop)
>>> for line in api.fetch_space_logs(repo_id=repo_id, follow=True):
...     print(line, end="")

Та же функциональность доступна из CLI:

hf spaces logs username/my-space             # drain run logs
hf spaces logs username/my-space --build     # read build logs
hf spaces logs username/my-space -f          # stream in real time
hf spaces logs username/my-space -n 50       # last 50 lines only

Подключение к Space по SSH (режим разработки)

Dev Mode позволяет подключиться по SSH к работающему контейнеру Space для отладки и разработки в реальном времени. Используйте hf spaces ssh, чтобы открыть сессию прямо из терминала. Если Dev Mode ещё не включён для Space, CLI предложит включить его (или передайте --auto, чтобы пропустить запрос).

Ваш публичный SSH-ключ должен быть зарегистрирован в настройках.

# SSH into a Space (enables Dev Mode if needed)
hf spaces ssh username/my-space

# Auto-enable Dev Mode without prompting
hf spaces ssh username/my-space --auto

# Print the SSH command without running it
hf spaces ssh username/my-space --dry-run

# Use a specific SSH key
hf spaces ssh username/my-space -i ~/.ssh/id_ed25519

Вы также можете включить Dev Mode без SSH с помощью hf spaces dev-mode, который выводит инструкции по подключению для SSH, VS Code, Cursor и Windsurf:

hf spaces dev-mode username/my-space

Включение режима Dev требует тарифного плана PRO или Team & Enterprise. Отключение режима всегда разрешено, например, если ваша подписка истекла, а режим Dev был включен:

hf spaces dev-mode username/my-space --stop

Подключение томов в вашем Space

Вы можете подключить ресурсы Hub (модели, наборы данных или хранилища) в качестве томов в контейнере вашего Space. Это обеспечивает прямому доступу файловой системы вашего Space к этим ресурсам без необходимости их загрузки в коде. Тома можно задать непосредственно при создании или дублировании Space:

>>> from huggingface_hub import Volume
>>> api.create_repo(
...     repo_id=repo_id,
...     repo_type="space",
...     space_sdk="gradio",
...     space_volumes=[
...         Volume(type="model", source="username/my-model", mount_path="/models", read_only=True),
...         Volume(type="bucket", source="username/my-bucket", mount_path="/data"),
...     ],
... )
>>> api.duplicate_repo(
...     from_id=repo_id,
...     repo_type="space",
...     space_volumes=[
...         Volume(type="model", source="username/my-model", mount_path="/models", read_only=True),
...         Volume(type="bucket", source="username/my-bucket", mount_path="/data"),
...     ],
... )

Вы можете проверить, какие тома в данный момент смонтированы через рантайм Space:

>>> runtime = api.get_space_runtime(repo_id=repo_id)
>>> runtime.volumes
[Volume(type='model', source='username/my-model', mount_path='/models', read_only=True), ...]

Если вам нужно обновить тома в существующем Space, используйте set_space_volumes(). Обратите внимание, что эта функция заменяет все ранее смонтированные тома.

>>> api.set_space_volumes(
...     repo_id=repo_id,
...     volumes=[
...         Volume(type="model", source="username/my-model", mount_path="/models", read_only=True),
...         Volume(type="dataset", source="username/my-dataset", mount_path="/data", read_only=True),
...         Volume(type="bucket", source="username/my-bucket", mount_path="/output"),
...     ],
... )

Чтобы удалить все тома из вашего Space:

>>> api.delete_space_volumes(repo_id=repo_id)

Модели, наборы данных и Spaces всегда монтируются только для чтения. Только хранилища поддерживают монтирование с возможностью чтения и записи.

Установка томов заменяет ранее смонтированные тома. Чтобы добавить том в существующий список, сначала прочитайте текущие тома из среды выполнения и включите их в новый список.

Все операции с томами также доступны из CLI:

# List current volumes
hf spaces volumes ls username/my-space

# Set (replace) volumes
hf spaces volumes set username/my-space \
    -v hf://models/username/my-model:/models \
    -v hf://buckets/username/my-bucket:/data

# Remove all volumes
hf spaces volumes delete username/my-space

Более продвинутый вариант: временно повысьте уровень вашего Space!

Spaces поддерживают множество различных сценариев использования. Иногда может потребоваться временно запустить Space на конкретном оборудовании, выполнить определённые действия, а затем остановить его. В этом разделе мы рассмотрим, как использовать Spaces для дообучения модели по запросу. Это лишь один из способов решения данной задачи. Его следует воспринимать как рекомендацию и адаптировать под ваш конкретный сценарий использования.

Допустим, у нас есть Space для дообучения модели. Это приложение на Gradio, которое принимает на вход идентификатор модели и идентификатор набора данных. Рабочий процесс выглядит следующим образом:

  1. (Запросите у пользователя модель и набор данных)
  2. Загрузите модель из Hub.
  3. Загрузите набор данных из Hub.
  4. Довыучите модель на наборе данных.
  5. Загрузите новую модель в Hub.

Шаг 3. требует специального оборудования, но вы не хотите, чтобы ваше Space постоянно работало на платном GPU. Решение — динамически запрашивать оборудование для обучения и отключать его после завершения. Поскольку запрос оборудования перезапускает ваше Space, ваше приложение каким-то образом должно «запоминать» текущую выполняемую задачу. Существует несколько способов сделать это. В этом руководстве мы рассмотрим одно решение с использованием Dataset в качестве «планировщика задач».

Каркас приложения

Вот как будет выглядеть ваше приложение. При запуске проверьте, запланирована ли задача, и если да, выполните её на соответствующем оборудовании. После завершения верните оборудование в свободное состояние cpu-basic и предложите пользователю новую задачу.

Такой рабочий процесс не поддерживает одновременный доступ, как обычные демо. В частности, интерфейс будет отключён во время обучения. Рекомендуется сделать репозиторий приватным, чтобы вы были единственным пользователем.

# Space will need your token to request hardware: set it as a Secret !
HF_TOKEN = os.environ.get("HF_TOKEN")

# Space own repo_id
TRAINING_SPACE_ID = "Wauplin/dreambooth-training"

from huggingface_hub import HfApi, SpaceHardware
api = HfApi(token=HF_TOKEN)

# On Space startup, check if a task is scheduled. If yes, finetune the model. If not,
# display an interface to request a new task.
task = get_task()
if task is None:
    # Start Gradio app
    def gradio_fn(task):
        # On user request, add task and request hardware
        add_task(task)
        api.request_space_hardware(repo_id=TRAINING_SPACE_ID, hardware=SpaceHardware.T4_MEDIUM)

    gr.Interface(fn=gradio_fn, ...).launch()
else:
    runtime = api.get_space_runtime(repo_id=TRAINING_SPACE_ID)
    # Check if Space is loaded with a GPU.
    if runtime.hardware == SpaceHardware.T4_MEDIUM:
        # If yes, finetune base model on dataset !
        train_and_upload(task)

        # Then, mark the task as "DONE"
        mark_as_done(task)

        # DO NOT FORGET: set back CPU hardware
        api.request_space_hardware(repo_id=TRAINING_SPACE_ID, hardware=SpaceHardware.CPU_BASIC)
    else:
        api.request_space_hardware(repo_id=TRAINING_SPACE_ID, hardware=SpaceHardware.T4_MEDIUM)

Планировщик задач

Планирование задач можно выполнять множеством способов. Ниже приведен пример того, как это можно сделать с помощью простого CSV-файла, сохраненного в виде Dataset.

# Dataset ID in which a `tasks.csv` file contains the tasks to perform.
# Here is a basic example for `tasks.csv` containing inputs (base model and dataset)
# and status (PENDING or DONE).
#     multimodalart/sd-fine-tunable,Wauplin/concept-1,DONE
#     multimodalart/sd-fine-tunable,Wauplin/concept-2,PENDING
TASK_DATASET_ID = "Wauplin/dreambooth-task-scheduler"

def _get_csv_file():
    return hf_hub_download(repo_id=TASK_DATASET_ID, filename="tasks.csv", repo_type="dataset", token=HF_TOKEN)

def get_task():
    with open(_get_csv_file()) as csv_file:
        csv_reader = csv.reader(csv_file, delimiter=',')
        for row in csv_reader:
            if row[2] == "PENDING":
                return row[0], row[1] # model_id, dataset_id

def add_task(task):
    model_id, dataset_id = task
    with open(_get_csv_file()) as csv_file:
        with open(csv_file, "r") as f:
            tasks = f.read()

    api.upload_file(
        repo_id=repo_id,
        repo_type=repo_type,
        path_in_repo="tasks.csv",
        # Quick and dirty way to add a task
        path_or_fileobj=(tasks + f"\n{model_id},{dataset_id},PENDING").encode()
    )

def mark_as_done(task):
    model_id, dataset_id = task
    with open(_get_csv_file()) as csv_file:
        with open(csv_file, "r") as f:
            tasks = f.read()

    api.upload_file(
        repo_id=repo_id,
        repo_type=repo_type,
        path_in_repo="tasks.csv",
        # Quick and dirty way to set the task as DONE
        path_or_fileobj=tasks.replace(
            f"{model_id},{dataset_id},PENDING",
            f"{model_id},{dataset_id},DONE"
        ).encode()
    )
Update on GitHub