Hub Python 庫文件
上傳檔案到 Hub
並獲得增強的文件體驗
開始使用
上傳檔案到 Hub
分享檔案和工作是 Hub 的重要方面。huggingface_hub
提供了多種將檔案上傳到 Hub 的選項。你可以獨立使用這些功能,也可以將它們整合到你的庫中,讓使用者更方便地與 Hub 互動。本指南將向你展示如何推送檔案:
- 不使用 Git。
- 使用 Git LFS 上傳非常大的檔案。
- 使用
commit
上下文管理器。 - 使用 push_to_hub() 函式。
每當你想要上傳檔案到 Hub 時,都需要登入到你的 Hugging Face 賬戶。有關身份驗證的更多詳細資訊,請檢視此部分。
上傳檔案
使用 create_repo() 建立倉庫後,你可以使用 upload_file() 將檔案上傳到你的倉庫。
指定要上傳的檔案路徑、要將檔案上傳到倉庫中的位置以及要新增檔案的倉庫名稱。根據你的倉庫型別,你可以選擇將倉庫型別設定為 dataset
、model
或 space
。
>>> from huggingface_hub import HfApi
>>> api = HfApi()
>>> api.upload_file(
... path_or_fileobj="/path/to/local/folder/README.md",
... path_in_repo="README.md",
... repo_id="username/test-dataset",
... repo_type="dataset",
... )
上傳資料夾
使用 upload_folder() 函式將本地資料夾上傳到現有倉庫。指定要上傳的本地資料夾路徑、要將資料夾上傳到倉庫中的位置以及要新增資料夾的倉庫名稱。根據你的倉庫型別,你可以選擇將倉庫型別設定為 dataset
、model
或 space
。
>>> from huggingface_hub import HfApi
>>> api = HfApi()
# Upload all the content from the local folder to your remote Space.
# By default, files are uploaded at the root of the repo
>>> api.upload_folder(
... folder_path="/path/to/local/space",
... repo_id="username/my-cool-space",
... repo_type="space",
... )
預設情況下,會考慮 .gitignore
檔案來確定哪些檔案應該提交,哪些不應該。預設情況下,我們檢查提交中是否存在 .gitignore
檔案,如果不存在,我們檢查 Hub 上是否存在。請注意,只有根目錄中存在的 .gitignore
檔案才會被使用。我們不會檢查子目錄中的 .gitignore
檔案。
如果你不想使用硬編碼的 .gitignore
檔案,你可以使用 allow_patterns
和 ignore_patterns
引數來過濾要上傳的檔案。這些引數接受單個模式或模式列表。模式是此處文件中描述的標準萬用字元(globbing 模式)。如果同時提供了 allow_patterns
和 ignore_patterns
,則兩者都適用。
除了 .gitignore
檔案和允許/忽略模式之外,任何子目錄中存在的 .git/
資料夾都將被忽略。
>>> api.upload_folder(
... folder_path="/path/to/local/folder",
... path_in_repo="my-dataset/train", # Upload to a specific folder
... repo_id="username/test-dataset",
... repo_type="dataset",
... ignore_patterns="**/logs/*.txt", # Ignore all text logs
... )
你還可以使用 delete_patterns
引數來指定要在同一提交中從倉庫中刪除的檔案。如果你想在推送檔案之前清理遠端資料夾,並且不知道哪些檔案已經存在,這可能會很有用。
以下示例將本地 ./logs
資料夾上傳到遠端 /experiment/logs/
資料夾。只上傳 txt 檔案,但在此之前,倉庫中所有以前的日誌都將被刪除。所有這些都在一個提交中完成。
>>> api.upload_folder(
... folder_path="/path/to/local/folder/logs",
... repo_id="username/trained-model",
... path_in_repo="experiment/logs/",
... allow_patterns="*.txt", # Upload all local text files
... delete_patterns="*.txt", # Delete all remote text files before
... )
從 CLI 上傳
你可以使用終端的 hf upload
命令直接將檔案上傳到 Hub。它在內部使用與上述 upload_file() 和 upload_folder() 相同的輔助函式。
你可以上傳單個檔案或整個資料夾
# Usage: hf upload [repo_id] [local_path] [path_in_repo]
>>> hf upload Wauplin/my-cool-model ./models/model.safetensors model.safetensors
https://huggingface.co/Wauplin/my-cool-model/blob/main/model.safetensors
>>> hf upload Wauplin/my-cool-model ./models .
https://huggingface.co/Wauplin/my-cool-model/tree/main
local_path
和 path_in_repo
是可選的,可以隱式推斷。如果未設定 local_path
,該工具將檢查本地資料夾或檔案是否與 repo_id
同名。如果是,其內容將被上傳。否則,將引發異常,要求使用者顯式設定 local_path
。在任何情況下,如果未設定 path_in_repo
,檔案將上傳到倉庫的根目錄。
有關 CLI 上傳命令的更多詳細資訊,請參閱 CLI 指南。
上傳大型資料夾
在大多數情況下,upload_folder() 方法和 hf upload
命令應該是將檔案上傳到 Hub 的首選解決方案。它們確保只會進行一次提交,處理大量用例,並在出錯時明確地失敗。然而,在處理大量資料時,你通常會更喜歡一種有彈性的流程,即使它會導致更多的提交或需要更多的 CPU 使用量。upload_large_folder() 方法正是本著這種精神實現的。
- 它是可恢復的:上傳過程分為許多小任務(雜湊檔案、預上傳檔案和提交檔案)。每次任務完成後,結果都會本地快取到你要上傳的資料夾內的
./cache/huggingface
資料夾中。透過這種方式,中斷後重新啟動過程將恢復所有已完成的任務。 - 它是多執行緒的:如果你的機器允許,雜湊大型檔案和預上傳檔案會大大受益於多執行緒。
- 它對錯誤具有彈性:已新增高層次的重試機制,以無限期地重試每個獨立任務,直到它透過(無論是 OSError、ConnectionError、PermissionError 等)。這個機制是雙刃劍。如果發生瞬時錯誤,程序將繼續並重試。如果發生永久性錯誤(例如許可權被拒絕),它將無限期地重試,而不會解決根本原因。
如果你想了解 upload_large_folder
在底層是如何實現的更多技術細節,請檢視 upload_large_folder() 包參考。
以下是如何在指令碼中使用 upload_large_folder()。該方法的簽名與 upload_folder() 非常相似
>>> api.upload_large_folder(
... repo_id="HuggingFaceM4/Docmatix",
... repo_type="dataset",
... folder_path="/path/to/local/docmatix",
... )
你將在終端中看到以下輸出
Repo created: https://huggingface.co/datasets/HuggingFaceM4/Docmatix
Found 5 candidate files to upload
Recovering from metadata files: 100%|█████████████████████████████████████| 5/5 [00:00<00:00, 542.66it/s]
---------- 2024-07-22 17:23:17 (0:00:00) ----------
Files: hashed 5/5 (5.0G/5.0G) | pre-uploaded: 0/5 (0.0/5.0G) | committed: 0/5 (0.0/5.0G) | ignored: 0
Workers: hashing: 0 | get upload mode: 0 | pre-uploading: 5 | committing: 0 | waiting: 11
---------------------------------------------------
首先,如果倉庫之前不存在,則建立倉庫。然後,掃描本地資料夾以查詢要上傳的檔案。對於每個檔案,我們嘗試恢復元資料資訊(從之前中斷的上傳中)。從那裡,它能夠啟動工作程式並每 1 分鐘列印一次更新狀態。在這裡,我們可以看到 5 個檔案已經雜湊但尚未預上傳。5 個工作程式正在預上傳檔案,而其他 11 個正在等待任務。
還提供了命令列。你可以在終端中定義工作程式數量和詳細程度
hf upload-large-folder HuggingFaceM4/Docmatix --repo-type=dataset /path/to/local/docmatix --num-workers=16
對於大型上傳,你必須顯式設定 repo_type="model"
或 --repo-type=model
。通常,此資訊在所有其他 HfApi
方法中都是隱式的。這是為了避免將資料上傳到錯誤型別的倉庫。如果發生這種情況,你將不得不重新上傳所有內容。
雖然 upload_large_folder
在上傳大型資料夾方面更加健壯,但它的功能比 upload_folder() 更受限制。實際上:
- 你無法設定自定義的
path_in_repo
。如果要上傳到子資料夾,則需要在本地設定適當的結構。 - 由於建立了多個提交,你無法設定自定義的
commit_message
和commit_description
。 - 你無法在上傳時從倉庫中刪除。請先進行單獨的提交。
- 你無法直接建立 PR。請先建立 PR(透過 UI 或使用 create_pull_request()),然後透過傳遞
revision
進行提交。
大型上傳的提示和技巧
在處理倉庫中的大量資料時,需要注意一些限制。考慮到資料流傳輸所需的時間,如果在過程結束時上傳/推送失敗或在 hf.co 上或在本地工作時遇到降級體驗,可能會非常令人惱火。
請檢視我們的 倉庫限制和建議 指南,瞭解在 Hub 上構建倉庫的最佳實踐。接下來,我們將介紹一些實用技巧,讓你的上傳過程儘可能順暢。
- 從小處著手:我們建議從少量資料開始測試你的上傳指令碼。當失敗只花費很少時間時,迭代指令碼會更容易。
- 預期失敗:流式傳輸大量資料是一項挑戰。你不知道會發生什麼,但最好始終考慮至少會失敗一次——無論是因為你的機器、你的連線還是我們的伺服器。例如,如果你計劃上傳大量檔案,最好在本地跟蹤你已經上傳了哪些檔案,然後再上傳下一批。你可以確保已經提交的 LFS 檔案永遠不會被重複上傳,但客戶端檢查仍然可以節省一些時間。這就是 upload_large_folder() 為你所做的。
- 使用
hf_xet
:這利用了 Hub 的新儲存後端,是用 Rust 編寫的,目前正在向用戶推出。要使用hf_xet
上傳,你的倉庫必須啟用 Xet 儲存後端。它現在正在推出,所以請加入候補名單,儘快加入! - 使用
hf_transfer
:這是一個基於 Rust 的庫,旨在加快頻寬非常高的機器上的上傳速度(上傳 LFS 檔案)。要使用hf_transfer
:- 安裝
huggingface_hub
時指定hf_transfer
額外依賴(即,pip install huggingface_hub[hf_transfer]
)。 - 將
HF_HUB_ENABLE_HF_TRANSFER=1
設定為環境變數。
- 安裝
hf_transfer
是一個用於上傳 LFS 檔案的超級使用者工具!它經過測試,已達到生產就緒狀態,但它未來的適用性較差,並且缺少使用者友好的功能,例如高階錯誤處理或代理。有關更多詳細資訊,請檢視此部分。
請注意,hf_xet
和 hf_transfer
工具是互斥的。前者用於將檔案上傳到啟用 Xet 的倉庫,而後者將 LFS 檔案上傳到常規倉庫。
高階功能
在大多數情況下,你只需要 upload_file() 和 upload_folder() 即可將檔案上傳到 Hub。但是,huggingface_hub
具有更高階的功能,可以使操作更簡單。讓我們看看它們!
更快的上傳
透過 hf_xet
利用更快的上傳,它是 xet-core
庫的 Python 繫結,可實現基於塊的重複資料刪除,從而加快上傳和下載速度。hf_xet
與 huggingface_hub
無縫整合,但使用 Rust xet-core
庫和 Xet 儲存而不是 LFS。
截至 2025 年 5 月 23 日,啟用 Xet 的儲存庫已成為所有新的 Hugging Face Hub 使用者和組織的預設設定。如果您的使用者或組織是在此日期之前建立的,您可能需要在儲存庫上啟用 Xet,才能讓 hf_xet
實際上傳到 Xet 後端。加入候補名單,讓 Xet 成為您所有儲存庫的預設設定。另請注意,雖然 hf_xet
適用於記憶體中的位元組或位元組陣列資料,但對 BinaryIO 流的支援仍在進行中。
hf_xet
使用 Xet 儲存系統,它將檔案分解成不可變的塊,將這些塊的集合(稱為塊或 xorbs)遠端儲存,並在請求時檢索它們以重新組裝檔案。上傳時,在確認使用者有權寫入此倉庫後,hf_xet
將掃描檔案,將其分解成塊並將這些塊收集到 xorbs 中(並在已知塊之間進行重複資料刪除),然後將這些 xorbs 上傳到 Xet 內容定址服務 (CAS),該服務將驗證 xorbs 的完整性,註冊 xorb 元資料以及 LFS SHA256 雜湊(以支援查詢/下載),並將 xorbs 寫入遠端儲存。
要啟用它,只需安裝最新版本的 huggingface_hub
pip install -U "huggingface_hub"
從 huggingface_hub
0.32.0 開始,這將同時安裝 hf_xet
。
所有其他 huggingface_hub
API 將繼續無需任何修改即可工作。要了解有關 Xet 儲存和 hf_xet
優勢的更多資訊,請參閱此部分。
叢集/分散式檔案系統上傳注意事項
從叢集上傳時,上傳的檔案通常位於分散式或網路檔案系統(NFS、EBS、Lustre、Fsx 等)上。Xet 儲存將分塊這些檔案並將其寫入本地塊(也稱為 xorbs),一旦塊完成,就會上傳它們。為了在從分散式檔案系統上傳時獲得更好的效能,請確保將 HF_XET_CACHE
設定為本地磁碟上的目錄(例如本地 NVMe 或 SSD 磁碟)。Xet 快取的預設位置在 HF_HOME
下(~/.cache/huggingface/xet
),並且此位置通常也位於分散式檔案系統上。
非阻塞上傳
在某些情況下,你可能希望在不阻塞主執行緒的情況下推送資料。這對於在繼續訓練的同時上傳日誌和工件特別有用。為此,你可以在 upload_file() 和 upload_folder() 中使用 run_as_future
引數。這將返回一個 concurrent.futures.Future
物件,你可以使用它來檢查上傳狀態。
>>> from huggingface_hub import HfApi
>>> api = HfApi()
>>> future = api.upload_folder( # Upload in the background (non-blocking action)
... repo_id="username/my-model",
... folder_path="checkpoints-001",
... run_as_future=True,
... )
>>> future
Future(...)
>>> future.done()
False
>>> future.result() # Wait for the upload to complete (blocking action)
...
使用 run_as_future=True
時,後臺作業將排隊。這意味著你保證作業將按正確的順序執行。
儘管後臺作業主要用於上傳資料/建立提交,但你可以使用 run_as_future() 佇列任何你喜歡的方法。例如,你可以使用它建立倉庫,然後將資料上傳到後臺。上傳方法中內建的 run_as_future
引數只是它的別名。
>>> from huggingface_hub import HfApi
>>> api = HfApi()
>>> api.run_as_future(api.create_repo, "username/my-model", exists_ok=True)
Future(...)
>>> api.upload_file(
... repo_id="username/my-model",
... path_in_repo="file.txt",
... path_or_fileobj=b"file content",
... run_as_future=True,
... )
Future(...)
分塊上傳資料夾
upload_folder() 可以輕鬆地將整個資料夾上傳到 Hub。但是,對於大型資料夾(數千個檔案或數百 GB),我們建議使用 upload_large_folder(),它將上傳拆分為多個提交。有關更多詳細資訊,請參閱上傳大型資料夾部分。
計劃性上傳
Hugging Face Hub 可以輕鬆儲存和版本化資料。但是,當更新同一個檔案數千次時,存在一些限制。例如,你可能希望儲存訓練過程的日誌或已部署 Space 的使用者反饋。在這些情況下,將資料作為資料集上傳到 Hub 是有意義的,但可能很難正確執行。主要原因是你不希望版本化資料的每次更新,因為這會使 Git 倉庫無法使用。CommitScheduler 類提供了此問題的解決方案。
其思想是執行一個後臺作業,定期將本地資料夾推送到 Hub。假設你有一個 Gradio Space,它以文字作為輸入並生成其兩種翻譯。然後,使用者可以選擇他們喜歡的翻譯。對於每次執行,你都希望儲存輸入、輸出和使用者偏好,以分析結果。這是一個使用 CommitScheduler 的完美用例;你希望將資料儲存到 Hub(可能是數百萬條使用者反饋),但你不需要即時儲存每個使用者的輸入。相反,你可以將資料本地儲存到 JSON 檔案中,然後每 10 分鐘上傳一次。例如:
>>> import json
>>> import uuid
>>> from pathlib import Path
>>> import gradio as gr
>>> from huggingface_hub import CommitScheduler
# Define the file where to save the data. Use UUID to make sure not to overwrite existing data from a previous run.
>>> feedback_file = Path("user_feedback/") / f"data_{uuid.uuid4()}.json"
>>> feedback_folder = feedback_file.parent
# Schedule regular uploads. Remote repo and local folder are created if they don't already exist.
>>> scheduler = CommitScheduler(
... repo_id="report-translation-feedback",
... repo_type="dataset",
... folder_path=feedback_folder,
... path_in_repo="data",
... every=10,
... )
# Define the function that will be called when the user submits its feedback (to be called in Gradio)
>>> def save_feedback(input_text:str, output_1: str, output_2:str, user_choice: int) -> None:
... """
... Append input/outputs and user feedback to a JSON Lines file using a thread lock to avoid concurrent writes from different users.
... """
... with scheduler.lock:
... with feedback_file.open("a") as f:
... f.write(json.dumps({"input": input_text, "output_1": output_1, "output_2": output_2, "user_choice": user_choice}))
... f.write("\n")
# Start Gradio
>>> with gr.Blocks() as demo:
>>> ... # define Gradio demo + use `save_feedback`
>>> demo.launch()
就這樣!使用者輸入/輸出和反饋將作為資料集在 Hub 上可用。透過使用唯一的 JSON 檔名,可以保證不會覆蓋先前執行的資料或同時推送到同一儲存庫的其他 Spaces/副本的資料。
有關 CommitScheduler 的更多詳細資訊,你需要了解以下內容:
- 僅追加: 假定你將僅向資料夾新增內容。你必須僅向現有檔案追加資料或建立新檔案。刪除或覆蓋檔案可能會損壞你的儲存庫。
- Git 歷史記錄:排程器將每
every
分鐘提交一次資料夾。為避免過多地汙染 Git 倉庫,建議將最小間隔設定為 5 分鐘。此外,排程器旨在避免空提交。如果在資料夾中未檢測到新內容,則會丟棄計劃的提交。 - 錯誤: 排程器作為後臺執行緒執行。它在你例項化類時啟動並永不停止。特別是,如果在上傳期間發生錯誤(例如:連線問題),排程器將靜默忽略它並在下一個計劃提交時重試。
- 執行緒安全: 在大多數情況下,可以安全地假設你可以寫入檔案而無需擔心鎖檔案。當你向資料夾寫入內容時,如果排程器正在上傳,它不會崩潰或損壞。實際上,可能會發生併發問題對於高負載應用程式。在這種情況下,我們建議使用
scheduler.lock
鎖來確保執行緒安全。鎖僅在排程器掃描資料夾以查詢更改時被阻塞,而不是在上傳資料時。你可以放心地假設它不會影響你的 Space 上的使用者體驗。
Space 持久化演示
將資料從 Space 持久化到 Hub 上的資料集是 CommitScheduler 的主要用例。根據用例,你可能希望以不同的方式組織資料。資料結構必須對併發使用者和重新啟動具有魯棒性,這通常意味著生成 UUID。除了魯棒性之外,你還應該以可由 🤗 Datasets 庫讀取的格式上傳資料,以便以後重用。我們建立了一個Space,演示瞭如何儲存幾種不同的資料格式(你可能需要根據自己的特定需求進行調整)。
自定義上傳
CommitScheduler 假定你的資料是僅追加的,並且應該“按原樣”上傳。但是,你可能希望自定義資料上傳方式。你可以透過建立一個繼承自 CommitScheduler 的類並覆蓋 push_to_hub
方法來做到這一點(你可以隨意以任何方式覆蓋它)。你保證它將在後臺執行緒中每 every
分鐘呼叫一次。你不必擔心併發和錯誤,但你必須小心其他方面,例如推送空提交或重複資料。
在下面的(簡化)示例中,我們覆蓋 push_to_hub
以將所有 PNG 檔案壓縮到一個存檔中,以避免 Hub 上的倉庫過載
class ZipScheduler(CommitScheduler):
def push_to_hub(self):
# 1. List PNG files
png_files = list(self.folder_path.glob("*.png"))
if len(png_files) == 0:
return None # return early if nothing to commit
# 2. Zip png files in a single archive
with tempfile.TemporaryDirectory() as tmpdir:
archive_path = Path(tmpdir) / "train.zip"
with zipfile.ZipFile(archive_path, "w", zipfile.ZIP_DEFLATED) as zip:
for png_file in png_files:
zip.write(filename=png_file, arcname=png_file.name)
# 3. Upload archive
self.api.upload_file(..., path_or_fileobj=archive_path)
# 4. Delete local png files to avoid re-uploading them later
for png_file in png_files:
png_file.unlink()
當你覆蓋 push_to_hub
時,你可以訪問 CommitScheduler 的屬性,特別是
- HfApi 客戶端:
api
- 資料夾引數:
folder_path
和path_in_repo
- 倉庫引數:
repo_id
、repo_type
、revision
- 執行緒鎖:
lock
有關自定義排程器的更多示例,請檢視我們的演示 Space,其中包含根據您的用例的不同實現。
create_commit
upload_file() 和 upload_folder() 函式是高階 API,通常使用起來很方便。如果你不需要在較低級別工作,我們建議你首先嚐試這些函式。但是,如果你想在提交級別工作,可以直接使用 create_commit() 函式。
create_commit() 支援三種類型的操作:
CommitOperationAdd 將檔案上傳到 Hub。如果檔案已存在,則檔案內容將被覆蓋。此操作接受兩個引數:
path_in_repo
:要上傳檔案的倉庫路徑。path_or_fileobj
:本地檔案路徑或檔案物件。這是要上傳到 Hub 的檔案內容。
CommitOperationDelete 從倉庫中刪除檔案或資料夾。此操作接受
path_in_repo
作為引數。CommitOperationCopy 在倉庫中複製檔案。此操作接受三個引數:
src_path_in_repo
:要複製的檔案的倉庫路徑。path_in_repo
:檔案應複製到的倉庫路徑。src_revision
:可選 - 如果要從不同的分支/修訂版本複製檔案,則為要複製的檔案的修訂版本。
例如,如果你想上傳兩個檔案並刪除 Hub 倉庫中的一個檔案:
- 使用適當的
CommitOperation
來新增或刪除檔案以及刪除資料夾
>>> from huggingface_hub import HfApi, CommitOperationAdd, CommitOperationDelete
>>> api = HfApi()
>>> operations = [
... CommitOperationAdd(path_in_repo="LICENSE.md", path_or_fileobj="~/repo/LICENSE.md"),
... CommitOperationAdd(path_in_repo="weights.h5", path_or_fileobj="~/repo/weights-final.h5"),
... CommitOperationDelete(path_in_repo="old-weights.h5"),
... CommitOperationDelete(path_in_repo="logs/"),
... CommitOperationCopy(src_path_in_repo="image.png", path_in_repo="duplicate_image.png"),
... ]
- 將你的操作傳遞給 create_commit()
>>> api.create_commit(
... repo_id="lysandre/test-model",
... operations=operations,
... commit_message="Upload my model weights and license",
... )
除了 upload_file() 和 upload_folder() 之外,以下函式也使用了 create_commit():
- delete_file() 從 Hub 上的倉庫中刪除單個檔案。
- delete_folder() 從 Hub 上的倉庫中刪除整個資料夾。
- metadata_update() 更新倉庫的元資料。
有關更詳細的資訊,請參閱 HfApi 參考。
提交前預上傳 LFS 檔案
在某些情況下,你可能希望在進行提交呼叫之前將大型檔案上傳到 S3。例如,如果你正在以記憶體中生成的多個分片提交資料集,則需要逐個上傳分片以避免記憶體不足問題。一個解決方案是將每個分片作為單獨的提交上傳到倉庫。雖然此解決方案完全有效,但它的缺點是可能會透過生成數十個提交來弄亂 Git 歷史記錄。為了解決此問題,你可以將檔案逐個上傳到 S3,然後最後建立一個單獨的提交。這可以使用 preupload_lfs_files() 與 create_commit() 結合使用來實現。
這是一種高階使用者方法。在絕大多數情況下,直接使用 upload_file()、upload_folder() 或 create_commit(),而不是處理預上傳檔案的底層邏輯,是首選方式。preupload_lfs_files() 的主要缺點是,在實際提交之前,上傳的檔案無法在 Hub 上的倉庫中訪問。如果您有疑問,請隨時在我們的 Discord 或 GitHub issue 中與我們聯絡。
以下是一個說明如何預上傳檔案的簡單示例
>>> from huggingface_hub import CommitOperationAdd, preupload_lfs_files, create_commit, create_repo
>>> repo_id = create_repo("test_preupload").repo_id
>>> operations = [] # List of all `CommitOperationAdd` objects that will be generated
>>> for i in range(5):
... content = ... # generate binary content
... addition = CommitOperationAdd(path_in_repo=f"shard_{i}_of_5.bin", path_or_fileobj=content)
... preupload_lfs_files(repo_id, additions=[addition])
... operations.append(addition)
>>> # Create commit
>>> create_commit(repo_id, operations=operations, commit_message="Commit all shards")
首先,我們逐個建立 CommitOperationAdd 物件。在實際示例中,這些物件將包含生成的碎片。每個檔案在生成下一個檔案之前都會上傳。在 preupload_lfs_files() 步驟中,CommitOperationAdd 物件將被修改。你只能將其直接傳遞給 create_commit()。物件的主要更新是二進位制內容已從其中移除,這意味著如果你不儲存對它的另一個引用,它將被垃圾回收。這是預期的,因為我們不想將已上傳的內容保留在記憶體中。最後,我們透過將所有操作傳遞給 create_commit() 來建立提交。你可以傳遞尚未處理的其他操作(新增、刪除或複製),它們將得到正確處理。
(舊版)使用 Git LFS 上傳檔案
上述所有方法都使用 Hub 的 API 來上傳檔案。這是上傳檔案到 Hub 的推薦方式。但是,我們也提供了 Repository,一個圍繞 Git 工具的包裝器,用於管理本地倉庫。
儘管 Repository 並未正式棄用,但我們建議改用上述基於 HTTP 的方法。有關此建議的更多詳細資訊,請參閱 本指南,其中解釋了基於 HTTP 和基於 Git 的方法之間的核心區別。
Git LFS 會自動處理大於 10MB 的檔案。但是對於非常大的檔案(>5GB),你需要為 Git LFS 安裝自定義傳輸代理
hf lfs-enable-largefiles
你應為每個包含非常大檔案的倉庫安裝此項。安裝後,你就能推送大於 5GB 的檔案了。
提交上下文管理器
commit
上下文管理器處理四個最常見的 Git 命令:pull、add、commit 和 push。git-lfs
自動跟蹤任何大於 10MB 的檔案。在以下示例中,commit
上下文管理器:
- 從
text-files
倉庫拉取。 - 新增對
file.txt
的更改。 - 提交更改。
- 將更改推送到
text-files
倉庫。
>>> from huggingface_hub import Repository
>>> with Repository(local_dir="text-files", clone_from="<user>/text-files").commit(commit_message="My first file :)"):
... with open("file.txt", "w+") as f:
... f.write(json.dumps({"hey": 8}))
以下是另一個使用 commit
上下文管理器儲存和上傳檔案到倉庫的示例
>>> import torch
>>> model = torch.nn.Transformer()
>>> with Repository("torch-model", clone_from="<user>/torch-model", token=True).commit(commit_message="My cool model :)"):
... torch.save(model.state_dict(), "model.pt")
如果你想非同步推送提交,請將 blocking=False
。非阻塞行為在你希望在提交被推送的同時繼續執行指令碼時很有用。
>>> with repo.commit(commit_message="My cool model :)", blocking=False)
你可以使用 command_queue
方法檢查推送狀態
>>> last_command = repo.command_queue[-1]
>>> last_command.status
請參閱下表瞭解可能的 statuses
狀態 | 描述 |
---|---|
-1 | 正在推送。 |
0 | 推送已成功完成。 |
非零 | 發生錯誤。 |
當 blocking=False
時,命令會被跟蹤,你的指令碼只有在所有推送完成後才會退出,即使指令碼中發生其他錯誤。一些其他用於檢查推送狀態的有用命令包括:
# Inspect an error.
>>> last_command.stderr
# Check whether a push is completed or ongoing.
>>> last_command.is_done
# Check whether a push command has errored.
>>> last_command.failed
push_to_hub
Repository 類有一個 push_to_hub() 函式,用於新增檔案、進行提交併將它們推送到倉庫。與 commit
上下文管理器不同,你需要先從倉庫中拉取,然後才能呼叫 push_to_hub()。
例如,如果你已經從 Hub 克隆了倉庫,則可以從本地目錄初始化 repo
>>> from huggingface_hub import Repository
>>> repo = Repository(local_dir="path/to/local/repo")
使用 git_pull() 更新你的本地克隆,然後將檔案推送到 Hub
>>> repo.git_pull()
>>> repo.push_to_hub(commit_message="Commit my-awesome-file to the Hub")
但是,如果你尚未準備好推送檔案,可以使用 git_add() 和 git_commit() 僅新增和提交檔案
>>> repo.git_add("path/to/file")
>>> repo.git_commit(commit_message="add my first model config file :)")
當你準備好後,使用 git_push() 將檔案推送到你的倉庫
>>> repo.git_push()