简体中文版经机器翻译而成,仅供参考。如与英语版出现任何冲突,应以英语版为准。

执行单节点 AI 工作负载

提供者 kevin-hoke mboglesby

要在 Kubernetes 集群中执行单节点 AI 和 ML 作业,请从部署跳转主机执行以下任务。借助 Trident ,您可以快速轻松地使可能包含数 PB 数据的数据卷可供 Kubernetes 工作负载访问。要使此类数据卷可从 Kubernetes Pod 中访问,只需在 Pod 定义中指定 PVC 即可。此步骤是 Kubernetes 本机操作;不需要 NetApp 专业知识。

注 本节假定您已将尝试在 Kubernetes 集群中执行的特定 AI 和 ML 工作负载容器化(采用 Docker 容器格式)。
  1. 以下示例命令显示了如何为使用 ImageNet 数据集的 TensorFlow 基准工作负载创建 Kubernetes 作业。有关 ImageNet 数据集的详细信息,请参见 "ImageNet 网站"

    此示例作业请求八个 GPU ,因此可以在具有八个或更多 GPU 的单个 GPU 工作节点上运行。此示例作业可以在集群中提交,其中包含八个或更多 GPU 的工作节点不存在或当前占用另一个工作负载。如果是,则此作业将保持待定状态,直到此类辅助节点变为可用为止。

    此外,为了最大程度地提高存储带宽,包含所需训练数据的卷会在该作业创建的 POD 中挂载两次。此外,还会在 Pod 中挂载另一个卷。第二个卷将用于存储结果和指标。这些卷在作业定义中使用 PVC 的名称进行引用。有关 Kubernetes 作业的详细信息,请参见 "Kubernetes 官方文档"

    在本示例作业创建的 Pod 中, edium 值为 Memory 的` emtyDir m卷将挂载到 ` /dev/shm 。Docker 容器运行时自动创建的 ` /dev/shm` 虚拟卷的默认大小有时可能不足以满足 TensorFlow 的需求。按以下示例所示挂载 emptyDir 卷可提供足够大的 ` /dev/shm` 虚拟卷。有关 emptyDir 卷的详细信息,请参见 "Kubernetes 官方文档"

    在此示例作业定义中指定的单个容器将获得 securityContext > privilegedtrue 。此值表示容器在主机上具有有效的 root 访问权限。在这种情况下使用此标注是因为要执行的特定工作负载需要 root 访问权限。具体而言,工作负载执行的清除缓存操作需要 root 访问权限。是否需要此 特权: true 标注取决于您要执行的特定工作负载的要求。

    $ cat << EOF > ./netapp-tensorflow-single-imagenet.yaml
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: netapp-tensorflow-single-imagenet
    spec:
      backoffLimit: 5
      template:
        spec:
          volumes:
          - name: dshm
            emptyDir:
              medium: Memory
          - name: testdata-iface1
            persistentVolumeClaim:
              claimName: pb-fg-all-iface1
          - name: testdata-iface2
            persistentVolumeClaim:
              claimName: pb-fg-all-iface2
          - name: results
            persistentVolumeClaim:
              claimName: tensorflow-results
          containers:
          - name: netapp-tensorflow-py2
            image: netapp/tensorflow-py2:19.03.0
            command: ["python", "/netapp/scripts/run.py", "--dataset_dir=/mnt/mount_0/dataset/imagenet", "--dgx_version=dgx1", "--num_devices=8"]
            resources:
              limits:
                nvidia.com/gpu: 8
            volumeMounts:
            - mountPath: /dev/shm
              name: dshm
            - mountPath: /mnt/mount_0
              name: testdata-iface1
            - mountPath: /mnt/mount_1
              name: testdata-iface2
            - mountPath: /tmp
              name: results
            securityContext:
              privileged: true
          restartPolicy: Never
    EOF
    $ kubectl create -f ./netapp-tensorflow-single-imagenet.yaml
    job.batch/netapp-tensorflow-single-imagenet created
    $ kubectl get jobs
    NAME                                       COMPLETIONS   DURATION   AGE
    netapp-tensorflow-single-imagenet          0/1           24s        24s
  2. 确认您在步骤 1 中创建的作业正在正确运行。以下示例命令确认已按照作业定义中的指定为此作业创建了一个 POD ,并且此 POD 当前正在其中一个 GPU 工作节点上运行。

    $ kubectl get pods -o wide
    NAME                                             READY   STATUS      RESTARTS   AGE
    IP              NODE            NOMINATED NODE
    netapp-tensorflow-single-imagenet-m7x92          1/1     Running     0          3m    10.233.68.61    10.61.218.154   <none>
  3. 确认您在步骤 1 中创建的作业已成功完成。以下示例命令确认作业已成功完成。

    $ kubectl get jobs
    NAME                                             COMPLETIONS   DURATION   AGE
    netapp-tensorflow-single-imagenet                1/1           5m42s      10m
    $ kubectl get pods
    NAME                                                   READY   STATUS      RESTARTS   AGE
    netapp-tensorflow-single-imagenet-m7x92                0/1     Completed   0          11m
    $ kubectl logs netapp-tensorflow-single-imagenet-m7x92
    [netapp-tensorflow-single-imagenet-m7x92:00008] PMIX ERROR: NO-PERMISSIONS in file gds_dstore.c at line 702
    [netapp-tensorflow-single-imagenet-m7x92:00008] PMIX ERROR: NO-PERMISSIONS in file gds_dstore.c at line 711
    Total images/sec = 6530.59125
    ================ Clean Cache !!! ==================
    mpirun -allow-run-as-root -np 1 -H localhost:1 bash -c 'sync; echo 1 > /proc/sys/vm/drop_caches'
    =========================================
    mpirun -allow-run-as-root -np 8 -H localhost:8 -bind-to none -map-by slot -x NCCL_DEBUG=INFO -x LD_LIBRARY_PATH -x PATH python /netapp/tensorflow/benchmarks_190205/scripts/tf_cnn_benchmarks/tf_cnn_benchmarks.py --model=resnet50 --batch_size=256 --device=gpu --force_gpu_compatible=True --num_intra_threads=1 --num_inter_threads=48 --variable_update=horovod --batch_group_size=20 --num_batches=500 --nodistortions --num_gpus=1 --data_format=NCHW --use_fp16=True --use_tf_layers=False --data_name=imagenet --use_datasets=True --data_dir=/mnt/mount_0/dataset/imagenet --datasets_parallel_interleave_cycle_length=10 --datasets_sloppy_parallel_interleave=False --num_mounts=2 --mount_prefix=/mnt/mount_%d --datasets_prefetch_buffer_size=2000 --datasets_use_prefetch=True --datasets_num_private_threads=4 --horovod_device=gpu > /tmp/20190814_105450_tensorflow_horovod_rdma_resnet50_gpu_8_256_b500_imagenet_nodistort_fp16_r10_m2_nockpt.txt 2>&1
  4. * 可选: * 清理作业项目。以下示例命令显示了在步骤 1 中创建的作业对象的删除情况。

    删除作业对象时, Kubernetes 会自动删除任何关联的 Pod 。

    $ kubectl get jobs
    NAME                                             COMPLETIONS   DURATION   AGE
    netapp-tensorflow-single-imagenet                1/1           5m42s      10m
    $ kubectl get pods
    NAME                                                   READY   STATUS      RESTARTS   AGE
    netapp-tensorflow-single-imagenet-m7x92                0/1     Completed   0          11m
    $ kubectl delete job netapp-tensorflow-single-imagenet
    job.batch "netapp-tensorflow-single-imagenet" deleted
    $ kubectl get jobs
    No resources found.
    $ kubectl get pods
    No resources found.