mirror of
https://github.com/nerfstudio-project/nerfstudio.git
synced 2026-11-13 11:24:00 +08:00
Add support for gradient clipping (#1331)
implement optional gradient clipping
This commit is contained in:
1 parent
53a830a691
commit
48ec36e53f
1 file changed
+14
-3
@@ -18,7 +18,7 @@ Optimizers class.
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Dict, List, Type
|
||||
from typing import Any, Dict, List, Optional, Type
|
||||
|
||||
import torch
|
||||
from torch.cuda.amp.grad_scaler import GradScaler
|
||||
@@ -36,6 +36,7 @@ class OptimizerConfig(base_config.PrintableConfig):
|
||||
_target: Type = torch.optim.Adam
|
||||
lr: float = 0.0005
|
||||
eps: float = 1e-08
|
||||
max_norm: Optional[float] = None
|
||||
|
||||
# TODO: somehow make this more generic. i dont like the idea of overriding the setup function
|
||||
# but also not sure how to go about passing things into predefined torch objects.
|
||||
@@ -43,6 +44,7 @@ class OptimizerConfig(base_config.PrintableConfig):
|
||||
"""Returns the instantiated object using the config."""
|
||||
kwargs = vars(self).copy()
|
||||
kwargs.pop("_target")
|
||||
kwargs.pop("max_norm")
|
||||
return self._target(params, **kwargs)
|
||||
|
||||
|
||||
@@ -73,9 +75,11 @@ class Optimizers:
|
||||
self.config = config
|
||||
self.optimizers = {}
|
||||
self.schedulers = {}
|
||||
self.parameters = {}
|
||||
for param_group_name, params in param_groups.items():
|
||||
lr_init = config[param_group_name]["optimizer"].lr
|
||||
self.optimizers[param_group_name] = config[param_group_name]["optimizer"].setup(params=params)
|
||||
self.parameters[param_group_name] = params
|
||||
if config[param_group_name]["scheduler"]:
|
||||
self.schedulers[param_group_name] = config[param_group_name]["scheduler"].setup(
|
||||
optimizer=self.optimizers[param_group_name], lr_init=lr_init
|
||||
@@ -109,13 +113,20 @@ class Optimizers:
|
||||
Args:
|
||||
grad_scaler: GradScaler to use
|
||||
"""
|
||||
for _, optimizer in self.optimizers.items():
|
||||
for param_group, optimizer in self.optimizers.items():
|
||||
max_norm = self.config[param_group]["optimizer"].max_norm
|
||||
if max_norm is not None:
|
||||
grad_scaler.unscale_(optimizer)
|
||||
torch.nn.utils.clip_grad_norm_(self.parameters[param_group], max_norm)
|
||||
grad_scaler.step(optimizer)
|
||||
|
||||
def optimizer_step_all(self):
|
||||
"""Run step for all optimizers."""
|
||||
for _, optimizer in self.optimizers.items():
|
||||
for param_group, optimizer in self.optimizers.items():
|
||||
# note that they key is the parameter name
|
||||
max_norm = self.config[param_group]["optimizer"].max_norm
|
||||
if max_norm is not None:
|
||||
torch.nn.utils.clip_grad_norm_(self.parameters[param_group], max_norm)
|
||||
optimizer.step()
|
||||
|
||||
def scheduler_step_all(self, step: int) -> None:
|
||||
|
||||
Reference in new issue
Block a user