Hub documentation

스토리지 버킷으로 데이터 마이그레이션

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

스토리지 버킷으로 데이터 마이그레이션

이 가이드는 현재 데이터셋이 어디에 있든(로컬 디스크, 다른 클라우드, 또는 Hub) Storage Bucket으로 대규모 데이터셋을 이동하는 방법을 보여줍니다. 아래 표에서 소스를 찾아 해당 섹션으로 이동하세요.

가능한 한 데이터를 파일 시스템으로 읽을 수 있도록 구성하고 hf sync를 실행하세요. 클라이언트에서 중복을 제거하므로, 원본을 그대로 복사하는 것보다 업로드하는 바이트 수가 줄어듭니다.

한눈에 보기

현재 데이터 위치권장대안
로컬 디스크 또는 클러스터 파일 시스템hf sync—
AWS S3 또는 S3 호환 (R2, MinIO)mount-s3로 마운트한 후 hf sync를 실행합니다S3 게이트웨이를 통한 rclone
Google Cloud Storagegcsfuse로 마운트한 후 hf sync 실행rclone 또는 Job
Azure Blob Storageblobfuse2로 마운트한 후 hf sync 실행rclone 또는 Job
Hub 저장소 또는 다른 버킷hf buckets cp (서버 사이드)—
매우 큰 S3 접두사hf-s3ream (알파)Mount + hf sync, 서브패스로 분할

hf sync가 기본값인 이유:

  • 업로드량이 줄어듭니다. hf sync는 Xet 클라이언트를 통해 업로드하며, 이 클라이언트는 데이터를 먼저 청크로 나누고 중복을 제거합니다. 따라서 Hub에서 아직 확인하지 않은 청크만 전송됩니다. 원본 복사(예: S3 게이트웨이를 통한 rclone)는 모든 바이트를 전송합니다.
  • 최소한 동일한 속도를 보장합니다. 지금까지 지원해 온 마이그레이션에서, 마운트된 소스를 통한 hf sync의 처리량은 rclone과 동등하거나 더 높았습니다.

시작하기 전에

이 가이드의 모든 명령은 Hugging Face CLI인 hf를 사용합니다. 도움말 출력이 에이전트가 읽을 수 있는 형식이라 코딩 에이전트가 마이그레이션을 구성하고 모니터링할 수 있습니다(자세한 내용은 CLI for AI Agents 참조). 대규모로 실행하기 전에 명령을 검토하세요.

  1. CLI를 설치합니다. Xet 클라이언트가 함께 제공됩니다.

    curl -LsSf https://hf.co/cli/install.sh | bash
    hf version
  2. 로그인하려면 Write 액세스 권한이 있는 토큰을 사용해야 합니다(토큰 생성):

    hf auth login
    hf auth whoami
  3. 대상 버킷을 생성합니다. <namespace>는 사용자 이름 또는 조직입니다. --region를 지정하지 않으면 버킷은 네임스페이스의 기본 스토리지 리전에 생성되며, Team & Enterprise 플랜을 제외한 모든 경우 미국입니다. 해당 플랜에서는 --region us 또는 --region eu를 전달하여 선택할 수 있습니다.

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

테스트 실행으로 시작하세요. 어떤 경로를 사용하든 작은 부분 집합(한 폴더 또는 --include 패턴)에서 먼저 연습하고, --dry-run 및 hf buckets ls로 결과를 확인한 후 전체 마이그레이션을 시작하세요. 이 가이드의 모든 경로는 재개할 수 있으므로 테스트 실행에는 아무 비용도 들지 않습니다.

로컬 디스크 또는 클러스터 파일시스템

데이터가 로컬 디스크, 연결된 볼륨, 또는 클러스터 스크래치에 있는 경우, 즉 머신이 파일로 읽을 수 있는 모든 환경에서 이 방법을 사용하세요. 아래에 나열된 모든 클라우드 경로에서도 소스가 마운트된 후 마지막 단계로 이 방법을 사용합니다.

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 클라이언트는 HF_HOME 아래에 청크와 중복 제거 인덱스(샤드 캐시)를 캐시합니다. 홈 디렉터리가 NVMe에 있지 않은 경우 HF_HOME을 로컬 NVMe로 지정하세요.
  • 리소스가 충분한 머신에서 대량 마이그레이션을 수행할 때 고성능 모드를 활성화하세요. HF_XET_HIGH_PERFORMANCE=1은 동시성, 버퍼 크기, 한 번에 가져오는 파일 수를 증가시켜 클라이언트가 모든 CPU 코어를 활용하고 네트워크를 포화 상태로 만들 수 있게 합니다. 이 모드는 대역폭이 높고 디스크 속도가 빠른 머신을 대상으로 하며, hf_xet 1.7.0 이전 버전에서는 최소 64 GB의 RAM(자신의 RAM은 hf env으로 확인할 수 있습니다)이 있는 환경에서만 사용해야 합니다. 환경 변수를 참조하세요.
  • 샤드 캐시 상한 설정. 크기 제한은 소프트입니다: 캐시는 실행 시작 시에만 정리되므로, 하나의 긴 실행 동안에는 제한을 크게 초과하여 성장할 수 있습니다. 대규모 마이그레이션, 특히 고성능 모드에서는 수백 GB까지 성장하여 디스크를 가득 채우고 실행을 중단시킬 수 있습니다. 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을 설정한 뒤, 데이터에 가까운 곳에서 실행하세요.
