Hub documentation

Перенос данных в хранилища

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Перенос данных в хранилища

В этом руководстве показано, как переместить большие наборы данных в Storage Bucket из того места, где они сейчас находятся: локальный диск, другое облако или Hub. Найдите свой источник в таблице ниже и перейдите к соответствующему разделу.

По возможности делайте данные доступными в виде файловой системы и запускайте hf sync. Он дедуплицирует данные на клиенте, поэтому вы загружаете меньше байтов, чем при обычном копировании.

Обзор

Где сейчас находятся ваши данныеРекомендуетсяАльтернативы
Локальный диск или файловая система кластераhf sync—
AWS S3 или совместимые с S3 (R2, MinIO)Смонтируйте с помощью mount-s3, затем выполните hf syncrclone через S3-шлюз
Google Cloud StorageСмонтируйте с помощью gcsfuse, затем выполните hf syncrclone или Job
Azure Blob StorageСмонтируйте с помощью blobfuse2, затем выполните hf syncrclone или Job
Репозиторий Hub или другое хранилищеhf buckets cp (на стороне сервера)—
Очень длинный префикс S3hf-s3ream (альфа)Mount + hf sync, разделение по подпутям

Почему hf sync используется по умолчанию:

  • Вы загружаете меньше. hf sync выполняет загрузку через клиент Xet, который предварительно разбивает данные на блоки и удаляет дубликаты, поэтому отправляются только те блоки, с которыми Hub ещё не работал. При прямой копии (например, с помощью rclone через S3-шлюз) передаётся каждый байт.
  • Скорость не ниже. Во всех миграциях, которые мы поддерживали до сих пор, hf sync через смонтированный источник демонстрировал пропускную способность не хуже, чем rclone.

Прежде чем начать

Все команды в этом руководстве используют hf, CLI Hugging Face. Его вывод справки предназначен для чтения агентами, поэтому кодинг-агент может собрать и отслеживать миграцию за вас (см. CLI для ИИ-агентов). Проверяйте команды перед их запуском в промышленных масштабах.

  1. Установите CLI. Клиент Xet поставляется вместе с ним.

    curl -LsSf https://hf.co/cli/install.sh | bash
    hf version
  2. Войдите с токеном, имеющим доступ Write (создайте его):

    hf auth login
    hf auth whoami
  3. Создайте целевое хранилище (bucket). <namespace> — это ваше имя пользователя или организации. Если не указать --region, хранилище будет создано в регионе хранения по умолчанию для данного пространства имён, который всегда находится в США, если не используется тариф Team & Enterprise. В этих тарифах можно выбрать регион, передав --region us или --region eu.

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

Начните с пробного запуска. Какой бы путь вы ни выбрали, отрепетируйте его на небольшом подмножестве (одна папка или шаблон --include), проверьте результат с помощью --dry-run и hf buckets ls, а затем запустите полную миграцию. Любой путь из этого руководства можно возобновить, поэтому пробный запуск ничего не стоит.

С локального диска или файловой системы кластера

Используйте этот вариант, если ваши данные находятся на локальном диске, подключённом томе или в каталоге scratch кластера: в любом месте, к которому машина может обращаться как к файлам. Это также последний шаг каждого из описанных ниже сценариев работы с облаком, после того как исходный ресурс смонтирован.

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

hf sync сравнивает исходный и целевой объекты и передаёт только различия, поэтому повторный запуск той же команды возобновляет прерванную миграцию: уже загруженные файлы пропускаются. Частые варианты:

# 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/*"

Чтобы просмотреть крупную миграцию перед её запуском, запишите план в файл, проверьте его, а затем примените. Это сканирует исходный и целевой объекты один раз, а не дважды — один раз для пробного запуска и ещё раз для реального.

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

Выполните --apply из той директории, где вы создали план, так как план сохраняет исходный путь в том виде, в каком вы его ввели. --apply не проверяет, что уже было загружено, поэтому для возобновления прерванного выполнения вместо этого повторите обычный hf sync.

Для проверки убедитесь, что в режиме предварительного запуска (dry run) не осталось данных для передачи, и проверьте содержимое выборочно:

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

