GPUtw 說明文件

監控與實驗追蹤

在訓練進行中查看 GPU 用量,並用 Weights & Biases 與 Hugging Face 記錄每次執行的結果。

兩個不同的問題

「GPU 現在有在工作嗎?」與「這個 checkpoint 是哪一次執行產生的?」要用不同的工具回答,把兩者混為一談,通常的結果是兩邊都沒做好。

  • 資源監控: 即時使用率、VRAM、RAM 與磁碟。用來確認你付費租用的硬體是否真的在工作,不需安裝任何東西。
  • 實驗追蹤: loss 曲線、超參數與產出物,在執行個體刪除後仍然保留。這是 Weights & Biases 的用途。
  • 模型與資料集管理: 把權重抓進來、把成果推出去,並把快取放在執行個體消失後仍存在的位置。這是 Hugging Face 搭配 /vault 的用途。

控制台已經顯示的資訊

每一台執行中的執行個體都會在「執行個體」頁面回報即時使用率,不需安裝代理程式、也不需設定。同樣的數字也在 API 上,而且這才是判斷租用資源用了多少的可靠依據:

GET/api/instances/{id}/resources
Info

磁碟用量也應以此為準。容器內 df 顯示的是整台機器的檔案系統,而不是執行個體被限制的容量——詳見 Docker/容器環境

在 Notebook 內查看 GPU 用量

! 開頭的 cell 會執行 shell 指令,因此標準工具都能直接使用。所有 GPU 映像都內含 nvidia-smi

範例
!nvidia-smi

若想在訓練期間持續觀察,nvitop 提供即時畫面並標示各程序用量——當你想知道佔住 VRAM 的是訓練程式,還是忘記關掉的 notebook kernel 時特別有用。它不會自行結束,請在 Jupyter 終端機分頁執行,不要放在 cell 裡:

範例
!pip install -q nvitop
# 接著在 Jupyter 終端機執行:
nvitop

在訓練迴圈內則直接問框架,它回報的是你的程序實際佔用量,而非驅動程式看到的總量:

範例
import torch

free, total = torch.cuda.mem_get_info()
print(f"使用中: {(total - free) / 1e9:.1f} / {total / 1e9:.1f} GB")
print(f"本程序尖峰: {torch.cuda.max_memory_allocated() / 1e9:.1f} GB")
Tip

訓練期間 GPU 使用率偏低,通常代表它在等資料,而不是算力不足。在租用更大張卡之前,先檢查 dataloader worker 數量與資料集位置——每個 epoch 都直接從 /vault 讀取資料集是常見原因。

Weights & Biases

W&B 會記錄每次執行的超參數、指標與系統狀態,並保存在它自己的伺服器上,因此紀錄不會隨執行個體消失。先用 wandb.ai/authorize 取得的 token 登入一次:

範例
%pip install -q wandb

import os, wandb
# WANDB_DIR 是「根目錄」——wandb 會在其中自建 wandb/,因此紀錄會落在
# /vault/wandb/。預設是腳本旁的 ./wandb,會隨執行個體一起消失。
os.environ["WANDB_DIR"] = "/vault"
wandb.login()  # 或將 WANDB_API_KEY 設為執行個體環境變數

接著包住整個訓練流程。把 GPU 記憶體和 loss 一起記錄只多一行,卻能讓你事後判斷當時的 batch size 是否真的安全:

範例
run = wandb.init(project="my-project", config={"lr": 3e-4, "batch_size": 32})

for epoch in range(epochs):
    loss = train_one_epoch()
    run.log({
        "loss": loss,
        "gpu_mem_gb": torch.cuda.max_memory_allocated() / 1e9,
    })

run.finish()  # 送出最後一批指標——kernel 被強制中斷會遺失
Tip

W&B 只需要對外的 HTTPS 連線,執行個體本來就有,不需要開放任何連接埠。若擔心網路中斷影響紀錄,可設定 WANDB_MODE=offline,事後再用 wandb sync /vault/wandb/offline-run-* 上傳。