Run이 디스크가 가득 찼다는 오류로 중단됩니다Shard 캐시가 디스크를 가득 채웠습니다. 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

Cloudflare R2 또는 MinIO와 같은 S3 호환 스토어의 경우 mount-s3에 --endpoint-url <url>를 추가합니다. AWS Open Data registry와 같이 익명 읽기를 허용하는 공개 버킷의 경우 --no-sign-request를 추가합니다. 검증, 튜닝 및 문제 해결은 로컬 데이터와 동일합니다.

대안: S3 게이트웨이를 통한 rclone

이미 rclone을 실행 중이고 마운트를 원하지 않는다면 이 방법을 사용하세요. 단, rclone은 클라이언트 측 중복 제거 없이 모든 바이트를 S3 게이트웨이를 통해 전송하므로 hf sync보다 더 많은 데이터를 전송합니다. 게이트웨이를 위해 S3 자격 증명이 필요합니다.

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가 필요합니다. 256M 개의 파트를 사용하면 rclone의 기본값인 5M을 사용할 때보다 훨씬 적은 수의 파트로 큰 파일을 전송할 수 있습니다. rclone은 전송당 4개의 파트를 메모리에 유지하므로, 아래 --transfers 16의 경우 약 16 GB의 RAM이 필요합니다. 사양이 낮은 머신에서는 이 값을 낮추세요. 그런 다음 복사하고 확인하세요:

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>

Without a mount, you can use rclone (it reads GCS and Azure natively; reuse the hf remote above, with the same no-deduplication trade-off), or run the migration as a Job.

Jobs를 사용하여 백그라운드에서 마이그레이션을 실행합니다

Jobs는 Hugging Face 컴퓨트에서 스크립트를 실행합니다. 하드웨어를 선택하고 CLI에서 시작하며, 분당 과금 방식입니다. 노트북이나 계속 열어 두어야 하는 세션 대신, 장시간에 걸리는 수 TB 규모의 마이그레이션을 무인 상태로 실행하고 싶을 때 사용하세요.

1. 마이그레이션 스크립트 작성 (migrate.py). 이 예제는 Xet 클라이언트를 통해 S3 프리픽스의 각 객체를 버킷으로 복사하여 쓰기가 중복 제거됩니다. 중간 크기의 프리픽스를 일회성으로 복사하는 데 적합하며, 매우 큰 프리픽스의 경우 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)
  • 각 객체는 Job의 디스크에 스테이징된 후 닫힐 때 업로드되므로, 디스크에는 가장 큰 객체 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의 경우, 설정되지 않았다면 로그인한 토큰이 사용됩니다). Job은 기본적으로 30분 후 중단되므로, 전체 전송에 충분한 시간을 --timeout으로 설정하세요. Job이 중간에 중단되면 다시 시작하면 이미 복사된 파일은 건너뜁니다.

--detach를 사용하면 Job 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에 해당하는 내용은 리포지토리와 버킷 간 파일 복사를 참조하세요.

hf-s3ream을 사용한 매우 큰 S3 프리픽스

hf-s3ream은 초기 단계(알파)의 커뮤니티 도구이며, Hugging Face에서 공식적으로 지원하는 제품이 아닙니다. 대규모 마이그레이션에 사용하기 전에 작은 prefix로 테스트해 보세요.

