AWS 기술 블로그
Amazon EC2 가속 컴퓨팅 인스턴스 활용하기 – 파트 1 – AWS Deep Learning AMI (DLAMI)
서론
전통적인 고성능 컴퓨팅(HPC, High Performance Computing) 뿐만 아니라, 인공지능, 기계 학습, 그리고 생성형 AI의 활용도가 높아짐에 따라, 고성능 GPU가 장착된 가속 컴퓨팅을 위한 하드웨어의 수요와 사용률이 급격히 증가하고 있습니다. 이는 온프레미스 데이터센터 뿐만 아니라 클라우드에서도 동일한 현상이 나타나고 있습니다. AWS와 같은 클라우드 서비스 제공업체를 통한 빠른 컴퓨팅 리소스의 공급, 구축, 그리고 온디맨드 방식의 과금은 가속 컴퓨팅을 활용할 수 있는 훌륭한 선택지가 될 것입니다. 그러나, 컴퓨팅 리소스를 할당 받고, 즉시 개발을 시작할 수 있어야 비용의 낭비가 없이 더 큰 효과를 발휘할 수 있을 것입니다. 하지만, 가속 컴퓨팅 리소스를 할당 받고도, 개발 환경을 구성하고 시작하는 데 어려움을 겪는 사례를 다수 확인할 수 있었습니다.
이 블로그는 이와 같은 어려움을 겪는 독자들을 위하여, Amazon EC2의 가속 컴퓨팅 인스턴스와 AWS에서 제공되는 다양한 리소스를 이용하여, 멀티 노드 가속 컴퓨팅 환경을 쉽게 구축할 수 있는 방법에 대해서 알아 볼 것입니다.
블로그는 아래와 같이 3개의 시리즈로 구성이 되어 있으며, EC2 기반의 가속 컴퓨팅 환경을 활용하는 데에 중점을 두고 있습니다. 만약, AWS의 완전 관리형 기계 학습 서비스에 더 많은 관심이 있으시다면 Amazon SageMaker와 Amazon SageMaker HyperPod을 검토하여 보시기 바랍니다.
- Amazon EC2 가속 컴퓨팅 인스턴스 활용하기 – 파트 1 – AWS Deep Learning AMI (DLAMI)
- Amazon EC2 가속 컴퓨팅 인스턴스 활용하기 – 파트 2 – AWS ParallelCluster
- Amazon EC2 가속 컴퓨팅 인스턴스 활용하기 – 파트 3 – Amazon Elastic Kubernetes Service (EKS) 기반의 GPU 클러스터
가속 컴퓨팅을 위한 AWS의 서비스
가속 컴퓨팅을 위하여 AWS는 자체 개발한 AWS Inferentia, AWS Trainium 칩이 적용된 Amazon EC2 Trn1, Amazon EC2 Inf2 인스턴스 유형 뿐만 아니라, NVIDIA H100과 A100 GPU가 장착된 Amazon EC2 P5, Amazon EC2 P4와 같이 다양한 유형의 인스턴스가 제공되고 있습니다. 이러한 가속 컴퓨팅 인스턴스를 최적으로 활용할 수 있도록, 고성능 네트워크 인터페이스인 Elastic Fabric Adaptor(EFA)와 함께, Amazon EC2 UltraClusters 아키텍처를 사용하여 리소스를 제공합니다. 또한, 블로그에서 더 알아 보게 될 AWS Deep Learning AMI (DLAMI), Amazon EKS 최적화 가속 Amazon Linux AMI, AWS Deep Learning Containers, 그리고 AWS Batch, AWS ParallelCluster, Amazon EKS와 같은 작업 및 클러스터 관리 도구도 또한 제공하고 있습니다.
가속 컴퓨팅 인스턴스를 즉시 활용할 수 있는 다양한 방법중에, 첫 번째의 선택지는 DLAMI를 사용하는 것입니다. DLAMI는 Amazon EC2를 기반으로 딥 러닝을 가속화할 수 있는 안전한 프레임워크, 종속성 및 도구를 엄선하여 기계 학습 실무자와 연구자에게 제공합니다. Amazon Linux 및 Ubuntu용으로 개발된 Amazon Machine Image(AMI)는 TensorFlow, PyTorch, NVIDIA CUDA 드라이버와 라이브러리, Intel MKL, Elastic Fabric Adapter(EFA) 및 AWS OFI NCCL 플러그인이 미리 구성되어 제공되므로 원하는 프레임워크 및 도구를 대규모로 신속하게 배포하고 실행할 수 있습니다. DLAMI의 전반적인 정보는 개발자 가이드를 참고할 수 있으며, 사전에 설치된 소프트웨어 스택은 DLAMI 릴리즈 노트에서 확인할 수 있습니다.
AWS DLAMI 가속 컴퓨팅 환경 구축
이제부터 DLAMI를 사용하여 가속 컴퓨팅 인스턴스를 활용하는 방법을 알아 보겠습니다. DLAMI를 사용하기 위해서는, 먼저 아래의 사전 필요 사항을 충족해야 하며 링크를 참고하여 구성할 수 있습니다.
사전 필요 사항
- AWS 계정, 관리용 사용자, AWS CLI
- 만약, AWS CLI의 프로파일을 “default”로 설정하지 않은 경우에는, 블로그에 사용된 AWS CLI 명령에 추가적으로
--profile PROFILE_NAME
을 명시해야 올바르게 동작합니다.
- 만약, AWS CLI의 프로파일을 “default”로 설정하지 않은 경우에는, 블로그에 사용된 AWS CLI 명령에 추가적으로
- AWS 리소스
- Amazon EC2 vCPU 서비스 할당량 증가
- 블로그 시리즈에서는 2개 이상의 G6 유형의 EC2 인스턴스를 사용합니다. 독자의 환경에 따라 새로운 EC2 인스턴스를 생성하려고 시도할 때, vCPU 할당량 부족으로 인해 오류가 발생하며 생성이 실패할 수 있습니다.
- 이 re:Post 게시글을 참고하여 현재의 vCPU 할당량을 확인하고, 사전에 증가시킨 후에 실습하시는 것을 권장하여 드립니다.
1. (선택 사항) 온디맨드 용량 예약(On-Demand Capacity Reservations, ODCR) 생성
이 단계는 선택 사항입니다. 가속 컴퓨팅 수요의 급증으로 공급이 원활하지 않은 인스턴스를 사용해야 할 경우에는, 온디맨드 용량 예약을 사용하여 필요한 컴퓨팅 용량을 예약하고 확보할 수 있습니다. 하지만, 용량이 계정에 프로비저닝되면, 인스턴스가 예약 용량으로 실행되는지의 여부와 관계 없이, 선택한 인스턴스 유형에 대한 용량 예약이 온디맨드 요금으로 청구되는 점을 유의해야 합니다. 필요한 인스턴스 유형, 플랫폼, 리전과 가용 영역등을 지정하여 용량 예약을 생성합니다.
aws ec2 create-capacity-reservation \
--instance-type g6.12xlarge \
--instance-platform Linux/UNIX \
--availability-zone us-west-2c \
--instance-count 2 \
--region us-west-2
2. 환경 변수 설정
인스턴스 생성에 필요한 환경 변수를 설정합니다. 이를 통하여 인스턴스 구성을 보다 자동화할 수 있게 됩니다. 이 단계에서 유의해야 할 사항은, AWS CLI에 사용된 리소스 조회를 위한 인덱스 번호입니다. 사용자의 환경에 맞게 인덱스를 수정하여, 사용하고자 하는 리소스를 지정해 주시기 바랍니다. 또한, 인스턴스에 사용할 DLAMI_ID는 DLAMI 릴리즈 노트를 참고하여 조회할 수 있습니다.
CR_ID=$(aws ec2 describe-capacity-reservations --query "CapacityReservations[0].CapacityReservationId" --output text)
VPC_ID=$(aws ec2 describe-vpcs --query "Vpcs[0].VpcId" --output text)
SUBNET_ID=$(aws ec2 describe-subnets --filters "Name=availability-zone,Values=us-west-2c" --query "Subnets[0].SubnetId" --output text)
KEY_PAIR_NAME=$(aws ec2 describe-key-pairs --query "KeyPairs[0].KeyName" --output text)
DLAMI_ID=$(aws ec2 describe-images --region us-west-2 --owners amazon \
--filters "Name=name,Values=Deep Learning OSS Nvidia Driver AMI GPU PyTorch 2.3.? (Ubuntu 20.04) ????????" "Name=state,Values=available" \
--query "reverse(sort_by(Images, &CreationDate))[:1].ImageId" --output text)
3. EFA용 보안 그룹 생성
멀티 노드 가속 컴퓨팅 환경을 최적으로 활용하기 위해서는, 고성능 네트워크 인터페이스인 Elastic Fabric Adaptor(EFA)를 사용하는 것을 권장합니다. EFA에 대한 보다 자세한 사항은 “AWS 고성능 컴퓨팅 네트워크, 1부: AWS가 제공하는 고속 네트워크 인터페이스, EFA(Elastic Fabric Adaptor)” 블로그를 참고하실 수 있습니다. 아래와 같이 EFA에 사용하기 위한 보안 그룹을 생성하고 인바운드 및 아웃바운드 규칙을 적용합니다. 유의할 사항은 SSH 접속을 위한 인바운드 규칙의 CIDR은 독자의 환경에 맞도록 수정을 합니다. EFA를 사용하기 위한 준비는 사용자 가이드를 통해 전체 과정을 확인할 수 있으며, DLAMI에는 EFA를 사용하기 위한 소프트웨어가 미리 설치되어 있으므로 별도의 설치는 필요하지 않습니다.
aws ec2 create-security-group --group-name EFA_SG --vpc-id $VPC_ID --description "Security group for EFA"
EFA_SG_ID=$(aws ec2 describe-security-groups --group-names EFA_SG --query "SecurityGroups[0].GroupId" --output text)
aws ec2 authorize-security-group-ingress --group-id $EFA_SG_ID --protocol tcp --port 22 --cidr 10.10.1.0/24
aws ec2 authorize-security-group-ingress --group-id $EFA_SG_ID --protocol -1 --port all --source-group $EFA_SG_ID
aws ec2 authorize-security-group-egress --group-id $EFA_SG_ID --protocol -1 --port all --source-group $EFA_SG_ID
4. 환경 변수 확인
앞선 과정에서 생성한 온디맨드 용량 예약, EFA용 보안 그룹, 그리고 다른 리소스들에 대한 환경 변수가 잘 설정이 되었는지 확인합니다.
echo $CR_ID
echo $EFA_SG_ID
echo $VPC_ID
echo $SUBNET_ID
echo $KEY_PAIR_NAME
echo $DLAMI_ID
5. 가속 컴퓨팅 인스턴스 생성
생성한 리소스와 환경 변수를 적용하여 가속 컴퓨팅 인스턴스를 생성합니다. 이 블로그에서는 EFA를 연결한 2개의 G6 유형의 인스턴스를 생성할 것이며, G6 유형의 인스턴스는 최대 8개의 NVIDIA L4 Tensor Core GPU와 192GB의 GPU 메모리를 제공합니다. 인스턴스 생성을 위한 보다 더 다양한 옵션은, AWS CLI 사용자 가이드를 참고하시기 바랍니다.
aws ec2 run-instances \
--count 2 \
--ebs-optimized \
--instance-type g6.12xlarge \
--private-dns-name-options "EnableResourceNameDnsARecord=true" \
--metadata-options "HttpEndpoint=enabled,HttpTokens=required,HttpPutResponseHopLimit=2" \
--image-id $DLAMI_ID \
--key-name $KEY_PAIR_NAME \
--network-interfaces \
"NetworkCardIndex=0,DeviceIndex=0,InterfaceType=efa,Groups=$EFA_SG_ID,SubnetId=$SUBNET_ID,DeleteOnTermination=true" \
--tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=g6-12xlarge-dlami-ubuntu-pytorch}]"
만약, 온디맨드 용량 예약을 생성하였다면, 아래의 옵션을 CLI의 마지막에 함께 추가해서 인스턴스를 생성합니다.
--capacity-reservation-specification "CapacityReservationTarget={CapacityReservationId=$CR_ID}"
지금까지의 과정에 문제가 없다면, CLI 명령은 아래와 같은 출력을 보여주며 인스턴스를 시작합니다.
2개 인스턴스의 시작이 성공적으로 완료가 되면, AWS 관리 콘솔을 사용하여 생성된 인스턴스의 정보를 확인할 수 있습니다. 인스턴스 유형, VPC, AMI 이름, 그리고 보안 그룹의 규칙등과 같은 주요 항목들을 확인합니다
6. 인스턴스 로그인 및 환경 확인
생성된 인스턴스의 퍼블릭 IP와 키페어를 이용하여 인스턴스에 로그인하고, 구성된 하드웨어와 소프트웨어의 환경을 확인합니다. 성공적으로 로그인이 완료되면 운영체제의 MOTD (Message of the Day)를 확인할 수 있습니다. MOTD에서는 운영체제의 기본 정보, DLAMI에 대한 설명, 그리고 PyTorch 가상 환경을 활성화 할 수 있는 명령을 보여줍니다.
ssh ubuntu@INSTANCE_PUBLIC_IP -i KEY_PAIR_NAME.pem
추가적으로 아래의 명령들을 사용하여 장착된 GPU 정보, CUDA 버전 정보, 그리고 EFA도 확인을 합니다. 4개의 NVIDIA L4 GPU와 1개의 EFA가 장착이 되어 있음을 확인할 수 있습니다.
nvidia-smi
nvcc --version
fi_info -p efa
7. 가상 환경 활성화 및 GPU 테스트
이제 G6 인스턴스의 GPU를 테스트할 수 있는 환경의 준비가 완료 되었습니다. 먼저 PyTorch 파이썬 가상 환경을 활성화하고, 아래의 샘플 스크립트를 실행하여 결과를 확인합니다. Conda 환경을 처음 시작할 때 로드가 되는 동안 기다려야 합니다. Conda를 사용한 DLAMI는 프레임워크가 처음 활성화될 때 EC2 인스턴스에 가장 최적화된 버전의 프레임워크를 자동으로 설치합니다. 한번 활성화가 된 이후에는 지연이 발생하지 않습니다.
source activate pytorch
cat << EOF> sample.py
import torch
print("PyTorch Version ->", torch.__version__)
print("GPU 확인 ->", torch.cuda.is_available())
print("GPU 이름 ->", torch.cuda.get_device_name(0))
# GPU 사용 가능 여부 확인
if torch.cuda.is_available():
device = torch.device('cuda')
print("GPU를 사용합니다.")
else:
device = torch.device('cpu')
print("GPU를 사용할 수 없습니다. CPU를 사용합니다.")
# GPU에서 간단한 텐서 연산
x = torch.tensor([1.0, 2.0, 3.0, 4.0, 5.0], device=device)
y = x ** 2
# 결과 출력
print('입력 텐서:', x)
print('출력 텐서:', y)
EOF
python sample.py
8. 멀티 노드 분산 데이터 병렬 처리
단일 노드에서 단일 GPU를 사용해 보는 테스트를 완료했습니다. 이번에는 2개의 노드와 8개의 GPU를 사용하는 분산 데이터 병렬 처리 테스트를 수행해 보겠습니다. 이는 PyTorch 예제 깃허브의 분산 데이터 병렬 처리 예제를 활용합니다. 아래와 같이 2개의 인스턴스 모두에서 예제 깃허브를 복제하고 확인합니다. PyTorch 프레임워크를 사용하여 분산 데이터 병렬 처리를 위한 실습 코드들을 확인할 수 있습니다.
cd ~
git clone https://github.com/pytorch/examples
cd ~/examples/distributed/ddp-tutorial-series
ls
첫 번째 인스턴스에서 분산 데이터 병렬 처리를 위해 아래와 같이 torchrun 명령을 수행합니다. torchrun 에 대한 개요와 사용 방법은 PyTorch 문서에서 확인할 수 있습니다. 이 단계에서 유의할 점은 --rdzv_endpoint
는 마스터 노드 역할을 하게 될 인스턴스의 프라이빗 IP를 사용한다는 것이며, 2개의 인스턴스중에 하나의 인스턴스를 선택하고 INSTANCE_01_PRIVATE_IP
를 변경하여 실행합니다. 이 명령은 8192 번의 Epoch를 수행하고, 1024 번째 Epoch 마다 스냅샷을 저장합니다.
torchrun --nproc_per_node=4 --nnodes=2 --node_rank=0 --rdzv_id=100 --rdzv_backend=c10d \
--rdzv_endpoint=INSTANCE_01_PRIVATE_IP:30000 multigpu_torchrun.py 8192 1024
두 번째 인스턴스에서도 동일하게 PyTorch 파이썬 가상 환경을 활성화하고, 분산 데이터 병렬 처리를 위해 아래와 같이 torchrun 명령을 수행합니다. 첫 번째 인스턴스와의 차이점은 --node_rank
가 “0”이 아닌 “1”로 변경이 된 것을 유의해야 합니다.
source activate pytorch
torchrun --nproc_per_node=4 --nnodes=2 --node_rank=1 --rdzv_id=100 --rdzv_backend=c10d \
--rdzv_endpoint=INSTANCE_01_PRIVATE_IP:30000 multigpu_torchrun.py 8192 1024
두 번째 인스턴스에서도 torchrun 명령이 실행되면, 아래와 같이 각 인스턴스에서 학습을 시작하고 성공적으로 완료가 되면 아래와 같은 출력을 보여 줍니다.
두 개의 인스턴스에서 학습 코드가 수행이 되는 동안에, 아래의 명령으로 각 인스턴스의 GPU 사용률을 모니터링 할 수 있습니다.
watch -n 1 nvidia-smi
9. 리소스 정리
실습을 완료하고 테스트 환경을 지속적으로 사용하지 않을 계획이라면, 추가 과금을 방지하기 위하여 인스턴스를 삭제하고 온디맨드 용량 예약을 취소합니다. YOUR_INSTANCE_IDS
는 “5. 가속 컴퓨팅 인스턴스 생성” 과정에서 확인한 인스턴스의 ID를 사용합니다.
aws ec2 terminate-instances --instance-ids YOUR_INSTANCE_IDS
aws ec2 cancel-capacity-reservation --capacity-reservation-id $CR_ID
결론
AWS는 가속 컴퓨팅을 위하여 다양한 유형의 Amazon EC2의 가속 컴퓨팅 인스턴스 뿐만 아니라, 고성능 네트워크 어댑터 Elastic Fabric Adaptor(EFA), 그리고 Amazon EC2 UltraClusters 아키텍처를 사용하여 리소스를 제공합니다. 그러나, 이런 가속 컴퓨팅 리소스를 이용하여 빠르고 효율적으로 환경을 구축하고 활용할 수 있는 방법이 필요합니다.
이를 위하여, AWS는 AWS Deep Learning AMI (DLAMI), Amazon EKS 최적화 가속 Amazon Linux AMI, AWS Deep Learning Containers, 그리고 AWS Batch, AWS ParallelCluster, Amazon EKS와 같은 작업 및 클러스터 관리 도구도 또한 제공하고 있습니다.
이 블로그에서는 가속 컴퓨팅 인스턴스를 빠르게 시작하고 사용할 수 있는 DLAMI에 대해서 자세히 알아 보았습니다. DLAMI를 사용하여 시간, 비용, 리소스의 낭비가 없이 효과적으로 가속 컴퓨팅 인스턴스를 즉시 시작하고 바로 활용할 수 있습니다.
다음의 블로그 시리즈에서는 가속 컴퓨팅 클러스터를 쉽게 배포하고 관리할 수 있게 해 주는 오픈 소스 클러스터 관리 도구인 AWS ParallelCluster에 대해서 알아 보겠습니다.