VPC環境で利用できます。
モデル学習のための複数のフレームワーク Jobを提供しています。
学習の基本となる単一ノード学習、分散ノード学習を最も多く使用される形態である単一ノード学習(Job)、分散ノード学習(PytorchJob)形態で説明します。
単一ノード学習の場合、Job の使用をお勧めします。
PytorchJobを使用する場合、分散ノード学習のための機能により、Masterと Workerの形態でリリース管理されるため、不要なリソースが浪費されることがあります。
単一ノード学習(Job)を実行する
学習のために Kubernetes Job明細は次のユースケースのように作成できます。
# job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: mnist
namespace: p-{projectName}
spec:
backoffLimit: 1
template:
metadata:
annotations:
sidecar.istio.io/inject: "false"
spec:
restartPolicy: Never
containers:
- name: main
image: { 学習画像 (e.g.example.com/mnist:latest ) } # NVIDIA Base画像を基準に作成された学習コード
imagePullPolicy: Always
resources:
limits:
memory: "8Gi"
cpu: "4"
nvidia.com/gpu: "1"
command: ["python"]
args:
- /opt/mnist/src/mnist.py
- --checkpoint_path
- /opt/mnist/checkpoints/mnist.pt
- --log_path
- /opt/mnist/log
- --data_path
- /opt/mnist/data
- --download_data
kubectl apply -f job.yaml
batch/mnist created
外部コンテナレジストリの使用
コンテナレジストリに Secret情報が必要な場合、 Container Secretを作成するを参照して作成できます。
作成された Secretは、次のように使用できます。
...
spec:
imagePullSecrets:
- name: my-harbor-secret # 事前に作成した Docker Credential Secretの名前
...
既存 Volumeの使用
Volumesを通じて作成された Volumeを使用するには、次のように使用できます。
...
spec:
containers:
- name: main
...
volumeMounts:
- mountPath: /data
name: mnist-data # 下部の spec.volumesに記載した名前
volumes:
- name: mnist-data
persistentVolumeClaim:
claimName: mnist-data # Volumesを通じて作成された PVC名
...
Jobライフサイクル
Jobが終了した場合、一定時間コンテナログとステータスを残すために削除されず、リストに残ります。
リストに残れる Jobの最大数制限があるため、TTLを通じてライフサイクルを管理する必要があります。詳細は Kubernetes Job APIドキュメントをご参照ください。
Jobを作成する際、TTL(Time To Live)を任意に設定できます。TTLは Jobが完了(成功/失敗)した後に有効になり、TTLだけ経過すると Jobとそれに属する Podがすべて自動的に削除されます。
以下は、3週間の TTLを適用した例です。
apiVersion: batch/v1
kind: Job
metadata:
name: mnist
namespace: p-{projectName}
spec:
ttlSecondsAfterFinished: 1814400 # TTLを直接設定するフィールド(単位: sec)
分散ノード学習(PytorchJob)を実行する
PyTorchJobの利用時に以下のようなメリットがあります。
- 作成されたコンテナ specをベースに Master、Worker Podを適切に作成します。
- PyTorch分散学習で一般的に必要な環境変数(i.e., WORLD_SIZE、RANK、MASTER_ADDRなど)を自動的に設定します。
- 学習に使用される Podが相互に通信できるように、K8s Serviceを自動的に作成します。Masterは
<pytorch-job-name>-master-0、Workerは<pytorch-job-name>-worker-<idx>のような名前でアクセスできます。 - 必要な場合、Elastic Policyを使用するを通じて torchrunで使用する引数を環境変数として作成します(
--nnodes、--nproc-per-node、--rdzv-endpointなど)。
PytorchJobを作成する
Pytorchでの分散学習時は torchrun(Elastic Launch)を使用することをお勧めします。また、 torchrun 使用時にマスター Podを別途明示しません。Torch Elasticではマスターノードの役割をする RANK=0 Podが実行中に変更されることがあります。
spec.elasticPolicy- torchrun関連の設定です。ここに明示した設定が環境変数として注入されます。詳細は Elastic Policyを使用するをご参照ください。spec.runPolicy- PyTorchJobの実行および終了後の処理に関連するパラメータを明示できます。詳細は Run Policyを使用するをご参照ください。spec.pytorchReplicaSpecs.Worker- 分散学習を行う Worker Podに関する情報です。
学習のために PytorchJob明細は次のユースケースのように作成できます
:::(Warning) (使用時に以下の事項を必ず遵守する必要があります)。
- 学習を進行するコンテナの名前(e.g.
spec.pytorchReplicaSpecs.Worker.template.spec.containers[*].name)は必ずpytorchである必要があります。 - 円滑な分散学習のために、Istio Sidecarが Injectにならないよう、
spec.pytorchReplicaSpecs.Worker.template.metadata.annotationsにsidecar.istio.io/inject: "false"を必ず明記する必要があります。当該 annotationが設定されていない場合、RuntimeError: Connection reset by peerなどのノード間通信に関連するエラーが発生します。
:::
# pytorchjob.yaml
apiVersion: kubeflow.org/v1
kind: PyTorchJob
metadata:
name: pytorch-mnist-dist-nccl
namespace: p-{ projectName } # プロジェクトに該当する Kubernetes Namespace名
spec:
pytorchReplicaSpecs:
Worker:
replicas: 2
restartPolicy: OnFailure
template:
metadata:
annotations:
sidecar.istio.io/inject: "false" # Istio sidecar injectionの無効化は必須
spec:
nodeSelector:
mlx.navercorp.com/zone: { 提供された GPU Zone名 } # GPU Resourcesで確認できる Zone名
containers:
- name: pytorch # PyTorchJobの container名を必ず pytorchに設定
image: examples.com/pytorch-mnist-dist:23.03-py3
imagePullPolicy: Always
command: ["bash", "-c"]
args:
- >
torchrun --nnodes ${PET_NNODES} --nproc_per_node ${PET_NPROC_PER_NODE} --rdzv_id ${PET_RDZV_ID} --rdzv_backend ${PET_RDZV_BACKEND} --rdzv_endpoint ${PET_RDZV_ENDPOINT}
/opt/mnist/src/mnist.py --checkpoint_path /data/checkpoints/mnist.pt --log_path /data/logs --data_path /data/dataset
env:
- name: NCCL_DEBUG
value: INFO
kubectl apply -f pytorchjob.yaml
pytorchjob.kubeflow.org/pytorch-elastic-mnist-nccl created
Elastic Policyを使用する
torchrun を使用するために elasticPolicy を作成します。
...
spec:
...
elasticPolicy:
rdzvId: mnist
rdzvBackend: c10d
minReplicas: 2
maxReplicas: 2
nProcPerNode: 8
...
elasticPolicy 各フィールド値に基づいて、 PyTorchJob に使用される環境変数が設定されます。環境変数は torchrun 引数の設定に使用できます。torchrun で使用する引数などに関する詳細な説明は、 公式ドキュメントをご参照ください。
elasticPolicy フィールド |
対応環境変数 | 関連 torchrun 因子 |
説明 |
|---|---|---|---|
rdzvId |
PET_RDZV_ID |
--rdzv-id |
ランデブー用 Job ID |
rdzvBackend |
PET_RDZV_BACKEND |
--rdzv-backend |
ランデブーバックエンド(i.e., c10d) |
minReplicas, maxReplicas |
PET_NNODES |
--nnodes |
ノード数 |
nProcPerNode |
PET_NPROC_PER_NODE |
--nproc-per-node |
ノード当たりの GPU数 |
maxRestarts |
PET_MAX_RESTARTS |
--max-restarts |
最大再起動回数 |
Run Policyを使用する
torchrunを使用するためにrunPolicyを作成します。
...
spec:
runPolicy:
cleanPodPolicy: None
ttlSecondsAfterFinished: 1814400 # TTLを直接設定するフィールド(単位: sec)
...
spec.runPolicyには PyTorchJob の実行および整理に関連するパラメータを明示できます。明示しない場合、デフォルト値が使用されます。spec.runPolicy の下位に明示できるパラメータは、次の通りです。(参考資料: Kubeflow Trainer API Reference v1.9)
cleanPodPolicy-PytorchJobの完了後、Podをどう整理するか決定します。- デフォルト値:
None None: Jobの完了後に Podを削除しないため、今後ログの確認に役立ちます。All: Jobの完了後、すべての Podを削除します。Runningは Jobの完了後に実行中の Podを削除します。特殊な場合を除き、使用することはありません。
- デフォルト値:
ttlSecondsAfterFinished- Jobの完了後、何秒後に Jobを削除するか決めます。activeDeadlineSeconds- Jobの最大実行時間です。明示された時間が経過した後は失敗処理となります。設定されていない場合、jobの実行時間に制限はありません。backoffLimit- Jobの失敗時の最大再試行回数です。
Infinibandの使用
InfiniBandネットワークで接続されたノードで分散学習を行うと、ノード間通信を高速化できます。
以前のセクションで示したユースケースを InfiniBand環境に合わせるには追加すべき明細がいくつかあり、次のように要約できます。
- InfiniBandネットワークが構成された区域の名前を Annotationとして明示します(i.e.,
mlx.navercorp.com/zone=a100-ib) - InfiniBandの使用のために
IPC_LOCKcapabilityをsecurityContextに追加します。 - ResourceRequestの作成時に InfiniBand用リソース(
rdma/hca_shared_devices_a: 1)を割り当てられるよう設定します。 - 分散学習に役立つ Shared Memoryを
volumesに設定します。
Infinibandの使用のために、次のように使用できます。
...
spec:
...
pytorchReplicaSpecs:
Worker:
template:
containers:
- name: pytorch
securityContext: # Infinibandの使用のために securityContextが必要です。
capabilities:
add: ["IPC_LOCK"]
resources:
limits:
...
rdma/hca_shared_devices_a: 1
...
requests:
...
rdma/hca_shared_devices_a: 1
...
# shared memory
volumeMounts:
- mountPath: /dev/shm
name: shared-memory
volumes:
- emptyDir:
medium: Memory
name: shared-memory
...
PytorchJobデバッグ
PytorchJob 使用時に問題が発生してデバッグが必要な場合、次のように環境変数値を設定して必要な情報をロギングするようにできます。
NCCL_DEBUG: NCCLと関連するデバッグTORCH_DISTRIBUTED_DEBUG、TORCH_CPP_LOG_LEVEL: 分散学習に関するデバッグ; 詳細は PyTorch公式ドキュメントをご参照ください。
デバッグのために、次のように使用できます。
...
spec:
...
pytorchReplicaSpecs:
Worker:
template:
containers:
- name: pytorch
...
env:
- name: NCCL_DEBUG
value: "INFO"
- name: TORCH_DISTRIBUTED_DEBUG
value: "DETAIL"
- name: TORCH_CPP_LOG_LEVEL
value: "INFO"
...
外部コンテナレジストリの使用
コンテナレジストリに Secret情報が必要な場合、 Container Secretを作成するを参照して作成できます。
作成された Secretは、次のように使用できます。
...
spec:
...
pytorchReplicaSpecs:
Worker:
template:
containers:
- name: pytorch
imagePullSecrets:
- name: my-harbor-secret # 事前に作成した Docker Credential Secretの名前
...
既存 Volumeの使用
Volumesを通じて作成された Volumeを使用するには、次のように使用できます。
...
spec:
...
pytorchReplicaSpecs:
Worker:
template:
containers:
- name: pytorch
volumeMounts:
- mountPath: /data
name: mnist-data # 下部の spec.volumesに記載した名前
volumes:
- name: mnist-data
persistentVolumeClaim:
claimName: mnist-data # Volumesを通じて作成された PVC名
...
PytorchJobのステータスを確認
kubectl get、 kubectl describe を利用して PyTorchJob のステータスを確認できます。
kubectl get pytorchjob pytorch-elastic-mnist-nccl
NAME STATE AGE
pytorch-elastic-mnist-nccl Running 12s
kubectl describe pytorchjob pytorch-elastic-mnist-nccl
Status:
Completion Time: 2024-11-22T09:16:58Z
Conditions:
Last Transition Time: 2024-11-22T09:15:43Z
Last Update Time: 2024-11-22T09:15:43Z
Message: PyTorchJob pytorch-elastic-mnist-nccl is created.
Reason: PyTorchJobCreated
Status: True
Type: Created
Last Transition Time: 2024-11-22T09:15:48Z
Last Update Time: 2024-11-22T09:15:48Z
Message: PyTorchJob nb12706/pytorch-elastic-mnist-nccl is running.
Reason: PyTorchJobRunning
Status: False
Type: Running
Last Transition Time: 2024-11-22T09:16:58Z
Last Update Time: 2024-11-22T09:16:58Z
Message: PyTorchJob nb12706/pytorch-elastic-mnist-nccl successfully completed.
Reason: PyTorchJobSucceeded
Status: True
Type: Succeeded
Last Reconcile Time: 2024-11-22T09:15:43Z
Replica Statuses:
Worker:
Selector: training.kubeflow.org/job-name=pytorch-elastic-mnist-nccl,training.kubeflow.org/operator-name=pytorchjob-controller,training.kubeflow.org/replica-type=worker
Succeeded: 2
Start Time: 2024-11-22T09:15:44Z
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreatePod 4m21s pytorchjob-controller Created pod: pytorch-elastic-mnist-nccl-worker-0
Normal SuccessfulCreatePod 4m21s pytorchjob-controller Created pod: pytorch-elastic-mnist-nccl-worker-1
Normal SuccessfulCreateService 4m21s pytorchjob-controller Created service: pytorch-elastic-mnist-nccl-worker-0
Normal SuccessfulCreateService 4m21s pytorchjob-controller Created service: pytorch-elastic-mnist-nccl-worker-1
Normal ExitedWithCode 3m7s (x3 over 3m8s) pytorchjob-controller Pod: nb12706.pytorch-elastic-mnist-nccl-worker-1 exited with code 0
Normal ExitedWithCode 3m7s (x2 over 3m8s) pytorchjob-controller Pod: nb12706.pytorch-elastic-mnist-nccl-worker-0 exited with code 0
Normal PyTorchJobSucceeded 3m7s pytorchjob-controller PyTorchJob nb12706/pytorch-elastic-mnist-nccl successfully completed.
Normal JobTerminated 3m6s (x4 over 3m7s) pytorchjob-controller Job has been terminated. Deleting PodGroup
Normal SuccessfulDeletePodGroup 3m6s (x4 over 3m7s) pytorchjob-controller Deleted PodGroup: pytorch-elastic-mnist-nccl
学習 Podが正常に作成されない場合、以下のように Eventsを通じて原因を把握できます。
kubectl describe pytorchjob pytorch-elastic-mnist-nccl
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedCreatePod 47m (x3 over 103m) pytorchjob-controller Error creating: Pods "job-worker-1" is forbidden: exceeded quota: normal-quota, requested: requests.nvidia.com/gpu=1, used: requests.nvidia.com/gpu=2, limited: requests.nvidia.com/gpu=2