AI 런타임에서 데이터 로드

중요합니다

단일 노드 작업에 대한 AI 런타임은 공개 미리 보기로 제공됩니다. 다중 GPU 워크로드에 대한 분산 학습 API는 베타에 남아 있습니다.

기계 학습 및 딥 러닝 워크로드를 위한 AI 런타임에 학습 데이터를 로드합니다. 모든 데이터 액세스는 Unity 카탈로그를 통해 진행됩니다. Spark Connect를 사용하여 델타 테이블에서 테이블 형식 데이터를 읽고, 큰 데이터 세트와 이미지, 오디오 및 텍스트와 같은 구조화되지 않은 파일에 대한 Unity 카탈로그 볼륨을 읽습니다. 여러 에포크 학습의 경우 더 빠른 액세스를 위해 데이터를 /tmp에 로컬로 캐시하세요. Spark Python API를 사용하여 데이터를 로드하고 변환하는 방법을 알아보려면 자습서를 참조하세요.

메모

Unity 카탈로그가 필요합니다. AI 런타임의 모든 데이터 액세스는 Unity 카탈로그를 통해 진행됩니다. 테이블 및 볼륨은 Unity 카탈로그에 등록되어야 하며 사용자 또는 서비스 주체가 액세스할 수 있어야 합니다.

표 형식 데이터 로드

Spark Connect를 사용하여 델타 테이블에서 테이블 형식 기계 학습 데이터를 로드합니다.

단일 노드 학습의 경우 PySpark 메서드를 사용하여 Apache Spark DataFrames를 pandas DataFrames로 변환한 다음 필요에 따라 toPandas()to_numpy()를 사용하여 NumPy 형식으로 변환할 수 있습니다.

메모

Spark Connect는 분석 및 이름 확인을 실행 시간으로 연기하여 코드의 동작을 변경할 수 있습니다. Spark Connect와 Spark 클래식 비교를 참조하세요.

Spark Connect는 Spark SQL, Spark의 Pandas API, 구조적 스트리밍 및 MLlib(데이터 프레임 기반)를 비롯한 대부분의 PySpark API를 지원합니다. 지원되는 최신 API는 PySpark API 참조 설명서를 참조하세요.

다른 제한 사항은 서버리스 컴퓨팅 제한을 참조하세요.

볼륨을 활용하여 대규모 델타 테이블 로드

변환할 수 없는 큰 델타 테이블의 경우 데이터를 Unity 카탈로그 볼륨으로 toPandas()내보내고 PyTorch 또는 Hugging Face를 사용하여 직접 로드합니다.

# Step 1: Export the Delta table to Parquet files in a UC volume
output_path = "/Volumes/catalog/schema/my_volume/training_data"
spark.table("catalog.schema.my_table").write.mode("overwrite").parquet(output_path)
# Step 2: Load the exported data directly using Hugging Face datasets
from datasets import load_dataset

dataset = load_dataset("parquet", data_files="/Volumes/catalog/schema/my_volume/training_data/*.parquet")

이 방법은 학습 중에 Spark 오버헤드를 방지하고 단일 GPU 및 분산 학습 워크플로 모두에서 잘 작동합니다.

볼륨에서 UCVolumeDataset를 사용하여 구조화되지 않은 데이터 가져오기

Unity 카탈로그 볼륨에 저장된 이미지, 오디오 및 텍스트 파일과 같은 구조화되지 않은 데이터의 경우 패키지에서 UCVolumeDataset 사용합니다serverless_gpu.data. UCVolumeDataset 는 볼륨에서 첫 번째 액세스 시 빠른 로컬 캐시로 각 파일을 복사하고 캐시된 로컬 파일 경로를 생성하는 PyTorch IterableDataset 입니다. 그렇지 않으면 직접 처리해야 할 성능 및 배포 관련 문제를 처리합니다.

  • 로컬 캐싱. 파일은 FUSE 탑재에서 첫 번째 액세스 시 로컬 캐시 디렉터리로 복사되고 나중에 캐시에서 제공되므로 다중 Epoch 학습은 볼륨을 다시 읽지 않습니다.
  • 자동 분할. torch.distributed가 초기화되면 파일들은 rank 간에 분할되고, 이어서 DataLoader 작업자들에 걸쳐 추가로 분할되므로 각 (rank, worker) 쌍은 추가 설정 없이 서로 겹치지 않는 슬라이스를 할당받습니다.

메모

UCVolumeDatasetserverless_gpu.data.DataLoader에는 GPU 환경 5 이상이 필요합니다.

UCVolumeDataset 는 원시 로컬 파일 경로를 생성합니다. 이러한 파일을 텐서로 디코딩하려면 경로 스트림을 받아 파싱 로직을 적용하는 두 번째 IterableDataset로 감싸세요. 이렇게 하면 I/O 및 구문 분석 문제가 별도로 유지됩니다.

