AWS 기술 블로그

카카오스타일의 Amazon SageMaker 분산 훈련을 활용한 카테고리 자동 분류 시스템 모델 구축 사례

회사/팀 소개

카카오스타일은 모든 사람이 나만의 특별한 스타일을 가지고 있고, 내가 좋아하는 무언가를 발견했을 때의 즐거움이 일상을 더욱 나답게 만든다고 믿습니다. 사용자의 패션 뿐 아니라 일상에서의 모든 스타일을 위해 뷰티, 라이프 카테고리까지 확장하여 사용자의 즐거운 발견을 돕고 있습니다.
카카오스타일의 Vision & NLP(Natural Language Processing) 팀은 패션, 뷰티, 라이프 분야에서 컴퓨터 비전과 자연어 처리 기술을 활용하여 카카오스타일의 서비스를 발전시키고 사용자 경험을 향상시키는 데 초점을 맞추고 있습니다. 상품 메타 정보 분석, 추천 시스템, 리뷰 분석, 패션 트렌드 분석 등을 통해 사용자에게 더 나은 플랫폼 경험을 제공하기 위해 노력하고 있습니다.

프로젝트 소개

Vision & NLP 팀은 지그재그 서비스에 연동되어 자동으로 등록되는 상품들의 카테고리 입력율을 높이고자 이번 프로젝트를 시작했습니다. 카테고리 입력은 상품의 노출영역 등 여러 정책에 사용되기 때문에, 카테고리 입력율이 낮으면 문제가 발생할 수 있습니다.
상품은 상품명, 상품 설명, 썸네일 이미지 등 풍부한 메타정보를 가지고 있습니다. 이 정보를 이용해 지그재그 내 카테고리에 자동으로 분류하는 것이 이번 프로젝트의 목표였습니다.
그러나, 지그재그 앱 내에는 2천만 개 이상의 상품이 등록되어 있으며, 패션 및 라이프 카테고리로의 확장으로 카테고리의 추가 등 카테고리 구조가 변경될 때마다 모델을 갱신해야 합니다. 설계된 모델을 대량의 데이터로 훈련하기 위해 단일 GPU 환경에서는 수 일 이상이 소요됩니다. 이는 컴퓨팅 비용의 문제뿐 아니라 파라미터 튜닝 등 모델의 관리 측면에서도 치명적입니다. 따라서 분산 훈련을 통해 훈련 시간을 줄일 필요가 있었습니다.

분산 훈련 아키텍처

그림 1. 카카오스타일의 분산 훈련 아키텍처

그림 1. 카카오스타일의 분산 훈련 아키텍처

최근 GPT, LLaMA트랜스포머 디코더 기반 언어 모델이 놀라운 문장 생성 성능을 바탕으로 지식 검색, 번역 등 다양한 분야에서 사용되고 있습니다. 그러나, 컴퓨팅 비용, 미세 조정의 어려움, 구문 분석이 필요한 출력 구조 등의 문제로 분류 문제와 같은 태스크에서는 여전히 상대적으로 가벼운 BERT와 같은 트랜스포머 인코더 기반 언어 모델이 널리 사용되고 있습니다. 따라서 카카오스타일에서도 패션 커머스 분야의 언어 분포를 잘 이해할 수 있도록 서비스 내 데이터를 이용하여 BERT 모델을 경량화한 DistilBERT 모델을 훈련했습니다.
BERT 모델은 MLM(Masked Language Model), NSP(Next Sentence Prediction)을 통해 문장 구조와 단어의 의미, 문법 등 언어에 대한 정보를 사전 훈련합니다. 사전 훈련된 BERT 모델은 12개의 트랜스포머 층으로 구성된 모델로, 3억 개 이상의 파라미터를 가지고 있습니다. 하지만 수천만 개 이상의 상품과 수천만 건 이상의 리뷰 데이터로 분류, 개체명 인식 등 다양한 작업을 수행하기에 BERT 모델을 그대로 사용하는 것은 지나치게 많은 비용이 필요합니다.
따라서 BERT를 지식 증류 기법(knowledge distillation)을 이용해 경량화한 DistilBERT 모델을 훈련했습니다. 지식 증류는 작은 모델(학생)이 대형 모델(교사)를 모방하도록 훈련하는 기법으로 훈련된 DistilBERT는 BERT의 절반인 6개의 트랜스포머 층을 사용하면서도 거의 동일한 성능을 보입니다. 그럼에도 불구하고 전체 상품을 이용하여 모델을 훈련하는 것은 여전히 많은 시간이 소요합니다.
Amazon SageMaker는 데이터 병렬 처리 및 모델 병렬 처리를 위한 빌트인 분산 학습 라이브러리를 제공하며, 데이터 병렬 처리 라이브러리인 SageMaker DDP(Distributed Data Parallel)은 훈련 코드를 거의 수정하지 않고 데이터 병렬화를 수행할 수 있습니다. PyTorch뿐 아니라 자연어 처리 분야에서 널리 사용되는 허깅페이스(Hugging Face) 기반의 파이프라인도 손쉽게 분산 훈련이 가능합니다.
모델의 훈련 데이터는 카카오스타일 내에 등록된 모든 상품을 이용하여 구성합니다. 오랜 시간 데이터가 쌓인 패션 카테고리와는 다르게 카테고리 확장 이후 등록된 뷰티, 라이프 상품은 상대적으로 상품 수가 적습니다. 따라서 검증 데이터 세트는 층화 추출법(stratified sampling)을 통해 전체 데이터의 10%로 구성합니다.

