Hub documentation

Migrando dados para buckets de armazenamento

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Migrando dados para buckets de armazenamento

Este guia mostra como mover grandes conjuntos de dados para um Storage Bucket de onde eles estão atualmente: disco local, outra nuvem ou o Hub. Encontre sua origem na tabela abaixo e vá para a seção correspondente.

Sempre que possível, faça com que seus dados sejam legíveis como um sistema de arquivos e execute hf sync. Ele remove duplicatas no cliente, de modo que você envia menos bytes do que em uma cópia bruta.

Visão geral

Onde seus dados estão agoraRecomendadoAlternativas
Disco local ou sistema de arquivos do clusterhf sync—
AWS S3 ou compatível com S3 (R2, MinIO)Monte com mount-s3 e, em seguida, execute hf syncrclone por meio do gateway S3
Google Cloud StorageMonte com gcsfuse e depois execute hf syncrclone, ou um Job
Azure Blob StorageMonte com blobfuse2 e depois execute hf syncrclone, ou um Job
Um repositório do Hub ou outro buckethf buckets cp (lado do servidor)—
Prefixo S3 muito grandehf-s3ream (alpha)Mount + hf sync, dividido por subcaminho

Por que hf sync é o padrão:

  • Você faz upload de menos. hf sync faz upload por meio do cliente Xet, que divide e deduplica seus dados primeiro, de modo que apenas os blocos que o Hub ainda não viu são enviados. Uma cópia bruta (por exemplo, rclone por meio do gateway S3) transfere cada byte.
  • É pelo menos tão rápido. Nas migrações que já suportamos, o hf sync sobre uma fonte montada igualou ou superou o rclone em throughput.

Antes de começar

Todos os comandos neste guia usam hf, o Hugging Face CLI. A saída de ajuda é legível por agentes, então um agente de código pode montar e monitorar uma migração para você (veja CLI para Agentes de IA). Revise os comandos antes de executá-los em escala.

  1. Instale o CLI. O cliente Xet é distribuído junto com ele.

    curl -LsSf https://hf.co/cli/install.sh | bash
    hf version
  2. Faça login com um token que tenha acesso de Escrita (crie um):

    hf auth login
    hf auth whoami
  3. Crie o bucket de destino. <namespace> é seu nome de usuário ou organização. Sem --region, o bucket é criado na região de armazenamento padrão do namespace, que é sempre os EUA fora dos planos Team & Enterprise. Nesses planos, passe --region us ou --region eu para escolher.

    hf buckets create <namespace>/<bucket> --private

Comece com uma execução de teste. Independentemente do caminho que você usar, ensaie-o em um subconjunto pequeno (uma pasta, ou um padrão --include), verifique o resultado com --dry-run e hf buckets ls e, em seguida, inicie a migração completa. Todos os caminhos neste guia podem ser retomados, portanto, uma execução de teste não tem custo.

De um disco local ou de um sistema de arquivos de cluster

Use isso quando seus dados estiverem em um disco local, um volume anexado ou no scratch do cluster: qualquer coisa que a máquina possa ler como arquivos. Este também é o último passo de todos os caminhos de nuvem abaixo, uma vez que a origem esteja montada.

hf sync ./data hf://buckets/<namespace>/<bucket>/data

hf sync compara a origem e o destino e transfere apenas a diferença, portanto, reexecutar o mesmo comando retoma uma migração interrompida: os arquivos já enviados são ignorados. Variantes comuns:

# Mirror exactly: also delete destination files that are gone from the source
hf sync ./data hf://buckets/<namespace>/<bucket>/data --delete

# Preview what would transfer, without uploading
hf sync ./data hf://buckets/<namespace>/<bucket>/data --dry-run

# Only some files
hf sync ./data hf://buckets/<namespace>/<bucket>/data --include "*.parquet" --exclude "tmp/*"

Para revisar uma migração de grande porte antes de executá-la, escreva o plano em um arquivo, verifique-o e, em seguida, aplique-o. Isso varre a origem e o destino uma única vez, em vez de uma vez para uma simulação e outra para a execução real.

hf sync ./data hf://buckets/<namespace>/<bucket>/data --plan plan.jsonl   # scan once, write the plan
hf sync --apply plan.jsonl                                                # run exactly that plan

