ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Docker + Pytorch + GPU로 딥 러닝 개발하기
    개발 환경/Docker 2020. 2. 18. 21:28
    반응형

    https://www.slideshare.net/MichaelDucy/the-future-of-everything-37344357

     

    The Future of Everything

    The Future of Everything

    www.slideshare.net

    Docker의 중요성을 알려주는 슬라이드다. 한 번 감상해보자.

    혼자 개발하고 연구할 때는 Docker의 필요성과 중요성을 느끼지 못한다. 하지만 점점 많은 소프트웨어가 도커라이징되가며 DevOps가 발달해간다. 개발, 도입, 운영을 모두 같은 환경에서 할 수 있다는 것이 바로 Docker의 장점이고 도입해야하는 이유다. 나는 Kubernetes와 Kubeflow에 관심 있는 딥 러닝 개발자로서 Docker를 먼저 공부하기 시작했다. 설치부터 run까지 한번 살펴보자.

     

    0. Docker란?

    https://subicura.com/2017/01/19/docker-guide-for-beginners-1.html

     

    초보를 위한 도커 안내서 - 도커란 무엇인가?

    도커를 처음 접하는 시스템 관리자나 서버 개발자를 대상으로 도커 전반에 대해 얕고 넓은 지식을 담고 있습니다. 도커가 등장한 배경과 도커의 역사, 그리고 도커의 핵심 개념인 컨테이너와 이미지에 대해 알아보고 왜 이렇게 도커가 인기 인지 하나하나 살펴보겠습니다.

    subicura.com

    아직까지 이 글보다 Docker에 대한 더 좋은 글을 찾지 못하였다. 천천히 정독하면 Docker가 무엇인지부터 왜 써야하는지까지 알 수 있다.

     

    1. Docker 설치 및 예제

    https://subicura.com/2017/01/19/docker-guide-for-beginners-2.html

     

    초보를 위한 도커 안내서 - 설치하고 컨테이너 실행하기

    초보를 위한 도커 안내서 2번째 글입니다. 도커의 기본적인 내용을 이야기 했던 첫번째 글에 이어 실제로 도커를 설치하고 컨테이너를 실행하면서 도커 명령어를 알아봅니다. 도커를 처음 접하는 분들을 위해 아주 가볍게 자주 쓰는 명령어를 다루었습니다.

    subicura.com

    https://subicura.com/2017/02/10/docker-guide-for-beginners-create-image-and-deploy.html

     

    초보를 위한 도커 안내서 - 이미지 만들고 배포하기

    이 글은 초보를 위한 도커 안내서 - 설치부터 배포까지 시리즈의 마지막 글입니다. 지난 글에서 도커를 설치하고 컨테이너를 실행해 보았으니 이번엔 이미지를 만들고 서버에 배포해보도록 하겠습니다.

    subicura.com

    이 글들을 모두 클리어하고 오자. 그러면 Docker의 기본 사용법을 모두 알 수 있다.

     

    2. pytorch를 위한 Dockerfile 만들기

    본격적으로 pytorch를 사용하기 위한 docker image를 만들어보자.

    mkdir test
    cd test
    • test라고 디렉토리를 만들고 이동한다.
    • 미리 작성해둔 코드가 있다면 그곳으로 이동한다.

    나는 pytorch 이외에 사용하는 패키지가 더 있어서 추가적으로 설치하는 dockerfile을 제작해보았다.

    vim Dockerfile
    FROM pytorch/pytorch:1.2-cuda10.0-cudnn7-devel
    MAINTAINER sah0322@naver.com
    RUN apt-get -y -qq update && \
        pip install numpy matplotlib librosa
    COPY . .

     

    하나씩 설명하자면,

    FROM pytorch/pytorch:1.2-cuda10.0-cudnn7-devel

    pytorch/pytorch:1.2-cuda10.0-cudnn7-devel을 base image로 선택하였다. 다른 pytorch 이미지에 대해서는 https://hub.docker.com/r/pytorch/pytorch/tags를 참고하자.

    안타깝게도 nvidia-driver는 docker보다 하위 시스템이다. 그러므로 최소 로컬에 nvidia-driver는 설치되어 있어야한다. (사용할 cuda 버전에 맞게)

    MAINTAINER sah0322@naver.com

    사용자(?)를 의미한다.

    RUN apt-get -y -qq update && \
        pip install numpy matplotlib librosa

    업데이트를 한 후 numpy, matplotlib, librosa를 설치한다. (뒤에 나오겠지만 여기서 libsndfile1을 빼먹었다.)

    COPY . .

    앞에 .이 현위치고 뒤에 .이 target이다. 즉 로컬에 코드들을 docker 서버에 복사한다. 사실 저렇게 하면 코드뿐만 아니라 db까지 전부 복사된다. 상관은 없지만 용량이 매우 커지고 코드를 변경할 때마다 db까지 다시 복사하는 그런 오버헤드가 발생할 염려가 크다. 그러므로 저 부분은 차후에 copy가 아니라 mount 시키는 방안으로 수정해볼까 한다.

    이렇게 파일을 작성하면 환경을 구축할 수 있게 된다.

     

    3. Docker image build

    이제 만들어둔 Dockerfile을 가지고 build를 해보자.

    docker build -t spoken_language_idenfication .

    -t는 tag를 정하는 옵션이다. 뒤에 .은 현 디렉토리를 의미한다.

    output:

    Sending build context to Docker daemon   11.6GB
    Step 1/5 : FROM pytorch/pytorch:1.2-cuda10.0-cudnn7-devel
    1.2-cuda10.0-cudnn7-devel: Pulling from pytorch/pytorch
    f7277927d38a: Pull complete
    8d3eac894db4: Pull complete
    edf72af6d627: Pull complete
    3e4f86211d23: Pull complete
    d6e9603ff777: Pull complete
    5cad422780e2: Pull complete
    8130687c8acb: Pull complete
    c11e9246d621: Pull complete
    0dfae24cbbd9: Pull complete
    0bb049a6d391: Pull complete
    8aae89f7c055: Pull complete
    d44fbafaedc4: Pull complete
    3065b56b2e9a: Pull complete
    c195c6ae1d54: Pull complete
    9b967434589a: Pull complete
    Digest: sha256:4bc7330797776866cd5361da4ba39d16937da4a3211733a3e47f304e80f86947
    Status: Downloaded newer image for pytorch/pytorch:1.2-cuda10.0-cudnn7-devel
     ---> 22645c78dd69
    Step 2/5 : MAINTAINER sah0322@naver.com
     ---> Running in f87a39c7540d
    Removing intermediate container f87a39c7540d
     ---> ea89d10f362b
    Step 3/5 : RUN apt-get -y -qq update &&     pip install numpy matplotlib librosa
     ---> Running in 8385c0f5230b
    Requirement already satisfied: numpy in /opt/conda/lib/python3.6/site-packages (1.16.5)
    Collecting matplotlib
      Downloading https://files.pythonhosted.org/packages/7e/07/4b361d6d0f4e08942575f83a11d33f36897e1aae4279046606dd1808778a/matplotlib-3.1.3-cp36-cp36m-manylinux1_x86_64.whl (13.1MB)
    Collecting librosa
      Downloading https://files.pythonhosted.org/packages/77/b5/1817862d64a7c231afd15419d8418ae1f000742cac275e85c74b219cbccb/librosa-0.7.2.tar.gz (1.6MB)
    Collecting pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 (from matplotlib)
      Downloading https://files.pythonhosted.org/packages/5d/bc/1e58593167fade7b544bfe9502a26dc860940a79ab306e651e7f13be68c2/pyparsing-2.4.6-py2.py3-none-any.whl (67kB)
    Collecting python-dateutil>=2.1 (from matplotlib)
      Downloading https://files.pythonhosted.org/packages/d4/70/d60450c3dd48ef87586924207ae8907090de0b306af2bce5d134d78615cb/python_dateutil-2.8.1-py2.py3-none-any.whl (227kB)
    Collecting kiwisolver>=1.0.1 (from matplotlib)
      Downloading https://files.pythonhosted.org/packages/f8/a1/5742b56282449b1c0968197f63eae486eca2c35dcd334bab75ad524e0de1/kiwisolver-1.1.0-cp36-cp36m-manylinux1_x86_64.whl (90kB)
    Collecting cycler>=0.10 (from matplotlib)
      Downloading https://files.pythonhosted.org/packages/f7/d2/e07d3ebb2bd7af696440ce7e754c59dd546ffe1bbe732c8ab68b9c834e61/cycler-0.10.0-py2.py3-none-any.whl
    Collecting audioread>=2.0.0 (from librosa)
      Downloading https://files.pythonhosted.org/packages/2e/0b/940ea7861e0e9049f09dcfd72a90c9ae55f697c17c299a323f0148f913d2/audioread-2.1.8.tar.gz
    Collecting scipy>=1.0.0 (from librosa)
      Downloading https://files.pythonhosted.org/packages/dc/29/162476fd44203116e7980cfbd9352eef9db37c49445d1fec35509022f6aa/scipy-1.4.1-cp36-cp36m-manylinux1_x86_64.whl (26.1MB)
    Collecting scikit-learn!=0.19.0,>=0.14.0 (from librosa)
      Downloading https://files.pythonhosted.org/packages/d1/48/e9fa9e252abcd1447eff6f9257636af31758a6e46fd5ce5d3c879f6907cb/scikit_learn-0.22.1-cp36-cp36m-manylinux1_x86_64.whl (7.0MB)
    Collecting joblib>=0.12 (from librosa)
      Downloading https://files.pythonhosted.org/packages/28/5c/cf6a2b65a321c4a209efcdf64c2689efae2cb62661f8f6f4bb28547cf1bf/joblib-0.14.1-py2.py3-none-any.whl (294kB)
    Requirement already satisfied: decorator>=3.0.0 in /opt/conda/lib/python3.6/site-packages (from librosa) (4.4.0)
    Requirement already satisfied: six>=1.3 in /opt/conda/lib/python3.6/site-packages (from librosa) (1.12.0)
    Collecting resampy>=0.2.2 (from librosa)
      Downloading https://files.pythonhosted.org/packages/79/75/e22272b9c2185fc8f3af6ce37229708b45e8b855fd4bc38b4d6b040fff65/resampy-0.2.2.tar.gz (323kB)
    Collecting numba>=0.43.0 (from librosa)
      Downloading https://files.pythonhosted.org/packages/ba/49/61522f34b1333aa4e9aa02005dc0774d25bd234400dff718b16615d6a744/numba-0.48.0-cp36-cp36m-manylinux1_x86_64.whl (2.5MB)
    Collecting soundfile>=0.9.0 (from librosa)
      Downloading https://files.pythonhosted.org/packages/eb/f2/3cbbbf3b96fb9fa91582c438b574cff3f45b29c772f94c400e2c99ef5db9/SoundFile-0.10.3.post1-py2.py3-none-any.whl
    Requirement already satisfied: setuptools in /opt/conda/lib/python3.6/site-packages (from kiwisolver>=1.0.1->matplotlib) (41.0.1)
    Collecting llvmlite<0.32.0,>=0.31.0dev0 (from numba>=0.43.0->librosa)
      Downloading https://files.pythonhosted.org/packages/ad/bb/60d4033d56c9da36490af19caa6c794b72b8aef6f792fdfa8cb95d11e419/llvmlite-0.31.0-cp36-cp36m-manylinux1_x86_64.whl (20.2MB)
    Requirement already satisfied: cffi>=1.0 in /opt/conda/lib/python3.6/site-packages (from soundfile>=0.9.0->librosa) (1.12.3)
    Requirement already satisfied: pycparser in /opt/conda/lib/python3.6/site-packages (from cffi>=1.0->soundfile>=0.9.0->librosa) (2.19)
    Building wheels for collected packages: librosa, audioread, resampy
      Building wheel for librosa (setup.py): started
      Building wheel for librosa (setup.py): finished with status 'done'
      Created wheel for librosa: filename=librosa-0.7.2-cp36-none-any.whl size=1612885 sha256=c95e67d4f1e353bba4d09bdab6a36d6b122abd8bbf58d850f02f5d326b0ffe12
      Stored in directory: /root/.cache/pip/wheels/4c/6e/d7/bb93911540d2d1e44d690a1561871e5b6af82b69e80938abef
      Building wheel for audioread (setup.py): started
      Building wheel for audioread (setup.py): finished with status 'done'
      Created wheel for audioread: filename=audioread-2.1.8-cp36-none-any.whl size=23092 sha256=9ed6d4ad8dce318f72d9c3265260e9e9bcf674ae6cc0cc4b3c5f5beaf43abfd1
      Stored in directory: /root/.cache/pip/wheels/b9/64/09/0b6417df9d8ba8bc61a7d2553c5cebd714ec169644c88fc012
      Building wheel for resampy (setup.py): started
      Building wheel for resampy (setup.py): finished with status 'done'
      Created wheel for resampy: filename=resampy-0.2.2-cp36-none-any.whl size=320719 sha256=85719752246192b84d346ba2116f4979f58276c1f2928db097d3eadaa853d1c6
      Stored in directory: /root/.cache/pip/wheels/fa/c1/56/e0e12c6f7f3d2cdea9712b35136a2d40a7817c6210ec096485
    Successfully built librosa audioread resampy
    Installing collected packages: pyparsing, python-dateutil, kiwisolver, cycler, matplotlib, audioread, scipy, joblib, scikit-learn, llvmlite, numba, resampy, soundfile, librosa
    Successfully installed audioread-2.1.8 cycler-0.10.0 joblib-0.14.1 kiwisolver-1.1.0 librosa-0.7.2 llvmlite-0.31.0 matplotlib-3.1.3 numba-0.48.0 pyparsing-2.4.6 python-dateutil-2.8.1 resampy-0.2.2 scikit-learn-0.22.1 scipy-1.4.1 soundfile-0.10.3.post1
    Removing intermediate container 8385c0f5230b
     ---> a034db0e4253
    Step 4/5 : COPY . .
     ---> 3f75ede4ec31
    Step 5/5 : CMD sh run_crnn.sh
     ---> Running in f87a7a16a629
    Removing intermediate container f87a7a16a629
     ---> f37ef7ccbc31
    Successfully built f37ef7ccbc31
    Successfully tagged spoken_language_idenfication:latest

    정말 길다. 자세히 보면 Step 5/5까지 진행되는데 이게 미리 작성해둔 Dockerfile대로 진행되는 과정이다. 마지막에 Successfully built ...라고 나오면 성공적으로 생성된 것이다.

    docker images

    output:

    REPOSITORY                     TAG                         IMAGE ID            CREATED             SIZE
    spoken_language_idenfication   latest                      f37ef7ccbc31        36 seconds ago      18.5GB

    프로젝트에 DB까지 다 복사했더니 용량이 어마어마하다...

    4. run pytorch image

    이제 파이썬 파일을 돌려보자. 이번 차례에서 성공하지 않는다. 기록을 위한 목적을 가진 글이므로 시행착오가 다 담겨져 있다.

    docker run -it spoken_language_idenfication:latest /bin/bash

    -it는 터미널에 입출력을 위한 옵션이다. image의 REPOSITORY 이름과 TAG를 쓰고 마지막에 실행할 명령어를 쓴다. 터미널을 사용하기 위해 /bin/bash를 입력하였다.

    root@6fe541dbdda4:/workspace# ls

    output:

    Dockerfile  README.md    dataset    log        models  result.py    run_crnn.sh  run_dnn.sh  util.py
    LICENSE     __pycache__  loader.py  logger.py  result  run_crnn.py  run_dnn.py   save_model  wavio.py

    프로젝트의 코드들이 모두 복사되었다. (코드는 https://github.com/HanSeokhyeon/Spoken_language_idenfication... star좀...)

     

    5. run python

    root@6fe541dbdda4:/workspace# sh run_crnn.sh

    저 shell 파일 안에는 python을 실행하는 스크립트가 담겨있다.

    output:

    Traceback (most recent call last):
      File "./run_crnn.py", line 28, in <module>
        from loader import *
      File "/workspace/loader.py", line 26, in <module>
        import librosa
      File "/opt/conda/lib/python3.6/site-packages/librosa/__init__.py", line 12, in <module>
        from . import core
      File "/opt/conda/lib/python3.6/site-packages/librosa/core/__init__.py", line 126, in <module>
        from .audio import *  # pylint: disable=wildcard-import
      File "/opt/conda/lib/python3.6/site-packages/librosa/core/audio.py", line 10, in <module>
        import soundfile as sf
      File "/opt/conda/lib/python3.6/site-packages/soundfile.py", line 142, in <module>
        raise OSError('sndfile library not found')
    OSError: sndfile library not found

    이렇게 패키지를 까먹으면 안된다.

    root@6fe541dbdda4:/workspace# apt-get install libsndfile1

    차후에는 Dockerfile에 수정하였다.

    다시 돌려보았다.

    output:

    [2020-02-18 11:32:48,131 util.py:10 - download_data()] TIMIT already exists
    [2020-02-18 11:32:48,131 util.py:49 - download_data()] Korean DB already exists
    [2020-02-18 11:32:48,937 run_crnn.py:261 - main()] start
    [2020-02-18 11:32:48,938 run_crnn.py:47 - train()] train() start
    [2020-02-18 11:32:54,903 run_crnn.py:100 - train()] batch:    0/1848, loss: 0.7055, elapsed: 5.96s 0.10m 0.00h
    [2020-02-18 11:33:23,683 run_crnn.py:100 - train()] batch:   10/1848, loss: 0.4744, elapsed: 28.78s 0.58m 0.01h

    돌아는 간다. 하지만 nvidia-smi로 확인해보니 GPU는 가만히 있고 CPU만 엄청 돌아가는 것을 확인하였다. 찾아보니깐 docker로 gpu를 사용하기 위해선 docker대신 nvidia-docker를 사용해야한다.

     

    6. nvidia-docker 설치 및 확인

    https://www.quantumdl.com/entry/PyTorchTensorflow를-위한-Docker-시작하기

     

    PyTorch/Tensorflow를 위한 Docker 시작하기

    Intro ML/DL을 위해 PyTorch/Tensorflow를 사용할 경우, Docker를 반드시 사용할 필요는 없습니다. 실제로 저도 여태까지는 Docker 없이 모든 작업을 잘 해왔고, 크게 불편한 점은 없었습니다. 하지만, 최근 모두..

    www.quantumdl.com

    이 글에서 nvidia-docker 설치하는 방법을 친절하게 설명해준다. 설치를 다했으면 다시 시도해보자.

    nvidia-docker run -it spoken_language_idenfication:latest /bin/bash

    아까 명령어에서 nvidia-만 추가되었다.

    root@e53d0de34011:/workspace# nvidia-smi

    output:

    Tue Feb 18 11:40:32 2020
    +-----------------------------------------------------------------------------+
    | NVIDIA-SMI 430.50       Driver Version: 430.50       CUDA Version: 10.1     |
    |-------------------------------+----------------------+----------------------+
    | GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
    | Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
    |===============================+======================+======================|
    |   0  GeForce GTX 1070    Off  | 00000000:01:00.0 Off |                  N/A |
    |  0%   30C    P8     6W / 166W |     21MiB /  8117MiB |      0%      Default |
    +-------------------------------+----------------------+----------------------+
    
    +-----------------------------------------------------------------------------+
    | Processes:                                                       GPU Memory |
    |  GPU       PID   Type   Process name                             Usage      |
    |=============================================================================|
    +-----------------------------------------------------------------------------+

    GPU가 확인되었다. 

     

    7. 다시 run python...

    root@6fe541dbdda4:/workspace# sh run_crnn.sh

    돌린 후 서버에서 nvidia-smi로 확인해보니

    Tue Feb 18 21:22:57 2020
    +-----------------------------------------------------------------------------+
    | NVIDIA-SMI 430.50       Driver Version: 430.50       CUDA Version: 10.1     |
    |-------------------------------+----------------------+----------------------+
    | GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
    | Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
    |===============================+======================+======================|
    |   0  GeForce GTX 1070    Off  | 00000000:01:00.0 Off |                  N/A |
    |  0%   38C    P2   135W / 166W |   6374MiB /  8117MiB |      6%      Default |
    +-------------------------------+----------------------+----------------------+
    
    +-----------------------------------------------------------------------------+
    | Processes:                                                       GPU Memory |
    |  GPU       PID   Type   Process name                             Usage      |
    |=============================================================================|
    |    0      1441      G   /usr/lib/xorg/Xorg                             9MiB |
    |    0      1502      G   /usr/bin/gnome-shell                           9MiB |
    |    0     30183      C   python                                      6343MiB |
    +-----------------------------------------------------------------------------+

    잘 돌아가는 것을 확인할 수 있었다.

     

    8. 정리하며..

    docker로 pytorch 돌리는 것은 성공하였다. 하지만 제대로 개발을 하기 위해서는 디버깅이 필요하다. 그래서 다음번엔 Pycharm professional + Docker + Pytorch로 도전해볼 계획이다.

    반응형
Designed by Tistory.