스터디

[KANS 3기] 슈퍼컴퓨팅 워크로드를 위한 컨테이너 설정

엔지니어-여리 2024. 8. 31. 03:12
반응형

컨테이너를 사용하는 목적은 대부분 프로세스 경량화, 패키징, 격리 등이 있습니다. 대량의 CPU나 GPU를 활용하는 슈퍼컴퓨팅 워크로드에서도 컨테이너를 사용하는 게 맞을까요 ?

네. 사실은 슈퍼컴퓨팅과 같은 워크로드는 컴퓨팅 파워 즉 연산 성능이 가.장 중요하기 때문에 컨테이너를 활용한 가상화조차도 워크로드의 손해가 적지 않습니다. 그럼에도 불구하고 많은 슈퍼컴퓨팅 아키텍처에서도  컨테이너를 도입합니다. 

그렇다면, 슈퍼컴퓨팅 서비스를 제공하는 워크로드에서는 어떤 설정을 해줘야 할까요 ?

앞서 언급한 것과 같이 슈퍼컴퓨팅 워크로드에서는 연산 성능이 가장 중요합니다. 다른 것들은 엔지니어가 아키텍처를 구성하면서 조금 불편함을 감수하기도 합니다. 하지만 워크로드의 동일한 실행 환경을 보장하기 위해 컨테이너 환경을 도입하는 경우도 많습니다. 

가장 많이 사용되는 스케줄러인 slurm의 경우에는 기본적으로 컨테이너 환경에서 제약이 있습니다. 하지만, 최근에는 slurm 클러스터를 k8s에서 구현하는 경우도 많이 있습니다. SUNK이라는 프로젝트가 있습니다.

sunk architecture

 

여기서 SUNK를 바로 다루기에는 너무 복잡하니 우리는 HPC 워크로드를 컨테이너 환경에서 아주 간단히 구성해보겠습니다.

 

HPC 워크로드에서는 다수의 코어를 활용합니다. 기본적으로 하나의 컨테이너가 노드의 모든 코어를 모.두 사용한다고 보시면 됩니다. 예를 들어 c5.24xlarge 인스턴스에서 하나의 컨테이너가 동작합니다. 이때, 이 컨테이너는 96 vCPU, 192 GiB 메모리를 활용합니다. 그리고 이 컨테이너는 하나의 작업 (Job)을 아주 빠르게 수행하기 위해서 모든 코어가 병렬적(parallel)으로 연산을 합니다. 연산을 하는 도중 각 코어는 별개의 메모리를 할당받고, 중간중간에 코어마다 연산된 값을 정리하기도 하고 몇몇 코어는 메모리를 공유하기도 합니다. 

 

자, 그럼 대충 컨테이너에서 하드웨어 리소스가 어떤 일을 하는지 맥락이 파악되었으니 무진장 거대한 컨테이너에 컴파일러, 컴파일된 소스코드의 바이너리, 인풋파일등을 넣고 병렬 연산을 해볼까요 ? 이렇게만 작업이 잘 실행되고 종료될까요 ?? 

 

어떨 때는 되고 어떨 때는 안된다구요 ? 왜요? 왤 까요 ?

 

 

docker run 에서 --shm-size 라는 옵션을 추가하셨을까요 ?

 

사실은 공유메모리 설정이 부족해서 그런겁니다. 공유메모리는 (각 코어가 할당된)프로세스간 통신을 위해 설정해줘야 하는 값입니다. 

 

공유메모리를 설정하지 않으면 기본적으로 64MB가 설정됩니다. 만약 필요한 공유메모리가 64MB 이하였다면 해당 잡은 에러 없이 잘 실행되었을 겁니다. 하지만 공유메모리가 부족했다면 [This might be caused by insufficient shared memory] 이런 에러 메시지를 경험했을 겁니다. 

 

그렇다면, 공유메모리는 어떻게 설정해줘야하나요 ? 얼마나 설정해줘야 하나요 ?

 

공유메모리는 컨테이너 생성시 docker run 명령에서 --shm-size 192G 와 같은 형태로 설정할 수 있습니다.

컨테이너가 가질 수 있는 가장 큰 메모리로 잡아주면 해당 컨테이너에서 작업을 수행하는데 공유메모리로 인해 작업이 종료될 걱정이 없습니다.

 

공유 메모리를 확인하는 방법

docker run -it --rm --shm-size 2g ubuntu:20.04  /bin/bash # 공유메모리를 설정한 컨테이너 생성

docker inspect [container id] | grep -i shm # 생성된 컨테이너의 공유메모리 확인 

  "ShmSize": 2147483648,

 

 

AI 학습을 위해 GPU를 사용하는 워크로드도 마찬가지로 적용하면 문제를 해결할 수 있습니다.

 

감사합니다.

반응형