Cloud TPU 및 GKE를 사용하여 Mask R-CNN 학습

이 가이드에서는 Cloud TPU와 GKE에서 Mask RCNN 모델을 학습시키는 방법을 설명합니다.

목표

  • 데이터세트와 모델 출력을 저장할 Cloud Storage 버킷을 만듭니다.
  • Cloud TPU 리소스를 관리할 GKE 클러스터를 만듭니다.
  • Cloud TPU에서 TensorFlow를 사용하여 Mask RCNN을 학습시키는 데 필요한 리소스를 설명하는 Kubernetes 작업 사양을 다운로드합니다.
  • GKE 클러스터에서 작업을 실행하여 모델을 학습시킵니다.
  • 로그와 모델 출력을 확인합니다.

비용

이 가이드에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud 구성요소를 사용합니다.

  • Compute Engine
  • Cloud TPU
  • Cloud Storage

가격 계산기를 사용하여 예상 사용량을 기준으로 예상 비용을 산출합니다. Google Cloud를 처음 사용하는 사용자는 무료 체험판을 사용할 수 있습니다.

시작하기 전에

  1. Google 계정으로 로그인합니다.

    아직 계정이 없으면 새 계정을 등록하세요.

  2. Cloud Console의 프로젝트 선택기 페이지에서 Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기 페이지로 이동

  3. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다. 프로젝트에 결제가 사용 설정되어 있는지 확인하는 방법을 알아보세요.

  4. GKE에서 Cloud TPU를 사용하면 프로젝트는 비용이 청구될 수 있는 Google Cloud 구성요소를 사용합니다. Cloud TPU 가격 책정GKE 가격 책정에서 예상 비용을 확인하고 안내를 따라 사용을 마친 리소스를 삭제합니다.

  5. Cloud Console에서 다음 링크를 열어 이 가이드에 필요한 API를 사용 설정합니다.

Cloud Storage 버킷 생성

모델 학습에 사용할 데이터 및 학습 결과를 저장할 Cloud Storage 버킷이 필요합니다. 이 가이드에서 사용하는 ctpu up 도구는 Cloud TPU 서비스 계정에 대한 기본 권한을 설정합니다. 권한을 더 세분화해야 하는 경우 액세스 수준 권한을 참조하세요.

  1. Cloud Console에서 Cloud Storage 페이지로 이동합니다.

    Cloud Storage 페이지로 이동

  2. 다음 옵션을 지정하여 새 버킷을 만듭니다.

    • 원하는 고유한 이름
    • 기본 스토리지 클래스: Regional
    • 데이터를 저장할 위치 선택: region 위치: us-central1
    • 데이터의 기본 스토리지 클래스 선택: Standard
    • 객체 액세스를 제어할 방법 선택: 객체 수준 및 버킷 수준 권한 설정

Cloud TPU가 Cloud Storage 버킷에 액세스하도록 승인

Cloud TPU에 Cloud Storage 객체에 대한 읽기/쓰기 액세스 권한을 부여해야 합니다. 이렇게 하려면 Cloud TPU에서 사용하는 서비스 계정에 필수 액세스 권한을 부여해야 합니다. 가이드에 따라 스토리지 버킷에 대한 액세스 권한을 부여하세요.

GKE에서 클러스터 만들기

