- 分布式训练training-operator
分布式训练(Distributed Training)是针对大规模深度学习模型训练的改进,通过将计算操作分发到多台机器上,同时利用网络通信技术实现模型参数共享和梯度信息传递,提高训练效率。在Kubernetes平台上,可以利用training-operator这一工具来实现分布式训练。下面是具体操作步骤:
1)创建Kubernetes集群
2)安装training-operator
kubectl apply -f https://raw.githubusercontent.com/kubeflow/kubeflow/1.2-branch/bootstrap/config/crd/applications/app.k8s.io_v1beta1_trainingjobs.yaml
kubectl apply -f https://raw.githubusercontent.com/kubeflow/kubeflow/1.2-branch/bootstrap/config/default_ns/upstream-images/training-controller-configmap.yaml
kubectl apply -f https://raw.githubusercontent.com/kubeflow/kubeflow/1.2-branch/bootstrap/config/default_ns/upstream-images/pytorch-operator.yaml
3)创建PyTorch分布式训练Job
apiVersion: "kubeflow.org/v1"
kind: "TrainingJob"
metadata:
name: "pytorch-dist"
spec:
pyTorchJob:
chief:
replicas: 1
restartPolicy: OnFailure
template:
spec:
containers:
- image: "pytorch/pytorch:1.6.0-cuda10.1-cudnn7-runtime"
name: pytorch
command:
- "python"
args:
- "-m"
- "torch.distributed.launch"
- "--nproc_per_node=2"
- "--nnodes=1"
- "--node_rank=0"
- "--master_addr=$(KUBERNETES_SERVICE_HOST)"
- "--master_port=2222"
- "/home/pytorch/train.py"
上述配置中定义了一个名为“pytorch-dist”的分布式训练任务,其中包含一个主节点和一个工作节点,每个节点有2个处理器核心,共同训练一个PyTorch深度学习模型。
- pytorch-distributed RANK变量不统一解决
在PyTorch distributed训练中,每个进程都有一个唯一的rank变量,用于在分布式环境中标识进程的唯一身份。然而,在一些情况下,可能会出现多个进程拥有相同的rank值的情况,这会导致分布式训练失败。下面是解决方案:
1)检查每个进程的作者和主机名是否唯一,如果不唯一可以通过以下命令进行修改:
import socket
import os
os.environ['HOSTNAME'] = socket.gethostname()
以上代码将hostname设置为当前进程所在主机的主机名。
2)如果上述方法无法解决问题,可以通过设置进程的启动端口号来保证rank值唯一,如下:
def next_free_port():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('localhost', 0))
addr, port = s.getsockname()
s.close()
return port
# 获取空闲端口号
port = next_free_port()
# 通过设置环境变量PYTORCH_DIST_INIT_METHOD来设置节点之间的初始化方式
os.environ['PYTORCH_DIST_INIT_METHOD'] = 'tcp://127.0.0.1:{}'.format(port)
以上代码获取一个空闲的端口号,通过环境变量PYTORCH_DIST_INIT_METHOD将该端口号作为初始化方式之一。这样,即使多个进程拥有相同的rank值,也能保证每个进程的初始化方式是唯一的,避免分布式训练失败的问题。
示例说明:
示例1:假设在一个由2个进程组成的分布式训练任务中,每个进程的作者和主机名均相同。这时可以通过设置进程的启动端口号来保证rank值唯一:
import socket
import os
# 设置hostname
os.environ['HOSTNAME'] = socket.gethostname()
# 获取空闲端口号
def next_free_port():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('localhost', 0))
addr, port = s.getsockname()
s.close()
return port
port = next_free_port()
# 设置环境变量PYTORCH_DIST_INIT_METHOD
os.environ['PYTORCH_DIST_INIT_METHOD'] = 'tcp://127.0.0.1:{}'.format(port)
# 启动分布式训练任务
...
示例2:假设在一个由4个进程组成的分布式训练任务中,每个进程的作者和主机名均相同。这时可以通过设置进程的启动端口号来保证rank值唯一:
import socket
import os
# 设置hostname
os.environ['HOSTNAME'] = socket.gethostname()
# 获取空闲端口号
def next_free_port():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('localhost', 0))
addr, port = s.getsockname()
s.close()
return port
# 设置环境变量PYTORCH_DIST_INIT_METHOD
os.environ['PYTORCH_DIST_INIT_METHOD'] = 'tcp://127.0.0.1:{}'.format(next_free_port())
# 启动分布式训练任务
...
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:分布式训练training-operator和pytorch-distributed RANK变量不统一解决 - Python技术站