Hub documentation

ストレージバケットへのデータ移行

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

ストレージバケットへのデータ移行

このガイドでは、現在データセットが保存されている場所(ローカルディスク、別のクラウド、または Hub)から、Storage Bucket へ大規模なデータセットを移動する方法を示します。以下の表からソースを探し、該当するセクションへ移動してください。

可能な限り、データをファイルシステムとして読み取れるようにし、hf syncを実行してください。クライアント側で重複排除を行うため、単純なコピーよりも少ないバイト数でアップロードできます。

ひと目でわかる

データが現在ある場所推奨代替案
ローカルディスクまたはクラスタファイルシステムhf sync—
AWS S3 または S3 互換 (R2、MinIO)mount-s3でマウントしてから、hf syncを実行しますS3ゲートウェイ経由でrcloneを使用する
Google Cloud Storagegcsfuseでマウントしてから、hf syncを実行するrclone、またはJob
Azure Blob Storageblobfuse2でマウントし、その後hf syncを実行しますrclone、またはJob
Hubのリポジトリまたは別のバケットhf buckets cp(サーバーサイド)—
非常に大きなS3プレフィックスhf-s3ream (アルファ版)マウント + hf sync、サブパスで分割

hf syncがデフォルトである理由:

  • アップロードするデータ量が少なくなります。 hf sync は Xet クライアントを介してアップロードを行い、まずデータをチャンク化して重複排除します。そのため、Hub がまだ見たことのないチャンクのみが送信されます。一方、rclone による S3 ゲートウェイ経由のコピーなどの生コピーでは、すべてのバイトが転送されます。
  • 少なくとも同等以上の速度です。 現在までサポートしてきた移行において、マウントされたソース経由のhf syncは、スループットにおいてrcloneに匹敵するか、それを上回る結果を示しています。

開始前に

このガイドのすべてのコマンドは、Hugging Face CLIであるhfを使用します。そのヘルプ出力はエージェントが読み取れる形式になっているため、コーディングエージェントが移行を構築・監視してくれます(AIエージェント向けCLIを参照)。大規模に実行する前に、コマンドの内容を確認してください。

  1. CLIをインストールします。 Xetクライアントはこれに同梱されています。

    curl -LsSf https://hf.co/cli/install.sh | bash
    hf version
  2. ログインするには、Writeアクセス権限を持つトークンを使用してください(作成する):

    hf auth login
    hf auth whoami
  3. 宛先のバケットを作成します。 <namespace> はユーザー名または組織名です。--region を指定しない場合、バケットはネームスペースのデフォルトのストレージリージョンに作成されます。Team & Enterprise プラン以外では、常に米国になります。これらのプランでは、--region us または --region eu を渡して選択できます。

    hf buckets create <namespace>/<bucket> --private

テストランから始めましょう。使用するパスがどちらであっても、小さなサブセット(1つのフォルダ、または--includeパターン)でリハーサルを行い、--dry-runとhf buckets lsで結果を確認してから、本番の移行を開始してください。このガイドのすべてのパスは再開可能であるため、テストランにはコストがかかりません。

ローカルディスクまたはクラスターファイルシステムから

データがローカルディスク、アタッチされたボリューム、またはクラスタのスクラッチ領域にある場合に使用します。マシンがファイルとして読み取れるものであれば、すべて対象となります。また、以下のクラウド系パスにおいても、ソースがマウントされた後の最終ステップとして使用されます。

hf sync ./data hf://buckets/<namespace>/<bucket>/data

hf sync はソースとデスティネーションを比較し、差分のみを転送します。そのため、同じコマンドを再実行すると、中断されたマイグレーションを再開できます。すでにアップロードされたファイルはスキップされます。一般的なバリアント:

# Mirror exactly: also delete destination files that are gone from the source
hf sync ./data hf://buckets/<namespace>/<bucket>/data --delete

# Preview what would transfer, without uploading
hf sync ./data hf://buckets/<namespace>/<bucket>/data --dry-run

# Only some files
hf sync ./data hf://buckets/<namespace>/<bucket>/data --include "*.parquet" --exclude "tmp/*"

大規模なマイグレーションを実行する前に確認するには、計画をファイルに書き出し、内容を確認してから適用します。これにより、ソースとデスティネーションをそれぞれ1回だけスキャンするだけで済み、ドライランと本番実行で2回スキャンする必要がなくなります。

hf sync ./data hf://buckets/<namespace>/<bucket>/data --plan plan.jsonl   # scan once, write the plan
hf sync --apply plan.jsonl                                                # run exactly that plan

