Hub Python Library documentation

Interaja com o Hub por meio da API de Filesystem

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

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