2019년 7월 23일 화요일

공유 HW infrastructure에서의 H2O DriverlessAI 사용 방안


H2O DriverlessAI (이하 DAI)를 사내의 여러 팀에서 사용할 경우 먼저 참고하셔야 할 사항은 다음과 같습니다.

1) DAI의 training(DAI 용어로는 experiment)는 host memory든 GPU memory든 꼭 필요한 만큼의 memory만 사용합니다.  따라서 시스템 자원의 여유만 충분하다면 하나의 서버에서 여러 training을 한꺼번에 수행해도 됩니다.

2) DAI는 일반적으로 dataset 크기의 10배에 해당하는 메모리를 사용한다고 예상하시면 됩니다.  가령 1GB의 dataset으로 training을 한다고 하면, 10GB의 메모리가 필요합니다.  "Accuracy" dial setting을 낮추면 더 적은 memory로도 training이 가능합니다.

3) DAI는 CPU 자원도 많이 쓰지만 특히 memory 자원에 민감합니다.  하나의 DAI training이 이미 시스템의 거의 모든 memory를 다 쓰고 있는 상황에서, 추가적으로 다른 DAI training을 수행하기 시작한다면, 이 두 DAI training 모두가 memory 부족으로 fail될 수 있습니다.

4) DAI는 GPU 자원이 없거나 GPU가 있어도 GPU의 메모리가 부족한 경우 그냥 CPU를 이용해서 training을 수행합니다.  따라서 GPU가 없거나 GPU 메모리가 부족하다고 해서 DAI training이 fail나는 경우는 없습니다.


위와 같은 사항을 이해한다면, 서로의 상황을 잘 이해하고 서로 배려하는 소수의 사용자들이 하나의 서버에서 여러개의 training을 동시에 수행하는 것은 별 문제를 일으키지 않습니다.  그러나 서로에 대해 잘 모르는 여러 팀의 여러 사용자들이 하나의 서버를 공유하는 것은 쉽지 않습니다.

이렇게 불특정 다수의 사용자들이 제한된 서버 자원을 이용하여 DAI에서 training을 하기 위해서는 각 사용자마다 한정된 시스템 자원 (CPU, memory, GPU)를 나누어주는 것이 가장 안정적입니다.  그러나 각각의 사용자들에게 완전히 격리된 가상머신을 할당해줄 경우 낭비되는 자원이 너무 많아진다는 약점이 있습니다.


이런 점들을 고려할 때, 가장 좋은 솔루션은 docker(GPU가 있는 환경에서는 nvidia-docker)를 사용하는 것입니다.  Docker를 사용할 경우의 장점은 아래와 같습니다.

1) 각 사용자가 사용하는 DAI docker image에서 사용할 수 있는 CPU와 memory, GPU의 한도를 정할 수 있으므로 각 사용자는 안정적인 training이 가능합니다.

2) 이미 다른 사용자에게 할당된 자원이라도, 당장 사용하지 않는 자원은 다른 사용자들의 docker container가 사용할 수 있으므로 전체적인 시스템 활용률이 높아집니다.

3) CPU나 메모리, disk 공간 등에 대한 가상화 오버헤드가 거의 없습니다.   IP도 사용자마다 1개씩 필요하지 않고, 각 사용자들에게는 서로 다른 port number만 할당해주면 됩니다.

4) 각 사용자 간의 보안은 일반적인 linux 보안 정책을 그대로 사용합니다.  따라서 보안 구분이 필요한 사용자 그룹마다 각기 다른 linux OS user id를 생성하여 관리하면 됩니다. 

5) 서비스의 생성은 command line 또는 script 한줄로 몇 초 안에 간단하게 처리되며, 이는 수퍼 유저(root)의 권한을 가진 시스템 관리자만 할 수 있습니다.

6) 100% 오픈소스로 간단하게 구축할 수 있습니다.


DAI를 구동할 때 docker를 이용하는 방법은 다음과 같이 간단합니다.  DAI가 설치된 docker image를 다음과 같이 구동하면 됩니다.

$ sudo docker run --runtime=nvidia --init --rm -p 12311:12345 -v /user01/data:/data -v /user01/log:/log -v /user01/tmp:/tmp h2oai/dai-redhat7-ppc64le:v0.1 

--runtime=nvidia : GPU를 사용하는 nvidia-docker 환경임을 명기
-p 12311:12345 : docker 내부의 DAI가 사용하는 port인 12345를 parent OS에서는 12311 port로 전달
-v /user01/data:/data : Parent OS의 /user01/data directory를 docker 내부에서는 /data directory로 mount 
h2oai/dai-redhat7-ppc64le:v0.1 : DAI가 설치된 docker image의 이름과 tag


위에서는 아무런 자원 제약을 주지 않고, 전체 시스템의 자원을 다 사용할 수 있도록 docker container를 구동한 것입니다.  이 경우, 1GB 정도의 AML dataset을 training할 때의 자원 사용 현황은 아래와 같습니다.   DAI process가 10GB의 memory(Res Data 기준 - 실제 real memory를 점유한 크기)를 사용하고 있으며 CPU도 (HW thread를 제외하고) 8개의 CPU core를 다 쓰고 있는 것을 보실 수 있습니다.



이렇게 시스템 자원의 제약 없이 수행한 경우엔 1GB dataset 수행에 (accuracy-time-interpretability dial 2-2-2로 세팅) 23m 29s가 걸렸습니다.



이번에는 CPU 자원은 core 4개, 메모리 자원은 5GB로 제한을 주고 수행해보겠습니다.

$ sudo docker run --runtime=nvidia --init --rm --cpus=4 --memory=5g -p 12311:12345 -v /user01/data:/data -v /user01/log:/log -v /user01/tmp:/tmp h2oai/dai-redhat7-ppc64le:v0.1

이 경우 동일한 크기의 dataset을 동일한 dial 세팅으로 수행할 때 자원 사용 현황은 아래와 같습니다.   DAI process가 4GB의 memory(Res Data 기준 - 실제 real memory를 점유한 크기)를 사용하고 있으며 CPU도 (HW thread를 제외하고) 8개의 CPU core 중 절반만을 쓰고 있는 것을 보실 수 있습니다.



이렇게 시스템 자원을 4 CPU core, 5GB의 메모리로 제약을 주고 수행한 경우엔 1GB dataset 수행에 (accuracy-time-interpretability dial 2-2-2로 세팅) 41m 12s가 걸렸습니다.   자원 제약 없을 때보다 2배 정도의 시간이 걸린 것을 보실 수 있습니다.




Docker container 수행시 GPU 자원을 할당하는 것은 아래와 같이 NVIDIA_VISIBLE_DEVICES 변수를 환경변수로 사용하면 됩니다.  아래의 경우에서는 2번과 3번 2개의 GPU를 할당하게 됩니다.

$ sudo docker run --runtime=nvidia --init --rm --cpus=4 --memory=5g -e NVIDIA_VISIBLE_DEVICES=2,3 -p 12311:12345 -v /user01/data:/data -v /user01/log:/log -v /user01/tmp:/tmp h2oai/dai-redhat7-ppc64le:v0.1




댓글 없음:

댓글 쓰기