어떤 클라우드에서도 AI 워크로드를 실행하고 Hugging Face에 저장하세요: SkyPilot을 통한 제로 이그레스
요약
Hugging Face와 SkyPilot의 협업을 통해 어떤 클라우드 환경에서도 데이터 전송 비용(egress) 없이 AI 워크로드를 실행할 수 있는 기능을 출시했습니다. hf:// 스킴을 사용하여 Hugging Face의 모델과 데이터셋을 SkyPilot 작업에 직접 마운트하여 효율적인 학습 및 서빙이 가능합니다.
핵심 포인트
- Hugging Face Storage 이용 시 데이터 이그레스 비용 발생 안 함
- SkyPilot을 통해 20개 이상의 클라우드 및 온프레미스 GPU 활용 가능
- hf:// 스킴으로 모델, 데이터셋, 체크포인트의 전체 라이프사이클 관리
- Xet 기반 중복 제거 기술로 증분 체크포인트 및 모델 변체 효율적 저장
Hugging Face와 함께 우리는 두 가지 요소를 결합했습니다. 여러분의 모델과 데이터셋은 Hub에 머물고, SkyPilot은 GPU가 있는 어떤 클러스터에서든 컴퓨팅(개발, 학습 또는 서빙)을 실행합니다. 이미 보유하고 있는 hf:// URL과 HF_TOKEN을 사용하여 Hugging Face Bucket 또는 모든 Hub 리포지토리(repo)를 SkyPilot 작업에 마운트(mount)한 다음, 용량이 있는 곳 어디에서나 실행하세요. Hugging Face는 이그레스(egress, 데이터 전송 비용)를 부과하지 않으므로, 어떤 클라우드에서든 해당 GPU로 데이터를 읽어오는 데 비용이 들지 않습니다.
새로운 기능은 다음과 같습니다:
모든 작업에서 Hub 데이터 사용. store: hf를 사용하면 hf:// URL과 기존의 HF_TOKEN을 통해 Hugging Face Bucket(읽기-쓰기) 또는 모든 model / dataset / Space repo(읽기 전용)를 MOUNT 또는 COPY를 통해 SkyPilot 태스크(task)에 마운트할 수 있습니다.
어떤 클라우드의 어떤 GPU에서도 실행 가능. SkyPilot은 20개 이상의 클라우드, Kubernetes, Slurm 및 온프레미스(on-prem)에서 해당 작업의 컴퓨팅 자원을 찾아냅니다. 따라서 동일한 실행 환경에서 어떤 벤더의 예약 인스턴스(reserved) 또는 온디맨드(on-demand) GPU라도 사용 가능한 것을 활용할 수 있습니다.
데이터를 읽을 때 이그레스 비용 없음. Hugging Face Storage는 이그레스(egress)나 CDN 비용을 부과하지 않습니다. 따라서 SkyPilot이 작업을 어디에 배치하든, 클라우드별 복사본을 만들거나 데이터를 가져오기 위한 이그레스 비용을 지불할 필요 없이 동일한 버킷에서 모델과 데이터셋을 직접 읽어옵니다.
Xet 기반의 중복 제거 (dedup). 버킷은 Xet을 기반으로 구축되었으므로, 증분 체크포인트(incremental checkpoints)와 모델 변체(model variants)는 변경된 청크(chunks)만 저장하고 전송합니다.
함께 구축됨. Hugging Face와 SkyPilot은 이를 공동으로 출시했으며, Hugging Face 팀은 권한이 없는 컨테이너(unprivileged containers)에서도 작동할 수 있도록 하는 hf-mount FUSE 수정 사항을 업스트림(upstream)에 반영했습니다.
SkyPilot 태스크는 이미 클라우드 오브젝트 스토어(S3, GCS, Azure, R2 등 다수)를 로컬 경로에 마운트하여 읽고 쓰는 기능을 갖추고 있습니다. 이제 Hugging Face Storage가 store: hf로서 그 목록에 합류하며, hf:// 스킴(scheme)을 통해 접근할 수 있습니다:
file_mounts:
# 체크포인트, 로그, 처리된 데이터를 위한 읽기-쓰기 가능 Hugging Face Bucket.
/checkpoints:
...
그 하나의 hf://
그 하나의 hf:// 스킴(scheme)은 전체 라이프사이클을 아우릅니다: 리포지토리(repo)에서 **모델 (model)**과 **데이터셋 (dataset)**을 읽고, 학습하는 동안 버킷(Bucket)에 **체크포인트 (checkpoints)**를 쓰며, 완성된 모델을 다시 리포지토리에 게시하고, 서빙(serving) 시 추론 서버(inference server)로 가져옵니다. 대부분의 팀은 이미 Hub에 모델과 데이터셋을 보관하고 있으므로, 별도의 마이그레이션 단계나 새로운 스토리지 계정을 생성할 필요가 없습니다.
MOUNT는 Hugging Face의 hf-mount FUSE 백엔드(backend)를 사용하므로, 버킷이나 리포지토리가 SkyPilot의 다른 FUSE 마운트(gcsfuse, blobfuse2, rclone, goofys)와 함께 로컬 경로로 나타납니다. 데이터 가져오기는 파일 시스템 계층에서 발생합니다. 코드가 read()를 호출하면 드라이버가 Xet 백엔드에서 해당 바이트만 가져오므로, 실제로 사용하는 데이터만 네트워크를 통과하며, hf-mount는 디스크 캐시(on-disk cache)를 유지하여 반복적인 읽기가 로컬에서 수행되도록 합니다. 이 디스크 캐시는 SkyPilot이 다른 백엔드에 MOUNT_CACHED 옵션으로 제공하는 동작 방식이며, 일반적인 MOUNT는 로컬에 아무것도 남기지 않고 버킷에서 모든 읽기 작업을 스트리밍합니다. hf 스토어의 경우, MOUNT와 MOUNT_CACHED는 동일하게 동작하므로 두 모드 모두 캐시를 유지합니다.
읽기 작업이 지연(lazy) 방식으로 이루어지기 때문에, 프로세스는 전체 파일이 다운로드될 때까지 차단(blocking)되어 기다리는 대신, 파일 전체를 복사하기 전에 대용량 파일을 처리하기 시작할 수 있습니다. 이를 통해 GPU가 데이터셋이나 체크포인트가 복사되는 동안 유휴 상태(및 과금)로 머물지 않고, 데이터가 스트리밍되는 대로 즉시 학습을 시작하여 거의 즉각적으로 가동될 수 있습니다. 이는 아직 아무것도 캐싱되지 않은 첫 번째 에포크(epoch)에서 가장 큰 효과를 발휘합니다. COPY는 다른 경로를 택하며, 특별한 요구 사항 없이 huggingface_hub를 통해 사전에 다운로드합니다.
인증은 이미 보유하고 있는 토큰을 사용합니다. 환경 변수에 HF_TOKEN을 설정하고 --secret HF_TOKEN으로 실행에 전달하세요. SkyPilot은 작업이 배치되는 클라우드에 상관없이 마운트를 위해 이 토큰을 사용합니다. 작업이 AWS, GCP, Azure, Nebius, Lambda 또는 자체 Kubernetes 클러스터에 배치되든 상관없이 하나의 토큰으로 작동하므로, 클라우드별로 버킷 키(bucket keys)를 관리할 필요가 없습니다.
GPU 용량(capacity)은 더 이상 한 곳에서만 제공되지 않습니다. 충분한 H100 및 H200을 확보하기 위해, 팀들은 여러 벤더에 걸쳐 예약 및 확약된 용량(reserved and committed capacity)을 동시에 보유하며(하이퍼스케일러의 블록, 네오클라우드(neocloud)의 클러스터, 또는 온프레미스(on-prem) 랙 등), 할당된 곳이 어디든 그곳에서 작업을 실행합니다. SkyPilot은 바로 이를 위해 구축되었습니다. 하나의 작업 사양(job spec)으로 20개 이상의 클라우드, Kubernetes, 그리고 온프레미스에 걸쳐 스케줄링하며, 예약된 클러스터 중 비어 있는 곳에 작업을 배치합니다.
그동안 걸림돌은 오브젝트 스토리지(Object storage)였습니다. 오브젝트 스토리지는 지역(regional) 단위이며 클라우드별로 존재하기 때문에, 다른 벤더의 데이터 센터에 위치한 GPU나 추론 서버(inference server)에 데이터를 공급하려면 모든 벤더의 버킷(bucket)에 데이터 복사본을 유지하거나, 데이터를 가져오는 비용을 지불해야 합니다. 대부분의 클라우드는 데이터가 네트워크를 벗어나는 순간 이그레스(egress, 데이터 송신) 비용을 부과하며(AWS의 경우 GB당 약 $0.09), 동일 클라우드 내의 리전(region) 간 이동 시에도 비용이 발생하는 경우가 많습니다. 모든 추론 노드(inference node)로 베이스 모델(base model)을 가져오거나, 다른 클라우드의 클러스터에서 여러 에포크(epoch) 동안 데이터셋을 반복 학습하는 과정은 이미 예약한 GPU 비용 외에 막대한 추가 비용을 발생시킵니다. 결국 팀들은 데이터를 보유하고 있는 특정 벤더에 각 실행 작업을 고정(pinning)하게 되고, 나머지 용량은 유휴 상태로 남겨두게 됩니다.
Hugging Face Storage는 비용 부담이 가장 큰 부분인 읽기(read) 측면의 비용을 제거합니다. 이그레스(egress)나 CDN 비용이 없고 스토리지 비용이 TB당 월 $12-18 수준(이그레스 비용을 제외한 AWS S3의 약 $23/TB 대비)이므로, 동일한 버킷에 모든 클러스터가 접근할 수 있으며 GPU가 어디에서 실행되든 읽기 비용은 무료입니다. 다시 쓰는(Writing back) 작업은 여전히 기존 컴퓨팅 클라우드의 일반적인 이그레스 비용이 발생하며, 이는 클라우드 외부의 다른 스토리지에 쓰는 것과 동일합니다. 하지만 대부분의 AI 작업에서는 읽기 작업이 지배적입니다. 여러 에포크 동안 스트리밍되는 데이터셋이나, 모든 새로운 학습 또는 추론 노드로 가져오는 모델 가중치(model weights)가 그 예입니다. 따라서 이제 데이터를 복사해 둔 특정 벤더에 실행 작업을 고정할 필요가 없습니다.
벤치마크 수치를 수집하기 위해, 우리는 다음과 같이 작은 파인튜닝(fine-tune)을 수행했습니다: Qwen/Qwen3.5-4B 모델을 HuggingFaceH4/Multilingual-Thinking 데이터셋을 사용하여 TRL의 SFTTrainer로 학습했습니다.
, 모델을 Hub 저장소로부터 읽기 전용(read-only)으로 마운트하고, 모든 체크포인트(checkpoint)를 Hugging Face Bucket에 기록했습니다. 동일한 SkyPilot YAML 파일이 --infra 옵션만 변경하여 AWS, GCP, Lambda에서 실행되었습니다. SkyPilot은 GPU가 사용 가능한 곳 어디든 각 작업을 배치했으며, 세 클라우드 모두 동일한 버킷을 읽고 썼습니다.
# qwen-sft.yaml. 어디서나 실행 가능: sky launch qwen-sft.yaml --infra aws|gcp|...
resources:
accelerators: H100:1 # 또는 해당 클라우드에서 제공하는 사양
...
측정 결과:
모든 클라우드에서 모델을 무료로 로드했습니다. Lazy read 방식은 from_pretrained가 접근하는 부분만 가져오므로, 약 30초 만에 학습 준비가 완료되었습니다(최대 ~500 MB/s). Hugging Face는 이그레스(egress) 비용을 부과하지 않으므로, 이 데이터 인출(pull) 비용은 0원이었습니다. 만약 모델이 S3에 있었다면, 다른 클라우드의 GPU로 읽어올 때마다 이그레스 비용(AWS 기준 GB당 약 $0.09)이 청구되었을 것입니다. 체크포인트는 최대 ~170 MB/s 속도로 버킷에 직접 스트리밍되었으며(각 가중치 파일당 8.43 GB), GPU 인스턴스가 종료된 후에도 데이터가 유지되었습니다.
클라우드별 체크포인트 버킷 쓰기 속도:
| 클라우드 | GPU | 체크포인트 쓰기 속도 |
|---|---|---|
| AWS (us-east-2) | L40S | ~168 MB/s |
| ... |
Hugging Face Buckets는 Xet을 기반으로 구축되었습니다. Xet은 콘텐츠 정의 청킹(content-defined chunking)을 사용하여 파일을 약 64 KB 크기의 청크(chunk)로 분할하고, 각 고유한 청크를 한 번만 저장합니다. 경계가 콘텐츠를 따르기 때문에, 편집이 발생하면 해당 편집이 영향을 미치는 청크만 변경되며 나머지는 이미 저장된 것으로 인식됩니다. 이는 다음과 같은 몇 가지 측면에서 이점을 제공합니다:
점진적 및 어댑터 체크포인트 (Incremental and adapter checkpoints). 레이어를 동결(freeze)하거나, 어댑터(adapter)를 학습시키거나, 저장 사이에 대부분의 가중치(weights)를 건드리지 않은 상태로 두면, 전체 체크포인트 대신 변경된 청크(chunk)만 업로드됩니다.
베이스를 공유하는 모델 변형 (Model variants that share a base). 하나의 베이스 모델에 대한 미세 조정(fine-tunes) 및 양자화(quantizations) 모델들은 서로 크게 중첩되므로, 공유된 청크는 모든 모델에 걸쳐 한 번만 저장됩니다.
추가되는 데이터셋 (Datasets you append to). 대화 기록(conversation traces)이나 추론 출력(inference outputs)과 같은 로그는 대규모 Parquet 파일에 행(row)을 추가함으로써 늘어납니다. 기존의 로우 그룹(row groups)은 바이트 단위로 동일하게 유지되므로, 새로운 행만 전송됩니다. Hugging Face의 테스트에 따르면, 10만 행 규모의 테이블에 1만 행을 추가할 때 전체 약 106 MB 대신 약 10 MB만 이동했습니다. (만약 기존 행을 직접 수정하거나 삭제하는 경우에는, 변경 사항을 로컬로 유지하기 위해 use_content_defined_chunking=True 옵션을 사용하여 작성하십시오.)
이미 저장된 항목은 재업로드 생략 (Re-uploads skip what's already stored). 우리의 테스트에서, 버킷에 이미 존재하는 8.43 GB 크기의 블롭(blob)을 재업로드하는 데는 약 8초가 소요되었으며, 이는 첫 업로드 시 소요된 24초와 대조적입니다. 이는 청크 해시(chunk hashes)만 이동하기 때문입니다. 동일한 메커니즘을 통해 서버 측의 hf buckets cp 명령은 리포지토리(repo)와 버킷 간에 바이트를 재업로드하는 대신 참조(reference) 방식으로 복사할 수 있습니다.
얼마나 절약할 수 있는지는 아티팩트(artifacts)가 얼마나 중첩되는지에 따라 다르지만, 중복 제거(deduplication)는 자동으로 이루어집니다. 평소처럼 체크포인트를 작성하면 새로운 청크만 머신을 떠나게 됩니다.
pip install "skypilot[huggingface]"
hf auth login # 또는: export HF_TOKEN=<your-token>
어떠한 SkyPilot 태스크에도 hf:// 마운트(mount)를 추가하고 실행하십시오. MOUNT에는 glibc 2.34 이상과 /dev/fuse가 포함된 베이스 이미지(base image)가 필요합니다.
초기 store: hf 지원은 Nikhil Jha의 기여로 시작되었습니다. Hugging Face 팀은 이를 발전시켜 많은 Kubernetes 클러스터의 기본 설정인 권한이 없는 컨테이너(unprivileged containers)에서도 마운트할 수 있도록 hf-mount FUSE 수정 사항을 반영하고 업스트림(upstream)했습니다. SkyPilot 팀은 이를 스토리지 백엔드(storage backend)에 연결했습니다. 전체 경로는 오픈 소스입니다: SkyPilot, Hugging Face의 hf-mount, 그리고 huggingface_hub 클라이언트가 이에 해당합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 HuggingFace Blog의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기