Настройка

  • Храните кэш на быстром диске. Клиент Xet кэширует чанки и индекс дедупликации (shard cache) в каталоге HF_HOME. Если ваш домашний каталог не находится на NVMe, укажите HF_HOME на локальный NVMe-диск.
  • Включите режим высокой производительности для пакетных миграций на машине с достаточными ресурсами. HF_XET_HIGH_PERFORMANCE=1 увеличивает параллелизм, размеры буферов и количество файлов, обрабатываемых одновременно, что позволяет клиенту задействовать все ядра CPU и полностью загрузить сеть. Этот режим предназначен для машин с высокой пропускной способностью и быстрым диском; при использовании версий hf_xet ранее 1.7.0 включайте его только при наличии не менее 64 ГБ ОЗУ (проверить объём можно командой hf env). См. Переменные окружения.
  • Ограничьте кэш шардов. Его лимит размера является мягким: кэш очищается только в начале запуска, поэтому в течение одного длительного запуска он может значительно превысить лимит. При крупной миграции, особенно в режиме высокой производительности, он может вырасти до сотен ГБ и заполнить диск, что приведёт к прерыванию запуска. Установите HF_XET_SHARD_CACHE_SIZE_LIMIT с запасом ниже свободного места на диске, но не ниже необходимого: кэш размера X дедуплицирует данные объёмом примерно 1000 × X. См. Shard Cache.

Установите их перед началом синхронизации. Размеры принимают значения в человекочитаемом формате, например 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

Разделение по подпуту (экспериментально)

Для очень больших наборов данных можно разбить исходный путь на подпуть и запустить несколько процессов hf sync одновременно. Ранние тесты показывают, что пропускная способность масштабируется примерно линейно, но это требует дополнительной проверки. Два правила:

  • Разбивайте данные по связанным файлам, чтобы дедупликация на каждом воркере эффективно устраняла дубликаты между ними.
  • Назначьте каждому воркеру собственный HF_HOME, чтобы они не конкурировали за кэш. Каждый кэш занимает место на диске, поэтому распределите HF_XET_SHARD_CACHE_SIZE_LIMIT между воркерами.
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

Один процесс использует одно кэширование и лучше всего дедуплицирует данные, поэтому разделяйте потоки только в том случае, если один процесс не может полностью загрузить вашу сеть.

Устранение неполадок

СимптомИсправление
401 или ошибка аутентификацииВыполните hf auth login с токеном Write и проверьте его с помощью hf auth whoami.
Медленнее, чем ожидалосьРазместите HF_HOME на NVMe, установите HF_XET_HIGH_PERFORMANCE=1 и работайте вблизи данных.
Запуск прерывается с ошибкой переполнения дискаКэш шаров заполнил диск. Установите значение HF_XET_SHARD_CACHE_SIZE_LIMIT меньше, чем ваше свободное место, или переместите HF_HOME на более крупный диск.
Передача прерванаПовторно выполните ту же команду hf sync. Файлы, которые уже были загружены, пропускаются.

Из AWS S3 или хранилища, совместимого с S3

hf sync doesn’t read s3:// URLs, so mount the source bucket as a filesystem with Mountpoint for Amazon S3, then sync from the mount. Your data still goes through the Xet client, so you get client-side deduplication.

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

Для S3-совместимых хранилищ, таких как Cloudflare R2 или MinIO, добавьте --endpoint-url <url> к mount-s3. Для публичного бакета, допускающего анонимное чтение, например, из реестра AWS Open Data, добавьте --no-sign-request. Проверка, настройка и устранение неполадок аналогичны для локальных данных.

Альтернатива: rclone через S3-шлюз

Используйте этот вариант, если вы уже работаете с rclone и не хотите использовать монтирование. Компромисс: rclone передаёт каждый байт через S3 gateway без дедупликации на стороне клиента, поэтому объём передаваемых данных больше, чем у hf sync. Для работы с gateway вам потребуются S3 credentials.

Используйте rclone версии 1.70 или новее (проверьте с помощью rclone version, обновите с rclone downloads). В старых версиях может закончиться память при выводе списка очень больших бакетов. В старых рекомендациях часто советуют использовать --fast-list; в актуальных версиях rclone он не нужен, а при выводе огромного списка он удерживает все данные в памяти и может привести к тому же сбою.

Добавьте шлюз как удалённое хранилище в ~/.config/rclone/rclone.conf, рядом с удалённым хранилищем для вашего источника (aws ниже):

