TensorFlow provides a flexible way to handle device placement. By default, TensorFlow will automatically place operations on your GPU or CPU, primarily to optimize performance. However, there are times when you need to manually control which device runs a particular part of your computation, for example to manage GPU memory use or to debug operations on a specific device.
Manual Device Placement
To manually set the device for a specific operation, TensorFlow has the tf.device
context manager. Within this block, all operations will be directed to the specified device. The simplest form of specification for a device is its type and ID.
import tensorflow as tf
# Specify device
with tf.device('/GPU:0'):
a = tf.constant([[1.0, 2.0], [3.0, 4.0]])
b = tf.constant([[1.0, 1.0], [0.0, 1.0]])
c = tf.matmul(a, b)
print(c)
In the above example, TensorFlow will try to place the matrix multiplication operation on GPU 0.
Device Naming Scheme
The device placement naming convention in TensorFlow is hierarchical and consists of the device type, device index (for multi-device setups), and job or task when running distributed TensorFlow.
"/CPU:0"
refers to the CPU of the machine."/GPU:0"
is the first GPU of the machine.- Devices can have more complex names with tasks and jobs, like for multi-machine configurations.
Using Logical Devices
With TensorFlow, you can create logical devices that divide the resources of a physical GPU into multiple portions. This can be helpful for working with models that run training loops and inference simulatenously or with constraints in different parts of the network.
physical_gpus = tf.config.experimental.list_physical_devices('GPU')
if physical_gpus:
try:
# Create 2 logical devices for the first physical GPU
tf.config.experimental.set_virtual_device_configuration(
physical_gpus[0],
[tf.config.experimental.VirtualDeviceConfiguration(memory_limit=4096),
tf.config.experimental.VirtualDeviceConfiguration(memory_limit=4096)])
logical_gpus = tf.config.experimental.list_logical_devices('GPU')
print(len(physical_gpus), "Physical GPUs,",
len(logical_gpus), "Logical GPUs")
except RuntimeError as e:
print(e)
Splitting the GPU's memory helps to run multiple computations ensuring that both do not surpass the capacity. In this snippet, we divide a GPU into two logical devices, each given a memory limit of 4096 MB.
Soft Placements
Soft placement allows TensorFlow to set operations to run on the CPU when a GPU is not available. This feature is useful because it provides robustness to your codebase without making it specific to runtime platforms.
tf.config.set_soft_device_placement(True)
The above line enables soft placement globally in the code. TensorFlow will allocate operations to the default device when the desired hardware is unavailable.
Device Options and Advanced Configurations
For complex device arrangements, configurations are possible through tf.distribute.Strategy
, which helps in running trains, managing replicas across clusters, and optimizing hyperparameters automatically.
Example with Strategy API
strategy = tf.distribute.MirroredStrategy()
with strategy.scope():
# Work within a strategy
model = tf.keras.Sequential([...])
model.compile(...)
model.fit(...)
The use of tf.distribute.MirroredStrategy()
in the above example will compile and distribute the model training across several GPUs to parallelize the work without explicitly setting device IDs.
Conclusion
Handling device placement in TensorFlow configuration can appear complicated. By using concepts like tf.device
, logical device settings, and distribution strategies, developers can finely control the execution of their operations, optimizing for performance and resource use. Whether you are developing standalone applications or large-scale distributed systems, understanding these mechanisms is crucial to fully leverage TensorFlow's power.