Hub Python 庫文件
管理你的空間
並獲得增強的文件體驗
開始使用
管理你的空間
本指南將介紹如何使用 huggingface_hub
管理你的 Space 執行時(金鑰、硬體和儲存)。
一個簡單示例:配置金鑰和硬體。
這是一個在 Hub 上建立和設定 Space 的端到端示例。
1. 在 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")
1. (續) 複製一個 Space。
如果你想從現有 Space 的基礎上構建,而不是從頭開始,這會很有用。如果你想控制公共 Space 的配置/設定,這也會很有用。有關更多詳細資訊,請參閱 duplicate_space()。
>>> api.duplicate_space("multimodalart/dreambooth-training")
2. 使用你偏好的解決方案上傳你的程式碼。
這是一個將本地資料夾 src/
從你的機器上傳到你的 Space 的示例
>>> api.upload_folder(repo_id=repo_id, repo_type="space", folder_path="src/")
在此步驟中,你的應用程式應該已經在 Hub 上免費運行了!但是,你可能希望使用金鑰和升級的硬體進一步配置它。
3. 配置金鑰和變數
你的 Space 可能需要一些金鑰、令牌或變數才能工作。有關更多詳細資訊,請參閱文件。例如,一個 HF 令牌,用於在你的 Space 生成影像資料集後將其上傳到 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")
金鑰和變數也可以刪除
>>> api.delete_space_secret(repo_id=repo_id, key="HF_TOKEN")
>>> api.delete_space_variable(repo_id=repo_id, key="MODEL_REPO_ID")
額外提示:在建立或複製 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_space(
... from_id=repo_id,
... secrets=[{"key"="HF_TOKEN", "value"="hf_api_***"}, ...],
... variables=[{"key"="MODEL_REPO_ID", "value"="user/repo"}, ...],
... )
4. 配置硬體
預設情況下,你的 Space 將在免費的 CPU 環境中執行。你可以升級硬體以在 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"
你現在擁有一個完全配置好的 Space。請確保在使用完畢後將你的 Space 降級回“cpu-classic”。
額外提示:在建立或複製 Space 時請求硬體!
升級後的硬體將在你的 Space 構建完成後自動分配。
>>> api.create_repo(
... repo_id=repo_id,
... repo_type="space",
... space_sdk="gradio"
... space_hardware="cpu-upgrade",
... space_storage="small",
... space_sleep_time="7200", # 2 hours in secs
... )
>>> api.duplicate_space(
... from_id=repo_id,
... hardware="cpu-upgrade",
... storage="small",
... sleep_time="7200", # 2 hours in secs
... )
5. 暫停和重啟你的 Space
預設情況下,如果你的 Space 正在升級後的硬體上執行,它將永遠不會停止。但是為了避免產生費用,你可能希望在你不用時暫停它。這可以透過 pause_space() 實現。暫停的 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 設定超時。如果你的 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_space(
... from_id=repo_id,
... hardware="t4-medium",
... sleep_time="3600",
... )
6. 為你的 Space 新增持久化儲存
你可以選擇你選擇的儲存層來訪問在你的 Space 重啟後仍能持久存在的磁碟空間。這意味著你可以像使用傳統硬碟一樣從磁碟讀寫。有關更多詳細資訊,請參閱文件。
>>> from huggingface_hub import SpaceStorage
>>> api.request_space_storage(repo_id=repo_id, storage=SpaceStorage.LARGE)
你也可以刪除儲存,從而永久丟失所有資料。
>>> api.delete_space_storage(repo_id=repo_id)
注意:一旦你的空間儲存層被授予,你將無法降低它。要降低儲存層,你必須先刪除現有儲存,然後請求新的所需層。
額外提示:在建立或複製 Space 時請求儲存!
>>> api.create_repo(
... repo_id=repo_id,
... repo_type="space",
... space_sdk="gradio"
... space_storage="large",
... )
>>> api.duplicate_space(
... from_id=repo_id,
... storage="large",
... )
更高階:臨時升級你的 Space!
Spaces 支援許多不同的用例。有時,你可能希望暫時在特定硬體上執行一個 Space,做一些事情然後將其關閉。在本節中,我們將探討如何利用 Spaces 按需微調模型。這只是解決這個特定問題的一種方法。它應被視為一種建議,並根據你的用例進行調整。
假設我們有一個用於微調模型的 Space。它是一個 Gradio 應用程式,輸入是模型 ID 和資料集 ID。工作流程如下:
- (提示使用者輸入模型和資料集)
- 從 Hub 載入模型。
- 從 Hub 載入資料集。
- 在資料集上微調模型。
- 將新模型上傳到 Hub。
步驟 3 需要自定義硬體,但你不希望你的 Space 始終在付費 GPU 上執行。一種解決方案是在訓練期間動態請求硬體,然後在訓練結束後關閉它。由於請求硬體會重新啟動你的 Space,你的應用程式必須以某種方式“記住”當前正在執行的任務。有多種方法可以做到這一點。在本指南中,我們將介紹一種使用資料集作為“任務排程器”的解決方案。
應用骨架
你的應用程式將看起來像這樣。在啟動時,檢查是否有計劃任務,如果存在,則在正確的硬體上執行它。完成後,將硬體設定回免費 CPU,並提示使用者進行新任務。
# 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()
)