Execute --apply a partir do diretório onde você criou o plano, pois o plano registra o caminho de origem exatamente como você o digitou. --apply não verifica o que já foi enviado, portanto, para retomar uma execução interrompida, execute novamente o comando simples hf sync.

Para verificar, confira se uma execução de teste não tem mais nada para transferir e verifique o conteúdo:

hf sync ./data hf://buckets/<namespace>/<bucket>/data --dry-run
hf buckets ls hf://buckets/<namespace>/<bucket>/data

Ajuste

  • Mantenha o cache em um disco rápido. O cliente Xet faz o cache de blocos e de um índice de deduplicação (o cache de shard) em HF_HOME. Aponte HF_HOME para um NVMe local se o seu diretório home não estiver em um.
  • Ative o modo de alto desempenho para migrações em massa em uma máquina com recursos abundantes. HF_XET_HIGH_PERFORMANCE=1 aumenta a concorrência, os tamanhos de buffer e o número de arquivos ingeridos de uma vez, permitindo que o cliente utilize todos os núcleos de CPU e sature a rede. Ele é destinado a máquinas com alta largura de banda e disco rápido; com versões do hf_xet anteriores à 1.7.0, use-o apenas com pelo menos 64 GB de RAM (verifique o seu com hf env). Consulte Variáveis de Ambiente.
  • Limite do cache de shards. Seu limite de tamanho é flexível: o cache é reduzido apenas no início de uma execução, portanto, dentro de uma única execução longa, ele pode crescer bem além do limite. Em uma migração grande, especialmente no modo de alto desempenho, ele pode crescer para centenas de GB e encher o disco, interrompendo a execução. Defina HF_XET_SHARD_CACHE_SIZE_LIMIT confortavelmente abaixo do seu espaço livre em disco, mas não menor do que o necessário: um cache de tamanho X deduplica em relação a aproximadamente 1000 × X de dados. Veja Shard Cache.

Defina esses valores antes de iniciar a sincronização. Os tamanhos aceitam valores legíveis por humanos, como 64gb:

export HF_HOME=/mnt/nvme/hf                 # chunk and shard caches on NVMe
export HF_XET_HIGH_PERFORMANCE=1            # use all cores and the full network
export HF_XET_SHARD_CACHE_SIZE_LIMIT=64gb   # keep the shard cache under free disk space

hf sync ./data hf://buckets/<namespace>/<bucket>/data

Dividir por subcaminho (experimental)

Para conjuntos de dados muito grandes, você pode dividir a origem em subcaminhos e executar vários processos hf sync simultaneamente. Testes iniciais sugerem que a taxa de transferência escala aproximadamente de forma linear, mas isso precisa de mais validação. Duas regras:

  • Divida com base em dados relacionados, para que os arquivos de cada worker sejam deduplicados de forma eficaz entre si.
  • Dê a cada worker seu próprio HF_HOME para que não haja disputa pelo cache. Cada cache ocupa espaço em disco, então divida HF_XET_SHARD_CACHE_SIZE_LIMIT entre os workers.
HF_HOME=/mnt/nvme/hf-a hf sync ./data/groupA hf://buckets/<namespace>/<bucket>/groupA &
HF_HOME=/mnt/nvme/hf-b hf sync ./data/groupB hf://buckets/<namespace>/<bucket>/groupB &
wait

Um único processo compartilha um único cache e deduplica melhor, portanto, divida apenas quando um processo não consegue saturar sua rede.

Solução de problemas

SintomaCorrigir
401 ou erro de autenticaçãoExecute hf auth login com um token Write e verifique com hf auth whoami.
Mais lento do que o esperadoColoque HF_HOME em NVMe, defina HF_XET_HIGH_PERFORMANCE=1 e execute perto dos seus dados.
A execução é interrompida com um erro de disco cheioO cache de shards preencheu o disco. Defina HF_XET_SHARD_CACHE_SIZE_LIMIT abaixo do seu espaço livre ou mova HF_HOME para um disco maior.
Transferência interrompidaExecute novamente o mesmo comando hf sync. Os arquivos já enviados são ignorados.

De AWS S3 ou armazenamento compatível com S3

