Hub Python Library documentation
Filesystem API を使用して Hub と対話する
Filesystem API を使用して Hub と対話する
HfApiに加えて、huggingface_hubライブラリは、Hugging Face HubへのPython的なfsspec互換ファイルインターフェースであるHfFileSystemを提供します。HfFileSystemはHfApiを基盤として構築されており、cp、mv、ls、du、glob、get_file、put_fileといった典型的なファイルシステムスタイルの操作を提供します。
HfFileSystem は fsspec 互換性を提供しており、これを必要とするライブラリ(
pandasを用いて Hugging Face のデータセットやバケットを直接読み込む場合など)で有用です。ただし、この互換性レイヤーにより追加のオーバーヘッドが発生します。パフォーマンスと信頼性を高めるため、可能な場合は HfApi のメソッドを使用することをお勧めします。
使用方法
>>> from huggingface_hub import hffs
>>> # List all files in a dataset directory
>>> hffs.ls("datasets/my-username/my-dataset-repo/data", detail=False)
['datasets/my-username/my-dataset-repo/data/train.csv', 'datasets/my-username/my-dataset-repo/data/test.csv']
>>> # List all files in a bucket directory
>>> hffs.ls("buckets/my-username/my-bucket/experiment-data", detail=False)
['bucket/my-username/my-bucket/data/train-0000.parquet', 'bucket/my-username/my-bucket/data/train-0001.parquet', ...]
>>> # List all ".csv" files in a dataset repository
>>> hffs.glob("datasets/my-username/my-dataset-repo/**/*.csv")
['datasets/my-username/my-dataset-repo/data/train.csv', 'datasets/my-username/my-dataset-repo/data/test.csv']
>>> # Read a remote file
>>> with hffs.open("datasets/my-username/my-dataset-repo/data/train.csv", "r") as f:
... train_data = f.readlines()
>>> # Read the content of a remote file as a string
>>> train_data = hffs.read_text("datasets/my-username/my-dataset-repo/data/train.csv", revision="dev")
>>> # Write a remote file
>>> with hffs.open("datasets/my-username/my-dataset-repo/data/validation.csv", "w") as f:
... f.write("text,label")
... f.write("Fantastic movie!,good")オプションのrevision引数を渡すことで、ブランチ、タグ名、コミットハッシュなどの特定のコミットから操作を実行できます。revisionはBucketsと互換性がないことに注意してください。
Pythonの組み込みのopenとは異なり、fsspecのopenはデフォルトでバイナリモードの"rb"になります。そのため、テキストモードで読み取りには"r"、書き込みには"w"を明示的に設定する必要があります。ファイルへの追記(モード"a"および"ab")は現在サポートされていません。
大規模リポジトリのリスト表示
find や glob のようなファイルを再帰的に列挙する操作では、リポジトリの全コンテンツを取得する必要があります。Hub はこれらのエントリをページ単位で返却しますが、前のページを受信した後にのみ次のページをリクエストできます。そのため、80万ファイルを含むリポジトリの列挙には約800回のシーケンシャルなリクエスト、つまり約30分かかります。
それを避けるために、HfFileSystem は大規模なリポジトリをディレクトリごとに並列で列挙します:
>>> from huggingface_hub import hffs
>>> # Takes ~30s on a repository holding 800k files
>>> files = hffs.glob("datasets/allenai/objaverse/**/*.glb", maxdepth=3)同時リクエストの数は、HfFileSystemのmax_workers引数で制御されます。デフォルト値は16ですが、並列リスト表示を無効にするには1に設定できます。
maxdepthを渡すこともリスト表示を大幅に高速化します。これは、Hubが実際にリクエストされたエントリのみを返すようになるためです。
リストの鮮度を保つ
ディレクトリは一度のみ列挙され、その内容はキャッシュされるため、他のユーザーが変更したばかりのディレクトリは自動的に反映されません。HfFileSystem.invalidate_cache() は、キャッシュされた列挙情報を破棄します。引数なしで呼び出すとすべてのパスに対して、引数を指定するとそのパス(および親ディレクトリ)に対して適用されます。
>>> hffs.ls("buckets/my-username/my-bucket/data", detail=False) # listing is cached
>>> # ... another process uploads a file to the bucket ...
>>> hffs.invalidate_cache("buckets/my-username/my-bucket/data")
>>> hffs.ls("buckets/my-username/my-bucket/data", detail=False) # listed again
['buckets/my-username/my-bucket/data/train.csv', 'buckets/my-username/my-bucket/data/new-file.csv']バケットの場合、huggingface_hubがこれを行います。Hubはバケットのファイル変更をリアルタイムでストリーミングし、HfFileSystemは変更が届くとすぐに、その変更の影響を受けたリストを破棄します。live_follow=Trueを指定して有効にします。
>>> from huggingface_hub import HfFileSystem
>>> hffs = HfFileSystem(live_follow=True)
>>> hffs.ls("buckets/my-username/my-bucket/data", detail=False) # starts following that bucket
>>> # ... another process uploads a file to the bucket ...
>>> hffs.ls("buckets/my-username/my-bucket/data", detail=False) # refreshed as changes arrive
['buckets/my-username/my-bucket/data/train.csv', 'buckets/my-username/my-bucket/data/new-file.csv']また、fsspec.filesystem("hf", live_follow=True) を通して、または引数を受け付けるライブラリ(pandas、arrow など)の storage_options 引数を通じて渡すこともできます。
これについて知っておくべきこと:
- バケットのみ。モデル、データセット、スペースのリポジトリは git リポジトリであり、Hub はそれらの変更をストリーミングしません。新しいコミットを確認するには、HfFileSystem.ls() に
refresh=Trueを渡すか、HfApi.list_repo_tree() を使用してください。 - 更新されるのは、リスト表示とそのメタデータのみです。 ファイルの読み取りでは常に Hub からそのコンテンツを要求するため、ライブフォローが影響するのは、
ls、info、exists、glob、… が報告する内容のみです。 - バケットがリストされた時点でフォローが開始され、フォロー中の各バケットにつき1つのバックグラウンド接続が常時開かれた状態に保たれます。この接続はすべてのHfFileSystemインスタンスで共有されます。そのため、このオプションはオプトイン方式となっています。
統合
fsspec と統合されているライブラリであれば、URL が以下のスキームに従っている限り、HfFileSystem を使用できます:
hf://[<repo_type_prefix>]<repo_id>[@<revision>]/<path/in/repo>
repo_type_prefix は、データセットの場合は datasets/、Spaces の場合は spaces/ であり、モデルは URL にプレフィックスを付ける必要はありません。
リポジトリに加えて、HfFileSystemはHugging Face Bucketsもサポートしています。これはS3のようなオブジェクトストレージです(詳細はこのガイドを参照してください):
hf://buckets/<bucket_id>/<path/in/bucket>HfFileSystem を使用して Hub とのやり取りを簡素化できる、いくつかの興味深い統合を以下に示します。
HubリポジトリからPandas DataFrameを読み込む/書き出す:
>>> import pandas as pd >>> # Read a remote CSV file into a dataframe >>> df = pd.read_csv("hf://datasets/my-username/my-dataset-repo/train.csv") >>> df = pd.read_csv("hf://buckets/my-username/my-bucket/train.csv") >>> # Write a dataframe to a remote CSV file >>> df.to_csv("hf://datasets/my-username/my-dataset-repo/test.csv") >>> df.to_csv("hf://buckets/my-username/my-bucket/test.csv")
同じワークフローは、DaskおよびPolarsのDataFrameにも使用できます。
DuckDBで(リモートの)Hubファイルをクエリする:
>>> from huggingface_hub import HfFileSystem >>> import duckdb >>> fs = HfFileSystem() >>> duckdb.register_filesystem(fs) >>> # Query a remote file and get the result back as a dataframe >>> fs_query_file = "hf://datasets/my-username/my-dataset-repo/data_dir/data.parquet" >>> df = duckdb.query(f"SELECT * FROM '{fs_query_file}' LIMIT 10").df()ZarrをアレイストアとしてHubを使用する:
>>> import numpy as np >>> import zarr >>> embeddings = np.random.randn(50000, 1000).astype("float32") >>> # Write an array to a repo >>> root = zarr.open_group("hf://my-username/my-model-repo/array-store", mode="w") >>> foo = root.create_group("embeddings") >>> foobar = foo.zeros(name="experiment_0", shape=(50000, 1000), chunks=(10000, 1000), dtype="f4") >>> foobar[:] = embeddings >>> # Read an array from a repo >>> root = zarr.open_group("hf://my-username/my-model-repo/array-store", mode="r") >>> first_row = root["embeddings/experiment_0"][0]
認証
多くの場合、Hubとやり取りするにはHugging Faceアカウントでログインする必要があります。Hubでの認証方法の詳細については、ドキュメントのAuthenticationセクションを参照してください。
token を HfFileSystem の引数として渡すことで、プログラム的にもログインできます。
>>> from huggingface_hub import HfFileSystem
>>> hffs = HfFileSystem(token=token)この方法でログインする場合は、ソースコードを共有する際にトークンを誤って漏洩しないよう注意してください!
Update on GitHub