Hugging Face

在 GPUtw 上最關鍵的設定是快取位置。huggingface_hub 預設把快取放在容器內的 ~/.cache/huggingface,因此每開一台新機器都會重新下載同一批權重。把 HF_HOME 指到 /vault,就只需要下載一次:

範例
%pip install -q -U huggingface_hub

import os
os.environ["HF_HOME"] = "/vault/hf"                 # 快取跨執行個體保留
os.environ["HF_XET_HIGH_PERFORMANCE"] = "1"         # 大檔下載時吃滿頻寬
os.environ.setdefault("HF_TOKEN", "")               # 於部署時設定,不要寫在這裡
Info

huggingface_hub v1.0(2025 年 10 月)之前的教學會使用 hf_transferHF_HUB_ENABLE_HF_TRANSFER=1。該套件已在 v1.0 移除,該變數也不再有作用——下載改走 Xet 後端,對應的設定是 HF_XET_HIGH_PERFORMANCE。設定舊變數不會出現警告,只是完全沒有效果。

Warning

這些設定必須在 import transformersdiffusershuggingface_hub 之前完成。快取路徑在 import 當下就會讀取,之後才執行的 cell 不會生效也不會報錯——若已經 import,請重新啟動 kernel。最乾淨的做法是在部署時填入「環境變數」欄位。

下載模型,以及把成果推回去:

範例
from huggingface_hub import snapshot_download

path = snapshot_download("Qwen/Qwen2.5-7B-Instruct")

# 訓練完成後
model.push_to_hub("my-org/my-model", private=True)
Warning

HF_HOME 設在 /vault 時,hf auth login 會把 Hugging Face token 以明文寫入 /vault/hf/token——該路徑由帳號下所有執行個體共用,且任何具備 vault:read 的憑證都能下載。請只搬快取、不要搬憑證:改用環境變數傳入 HF_TOKEN,不要呼叫 login()。若已經執行過,請刪除該檔案。

Tip

沒有執行中的執行個體?Vault 頁面的「從網址下載」可直接接受 Hugging Face 參照,由伺服器抓進你的 Vault——詳見 Vault 儲存空間

快取該放在哪裡

/vault 是網路儲存空間。這正是它能持久保存、並在多台執行個體間共用的原因,也是大檔案第一次讀取比本機磁碟慢的原因。由此可得的原則:

  • 只載入一次的權重: 放在 /vault。啟動時載入 checkpoint 只是一次性成本,而永遠不必重新下載的價值高得多。
  • 每個 epoch 都要讀的資料: 先複製到 /workspace。那是本機磁碟,複製成本通常一兩個 epoch 就回本。
Warning

HF_HOME 放在 /vault 會計入 Vault 配額,而模型快取往往在無聲中膨脹。當 Vault 頁面顯示用量持續上升時,請用 hf cache prune 清除舊版本。

不要把 token 寫進 Notebook

貼在 cell 裡的 WANDB_API_KEYHF_TOKEN 會被存進 .ipynb 檔案,並隨著檔案進入 /vault、你推送的任何 repo,以及任何你分享出去的內容。請改在部署時以環境變數傳入——部署頁面的「環境變數」欄位,或建立執行個體 APIenv

但也請了解其代價:這些值會與執行個體紀錄一起保存,以便下次部署時自動帶入,且未加密儲存。它比寫在 notebook 好——不會被複製擴散——但並不是密鑰管理系統。若服務支援,請使用範圍受限、有效期短的權杖(Hugging Face fine-grained token、W&B service account),而非帳號層級的金鑰。

Warning

這兩個 token 都是 GPUtw 以外服務的帳號憑證。請比照 GPUtw API 金鑰處理:在服務允許的範圍內縮小權限;若含有 token 的 notebook 曾被分享,請立即輪替。