mirror of
https://github.com/hanzoai/gym-v1.git
synced 2026-11-03 00:15:37 +00:00
61 lines
1.9 KiB
Python
61 lines
1.9 KiB
Python
import torch
|
|
|
|
from typing import Type, Union, Optional
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Dict, Any
|
|
|
|
|
|
@dataclass
|
|
class OptimSpec:
|
|
cls: Type[torch.optim.Optimizer] = torch.optim.AdamW
|
|
kwargs: Dict[str, Any] = None # e.g. {'lr': 3e-4}
|
|
|
|
def __init__(self, cls: Type[torch.optim.Optimizer], **kwargs: Dict[str, Any]):
|
|
self.cls = cls
|
|
self.kwargs = kwargs
|
|
|
|
@classmethod
|
|
def from_string(cls, name: str, **kwargs) -> "OptimSpec":
|
|
"""Create OptimSpec from optimizer name string."""
|
|
optimizer_map = {
|
|
"adam": torch.optim.Adam,
|
|
"adamw": torch.optim.AdamW,
|
|
"sgd": torch.optim.SGD,
|
|
"rmsprop": torch.optim.RMSprop,
|
|
"adagrad": torch.optim.Adagrad,
|
|
}
|
|
|
|
name_lower = name.lower()
|
|
if name_lower not in optimizer_map:
|
|
available = ", ".join(optimizer_map.keys())
|
|
raise ValueError(
|
|
f"Unknown optimizer '{name}'. Available options: {available}"
|
|
)
|
|
|
|
return cls(optimizer_map[name_lower], **kwargs)
|
|
|
|
def build(self, model):
|
|
return self.cls(model.parameters(), **(self.kwargs or {}))
|
|
|
|
|
|
def ensure_optim_spec(
|
|
optim: Union[str, OptimSpec, None], default: Optional[OptimSpec] = None, **kwargs
|
|
) -> OptimSpec:
|
|
"""Convert string or OptimSpec to OptimSpec instance."""
|
|
if optim is None:
|
|
if default is None:
|
|
return OptimSpec(torch.optim.AdamW, **kwargs)
|
|
else:
|
|
return default
|
|
elif isinstance(optim, str):
|
|
return OptimSpec.from_string(optim, **kwargs)
|
|
elif isinstance(optim, OptimSpec):
|
|
# If additional kwargs provided, merge them
|
|
if kwargs:
|
|
merged_kwargs = {**(optim.kwargs or {}), **kwargs}
|
|
return OptimSpec(optim.cls, **merged_kwargs)
|
|
return optim
|
|
else:
|
|
raise TypeError(f"Expected str, OptimSpec, or None, got {type(optim)}")
|