--apply は、プランを作成したディレクトリから実行してください。プランには、入力したとおりのソースパスが記録されるためです。--apply は、すでにアップロードされた内容を確認しないため、中断された実行を再開するには、代わりに通常の hf sync コマンドを再実行してください。

検証するには、ドライランで転送すべきものが残っていないことを確認し、内容を抜き打ちでチェックしてください。

hf sync ./data hf://buckets/<namespace>/<bucket>/data --dry-run
hf buckets ls hf://buckets/<namespace>/<bucket>/data

チューニング

  • キャッシュを高速ディスクに保持します。 Xetクライアントは、チャンクと重複排除インデックス(シャードキャッシュ)をHF_HOMEの下にキャッシュします。ホームディレクトリがNVMe上にない場合は、HF_HOMEをローカルのNVMeに設定してください。
  • リソースに余裕のあるマシンでの一括移行には、高性能モードを有効にしてください。HF_XET_HIGH_PERFORMANCE=1 を設定すると、並行性、バッファサイズ、および同時に取り込むファイル数が引き上げられ、クライアントがすべての CPU コアを活用してネットワークを飽和させるようになります。これは高帯域幅と高速ディスクを備えたマシン向けです。hf_xet の 1.7.0 以前のバージョンでは、少なくとも 64 GB の RAM を備えた環境でのみ使用してください(hf env で確認できます)。環境変数を参照してください。
  • シャードキャッシュの上限を設定する。そのサイズ制限はソフトであり、キャッシュは実行の開始時のみ削除されるため、1つの長時間実行の間に制限を大きく超えて増加する可能性があります。大規模なマイグレーション、特に高性能モードでは、数百 GB に増加してディスクを埋め尽くし、実行が中断される場合があります。HF_XET_SHARD_CACHE_SIZE_LIMITは、空きディスク容量より十分下回る値に設定してください。ただし、必要以上に低くしないようにしてください。サイズがXのキャッシュは、おおよそ 1000 × X のデータに対して重複排除を行います。Shard Cacheを参照してください。

同期を開始する前にこれらを設定してください。サイズには64gbのような人間が読みやすい値を指定できます:

export HF_HOME=/mnt/nvme/hf                 # chunk and shard caches on NVMe
export HF_XET_HIGH_PERFORMANCE=1            # use all cores and the full network
export HF_XET_SHARD_CACHE_SIZE_LIMIT=64gb   # keep the shard cache under free disk space

hf sync ./data hf://buckets/<namespace>/<bucket>/data

サブパスで分割(実験的)

非常に大規模なデータセットでは、ソースをサブパスに分割し、複数のhf syncプロセスを同時に実行できます。初期のテストではスループットがほぼ線形にスケールする傾向が見られますが、さらなる検証が必要です。2つのルール:

  • 関連するデータで分割し、各ワーカーのファイルが互いに適切に重複排除されるようにします。
  • 各ワーカーに独自のHF_HOMEを割り当て、キャッシュの競合を避けてください。各キャッシュはディスク容量を消費するため、HF_XET_SHARD_CACHE_SIZE_LIMITをワーカー間で分割してください。
HF_HOME=/mnt/nvme/hf-a hf sync ./data/groupA hf://buckets/<namespace>/<bucket>/groupA &
HF_HOME=/mnt/nvme/hf-b hf sync ./data/groupB hf://buckets/<namespace>/<bucket>/groupB &
wait

単一プロセスは1つのキャッシュを共有し、重複排除が最も効率的に機能するため、1つのプロセスでネットワークを十分に活用できない場合にのみ分割してください。

トラブルシューティング

症状修正
401 または認証エラーWriteトークンを使用してhf auth loginを実行し、hf auth whoamiで確認してください。
予想より遅いHF_HOMEをNVMeに配置し、HF_XET_HIGH_PERFORMANCE=1を設定して、データに近い場所で実行してください。
実行がディスクフルエラーで中断されますシャードキャッシュがディスクを埋め尽くしました。HF_XET_SHARD_CACHE_SIZE_LIMITを空き容量未満に設定するか、HF_HOMEをより大きなディスクに移動してください。
転送が中断されました同じhf syncコマンドを再実行します。すでにアップロードされたファイルはスキップされます。

AWS S3 または S3 互換ストレージから

hf sync doesn’t read s3:// URLs, so mount the source bucket as a filesystem with Mountpoint for Amazon S3, then sync from the mount. Your data still goes through the Xet client, so you get client-side deduplication.

