10/23/2019

NVIDIA Docker 기반의 Tensorflow 설치 및 기본테스트 (1차 분석)

1. NVIDIA Docker 사용목적 


NVIDIA Docker는 Docker-CE와 기능은 기본적으로 동일하지만, 기존 Docker가 GPU를 이용하지 못했기 때문에, NVIDIA Docker가 필요하게되었다.
하지만, Docker 19.03 부터는 GPU 사용가능 기능이 추가된 것 같으며,  필요한 Library를 설치한 후 사용하면 될것으로 생각되어진다.
별도의 nvidia-docker2를 이용해도 문제는 없을 것으로 생각되어진다.


기존 Docker 사용법 
  https://ahyuo79.blogspot.com/2018/05/docker.html


1.1 NVIDIA Docker 설치 및 설정 

설치방법 아래 참조
  https://github.com/NVIDIA/nvidia-docker

관련부분 참조
  https://github.com/JeonghunLee/NVIDIA_SDK

  • Docker의 권한설정
매번 sudo를 해야하기 때문에 아래와 같이 USER를 등록을 하자
$ sudo usermod -aG docker $USER 
$ sudo systemctl restart docker

1.2 일반 Docker 명령어 확인 

지금까지 Docker를 쉽게 설치해보고, Docker 문서에 따라 쉽게 Dockerfile을 만들어 보았지만, 
이 DockerFile를 직접 적극적으로 활용해서 응용하여 사용해 본적이 거의 없는 것 같다.

  • NVIDIA Docker 관련문서 (Docker 문서로 가장추천)
아래의 PDF를 보며 쉽게 Docker 명령어가 이해가며, 사용법도 쉽게 익히자
아래의 문서는 DGX에서 사용되어지는 Docker관련문서이다.
  https://www.nvidia.co.kr/content/apac/event/kr/deep-learning-day-2017/dli-1/Docker-User-Guide-17-08_v1_NOV01_Joshpark.pdf




  • Docker 전체구조 
Linux에서 Docker 설치 후 아래의 그림에서 각 명령어를 보면 쉽게 이해를 할 수 있다.

Docker Hub


상위 그림으로 전체 docker의 명령어를 쉽게 이해 할 수 있다.

  • 각  Docker 명령어는  관련부분 옵션확인 
$ docker version  // Docker version 확인 19.03.4 사용 
$ docker help // 모든 command 명령확인 

Management Commands:
  builder     Manage builds
  config      Manage Docker configs
  container   Manage containers
  context     Manage contexts
  engine      Manage the docker engine
  image       Manage images
  network     Manage networks
  node        Manage Swarm nodes
  plugin      Manage plugins
  secret      Manage Docker secrets
  service     Manage services
  stack       Manage Docker stacks
  swarm       Manage Swarm
  system      Manage Docker
  trust       Manage trust on Docker images
  volume      Manage volumes

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  build       Build an image from a Dockerfile
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  deploy      Deploy a new stack or update an existing stack
  diff        Inspect changes to files or directories on a container's filesystem
  events      Get real time events from the server
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  history     Show the history of an image
  images      List images
  import      Import the contents from a tarball to create a filesystem image
  info        Display system-wide information
  inspect     Return low-level information on Docker objects
  kill        Kill one or more running containers
  load        Load an image from a tar archive or STDIN
  login       Log in to a Docker registry
  logout      Log out from a Docker registry
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  ps          List containers
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  run         Run a command in a new container
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  search      Search the Docker Hub for images
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  version     Show the Docker version information
  wait        Block until one or more containers stop, then print their exit codes


$ docker COMMAND --help  // 개별 Command의 옵션들을 확인하자 
$ docker run         // Image를 가지고 와서 Container를 생성하고 이를 실행  (exit를 하면 container 종료)
$ docker attach      // run으로 Container로 생성된 container에 접속이가능 (주의, Exit 하게 될 경우 , container 종료)
$ docker images      // 현재 가지고 있는 docker Images들의 정보확인 
$ docker status      // 현재 동작중인 container   세부정보확인 (CPU/MEM 정보)
$ docker ps -a       // 현재 동작중인 container의 정보확인  

Tensorflow의 Docker 설치법
  https://www.tensorflow.org/install/docker?hl=ko