from serverless_gpu.data import UCVolumeDataset
from torch.utils.data import IterableDataset
from PIL import Image
import torchvision.transforms.functional as TF

class ImageDataset(IterableDataset):
    """Decodes each cached file path from UCVolumeDataset into a tensor."""

    def __init__(self, path_dataset: UCVolumeDataset):
        self._path_dataset = path_dataset

    def __iter__(self):
        for local_path in self._path_dataset:
            image = Image.open(local_path).convert("RGB")
            yield TF.to_tensor(image)

path_dataset = UCVolumeDataset("/Volumes/catalog/schema/my_volume/images")
dataset = ImageDataset(path_dataset)

래퍼는 이미 캐시된 로컬 경로를 전달받으므로, 파싱 단계에서는 FUSE 마운트에 전혀 접근하지 않습니다. 확대, 토큰화 또는 필터링을 위해 추가 래퍼를 연결할 수 있습니다.

최적의 성능을 위해 기본 PyTorch UCVolumeDataset 대신 serverless_gpu.data.DataLoaderDataLoader를 함께 사용하세요. 서버리스 GPU I/O용으로 조정되고 GPU가 컴퓨팅하는 동안 파일을 동시에 가져오고 캐시합니다. 데이터 로드 성능을 참조하세요.

데코레이터 내부에 @distributed 데이터 로드

분산 학습에 서버리스 GPU API 를 사용하는 경우 @distributed 데코레이터 내에서 데이터 로드 코드를 이동합니다. 데이터 세트 크기는 피클에서 허용하는 최대 크기를 초과할 수 있으므로 아래와 같이 데코레이터 내부에 데이터 세트를 생성하는 것이 좋습니다.

from serverless_gpu import distributed

# This may cause a pickle error if the dataset is too large
dataset = get_dataset(file_path)

@distributed(gpus=8, gpu_type='H100')
def run_train():
    # Load data inside the decorator to avoid pickle serialization issues
    dataset = get_dataset(file_path)
    ...

데코레이터 내부에서 UCVolumeDataset를 생성하면 반복 시 torch.distributed의 rank 정보를 읽어 rank별로 파일을 자동으로 분할하므로, 파일 기반 볼륨 데이터에는 DistributedSampler가 필요하지 않습니다.

데이터 로드 성능

/Workspace/Volumes 디렉터리 원격 Unity 카탈로그 스토리지에 호스트됩니다. 데이터 세트가 Unity 카탈로그에 저장되는 경우 데이터 로드 속도는 사용 가능한 네트워크 대역폭에 의해 제한됩니다. 여러 Epoch를 학습하는 경우 이 캐싱을 수행하는 방법을 사용하는 UCVolumeDataset 것이 좋습니다. 첫 번째 액세스 시 각 파일을 로컬 스토리지에 복사하고 로컬 복사본에서 후속 읽기를 제공합니다. 볼륨 내 데이터 세트의 경우, 학습에서 그중 일부만 사용하더라도 전체 트리를 미리 복사하는 수동 shutil.copytree보다 이를 사용하는 것이 좋습니다.

데이터 세트가 큰 경우 다음 기술을 통해 처리량을 향상시킬 수 있습니다.

  • 가져오기를 병렬화하려면 serverless_gpu.data.DataLoader를 사용하세요. 서버리스 GPU I/O에 대해 조정된 토치 DataLoader 의 드롭인 서브클래스입니다. 기본값은 num_workers 6과 prefetch_factor 4(PyTorch의 0과 2에 비해)이므로 GPU가 계산하는 동안 파일을 동시에 가져오고 캐시합니다. 또한 일괄 처리별 인출 타이밍을 활성 MLflow 실행에 기록하여 데이터 로드 병목 상태를 파악하는 데 도움이 됩니다.

    from serverless_gpu.data import DataLoader
    
    loader = DataLoader(
        dataset,
        batch_size=32,
        pin_memory=True,
        # num_workers=6, by default
        # prefetch_factor=4, by default
        # raise num_workers to increase parallel reads, or prefetch_factor to deepen each worker's queue.
    )
    

    모든 랭크는 동일한 num_workers 값을 사용해야 합니다. UCVolumeDatasetworld_size × num_workers개 슬롯 전체에 걸쳐 전역 보폭을 사용해 파일을 분할하기 때문입니다. 값이 일치하지 않는 경우 파일이 중복되거나 건너뜁게 됩니다.

  • 일괄 처리 크기를 늘입니다. 더 큰 일괄 처리는 더 많은 샘플보다 일괄 처리당 데이터 로드 오버헤드를 분할 상환하고 단계당 파일 인출 작업 수를 줄입니다. GPU 메모리가 제한 요소인 경우 더 큰 일괄 처리 크기를 그라데이션 누적과 결합하여 유효한 일괄 처리 크기를 유지합니다.

스트리밍 데이터 세트

메모리에 맞지 않는 매우 큰 데이터 세트의 경우 스트리밍 방법을 사용합니다.