아주 쉽게 Docker 이용해 가상 환경 배포하기

Docker란?

 

Docker

 

 인공지능 개발자라고 하면 종종 제작한 모델을 배포하거나 타인의 모델을 가져올 때 환경 설정에서 크게 애를 먹을 것이다. 아나콘다가 설치된 환경이라면, 환경설정을 Conda export, Conda import 명령어를 통해 yaml 파일로 만들어서 모델이 돌아갈 환경을 배포할 수도 있지만, Docker를 이용하면 보다 편리하게 OS 환경부터 응용 프로그램, 세부적인 라이브러리까지 모두 제공할 수 있다.

 

 

따라서 Docker에 대해 쉽게 정리하면,

 

"응용 프로그램과 해당 종속성(라이브러리, 환경 설정 등)을 하나의 격리된 환경으로 묶어 실행할 수 있도록 하는 프로그램"

 

 

정도라고 생각하면 좋을 것 같다.

 

 

 

Docker를 이용해 모델이 돌아갈만한 환경을 제공하기 위해선 최소한의 몇가지 용어들을 알아야 한다.

 

 

1. 이미지 (Image)

  • 컨테이너를 가동하기 위한 실행 파일과 설정 파일의 묶음
  • 데이터 베이스, 웹 서버, 애플리케이션 등 다양한 이미지가 등록되어 있음
  • 이미지는 컨테이너의 기반을 이루는 실행 가능한 패키지
  • 파일 시스템, 소프트웨어, 환경설정 및 실행 명령을 포함
  • 응용 프로그램을 실행하기 위한 모든 것을 포함하며, 공유 및 재사용이 가능한 형태로 존재
  • 읽기 전용이며 수정이 불가능 (따라서 이미지가 생성된 이후에는 내부 내용을 수정할 수 없음.)

 

2. 컨테이너 (Container)

  • 이미지의 인스턴스 또는 실행 가능한 실행 환경
  • 이미지를 실행하면, 컨테이너가 생성되고 컨테이너 내에서 응용 프로그램이 실행됨
  • 호스트 시스템과 격리된 환경에서 실행되므로 다른 컨테이너나 시스템에 영향을 주지 않음
  • 가상머신 (Virtual Machine) 보다 가볍고 시작과 종료가 빠름

 

 즉, 이미지를 이용해서 실행 환경(컨테이너)를 만들고, 또 그 실행환경을 하나의 이미지 파일로 내보내어 언제든 컨테이너를 생성해서 모델이 돌아갈 수 있는 환경을 구현할 수 있도록 하는 것이다.

 

 

 

Docker 이미지 굽기

 

그럼, 도커를 이용하여 타인에게 배포할 이미지를 구워보도록 하자

 

도커 이미지를 생성하는 방법은 크게 두 가지가 있다.

 

1. Docker file 생성하기

2. Base 이미지 선정 후 컨테이너를 생성하고 그 안에서 환경설정을 한 후 이미지로 추출 하기

 

먼저, Docker file은 Docker Image를 생성하기 위한 스크립트 설정파일이다.

명령어를 토대로 스크립트를 작성하면 Docker Image를 생성해주는데, 기본적인 구조는 아래와 같이 생겼다.

# 기반 이미지 선택
FROM ubuntu:16.04

