mirror of
https://github.com/wassname/ray.git
synced 2026-08-03 13:10:57 +08:00
[tune/sgd] Document func_trainable and add checkpoint context (#9739)
Co-authored-by: krfricke <krfricke@users.noreply.github.com> Co-authored-by: Amog Kamsetty <amogkam@users.noreply.github.com>
This commit is contained in:
co-authored by
krfricke
Amog Kamsetty
parent
e540e425e4
commit
0c3b9ebeef
@@ -213,16 +213,7 @@ In GCP, you can use the following configuration modification:
|
||||
scheduling:
|
||||
- preemptible: true
|
||||
|
||||
Spot instances may be removed suddenly while trials are still running. Often times this may be difficult to deal with when using other distributed hyperparameter optimization frameworks. Tune allows users to mitigate the effects of this by preserving the progress of your model training through checkpointing.
|
||||
|
||||
The easiest way to do this is to subclass the pre-defined ``Trainable`` class and implement ``save_checkpoint``, and ``load_checkpoint`` abstract methods, as seen in the example below:
|
||||
|
||||
.. literalinclude:: /../../python/ray/tune/examples/mnist_pytorch_trainable.py
|
||||
:language: python
|
||||
:start-after: __trainable_example_begin__
|
||||
:end-before: __trainable_example_end__
|
||||
|
||||
This can then be used similarly to the Function API as before:
|
||||
Spot instances may be removed suddenly while trials are still running. Often times this may be difficult to deal with when using other distributed hyperparameter optimization frameworks. Tune allows users to mitigate the effects of this by preserving the progress of your model training through :ref:`checkpointing <tune-function-checkpointing>`.
|
||||
|
||||
.. literalinclude:: /../../python/ray/tune/tests/tutorial.py
|
||||
:language: python
|
||||
|
||||
@@ -25,6 +25,8 @@ need to
|
||||
3. add checkpointing (optional),
|
||||
4. and define the search space for the model tuning
|
||||
|
||||
Optionally, you can seamlessly leverage :ref:`DistributedDataParallel training <tune-torch-ddp>` for each individual Pytorch model within Tune.
|
||||
|
||||
.. note::
|
||||
|
||||
To run this example, you will need to install the following:
|
||||
@@ -74,15 +76,16 @@ The train function
|
||||
Now it gets interesting, because we introduce some changes to the example `from the PyTorch
|
||||
documentation <https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html>`_.
|
||||
|
||||
We wrap the training script in a function ``train_cifar(config, checkpoint=None)``. As you
|
||||
We wrap the training script in a function ``train_cifar(config, checkpoint_dir=None)``. As you
|
||||
can guess, the ``config`` parameter will receive the hyperparameters we would like to
|
||||
train with. The ``checkpoint`` parameter is used to restore checkpoints.
|
||||
train with. The ``checkpoint_dir`` parameter is used to restore checkpoints.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
net = Net(config["l1"], config["l2"])
|
||||
|
||||
if checkpoint:
|
||||
if checkpoint_dir:
|
||||
checkpoint = os.path.join(checkpoint_dir, "checkpoint")
|
||||
net.load_state_dict(torch.load(checkpoint))
|
||||
|
||||
The learning rate of the optimizer is made configurable, too:
|
||||
@@ -97,6 +100,7 @@ with which we iterate through the training and test sets are configurable as wel
|
||||
|
||||
Adding (multi) GPU support with DataParallel
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Image classification benefits largely from GPUs. Luckily, we can continue to use
|
||||
PyTorch's abstractions in Ray Tune. Thus, we can wrap our model in ``nn.DataParallel``
|
||||
to support data parallel training on multiple GPUs:
|
||||
@@ -132,10 +136,9 @@ The most interesting part is the communication with Tune:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
checkpoint_dir = tune.make_checkpoint_dir(epoch)
|
||||
path = os.path.join(checkpoint_dir, "checkpoint")
|
||||
torch.save((net.state_dict(), optimizer.state_dict()), path)
|
||||
tune.save_checkpoint(path)
|
||||
with tune.checkpoint_dir(epoch) as checkpoint_dir:
|
||||
path = os.path.join(checkpoint_dir, "checkpoint")
|
||||
torch.save((net.state_dict(), optimizer.state_dict()), path)
|
||||
|
||||
tune.report(loss=(val_loss / val_steps), accuracy=correct / total)
|
||||
|
||||
@@ -273,6 +276,75 @@ be confirmed on the test set.
|
||||
|
||||
So that's it! You can now tune the parameters of your PyTorch models.
|
||||
|
||||
.. _tune-torch-ddp:
|
||||
|
||||
Advanced: Distributed training with DistributedDataParallel
|
||||
-----------------------------------------------------------
|
||||
|
||||
Some models require multiple nodes to train in a short amount of time. Ray Tune allows you to easily do distributed data parallel training in addition to distributed hyperparameter tuning.
|
||||
|
||||
You can wrap your model in ``torch.nn.parallel.DistributedDataParallel`` to support distributed data parallel training:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from ray.util.sgd.torch import is_distributed_trainable
|
||||
from torch.nn.parallel import DistributedDataParallel
|
||||
|
||||
def train_cifar(config, checkpoint_dir=None, data_dir=None):
|
||||
net = Net(config["l1"], config["l2"])
|
||||
|
||||
device = "cpu"
|
||||
|
||||
#### Using distributed data parallel training
|
||||
if is_distributed_trainable():
|
||||
net = DistributedDataParallel(net)
|
||||
|
||||
if torch.cuda.is_available():
|
||||
device = "cuda"
|
||||
|
||||
net.to(device)
|
||||
|
||||
|
||||
If using checkpointing, be sure to use a :ref:`special checkpoint context manager <tune-ddp-doc>`, ``distributed_checkpoint_dir`` that avoids redundant checkpointing across multiple processes:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from ray.util.sgd.torch import distributed_checkpoint_dir
|
||||
|
||||
#### Using distributed data parallel training
|
||||
# Inside `def train_cifar(...)`,
|
||||
# replace tune.checkpoint_dir() with the following
|
||||
# Avoids redundant checkpointing on different processes.
|
||||
with distributed_checkpoint_dir(step=epoch) as checkpoint_dir:
|
||||
path = os.path.join(checkpoint_dir, "checkpoint")
|
||||
torch.save((net.state_dict(), optimizer.state_dict()), path)
|
||||
|
||||
|
||||
Finally, we need to tell Ray Tune to start multiple distributed processes at once by using ``ray.tune.integration.torch.DistributedTrainableCreator`` (:ref:`docs <tune-ddp-doc>`). This is essentially equivalent to running ``torch.distributed.launch`` for each hyperparameter trial:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# You'll probably want to be running on a distributed Ray cluster.
|
||||
# ray.init(address="auto")
|
||||
|
||||
from ray.util.sgd.integration.torch import DistributedTrainableCreator
|
||||
|
||||
distributed_train_cifar = DistributedTrainableCreator(
|
||||
partial(train_cifar, data_dir=data_dir),
|
||||
use_gpu=True,
|
||||
num_workers=2, # number of parallel workers to use
|
||||
num_cpus_per_worker=8
|
||||
)
|
||||
tune.run(
|
||||
distributed_train_cifar,
|
||||
resources_per_trial=None,
|
||||
config=config,
|
||||
num_samples=num_samples,
|
||||
...
|
||||
)
|
||||
|
||||
See an :doc:`end-to-end example here </tune/examples/ddp_mnist_torch>`.
|
||||
|
||||
If you consider switching to PyTorch Lightning to get rid of some of your boilerplate
|
||||
training code, please know that we also have a walkthrough on :doc:`how to use Tune with
|
||||
PyTorch Lightning models <tune-pytorch-lightning>`.
|
||||
PyTorch Lightning models <tune-pytorch-lightning>`.
|
||||
|
||||
Reference in New Issue
Block a user