Hub Python Library documentation
Interaja com o Hub por meio da API de Filesystem
Interaja com o Hub por meio da API de Filesystem
Além do HfApi, a biblioteca huggingface_hub oferece o HfFileSystem, uma interface de arquivos compatível com fsspec e pythonic para o Hugging Face Hub. O HfFileSystem é construído sobre o HfApi e oferece operações típicas de sistema de arquivos, como cp, mv, ls, du, glob, get_file e put_file.
HfFileSystem oferece compatibilidade com fsspec, o que é útil para bibliotecas que a exigem (por exemplo, para ler datasets e buckets do Hugging Face diretamente com
pandas). No entanto, essa camada de compatibilidade introduz sobrecarga adicional. Para melhor desempenho e confiabilidade, recomenda-se usar os métodos de HfApi sempre que possível.
Uso
>>> 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")O argumento opcional revision pode ser passado para executar uma operação a partir de um commit específico, como um branch, nome de tag ou hash de commit. Observe que revision não é compatível com Buckets.
Diferentemente do open embutido do Python, o open do fsspec usa o modo binário, "rb", por padrão. Isso significa que você deve definir explicitamente o modo como "r" para leitura e "w" para escrita em modo de texto. A adição a um arquivo (modos "a" e "ab") ainda não é suportada.
Listando repositórios grandes
Operações que listam arquivos de forma recursiva, como find e glob, precisam buscar todo o conteúdo do repositório. O Hub retorna essas entradas página por página, e uma página só pode ser solicitada após a anterior ter sido recebida: listar um repositório com 800 mil arquivos requer cerca de 800 solicitações sequenciais e, portanto, aproximadamente 30 minutos.
Para evitar isso, o HfFileSystem lista repositórios grandes diretório por diretório, em paralelo:
>>> from huggingface_hub import hffs
>>> # Takes ~30s on a repository holding 800k files
>>> files = hffs.glob("datasets/allenai/objaverse/**/*.glb", maxdepth=3)O número de solicitações simultâneas é controlado pelo argumento max_workers de HfFileSystem. O valor padrão é 16
e pode ser definido como 1 para desabilitar listagens paralelas.
Observe que passar um maxdepth também acelera significativamente as listagens, pois o Hub retorna apenas as entradas
que são efetivamente solicitadas.
Mantenha as listagens atualizadas
Os diretórios são listados uma vez e seu conteúdo é cacheado, portanto, um diretório que outra pessoa acabou de modificar não é detectado automaticamente. HfFileSystem.invalidate_cache() descarta as listagens em cache, seja para um caminho (e seus pais) ou em todos os lugares quando chamado sem argumento:
>>> 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']Para buckets, o huggingface_hub pode fazer isso por você: o Hub transmite as alterações de arquivo de um bucket conforme elas ocorrem e o HfFileSystem remove as listagens afetadas por uma alteração assim que ela chega. Ative com 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']Ele também pode ser passado por meio do fsspec, com fsspec.filesystem("hf", live_follow=True) ou por meio do argumento storage_options das bibliotecas que aceitam um (pandas, arrow, …).
Algumas coisas a saber sobre ele:
- Somente buckets. Repositórios de modelos, conjuntos de dados e espaços são repositórios git e o Hub não transmite suas alterações: passe
refresh=Truepara HfFileSystem.ls() (ou use HfApi.list_repo_tree()) para ver um novo commit. - Somente as listagens e os metadados que elas carregam são atualizados. A leitura de um arquivo sempre solicita seu conteúdo do Hub, portanto, o acompanhamento em tempo real afeta apenas o que
ls,info,exists,glob, … relatam. - O acompanhamento começa assim que um bucket é listado, e uma conexão de plano de fundo é mantida aberta para cada bucket acompanhado, compartilhada por todas as instâncias de HfFileSystem. É por isso que a opção é opt-in.
Integrações
O HfFileSystem pode ser usado com qualquer biblioteca que integre o fsspec, desde que a URL siga o esquema:
hf://[<repo_type_prefix>]<repo_id>[@<revision>]/<path/in/repo>
O repo_type_prefix é datasets/ para datasets, spaces/ para Spaces, e os modelos não precisam de prefixo na URL.
Além dos repositórios, o HfFileSystem também suporta Buckets do Hugging Face, que são um armazenamento de objetos semelhante ao S3 (veja este guia para mais detalhes):
hf://buckets/<bucket_id>/<path/in/bucket>Algumas integrações interessantes em que o HfFileSystem simplifica a interação com o Hub estão listadas abaixo:
Lendo/gravando um DataFrame do Pandas de/para um repositório do Hub:
>>> 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")
O mesmo fluxo de trabalho também pode ser usado para DataFrames do Dask e do Polars.
Consultando arquivos (remotos) do Hub com DuckDB:
>>> 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()Usando o Hub como um armazenamento de arrays com 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]
Autenticação
Em muitos casos, é necessário estar conectado com uma conta do Hugging Face para interagir com o Hub. Consulte a seção Autenticação da documentação para saber mais sobre os métodos de autenticação no Hub.
Também é possível fazer login programaticamente passando seu token como argumento para HfFileSystem:
>>> from huggingface_hub import HfFileSystem
>>> hffs = HfFileSystem(token=token)Se você fizer login dessa forma, tenha cuidado para não vazar acidentalmente o token ao compartilhar seu código-fonte!
Update on GitHub