mount-s3 my-source-bucket /mnt/src
hf sync /mnt/src hf://buckets/<namespace>/<bucket>
umount /mnt/src

Cloudflare R2 や MinIO などの S3 互換ストレージの場合、mount-s3 に --endpoint-url <url> を追加します。AWS Open Data registry などの匿名読み取りを許可するパブリックバケットの場合、--no-sign-request を追加します。検証、チューニング、トラブルシューティングは、ローカルデータの場合と同じです。

代替案: S3ゲートウェイ経由のrclone

すでに rclone を実行しており、マウントを避けたい場合は、こちらを使用してください。トレードオフとして、rclone はクライアント側の重複排除なしにすべてのバイトをS3 ゲートウェイ経由で送信するため、hf syncよりも多くのデータが転送されます。ゲートウェイにはS3 認証情報が必要です。

rclone 1.70 以降を使用してください(rclone versionで確認し、rclone downloadsからアップグレードしてください)。古いバージョンでは、非常に大きなバケットのリスト表示時にメモリ不足が発生する可能性があります。古いアドバイスでは --fast-list の使用が推奨されることが多いですが、最近の rclone では不要です。また、巨大なリスト表示ではすべてをメモリに保持するため、同じような失敗を引き起こす可能性があります。

~/.config/rclone/rclone.conf に、ソースの remote(ここでは aws)の隣に、gateway を remote として追加します:

[hf]
type = s3
provider = Other
endpoint = https://s3.hf.co/<namespace>
access_key_id = HFAK...
secret_access_key = ...
region = us-east-1
force_path_style = true
list_version = 2
upload_cutoff = 256M
chunk_size = 256M

ゲートウェイは ListObjectsV2 のみをサポートしているため、list_version = 2 が必須です。256M パーツを使用すると、rclone のデフォルトである 5M パーツの場合よりも、大規模なファイルをはるかに少ないパーツ数で処理できます。rclone は 1 転送あたり 4 パーツをメモリに保持するため、以下の --transfers 16 では約 16 GB の RAM が必要です。メモリ容量が小さいマシンでは、この値を下げてください。その後、コピーを実行して確認します。

rclone copy aws:my-source-bucket hf:<bucket> --transfers 16 --checkers 16 --progress
rclone check aws:my-source-bucket hf:<bucket>

rclone copyは欠落または変更されたオブジェクトのみを転送するため、再開のために再実行しても安全です。大規模なインポートを行う前に、ゲートウェイの制限、特にオブジェクトキーの命名規則についてお読みください。

Google Cloud StorageまたはAzure Blob Storageから

S3と同様のアプローチです。ソースをそのクラウド独自のドライバでマウントし、hf syncを実行します。

Google Cloud Storage: gcsfuseでマウントします。

gcsfuse my-gcs-bucket /mnt/src
hf sync /mnt/src hf://buckets/<namespace>/<bucket>

Azure Blob Storage: blobfuse2でマウントします。設定ファイルには、ストレージアカウントとコンテナの名前を指定します。

blobfuse2 mount /mnt/src --config-file=./blobfuse2.yaml
hf sync /mnt/src hf://buckets/<namespace>/<bucket>

マウントなしの場合、rclone を使用できます(GCS と Azure をネイティブで読み取ります。上記の hf リモート を再利用できますが、重複排除を行わないというトレードオフは同じです)。または、Job として移行を実行することもできます。

Jobs を使用してバックグラウンドでマイグレーションを実行します

Jobs は Hugging Face のコンピューティングリソース上でスクリプトを実行します。ハードウェアを選択し、CLI から起動して、分単位で課金されます。ラップトップや、開きっぱなしにしておく必要があるセッションではなく、長時間にわたるマルチ TB 規模の移行を無人で実行したい場合に使用してください。

1. 移行スクリプトの作成(migrate.py)。この例では、Xet クライアントを介して S3 プレフィックス内の各オブジェクトをバケットにコピーするため、書き込みは重複排除されます。中程度のプレフィックスのワンショットコピーに適しています。非常に大きなプレフィックスについては、hf-s3reamを参照してください。上部の設定を調整してください:

# /// script
# dependencies = ["huggingface_hub", "boto3", "tqdm"]
# ///
import boto3
from botocore import UNSIGNED
from botocore.config import Config
from huggingface_hub import HfFileSystem
from tqdm.contrib.concurrent import thread_map

