Hub Python Library documentation
ファイルをHubにアップロードする
ファイルをHubにアップロードする
ファイルを共有することは、Hubの重要な側面です。huggingface_hubには、ファイルをHubにアップロードするための複数のオプションが用意されています。これらの関数は単独で使用することも、ライブラリに統合することもでき、ユーザーがより簡単に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
... )ファイルがアップロードされる方法
hf_xet がインストールされている場合(デフォルトではインストールされています)、upload_folder() はストリーミングパイプラインを通じてファイルをアップロードします。ファイルは Hub と照合され、Xet ストレージバックエンドにアップロードされます(このバックエンドは内部でチャンク化、重複排除、転送の再試行を行います)。その後、適応的なバッチでコミットされ、これらはすべて並列で実行されます。具体的には、以下のようになります。
- 任意のサイズのフォルダ: 小さいフォルダは1回のコミットでアップロードされますが、ファイル数が多いフォルダはサーバーの制限を超えないように自動的に複数のコミットに分割されます。この場合、後続のコミットにはコミットメッセージに
(part 2)、(part 3)、…というサフィックスが付けられます。 - 再開可能: アップロードが何らかの理由で中断された場合、同じ呼び出しを再実行するだけです。すでにコミットされたファイルは検出されてスキップされ、すでにアップロードされたチャンクは重複排除されます。再アップロードしても(ほぼ)データは転送されません。ローカル状態は関与しません。別のマシンから再開することも可能です。1つの例外があります。
create_pr=Trueの場合、再実行すると新しいプルリクエストが開かれます。アップロードを再開する際は、代わりにrevision="refs/pr/N"を指定して再実行することを推奨します。 - 二重読み込みなし: ファイルはアップロード用のチャンク分割時にハッシュ化され、単一の読み込みパスで処理されます。アップロード開始前に別途「ハッシュ化」フェーズはありません。
ライブの進捗表示は、3つのステージを追跡します:
Found 5,000 files to upload
Preparing ████████████████████ 5,000 / 5,000 ✓
Uploading ██████████████░░░░░░ 423 / 603 files 3.8GB · 19.7MB/s
Committing ██████████████████░░ 4,580 / 5,000 6 commitshf_xet がインストールされていない場合、upload_folder() は従来の動作にフォールバックします。まずすべてをハッシュ化し、HTTP 経由でアップロードしてから、単一のコミットを作成します。より高い堅牢性を確保するため、hf_xet を常にインストールしておくことをお勧めします。
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/mainlocal_path と path_in_repo は省略可能であり、暗黙的に推論できます。local_path が設定されていない場合、ツールは repo_id と同じ名前のローカルフォルダまたはファイルが存在するかを確認します。存在する場合は、その内容がアップロードされます。存在しない場合は、local_path を明示的に設定するようユーザーに求める例外が発生します。いずれの場合も、path_in_repo が設定されていない場合、ファイルはリポジトリのルートにアップロードされます。
デスティネーションは、文法hf://[<TYPE>/]<ID>[@<REVISION>][/<PATH>]に従う単一のhf:// URIとしても表現できます(完全な構文についてはHF URIs リファレンスを参照してください)。この場合、リポジトリタイプ、リビジョン、path_in_repoはURIから読み取られ、--repo-typeおよび--revisionオプションと併用することはできません。
# Upload a single file to a dataset on a specific branch
>>> hf upload hf://datasets/Wauplin/my-cool-dataset@my-branch/data/train.csv ./train.csv
https://huggingface.co/datasets/Wauplin/my-cool-dataset/blob/my-branch/data/train.csv大規模なファイルのアップロードスループスを最大化するには、
HF_XET_HIGH_PERFORMANCE=1環境変数を設定してください。これにより、hf_xetの高性能モードが有効になり、利用可能な帯域幅と CPU コアを最大限に活用します。なお、hf_transferはhf_xetに置き換えられたため、従来のHF_HUB_ENABLE_HF_TRANSFER=1フラグは使用されなくなりました。代わりにHF_XET_HIGH_PERFORMANCE=1を設定してください。
CLIアップロードコマンドの詳細については、CLIガイドを参照してください。
大きなフォルダーをアップロードする
upload_folder() と hf upload コマンドは、非常に大きなフォルダを含むファイルを Hub にアップロードするための標準的なソリューションです。ファイルは複数のコミットに分割されて Hub にストリーミングされ、中断が発生しても処理は自動的に再開されます。同じ呼び出しを再実行するだけで、すでにアップロード済みのファイルはスキップされます。
>>> api.upload_folder(
... repo_id="HuggingFaceM4/Docmatix",
... repo_type="dataset",
... folder_path="/path/to/local/docmatix",
... )またはターミナルから:
hf upload HuggingFaceM4/Docmatix --repo-type=dataset /path/to/local/docmatix
大規模なアップロードに関するヒントとコツ
リポジトリに大量のデータを扱う際には、いくつかの制約に注意が必要です。データのストリーミングには時間がかかるため、アップロード/プッシュが処理の最後に失敗したり、hf.co 上でもローカル作業中にも、体験が劣化したりすると、非常に煩わしくなります。
リポジトリの構造に関するベストプラクティスについては、リポジトリの制限と推奨事項ガイドをご参照ください。ここでは、アップロードプロセスを円滑に進めるための実践的なヒントをいくつかご紹介します。
- 小さく始める: アップロードスクリプトのテストには、まず少量のデータから始めることをお勧めします。失敗してもすぐに試行錯誤できるため、スクリプトの反復作業が容易になります。
- 失敗を想定する: 大量のデータをストリーミングすることは困難を伴います。何が起きるかは予測できませんが、マシン、接続、または当社のサーバーのいずれかの原因で、少なくとも一度は失敗する可能性を常に考慮しておくのが最善です。例えば、大量のファイルをアップロードする予定がある場合は、次のバッチをアップロードする前に、ローカルでどのファイルをすでにアップロード済みかを追跡しておくのが望ましいです。すでにコミット済みのLFSファイルが二度と再アップロードされることはないことが保証されていますが、クライアント側で確認しておくと、時間を節約できる場合があります。upload_folder()はこの処理を代行してくれます。
hf_xetを使用する: これはHubの新しいストレージバックエンドを活用しており、Rustで記述され、現在では誰でも利用できます。実際、huggingface_hubを使用する際は、hf_xetがデフォルトで有効になっています。最大のパフォーマンスを得るには、HF_XET_HIGH_PERFORMANCE=1を環境変数として設定してください。高パフォーマンスモードが有効な場合、ツールは利用可能な帯域幅とCPUコアをすべて使用しようとします。
高度な機能
ほとんどの場合、ファイルをHubにアップロードするには、upload_file()とupload_folder()だけで十分です。
ただし、huggingface_hubには、作業をさらに容易にするための高度な機能も用意されています。それらを見ていきましょう。
より高速なアップロード
hf_xet は xet-core ライブラリへの Python バインディングであり、チャンクベースの重複排除により、より高速なアップロードとダウンロードを可能にします。これにより、アップロードの高速化を実現できます。hf_xet は huggingface_hub とシームレスに統合されますが、LFS の代わりに Rust 製の xet-core ライブラリと Xet ストレージを使用します。
hf_xet は Xet ストレージシステムを使用します。このシステムはファイルを不変のチャンクに分割し、これらのチャンクのコレクション(ブロックまたは xorb と呼ばれる)をリモートに保存し、要求があった際にそれらを取得してファイルを再構築します。アップロード時、ユーザーがこのリポジトリへの書き込み権限を持っていることを確認した後、hf_xet はファイルをスキャンし、チャンクに分割して、それらのチャンクを xorb に集約します(既知のチャンク間で重複排除も行います)。その後、これらの xorb を Xet のコンテンツアドレス可能サービス(CAS)にアップロードします。CAS は xorb の完全性を検証し、xorb のメタデータと LFS SHA256 ハッシュ(検索/ダウンロードのサポートのため)を登録し、xorb をリモートストレージに書き込みます。
有効にするには、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(...)リポジトリ間でファイルをコピー
copy_files() を使用すると、ハブ上のリポジトリ間でファイルやフォルダをダウンロードや再アップロードなしにコピーできます。これは、モデルのバリアント間で重みを複製したり、リポジトリ間でデータセットファイルをコピーしたり、リポジトリ間でファイルを再構成したりする場合に便利です。内部では、CommitOperationCopy 操作を含むコミットを作成します。
>>> from huggingface_hub import HfApi
>>> api = HfApi()
# Copy a single file between repos
>>> api.copy_files(
... "hf://username/source-model/weights.safetensors",
... "hf://username/target-model/weights.safetensors",
... )
# Copy an entire folder
>>> api.copy_files(
... "hf://datasets/username/source-dataset/data/",
... "hf://datasets/username/target-dataset/data/",
... )同じリポジトリ内でのコピーも可能です:
# Duplicate a file in the same repo
>>> api.copy_files(
... "hf://username/my-model/config.json",
... "hf://username/my-model/backup/config.json",
... )フォルダをコピーする際、ソースの末尾に
/がある場合、rsyncと同様のセマンティクスが適用され、フォルダ自体をネストせずにその中身がコピーされます。末尾に/がない場合、フォルダ自体がネストされた状態でコピー先へ配置されます。
copy_files() は、Buckets へのファイルコピーもサポートしています。詳細については、Buckets ガイドを参照してください。
スケジュールされたアップロード
Hugging Face Hub を使用すると、データの保存とバージョン管理が容易になります。ただし、同じファイルを数千回更新する際にはいくつかの制限があります。例えば、学習プロセスのログや、デプロイされた Space に対するユーザーのフィードバックを保存したい場合があります。このようなケースでは、データを Hub 上のデータセットとしてアップロードするのが理にかなっていますが、適切に行うのは難しい場合があります。主な理由は、データのすべての更新をバージョン管理すると git リポジトリが使用不能になるためです。CommitScheduler クラスは、この問題に対する解決策を提供します。
アイデアは、ローカルフォルダを定期的にHubにプッシュするバックグラウンドジョブを実行することです。テキストを入力として受け取り、その2つの翻訳を生成する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の詳細については、以下の点をご確認ください。
- append-only: フォルダにコンテンツを追加するのみであることが前提です。既存のファイルにデータを追記するか、新しいファイルを作成するだけです。ファイルを削除したり上書きしたりすると、リポジトリが破損する可能性があります。
- git history:
スケジューラーは、
every分ごとにフォルダーをコミットします。git リポジトリを過度に汚染しないようにするため、最小値を 5 分とすることをお勧めします。また、スケジューラーは空のコミットを回避するように設計されています。フォルダーに新しいコンテンツが検出されない場合、スケジュールされたコミットは破棄されます。 - エラー: スケジューラはバックグラウンドスレッドとして実行されます。クラスのインスタンス化時に開始され、
stop()が呼び出されるか、プロセスが終了するまで実行し続けます。アップロード中にエラーが発生した場合(例: 接続の問題)、エラーがログに記録され、次のスケジュールされたコミット時にスケジューラが再試行を行います。 - scripts: 寿命が限定されたスクリプト(例:学習)では、スケジューラーをコンテキストマネージャーとして使用します。
withブロックを離れると、最後のアップロードがトリガーされ、その完了を待ってからスケジューラーが停止します。 - スレッドセーフ性: ほとんどの場合、ロックファイルを気にせずにファイルに書き込むことは安全であると仮定できます。アップロード中にフォルダにコンテンツを書き込んでも、スケジューラーはクラッシュしたり破損したりしません。実際には、負荷の高いアプリでは並行処理の問題が発生する可能性があります。この場合、スレッドセーフ性を確保するために
scheduler.lockロックの使用を推奨します。このロックは、スケジューラーがフォルダをスキャンして変更を検出している間のみブロックされ、データをアップロードしている間ではありません。Space のユーザー体験に影響を与えないと安全に仮定できます。
Space永続化デモ
Space のデータを Hub 上の Dataset に永続化することは、CommitScheduler の主な使用例です。使用例に応じて、データの構造を異ならせる必要がある場合があります。構造は、同時接続ユーザーや再起動に対して堅牢である必要があり、多くの場合、UUID の生成を意味します。堅牢性に加えて、後で再利用できるように、🤗 Datasets ライブラリで読み取れる形式でデータをアップロードする必要があります。異なる複数のデータ形式を保存する方法を示す Space を作成しました(ご自身の特定のニーズに合わせて調整する必要がある場合があります)。
カスタムアップロード
CommitScheduler は、データが追記専用(append-only)であり、“そのまま”アップロードされることを前提としています。ただし、データのアップロード方法をカスタマイズしたい場合があります。そのためには、CommitScheduler を継承するクラスを作成し、push_to_hub メソッドをオーバーライドします(任意の方法でオーバーライドして構いません)。このメソッドは、バックグラウンドスレッド上で every 分ごとに呼び出されることは保証されています。並行性やエラー処理については心配しなくて構いませんが、空のコミットをプッシュすることや、データの重複といった他の点には注意が必要です。
以下の(簡略化された)例では、Hub上のリポジトリへの負荷を避けるため、すべてのPNGファイルを単一のアーカイブに圧縮するようにpush_to_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
カスタムスケジューラーのより多くの例については、ユースケースに応じた異なる実装を含むデモスペースをご覧ください。
create_commit
upload_file() と upload_folder() 関数は、一般的に使い勝手の良い高レベル API です。低レベルでの操作が不要な場合は、まずこれらの関数をお試しください。ただし、コミットレベルでの操作を行いたい場合は、create_commit() 関数を直接使用できます。
create_commit()がサポートする操作には、3つの種類があります。
CommitOperationAdd はファイルを Hub にアップロードします。ファイルが既に存在する場合、ファイルの内容は上書きされます。この操作は2つの引数を受け取ります:
path_in_repo: ファイルをアップロードするリポジトリ内のパス。path_or_fileobj: ファイルシステム上のファイルへのパス、またはファイルライクオブジェクト。これは、Hubにアップロードするファイルの内容です。
CommitOperationDelete は、リポジトリからファイルまたはフォルダーを削除します。この操作は
path_in_repoを引数として受け取ります。CommitOperationCopy は、リポジトリ内またはリポジトリ間でファイルをコピーします。この操作は、以下の引数を受け取ります。
src_path_in_repo: コピーするファイルのリポジトリ内のパス。path_in_repo: ファイルをコピーするリポジトリ内のパス。src_revision: 任意 - 別のブランチ/リビジョンからファイルをコピーする場合は、コピーするファイルのリビジョンを指定します。src_repo_id: 任意 - コピー元のソースリポジトリ(例:"username/source-model")。デフォルトでは、宛先リポジトリが使用されます。src_repo_type: 任意 - ソースリポジトリのタイプ("model"、"dataset"または"space")。src_repo_idが設定されている場合は必須です。
例えば、Hubリポジトリに2つのファイルをアップロードして1つのファイルを削除する場合:
- ファイルの追加または削除、フォルダの削除には、適切な
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にアップロードしたい場合があります。例えば、メモリ内で生成された複数のシャードからなるデータセットをコミットする場合、メモリ不足の問題を回避するために、シャードを1つずつアップロードする必要があります。1つの解決策は、リポジトリ上で各シャードを個別のコミットとしてアップロードすることです。この方法は完全に有効ですが、数十個のコミットを生成することでgit履歴を乱す可能性があるという欠点があります。この問題を克服するために、ファイルを1つずつ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 オブジェクトを1つずつ作成します。実際の使用例では、これらは生成されたシャードを保持します。各ファイルは、次のファイルの生成前にアップロードされます。preupload_lfs_files() ステップでは、CommitOperationAdd オブジェクトが変更されます。このオブジェクトは、create_commit() に直接渡すためにのみ使用する必要があります。オブジェクトの主な更新点は、バイナリコンテンツが削除されることです。つまり、別の参照を保持しない場合、ガベージコレクションの対象となります。これは、すでにアップロード済みのコンテンツをメモリに保持したくないため、想定された動作です。最後に、すべての操作を create_commit() に渡してコミットを作成します。まだ処理されていない追加の操作(追加、削除、コピー)を渡すこともでき、それらは正しく処理されます。