# ファイルをHubにアップロードする

ファイルを共有することは、Hubの重要な側面です。`huggingface_hub`には、ファイルをHubにアップロードするための複数のオプションが用意されています。これらの関数は単独で使用することも、ライブラリに統合することもでき、ユーザーがより簡単にHubとやり取りできるようにできます。

ファイルをHubにアップロードする際は、Hugging Faceアカウントへのログインが必要です。認証の詳細については、[このセクション](../quick-start#authentication)を参照してください。

## ファイルのアップロード

[create_repo()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.create_repo)でリポジトリを作成した後、[upload_file()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.upload_file)を使用してリポジトリにファイルをアップロードできます。

アップロードするファイルのパス、リポジトリ内のアップロード先、ファイルを追加するリポジトリ名を指定します。リポジトリの種類に応じて、リポジトリの種類を`dataset`、`model`、または`space`としてオプションで設定できます。

```py
>>> 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()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.upload_folder) 関数を使用して、ローカルのフォルダを既存のリポジトリにアップロードします。アップロードするローカルフォルダのパス、リポジトリ内のアップロード先、およびフォルダを追加するリポジトリ名を指定します。リポジトリの種類に応じて、リポジトリの種類を `dataset`、`model`、または `space` としてオプションで設定できます。

```py
>>> 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`引数を使用して、アップロードするファイルをフィルタリングできます。これらのパラメータは、単一のパターンまたはパターンのリストを受け取ります。パターンは、[こちら](https://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm)にドキュメント化されている標準ワイルドカード（globbingパターン）です。`allow_patterns`と`ignore_patterns`の両方が指定された場合、両方の制約が適用されます。

`.gitignore` ファイルと許可/無視パターンに加えて、サブディレクトリ内に存在する `.git/` フォルダもすべて無視されます。

```py
>>> 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ファイルのみがアップロードされますが、その前にリポジトリ上の以前のログがすべて削除されます。これらはすべて単一のコミットで行われます。
```py
>>> 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()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.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 commits
```

`hf_xet` がインストールされていない場合、[upload_folder()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.upload_folder) は従来の動作にフォールバックします。まずすべてをハッシュ化し、HTTP 経由でアップロードしてから、単一のコミットを作成します。より高い堅牢性を確保するため、`hf_xet` を常にインストールしておくことをお勧めします。

## CLIからのアップロード

ターミナルから`hf upload`コマンドを使用すると、ファイルをHubに直接アップロードできます。内部では、上記で説明した[upload_file()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.upload_file)および[upload_folder()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.upload_folder)ヘルパーが同じように使用されています。

単一のファイルまたはフォルダ全体をアップロードできます:

```bash
# 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` が設定されていない場合、ファイルはリポジトリのルートにアップロードされます。

デスティネーションは、文法`hf://[<TYPE>/]<ID>[@<REVISION>][/<PATH>]`に従う単一の`hf://` URIとしても表現できます（完全な構文については[HF URIs リファレンス](../package_reference/hf_uris)を参照してください）。この場合、リポジトリタイプ、リビジョン、`path_in_repo`はURIから読み取られ、`--repo-type`および`--revision`オプションと併用することはできません。

```bash
# 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
```

> [!TIP]
> 大規模なファイルのアップロードスループスを最大化するには、[`HF_XET_HIGH_PERFORMANCE=1`](../package_reference/environment_variables#hf_xet_high_performance) 環境変数を設定してください。これにより、`hf_xet` の高性能モードが有効になり、利用可能な帯域幅と CPU コアを最大限に活用します。なお、`hf_transfer` は `hf_xet` に置き換えられたため、従来の `HF_HUB_ENABLE_HF_TRANSFER=1` フラグは使用されなくなりました。代わりに `HF_XET_HIGH_PERFORMANCE=1` を設定してください。

CLIアップロードコマンドの詳細については、[CLIガイド](./cli#hf-upload)を参照してください。

## 大きなフォルダーをアップロードする

[upload_folder()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.upload_folder) と `hf upload` コマンドは、非常に大きなフォルダを含むファイルを Hub にアップロードするための標準的なソリューションです。ファイルは複数のコミットに分割されて Hub にストリーミングされ、中断が発生しても処理は自動的に再開されます。同じ呼び出しを再実行するだけで、すでにアップロード済みのファイルはスキップされます。

```py
>>> api.upload_folder(
...     repo_id="HuggingFaceM4/Docmatix",
...     repo_type="dataset",
...     folder_path="/path/to/local/docmatix",
... )
```

またはターミナルから:

```sh
hf upload HuggingFaceM4/Docmatix --repo-type=dataset /path/to/local/docmatix
```

### 大規模なアップロードに関するヒントとコツ

リポジトリに大量のデータを扱う際には、いくつかの制約に注意が必要です。データのストリーミングには時間がかかるため、アップロード/プッシュが処理の最後に失敗したり、hf.co 上でもローカル作業中にも、体験が劣化したりすると、非常に煩わしくなります。

Hub上のリポジトリの構成に関するベストプラクティスについては、[リポジトリの制限と推奨事項](https://huggingface.co/docs/hub/repositories-recommendations)ガイドをご覧ください。ここでは、アップロードプロセスを円滑に進めるための実践的なヒントをいくつかご紹介します。

- **小さく始める**: アップロードスクリプトのテストには、まず少量のデータから始めることをお勧めします。失敗してもすぐに試行錯誤できるため、スクリプトの反復作業が容易になります。
- **失敗を想定する**: 大量のデータをストリーミングすることは困難を伴います。何が起きるかは予測できませんが、マシン、接続、または当社のサーバーのいずれかの原因で、少なくとも一度は失敗する可能性を常に考慮しておくのが最善です。例えば、大量のファイルをアップロードする予定がある場合は、次のバッチをアップロードする前に、ローカルでどのファイルをすでにアップロード済みかを追跡しておくのが望ましいです。すでにコミット済みのLFSファイルが二度と再アップロードされることはないことが保証されていますが、クライアント側で確認しておくと、時間を節約できる場合があります。[upload_folder()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.upload_folder)はこの処理を代行してくれます。
- **`hf_xet`を使用する**: これはHubの新しいストレージバックエンドを活用しており、Rustで記述され、現在では誰でも利用できます。実際、`huggingface_hub`を使用する際は、`hf_xet`がデフォルトで有効になっています。最大のパフォーマンスを得るには、[`HF_XET_HIGH_PERFORMANCE=1`](../package_reference/environment_variables#hf_xet_high_performance)を環境変数として設定してください。高パフォーマンスモードが有効な場合、ツールは利用可能な帯域幅とCPUコアをすべて使用しようとします。

## 高度な機能

ほとんどの場合、ファイルをHubにアップロードするには[upload_file()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.upload_file)と[upload_folder()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.upload_folder)だけで十分です。ただし、`huggingface_hub`には、作業をさらに容易にするための高度な機能も用意されています。それらを見ていきましょう!

### より高速なアップロード

`hf_xet` は [`xet-core`](https://github.com/huggingface/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`の最新バージョンをインストールするだけです:

```bash
pip install -U "huggingface_hub"
```

`huggingface_hub` 0.32.0 以降、`hf_xet` もインストールされます。

その他のすべての`huggingface_hub` APIは、変更なしで引き続き動作します。Xetストレージと`hf_xet`の利点について詳しく知るには、この[セクション](https://huggingface.co/docs/hub/xet/index)を参照してください。

**クラスタ / 分散ファイルシステムへのアップロードに関する考慮事項**

クラスターからアップロードする場合、アップロード対象のファイルは、分散ファイルシステムまたはネットワークファイルシステム（NFS、EBS、Lustre、Fsx など）上に存在していることがよくあります。Xet ストレージはこれらのファイルをチャンクに分割し、ブロック（xorbs とも呼ばれます）としてローカルに書き込み、ブロックの作成が完了するとアップロードします。分散ファイルシステムからのアップロードでパフォーマンスを向上させるには、[`HF_XET_CACHE`](../package_reference/environment_variables#hfxetcache)をローカルディスク上のディレクトリ（例：ローカルの NVMe または SSD ディスク）に設定してください。Xet キャッシュのデフォルトの場所は `HF_HOME` 配下の (`~/.cache/huggingface/xet`) にあり、ユーザーのホームディレクトリは分散ファイルシステム上に存在していることもよくあります。

### 非ブロッキングアップロード

一部のケースでは、メインスレッドをブロックせずにデータをプッシュしたい場合があります。これは、トレーニングを継続しながらログや成果物をアップロードする場合に特に有用です。そのためには、[upload_file()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.upload_file) と [upload_folder()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.upload_folder) の両方で `run_as_future` 引数を使用できます。これにより、アップロードのステータスを確認するために使用できる [`concurrent.futures.Future`](https://docs.python.org/3/library/concurrent.futures.html#future-objects) オブジェクトが返されます。

```py
>>> 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)
...
```

> [!TIP]
> `run_as_future=True` を使用すると、バックグラウンドジョブはキューに投入されます。これにより、ジョブが正しい順序で実行されることが保証されます。

バックグラウンドジョブは主にデータのアップロードやコミットの作成に有用ですが、[run_as_future()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.run_as_future) を使用して任意のメソッドをキューに追加できます。例えば、リポジトリを作成し、その後バックグラウンドでデータにアップロードする用途に利用できます。アップロードメソッドに組み込まれている `run_as_future` 引数は、これのエイリアスに過ぎません。

```py
>>> 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()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.copy_files) を使用すると、ハブ上のリポジトリ間でファイルやフォルダをダウンロードや再アップロードなしにコピーできます。これは、モデルのバリアント間で重みを複製したり、リポジトリ間でデータセットファイルをコピーしたり、リポジトリ間でファイルを再構成したりする場合に便利です。内部では、[CommitOperationCopy](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.CommitOperationCopy) 操作を含むコミットを作成します。

```py
>>> 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/",
... )
```

同じリポジトリ内でのコピーも可能です:

```py
# Duplicate a file in the same repo
>>> api.copy_files(
...     "hf://username/my-model/config.json",
...     "hf://username/my-model/backup/config.json",
... )
```

> [!TIP]
> フォルダをコピーする際、ソースの末尾に`/`がある場合、rsyncと同様のセマンティクスが適用され、フォルダ自体をネストせずにその*中身*がコピーされます。末尾に`/`がない場合、フォルダ自体がネストされた状態でコピー先へ配置されます。

> [!TIP]
> [copy_files()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.copy_files) は、[Buckets](./buckets) へのファイルコピーもサポートしています。詳細については、[Buckets ガイド](./buckets#copy-files-to-bucket)を参照してください。

### スケジュールされたアップロード

Hugging Face Hub を使用すると、データの保存とバージョン管理が容易になります。ただし、同じファイルを数千回更新する際にはいくつかの制限があります。例えば、学習プロセスのログや、デプロイされた Space に対するユーザーのフィードバックを保存したい場合があります。このようなケースでは、データを Hub 上のデータセットとしてアップロードするのが理にかなっていますが、適切に行うのは難しい場合があります。主な理由は、データのすべての更新をバージョン管理すると git リポジトリが使用不能になるためです。[CommitScheduler](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.CommitScheduler) クラスは、この問題に対する解決策を提供します。

アイデアは、ローカルフォルダを定期的にHubにプッシュするバックグラウンドジョブを実行することです。テキストを入力として受け取り、その2つの翻訳を生成するGradio Spaceを持っていると仮定します。その後、ユーザーは好みの翻訳を選択できます。各実行について、結果を分析するために、入力、出力、ユーザーの選択を保存したいと考えています。これは[CommitScheduler](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.CommitScheduler)の最適な使用例です。Hubにデータを保存したい（潜在的に数百万件のユーザーフィードバックを含む）ものの、各ユーザーの入力をリアルタイムで保存する_必要はありません_。代わりに、データをJSONファイルにローカルで保存し、10分ごとにアップロードできます。例えば:

```py
>>> 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](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.CommitScheduler)の詳細については、以下の点をご確認ください。
- **append-only:** フォルダにはコンテンツを追加するのみであることが前提とされています。既存のファイルにデータを追記するか、新しいファイルを作成するだけです。ファイルを削除したり上書きしたりすると、リポジトリが破損する可能性があります。
- **git history**: スケジューラーは、`every` 分ごとにフォルダーをコミットします。git リポジトリを過度に汚染しないようにするため、最小値を 5 分と設定することをお勧めします。また、スケジューラーは空のコミットを回避するように設計されています。フォルダーに新しいコンテンツが検出されない場合、スケジュールされたコミットは破棄されます。
- **エラー:** スケジューラはバックグラウンドスレッドとして実行されます。クラスのインスタンス化時に開始され、`stop()` が呼び出されるか、プロセスが終了するまで実行し続けます。アップロード中にエラーが発生した場合（例: 接続の問題）、エラーがログに記録され、次のスケジュールされたコミット時にスケジューラが再試行を行います。
- **scripts:** 寿命が限定されたスクリプト（例：学習）では、スケジューラーをコンテキストマネージャーとして使用します。`with` ブロックを離れると、最後のアップロードがトリガーされ、その完了を待ってからスケジューラーが停止します。
- **スレッドセーフ性:** ほとんどの場合、ロックファイルを気にせずにファイルに書き込むことは安全であると仮定できます。アップロード中にフォルダにコンテンツを書き込んでも、スケジューラーがクラッシュしたり破損したりすることはありません。実際には、負荷の高いアプリでは_並行処理の問題が発生する可能性_があります。この場合、スレッドセーフ性を確保するために`scheduler.lock`ロックの使用を推奨します。このロックは、スケジューラーがフォルダをスキャンして変更を検出している間のみブロックされ、データをアップロードしている間ではありません。Space のユーザー体験に影響を与えないと安全に仮定できます。

#### Space永続化デモ

SpaceからHub上のDatasetにデータを永続化することは、[CommitScheduler](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.CommitScheduler)の主なユースケースです。ユースケースに応じて、データの構造を異ならせる必要がある場合があります。構造は、同時接続するユーザーや再起動に対して堅牢である必要があり、多くの場合、UUIDの生成を意味します。堅牢性に加えて、後で再利用できるように、🤗 Datasetsライブラリで読み取れる形式でデータをアップロードする必要があります。異なる複数のデータ形式を保存する方法を示す[Space](https://huggingface.co/spaces/Wauplin/space_to_dataset_saver)を作成しました（ご自身の特定のニーズに合わせて調整する必要がある場合があります）。

#### カスタムアップロード

[CommitScheduler](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.CommitScheduler) は、データが追記専用（append-only）であり、そのままアップロードされることを前提としています。ただし、データのアップロード方法をカスタマイズしたい場合があります。そのためには、[CommitScheduler](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.CommitScheduler) を継承するクラスを作成し、`push_to_hub` メソッドをオーバーライドします（任意の方法でオーバーライドして構いません）。このメソッドは、バックグラウンドスレッド上で `every` 分ごとに呼び出されることは保証されています。並行性やエラー処理については心配しなくて構いませんが、空のコミットをプッシュすることやデータの重複といった他の点には注意が必要です。

以下の（簡略化された）例では、Hub上のリポジトリに負荷をかけないよう、すべてのPNGファイルを単一のアーカイブに圧縮するために`push_to_hub`をオーバーライドしています。

```py
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](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.CommitScheduler)の属性にアクセスでき、特に以下を利用できます。
- [HfApi](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi) クライアント: `api`
- フォルダーのパラメーター: `folder_path` と `path_in_repo`
- リポジトリのパラメータ: `repo_id`、`repo_type`、`revision`
- スレッドロック: `lock`

> [!TIP]
> カスタムスケジューラーのより多くの例については、ユースケースに応じた異なる実装を含む[デモスペース](https://huggingface.co/spaces/Wauplin/space_to_dataset_saver)をご覧ください。

### create_commit

[upload_file()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.upload_file) と [upload_folder()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.upload_folder) 関数は、一般的に使い勝手の良い高レベル API です。低レベルでの操作が不要な場合は、まずこれらの関数をお試しください。ただし、コミットレベルでの操作を行いたい場合は、[create_commit()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.create_commit) 関数を直接使用できます。

[create_commit()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.create_commit)がサポートする操作には、3つの種類があります。

- [CommitOperationAdd](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.CommitOperationAdd) はファイルを Hub にアップロードします。ファイルが既に存在する場合、ファイルの内容は上書きされます。この操作は2つの引数を受け取ります:

  - `path_in_repo`: ファイルをアップロードするリポジトリ内のパス。
  - `path_or_fileobj`: ファイルシステム上のファイルへのパス、またはファイルライクオブジェクト。これは、Hubにアップロードするファイルの内容です。

- [CommitOperationDelete](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.CommitOperationDelete) は、リポジトリからファイルまたはフォルダーを削除します。この操作は `path_in_repo` を引数として受け取ります。

- [CommitOperationCopy](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.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つのファイルを削除する場合:

1. ファイルの追加または削除、フォルダの削除には、適切な`CommitOperation`を使用します。

```py
>>> 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"),
... ]
```

2. 操作を[create_commit()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.create_commit)に渡します:

```py
>>> api.create_commit(
...     repo_id="lysandre/test-model",
...     operations=operations,
...     commit_message="Upload my model weights and license",
... )
```

[upload_file()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.upload_file)と[upload_folder()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.upload_folder)に加えて、以下の関数も内部で[create_commit()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.create_commit)を使用しています:

- [delete_file()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.delete_file) は、Hub 上のリポジトリから単一のファイルを削除します。
- [delete_folder()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.delete_folder) は、Hub 上のリポジトリからフォルダ全体を削除します。
- [metadata_update()](/docs/huggingface_hub/v2.4.0/ja/package_reference/cards#huggingface_hub.metadata_update) は、リポジトリのメタデータを更新します。

より詳細な情報については、[HfApi](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi)の参照をご覧ください。

### コミット前にLFSファイルを事前アップロードする

一部のケースでは、コミット呼び出しを行う**前に**、巨大なファイルを S3 にアップロードしたい場合があります。例えば、メモリ内で生成された複数のシャードからなるデータセットをコミットする場合、メモリ不足の問題を回避するために、シャードを1つずつアップロードする必要があります。1つの解決策は、リポジトリ上で各シャードを個別のコミットとしてアップロードすることです。これは完全に有効な方法ですが、数十個のコミットを生成して git の履歴を乱す可能性があるという欠点があります。この問題を克服するために、ファイルを1つずつ S3 にアップロードし、最後に単一のコミットを作成することができます。これは、[preupload_lfs_files()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.preupload_lfs_files) と [create_commit()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.create_commit) を組み合わせて使用することで可能です。

> [!WARNING]
> これは上級者向けのメソッドです。ファイルの事前アップロードに関する低レベルなロジックを処理する代わりに、[upload_file()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.upload_file)、[upload_folder()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.upload_folder)、または[create_commit()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.create_commit)を直接使用することが、ほとんどのケースで推奨される方法です。[preupload_lfs_files()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.preupload_lfs_files)の主な注意点として、コミットが実際に実行されるまで、アップロードされたファイルはHub上のリポジトリからアクセスできません。ご質問がある場合は、DiscordまたはGitHubのIssueで気軽にご連絡ください。

ファイルを事前にアップロードする方法を示す簡単な例を以下に示します。

```py
>>> 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](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.CommitOperationAdd) オブジェクトを1つずつ作成します。実際の使用例では、これらは生成されたシャードを保持します。各ファイルは、次のファイルの生成前にアップロードされます。[preupload_lfs_files()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.preupload_lfs_files) ステップでは、**`CommitOperationAdd` オブジェクトが変更されます**。このオブジェクトは、[create_commit()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.create_commit) に直接渡すためにのみ使用するべきです。オブジェクトの主な更新点は、**バイナリコンテンツが削除される** ことです。つまり、別の参照を保持しない場合、ガベージコレクションの対象となります。これは、すでにアップロード済みのコンテンツをメモリに保持したくないため、想定された動作です。最後に、すべての操作を [create_commit()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.create_commit) に渡してコミットを作成します。まだ処理されていない追加の操作（追加、削除、コピー）を渡すこともでき、それらは正しく処理されます。