# --- adapt these ---
SRC_BUCKET = "my-source-bucket"
SRC_PREFIX = "some/prefix/"
DST = "buckets/<namespace>/<bucket>"
WORKERS = 8   # files copied in parallel
# -------------------

s3 = boto3.client("s3")   # AWS credentials come from the Job's secrets
# For a public bucket (for example from the AWS Open Data registry), read anonymously
# instead, and drop the AWS secrets from the launch command:
# s3 = boto3.client("s3", config=Config(signature_version=UNSIGNED))
fs = HfFileSystem()       # HF token comes from the Job's HF_TOKEN secret

# List the destination once: {path: size} of the files already copied
done = {path: info["size"] for path, info in fs.find(DST, detail=True).items()}

# List the source and keep the objects not copied yet
todo = []
pages = s3.get_paginator("list_objects_v2").paginate(Bucket=SRC_BUCKET, Prefix=SRC_PREFIX)
for page in pages:
    for obj in page.get("Contents", []):
        key = obj["Key"]
        if key.endswith("/"):
            continue  # folder marker: bucket keys can't end with "/"
        if done.get(f"{DST}/{key}") != obj["Size"]:
            todo.append(key)

def copy(key):
    body = s3.get_object(Bucket=SRC_BUCKET, Key=key)["Body"]
    with fs.open(f"{DST}/{key}", "wb") as out:
        for chunk in iter(lambda: body.read(64 << 20), b""):
            out.write(chunk)

# Copy WORKERS files at a time, with a progress bar
thread_map(copy, todo, max_workers=WORKERS)
  • 各オブジェクトは Job のディスクにステージングされ、クローズ時にアップロードされるため、ディスクには最大サイズのオブジェクトを WORKERS 個分同時に保持できる必要があります。多数の小さなオブジェクトを高速に処理するには WORKERS を増やし、非常に大きなオブジェクトの場合は減らしてください。
  • バケット内に同じサイズのファイルが既に存在する場合、そのファイルはスキップされるため、スクリプトを再実行すると中断されたコピーを再開できます。ただし、サイズは同じだが内容が変更されたソースファイルは再コピーされません。変更されるソースとバケットを同期させるには、代わりにソースをマウントしてhf syncを実行してください。

GCSまたはAzureの場合は、boto3をそのクラウドのSDK(google-cloud-storage、azure-storage-blob)に置き換え、リスト表示と読み取りの呼び出しを調整してください。宛先側の処理は同じままで構いません。

2. 背景ジョブとして起動する。認証情報をシークレットとして渡します:

hf jobs uv run --detach --flavor cpu-performance --timeout 24h \
  --secrets HF_TOKEN \
  --secrets AWS_ACCESS_KEY_ID \
  --secrets AWS_SECRET_ACCESS_KEY \
  migrate.py

各 --secrets NAME は、その変数の値を環境から渡します(HF_TOKEN の場合は、設定されていない場合にログイン中のトークンが使用されます)。ジョブはデフォルトで 30 分後に停止するため、転送全体に十分な長さの --timeout を設定してください。ジョブが早期に停止した場合、再度起動すると、すでにコピー済みのファイルはスキップされます。

--detach を使用すると、Job ID が即座に返されます。進捗は hf jobs logs -f <job_id> で追跡し、実行一覧は hf jobs ls で表示し、ハードウェアのオプションは hf jobs hardware で確認できます。

Hubのリポジトリまたは別のバケットから

データがすでに Hub 上のモデルまたはデータセットのリポジトリ、あるいは別のバケットにある場合は、サーバーサイドでコピーしてください。Xet 管理のファイルではコンテンツハッシュのみが移動されるため、コピーはほぼ即時に完了し、再アップロードは発生しません。

# From a dataset repository into a bucket
hf buckets cp hf://datasets/<org>/<dataset>/<path> hf://buckets/<namespace>/<bucket>/<path>

# From one bucket to another
hf buckets cp hf://buckets/<namespace>/<bucket-a>/<path> hf://buckets/<namespace>/<bucket-b>/<path>
  • ソースとデスティネーションは同じストレージリージョン内に存在する必要があります。
  • ソースへの読み取りアクセスと、宛先への書き込みアクセスが必要です。
  • Xetで管理されていない小さなファイル(設定ファイルやREADMEなど)は、自動的にダウンロードされ、再アップロードされます。
  • バケットからリポジトリへコピーする機能はまだ利用できませんが、ロードマップに組み込まれています。

Python での同等の処理については、リポジトリとバケット間のファイルのコピーを参照してください。