아래의 안내를 따라 gcloud 명령줄 도구를 사용하여 환경을 설정하고 Cloud TPU를 지원하는 GKE 클러스터를 만듭니다.

  1. Cloud Shell 창을 엽니다.

    Cloud Shell 열기

  2. Google Cloud 프로젝트를 지정합니다.

    $ gcloud config set project project-name
    

    여기서 project-name는 Google Cloud 프로젝트의 이름입니다.

  3. Cloud TPU 리소스를 사용할 영역을 지정합니다. 이 예시에서는 us-central1-b 영역을 사용합니다.

    $ gcloud config set compute/zone us-central1-b
    
  4. gcloud container clusters 명령어를 사용하여 Cloud TPU를 지원하는 GKE에서 클러스터를 만듭니다. GKE 클러스터와 해당 노드 풀은 위의 환경 변수 섹션에 설명된 대로 Cloud TPU를 사용할 수 있는 영역에 만들어야 합니다. 다음 명령어는 tpu-models-cluster 클러스터를 만듭니다.

    $ gcloud container clusters create tpu-models-cluster \
    --cluster-version=1.13 \
    --scopes=cloud-platform \
    --enable-ip-alias \
    --enable-tpu \
    --machine-type=n1-standard-4
    

    위의 명령어에서 각 항목의 의미는 다음과 같습니다.

    • --cluster-version=1.13은 클러스터가 최신 Kubernetes 1.16 버전을 사용할 것임을 나타냅니다. 버전 1.13.4-gke.5 이상을 사용해야 합니다.
    • --scopes=cloud-platform은 클러스터의 모든 노드가 위의 project-name로 정의된 Google Cloud의 Cloud Storage 버킷에 액세스할 수 있도록 합니다. 이를 위해 클러스터와 스토리지 버킷이 같은 프로젝트에 있어야 합니다. Pod에 기본적으로 배포되는 노드 범위가 상속됩니다. 이 플래그는 클러스터에서 실행되는 모든 Pod에 cloud-platform 범위를 제공합니다. Pod 단위로 액세스를 제한하려면 GKE 가이드의 서비스 계정으로 인증을 참조하세요.
    • --enable-ip-alias는 클러스터가 별칭 IP 범위를 사용함을 나타냅니다. 이는 GKE에서 Cloud TPU를 사용하는 데 필요합니다.
    • --enable-tpu는 클러스터가 Cloud TPU를 지원해야 함을 나타냅니다.
    • machine-type=n1-standard-4는 이 작업을 실행하기 위해 필요합니다.

    명령어 실행이 끝나면 다음과 비슷한 확인 메시지가 나타납니다.

    kubeconfig entry generated for tpu-models-cluster.
    NAME                LOCATION       MASTER_VERSION   MASTER_IP      MACHINE_TYPE   NODE_VERSION   NUM_NODES  STATUS
    tpu-models-cluster  us-central1-b  1.13.6-gke.5     35.232.204.86  n1-standard-4  1.13.6-gke.5   3          RUNNING
    

학습 데이터 처리

