ファイルのダウンロード¶
thinkingface からファイルを取り出す方法には、根本的に異なる 2 つの経路があります。
huggingface_hub、datasets、git、素の HTTP がいずれも使っているサーバー経由の経路と、
サーバーをまったく介さずオブジェクトストアから直接取り出す経路です。このページではその
両方と、後者がひと手間かける価値のある場面を説明します。
経路を選ぶ¶
| 経路 | 向いている用途 |
|---|---|
hf_hub_download |
パスの分かっているファイルを 1 つ、ローカルキャッシュ付きで取得する |
snapshot_download |
あるリビジョンの全ファイルをローカルディレクトリに取得する |
datasets.load_dataset |
データセットリポジトリを Dataset オブジェクトとして読む |
resolve URL |
curl、wget、その他 HTTP を話すあらゆるもの |
git clone |
履歴すべてと、コミットできる作業ツリー |
生成される gcloud storage cp スクリプト |
大量の復元、およびサーバーを経由せずにバケット間でコピーする場合 |
Hugging Face クライアントを設定する¶
アップロード側と同じ 3 つの環境変数です。
export HF_ENDPOINT=http://localhost:8080
export HF_TOKEN=tf_xxxxxxxxxxxx
export HF_HUB_DISABLE_XET=1
これらは Python を起動する前に export してください。huggingface_hub は import 時に一度
だけデフォルトのエンドポイントを解決します。詳細と thinkingface.login() ヘルパーについては
ファイルのアップロード を参照してください。
1 つのファイルをダウンロードする¶
from huggingface_hub import hf_hub_download
path = hf_hub_download(
repo_id="admin/imdb-reviews",
repo_type="dataset",
filename="data/train.parquet",
)
戻り値はローカルの huggingface_hub キャッシュ内のパスです。そのため、変更のないファイルに
対して再度呼び出してもリクエスト 1 回で済み、転送は発生しません。リビジョンを固定するには
revision= を使います。ブランチ名、タグ、コミット SHA のいずれも指定できます。
path = hf_hub_download(
repo_id="acme/sentiment-base",
filename="model.safetensors",
revision="v1.0",
)
リビジョン全体をダウンロードする¶
from huggingface_hub import snapshot_download
local_dir = snapshot_download(repo_id="admin/imdb-reviews", repo_type="dataset")
snapshot_download は全パスのメタデータをまとめて 1 回でサーバーに問い合わせてから
ファイルを取得するため、自分で hf_hub_download をループさせるよりもかなり効率的です。
取得対象を絞り込むには allow_patterns / ignore_patterns を使います。
データセットを読み込む¶
datasets はコードを変更せずに thinkingface に対して動作します。
from datasets import load_dataset
ds = load_dataset("admin/imdb-reviews")
分割(split)の検出も通常どおり動作します。ファイルが data/train-*.parquet と
data/test-*.parquet のように配置されているリポジトリは、追加の設定なしに train と
test の split として解決されます。
明示的に指定したい場合、あるいはリポジトリが datasets の認識するレイアウトに従っていない
場合は、先にファイルをダウンロードしてパスから読み込んでください。
from datasets import load_dataset
from huggingface_hub import hf_hub_download
path = hf_hub_download(
repo_id="admin/imdb-reviews", repo_type="dataset", filename="data/train.parquet"
)
ds = load_dataset("parquet", data_files=path)
素の HTTP でダウンロードする¶
すべてのファイルは resolve URL から取得できます。これは Hugging Face Hub と同じ URL の形
です。データセットには /datasets プレフィックスが付き、モデルはルート直下に配置されます。
http://localhost:8080/datasets/{namespace}/{name}/resolve/{revision}/{path}
http://localhost:8080/{namespace}/{name}/resolve/{revision}/{path}
curl -L -H "Authorization: Bearer tf_xxxxxxxxxxxx" \
-o train.parquet \
http://localhost:8080/datasets/admin/imdb-reviews/resolve/main/data/train.parquet
これらの URL について知っておくべきことが 3 つあります。
- リダイレクトをたどってください。 通常のファイルは git から直接ストリーミングされます。
LFS ファイルはバケット上のオブジェクトへの有効期限付き署名付き URL にリダイレクトされる
ため、転送が API サーバーを通ることはありません。(URL に署名できないローカルの
ストレージエミュレータに対しては、代わりにサーバーがオブジェクトを中継します。)
curl -Lはどちらのケースにも対応します。 HEADが使えます。 しかも安価で、何も転送せずにサイズとオブジェクトの識別子を返します。- すべて添付ファイルとして配信されます。
Content-Disposition: attachmentとX-Content-Type-Options: nosniffが付きます。リポジトリに push した.htmlファイルは、 意図的にレンダリングされずダウンロードされます。
バケットから直接リビジョンを復元する¶
バケット内のオブジェクトは 内容アドレス方式 で保存されます。LFS オブジェクトは
lfs/{oid[0:2]}/{oid[2:4]}/{oid}、通常のファイルは blobs/{sha[0:2]}/{sha[2:4]}/{sha} です。バケット内にネームスペース、リポジトリ、
パスにちなんだ名前を持つものは何もないため、cp -r できるディレクトリツリーは存在しません。
名前を復元するのは、サーバーが要求に応じて生成するスクリプトです。このスクリプトが、内容
アドレスで保存された各オブジェクトを、そのリビジョンにおけるパスに対応付けます。
次のような場合に使ってください。
- 大きなリビジョンを復元するにあたって、バイト列を API サーバーに一切通したくないとき。
- 送り先が別のバケットであるとき。
DESTにgs://プレフィックスを渡すと、ダウンロード ではなくサーバーサイドのバケット間コピーになります。 - 再現可能なものを同僚に渡したいとき。スクリプトは決定的であり、その元になるファイル一覧は パス順にソートされています。
Web UI から¶
リポジトリページを開き、GCS access を選びます。ダイアログにはそのリビジョンのファイル数
と合計サイズが表示され、コピー可能な gcloud storage script が用意されています。リビジョン
に Parquet ファイルが含まれる場合は、対応する read_parquet() クエリを収めた DuckDB
タブも表示されます。ファイルブラウザ内の個々のファイルにも GCS access アクションがあり、
1 ファイル分の gcloud storage cp コマンドをコピーできます。
API から¶
curl -s http://localhost:8080/api/v1/repos/dataset/admin/imdb-reviews/gcs/main \
| jq -r .gcloud_script | DEST=./imdb-ja sh
レスポンスにはファイル一覧(files。各要素が gs:// URI、サイズ、lfs フラグを持ちます)と
DuckDB 用のスニペット(duckdb_snippet)も含まれるため、スクリプトをそのまま実行するのでは
なく、これらを使って独自のツールを組むこともできます。
スクリプト自体は次のような内容です。
#!/bin/sh
# thinkingface: datasets/admin/imdb-reviews @ main -- 3 files, 536871936 bytes
# Objects are content-addressed; this script lays them out under DEST.
# DEST may be a local directory or a gs:// prefix.
set -eu
DEST="${DEST:-./imdb-ja}"
cp_one() {
case "$DEST" in gs://*) ;; *) mkdir -p "$(dirname "$2")" ;; esac
gcloud storage cp "$1" "$2"
}
cp_one 'gs://my-bucket/blobs/3f/2a/3f2a9c…' "$DEST"/'README.md'
cp_one 'gs://my-bucket/lfs/9b/1d/9b1de4…' "$DEST"/'data/train.parquet'
DEST のデフォルトはリポジトリ名を付けたディレクトリです。スクリプト内の gs:// キーは
すべて内容アドレスなので、同じキーをオブジェクトストレージから読む他のもの — DuckDB の
read_parquet()、BigQuery の外部テーブル、別マシン上の学習ジョブなど — にそのまま渡せます。
2 つの注意点¶
- スクリプトが列挙するのは、git が知っている内容ではなくインデックス済みの内容です。 これは push のたびにバックグラウンドワーカーが作り直すファイルインデックスから生成される ため、たった今 push されたリビジョンや、タグとしてしか存在しない(インデックス作成が 予約されない)リビジョンは、エラーではなく空のファイル一覧が返ることがあります。少し待って から再度取得してください。
-
バケットへのアクセスは thinkingface へのアクセスとは別物です。 スクリプトの生成は API の通常の読み取りですが、実行 にはバケット自体の認証情報が必要で、これは thinkingface が発行するものではありません。ローカルの compose 環境では、
gcloudCLI を ストレージエミュレータに向けることになります。gcloud config set api_endpoint_overrides/storage http://localhost:4443/storage/v1/
リポジトリをクローンする¶
履歴付きの作業ツリーが欲しい場合はクローンしてください。HTTP または SSH 経由の
git clone を使い、大きなファイルの実体はチェックアウト時に Git LFS が取得します。
Git を使う を参照してください。
誰が何を読めるか¶
thinkingface には リポジトリの公開設定がありません。リポジトリに private / public の
フラグはなく、リポジトリ単位の読み取り権限もありません。インスタンス上のすべてのリポジトリ
は、認証情報をまったく提示しない呼び出し元も含め、サーバーに到達できる全員が読み取れます。
create_repo に渡す private=True はクライアント互換性のために受け付けられますが、何も
しません。
権限システムが制御するのは書き込みです。インスタンスそのものをセキュリティ境界とみなし、 中身が機微なものであればネットワークの内側に置いてください。
| 経路 | 必要な認証情報 |
|---|---|
hf_hub_download、snapshot_download、load_dataset |
読み取りには不要。ただし同じスクリプトで書き込みもできるよう HF_TOKEN は設定しておく価値があります |
resolve URL |
読み取りには不要。Authorization: Bearer tf_... は受け付けられます |
HTTP 経由の git clone |
読み取りには不要。push にはトークンが必要 |
SSH 経由の git clone |
常に登録済みの SSH 鍵が必要 — SSH トランスポートはすべての接続を認証します |
gcloud storage cp スクリプト |
生成には不要。実行にはバケット自体の認証情報が必要 |
トークン、スコープ、ロールについては 認証 を参照して ください。