hf sync não lê URLs s3://, então monte o bucket de origem como um sistema de arquivos com Mountpoint for Amazon S3 e, em seguida, sincronize a partir do mount. Seus dados ainda passam pelo cliente Xet, então você obtém deduplicação no lado do cliente.

mount-s3 my-source-bucket /mnt/src
hf sync /mnt/src hf://buckets/<namespace>/<bucket>
umount /mnt/src

Para stores compatíveis com S3, como Cloudflare R2 ou MinIO, adicione --endpoint-url <url> ao mount-s3. Para um bucket público que permite leituras anônimas, como aqueles no registro AWS Open Data, adicione --no-sign-request. A verificação, o ajuste fino e a solução de problemas são os mesmos que para dados locais.

Alternativa: rclone através do gateway S3

Use isso se você já executa rclone e prefere não montar. A desvantagem: o rclone envia cada byte através do gateway S3 sem deduplicação no lado do cliente, então transfere mais do que hf sync. Você precisa de credenciais S3 para o gateway.

Use o rclone 1.70 ou mais recente (verifique com rclone version, faça o upgrade a partir de rclone downloads). Versões mais antigas podem esgotar a memória ao listar buckets muito grandes. Conselhos antigos frequentemente recomendam --fast-list; com um rclone recente, você não precisa dele, e em um listagem enorme ele mantém tudo na memória e pode causar a mesma falha.

Adicione o gateway como um remoto em ~/.config/rclone/rclone.conf, ao lado do remoto da sua origem (aws abaixo):

[hf]
type = s3
provider = Other
endpoint = https://s3.hf.co/<namespace>
access_key_id = HFAK...
secret_access_key = ...
region = us-east-1
force_path_style = true
list_version = 2
upload_cutoff = 256M
chunk_size = 256M

O gateway suporta apenas ListObjectsV2, portanto list_version = 2 é obrigatório. Com 256M de partes, arquivos grandes são divididos em muito menos partes do que com o padrão de 5M do rclone. O rclone mantém 4 partes por transferência em memória, portanto --transfers 16 abaixo requer cerca de 16 GB de RAM; reduza esse valor em uma máquina menor. Em seguida, copie e verifique:

rclone copy aws:my-source-bucket hf:<bucket> --transfers 16 --checkers 16 --progress
rclone check aws:my-source-bucket hf:<bucket>

rclone copy transfere apenas objetos ausentes ou alterados, portanto é seguro reexecutar para retomar. Antes de uma importação grande, leia as limitações do gateway, especialmente as regras de nomenclatura das chaves de objeto.

Do Google Cloud Storage ou do Azure Blob Storage

Mesma abordagem que no S3: monte a origem com o driver próprio da nuvem e, em seguida, execute hf sync.

Google Cloud Storage: monte com gcsfuse.

gcsfuse my-gcs-bucket /mnt/src
hf sync /mnt/src hf://buckets/<namespace>/<bucket>

Azure Blob Storage: monte com blobfuse2. O arquivo de configuração nomeia sua conta de armazenamento e seu contêiner.

blobfuse2 mount /mnt/src --config-file=./blobfuse2.yaml
hf sync /mnt/src hf://buckets/<namespace>/<bucket>

Sem um mount, você pode usar o rclone (ele lê GCS e Azure nativamente; reutilize o remote hf acima, com o mesmo compromisso de não deduplicação), ou executar a migração como um Job.

Execute a migração em segundo plano com Jobs

Jobs executa um script na infraestrutura de computação do Hugging Face: você escolhe o hardware, inicia a execução pela CLI e paga por minuto. Use-o quando quiser que uma migração longa, de múltiplos TB, seja executada de forma autônoma, em vez de no seu laptop ou em uma sessão que você precisa manter aberta.

1. Escreva o script de migração (migrate.py). Este exemplo copia cada objeto em um prefixo do S3 para um bucket por meio do cliente Xet, de modo que as gravações sejam deduplicadas. Ele é adequado para uma cópia pontual de um prefixo de tamanho moderado; para prefixos muito grandes, consulte hf-s3ream. Adapte as configurações no topo:

# /// script
# dependencies = ["huggingface_hub", "boto3", "tqdm"]
# ///
import boto3
from botocore import UNSIGNED
from botocore.config import Config
from huggingface_hub import HfFileSystem
from tqdm.contrib.concurrent import thread_map