그 다음으로 할 일은 작업 생성입니다. Google Kubernetes Engine에서 작업은 유한한 태스크를 나타내는 컨트롤러 객체입니다. 가장 먼저 해야 할 일은 Mask RCNN 모델을 학습시키는 데 사용된 COCO 데이터세트를 다운로드해서 처리하는 것입니다.

  1. 셸 환경에서 아래와 같이 download_and_preprocess_coco_k8s.yaml 파일을 만듭니다. 또는 GitHub에서 이 파일을 다운로드할 수 있습니다.

    # Download and preprocess the COCO dataset.
    #
    # Instructions:
    #   1. Follow the instructions on https://cloud.google.com/tpu/docs/kubernetes-engine-setup
    #      to create a Kubernetes Engine cluster. The Job must be running at least
    #      on a n1-standard-4 machine.
    #   2. Change the environment variable DATA_BUCKET below to the path of the
    #      Google Cloud Storage bucket where you want to store the training data.
    #   3. Run `kubectl create -f download_and_preprocess_coco_k8s.yaml`.
    
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: download-and-preprocess-coco
    spec:
      template:
        spec:
          restartPolicy: Never
          containers:
          - name: download-and-preprocess-coco
            # The official TensorFlow 1.13 TPU model image built from https://github.com/tensorflow/tpu/blob/r1.13/tools/docker/Dockerfile.
            image: gcr.io/tensorflow/tpu-models:r1.13
            command:
              - /bin/bash
              - -c
              - >
                DEBIAN_FRONTEND=noninteractive apt-get update &&
                cd /tensorflow_tpu_models/tools/datasets &&
                bash download_and_preprocess_coco.sh /scratch-dir &&
                gsutil -m cp /scratch-dir/*.tfrecord ${DATA_BUCKET}/coco &&
                gsutil cp /scratch-dir/raw-data/annotations/*.json ${DATA_BUCKET}/coco
            env:
              # [REQUIRED] Must specify the Google Cloud Storage location where the
              # COCO dataset will be stored.
            - name: DATA_BUCKET
              value: "gs://<my-data-bucket>/data/coco"
            volumeMounts:
            - mountPath: /scratch-dir
              name: scratch-volume
          volumes:
          - name: scratch-volume
            persistentVolumeClaim:
              claimName: scratch-disk-coco
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: scratch-disk-coco
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 100Gi
    
  2. DATA_BUCKET 환경 변수를 찾습니다. 이 변수의 value를 Cloud Storage 버킷에서 COCO 데이터세트를 저장할 경로로 업데이트합니다. 예를 들면 다음과 같습니다. 'gs://my-maskrcnn-bucket/coco/'

  3. 다음 명령어를 실행하여 클러스터에서 작업을 만듭니다.

    kubectl create -f download_and_preprocess_coco_k8s.yaml
    

작업이 시작될 때까지 몇 분이 걸릴 수 있습니다. 다음 명령어를 사용하여 클러스터에서 실행 중인 작업의 상태를 볼 수 있습니다.

kubectl get pods -w

이 명령어는 클러스터에서 실행 중인 모든 작업에 대한 정보를 반환합니다. 예를 들면 다음과 같습니다.

NAME                                 READY     STATUS      RESTARTS   AGE
download-and-preprocess-coco-xmx9s   0/1       Pending     0          10s

-w 플래그는 명령어에 Pod 상태의 변경을 감시하도록 지시합니다. 몇 분 후에 작업의 상태가 Running으로 업데이트됩니다.

작업에 문제가 발생하는 경우 삭제하고 다시 시도할 수 있습니다. 이렇게 하려면 kubectl create 명령어를 다시 실행하기 전에 kubectl delete -f download_and_preprocess_coco_k8s.yaml 명령어를 실행합니다.

다운로드와 사전 처리가 완료되면 모델을 실행할 수 있습니다.

Mask RCNN 모델 실행

이제 Cloud TPU와 GKE를 사용하여 Mask RCNN 모델을 실행할 수 있는 모든 여건이 갖춰졌습니다.

  1. 셸 환경에서 아래와 같이 mask_rcnn_k8s.yaml 파일을 만듭니다. 또는 GitHub에서 이 파일을 다운로드할 수 있습니다.

    # Train Mask-RCNN with Coco dataset using Cloud TPU and Google Kubernetes Engine.
    #
    # [Training Data]
    #   Download and preprocess the COCO dataset using https://github.com/tensorflow/tpu/blob/r1.13/tools/datasets/download_and_preprocess_coco_k8s.yaml
    #   if you don't already have the data.
    #
    # [Instructions]
    #   1. Follow the instructions on https://cloud.google.com/tpu/docs/kubernetes-engine-setup
    #      to create a Kubernetes Engine cluster.
    #   2. Change the environment variable MODEL_BUCKET in the Job spec to the
    #      Google Cloud Storage location where you want to store the output model.
    #   3. Run `kubectl create -f mask_rcnn_k8s.yaml`.
    
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: mask-rcnn-gke-tpu
    spec:
      template:
        metadata:
          annotations:
            # The Cloud TPUs that will be created for this Job must support
            # TensorFlow 1.13. This version MUST match the TensorFlow version that
            # your model is built on.
            tf-version.cloud-tpus.google.com: "1.13"
        spec:
          restartPolicy: Never
          containers:
          - name: mask-rcnn-gke-tpu
            # The official TensorFlow 1.13 TPU model image built from https://github.com/tensorflow/tpu/blob/r1.13/tools/docker/Dockerfile.
            image: gcr.io/tensorflow/tpu-models:r1.13
            command:
            - /bin/sh
            - -c
            - >
                DEBIAN_FRONTEND=noninteractive apt-get update &&
                DEBIAN_FRONTEND=noninteractive apt-get install -y python-dev python-tk libsm6 libxrender1 libxrender-dev libgtk2.0-dev libxext6 libglib2.0 &&
                pip install Cython matplotlib opencv-python-headless &&
                pip install 'git+https://github.com/cocodataset/cocoapi#egg=pycocotools&subdirectory=PythonAPI' &&
                python /tensorflow_tpu_models/models/experimental/mask_rcnn/mask_rcnn_main.py
                --model_dir=${MODEL_BUCKET}
                --iterations_per_loop=500
                --config=resnet_checkpoint=${RESNET_CHECKPOINT},resnet_depth=50,use_bfloat16=true,train_batch_size=64,eval_batch_size=8,training_file_pattern=${DATA_BUCKET}/train-*,validation_file_pattern=${DATA_BUCKET}/val-*,val_json_file=${DATA_BUCKET}/instances_val2017.json,total_steps=22500
            env:
              # The Google Cloud Storage location to store dataset.
            - name: DATA_BUCKET
              value: "gs://<my-data-bucket>"
            - name: MODEL_BUCKET
              value: "gs://<my-model-bucket>/mask_rcnn"
            - name: RESNET_CHECKPOINT
              value: "gs://cloud-tpu-artifacts/resnet/resnet-nhwc-2018-02-07/model.ckpt-112603"
    
              # Point PYTHONPATH to the top level models folder
            - name: PYTHONPATH
              value: "/tensorflow_tpu_models/models"
            resources:
              limits:
                # Request a single v3-8 Cloud TPU device to train the model.
                # A single v3-8 Cloud TPU device consists of 4 chips, each of which
                # has 2 cores, so there are 8 cores in total.
                cloud-tpus.google.com/v3: 8
    
  2. DATA_BUCKET 환경 변수를 찾습니다. 이 변수의 valuedownload_and_preprocess_coco_k8s.yaml 스크립트에 지정한 DATA_BUCKET 파일 경로로 업데이트합니다.

  3. MODEL_BUCKET 환경 변수를 찾습니다. 이 변수의 value를 Cloud Storage 버킷 경로로 업데이트합니다. 이 위치는 스크립트가 학습 출력을 저장하는 위치입니다. 지정된 MODEL_BUCKET이 없는 경우 작업을 실행할 때 생성됩니다.

  4. 다음 명령어를 실행하여 클러스터에서 작업을 만듭니다.

    kubectl create -f mask_rcnn_k8s.yaml
    

    이 명령어를 실행할 때 다음 확인 메시지가 표시됩니다.

    job "mask-rcnn-gke-tpu" created

학습 데이터 처리 섹션에서 언급했듯이 작업이 시작될 때까지 몇 분 정도 걸릴 수 있습니다. 다음 명령어를 사용하여 클러스터에서 실행 중인 작업의 상태를 봅니다.

kubectl get pods -w

학습 상태 보기

kubectl 명령줄 유틸리티를 사용하여 학습 상태를 추적할 수 있습니다.

  1. 다음 명령어를 실행하여 작업의 상태를 가져옵니다.

    kubectl get pods
    

    학습 프로세스 중 pod의 상태는 RUNNING이어야 합니다.

  2. 학습 프로세스에 대한 추가 정보를 보려면 다음 명령어를 실행하세요.

    $ kubectl logs job name

    여기에서 job name은 작업의 전체 이름입니다(예: mask-rcnn-gke-tpu-abcd).

    Cloud Console의 GKE 워크로드 대시보드에서 출력을 확인할 수도 있습니다.

    첫 번째 항목이 로그에 표시되는데 시간이 좀 걸립니다. 다음과 같은 내용이 표시될 수 있습니다.

    I0622 18:14:31.617954 140178400511808 tf_logging.py:116] Calling model_fn.
    I0622 18:14:40.449557 140178400511808 tf_logging.py:116] Create CheckpointSaverHook.
    I0622 18:14:40.697138 140178400511808 tf_logging.py:116] Done calling model_fn.
    I0622 18:14:44.004508 140178400511808 tf_logging.py:116] TPU job name worker
    I0622 18:14:45.254548 140178400511808 tf_logging.py:116] Graph was finalized.
    I0622 18:14:48.346483 140178400511808 tf_logging.py:116] Running local_init_op.
    I0622 18:14:48.506665 140178400511808 tf_logging.py:116] Done running local_init_op.
    I0622 18:14:49.135080 140178400511808 tf_logging.py:116] Init TPU system
    I0622 18:15:00.188153 140178400511808 tf_logging.py:116] Start infeed thread controller
    I0622 18:15:00.188635 140177578452736 tf_logging.py:116] Starting infeed thread controller.
    I0622 18:15:00.188838 140178400511808 tf_logging.py:116] Start outfeed thread controller
    I0622 18:15:00.189151 140177570060032 tf_logging.py:116] Starting outfeed thread controller.
    I0622 18:15:07.316534 140178400511808 tf_logging.py:116] Enqueue next (100) batch(es) of data to infeed.
    I0622 18:15:07.316904 140178400511808 tf_logging.py:116] Dequeue next (100) batch(es) of data from outfeed.
    I0622 18:16:13.881397 140178400511808 tf_logging.py:116] Saving checkpoints for 100 into gs://<bucket-name>/mask_rcnn/model.ckpt.
    I0622 18:16:21.147114 140178400511808 tf_logging.py:116] loss = 1.589756, step = 0
    I0622 18:16:21.148168 140178400511808 tf_logging.py:116] loss = 1.589756, step = 0
    I0622 18:16:21.150870 140178400511808 tf_logging.py:116] Enqueue next (100) batch(es) of data to infeed.
    I0622 18:16:21.151168 140178400511808 tf_logging.py:116] Dequeue next (100) batch(es) of data from outfeed.
    I0622 18:17:00.739207 140178400511808 tf_logging.py:116] Enqueue next (100) batch(es) of data to infeed.
    I0622 18:17:00.739809 140178400511808 tf_logging.py:116] Dequeue next (100) batch(es) of data from outfeed.
    I0622 18:17:36.598773 140178400511808 tf_logging.py:116] global_step/sec: 2.65061
    I0622 18:17:37.040504 140178400511808 tf_logging.py:116] examples/sec: 2698.56
    I0622 18:17:37.041333 140178400511808 tf_logging.py:116] loss = 2.63023, step = 200 (75.893 sec)
    
  3. gs://<bucket-name>/mask-rcnn/model.ckpt에서 학습된 모델을 봅니다.

    gsutil ls -r gs://bucket-name/mask-rcnn/model.ckpt

삭제

GKE에서 Cloud TPU 작업을 마쳤으면 Google Cloud 계정에 추가 비용이 발생하지 않도록 리소스를 삭제합니다.

이 세션을 위한 프로젝트 및 영역을 설정하지 않았으면 지금 설정합니다. 이 설명서 앞부분의 안내를 참조하세요. 그런 다음 이 삭제 절차를 따릅니다.

  1. 다음 명령어를 실행하여 GKE 클러스터 tpu-models-cluster를 삭제하고 project-name을 Google Cloud 프로젝트 이름으로 바꿉니다.

    $ gcloud container clusters delete tpu-models-cluster --project=project-name
    
  2. 데이터 검토를 마쳤으면 gsutil 명령어를 사용하여 이 가이드에서 만든 Cloud Storage 버킷을 삭제합니다. bucket-name을 Cloud Storage 버킷 이름으로 바꿉니다.

    $ gsutil rm -r gs://bucket-name
    

    무료 스토리지 한도와 기타 가격 정보는 Cloud Storage 가격 책정 가이드를 참조하세요.

다음 단계

  • 텐서보드의 TPU 도구를 살펴보세요.
  • 다음 작업 사양 중 하나를 사용하여 더 많은 모델 및 데이터세트 검색 작업을 실행하세요.

    • GKE에 COCO 데이터세트를 다운로드하고 사전 처리합니다.
    • GKE에 ImageNet을 다운로드하고 사전 처리합니다.
    • Cloud TPU와 GKE를 사용하여 AmoebaNet-D을 학습시킵니다.
    • Cloud TPU와 GKE를 사용하여 Inception v3을 학습시킵니다.
    • Cloud TPU와 GKE를 사용하여 RetinaNet을 학습시킵니다.
  • 추가 TPU 샘플을 사용해 시험해 보세요.