Hub Python Library documentation

通过文件系统 API 与 Hub 交互

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v2.4.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

通过文件系统 API 与 Hub 交互

除了 HfApi 之外,huggingface_hub 库还提供了 HfFileSystem,这是一个符合 Python 风格的、兼容 fsspec 的 Hugging Face Hub 文件接口。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"。这意味着在文本模式下,您必须显式地将 mode 设置为 "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']

对于 bucket,huggingface_hub 可以为您完成此操作:Hub 会实时流式传输 bucket 的文件变更,而 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) 经由 fsspec 传递,或者通过接受该参数的库(pandas、arrow 等)的 storage_options 参数传递。

关于它,有几点需要了解:

  • 仅限存储桶。模型、数据集和空间仓库均为 git 仓库,Hub 不会流式传输其变更:请向 HfFileSystem.ls() 传入 refresh=True(或使用 HfApi.list_repo_tree())以查看新的提交。
  • 仅刷新列表及其携带的元数据。读取文件时始终会从 Hub 请求其内容,因此实时跟踪仅影响 ls、info、exists、glob、… 所报告的内容。
  • 只要列出了某个存储桶,跟随操作便会立即开始,并且每个被跟随的存储桶都会保持一个后台连接处于打开状态,该连接由所有 HfFileSystem 实例共享。因此,该选项采用选择性启用(opt-in)的方式。

集成

HfFileSystem 可与任何集成了 fsspec 的库配合使用,前提是 URL 遵循以下格式:

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()
  • 使用 Hub 作为 Zarr 数组存储:

    >>> 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]

身份验证

在许多情况下,你必须使用 Hugging Face 账户登录才能与 Hub 进行交互。请参阅文档中的 Authentication 部分,以了解有关 Hub 上身份验证方法的更多信息。

也可以通过将 token 作为参数传递给 HfFileSystem 来以编程方式登录:

>>> from huggingface_hub import HfFileSystem
>>> hffs = HfFileSystem(token=token)

如果您以这种方式登录,请注意在分享源代码时不要意外泄露令牌!

Update on GitHub