# --- adapt these ---
SRC_BUCKET = "my-source-bucket"
SRC_PREFIX = "some/prefix/"
DST = "buckets/<namespace>/<bucket>"
WORKERS = 8   # files copied in parallel
# -------------------

s3 = boto3.client("s3")   # AWS credentials come from the Job's secrets
# For a public bucket (for example from the AWS Open Data registry), read anonymously
# instead, and drop the AWS secrets from the launch command:
# s3 = boto3.client("s3", config=Config(signature_version=UNSIGNED))
fs = HfFileSystem()       # HF token comes from the Job's HF_TOKEN secret

# List the destination once: {path: size} of the files already copied
done = {path: info["size"] for path, info in fs.find(DST, detail=True).items()}

# List the source and keep the objects not copied yet
todo = []
pages = s3.get_paginator("list_objects_v2").paginate(Bucket=SRC_BUCKET, Prefix=SRC_PREFIX)
for page in pages:
    for obj in page.get("Contents", []):
        key = obj["Key"]
        if key.endswith("/"):
            continue  # folder marker: bucket keys can't end with "/"
        if done.get(f"{DST}/{key}") != obj["Size"]:
            todo.append(key)

def copy(key):
    body = s3.get_object(Bucket=SRC_BUCKET, Key=key)["Body"]
    with fs.open(f"{DST}/{key}", "wb") as out:
        for chunk in iter(lambda: body.read(64 << 20), b""):
            out.write(chunk)

# Copy WORKERS files at a time, with a progress bar
thread_map(copy, todo, max_workers=WORKERS)
  • Cada objeto é armazenado no disco do Job e enviado quando é fechado, portanto o disco deve comportar WORKERS dos seus maiores objetos ao mesmo tempo. Aumente WORKERS para acelerar o processamento de muitos objetos pequenos; diminua-o para objetos muito grandes.
  • Arquivos que já estão no bucket com o mesmo tamanho são ignorados, portanto, reexecutar o script retoma uma cópia interrompida. Ele não recopiará um arquivo de origem que foi alterado, mas manteve o mesmo tamanho: para manter um bucket sincronizado com uma origem em constante mudança, monte a origem e execute hf sync em vez disso.

Para GCS ou Azure, substitua boto3 pelo SDK da nuvem correspondente (google-cloud-storage, azure-storage-blob) e ajuste as chamadas de listagem e leitura. A metade de destino permanece a mesma.

2. Inicie-o como um Job em segundo plano, passando suas credenciais como segredos:

hf jobs uv run --detach --flavor cpu-performance --timeout 24h \
  --secrets HF_TOKEN \
  --secrets AWS_ACCESS_KEY_ID \
  --secrets AWS_SECRET_ACCESS_KEY \
  migrate.py

Cada --secrets NAME passa o valor dessa variável do seu ambiente (para HF_TOKEN, o seu token de login é usado se ele não estiver definido). Os Jobs param após 30 minutos por padrão, então defina --timeout com tempo suficiente para a transferência inteira; se um Job parar antes, inicie-o novamente e ele pulará os arquivos já copiados.

--detach retorna imediatamente com um ID de Job. Acompanhe o progresso com hf jobs logs -f <job_id>, liste as execuções com hf jobs ls e veja as opções de hardware com hf jobs hardware.

De um repositório do Hub ou de outro bucket

Se os dados já estiverem no Hub, em um repositório de modelo ou dataset ou em outro bucket, copie-os no lado do servidor. Para arquivos rastreados por Xet, apenas os hashes de conteúdo são movidos, portanto a cópia é quase instantânea e nada é reenviado.

# From a dataset repository into a bucket
hf buckets cp hf://datasets/<org>/<dataset>/<path> hf://buckets/<namespace>/<bucket>/<path>

# From one bucket to another
hf buckets cp hf://buckets/<namespace>/<bucket-a>/<path> hf://buckets/<namespace>/<bucket-b>/<path>
  • A origem e o destino devem estar na mesma região de armazenamento.
  • Você precisa de acesso de leitura à origem e acesso de escrita ao destino.
  • Arquivos pequenos que não são rastreados pelo Xet (configurações, READMEs) são baixados e reenviados automaticamente.
  • Copiar de um bucket de volta para um repositório ainda não está disponível; está no roadmap.

