Hub Python 庫文件

管理你的 Space

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

管理你的 Space

在本指南中,我們將瞭解如何使用 huggingface_hub 管理你的 Space 執行時(Secrets硬體儲存)。

一個簡單的例子:配置 Secrets 和硬體。

下面是一個在 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. (bis) 複製一個 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 上免費執行!但是,你可能希望使用 Secrets 和升級的硬體對其進行進一步配置。

3. 配置 Secrets 和變數

你的 Space 可能需要一些 Secret 金鑰、令牌或變數才能執行。有關更多詳細資訊,請參閱 文件。例如,一個 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")

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_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。請務必在你不再使用它時將其降級回“cpu-classic”。

獎勵:在建立或複製 Space 時請求硬體!

升級後的硬體將在 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 或透過 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 構建完成後自動分配給你的 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 的儲存層。要做到這一點,你必須先刪除儲存,然後請求新的所需層。

獎勵:在建立或複製 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 作為輸入。工作流程如下:

  1. (提示使用者輸入模型和資料集)
  2. 從 Hub 載入模型。
  3. 從 Hub 載入資料集。
  4. 在資料集上微調模型。
  5. 將新模型上傳到 Hub。

步驟 3 需要自定義硬體,但你不想讓你的 Space 一直執行在付費 GPU 上。一種解決方案是動態請求用於訓練的硬體,然後在之後將其關閉。由於請求硬體會重新啟動你的 Space,因此你的應用程式必須以某種方式“記住”它當前正在執行的任務。有多種方法可以實現這一點。在本指南中,我們將看到一種使用 Dataset 作為“任務排程程式”的解決方案。

應用程式框架

你的應用程式看起來會是這樣的。啟動時,檢查是否有任務被安排,如果有,則在正確的硬體上執行它。完成後,將硬體設定回免費的 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)

任務排程程式

任務排程可以透過多種方式完成。這是一個使用儲存為 Dataset 的簡單 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()
    )
在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.