我试图了解参数服务器 (PS) 如何在 Amazon SageMaker 上的 Tensorflow 中进行分布式训练。
为了使事情更具体,我可以使用 PS 从 AWS 运行示例:https ://github.com/aws-samples/amazon-sagemaker-script-mode/blob/master/tf-distribution-options/tf-分布式训练.ipynb
这是初始化 Tensorflow 估计器的代码块:
from sagemaker.tensorflow import TensorFlow
git_config = {'repo': 'https://github.com/aws-samples/amazon-sagemaker-script-mode', 'branch': 'master'}
ps_instance_type = 'ml.p3.2xlarge'
ps_instance_count = 2
model_dir = "/opt/ml/model"
distributions = {'parameter_server': {
'enabled': True}
}
hyperparameters = {'epochs': 60, 'batch-size' : 256}
estimator_ps = TensorFlow(
git_config=git_config,
source_dir='tf-distribution-options/code',
entry_point='train_ps.py',
base_job_name='ps-cifar10-tf',
role=role,
framework_version='1.13',
py_version='py3',
hyperparameters=hyperparameters,
train_instance_count=ps_instance_count,
train_instance_type=ps_instance_type,
model_dir=model_dir,
tags = [{'Key' : 'Project', 'Value' : 'cifar10'},{'Key' : 'TensorBoard', 'Value' : 'dist'}],
distributions=distributions)
浏览 Tensorflow 的文档,似乎可以使用设备范围将变量分配给特定的工作人员。但是,在 SageMaker 上运行训练作业时,我从未见过这样做。在 AWS 的示例中,模型定义为:
这是一个片段:
def get_model(learning_rate, weight_decay, optimizer, momentum, size, mpi=False, hvd=False):
model = Sequential()
model.add(Conv2D(32, (3, 3), padding='same', input_shape=(HEIGHT, WIDTH, DEPTH)))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Conv2D(32, (3, 3)))
...
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(NUM_CLASSES))
model.add(Activation('softmax'))
if mpi:
size = hvd.size()
if optimizer.lower() == 'sgd':
...
if mpi:
opt = hvd.DistributedOptimizer(opt)
model.compile(loss='categorical_crossentropy',
optimizer=opt,
metrics=['accuracy'])
return model
在这里,没有对分配策略的引用(除了 MPI,但对于 PS 来说,该标志设置为 False)。不知何故,Tensorflow 或 SageMaker 容器能够决定每个层的变量应该存储在哪里。但是,我在容器代码中没有看到与分发策略有任何关系的任何内容。
我能够运行此代码并使用 1 个和 2 个实例训练模型。当我这样做时,我看到运行时减少了近 50%,这表明正在进行分布式训练。
我的问题是:
- Tensorflow 如何决定 PS 上的变量分布?在示例代码中,没有明确引用设备。不知何故,分配是自动完成的。
- 是否可以查看已为每个 PS 分配了哪些参数?或者看看PS之间的交流是什么样子的?如果是这样,怎么做?