1.3 Docker Container 의 종료 혹은 임시 나오기 

Docker의 Container를 만들고 실행을 attach 모드를 사용하여 진입을 했을 경우, 내부에서 exit를 명령을 하면, Container는 종료되고 나온다.
물론 아래의 terminal 관련옵션을 설정했을 때 일이므로, 주의하자.
Terminal 모드로 동작 중인 Container에서 종료하지 말고 빠져나오는 방법은 이 때 봐야할 것이 run의 옵션이므로 이 부분을 자세히 보자


container 내부에서 명령어 exit 종료

  • docker run 옵션 
  1. - t 옵션 shell 에서 container의 default shell의 stdout을 볼 수 있다. 
  2. - i 옵션 shell 의 input key이 container에 입력이 되도록 한다 
  3. -d 옵션 detach mode로 background로 실행 




  • docker run -t -i  or -ti or -it 
결론적으로 기본적으로 attach(foreground mode)로 동작하며, container의 default shell로 실행이 동작가능하다
만약 -d 옵션을 주어 detach mode(Background mode)로 동작하며, 추후 docker attach 로 접속가능

  1. 종료방법: container shell 에서 직접 exit 입력  (default shell 만 존재할 경우 container도 동시 종료)
  2. 종료하지 않고 나오기:  [Ctrl + P] + [Ctrl + Q]로  빠져나옴  

  • docker run -i  or docker run 
Container terminal 모드로 들어간 것이 아니므로, container의 default shell 실행이 안됨
[Ctrl + P] + [Ctrl + Q] 사용못함


참고사항
  http://egloos.zum.com/sstories/v/9731853


