Hub documentation

Deduplicação

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Deduplicação

Repositórios habilitados para Xet utilizam divisão definida por conteúdo (CDC) para deduplicar no nível de bytes (~64KB de dados, também referidos como “chunk”). Cada chunk é identificado por um hash rolante que determina as fronteiras dos chunks com base no conteúdo real do arquivo, tornando-o resiliente a inserções ou exclusões em qualquer parte do arquivo. Quando um arquivo é enviado para um repositório baseado em Xet usando um cliente compatível com Xet, seu conteúdo é dividido nesses chunks de tamanho variável. Somente os novos chunks que ainda não estão presentes no armazenamento do Xet são mantidos após a divisão; todo o resto é descartado.

A deduplicação em nível de chunk também é o que torna cópias no lado do servidor instantâneas: hf buckets cp entre repositórios e buckets migra apenas hashes de conteúdo, sem reenvio de dados. Veja Copiando arquivos entre repositórios e buckets.

Como o Content-Defined Chunking Funciona

Para entender o chunking definido por conteúdo, imagine um arquivo como uma longa passagem de texto. O sistema varre os dados usando um hash rolante — uma pequena função matemática que desliza sobre os bytes. Sempre que o hash atinge um padrão especial, um limite de chunk é colocado naquela posição. Como os limites são determinados pelo próprio conteúdo (e não por posições fixas), regiões idênticas de dados sempre produzem os mesmos chunks, mesmo que o conteúdo ao redor mude.

Por que não usar blocos de tamanho fixo?

Considere o que acontece quando você insere uma pequena quantidade de dados no meio de um arquivo. Com a divisão em blocos de tamanho fixo, todos os limites de bloco após a inserção são deslocados, invalidando todos os blocos subsequentes — mesmo que a maior parte dos dados permaneça inalterada:

Original file, fixed 6-byte chunks:

  |The qu|ick br|own fo|x jump|s over| the l|azy do|g     |
  chunk1  chunk2 chunk3 chunk4 chunk5 chunk6 chunk7 chunk8

Insert "very " before "lazy":

  |The qu|ick br|own fo|x jump|s over| the v|ery la|zy dog|
  chunk1  chunk2 chunk3 chunk4 chunk5 chunk6 chunk7 chunk8
                                       ~~~~~~ ~~~~~~ ~~~~~~
                                        3 chunks changed!

Embora apenas 5 bytes tenham sido inseridos, 3 dos 8 blocos foram alterados porque todos os limites após a edição se deslocaram em 5 posições. Em arquivos reais com tamanho de bloco de 64KB, uma pequena edição pode invalidar centenas de megabytes de blocos.

O Chunking Definido por Conteúdo Mantém as Fronteiras Estáveis

Com o CDC, as fronteiras são definidas onde o conteúdo corresponde a um padrão — e não em intervalos fixos. Isso significa que uma inserção afeta apenas o bloco onde a edição ocorre. Os blocos antes e depois permanecem idênticos:

Original file, content-defined chunks (boundaries marked by "|"):

  |The quick |brown fox |jumps over |the lazy dog|
    chunk 1     chunk 2    chunk 3     chunk 4

Insert "very " before "lazy":

  |The quick |brown fox |jumps over |the very lazy dog|
    chunk 1     chunk 2    chunk 3     chunk 4'
    (same)      (same)     (same)      (changed)

Apenas 1 dos 4 blocos foi alterado — aquele que contém a edição. Os outros três são idênticos byte a byte e são deduplicados. É por isso que o CDC é tão eficaz para dados versionados: ao atualizar um checkpoint de modelo ou adicionar linhas a um conjunto de dados, apenas as porções modificadas precisam ser enviadas e armazenadas.

De Chunks para Armazenamento

O pipeline completo de deduplicação funciona da seguinte forma:

Quando um arquivo é dividido em blocos, o hash de cada bloco é verificado em relação ao que já está armazenado. Isso ocorre em vários níveis: primeiro, em relação aos blocos já vistos na sessão de upload atual; em seguida, em relação a um cache local de metadados de uploads anteriores; e, por fim, um subconjunto de blocos é verificado em relação a todo o armazenamento do Xet por meio de uma consulta global de deduplicação. Blocos duplicados são ignorados por completo. Os blocos novos são agrupados em blocos de 64 MB e enviados. Cada bloco é armazenado uma única vez em um armazenamento endereçado por conteúdo (CAS), indexado pelo seu hash.

Economia de Armazenamento na Prática

A recomendação atual do Hub é limitar os arquivos a 200 GB. Com um tamanho de bloco de 64KB, um arquivo de 20GB possui 312.500 blocos, muitos dos quais permanecem inalterados de uma versão para outra. O Git LFS foi projetado para perceber apenas que um arquivo foi alterado e armazenar a totalidade daquela revisão. Ao deduplicar no nível dos blocos, o backend Xet permite armazenar apenas o conteúdo modificado em um arquivo (que pode ser de apenas alguns KB ou MB) e deduplica com segurança blocos compartilhados entre repositórios. Para os grandes arquivos binários encontrados em repositórios de Model e Dataset, isso proporciona melhorias significativas nos tempos de transferência de arquivos.

Para mais detalhes, consulte os posts de blog De Arquivos para Chunks e De Chunks para Blocks, ou o paper Git is for Data de Low et al. que serviu como ponto de partida para o XetHub antes de ser adquirido pela Hugging Face.

Update on GitHub