Hub Python Library documentation
通过文件系统 API 与 Hub 交互
通过文件系统 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