1.4  Host에서  Docker Container를 접속방법 
    외부 일반 터미널 혹은 Background로 돌려 각 Container를 접속하고자 한다면,  attach를 사용
    상위에서 이름을 정하지 않았기 때문에 아래와 같이 Random으로 생성되므로, 이를 파악하여 접속

    Container는 Process가 하나로 동작되기 때문에, 만약 상위에 이미 접속중이고, 다시 아래와 같이 접속하면 동일한 화면을 볼수가 있다


    $ docker ps -a
    CONTAINER ID        IMAGE                                 COMMAND                  CREATED             STATUS              PORTS                          NAMES
    e0d05f676eb4        nvcr.io/nvidia/tensorflow:19.08-py3   "/usr/local/bin/nvid…"   8 seconds ago       Up 7 seconds        6006/tcp, 6064/tcp, 8888/tcp   hungry_faraday
    
    //docker run 에서 Portmapping을 하기전에 PORTS를 보면 사용되어지는 PORT를 알수 있다. 
    
    $ docker attach hungry_faraday
    root@650519457d6f:/workspace#  exit // exit 하면 docker container가 종료 
    


    • exec로 bash를 실행하여 process 추가 
    이렇게 접속을 하고,  exit로 빠져나와도 기존에 남아 있는 default shell process가 존재하기 때문에 문제 없음 ( docker run -it 옵션을 했을 경우)

    $ docker ps -a
    [sudo] password for jhlee: 
    CONTAINER ID        IMAGE                                 COMMAND                  CREATED             STATUS              PORTS                                                      NAMES
    7438ab2813a1        nvcr.io/nvidia/tensorflow:19.08-py3   "/usr/local/bin/nvid…"   45 minutes ago      Up 45 minutes       0.0.0.0:6006->6006/tcp, 0.0.0.0:8888->8888/tcp, 6064/tcp   tensorflow
    
    
    $ docker exec -it tensorflow /bin/bash 
    root@650519457d6f:/workspace#  // exit 하면 docker 종료되며 상위와 동일 
    


    Host Docker Container 접속
      https://bluese05.tistory.com/21


    Docker 사용법 참고
      https://devyurim.github.io/python/tensorflow/development%20enviroment/docker/2018/05/25/tensorflow-3.html
      https://noanswercode.tistory.com/11
      https://handcoding.tistory.com/203

    2. Tensorflow Docker 설치 및 테스트 진행 

    현재 NVIDIA에서는 기존에 GPU가 사용가능한 DOCKER인 NVIDIA-DOCKER를 제공을 했지만, DOCKER-CE 19.03 부터, 이제 불필요해진 것 같다.

    NVIDIA Docker 관련내용
      https://docs.nvidia.com/deeplearning/frameworks/user-guide/index.html#enable-gpu-support



    2.1  Docker Tensorflow 설치 및 기본실행 

    • NGC(NVIDIA GPU CLOUD) 관련문서 
    Docker Pull하기위해서 아래의 Manual을 참조
      https://docs.nvidia.com/deeplearning/frameworks/user-guide/index.html#pullcontainer
      https://docs.nvidia.com/deeplearning/frameworks/user-guide/index.html#runcont

    • Tensorflow 설치 및 실행 관련사이트 
      https://ngc.nvidia.com/catalog/containers/nvidia:tensorflow


    • Tensorflow Version 
      https://tensorflow.blog/category/tensorflow/


    • Docker Run 사용법
    docker run의 기본사용법 
    $ docker run options image:tags  //기본동작 
    $ docker run --help  //option 확인 
    $ docker run --gpus all  // GPU 사용 
                 -it         // intereactive mode로 이 부분은 상위 빠져나오기할때도 중요 
                 --rm        // container가 종료되며 자동으로 삭제 
                 -p Host-port:Container-Port  // Host 와 Container Portmapping 
                 -v HOST:Container            // Host 와 Container의 Mount를 하여 공유가능 
                 --name string     // 만약 name 옵션을 주지 않는다면, docker가 임의로 이름생성              
    


    • Docker Pull Container (GPU사용가능)
    상위 사이트에서 제공해주는 tensorflow의 Image를 pull 하여 이를 TEST를 진행하자.

    $ docker pull nvcr.io/nvidia/tensorflow:19.08-py3  


    • Docker 기반의 Tensorflow 기본 테스트 
    Docker를 이용하여 NVIDIA에서 제공하는 Tensorflow를 Container 가져와서 기본적인 테스트와 무슨기능이 있는지 대충 알아보자.

    $ docker run --gpus all -it --rm  \
    nvcr.io/nvidia/tensorflow:19.08-py3
    
    ================
    == TensorFlow ==
    ================
    
    NVIDIA Release 19.08 (build 7791926)
    TensorFlow Version 1.14.0
    
    Container image Copyright (c) 2019, NVIDIA CORPORATION.  All rights reserved.
    Copyright 2017-2019 The TensorFlow Authors.  All rights reserved.
    
    Various files include modifications (c) NVIDIA CORPORATION.  All rights reserved.
    NVIDIA modifications are covered by the license terms that apply to the underlying project or file.
    
    NOTE: MOFED driver for multi-node communication was not detected.
          Multi-node communication performance may be reduced.
    
    NOTE: The SHMEM allocation limit is set to the default of 64MB.  This may be
       insufficient for TensorFlow.  NVIDIA recommends the use of the following flags:
       nvidia-docker run --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 ...
    
    root@650519457d6f:/workspace# 
    root@650519457d6f:/workspace#  
    root@650519457d6f:/workspace# python      // Tensorflow 동작확인 
    >>> import tensorflow as tf
    >>> hello = tf.constant('Hello, TensorFlow!')
    >>> sess = tf.Session()
    >>> sess.run(hello)
    Hello, TensorFlow!
    >>> a = tf.constant(10)
    >>> b = tf.constant(32)
    >>> sess.run(a+b)
    42
    
    root@650519457d6f:/workspace#  find / -name cuda*  
    .....
    // cuda version 및 관련부분 확인 
    // tf-trt 예제도 확인가능  (Tensorflow-TensorRT)
    root@650519457d6f:/workspace# ll /usr/local/cuda-10.1/bin/    // CUDA GDB와 nvcc 확인 
    ....
    root@650519457d6f:/workspace# find / -name tensorrt*   // tensorrt version 및 관련사항 확인  
    .....
    // tensorrt 및 관련부분 확인 
    // 기타 UFF convert 및 관련사항 확인
    
    root@650519457d6f:/workspace# exit  // exit 하면 docker container가 종료되므로 삭제되며, docker ps 에서 찾을 수 없음 
    


    exit를 하면 container가 종료가 되어 본인이 생성했거나, 저장된 정보들이 모두 삭제된다.
    만약 유지하고 싶다면 상위 옵션에서 변경

    • 상위의  Docker에서 Tensorflow 필요한 Pakcage들을 확인
    1. cuda
    2. tensorrt 
    3. convert-to-uff

    2.2  Tensorboard 와 Jupyter notebook TEST 진행 

    Tensorflow기반에서 Tensorboard 와 Jupyter 관련부분 테스트 

     $ docker run --gpus all -it --rm  \
    -p 8888:8888 -p 6006:6006  \
    --name tensorflow \
    nvcr.io/nvidia/tensorflow:19.08-py3
    
    ================
    == TensorFlow ==
    ================
    
    NVIDIA Release 19.08 (build 7791926)
    .....
    
    //Tensorboard TEST 진행 기본 6006
    root@7438ab2813a1:/workspace#  tensorboard --logdir=/tmp
    or 
    root@7438ab2813a1:/workspace#  tensorboard --logdir=/tmp --port=8008  // Port를 변경하고자 한다면 
    //아래의 Host Browser에서 확인하고 Ctrl+C 중지 
    
    root@7438ab2813a1:/workspace#  jupyter notebook
    token 정보를 봐서 입력하여 로그인
    
    //아래의 Host Browser에서 확인하고 Ctrl+C 중지  
    


    • Docker 에서 상위 기능확인 
    HOST Browser에서 아래의 링크로 각각 확인을 해보자

    Tensorboard
      http://localhost:6006/

    Jupyter notebook
      http://localhost:8888/


    2.3 NVIDIA Tensorflow 구성확인

    • Host 와 Container의 Workspace 공유 
    Docker에 들어가기전에 아래와 같이 미리 HOST Directory 생성 후 Container로 진입하며, workspace를 공유하기위해서 mount 추가

     $ docker run --gpus all -it --rm  \
    -p 8888:8888 -p 6006:6006  \
    --name tensorflow \
    -v /home/jhlee/works/dockers/tensorflow/Workspace:/Workspace \
    nvcr.io/nvidia/tensorflow:19.08-py3
    ........
    root@55e1bf3c0391:/workspace# ls /Workspace   // 원래 Workspace directory는 없음 
    root@55e1bf3c0391:/workspace# cp -a * /Workspace
    root@55e1bf3c0391:/workspace# ls /Workspace    // 전부 Host로 복사완료 
    README.md  docker-examples  nvidia-examples
    


    • Host에서 NVIDIA Example  전체 구조확인 
    Host에서 NVIDIA Example을 간단히 기본구조를 확인가능하며 아래의 README.md가 있는 걸로 봐서 어디의 Github에 저장되어있는것 같은데 아직모름

    $ cd /home/jhlee/works/dockers/tensorflow/Workspace
    $ tree -L2 
    .
    ├── docker-examples
    │   ├── Dockerfile.addpackages            // DOCKER FILE로 Host에서 docker build를 확장 
    │   └── Dockerfile.customtensorflow       // DOCKER FILE로 Host에서 docker build를 확장
    ├── nvidia-examples        // 각 Model의 Example 
    │   ├── bert
    │   ├── big_lstm
    │   ├── build_imagenet_data
    │   ├── cnn
    │   ├── gnmt_v2
    │   ├── NCF
    │   ├── OpenSeq2Seq
    │   ├── resnet50v1.5
    │   ├── ssdv1.2             // 눈이 익은 이것을  SSD를 테스트를 진행해보자 
    │   ├── tensorrt
    │   ├── Transformer_TF
    │   ├── UNet_Industrial
    │   └── UNet_Medical
    └── README.md 


    2.4  Docker Dockerfile 수정 과 Image 생성 

    • Dockerfile 확인 및 수정  
    상위 Dockerfile에서 본인이 변경하고자 하는 것이 있으면 수정하여 사용하자 

    $ cd docker-examples
    $ cat Dockerfile.addpackages  //nvcr.io/nvidia/tensorflow:19.08-py3 기반으로 추가 Package  
    
    FROM nvcr.io/nvidia/tensorflow:19.08-py3
    
    # Install my-extra-package-1 and my-extra-package-2
    RUN apt-get update && apt-get install -y --no-install-recommends \
            my-extra-package-1 \
            my-extra-package-2 \
          && \
        rm -rf /var/lib/apt/lists/
    
    
    $ cat Dockerfile.customtensorflow  // 동일하며, 본인이 원하는 것을 추가하여 Image를 생성해도 될 것 같다. 
    
    FROM nvcr.io/nvidia/tensorflow:19.08-py3
    
    # Bring in changes from outside container to /tmp
    # (assumes my-tensorflow-modifications.patch is in same directory as Dockerfile)
    COPY my-tensorflow-modifications.patch /tmp
    
    # Change working directory to TensorFlow source path
    WORKDIR /opt/tensorflow
    
    # Apply modifications
    RUN patch -p1 < /tmp/my-tensorflow-modifications.patch
    
    # Rebuild TensorFlow for python 2 and 3
    RUN ./nvbuild.sh --python2
    RUN ./nvbuild.sh --python3
    
    # Reset default working directory
    WORKDIR /workspace

    본인이 원하면, nvcr.io/nvidia/tensorflow:19.08-py3 기반으로 Dockerfile을 이용하여 Image를 생성하여 본인만의 Tensorflow Image를 생성 및 구성가능


    • Docker Image 생성방법 

    $ docker build . -t my_images  // Dockerfile 위치가서 -t name or 'name:tag' image 생성가능 


    2.5  Tensorflow의 SSDv1.2  기본분석 

    처음 NVIDIA의 Tensorflow의 SSD를 Training을 하기 위해서 README.md를 보면서 이해가 가지 않았다.
    그래서 어쩔수 없이 소스를 분석을 해보기로 했다.

    • Host에서 README.md 확인
    README.md는 Github에서 사용하는 것으로 처음 이것 때문에 사용해야하는 절차가 헷갈렸다.
    이 것을 보면, Github의 내용처럼 동일하다.

    $ cd /home/jhlee/works/dockers/tensorflow/Workspace
    $ cd nvidia-examples/ssdv1.2#
    $ ls 
    Dockerfile  NOTICE  README.md  configs  download_all.sh  examples  img  models  qa  requirements.txt
    


    상위 SSD가 아래의 Github와 동일
      https://github.com/NVIDIA/DeepLearningExamples/tree/master/TensorFlow/Detection/SSD

    이밖에 NVIDIA DeepLearning 다른 Example 확인가능
      https://github.com/NVIDIA/DeepLearningExamples


    • HOST에서 아래와 같이 Dockerfile을 확인  및 비교 
    $ cat Dockerfile  // Dockerfile을 보면 19.05 image 기반으로 더 추가하여 설치를 한다음 각각의 구성한다. 
    FROM nvcr.io/nvidia/tensorflow:19.05-py3 as base
    
    FROM base as sha
    
    RUN mkdir /sha
    RUN cat `cat HEAD | cut -d' ' -f2` > /sha/repo_sha
    
    FROM base as final
    
    WORKDIR /workdir
    
    RUN PROTOC_VERSION=3.0.0 && \
        PROTOC_ZIP=protoc-${PROTOC_VERSION}-linux-x86_64.zip && \
        curl -OL https://github.com/google/protobuf/releases/download/v$PROTOC_VERSION/$PROTOC_ZIP && \
        unzip -o $PROTOC_ZIP -d /usr/local bin/protoc && \
        rm -f $PROTOC_ZIP
    
    COPY requirements.txt .
    RUN pip install Cython
    RUN pip install -r requirements.txt
    
    WORKDIR models/research/
    COPY models/research/ .
    RUN protoc object_detection/protos/*.proto --python_out=.
    ENV PYTHONPATH="/workdir/models/research/:/workdir/models/research/slim/:$PYTHONPATH"
    
    COPY examples/ examples
    COPY configs/ configs/
    COPY download_all.sh download_all.sh
    
    COPY --from=sha /sha .   


    결론은  nvcr.io/nvidia/tensorflow:19.05-py3 기반으로 base Image 만들고, 이를 다시 sha로 변경 후 각각의 새로운 Package들을 추가해서 새로운 Image를 생성한다.
      https://github.com/NVIDIA/DeepLearningExamples/blob/master/TensorFlow/Detection/SSD/Dockerfile


    • download.sh 비교 
    구성을 보면 각각의 DATASET을 Download와 Directory 구성후 tf_record를 만든다.
    1. $1 : 1st Arg    Container name 
    2. $2:  2nd Arg /data/coco2017_tfrecords 의 root path
    3. $3:  3rd Arg  /checkpoints 의 root path 

    $ cat download_all.sh
    if [ -z $1 ]; then echo "Docker container name is missing" && exit 1; fi
    CONTAINER=$1
    COCO_DIR=${2:-"/data/coco2017_tfrecords"}
    CHECKPOINT_DIR=${3:-"/checkpoints"}
    mkdir -p $COCO_DIR
    chmod 777 $COCO_DIR
    cd $COCO_DIR
    curl -O http://images.cocodataset.org/zips/train2017.zip; unzip train2017.zip
    curl -O http://images.cocodataset.org/zips/val2017.zip; unzip val2017.zip
    curl -O http://images.cocodataset.org/annotations/annotations_trainval2017.zip; unzip annotations_trainval2017.zip
    # Download backbone checkpoint
    mkdir -p $CHECKPOINT_DIR
    chmod 777 $CHECKPOINT_DIR
    cd $CHECKPOINT_DIR
    wget http://download.tensorflow.org/models/resnet_v1_50_2016_08_28.tar.gz
    tar -xzf resnet_v1_50_2016_08_28.tar.gz
    mkdir -p resnet_v1_50
    mv resnet_v1_50.ckpt resnet_v1_50/model.ckpt
    nvidia-docker run --rm -it -u 123 -v $COCO_DIR:/data/coco2017_tfrecords $CONTAINER bash -c '
    cd /data/coco2017_tfrecords
    # Create TFRecords
    python /workdir/models/research/object_detection/dataset_tools/create_coco_tf_record.py \
        --train_image_dir=`pwd`"/train2017" \
        --val_image_dir=`pwd`"/val2017" \
        --val_annotations_file=`pwd`"/annotations/instances_val2017.json" \
        --train_annotations_file=`pwd`"/annotations/instances_train2017.json" \
        --testdev_annotations_file=`pwd`"/annotations/instances_val2017.json" \
        --test_image_dir=`pwd`"/val2017" \
        --output_dir=`pwd`'
    
    


    상위의 각각의 COCO DATA SET을 Download한 후 TF Record를 만드는 방식으로 동작

      https://github.com/NVIDIA/DeepLearningExamples/blob/master/TensorFlow/Detection/SSD/download_all.sh


    COCO DATA Set의 크기가 방대해서 이미 Download하고 아래와 같이 실행하려고 했으나, 최신 Version으로 다시 하기로 결정

     $ docker run --gpus all -it --rm  \
    -p 8888:8888 -p 6006:6006  \
    --name tensorflow \
    -v /home/jhlee/works/dockers/tensorflow/Workspace:/Workspace \
    -v /home/jhlee/works/dockers/tensorflow/data:/data \
    -v /home/jhlee/works/dockers/tensorflow/checkpoints:/checkpoints \
    nvcr.io/nvidia/tensorflow:19.08-py3
    ........
    root@55e1bf3c0391:/workspace# ls /Workspace   // 원래 Workspace directory는 없음 
    root@55e1bf3c0391:/workspace# cp -a * /Workspace
    root@55e1bf3c0391:/workspace# ls /Workspace    // 전부 Host로 복사완료 
    README.md  docker-examples  nvidia-examples
    

    • NvLink (NVIDIA GPU Link)
    Nvidia-smi 기반으로  Nvlink 기능확인 및 활용 
    $ nvidia-smi nvlink -h
    
        nvlink -- Display NvLink information.
    
        Usage: nvidia-smi nvlink [options]
    
        Options include:
        [-h | --help]: Display help information
        [-i | --id]: Enumeration index, PCI bus ID or UUID.
    
        [-l | --link]: Limit a command to a specific link.  Without this flag, all link information is displayed.
        [-s | --status]: Display link state (active/inactive).
        [-c | --capabilities]: Display link capabilities.
        [-p | --pcibusid]: Display remote node PCI bus ID for a link.
        [-sc | --setcontrol]: Set the utilization counters to count specific NvLink transactions.
           The argument consists of an N-character string representing what is meant to be counted:
               First character specifies the counter set:
                   0 = counter 0
                   1 = counter 1
               Second character can be:
                   c = count cycles
                   p = count packets
                   b = count bytes
               Next N characters can be any of the following:
                   n = nop
                   r = read
                   w = write
                   x = reduction atomic requests
                   y = non-reduction atomic requests
                   f = flush
                   d = responses with data
                   o = responses with no data
                   z = all traffic
    
        [-gc | --getcontrol]: Get the utilization counter control information showing
    the counting method and packet filter for the specified counter set (0 or 1).
        [-g | --getcounters]: Display link utilization counter for specified counter set (0 or 1).
            Note that this currently requires root by default for security reasons.
            See "GPU performance counters" in the Known Issues section of the GPU driver README
        [-r | --resetcounters]: Reset link utilization counter for specified counter set (0 or 1).
        [-e | --errorcounters]: Display error counters for a link.
        [-ec | --crcerrorcounters]: Display per-lane CRC error counters for a link.
        [-re | --reseterrorcounters]: Reset all error counters to zero.
    


    • NvLink (NVIDIA GPU Link)
    동일한 OS와 동일한 GPU인데, 아래와 같이 동작이 다름
    NVLINK 부분에 대해서도 좀 더 자세히 알아야 할 것 같으며 , 이를 적극적으로 활용 

    $ nvidia-smi nvlink -c
    GPU 0: GeForce RTX 2080 Ti (UUID: GPU-0c2ff3ff-47a9-2a70-afba-eb1be7d1d5fb)
    GPU 1: GeForce RTX 2080 Ti (UUID: GPU-024cc4d2-008a-de50-b130-e24beae9d650)
    
    $ nvidia-smi nvlink -s
    GPU 0: GeForce RTX 2080 Ti (UUID: GPU-0c2ff3ff-47a9-2a70-afba-eb1be7d1d5fb)
      Link 0:  inactive
      Link 1:  inactive
    GPU 1: GeForce RTX 2080 Ti (UUID: GPU-024cc4d2-008a-de50-b130-e24beae9d650)
      Link 0:  inactive
      Link 1:  inactive
    


    아래의 사이트에서 나온 정보로 상위 현재 GPU 두개 사용하는 것이 다름

    $ nvidia-smi nvlink -c
    GPU 0: GeForce RTX 2080 Ti (UUID: GPU-1ac935c2-557f-282e-14e5-3f749ffd63ac)
             Link 0, P2P is supported: true
             Link 0, Access to system memory supported: true
             Link 0, P2P atomics supported: true
             Link 0, System memory atomics supported: true
             Link 0, SLI is supported: true
             Link 0, Link is supported: false
             Link 1, P2P is supported: true
             Link 1, Access to system memory supported: true
             Link 1, P2P atomics supported: true
             Link 1, System memory atomics supported: true
             Link 1, SLI is supported: true
             Link 1, Link is supported: false
    GPU 1: GeForce RTX 2080 Ti (UUID: GPU-13277ce5-e1e9-0cb1-8cee-6c9e6618e774)
             Link 0, P2P is supported: true
             Link 0, Access to system memory supported: true
             Link 0, P2P atomics supported: true
             Link 0, System memory atomics supported: true
             Link 0, SLI is supported: true
             Link 0, Link is supported: false
             Link 1, P2P is supported: true
             Link 1, Access to system memory supported: true
             Link 1, P2P atomics supported: true
             Link 1, System memory atomics supported: true
             Link 1, SLI is supported: true
             Link 1, Link is supported: false
    

    NVIDIA NVLINK
      http://blog.naver.com/PostView.nhn?blogId=computer8log&logNo=221378763004
      https://www.nvidia.com/ko-kr/data-center/nvlink/


    참고
      http://wp.study3.biz/wp-content/uploads/2019/04/Big-LSTM-Manjaro-Linux-RTX-2080Ti-x2-Nvlink-CUDA-10.1-i7-5960x-19.04-py3-TensorFlow-Training-performance-wordssecond-wps64160-63475-62864.txt
      http://wp.study3.biz/wp-content/uploads/2019/04/Big-LSTM-CentOS7.6-RTX-2080Ti-x2-Nvlink-CUDA-10.1-i7-5960x-19.04-py3-TensorFlow-Training-performance-wordssecond-wps68609-67909-68423.txt