# 필요한 라이브러리 및 도구 설치
RUN apt-get update && apt-get install -y \
    wget \
    && rm -rf /var/lib/apt/lists/*

# conda 설치
RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh && \
    /bin/bash miniconda.sh -b -p /usr/local/conda && \
    rm miniconda.sh
ENV PATH="/usr/local/conda/bin:$PATH"

# conda 환경 설정
COPY ocr_fastswin.yaml /ocr_fastswin.yaml
RUN conda env create -f /ocr_fastswin.yaml

(대략적인 예시일 뿐 정확한 코드예시는 아니다.)

 

Docker file의 경우 Visual Studio Code 에서 Docker Extension을 설치하게 되면 사용할 수 있는 명령어가 나열되면서 보다 쉽게 Docker file을 작성할 수 있다.

하지만 Docker file을 작성하려면 Docker에 대한 보다 더 깊은 이해가 필요하기 때문에 두 번째 방법을 이용하여 이미지를 구워보고자 한다.

 

 

Base Image 이용 Docker Container 만들기

 

두 번째 방법을 하기 위해서 기존에 했던 OCR 프로젝트 모델을 바탕으로

구현했던 환경과 코드를 이미지로 구워 예시로 추출해보고자 한다.

 

https://hub.docker.com/_/docker

 

docker - Official Image | Docker Hub

Docker Official Images are a curated set of Docker open source and drop-in solution repositories. Why Official Images? These images have clear documentation, promote best practices, and are designed for the most common use cases.

hub.docker.com

 

Official Docker 사이트에 접속하면, 다양한 Base Image들을 다운받을 수 있다.

 

여기서 이미지의 Tag는 해당 이미지의 버전을 의미하며 다양한 버전들이 존재하니 필요한 이미지를 다운받아 사용하면 된다.

이미지를 다운받는 방법은 간단하다.

 

docker pull 이미지이름

 

다음 명령어를 이용하여 바로 사이트에서 이미지를 가져올 수 있다.

 

해당 OCR 모델은 ubuntu 16.04 , nvidia cuda 10.2 버전이 지원되는 GPU와 드라이버가 설치된 환경에서 진행되었다.

 

따라서, ubuntu 16.04를 기반으로 cuda 10.2 버전이 깔려 있는 이미지를 찾아준다.

 

여기서 Tags 란을 보면 10.2에 해당하는 버전이 있을 것이고

Cuda에서 다양한 라이브러리를 사용하고 header 파일을 참조할 예정이라면

base가 아닌 devel 버전을 다운하는 것이 좋다!!

 

(하지만 base와 용량 차이가 매우 크므로 고려해서 설치하는 것이 좋다.)

 

이미지가 제대로 pull 되어있는지 확인하려면

docker images

 

다음과 같은 명령어를 통해 확인한다.

 

그 다음은 아래와 같은 과정을 거치면 된다.

# 도커 이미지 올리기
docker pull nvidia/cuda:10.2-cudnn8-devel-ubuntu16.04

# 도커 컨테이너 생성
docker run --gpus all --name ocr_fastswin -it nvidia/cuda:10.2-cudnn8-devel-ubuntu16.04 /bin/bash

# 로컬의 파일 도커 환경으로 옮기기
docker cp ocr_fastswin.yaml ocr_fastswin:/OCR/

 

Docker Image를 Pull 하고 컨테이너를 생성하고 나면, 필요한 로컬 파일들을 모두 도커 환경으로 옮겨주면 된다.

(명령어는 로컬 터미널에서 실행해야 한다.)

docker cp

 

필자는 모델의 가상환경 라이브러리를 conda를 이용해 yaml 파일로 추출하였고

다시 import 할 생각이기 때문에 Docker Container 내부에 추가로 conda를 설치해주었다.

 

.

.

.

.

(혹시 추가로 Cuda 경로를 설정해야 한다면 > nvidia-smi가 통하지 않거나 nvcc-V가 되지 않는다면?)

아래 코드를 참고하도록 하자.

# 쿠다 경로 설정
export LD_LIBRARY_PATH=/usr/local/cuda-10.2/lib64:$LD_LIBRARY_PATH
source ~/.bashrc

mv * /home/pirl/Desktop/OCR/FAST/

 

 

또한 이미지를 기반으로 컨테이너가 제대로 제작되어 있는지 확인하려면

docker ps -a

(동작이 완료된 컨테이너까지 모두 볼 수 있다.)

 

명령어를 사용하면 된다.

 

Conda 설치

# wget 설치
apt-get update
apt-get install wget

#아나콘다 설치
wget https://repo.anaconda.com/archive/Anaconda3-2023.03-1-Linux-x86_64.sh
chmod +x Anaconda3-2023.03-1-Linux-x86_64.sh
./Anaconda3-2023.03-1-Linux-x86_64.sh

# 아나콘다 경로 설정
export PATH="/root/anaconda3/bin:$PATH"

# 경로 변경내용 저장
source ~/.bashrc

 

추가로 yaml 파일을 바탕으로 아나콘다 가상 환경을 만들어준다.

# 환경 설정
conda env create -f environment.yaml

 

 

컨테이너 파일 이미지 Tar 파일로 추출하기

docker save ocr_fastswin > ocr_fastswin.tar

 

Docker Container 환경을 tar 이미지 파일로 추출하기 위해 사용할 수 있는 명령어는 총 2가지 이다.

 

docker export

 

export를 이용하면 컨테이너 자체를 tar 파일로 보낼 수 있다.

docker save

 

save 를 이용하면 이미지를 tar파일로 보낼 수 있다.

컨테이너 환경을 이미지로 만들고 이를 다시 tar 파일로 보낼려면 아래 과정을 수행하면 된다.

docker commit ocr_fastswin ocr_fastswin:latest
docker save -o ocr_fastswin.tar ocr_fastswin

 

docker commit 컨테이너 이름 이미지 이름
docker save -o 저장할파일이름.tar 이미지 이름

 

docker export를 사용하게 되면 해당 이미지를 다시 컨테이너로 만들기 위해서는

docker import

 

명령어를 사용해야 하며,

 

docker save를 사용한 경우 해당 이미지를 다시 컨테이너로 만들기 위해서는

docker load

 

명령어를 사용하면 된다.

 

 

Docker Image TEST 하기

 

그럼, 만들어진 이미지를 테스트 해보자

 

Docker image로 사용될 tar 파일이 있는 디렉토리에서 터미널을 실행하고

아래 명령어를 입력하여 docker image를 등록한다.

 

docker load -l ocr_fastswin_final.tar

 

아래 명령어를 입력하여 예시 이미지의 REPOSITORY가 동일하게 등록되었는지 확인한다.

docker images

 

 

예시 Docker images

 

 

그 후, 아래 명령어를 이용하여 docker container를 생성한다.

sudo docker run -itd --gpus all --name ocr_fastswin ocr_fastswin_image:latest /bin/bash
docker ps -a

 

를 이용하여 생성된 컨테이너 확인

 

 

컨테이너가 제대로 생성된 것을 확인할 수 있다.

 

 

다음 아래 명령어를 통해 docker 환경에 진입후 모델을 테스트 하면 완료!

docker attach ocr_fastswin

 

(만약, 환경을 종료한 상황이라면 아래 명령어를 입력하여 docker 환경을 재시작한다.)

docker start ocr_fastswin

docker 환경에 제대로 진입된 모습

 

 

후에 모델이 동작하는지 확인하면 Docker 이미지 굽기가 마무리된다! 

제대로 모델이 잘 동작하는 모습

 

 

 


 

 

+ 추가)

 

만약 도커를 돌리다가

 

ERROR: Unexpected bus error encountered in worker. This might be caused by insufficient shared memory (shm).

 

아래와 같은 메모리 부족 경고문이 뜨게 되면 도커 컨테이너 생성시에 

 

sudo docker run -itd --gpus all --ipc=host --name ocr_fastswin ocr_fastswin_image:latest /bin/bash

 

이런 식으로

--ipc=host

 

명령어를 추가로 입력해주면 문제가 해결된다!