[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

Шлюз поддерживает только ListObjectsV2, поэтому требуется list_version = 2. При 256 млн частей крупные файлы разбиваются на значительно меньшее количество частей по сравнению с значением по умолчанию в rclone (5 млн). rclone удерживает в памяти 4 части на каждый процесс передачи, поэтому для --transfers 16 ниже потребуется около 16 ГБ ОЗУ; на машине с меньшим объёмом памяти уменьшите это значение. Затем выполните копирование и проверку:

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

rclone copy переносит только отсутствующие или изменённые объекты, поэтому повторный запуск безопасен для возобновления процесса. Перед крупным импортом ознакомьтесь с ограничениями шлюза, в частности с правилами именования ключей объектов.

Из Google Cloud Storage или Azure Blob Storage

Тот же подход, что и для S3: смонтируйте источник с помощью собственного драйвера облака, затем выполните hf sync.

Google Cloud Storage: монтирование с помощью gcsfuse.

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

Azure Blob Storage: монтирование с помощью blobfuse2. В файле конфигурации указываются имя вашего хранилища и контейнера.

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

Без монтирования можно использовать rclone (он нативно читает GCS и Azure; переиспользуйте удалённый ресурс hf выше, с тем же компромиссом в виде отсутствия дедупликации), либо выполнить миграцию как Job.

Запустите миграцию в фоновом режиме с помощью Jobs

Jobs выполняет скрипт на вычислительных мощностях Hugging Face: вы выбираете оборудование, запускаете его из CLI и платите за минуту. Используйте этот сервис, когда вам нужно, чтобы длительная миграция данных объёмом в несколько ТБ выполнялась автономно, а не на вашем ноутбуке или в сессии, которую необходимо держать открытой.

1. Напишите скрипт миграции (migrate.py). В этом примере каждый объект в префиксе S3 копируется в бакет через клиент Xet, благодаря чему записи дедуплицируются. Это подходит для разового копирования префикса среднего размера; для очень больших префиксов см. hf-s3ream. Настройте параметры в начале файла:

# /// 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)
  • Каждый объект размещается на диске задачи и загружается при его закрытии, поэтому диск должен одновременно вмещать WORKERS ваших самых крупных объектов. Увеличьте WORKERS, чтобы ускорить загрузку множества небольших объектов; уменьшите для очень крупных.
  • Файлы, уже находящиеся в хранилище и имеющие одинаковый размер, пропускаются, поэтому повторный запуск скрипта возобновляет прерванную копию. Скрипт не скопирует исходный файл, который изменился, но сохранил свой размер: чтобы хранилище оставалось в актуальном состоянии при изменении исходных данных, вместо этого подключите исходный ресурс и выполните hf sync.

Для GCS или Azure замените boto3 на SDK соответствующего облака (google-cloud-storage, azure-storage-blob) и скорректируйте вызовы для получения списка и чтения. Часть, отвечающая за назначение, остаётся без изменений.

2. Запустите его как фоновую задачу (Job), передав свои учётные данные в качестве секретов:

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

Каждый --secrets NAME передаёт значение этой переменной из вашего окружения (для HF_TOKEN используется токен вашего текущего сеанса, если переменная не задана). По умолчанию задачи останавливаются через 30 минут, поэтому установите --timeout с достаточным запасом на весь процесс передачи; если задача остановится раньше, запустите её снова — она пропустит файлы, которые уже были скопированы.

--detach сразу возвращает ID задачи. Следить за ходом выполнения можно с помощью hf jobs logs -f <job_id>, список запусков — с помощью hf jobs ls, а варианты аппаратного обеспечения — с помощью hf jobs hardware.

Из репозитория Hub или другого хранилища

Если данные уже находятся на Hub, в репозитории модели или датасета или в другом бакете, скопируйте их на стороне сервера. Для файлов, отслеживаемых Xet, перемещаются только хеши содержимого, поэтому копирование происходит практически мгновенно, и ничего не загружается повторно.

# 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>
  • Источник и назначение должны находиться в одном и том же регионе хранения.
  • Для работы вам нужен доступ на чтение к источнику и доступ на запись к месту назначения.
  • Небольшие файлы, не отслеживаемые Xet (конфигурации, README), загружаются и повторно выгружаются автоматически.
  • Копирование данных из хранилища обратно в репозиторий пока недоступно; эта функция запланирована в дорожной карте.

См. Копирование файлов между репозиториями и бакетами для эквивалента на Python.

Очень длинные префиксы S3 с hf-s3ream

hf-s3ream — это инструмент сообщества на ранней стадии (альфа), а не официально поддерживаемый продукт Hugging Face. Перед началом крупномасштабной миграции протестируйте его на небольшом префиксе.

hf-s3ream (исходный код на GitHub, Apache-2.0) выполняет копирование из S3 в bucket из веб-интерфейса:

  1. Войдите с Hugging Face.
  2. Укажите префикс источника S3, целевое хранилище (bucket) и ваши учётные данные AWS. Для публичного хранилища, допускающего анонимное чтение, включите Public bucket: учётные данные AWS не требуются, и Jobs читают S3 без подписи.
  3. Analyze выполняет быструю проверку «вхолостую»: проверяет доступ, определяет регион источника и рекомендует конфигурацию. Если целевое хранилище (bucket) не существует, оно будет создано (с приватным доступом).
  4. Запуск Run запускает задачу планировщика. Планировщик строит план копирования на основе диапазонов, запускает задачи копирования и отображает прогресс на живой диаграмме. Копирование продолжает выполняться, даже если вы закроете вкладку, но страница не сможет переподключиться к нему. Чтобы остановить копирование, нажмите Stop copy или отмените задачу планировщика (hf jobs cancel <planner-job-id>): планировщик отменит свои задачи копирования.

hf-s3ream работает на Jobs в рамках вашего аккаунта, поэтому за Jobs вы платите. С3-бакеты, доступ к которым разрешён только из частной сети (VPC), недоступны из Jobs.

Где выполнять крупную миграцию

Для миграции данных объёмом в несколько ТБ перенос обычно выполняется на облачной ВМ, а не на ноутбуке. Если вы не хотите управлять ВМ, запустите процесс как Job.

  • Запускайте в том же облаке и регионе, что и источник. Чтение источника по локальной сети — самый быстрый и дешёвый вариант, а исходящий трафик из облака источника обычно является самой крупной статьёй расходов. Загрузка данных затем идёт через интернет в Hugging Face (регион США — это AWS us-east-1).
  • Используйте один процесс с множеством потоков. Одна команда hf sync в режиме высокой производительности использует общий кэш дедупликации. Разбивайте по подпутям только в том случае, если один процесс не способен полностью загрузить вашу сеть.
  • Держите длинные процессы живыми. По SSH запускайте миграцию внутри tmux (или screen, или nohup), чтобы она переживала обрыв сессии: tmux new -s migrate, отсоединяйтесь с помощью Ctrl-b, затем d, и позже подключайтесь снова с помощью tmux attach -t migrate.

Точка отсчёта для определения размера, которую следует проверить на тестовом прогоне:

РесурсРуководствоПример для AWSПример для GCP
ДискЛокальный NVMe для HF_HOME с свободным местом, превышающим лимит кэша шардов. Избегайте использования сетевых дисков для кэша.NVMe в хранилище экземпляра (c7i/m7i d варианты, или i4i)Локальный SSD на ВМ n2 или c3
CPUМножество vCPU: клиент разбивает данные на блоки и вычисляет их хеши на CPU.c7i.8xlarge или более мощныйc3-standard-22 или более мощный
ПамятьДостаточно для буферов режима высокой производительности; не менее 64 ГБ с hf_xet до версии 1.7.0.——
СетьВысокая пропускная способность канала в интернет (класс 25 Гбит/с).——

Дальнейшие шаги

  • Используйте данные на месте. Подключите бакет как локальную файловую систему с помощью hf-mount или как том в Jobs и Spaces.
  • Читайте данные из ваших инструментов. pandas, Dask, PyArrow, Daft, DuckDB, 🤗 Datasets и Spark читают пути hf://buckets/... напрямую. См. Интеграции с бакетами.

Не выполняйте массовую загрузку данных через точку монтирования. hf-mount кэширует записи на диске (по умолчанию в /tmp/hf-mount-cache), и крупная миграция через него может заполнить этот диск. Используйте один из описанных выше способов, чтобы загрузить данные в бакет. Если вам необходимо выполнить много записей через точку монтирования, укажите для кэша диск с достаточным свободным местом: hf-mount start --cache-dir /mnt/big bucket <namespace>/<bucket> /mnt/data (флаг указывается перед bucket).

Update on GitHub