python tf.distribute.strategy.scope()中必须包含什么?

i7uq4tfw  于 2023-02-18  发布在  Python
关注(0)|答案(5)|浏览(134)

我目前正在tensorflow 2.0中使用分销策略,如此处所述https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/distribute/Strategy
我想知道with ...scope()块中必须包含哪些内容,以及哪些内容是“可选的”。
特别是以下操作。我是否必须将...放入with ...scope()中才能进行分发?

  • 优化器创建
  • 数据集创建
  • 数据集实验_分布_数据集
  • 应用梯度调用
  • 循环的数据集迭代
  • 实验运行v2

我已经玩了一点,我的代码似乎工作,甚至当我没有使用with ...scope在所有。我很困惑,如果这有一些副作用,我只是没有看到现在。
不带scope的代码:

strat = tf.distribute.MirroredStrategy()

BATCH_SIZE_PER_REPLICA = 5

print('Replicas: ', strat.num_replicas_in_sync)

global_batch_size = (BATCH_SIZE_PER_REPLICA * strat.num_replicas_in_sync)

dataset = tf.data.Dataset.from_tensors(tf.random.normal([100])).repeat(1000).batch(
    global_batch_size)

g = Model('m', 10, 10, 1, 3)

dist_dataset = strat.experimental_distribute_dataset(dataset)

@tf.function
def train_step(dist_inputs):
  def step_fn(inputs):
    print([(v.name, v.device) for v in g.trainable_variables])
    return g(inputs)

  out = strat.experimental_run_v2(step_fn, args=(dist_inputs,))

for inputs in dist_dataset:
    train_step(inputs)
    break

范围代码:

strat = tf.distribute.MirroredStrategy()

BATCH_SIZE_PER_REPLICA = 5

print('Replicas: ', strat.num_replicas_in_sync)

global_batch_size = (BATCH_SIZE_PER_REPLICA * strat.num_replicas_in_sync)

with strat.scope():
    dataset = tf.data.Dataset.from_tensors(tf.random.normal([100])).repeat(1000).batch(
        global_batch_size)

    g = Model('m', 10, 10, 1, 3)

    dist_dataset = strat.experimental_distribute_dataset(dataset)

    @tf.function
    def train_step(dist_inputs):
        def step_fn(inputs):
            print([(v.name, v.device) for v in g.trainable_variables])
            return g(inputs)

        out = strat.experimental_run_v2(step_fn, args=(dist_inputs,))

    for inputs in dist_dataset:
        train_step(inputs)
        break

编辑:似乎strat.experimental_run_v2自动进入strat的范围,那么with strat.scope()为什么会存在呢?

yi0zb3m4

yi0zb3m41#

根据我的实验,唯一需要声明的是模型创建,如果你使用use Keras .fit()而不是自定义训练,那么model.compile()也必须在里面。
你可以这样做:

def create_model():
    """ This can be outside of the scope
    """
    ...
    return model

with strategy.scope():
    model = create_model()

如果您使用tf.train.Checkpoint,那么请确保它的示例化和checkpoint.resume()的调用都在作用域内。

ctehm74n

ctehm74n2#

你不需要把数据集、数据集迭代循环等放在scope()里面,你只需要定义你的顺序模型和它的编译。

mirrored_strategy = tf.distribute.MirroredStrategy()
with mirrored_strategy.scope():
  model = tf.keras.Sequential()
  model.add(tf.keras.layers.Embedding(vocab_size, 64))
  model.add(tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64, activation= 'tanh', recurrent_activation= 'sigmoid', recurrent_dropout = 0, unroll = False, use_bias= True)))
  # One or more dense layers.
  # Edit the list in the `for` line to experiment with layer sizes.
  for units in [64, 64]:
    model.add(tf.keras.layers.Dense(units, activation='relu'))
  # Output layer. The first argument is the number of labels.
  model.add(tf.keras.layers.Dense(3, activation='softmax'))
  model.compile(optimizer='adam',
                loss='sparse_categorical_crossentropy',
                metrics=['accuracy'])

它将在每个GPU上创建模型及其参数的副本,并在训练过程中进行训练。您定义的批处理大小将除以可用的GPU数量,这些批处理将发送到这些GPU,例如,如果您有batch_size = 64和两个GPU,则每个GPU将获得32个批处理大小。您可以在此处阅读更多信息。

aamkag61

aamkag613#

你不需要调用strat.scope()
experimental_run_v2是将计算放入strat.scope()的简单方法。
请参见下面的experimental_run_v2源代码,它实际上为您将fn Package 在作用域中。
https://github.com/tensorflow/tensorflow/blob/919dfc3d066e72ee02baa11fbf7b035d9944daa9/tensorflow/python/distribute/distribute_lib.py#L729

xfb7svmp

xfb7svmp4#

我在Kaggle上使用TPU的经验显示了这些效果:
1.创建策略并在构建数据集(tf.dataset.Dataset)之前连接到TPU。否则,特别是对于更复杂的数据集加载/预处理,TPU单元会抱怨。
1.在with strategy.scope():内放入:
a)模型创建
B)度量的示例化
(c)编制模式
对于简单的指标,即使在范围外编译也能工作,但是当添加自定义指标列表时,TPU再次开始抱怨,并将所有指标都放在.scope()下解决了这个问题。

gg58donl

gg58donl5#

这在官方文件中有详细说明:
https://www.tensorflow.org/api_docs/python/tf/distribute/Strategy#scope
本质上,任何创建需要跨副本分布的变量的东西都应该在策略的范围内初始化(例如,模型、优化器、度量)。
如果您使用的是高级模型API(model.fit()model.predict()),那么很可能所有的分布式变量创建都将在模型创建和编译步骤中进行,因此,如Rishabh Sahrawat's answer所示,在策略的作用域中只需要这两个步骤。
但是,如果您正在编写一个自定义训练循环,并且需要显式定义变量,那么这些变量也需要在作用域中:

strategy = tf.distribute.MirroredStrategy()
with strategy.scope():
  model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(10)
  ])
  optimizer = tf.keras.optimizers.Adam()
  loss_object = tf.keras.losses.SparseCategoricalCrossentropy(
    from_logits=True, reduction=tf.keras.losses.Reduction.NONE
  )
  def loss_fn(labels, predictions):
    per_example_loss = loss_object(labels, predictions)
    return tf.nn.compute_average_loss(per_example_loss, global_batch_size=GLOBAL_BATCH_SIZE)
  train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name='train_accuracy')

注意,您可以不使用范围上下文管理器来输入策略的范围,例如通过strategy.runstrategy.reduce API。
处理需要在with ...scope()块中的操作列表:

  • 优化程序创建:* * 是**(手动或在范围内调用model.compile()
  • 数据集创建:* * 没有**
  • 数据集实验_分布_数据集:* * 没有**
  • apply_gradients调用:* * 否***--如文档中所建议,应使用strategy.run调用培训步骤,这在内部属于策略范围。
  • 实验运行版本2:* * 否***--现在不推荐使用strategy.run,因为它不需要 Package 在策略的作用域中。

相关问题