아래는 SageMaker DDP를 사용하기 위해 모델을 정의하는 훈련 스크립트 train.py 예시입니다. 보다 자세한 사용 방법은 Modify a PyTorch Training Script와 참고 자료의 핸즈온을 확인하기 바랍니다.

import os
import sys
import torch
import torch.distributed as dist
from torch.nn.parallel.distributedimport DistributedDataParallel as DDP
from transformers import AutoTokenize, AutoModelForSequenceClassification
import smdistributed.dataparallel.torch.torch_smddp
 
# Environment variables set by torch.distributed.launch or torchrun
world_size =int(os.environ['WORLD_SIZE'])
rank = int(os.environ['RANK'])
local_rank = int(os.environ['LOCAL_RANK'])
 
# initialize the process group
dist.init_process_group(backend='smddp', rank=rank, world_size=world_size)
torch.cuda.set_device(local_rank)
device = torch.device("cuda", local_rank)
 
tokenizer = AutoTokenizer.from_pretrained('distilbertmodel')
model = AutoModelForSequenceClassification.from_pretrained('distilbertmodel')
model = DDP(
    model.to(device),
    device_ids=[local_rank],
    output_device=local_rank
).to(local_rank)

훈련 스크립트 train.py를 작성하면, SageMaker SDK를 이용하여 SageMaker 훈련 Job을 정의하고 훈련을 시작합니다. 다음 예시는 8개의 NVIDIA V100 GPU를 사용하는 ml.p3.16xlarge 인스턴스를 이용하여 모델을 훈련하는 방법을 보여줍니다. 보다 자세한 사용 방법은 Launch a SageMaker Distributed Training Job Using the SageMaker Python SDK를 확인하기 바랍니다.

import sagemaker
from sagemaker.debugger import ProfilerRule, rule_configs
from sagemaker.pytorch import PyTorch

role = sagemaker.get_execution_role()
rules = [
    ProfilerRule.sagemaker(rule_configs.ProfilerReport()),
]

distribution = {
    'smdistributed':{
        'dataparallel':{
            'enabled': True
        }
    }
}

job_name = 'ddp-training'
instance_type = 'ml.p3.16xlarge'  # 'ml.p3.16xlarge', 'ml.p3dn.24xlarge', 'ml.p4d.24xlarge', 'local_gpu'
instance_count = 2    # 사용할 인스턴스 개수
max_wait = None
max_run = 48*60*60    # 최대 48시간 훈련

hyperparameters = {
    'epochs': 5,
    'batch_size': 64,
    'test_batch_size': 128
}

sagemaker_session = sagemaker.Session()
source_dir = 'src'