hf-s3ream による非常に大きな S3 プレフィックス

hf-s3ream は初期段階(アルファ版)のコミュニティツールであり、Hugging Face が公式にサポートする製品ではありません。大規模な移行に使用する前に、小さなプレフィックスでテストしてください。

hf-s3ream(GitHub でのソース、Apache-2.0)は、Web UI から大規模な S3 バケット間コピーを実行します:

  1. Hugging Faceでサインインしてください。
  2. S3ソースプレフィックス、宛先バケット、AWS認証情報を入力します。匿名読み取りを許可するパブリックバケットの場合は、Public bucketをオンにします。この場合、AWS認証情報は不要であり、JobsはS3に署名なしで読み取ります。
  3. Analyze は、アクセス権限の確認、ソースリージョンの検出、および構成の推奨を行う低コストのドライランを実行します。存在しない場合は、デスティネーションバケット(プライベート)を作成します。
  4. Run をクリックすると、プランナージョブが起動します。プランナーは範囲ベースのコピー計画を作成し、コピアジョブを開始して、ライブグラフ上で進捗を表示します。タブを閉じてもコピーは実行を続けますが、ページからは再接続できません。コピーを停止するには、Stop copy をクリックするか、プランナージョブをキャンセル(hf jobs cancel <planner-job-id>)してください。プランナーは自身のコピアをキャンセルします。

hf-s3ream は、あなたのアカウント配下の Jobs で実行されるため、Jobs の請求はあなたに課金されます。プライベートネットワーク(VPC)からのアクセスのみを許可する S3 バケットには、Jobs からアクセスできません。

大規模なマイグレーションの実行場所

マルチTB規模の移行では、通常、ラップトップではなくクラウドVM上で転送を実行します。VMの管理を避けたい場合は、Jobとして実行できます。

  • ソースと同じクラウドとリージョンで実行します。ローカルネットワーク経由でソースを読み込むのが最も高速かつ低コストであり、ソースクラウドからのエグレスが通常は最大の費用要因です。その後、アップロードはインターネット経由で Hugging Face(US リージョンは AWS us-east-1)に送信されます。
  • 1つのプロセスで多数のスレッドを使用します。 高性能モードの単一のhf syncは、1つの重複排除キャッシュを共有します。1つのプロセスでネットワークを飽和させられない場合のみ、サブパスで分割してください。
  • 長時間の実行を維持します。 SSH 経由で移行を開始する場合は、セッションが切断されても実行が続くように、tmux(または screen、nohup)内で開始してください: tmux new -s migrate。Ctrl-b の後に d を押してデタッチし、後で tmux attach -t migrate を実行して再接続します。

テストランで検証するための、サイズ設定の出発点:

リソースガイダンスAWSの例GCPの例
ディスクHF_HOME用のローカルNVMeストレージを使用し、シャードキャッシュの上限を超える空き容量を確保してください。キャッシュにはネットワーク接続ディスクを避けてください。インスタンスストア NVMe(c7i/m7i d バリアント、またはi4i)n2またはc3VM上のローカルSSD
CPU多数のvCPU: クライアントがCPU上でデータをチャンク化し、ハッシュ化します。c7i.8xlarge またはそれ以上c3-standard-22以上
メモリ高性能モードのバッファには十分な容量が必要です。hf_xetを使用する場合、1.7.0以前では少なくとも64 GB必要です。——
ネットワークインターネットへの高帯域(25 Gbps クラス)。——

次のステップ

  • データをその場で使用します。hf-mount を使用してバケットをローカルファイルシステムとしてマウントするか、Jobs と Spaces でのボリューム としてマウントします。
  • ツールから直接読み取れます。 pandas、Dask、PyArrow、Daft、DuckDB、🤗 Datasets、Spark は hf://buckets/... パスを直接読み取れます。バケット統合を参照してください。

マウント経由で一括インジェストを実行しないでください。hf-mount は書き込みをディスク上のキャッシュ(デフォルトでは /tmp/hf-mount-cache)にステージングするため、これを経由した大規模なマイグレーションではそのディスクが埋まってしまう可能性があります。データをバケットに格納するには、上記のいずれかのパスを使用してください。マウント経由で大量の書き込みを行う必要がある場合は、十分な空き容量があるディスクをキャッシュ先として指定してください: hf-mount start --cache-dir /mnt/big bucket <namespace>/<bucket> /mnt/data(このフラグは bucket の前に指定します)。

Update on GitHub