Streaming datasets: 100x More Efficient
Quick Summary
허깅페이스는 데이터 파일 목록의 공유 캐시, 요청 최적화, Parquet 사전 가져오기와 버퍼 조정을 통해 대규모 데이터셋 스트리밍의 시작 요청을 최대 100분의 1로 줄이고 처리량을 최대 2배로 높였다.
🖼️ 인포그래픽
🖼️ 4컷 인포그래픽
💡 한 줄 요약
허깅페이스는 데이터 파일 목록의 공유 캐시, 요청 최적화, Parquet 사전 가져오기와 버퍼 조정을 통해 대규모 데이터셋 스트리밍의 시작 요청을 최대 100분의 1로 줄이고 처리량을 최대 2배로 높였다.
📌 핵심 요약
- 개선된 스트리밍은 여러 테라바이트 규모의 데이터셋을 미리 내려받거나 로컬 디스크에 모두 저장하지 않고도 load_dataset 함수의 streaming=True 설정만으로 즉시 사용할 수 있게 한다.
- 대규모 학습에서는 각 DataLoader 작업자가 데이터셋을 독립적으로 초기화하면서 중복 요청이 폭증했으며, nanoVLM 시험 실행에서는 1분도 안 되어 10만 건 이상의 요청이 발생해 허브에서 IP가 차단되기도 했다.
- 첫 작업자가 확인한 데이터 파일 목록을 로컬 영구 캐시에 저장해 다른 작업자가 공유하고, 최초 목록 조회에 필요한 API 호출까지 묶어 최적화함으로써 파일 해석 시간을 10배 단축하고 시작 요청을 최대 100배 줄였다.
- Parquet 데이터의 다음 청크를 백그라운드에서 미리 가져오고 블록 크기와 사전 가져오기 양을 조절할 수 있게 하여 스트리밍 속도를 최대 2배, 진행 중 요청 효율을 최대 2배 개선했다.
- 이 개선은 기존 API와 호환되며 datasets와 huggingface_hub를 업데이트하는 것만으로 적용할 수 있고, nanoVLM에서는 스트리밍 성능이 클러스터의 계층형 디스크 구성을 넘어 로컬 SSD 읽기와 비슷한 수준에 도달했다.
🧩 주요 포인트
- 개선된 스트리밍은 여러 테라바이트 규모의 데이터셋을 미리 내려받거나 로컬 디스크에 모두 저장하지 않고도 load_dataset 함수의 streaming=True 설정만으로 즉시 사용할 수 있게 한다.
- 대규모 학습에서는 각 DataLoader 작업자가 데이터셋을 독립적으로 초기화하면서 중복 요청이 폭증했으며, nanoVLM 시험 실행에서는 1분도 안 되어 10만 건 이상의 요청이 발생해 허브에서 IP가 차단되기도 했다.
- 첫 작업자가 확인한 데이터 파일 목록을 로컬 영구 캐시에 저장해 다른 작업자가 공유하고, 최초 목록 조회에 필요한 API 호출까지 묶어 최적화함으로써 파일 해석 시간을 10배 단축하고 시작 요청을 최대 100배 줄였다.
- Parquet 데이터의 다음 청크를 백그라운드에서 미리 가져오고 블록 크기와 사전 가져오기 양을 조절할 수 있게 하여 스트리밍 속도를 최대 2배, 진행 중 요청 효율을 최대 2배 개선했다.
- 이 개선은 기존 API와 호환되며 datasets와 huggingface_hub를 업데이트하는 것만으로 적용할 수 있고, nanoVLM에서는 스트리밍 성능이 클러스터의 계층형 디스크 구성을 넘어 로컬 SSD 읽기와 비슷한 수준에 도달했다.
🧠 상세 정리
1. 대용량 데이터 학습에서 발생한 병목
머신러닝 학습에서 여러 테라바이트 규모의 데이터를 준비하는 일은 실행 자체보다 앞선 큰 병목이었다. SmolLM3 학습 과정에서는 매번 충분한 데이터를 내려받는 데 약 3시간을 기다려야 했고, 로컬 저장 공간 부족과 복잡한 데이터 배치 절차도 함께 감수해야 했다. datasets 라이브러리는 이전부터 스트리밍 기능을 제공했지만, 이는 데이터셋을 빠르게 살펴보는 용도에는 유용해도 대규모 모델 학습에서는 충분히 안정적이고 효율적이지 않았다. 실제 학습에서는 데이터를 로컬에 내려받거나 별도의 원격 저장소에 복사한 뒤 그곳에서 스트리밍하는 방식이 일반적이었으며, 글은 이러한 사전 다운로드와 저장소 관리 없이 허브에서 곧바로 학습할 수 있도록 백엔드를 개선한 과정을 설명한다.
2. 기존 사용법을 유지한 호환성
성능 개선에도 사용자 API는 바뀌지 않아 기존 코드에서 load_dataset을 호출할 때 streaming=True를 지정하는 방식이 그대로 유지된다. 예를 들어 HuggingFaceM4/FineVisionMax의 train 분할을 스트리밍으로 열고 반복자에서 첫 항목을 가져오는 코드만으로 데이터 전체를 내려받지 않은 채 처리를 시작할 수 있다. 전 세계에서 datasets를 사용하는 개발자는 별도의 분산 저장 설정이나 새로운 스트리밍 프레임워크를 도입할 필요 없이 라이브러리 업데이트만으로 개선 효과를 얻도록 설계됐다. 즉 이번 변경의 핵심은 새로운 사용법을 요구하는 것이 아니라, 익숙한 한 줄짜리 설정 뒤에서 초기화 요청과 데이터 전송 방식을 효율화한 데 있다.
3. 다중 작업자 환경의 요청 폭증 문제
개발팀은 nanoVLM에서 허브의 데이터를 직접 스트리밍하던 중 시험 실행이 1분도 되지 않아 10만 건이 넘는 요청을 만들고, 그 결과 사용 중인 IP가 허브에서 차단되는 문제를 겪었다. 원인은 여러 DataLoader 작업자가 데이터셋을 각각 독립적으로 초기화하면서 동일한 데이터 파일 목록과 메타데이터를 반복해서 조회한 데 있었다. 작업자 수가 늘수록 실제 데이터 전송과 관계없는 중복 요청이 폭발적으로 증가해 429 응답, 시작 지연, 작업자 충돌로 이어질 수 있었다. 개선 결과 시작 단계의 요청은 최대 100분의 1로 감소했고, 데이터 파일 해석 시간은 10배 빨라졌으며, 256개 동시 작업자를 사용한 시험에서는 작업자 충돌이 발생하지 않았다고 제시한다.
4. 시작 단계의 공유 캐시와 조회 최적화
시작 단계의 첫 번째 개선은 데이터 파일 목록을 모든 DataLoader 작업자가 함께 이용할 수 있도록 로컬 영구 캐시에 보관하는 것이다. 최초 작업자만 허브에 접근해 파일 목록을 확인하고 캐시에 기록하며, 나머지 작업자는 같은 정보를 원격에서 다시 조회하지 않고 로컬 캐시에서 읽는다. 이 구조는 작업자마다 반복되던 목록 조회를 사실상 제거해 요청 폭증을 막고, 학습이 실제 샘플을 읽기 시작하기까지의 해석 시간을 크게 줄인다. 또한 최초 작업자에게 여전히 필요한 API 호출도 가능한 한 효율적으로 묶도록 조회 로직을 다듬어 왕복 횟수와 지연을 추가로 낮췄으며, 두 변경이 결합되어 시작 요청 최대 100배 절감과 파일 해석 10배 가속이라는 결과로 이어졌다.
5. Parquet 사전 가져오기와 버퍼 조정
실제 스트리밍 단계에서는 Parquet 데이터에 사전 가져오기를 적용해 모델이 현재 데이터 청크를 처리하는 동안 다음 청크를 백그라운드에서 받아오도록 했다. 계산과 네트워크 입력을 겹쳐 실행함으로써 데이터 파이프라인이 비는 시간을 줄이고, 가속기가 다음 샘플을 기다리는 상황을 방지하는 것이 목적이다. 고급 사용자는 PyArrow의 ParquetFragmentScanOptions와 CacheOptions를 전달해 버퍼 블록 크기와 사전 가져오기 양을 하드웨어 및 네트워크 환경에 맞게 조절할 수 있다. 글의 예시는 기본 32MiB였던 최소 요청 크기를 128MiB로 늘리고 prefetch_limit을 1로 지정하며, 이러한 스트리밍 개선을 통해 데이터 처리량을 최대 2배 높이고 진행 중인 요청의 효율도 최대 2배 개선할 수 있다고 설명한다.
6. Xet과 Parquet 중복 제거의 역할
허깅페이스 허브는 중복 제거 기반 저장 기술인 Xet을 사용해 동일한 데이터가 여러 번 포함돼 있어도 중복 부분을 한 번만 전송하도록 한다. 전통적인 원격 저장 방식과 달리 중복 데이터의 반복 업로드와 다운로드를 피할 수 있으므로, 대규모 데이터셋을 허브에 올리는 과정과 이후 전송 과정이 빨라진다는 설명이다. Parquet 데이터에는 내용에 따라 청크 경계를 정하는 Parquet Content Defined Chunking이 적용되어 Xet의 중복 제거가 효율적으로 작동하며, 업로드가 끝난 데이터셋은 곧바로 스트리밍할 수 있다. 또한 Spark에서 허깅페이스 데이터셋을 읽고 쓰는 pyspark_huggingface 패키지도 Parquet CDC와 Xet을 지원해 대규모 데이터 전송을 가속한다.
7. 사용자 정의 스트리밍을 위한 HfFileSystem
datasets가 직접 지원하지 않는 파일 형식을 다루거나 읽기 과정을 세밀하게 제어해야 하는 경우에는 huggingface_hub의 HfFileSystem으로 사용자 정의 스트리밍 파이프라인을 만들 수 있다. hf://datasets 형식의 경로를 열면 read 또는 readline으로 순차적으로 데이터를 읽을 수 있고, seek를 사용하면 원격 파일의 임의 위치에도 접근할 수 있다. 이 방식은 LeRobot에서 비디오 프레임을 표본 추출하고 WebDataset에서 TAR 아카이브를 스트리밍하는 과정으로 실제 검증됐다. HfFileSystem 객체를 torch DataLoader에 전달하면 ls와 glob 호출 결과가 캐시되어 데이터 파일을 나열할 때 추가 요청을 반복하지 않으므로, 기본 datasets API 밖에서도 동일한 요청 절감 원칙을 활용할 수 있다.
8. 대규모 검증 결과와 적용 방법
개발팀은 개선된 스트리밍을 nanoVLM에 적용해 차세대 SmolVLM 학습에 사용했으며, 64개의 H100과 데이터를 내려받는 256개 작업자 환경에서도 높은 성능과 안정성을 확인했다고 밝혔다. 해당 환경에서 스트리밍은 클러스터의 계층형 하드디스크 구성으로 학습할 때보다 빠르게 동작했고, 로컬 SSD에서 데이터를 읽는 것과 비슷한 속도에 도달해 이전의 약 3시간짜리 SSD 전송 대기를 제거했다. 기능은 datasets와 huggingface_hub 라이브러리에 포함됐으므로 두 패키지를 최신 버전으로 업데이트하면 기존 streaming=True 코드에서 바로 이용할 수 있다. 함께 공개된 FineVisionMax는 FineVision의 여러 데이터 소스를 미리 연결하고 섞어 만든 단일 데이터셋으로, 사용자가 여러 시각·언어 데이터셋을 직접 조합하지 않고도 같은 스트리밍 방식으로 VLM 학습을 시작할 수 있게 한다.
🧾 핵심 주장 / 시사점
- 이번 성능 향상의 핵심은 데이터 압축 자체보다 다중 작업자가 동일한 파일 목록을 반복 조회하던 제어 단계의 중복을 제거한 것으로, 첫 작업자의 조회 결과를 공유하는 방식이 시작 요청과 해석 시간을 동시에 줄였다.
- 처리량 개선은 Parquet 청크를 더 크게 요청하는 것만이 아니라 현재 청크의 계산과 다음 청크의 다운로드를 겹쳐 수행하는 사전 가져오기에서 나오며, 사용자는 네트워크와 하드웨어에 맞춰 요청 크기와 사전 가져오기 양을 조절할 수 있다.
- 기본 datasets API와 사용자 정의 HfFileSystem 경로 모두에서 목록 조회 결과를 재사용하도록 개선되어, 지원되는 Parquet 데이터셋뿐 아니라 비디오 프레임이나 TAR 아카이브 같은 별도 스트리밍 파이프라인에도 요청 절감 방식을 적용할 수 있다.
✅ 액션 아이템
- 대규모 학습에서 DataLoader 작업자별 초기 목록 조회 중복을 없애기 위해 파일 목록 공유 캐시의 사용 범위와 의존 조건을 정의한다.
- 스트리밍 개선 적용은 datasets와 huggingface_hub 버전 업데이트로 먼저 전환해 기존 API 호환성 하에서 동작 여부를 즉시 확인한다.
- Parquet 청크 사전 가져오기와 블록 크기·버퍼 조절 값을 조합해 처리량 2배 개선을 목표로 성능 재측정 기준을 잡는다.
❓ 열린 질문
- 초기 목록 공유 캐시가 실제 분산 학습 환경에서 1분 내 10만 건 요청 급증을 어느 수준까지 완화하는가?
- Parquet 사전 가져오기 양과 블록 크기 조합은 작업 부하별로 어떤 기준으로 최적 성능 점을 판단할 것인가?
- 업데이트가 어렵거나 제한된 환경에서 IP 차단 없이 streaming=True 성능 개선을 유지할 수 있는 대안이 무엇인가?