我试图为以下示例建立一个非常简单的“最小工作示例”:在tf.train.MonitoredSession中使用通过tf.keras构建的模型,并使用带有tf.distribute.ParameterServerStrategy的tf.Server。
最终,我的目标是在分布式环境中使用tf.keras模型,该环境中有两个工作人员,每个工作人员具有一个GPU和一个参数服务器。
该模型是根据此处的示例和文档构建的:https://www.tensorflow.org/versions/r1.12/api_docs/python/tf/keras/models/Sequential
根据此处找到的文档使用参数服务器策略:https://www.tensorflow.org/versions/r1.12/api_docs/python/tf/contrib/distribute/ParameterServerStrategy
包括设备放置和使用MonitoredSession在内的整体设置来自:https://github.com/tensorflow/examples/blob/master/community/en/docs/deploy/distributed.md
我已经在使用“ allow_soft_placement”选项,并且正在“模拟”仅具有单个CPU的本地计算机上的分布式设置,因为我试图解决的实际分布式设置中存在不同的问题通过使用MonitoredSession来自动处理变量初始化。
此代码与“正常”(不受监视)tf.Session和变量初始化-全局,局部,模型变量和表等一起使用。
解冻图形的行对于使用tf.keras.Model的fit函数中的tf.data.Dataset是必需的,因为必须创建迭代器-这会在冻结的图形中导致错误。 / p>
这是我要运行的代码。我使用tensorflow 1.12.0和python 3.6.7。我也尝试过python 2.7,结果相同。
除了安装tensorflow外,该代码无需设置。
import sys
import tensorflow as tf
def main(argv):
# Create local cluster config for run_local_server.sh script.
cluster = tf.train.ClusterSpec({"worker": ["localhost:2222"], "ps": ["localhost:2223"]})
task = 0
job = str(argv[0])
# Number of GPUs per worker
GPU_PER_WORKER = 0
config = tf.ConfigProto(allow_soft_placement=True, log_device_placement=False)
server = tf.train.Server(cluster, job_name=job, task_index=task,config=config)
strategy = tf.contrib.distribute.ParameterServerStrategy(num_gpus_per_worker=GPU_PER_WORKER)
strategy.configure(session_config=config, cluster_spec=cluster,task_type=job,task_id=task)
with strategy.scope():
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_train = x_train.astype('float32') / 255
x_test = x_test.astype('float32') / 255
# Reshape input data from (28, 28) to (28, 28, 1)
w, h = 28, 28
x_train = x_train.reshape(x_train.shape[0], w, h, 1)
x_test = x_test.reshape(x_test.shape[0], w, h, 1)
# One-hot encode the labels
y_train = tf.keras.utils.to_categorical(y_train, 10)
y_test = tf.keras.utils.to_categorical(y_test, 10)
train_ds = tf.data.Dataset.zip((tf.data.Dataset.from_tensor_slices(x_train),tf.data.Dataset.from_tensor_slices(y_train))).repeat().shuffle(60000).batch(10)
val_ds = tf.data.Dataset.zip((tf.data.Dataset.from_tensor_slices(x_test),tf.data.Dataset.from_tensor_slices(y_test))).repeat().shuffle(10000).batch(10)
with tf.device(tf.train.replica_device_setter(worker_device="/job:worker/task:%d" % task,cluster=cluster)):
model = tf.keras.models.Sequential()
conv0 = tf.keras.layers.Conv2D(filters=16, data_format='channels_last', padding="valid", kernel_size=4, strides=1, input_shape=(28,28,1), activation=tf.keras.activations.relu)
model.add(conv0)
flatten = tf.keras.layers.Flatten()
model.add(flatten)
dense1 = tf.keras.layers.Dense(10, activation=tf.keras.activations.softmax)
model.add(dense1)
model.compile(tf.contrib.optimizer_v2.AdamOptimizer(0.001), loss=tf.keras.metrics.mean_absolute_error,metrics=['accuracy'],distribute=strategy)
if job == "ps":
server.join()
elif job == "worker":
with tf.train.MonitoredSession(session_creator=tf.train.ChiefSessionCreator(master=server.target,config=config)) as sess:
sess.graph._unsafe_unfinalize()
history = model.fit(x=train_ds, validation_data=val_ds, validation_steps=1000, steps_per_epoch=100, epochs=60)
if __name__ == "__main__":
main(sys.argv[1:])
代码不需要大量的设置,因为数据集是从Web加载并转换为tf.data.Dataset的,因为这是我要用真实数据组织管道的方式。 MNIST数据设置示例摘自 https://www.kaggle.com/margaretmz/mnist-with-tf-keras。
我希望代码不会因变量或操作位置错误而失败,因为我基本上是通过使用strategy.scope()
和tf.device(tf.train.replica_device_setter(worker_device="/job:worker/task:%d" % task,cluster=cluster))
将所有这些决定留给Tensorflow的实现