在 Kubernetes 上使用 CPU 训练 PyTorch 模型(Fashion MNIST)#

本示例使用 Ray Train 在 Kubernetes 上通过 CPU 分布式训练 PyTorch 模型(Fashion MNIST)。有关更多详细信息,请参阅 训练 PyTorch 模型(Fashion MNIST)

步骤 1:创建 Kubernetes 集群#

此步骤使用 Kind 创建一个本地 Kubernetes 集群。如果您已有一个 Kubernetes 集群,则可以跳过此步骤。

kind create cluster --image=kindest/node:v1.26.0

步骤 2:安装 KubeRay operator#

请按照 本文档 从 Helm 存储库安装最新的稳定版 KubeRay operator。

步骤 3:创建 RayJob#

RayJob 由 RayCluster 自定义资源和可提交到 RayCluster 的作业组成。使用 RayJob,KubeRay 会在集群准备就绪时创建一个 RayCluster 并提交一个作业。以下是用于在 PyTorch 模型上进行 MNIST 训练的 CPU Only RayJob 描述 YAML 文件。

# Download `ray-job.pytorch-mnist.yaml`
curl -LO https://raw.githubusercontent.com/ray-project/kuberay/master/ray-operator/config/samples/pytorch-mnist/ray-job.pytorch-mnist.yaml

您可能需要调整 RayJob 描述 YAML 文件中的某些字段,以便在您的环境中运行。

  • replicas (位于 rayClusterSpecworkerGroupSpecs 下):此字段指定 KubeRay 调度到 Kubernetes 集群的工作 Pod 的数量。每个工作 Pod 需要 3 个 CPU,而 Head Pod 需要 1 个 CPU(如 template 字段所述)。RayJob 提交 Pod 需要 1 个 CPU。例如,如果您的机器有 8 个 CPU,则 replicas 的最大值为 2,以便所有 Pod 都能达到 Running 状态。

  • NUM_WORKERS (位于 specruntimeEnvYAML 下):此字段指示要启动的 Ray Actor 的数量(有关更多信息,请参阅此 文档 中的 ScalingConfig)。每个 Ray Actor 必须由 Kubernetes 集群中的工作 Pod 提供服务。因此,NUM_WORKERS 必须小于或等于 replicas

  • CPUS_PER_WORKER:此值必须设置为小于或等于 (每个工作 Pod CPU 资源请求) - 1。例如,在示例 YAML 文件中,每个工作 Pod 的 CPU 资源请求为 3 个 CPU,因此 CPUS_PER_WORKER 必须设置为 2 或更少。

# `replicas` and `NUM_WORKERS` set to 2.
# Create a RayJob.
kubectl apply -f ray-job.pytorch-mnist.yaml

# Check existing Pods: According to `replicas`, there should be 2 worker Pods.
# Make sure all the Pods are in the `Running` status.
kubectl get pods
# NAME                                                             READY   STATUS    RESTARTS   AGE
# kuberay-operator-6dddd689fb-ksmcs                                1/1     Running   0          6m8s
# rayjob-pytorch-mnist-raycluster-rkdmq-small-group-worker-c8bwx   1/1     Running   0          5m32s
# rayjob-pytorch-mnist-raycluster-rkdmq-small-group-worker-s7wvm   1/1     Running   0          5m32s
# rayjob-pytorch-mnist-nxmj2                                       1/1     Running   0          4m17s
# rayjob-pytorch-mnist-raycluster-rkdmq-head-m4dsl                 1/1     Running   0          5m32s

检查 RayJob 是否处于 RUNNING 状态

kubectl get rayjob
# NAME                   JOB STATUS   DEPLOYMENT STATUS   START TIME             END TIME   AGE
# rayjob-pytorch-mnist   RUNNING      Running             2024-06-17T04:08:25Z              11m

步骤 4:等待 RayJob 完成并检查训练结果#

等待 RayJob 完成。这可能需要几分钟时间。

kubectl get rayjob
# NAME                   JOB STATUS   DEPLOYMENT STATUS   START TIME             END TIME               AGE
# rayjob-pytorch-mnist   SUCCEEDED    Complete            2024-06-17T04:08:25Z   2024-06-17T04:22:21Z   16m

看到 JOB_STATUS 标记为 SUCCEEDED 后,您可以检查训练日志。

# Check Pods name.
kubectl get pods
# NAME                                                             READY   STATUS      RESTARTS   AGE
# kuberay-operator-6dddd689fb-ksmcs                                1/1     Running     0          113m
# rayjob-pytorch-mnist-raycluster-rkdmq-small-group-worker-c8bwx   1/1     Running     0          38m
# rayjob-pytorch-mnist-raycluster-rkdmq-small-group-worker-s7wvm   1/1     Running     0          38m
# rayjob-pytorch-mnist-nxmj2                                       0/1     Completed   0          38m
# rayjob-pytorch-mnist-raycluster-rkdmq-head-m4dsl                 1/1     Running     0          38m

# Check training logs.
kubectl logs -f rayjob-pytorch-mnist-nxmj2

# 2024-06-16 22:23:01,047 INFO cli.py:36 -- Job submission server address: http://rayjob-pytorch-mnist-raycluster-rkdmq-head-svc.default.svc.cluster.local:8265
# 2024-06-16 22:23:01,844 SUCC cli.py:60 -- -------------------------------------------------------
# 2024-06-16 22:23:01,844 SUCC cli.py:61 -- Job 'rayjob-pytorch-mnist-l6ccc' submitted successfully
# 2024-06-16 22:23:01,844 SUCC cli.py:62 -- -------------------------------------------------------
# ...
# (RayTrainWorker pid=1138, ip=10.244.0.18)
#   0%|          | 0/26421880 [00:00<?, ?it/s]
# (RayTrainWorker pid=1138, ip=10.244.0.18)
#   0%|          | 32768/26421880 [00:00<01:27, 301113.97it/s]
# ...
# Training finished iteration 10 at 2024-06-16 22:33:05. Total running time: 7min 9s
# ╭───────────────────────────────╮
# │ Training result               │
# ├───────────────────────────────┤
# │ checkpoint_dir_name           │
# │ time_this_iter_s      28.2635 │
# │ time_total_s          423.388 │
# │ training_iteration         10 │
# │ accuracy               0.8748 │
# │ loss                  0.35477 │
# ╰───────────────────────────────╯

# Training completed after 10 iterations at 2024-06-16 22:33:06. Total running time: 7min 10s

# Training result: Result(
#   metrics={'loss': 0.35476621258825347, 'accuracy': 0.8748},
#   path='/home/ray/ray_results/TorchTrainer_2024-06-16_22-25-55/TorchTrainer_122aa_00000_0_2024-06-16_22-25-55',
#   filesystem='local',
#   checkpoint=None
# )
# ...

清理#

使用以下命令删除您的 RayJob。

kubectl delete -f ray-job.pytorch-mnist.yaml