Hub Python Library documentation

Interaja com o Hub por meio da API de Filesystem

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

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=True para 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