Hub Python Library documentation
Управление вашим Space
Управление вашим 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, которое принимает на вход идентификатор модели и идентификатор набора данных. Рабочий процесс выглядит следующим образом:
- (Запросите у пользователя модель и набор данных)
- Загрузите модель из Hub.
- Загрузите набор данных из Hub.
- Довыучите модель на наборе данных.
- Загрузите новую модель в 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()
)