Hugging Face завершила первый этап перевода репозиториев моделей и датасетов с Git LFS на Xet. Новая система разбивает содержимое больших файлов на контентно-зависимые чанки размером примерно 64 КБ и повторно использует уже сохранённые фрагменты. При небольших изменениях это позволяет передавать в хранилище только новые части файла.
Для пользователей Hugging Face Hub главный эффект заметен при работе с крупными GGUF-моделями, Parquet-датасетами и SQLite-базами. Если файл размером в несколько гигабайт изменился лишь частично, Xet может избежать повторной загрузки всего объекта. В демонстрационном сценарии добавление 1 МБ в SQLite-базу размером 5 ГБ заняло около десятой доли секунды вместо 13 минут.
Xet не ускоряет любую операцию на Hub автоматически. Основная выгода появляется при повторной загрузке больших файлов, в которых значительная часть данных осталась прежней. Доступ к хранилищу пока оформляется через waitlist и требует пакета hf_xet.
Что такое Xet на Hugging Face Hub и в чём его отличие от Git LFS
Git LFS работает с большими файлами как с отдельными объектами. Когда файл меняется, система в типичном сценарии воспринимает новую версию как новый крупный объект. Для модели на десятки гигабайт или датасета на сотни гигабайт это означает повторную передачу значительного объёма данных, даже если изменения затронули небольшой участок.
Xet меняет уровень работы с данными. Клиент анализирует содержимое файла, разбивает его на фрагменты и сопоставляет их с уже сохранёнными чанками. Одинаковые фрагменты получают возможность повторного использования, а в хранилище отправляются только отсутствующие части.
Главная разница: дедупликация по содержимому, а не по имени и целому файлу
Классическая дедупликация на уровне файлов сравнивает объекты целиком. Если две версии отличаются хотя бы в одном месте, системе приходится обращаться с ними как с разными файлами. Xet использует content-defined chunking, то есть контентно-зависимое разбиение. Границы чанков определяются содержимым, поэтому вставка данных в одном месте не обязательно превращает весь последующий хвост файла в новый набор фрагментов.
Средний ориентир для размера чанка составляет около 64 КБ. Это не означает, что каждый фрагмент всегда имеет строго такой размер. Система подбирает границы так, чтобы устойчиво находить совпадающие части в разных версиях файла.
Чанки получают адреса на основе содержимого. Если фрагмент уже присутствует в хранилище, повторно передавать его не требуется. Такой подход снижает объём сетевого трафика и количество данных, которые приходится записывать при обновлении репозитория.
Почему это заметно именно в репозиториях моделей и датасетов
AI-репозитории редко ограничиваются маленькими конфигурационными файлами. Квантованная модель в формате GGUF может занимать десятки гигабайт. Parquet-датасеты растут за счёт новых строк, партиций и версий обработанных данных. SQLite-база способна хранить большой индекс или набор метаданных, который регулярно дополняется.
В таких сценариях автор часто публикует новую версию, хотя большая часть байтов осталась неизменной. Xet подходит именно для этого паттерна: файл большой, обновления происходят регулярно, а изменения занимают небольшую долю общего объёма.
Практические особенности работы с GGUF и требования к локальному запуску моделей разобраны в материале о сжатии большой модели в GGUF. Для Xet формат важен прежде всего как пример крупного бинарного артефакта, который может обновляться частями.
Как Xet загружает только изменённые части большого файла
Логика загрузки состоит из нескольких шагов. Клиент получает локальный файл, разбивает его на контентно-зависимые чанки и вычисляет идентификаторы этих фрагментов. Затем он проверяет, какие чанки уже доступны в системе хранения. Совпадающие части повторно не передаются, а новые отправляются в Hub.
После загрузки репозиторий по-прежнему должен представлять целостную версию файла. Для этого система хранит описание того, из каких чанков состоит объект и в каком порядке их нужно собрать при чтении.
Пример с SQLite: 1 МБ изменений вместо повторной загрузки 5 ГБ
Представим SQLite-базу размером 5 ГБ, в которую добавили 1 МБ данных. При файловой модели хранения новая версия может потребовать передачи всего объекта. Xet ищет совпадающие фрагменты, сохраняет новые чанки и использует старые для остальной части базы.
В приведённом сценарии загрузка изменения заняла около 0,1 секунды вместо 13 минут. Это показательный пример разницы между передачей целого файла и передачей небольшой дельты.
Цифру нельзя воспринимать как гарантию для любой базы или сети. На результат влияют размер изменения, расположение новых данных, скорость диска, задержка соединения и состояние сервиса. Аппенд обычно создаёт благоприятные условия для повторного использования существующих чанков.
Что происходит при обновлении GGUF и Parquet
Если в большой версии GGUF изменились отдельные области, Xet потенциально передаст только новые фрагменты. Это может быть полезно при публикации нескольких близких вариантов модели, исправлении части метаданных или пересборке, которая сохраняет большую долю исходного содержимого.
Для Parquet результат зависит от того, как именно создаётся новая версия. Добавление новых данных и изменение отдельных партиций обычно дают больше возможностей для повторного использования, чем полная пересортировка и пересборка всего набора.
При полном преобразовании файла совпадений может оказаться мало. Формат сам по себе не гарантирует высокий коэффициент дедупликации. Решающее значение имеет структура изменений.
Архитектура Xet: клиент, Hub, CAS, S3 и LFS Bridge
За загрузкой одного файла стоит несколько компонентов. Клиент Xet работает с локальными данными и чанками. Hugging Face Hub управляет репозиторием и связывает версию файла с набором фрагментов. CAS хранит данные по содержимому, S3 предоставляет объектный слой хранения, а LFS Bridge поддерживает совместимость с Git LFS.
CAS и S3: где хранятся чанки и почему они могут переиспользоваться
CAS, или content-addressable storage, адресует объект через его содержимое. Для Xet таким объектом может выступать отдельный чанк. Два одинаковых фрагмента получают один и тот же адрес, поэтому системе не требуется хранить две физические копии только из-за того, что они принадлежат разным версиям файла.
S3 выступает объектным хранилищем, где размещаются данные инфраструктуры. CAS отвечает за адресацию и повторное использование содержимого, а S3 предоставляет масштабируемый слой для хранения объектов. Такое разделение позволяет работать с большими объёмами данных без модели, в которой каждая версия файла обязательно хранится как полностью независимая копия.
Для пользователей это проявляется в двух местах: уменьшается объём повторной загрузки и меняется путь чтения данных. Система должна быстро найти нужные чанки, получить их из хранилища и собрать исходный файл без лишнего чтения.
Зачем нужен LFS Bridge
LFS Bridge связывает новую систему с привычной моделью Git LFS. Такой слой совместимости нужен, чтобы переход на Xet не требовал мгновенно переписывать все рабочие процессы, инструменты и репозитории.
Это не означает, что каждый старый клиент и любой сценарий будут работать полностью одинаково без ограничений. Совместимость снижает барьер перехода, но конкретный рабочий процесс всё равно нужно проверить, особенно если он зависит от особенностей Git LFS, автоматизации CI или собственного клиента.
Архитектурный переход Hugging Face Hub и изменения в библиотеке huggingface_hub подробнее разобраны в техническом разборе версии 1.0.
Что показала миграция 4,5 ТБ: Xet пришлось дорабатывать в процессе
Первый этап миграции охватил 4,5 ТБ данных. Такой объём позволил проверить Xet под нагрузкой, близкой к реальным условиям крупного каталога моделей и датасетов. Тестирование выявило два инфраструктурных узких места.
Блочный формат увеличивал чтение из CAS в четыре раза
Система хранения может экономить место и трафик, но при этом читать больше данных, чем требуется для конкретной операции. В Xet блочный формат в одном из сценариев приводил к четырёхкратному росту чтения из CAS.
Причина была связана с тем, что для работы с блоками не хватало метаданных о длине чанков. Без этой информации системе приходилось читать дополнительные данные, чтобы определить границы нужного фрагмента.
Проблему исправили добавлением сведений о длине чанков. Это позволило точнее определять необходимый диапазон и сократить лишнее чтение. Урок важен для любой системы дедупликации: эффективная запись не гарантирует эффективный доступ, если метаданные описывают структуру блоков недостаточно подробно.
Почему отсутствие fsync привело к перекосу нагрузки между подами
Второй сбой возник при записи временных файлов. Отсутствие fsync приводило к тому, что операции записи не всегда синхронизировались с диском в ожидаемый момент. Из-за этого поды получали неравномерную нагрузку.
Один под мог временно накапливать больше работы, тогда как другие использовались слабее. На уровне отдельного файла такая деталь выглядит низкоуровневой. В распределённом сервисе она влияет на баланс запросов, задержки и стабильность обработки больших загрузок.
Команда выявила проблему во время миграции и доработала инфраструктуру записи временных данных. Публичных гарантий, что все возможные узкие места уже исключены, из этих двух исправлений не следует. Зато сама история миграции показывает, почему масштабная проверка важнее красивой схемы на бумаге.
Кому Xet даст практическую выгоду, а кому пока можно не спешить
Xet ориентирован на повторяющиеся операции с большими артефактами. Если пользователь один раз загружает уникальный файл, чанковая дедупликация почти не с чем сравнивать его содержимое. При работе с небольшими репозиториями разница тоже может быть незаметной.
Сценарии, где чанковая дедупликация особенно уместна
- Публикация новых версий больших GGUF-файлов, когда сохраняется значительная часть исходных данных.
- Обновление Parquet-датасетов с добавлением новых строк, файлов или партиций.
- Дополнение SQLite-баз, индексов и других крупных файлов, где изменения добавляются к существующему содержимому.
- Повторная загрузка близких версий моделей и датасетов после исправления отдельных частей.
- Командные AI-пайплайны, где один и тот же крупный артефакт регулярно передаётся между окружениями.
Общий признак у этих сценариев один: файл большой, а новая версия сохраняет много данных из предыдущей. Чем выше доля совпадающих чанков, тем вероятнее экономия времени и трафика.
При работе с Parquet полезно учитывать и способ доступа к данным. В руководстве по DuckDB и Hugging Face Hub разобран сценарий SQL-анализа удалённых Parquet-файлов без полного локального скачивания. Xet решает другую задачу, он сокращает повторную передачу частей файла при его обновлении.
Ограничения Xet на текущем этапе
- Доступ к Xet пока связан с waitlist, поэтому функция доступна не каждому аккаунту сразу.
- Для работы требуется пакет
hf_xetв пользовательском окружении. - Выигрыш зависит от характера изменений. Полная пересборка файла может разрушить большую часть совпадений.
- Совместимость через LFS Bridge снижает риски перехода, но рабочие процессы с Git LFS всё равно нужно проверять отдельно.
- Миграция 4,5 ТБ уже выявила инфраструктурные проблемы, поэтому для production-сценариев нужны собственные проверки задержек, ошибок и пропускной способности.
Как получить доступ к Xet через waitlist и пакет hf_xet
Пользовательский маршрут состоит из двух шагов. Сначала нужно подать заявку в waitlist Xet и дождаться доступа для аккаунта. После этого в рабочем окружении используется пакет hf_xet, который обеспечивает работу с Xet-хранилищем.
Конкретные команды установки, версии пакета и параметры подключения могут меняться. Перед настройкой рабочего процесса проверьте актуальные требования в документации Hugging Face, доступной после получения соответствующего доступа. В этой статье не приводятся команды, которые могут устареть или не подойти конкретному окружению.
Что проверить перед переходом репозитория на Xet
- Определите размер файлов и частоту их обновления. Xet интереснее для крупных объектов, которые меняются регулярно.
- Оцените долю повторяющихся данных между версиями. Полная пересборка GGUF или Parquet может дать слабый эффект.
- Проверьте зависимость пайплайна от Git LFS, включая CI, скрипты скачивания и сторонние клиенты.
- Убедитесь, что аккаунту доступен Xet через waitlist, а окружение может использовать
hf_xet. - Сравните задержки и объём передаваемых данных на копии репозитория до перехода в production-процесс.
Для автора большой модели или датасета Xet выглядит полезным инструментом, когда новые версии сохраняют значительную часть прежнего содержимого. Для разовой публикации небольших файлов срочный переход не нужен. Сначала стоит сопоставить размер артефактов, частоту изменений и требования к совместимости, затем проверить работу на конкретном репозитории.