• 单机多卡训练: MirroredStrategy

    单机多卡训练: MirroredStrategy

    tf.distribute.MirroredStrategy 是一种简单且高性能的,数据并行的同步式分布式策略,主要支持多个GPU在同一台主机上训练。使用这种策略时,我们只需实例化一个 MirroredStrategy 策略:

    1. strategy = tf.distribute.MirroredStrategy()

    并将模型构建的代码放入 strategy.scope() 的上下文环境中:

    1. with strategy.scope():
    2. # 模型构建代码

    小技巧

    可以在参数中指定设备,如:

    1. strategy = tf.distribute.MirroredStrategy(devices=["/gpu:0", "/gpu:1"])

    即指定只使用第0、1号GPU参与分布式策略。

    以下代码展示了使用 MirroredStrategy 策略,在TensorFlow Datasets中的部分图像数据集上使用Keras训练MobileNetV2的过程:

    1. import tensorflow as tf
    2. import tensorflow_datasets as tfds
    3.  
    4. num_epochs = 5
    5. batch_size_per_replica = 64
    6. learning_rate = 0.001
    7.  
    8. strategy = tf.distribute.MirroredStrategy()
    9. print('Number of devices: %d' % strategy.num_replicas_in_sync) # 输出设备数量
    10. batch_size = batch_size_per_replica * strategy.num_replicas_in_sync
    11.  
    12. # 载入数据集并预处理
    13. def resize(image, label):
    14. image = tf.image.resize(image, [224, 224]) / 255.0
    15. return image, label
    16.  
    17. # 当as_supervised为True时,返回image和label两个键值
    18. dataset = tfds.load("cats_vs_dogs", split=tfds.Split.TRAIN, as_supervised=True)
    19. dataset = dataset.map(resize).shuffle(1024).batch(batch_size)
    20.  
    21. with strategy.scope():
    22. model = tf.keras.applications.MobileNetV2()
    23. model.compile(
    24. optimizer=tf.keras.optimizers.Adam(learning_rate=learning_rate),
    25. loss=tf.keras.losses.sparse_categorical_crossentropy,
    26. metrics=[tf.keras.metrics.sparse_categorical_accuracy]
    27. )
    28.  
    29. model.fit(dataset, epochs=num_epochs)

    在以下的测试中,我们使用同一台主机上的4块NVIDIA GeForce GTX 1080 Ti显卡进行单机多卡的模型训练。所有测试的epoch数均为5。使用单机无分布式配置时,虽然机器依然具有4块显卡,但程序不使用分布式的设置,直接进行训练,Batch Size设置为64。使用单机四卡时,测试总Batch Size为64(分发到单台机器的Batch Size为16)和总Batch Size为256(分发到单台机器的Batch Size为64)两种情况。

    数据集单机无分布式(Batch Size为64)单机四卡(总Batch Size为64)单机四卡(总Batch Size为256)
    cats_vs_dogs146s/epoch39s/epoch29s/epoch
    tf_flowers22s/epoch7s/epoch5s/epoch

    可见,使用MirroredStrategy后,模型训练的速度有了大幅度的提高。在所有显卡性能接近的情况下,训练时长与显卡的数目接近于反比关系。

    MirroredStrategy 过程简介

    MirroredStrategy的步骤如下:

    • 训练开始前,该策略在所有N个计算设备上均各复制一份完整的模型;

    • 每次训练传入一个批次的数据时,将数据分成N份,分别传入N个计算设备(即数据并行);

    • N个计算设备使用本地变量(镜像变量)分别计算自己所获得的部分数据的梯度;

    • 使用分布式计算的All-reduce操作,在计算设备间高效交换梯度数据并进行求和,使得最终每个设备都有了所有设备的梯度之和;

    • 使用梯度求和的结果更新本地变量(镜像变量);

    • 当所有设备均更新本地变量后,进行下一轮训练(即该并行策略是同步的)。

    默认情况下,TensorFlow中的 MirroredStrategy 策略使用NVIDIA NCCL进行All-reduce操作。

    为了进一步理解MirroredStrategy的过程,以下展示一个手工构建训练流程的示例,相对而言要复杂不少: