Hub Python 函式庫文件
管理您的 Space
並獲得增強的文件體驗
開始使用
管理您的 Space
在本指南中,我們將介紹如何使用 huggingface_hub 來管理您的 Space 執行環境(Secrets、硬體及 Volumes)。
搜尋 Spaces
您可以使用 search_spaces() 透過語意搜尋功能在 Hub 上搜尋 Spaces。對於多字查詢,它會使用基於嵌入 (embedding) 的搜尋;對於單字查詢,則使用全文檢索。
>>> 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 或標籤 (tags) 來篩選結果。
>>> results = search_spaces("chatbot", sdk="gradio", filter="mcp-server")或透過 CLI
>>> hf spaces search "generate image"
>>> hf spaces search "chatbot" --sdk gradio --limit 5簡單範例:設定 Secrets 與硬體。
以下是一個在 Hub 上建立並設定 Space 的端對端範例。
在 Hub 上建立 Space
>>> 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")複製 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 上免費執行了!不過,您可能需要透過 Secrets 與升級的硬體來進一步設定它。
設定 Secrets 與變數
您的 Space 可能需要某些秘密金鑰 (secret keys)、Token 或變數才能運作。詳情請參閱文件。例如,當您的 Space 產生影像資料集時,需要一個 HF Token 將其上傳至 Hub。
>>> 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")您可以列出現有的 Secrets 與變數。秘密值僅供寫入 (write-only),因此只會返回鍵值、說明及更新時間戳記。
>>> 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=...)}Secrets 與變數也可以刪除。
>>> api.delete_space_secret(repo_id=repo_id, key="HF_TOKEN")
>>> api.delete_space_variable(repo_id=repo_id, key="MODEL_REPO_ID")在 Space 內部,Secrets 可作為環境變數使用(若使用 Streamlit,則為 Streamlit Secrets Management)。不需要透過 API 取得它們!
任何 Space 組態(Secrets 或硬體)的變更都會觸發應用程式重新啟動。
加碼:在建立或複製 Space 時設定 Secrets 與變數!
在建立或複製 Space 時,可以設定 Secrets 與變數。
>>> 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 環境中免費執行。您可以升級硬體以在 GPU 上執行。存取或升級您的 Space 需要付款卡或社群補助 (community grant)。詳情請參閱文件。
# 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"現在您已擁有一個完整設定的 Space。當您使用完畢後,請務必將 Space 降級回 “cpu-classic”。
加碼:在建立或複製 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
... )暫停並重新啟動您的 Space
預設情況下,如果您的 Space 在升級硬體上執行,它將不會被停止。然而,為了避免產生費用,您可能希望在不使用時將其暫停。這可以使用 pause_space() 來實現。暫停的 Space 將處於非活動狀態,直到擁有者透過 UI 或使用 restart_space() 的 API 將其重新啟動。關於暫停模式的更多詳細資訊,請參閱此章節。
# 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 設定逾時 (timeout)。如果您的 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 小時無活動後自動暫停。
透過閱讀記錄 (logs) 來偵錯故障的 Space
當 Space 建置失敗或在執行期間崩潰時,您通常在瀏覽器中看到的記錄,也可以透過 fetch_space_logs() 以程式方式存取。這在腳本或代理工作流程 (agentic workflows) 中特別有用,因為在這些情況下開啟瀏覽器並不可行。
# 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 建置完成後自動指派給它。
>>> 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 中掛載 Volumes
您可以將 Hub 資源(模型、資料集或儲存區)掛載為 Space 容器中的 Volumes。這讓您的 Space 可以直接存取這些資源的檔案系統,而無需在程式碼中下載它們。Volumes 可以在建立或複製 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 執行環境檢查目前掛載了哪些 Volumes。
>>> 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 上的 Volumes,請使用 set_space_volumes()。請注意,這會替換所有先前掛載的 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 移除所有 Volumes:
>>> api.delete_space_volumes(repo_id=repo_id)模型、資料集和 Spaces 總是以唯讀方式掛載。只有儲存區 (storage buckets) 支援讀寫掛載。
設定 Volumes 會取代任何先前掛載的 Volumes。若要將 Volume 新增至現有清單,請先從執行環境中讀取目前的 Volumes,並將其包含在新的清單中。
所有 Volume 操作也可以從 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 應用程式,將模型 ID 和資料集 ID 作為輸入。工作流程如下:
- (提示使用者輸入模型和資料集)
- 從 Hub 載入模型。
- 從 Hub 載入資料集。
- 在資料集上微調模型。
- 將新模型上傳至 Hub。
第 3 步需要自訂硬體,但您不希望您的 Space 一直在付費 GPU 上執行。一種解決方案是動態請求訓練所需的硬體,並在事後將其關閉。由於請求硬體會重新啟動您的 Space,因此您的應用程式必須以某種方式「記住」它正在執行的當前任務。有多種方法可以做到這一點。在本指南中,我們將介紹一種使用資料集作為「任務排程器」的解決方案。
應用程式骨架
這是您的應用程式的樣子。啟動時,檢查是否有排定的任務,如果有,則在正確的硬體上執行它。完成後,將硬體設定回免費方案的 CPU,並提示使用者進行新任務。
此類工作流程不支援像一般展示那樣的並發存取。特別是,當訓練發生時,介面將被停用。最好將您的儲存庫 (repo) 設定為私有,以確保您是唯一的使用者。
# 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 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()
)