Kubernetes Engine에서 GPU 인코딩 - NVENC

Google Kubernetes Engine의 컨테이너 GPU에서 동영상 인코딩(NVENC)을 수행하여 고속 인코딩과 확장성을 결합할 수 있습니다.
Container Engine GPU의 입문 기사는 기계 학습용의 것이 많아, 동영상 처리의 것이 발견되지 않았기 때문에 기사를 썼습니다.

Docker 빌드 머신 측에서는 GPU는 물론 NVIDIA 드라이버조차 넣을 필요가 없기 때문에 편합니다.

준비



Docker 이미지의 빌드 머신은 Google Compute Engine VM을 사용하면 빠르고 편리합니다.
이번에는 CentOS 7을 사용했습니다.
이미지를 Google 클라우드 스토리지에 Container Registry로 저장하므로 VM에 스토리지에 대한 읽기 및 쓰기 권한이 필요합니다.

Docker 이미지 빌드



(1) Docker 설치


# yum install -y yum-utils
# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# yum makecache fast
# yum install -y docker-ce
# systemctl start docker

(2) nvidia-docker2 설치


# distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
# curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo | tee /etc/yum.repos.d/nvidia-docker.repo
# yum -y install nvidia-docker2
# pkill -SIGHUP dockerd

(3) Dockerfile 만들기



여기 에 따라 Dockerfile을 만들고 있습니다.
GKE에서는 Ubuntu 기반이 권장되는 것처럼 Ubuntu16.04를 선택했습니다.

Dockerfile
FROM ubuntu:16.04
LABEL maintainer "NVIDIA CORPORATION <[email protected]>"

RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates apt-transport-https gnupg-curl && \
    rm -rf /var/lib/apt/lists/* && \
    NVIDIA_GPGKEY_SUM=d1be581509378368edeec8c1eb2958702feedf3bc3d17011adbf24efacce4ab5 && \
    NVIDIA_GPGKEY_FPR=ae09fe4bbd223a84b2ccfce3f60f4b3d7fa2af80 && \
    apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub && \
    apt-key adv --export --no-emit-version -a $NVIDIA_GPGKEY_FPR | tail -n +5 > cudasign.pub && \
    echo "$NVIDIA_GPGKEY_SUM  cudasign.pub" | sha256sum -c --strict - && rm cudasign.pub && \
    echo "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64 /" > /etc/apt/sources.list.d/cuda.list && \
    echo "deb https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1604/x86_64 /" > /etc/apt/sources.list.d/nvidia-ml.list

ENV CUDA_VERSION 9.2.148

ENV CUDA_PKG_VERSION 9-2=$CUDA_VERSION-1
RUN apt-get update && apt-get install -y --no-install-recommends \
        cuda-cudart-$CUDA_PKG_VERSION && \
    ln -s cuda-9.2 /usr/local/cuda && \
    rm -rf /var/lib/apt/lists/*

# nvidia-docker 1.0
LABEL com.nvidia.volumes.needed="nvidia_driver"
LABEL com.nvidia.cuda.version="${CUDA_VERSION}"

RUN echo "/usr/local/nvidia/lib" >> /etc/ld.so.conf.d/nvidia.conf && \
    echo "/usr/local/nvidia/lib64" >> /etc/ld.so.conf.d/nvidia.conf

ENV PATH /usr/local/nvidia/bin:/usr/local/cuda/bin:${PATH}
ENV LD_LIBRARY_PATH /usr/local/nvidia/lib:/usr/local/nvidia/lib64

# nvidia-container-runtime
ENV NVIDIA_VISIBLE_DEVICES all
ENV NVIDIA_DRIVER_CAPABILITIES compute,utility
ENV NVIDIA_REQUIRE_CUDA "cuda>=9.2"

# FFMPEG
RUN set -x \
 && apt update \
 && apt install -y gcc git make pkg-config devscripts \
 && apt install -y yasm nasm zlib1g-dev \
 && cd /usr/local/src \
 && curl -L http://sourceforge.net/projects/lame/files/lame/3.99/lame-3.99.5.tar.gz -o lame-3.99.5.tar.gz \
 && tar xvzf lame-3.99.5.tar.gz \
 && cd lame-3.99.5 \
 && ./configure \
 && make \
 && make install \
 && cd /usr/local/src \
 && git clone http://git.videolan.org/git/x264.git \
 && cd x264 \
 && ./configure --enable-shared --disable-asm \
 && make \
 && make install \
 && export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig \
 && echo /usr/local/lib >> /etc/ld.so.conf \
 && ldconfig \
 && cd /usr/local/src \
 && curl -L https://github.com/FFmpeg/nv-codec-headers/releases/download/n8.0.14.6/nv-codec-headers-8.0.14.6.tar.gz -o nv-codec-headers-8.0.14.6.tar.gz \
 && tar xvzf nv-codec-headers-8.0.14.6.tar.gz \
 && cd nv-codec-headers-n8.0.14.6 \
 && make \
 && make install \
 && cd /usr/local/src \
 && git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg \
 && cd ffmpeg \
 && ./configure --enable-nvenc --enable-libx264 --enable-gpl --enable-libmp3lame \
 && make \
 && make install \
 && cd /usr/local/src \
 && rm -rf *

#この辺から下はご自身のプロジェクトに合わせてください。
# Node.js
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - \
 && apt-get install -y nodejs \
 && mkdir /var/video_encode
COPY ./video_encode /var/video_encode
CMD /usr/bin/node /var/video_encode/bin/www
EXPOSE 3000

(4) Docker 빌드하고 PUSH



아래의 "asia.gcr.io"부분은 좋아하는 리전으로 바꾸어도 OK.
Dockerfile이 있는 디렉토리에서
# nvidia-docker build -t asia.gcr.io/自分のGCPプロジェクト名/test-encode .
# gcloud auth configure-docker
# nvidia-docker push asia.gcr.io/自分のGCPプロジェクト名/test-encode

Kubernetes Engine 콘솔에서 작업



(1) 클러스터 생성



콘솔의 클러스터 메뉴 > 클러스터 만들기

  • 영역/리전에서 제공하는 GPU가 다릅니다.
  • GPU를 사용하는 노드 풀과 사용하지 않는 노드 풀을 나누어 작성하는 것이 추천입니다.
    GPU를 요구하는 Pod는 nvidia.com/gpu 테인트에 의해 GPU 노드에 스케줄 되는 구조로 되어 있습니다.

  • (2) NVIDIA 디바이스 드라이버 준비



    클러스터 목록에서 새 클러스터가 생성되었는지 확인하고 오른쪽의 연결 메뉴에서 Cloud Shell을 엽니다.
    NVIDIA 디바이스 드라이버를 설치할 데몬 세트를 설정합니다.
    # kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/stable/nvidia-driver-installer/cos/daemonset-preloaded.yaml
    結果:
    daemonset.extensions "nvidia-driver-installer" created
    

    (3) 이전의 Docker 이미지 배포



    콘솔 워크로드 메뉴 > 배포


    배포 후 워크로드 메뉴에서 YAML을 편집하고 아래의 resources 부분을 다시 작성하여 nvidia.com/gpu에서 GPU 수를 지정하여 저장합니다.
    apiVersion: extensions/v1beta1
    kind: Deployment
    ... 略
        spec:
          containers:
          - name: 〇〇
            image: 〇〇
            resources:
              limits:
                nvidia.com/gpu: 1
    

    ※ 편집 후, "Insufficient nvidia"등의 에러로 Pod가 곧바로 기동하지 않는 경우가 있습니다만, 잠시 기다리고 있으면 해소됩니다.

    ※ 워크로드의 자동 스케일러 설정에 대해
    포드마다 가능한 한 동일한 GPU를 사용하지 않는 것이 바람직하다면 CPU 타겟 값을 낮추는 것이 좋습니다. CPU 타겟치가 높으면, CPU를 많이 소비하지 않는 어플리케이션의 경우, 같은 노드내에 Pod가 차례차례로 만들어져, GPU를 공유합니다.

    (4) NVENC를 할 수 있는지 확인



    포드에 exec하여 확인합시다.
    실행 중인 Pod 이름은 워크로드 메뉴에서 확인할 수 있습니다.

    CloudShell
    # kubectl exec -it Pod名 /bin/bash
    

    포드에 들어가면 h264_nvenc로 인코딩 해보십시오.
    # ffmpeg -i test.mov -vcodec h264_nvenc -b:v 2000k -acodec libmp3lame -b:a 128k output.mp4
    

    (5) 애플리케이션 공개 (필요한 경우)





    이상

    좋은 웹페이지 즐겨찾기