hf-s3ream(GitHub 소스, Apache-2.0)는 웹 UI에서 대규모 S3-to-bucket 복사를 실행합니다:

  1. Hugging Face로 로그인하세요.
  2. S3 소스 접두사, 대상 버킷, AWS 자격 증명을 입력합니다. 익명 읽기를 허용하는 공개 버킷의 경우 Public bucket을 켜면 AWS 자격 증명이 필요하지 않으며, Jobs는 S3를 서명 없이 읽습니다.
  3. Analyze는 액세스를 확인하고 소스 리전을 감지하며 구성을 권장하는 저비용 드라이 러ンを 실행합니다. 대상 버킷(비공개)이 존재하지 않는 경우 생성합니다.
  4. Run을 클릭하면 플래너 작업이 시작됩니다. 플래너는 범위 기반 복사 계획을 수립하고, 복서 작업을 시작하며, 라이브 그래프에서 진행 상황을 표시합니다. 탭을 닫아도 복사는 계속 실행되지만, 페이지가 해당 작업에 다시 연결되지 않습니다. 복사를 중단하려면 Stop copy를 클릭하거나 플래너 작업을 취소(hf jobs cancel <planner-job-id>)하십시오. 플래너는 자신의 복서들을 취소합니다.

hf-s3ream은 사용자의 계정에서 Jobs로 실행되므로, Jobs 비용은 사용자에게 청구됩니다. 사설 네트워크(VPC)에서만 액세스를 허용하는 S3 버킷은 Jobs에서 접근할 수 없습니다.

대규모 마이그레이션을 실행할 위치

멀티 TB 마이그레이션의 경우, 노트북 대신 클라우드 VM에서 전송을 실행하는 것이 일반적입니다. VM을 직접 관리하고 싶지 않다면 Job으로 실행할 수 있습니다.

  • 소스와 동일한 클라우드 및 리전에서 실행하세요. 로컬 네트워크를 통해 소스를 읽는 것이 가장 빠르고 저렴하며, 소스 클라우드의 egress 비용이 일반적으로 가장 큰 비용 요인입니다. 업로드는 인터넷을 통해 Hugging Face로 전송됩니다(미국 리전은 AWS us-east-1에 위치합니다).
  • 프로세스 1개에 스레드 여러 개를 사용합니다. 고성능 모드에서 단일 hf sync는 중복 제거 캐시 1개를 공유합니다. 프로세스 1개로 네트워크를 포화 상태로 만들 수 없는 경우에만 서브패스로 분할합니다.
  • 긴 실행을 유지하세요. SSH를 통해 tmux(또는 screen, nohup) 안에서 마이그레이션을 시작하면 세션이 끊겨도 실행이 유지됩니다: tmux new -s migrate로 시작하고, Ctrl-b를 누른 뒤 d를 눌러 디태치한 다음, 나중에 tmux attach -t migrate로 다시 연결하세요.

테스트 실행을 통해 검증할 시작점 크기:

리소스가이드AWS 예제GCP 예시
디스크HF_HOME에 사용할 로컬 NVMe 디스크는 샤드 캐시 한도를 초과하는 여유 공간이 있어야 합니다. 캐시에 네트워크 연결 디스크는 사용하지 마세요.인스턴스 스토어 NVMe(c7i/m7i d 변형 또는 i4i)n2 또는 c3 VM의 로컬 SSD
CPU많은 vCPU: 클라이언트가 CPU에서 데이터를 청크로 나누고 해시합니다.c7i.8xlarge 이상c3-standard-22 이상
메모리고성능 모드 버퍼에 충분한 용량; 1.7.0 이전의 hf_xet의 경우 최소 64 GB.——
네트워크인터넷으로의 높은 대역폭(25 Gbps급).——

다음 단계

  • 데이터를 제자리에서 사용합니다. hf-mount를 사용하여 버킷을 로컬 파일시스템으로 마운트하거나, Jobs 및 Spaces에서 볼륨으로 마운트할 수 있습니다.
  • 도구에서 직접 읽으세요. pandas, Dask, PyArrow, Daft, DuckDB, 🤗 Datasets, Spark는 hf://buckets/... 경로를 직접 읽을 수 있습니다. Bucket Integrations를 참조하세요.

마운트를 통해 대량 데이터 인게스트를 실행하지 마세요. hf-mount는 디스크 캐시(/tmp/hf-mount-cache가 기본값)에 쓰기를 스테이징하며, 이를 통한 대규모 마이그레이션은 해당 디스크를 가득 채울 수 있습니다. 버킷에 데이터를 가져오려면 위의 경로 중 하나를 사용하세요. 마운트를 통해 대량으로 작성해야 한다면, 캐시를 충분한 여유 공간이 있는 디스크로 지정하세요: hf-mount start --cache-dir /mnt/big bucket <namespace>/<bucket> /mnt/data (플래그는 bucket 앞에 위치합니다).

Update on GitHub