Veja Copiar arquivos entre repositórios e buckets para o equivalente em Python.

Prefixos S3 muito grandes com hf-s3ream

hf-s3ream é uma ferramenta comunitária em estágio inicial (alpha), não sendo um produto oficialmente suportado pela Hugging Face. Teste-o em um prefixo pequeno antes de usá-lo para uma migração de grande escala.

hf-s3ream (fonte no GitHub, Apache-2.0) executa uma cópia grande de S3 para bucket a partir de uma interface web:

  1. Faça login com o Hugging Face.
  2. Insira o prefixo de origem do S3, o bucket de destino e suas credenciais da AWS. Para um bucket público que permite leituras anônimas, ative Public bucket: não são necessárias credenciais da AWS e os Jobs leem o S3 sem assinatura.
  3. Analyze executa uma simulação de baixo custo que verifica o acesso, detecta a região de origem e recomenda uma configuração. Ele cria o bucket de destino (privado) caso ele não exista.
  4. Executar inicia um trabalho de planejador. O planejador cria um plano de cópia baseado em intervalos, inicia os trabalhos de cópia e exibe o progresso em um gráfico ao vivo. A cópia continua sendo executada se você fechar a aba, mas a página não se reconectará a ela. Para interromper uma cópia, clique em Interromper cópia ou cancele o trabalho do planejador (hf jobs cancel <planner-job-id>): o planejador cancela seus copiadores.

hf-s3ream é executado em Jobs sob sua conta, portanto, os Jobs são cobrados a você. Buckets S3 que permitem acesso apenas de uma rede privada (VPC) não podem ser acessados a partir de Jobs.

Onde executar uma migração de grande escala

Para uma migração de múltiplos TB, você geralmente executa a transferência em uma VM na nuvem, em vez de em um laptop. Se você preferir não gerenciar uma VM, execute como um Job.

  • Execute na mesma nuvem e região da sua origem. Ler a origem pela rede local é o mais rápido e barato, e a saída (egress) da nuvem de origem costuma ser o maior custo. Os uploads, então, passam pela internet até o Hugging Face (a região dos EUA está na AWS us-east-1).
  • Use um processo com muitas threads. Um único hf sync em modo de alto desempenho compartilha um único cache de deduplicação. Divida por subcaminho apenas quando um único processo não consegue saturar sua rede.
  • Mantenha execuções longas ativas. Por SSH, inicie a migração dentro de tmux (ou screen, ou nohup) para que ela sobreviva a uma sessão interrompida: tmux new -s migrate, desconecte com Ctrl-b e depois d, e reconecte mais tarde com tmux attach -t migrate.

Pontos de partida para dimensionamento, a serem validados em uma execução de teste:

RecursoOrientaçõesExemplo da AWSExemplo do GCP
DiscoNVMe local para HF_HOME, com espaço livre acima do limite do cache de shards. Evite discos conectados à rede para o cache.NVMe de loja de instâncias (variantes c7i/m7i d ou i4i)SSD local em uma VM n2 ou c3
CPUMuitos vCPUs: o cliente divide e calcula o hash dos dados na CPU.c7i.8xlarge ou maiorc3-standard-22 ou maior
MemóriaSuficiente para os buffers do modo de alto desempenho; pelo menos 64 GB com hf_xet antes da 1.7.0.——
RedeAlta largura de banda para a internet (classe de 25 Gbps).——

Próximas etapas

  • Use os dados no local. Monte o bucket como um sistema de arquivos local com hf-mount ou como um volume em Jobs e Spaces.
  • Leia a partir das suas ferramentas. pandas, Dask, PyArrow, Daft, DuckDB, 🤗 Datasets e Spark leem caminhos hf://buckets/... diretamente. Consulte Integrações de Bucket.

Não execute uma ingestão em massa por meio de um mount. O hf-mount faz o staging das gravações em um cache em disco (/tmp/hf-mount-cache por padrão) e uma migração grande por ele pode encher esse disco. Use um dos caminhos acima para colocar os dados em um bucket. Se você precisar gravar muito por meio de um mount, aponte o cache para um disco com bastante espaço livre: hf-mount start --cache-dir /mnt/big bucket <namespace>/<bucket> /mnt/data (a flag vem antes de bucket).

Update on GitHub