Files
tensorflow--tensorflow/tensorflow/python/distribute/__init__.py
T
wehub-resource-sync 8a852e4b4e
cffconvert / validate (push) Has been skipped
License Check / license-check (push) Failing after 2s
chore: import upstream snapshot with attribution
2026-07-13 12:14:16 +08:00

191 lines
10 KiB
Python

# Copyright 2023 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Library for running a computation across multiple devices.
The intent of this library is that you can write an algorithm in a stylized way
and it will be usable with a variety of different `tf.distribute.Strategy`
implementations. Each descendant will implement a different strategy for
distributing the algorithm across multiple devices/machines. Furthermore, these
changes can be hidden inside the specific layers and other library classes that
need special treatment to run in a distributed setting, so that most users'
model definition code can run unchanged. The `tf.distribute.Strategy` API works
the same way with eager and graph execution.
*Guides*
* [TensorFlow v2.x](https://www.tensorflow.org/guide/distributed_training)
* [TensorFlow
v1.x](https://github.com/tensorflow/docs/blob/master/site/en/r1/guide/distribute_strategy.ipynb)
*Tutorials*
* [Distributed Training
Tutorials](https://www.tensorflow.org/tutorials/distribute/)
The tutorials cover how to use `tf.distribute.Strategy` to do distributed
training with native Keras APIs, and custom training loops.
They also cover how to save/load model when using `tf.distribute.Strategy`.
*Glossary*
* _Data parallelism_ is where we run multiple copies of the model
on different slices of the input data. This is in contrast to
_model parallelism_ where we divide up a single copy of a model
across multiple devices.
Note: we only support data parallelism for now, but
hope to add support for model parallelism in the future.
* A _device_ is a CPU or accelerator (e.g. GPUs, TPUs) on some machine that
TensorFlow can run operations on (see e.g. `tf.device`). You may have multiple
devices on a single machine, or be connected to devices on multiple
machines. Devices used to run computations are called _worker devices_.
Devices used to store variables are _parameter devices_. For some strategies,
such as `tf.distribute.MirroredStrategy`, the worker and parameter devices
will be the same (see mirrored variables below). For others they will be
different. For example, `tf.distribute.experimental.CentralStorageStrategy`
puts the variables on a single device (which may be a worker device or may be
the CPU), and `tf.distribute.experimental.ParameterServerStrategy` puts the
variables on separate machines called _parameter servers_ (see below).
* A _replica_ is one copy of the model, running on one slice of the
input data. Right now each replica is executed on its own
worker device, but once we add support for model parallelism
a replica may span multiple worker devices.
* A _host_ is the CPU device on a machine with worker devices, typically
used for running input pipelines.
* A _worker_ is defined to be the physical machine(s) containing the physical
devices (e.g. GPUs, TPUs) on which the replicated computation is executed. A
worker may contain one or more replicas, but contains at least one
replica. Typically one worker will correspond to one machine, but in the case
of very large models with model parallelism, one worker may span multiple
machines. We typically run one input pipeline per worker, feeding all the
replicas on that worker.
* _Synchronous_, or more commonly _sync_, training is where the updates from
each replica are aggregated together before updating the model variables. This
is in contrast to _asynchronous_, or _async_ training, where each replica
updates the model variables independently. You may also have replicas
partitioned into groups which are in sync within each group but async between
groups.
* _Parameter servers_: These are machines that hold a single copy of
parameters/variables, used by some strategies (right now just
`tf.distribute.experimental.ParameterServerStrategy`). All replicas that want
to operate on a variable retrieve it at the beginning of a step and send an
update to be applied at the end of the step. These can in principle support
either sync or async training, but right now we only have support for async
training with parameter servers. Compare to
`tf.distribute.experimental.CentralStorageStrategy`, which puts all variables
on a single device on the same machine (and does sync training), and
`tf.distribute.MirroredStrategy`, which mirrors variables to multiple devices
(see below).
* _Replica context_ vs. _Cross-replica context_ vs _Update context_
A _replica context_ applies
when you execute the computation function that was called with `strategy.run`.
Conceptually, you're in replica context when executing the computation
function that is being replicated.
An _update context_ is entered in a `tf.distribute.StrategyExtended.update`
call.
An _cross-replica context_ is entered when you enter a `strategy.scope`. This
is useful for calling `tf.distribute.Strategy` methods which operate across
the replicas (like `reduce_to()`). By default you start in a _replica context_
(the "default single _replica context_") and then some methods can switch you
back and forth.
* _Distributed value_: Distributed value is represented by the base class
`tf.distribute.DistributedValues`. `tf.distribute.DistributedValues` is useful
to represent values on multiple devices, and it contains a map from replica id
to values. Two representative types of `tf.distribute.DistributedValues`
are `tf.types.experimental.PerReplica` and `tf.types.experimental.Mirrored`
values.
`PerReplica` values exist on the worker devices, with a different value for
each replica. They are produced by iterating through a distributed dataset
returned by `tf.distribute.Strategy.experimental_distribute_dataset` and
`tf.distribute.Strategy.distribute_datasets_from_function`. They are also the
typical result returned by `tf.distribute.Strategy.run`.
`Mirrored` values are like `PerReplica` values, except we know that the value
on all replicas are the same. `Mirrored` values are kept synchronized by the
distribution strategy in use, while `PerReplica` values are left
unsynchronized. `Mirrored` values typically represent model weights. We can
safely read a `Mirrored` value in a cross-replica context by using the value
on any replica, while PerReplica values can only be read within a replica
context.
* _Unwrapping_ and _merging_: Consider calling a function `fn` on multiple
replicas, like `strategy.run(fn, args=[w])` with an
argument `w` that is a `tf.distribute.DistributedValues`. This means `w` will
have a map taking replica id `0` to `w0`, replica id `1` to `w1`, etc.
`strategy.run()` unwraps `w` before calling `fn`, so it calls `fn(w0)` on
device `d0`, `fn(w1)` on device `d1`, etc. It then merges the return
values from `fn()`, which leads to one common object if the returned values
are the same object from every replica, or a `DistributedValues` object
otherwise.
* _Reductions_ and _all-reduce_: A _reduction_ is a method of aggregating
multiple values into one value, like "sum" or "mean". If a strategy is doing
sync training, we will perform a reduction on the gradients to a parameter
from all replicas before applying the update. _All-reduce_ is an algorithm for
performing a reduction on values from multiple devices and making the result
available on all of those devices.
* _Mirrored variables_: These are variables that are created on multiple
devices, where we keep the variables in sync by applying the same
updates to every copy. Mirrored variables are created with
`tf.Variable(...synchronization=tf.VariableSynchronization.ON_WRITE...)`.
Normally they are only used in synchronous training.
* _SyncOnRead variables_
_SyncOnRead variables_ are created by
`tf.Variable(...synchronization=tf.VariableSynchronization.ON_READ...)`, and
they are created on multiple devices. In replica context, each
component variable on the local replica can perform reads and writes without
synchronization with each other. When the
_SyncOnRead variable_ is read in cross-replica context, the values from
component variables are aggregated and returned.
_SyncOnRead variables_ bring a lot of custom configuration difficulty to the
underlying logic, so we do not encourage users to instantiate and use
_SyncOnRead variable_ on their own. We have mainly used _SyncOnRead
variables_ for use cases such as batch norm and metrics. For performance
reasons, we often don't need to keep these statistics in sync every step and
they can be accumulated on each replica independently. The only time we want
to sync them is reporting or checkpointing, which typically happens in
cross-replica context. _SyncOnRead variables_ are also often used by advanced
users who want to control when variable values are aggregated. For example,
users sometimes want to maintain gradients independently on each replica for a
couple of steps without aggregation.
* _Distribute-aware layers_
Layers are generally called in a replica context, except when defining a
Keras functional model. `tf.distribute.in_cross_replica_context` will let you
determine which case you are in. If in a replica context,
the `tf.distribute.get_replica_context` function will return the default
replica context outside a strategy scope, `None` within a strategy scope, and
a `tf.distribute.ReplicaContext` object inside a strategy scope and within a
`tf.distribute.Strategy.run` function. The `ReplicaContext` object has an
`all_reduce` method for aggregating across all replicas.
Note that we provide a default version of `tf.distribute.Strategy` that is
used when no other strategy is in scope, that provides the same API with
reasonable default behavior.
API docstring: tensorflow.distribute
"""