image_uri = "763104351884.dkr.ecr.ap-northeast-2.amazonaws.com/pytorch-training:1.10.2-gpu-py38-cu113-ubuntu20.04-sagemaker"
estimator = PyTorch(
    entry_point='train.py',
    source_dir=source_dir,
    role=role,
    image_uri=image_uri,
    instance_count=instance_count,
    instance_type=instance_type,
    distribution=distribution,
    rules=rules,
    max_wait=max_wait,
    max_run=max_run,
    hyperparameters=hyperparameters,
    sagemaker_session=sagemaker_session
)

estimator.fit(
    job_name=job_name,
    wait=False
)

SageMaker DDP는 ml.p3.16xlarge, ml.p3dn.24xlarge, ml.p4d.24xlarge 인스턴스 및 로컬 GPU를 이용하여 훈련이 가능합니다. 카카오스타일의 카테고리 분류 모델은 2개의 ml.p3.16xlarge 인스턴스를 이용하여 총 16장의 GPU를 사용하며, 과도한 비용 청구 방지를 위해 최대 48시간 동안 훈련을 수행합니다.
분산 훈련을 위한 개발 환경은 도커 이미지(Docker Image)를 통해 불러올 수 있습니다. SageMaker는 PyTorch 버전 등 자주 사용되는 환경에 맞춰 최적화된 빌트인 도커 이미지를 제공합니다. 사용 가능한 이미지 목록은 Deep Learning Containers 레포지토리에서 확인할 수 있습니다.

분산 훈련 팁

SageMaker DDP 기반 분산 훈련은 매우 간단한 방법으로 구현이 가능하지만, 예상치 못한 오류나 의도치 않은 방향으로 훈련이 진행될 수도 있습니다. 따라서, 아래의 분산 훈련 팁들을 적용해 보세요.

  • 일부 데이터 세트 및 로컬 모드로 디버깅: 분산 훈련은 대부분 대량의 데이터 세트나 대규모의 모델을 이용하여 훈련이 이루어지므로, 한 번의 오류로도 많은 비용 손실을 야기합니다. 따라서 데이터 세트의 일부만을 이용하여 훈련 작업이 오류 없이 완전히 종료되는지 테스트하는 것을 추천드립니다. 그리고 로컬 모드를 적용하면 디버깅을 더 빠르게 수행할 수 있습니다. 로컬 모드는 훈련 인스턴스를 프로비저닝하지 않고 훈련 인스턴스와 동일한 컨테이너로 로컬 환경에서 모델 개발과 디버깅을 수행하는 모드로 train_instance_type='local_gpu'로 설정하면 됩니다.
  • 혼합 정밀도(Mixed Precision): 대형 모델은 많은 GPU 메모리가 필요하므로 미니배치 크기를 늘리기 어렵습니다. 하지만 파라메터 연산에 16비트 부동 소수점을 사용하되, 수치 안정성을 위해 특정 파라메터는 32비트 부동 소수점을 사용하는 혼합 정밀도를 사용하면 미니배치 크기를 늘리면서 훈련 시간을 절감할 수 있습니다.
  • 훈련 데이터 준비 시간 개선: 대부분의 데이터 분산 훈련은 대량의 데이터 세트를 이용합니다. 만약 데이터 세트가 S3 버킷에 저장되어 있다면 데이터를 훈련 인스턴스에 내려받는 과정도 많은 시간이 소요됩니다. 이럴 때에는 훈련 데이터를 스트리밍하는 FastFile 모드나 Amazon FSx for Lustre 파일 시스템을 이용하여 훈련 데이터를 준비하는 시간을 줄여보세요. 자세한 내용은 SageMaker 개발자 문서(Access Training Data)를 참조하기 바랍니다.
  • 체크포인트 및 관리형 스팟 훈련(managed spot training)으로 비용 절감하기: 특정 주기(예: 매 에폭)마다 중간 훈련 결과를 /opt/ml/checkpoints로 저장합니다. 훈련 Job을 정의할 때 아래 코드 스니펫과 같이 스팟 인스턴스 옵션을 활성화하면 훈련 비용을 최대 90%까지 절감할 수 있는 SageMaker 관리형 스팟 훈련 기능을 사용할 수 있습니다. 훈련 작업이 중단되면 자동으로 훈련 인스턴스의 체크포인트 파일이 S3의 checkpoint_s3_uri 경로로 복사되고 새로운 스팟 인스턴스에서 훈련이 재개될 때 S3의 체크포인트가 인스턴스의 스토리지로 자동으로 복사됩니다.
  • chkpt_s3_path = f's3://[YOUR-BUCKET]/checkpoints-{curr_time}'
    use_spot_instances = False
    max_run = 48*60*60 # 최대 48시간 훈련
    
    if use_spot_instances:
     max_wait = 72*60*60 # 최대 72시간 훈련: spot instance waiting + max runtime
    else:
     max_wait = None
    
    sm_estimator = PyTorch(
        ...
        use_spot_instances = use_spot_instances,
        max_wait = max_wait,
        max_run = max_run, 
        checkpoint_s3_uri = chkpt_s3_path,
        checkpoint_local_path ='/opt/ml/checkpoints'
    )

결론

Amazon SageMaker의 DDP를 이용하여 대량의 데이터로도 빠르게 모델을 훈련하고 실험할 수 있었습니다. 로컬 환경에서의 분산 훈련은 개발환경을 구축하는 것 만으로도 큰 비용이 발생합니다. 단 몇 줄의 코드 수정만으로 쉽게 분산 훈련을 구현한다는 것은 훈련 시간의 감소 그 이상의 가치가 있습니다.
단일 V100 GPU를 사용하는 환경에서 보름 이상 걸리는 훈련을 16개의 V100 GPU를 제공하는 환경에서 SageMaker DDP를 이용한 최적화된 데이터 분산 훈련으로 30시간만에 마칠 수 있었습니다.
카테고리 분류 작업은 비교적 간단한 작업으로, 데이터 전처리 방법에 따라 모델의 성능이 크게 좌우되는 경우가 많습니다. 데이터 전처리 후 긴 시간 동안 모델의 학습 결과를 기다리는 대신 데이터를 전처리하고 준비하는 데에 더 많은 시간을 사용하여 모델을 훈련할 수 있었습니다.
아울러, 모델을 학습하며 맞닥뜨린 여러 문제에 적극적으로 도움 주신 AWS에 감사의 마음을 전합니다.

참고 자료

Jin HyunDoo

Hyundoo Jin

진현두 데이터 사이언티스트는 텍스트 데이터를 이용한 다양한 프로젝트 경험을 바탕으로 카카오스타일에서 리뷰 속성 태깅, 상품명 정규화 등 여러 프로젝트를 진행하였습니다. 풍부한 자연어 데이터를 활용한 사용자 경험 개선을 위해 여러 프로젝트를 진행하고 있으며, 지능형 검색 시스템을 이용한 검색 개선에도 관심이 많습니다.

Daekeun Kim

Daekeun Kim

김대근 AI/ML 전문 솔루션즈 아키텍트는 다년간 스타트업, 제조 및 금융 업계를 거치며 컴퓨터 비전 엔지니어로서 다수의 1저자 특허를 등록하고 제품 양산에 기여했으며, 데이터 과학자로서 다양한 PoC와 현업 프로젝트를 수행했습니다. 현재는 고객들이 AWS 인프라 상에서 AI/ML 서비스를 더욱 효율적으로 사용할 수 있도록 기술적인 도움을 드리면서 AI/ML 생태계 확장에 기여하고 있습니다. 머신러닝을 공부하기 시작했을 때 접한 톰 미첼(Tom M. Mitchell)의 명언, “머신러닝으로 문제를 해결하려면 해결하고자 하는 문제를 명확히 정의해야 한다”라는 말을 상기하며 항상 초심을 잃지 않으려 합니다.

Daeyeol Shim

Daeyeol Shim

심대열 AI/ML Expert 솔루션즈 아키텍트는 다양한 분야의 인공지능 경험을 바탕으로 고객이 AI/ML을 활용하여 비즈니스 성과를 달성할 수 있도록 고객과 함께 효율적인 아키텍처를 구성하고 도입하는 데 도움을 주는 역할을 수행하고 있습니다.

Daeheon Oh

Daeheon Oh

오대헌 테크니컬 어카운트 매니저는 데이터베이스에 대한 경험을 바탕으로 Enterprise support 고객에게 데이터베이스를 안정적으로 서비스 될 수 있도록 고객과 함께 효율적인 아키텍처와 운영 방식을 구성하는 역할을 수행하고 있습니다.