pytorch-optimizer 3.3.2__tar.gz → 3.3.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/PKG-INFO +12 -5
  2. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/README.md +8 -1
  3. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pyproject.toml +10 -10
  4. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/__init__.py +3 -0
  5. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/base/optimizer.py +10 -0
  6. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/__init__.py +5 -0
  7. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/adamw.py +3 -4
  8. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/ademamix.py +7 -1
  9. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/adopt.py +9 -2
  10. pytorch_optimizer-3.3.3/pytorch_optimizer/optimizer/experimental/__init__.py +0 -0
  11. pytorch_optimizer-3.3.3/pytorch_optimizer/optimizer/experimental/ranger25.py +184 -0
  12. pytorch_optimizer-3.3.3/pytorch_optimizer/optimizer/grams.py +108 -0
  13. pytorch_optimizer-3.3.3/pytorch_optimizer/optimizer/orthograd.py +48 -0
  14. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/prodigy.py +12 -6
  15. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/rotograd.py +2 -2
  16. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/LICENSE +0 -0
  17. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/base/__init__.py +0 -0
  18. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/base/exception.py +0 -0
  19. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/base/scheduler.py +0 -0
  20. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/base/types.py +0 -0
  21. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/loss/__init__.py +0 -0
  22. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/loss/bi_tempered.py +0 -0
  23. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/loss/cross_entropy.py +0 -0
  24. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/loss/dice.py +0 -0
  25. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/loss/f1.py +0 -0
  26. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/loss/focal.py +0 -0
  27. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/loss/jaccard.py +0 -0
  28. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/loss/ldam.py +0 -0
  29. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/loss/lovasz.py +0 -0
  30. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/loss/tversky.py +0 -0
  31. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/lr_scheduler/__init__.py +0 -0
  32. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/lr_scheduler/chebyshev.py +0 -0
  33. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/lr_scheduler/cosine_anealing.py +0 -0
  34. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/lr_scheduler/experimental/__init__.py +0 -0
  35. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/lr_scheduler/experimental/deberta_v3_lr_scheduler.py +0 -0
  36. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/lr_scheduler/linear_warmup.py +0 -0
  37. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/lr_scheduler/proportion.py +0 -0
  38. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/lr_scheduler/rex.py +0 -0
  39. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/lr_scheduler/wsd.py +0 -0
  40. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/a2grad.py +0 -0
  41. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/adabelief.py +0 -0
  42. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/adabound.py +0 -0
  43. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/adadelta.py +0 -0
  44. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/adafactor.py +0 -0
  45. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/adahessian.py +0 -0
  46. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/adai.py +0 -0
  47. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/adalite.py +0 -0
  48. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/adam_mini.py +0 -0
  49. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/adamax.py +0 -0
  50. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/adamg.py +0 -0
  51. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/adamod.py +0 -0
  52. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/adamp.py +0 -0
  53. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/adams.py +0 -0
  54. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/adan.py +0 -0
  55. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/adanorm.py +0 -0
  56. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/adapnm.py +0 -0
  57. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/adashift.py +0 -0
  58. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/adasmooth.py +0 -0
  59. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/agc.py +0 -0
  60. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/aggmo.py +0 -0
  61. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/aida.py +0 -0
  62. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/alig.py +0 -0
  63. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/amos.py +0 -0
  64. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/apollo.py +0 -0
  65. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/avagrad.py +0 -0
  66. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/came.py +0 -0
  67. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/dadapt.py +0 -0
  68. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/demo.py +0 -0
  69. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/diffgrad.py +0 -0
  70. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/fadam.py +0 -0
  71. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/fp16.py +0 -0
  72. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/fromage.py +0 -0
  73. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/ftrl.py +0 -0
  74. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/galore.py +0 -0
  75. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/galore_utils.py +0 -0
  76. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/gc.py +0 -0
  77. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/gravity.py +0 -0
  78. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/grokfast.py +0 -0
  79. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/kate.py +0 -0
  80. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/lamb.py +0 -0
  81. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/laprop.py +0 -0
  82. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/lars.py +0 -0
  83. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/lion.py +0 -0
  84. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/lomo.py +0 -0
  85. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/lookahead.py +0 -0
  86. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/madgrad.py +0 -0
  87. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/mars.py +0 -0
  88. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/msvag.py +0 -0
  89. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/muon.py +0 -0
  90. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/nero.py +0 -0
  91. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/novograd.py +0 -0
  92. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/padam.py +0 -0
  93. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/pcgrad.py +0 -0
  94. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/pid.py +0 -0
  95. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/pnm.py +0 -0
  96. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/qhadam.py +0 -0
  97. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/qhm.py +0 -0
  98. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/radam.py +0 -0
  99. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/ranger.py +0 -0
  100. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/ranger21.py +0 -0
  101. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/sam.py +0 -0
  102. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/schedulefree.py +0 -0
  103. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/sgd.py +0 -0
  104. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/sgdp.py +0 -0
  105. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/shampoo.py +0 -0
  106. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/shampoo_utils.py +0 -0
  107. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/sm3.py +0 -0
  108. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/soap.py +0 -0
  109. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/sophia.py +0 -0
  110. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/srmm.py +0 -0
  111. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/swats.py +0 -0
  112. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/tiger.py +0 -0
  113. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/trac.py +0 -0
  114. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/utils.py +0 -0
  115. {pytorch_optimizer-3.3.2 → pytorch_optimizer-3.3.3}/pytorch_optimizer/optimizer/yogi.py +0 -0
@@ -1,10 +1,9 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: pytorch_optimizer
3
- Version: 3.3.2
3
+ Version: 3.3.3
4
4
  Summary: optimizer & lr scheduler & objective function collections in PyTorch
5
- Home-page: https://github.com/kozistr/pytorch_optimizer
6
5
  License: Apache-2.0
7
- Keywords: pytorch,deep-learning,optimizer,lr scheduler,A2Grad,ASGD,AccSGD,AdaBelief,AdaBound,AdaDelta,AdaFactor,AdaMax,AdamG,AdaMod,AdaNorm,AdaPNM,AdaSmooth,AdEMAMix,ADOPT,AdaHessian,Adai,Adalite,AdaLomo,AdamMini,AdamP,AdamS,Adan,AggMo,Aida,AliG,Amos,Apollo,APOLLO,AvaGrad,bSAM,CAME,DAdaptAdaGrad,DAdaptAdam,DAdaptAdan,DAdaptSGD,DAdaptLion,DeMo,DiffGrad,FAdam,Fromage,FTRL,GaLore,Gravity,GrokFast,GSAM,Kate,Lamb,LaProp,LARS,Lion,LOMO,Lookahead,MADGRAD,MARS,MSVAG,Muno,Nero,NovoGrad,PAdam,PCGrad,PID,PNM,Prodigy,QHAdam,QHM,RAdam,Ranger,Ranger21,RotoGrad,SAM,ScheduleFreeSGD,ScheduleFreeAdamW,ScheduleFreeRAdam,SGDP,Shampoo,ScalableShampoo,SGDW,SignSGD,SM3,SOAP,SopihaH,SRMM,StableAdamW,SWATS,Tiger,TRAC,WSAM,Yogi,BCE,BCEFocal,Focal,FocalCosine,SoftF1,Dice,LDAM,Jaccard,Bi-Tempered,Tversky,FocalTversky,LovaszHinge,bitsandbytes,WSD,QGaLore
6
+ Keywords: pytorch,deep-learning,optimizer,lr scheduler,A2Grad,ASGD,AccSGD,AdaBelief,AdaBound,AdaDelta,AdaFactor,AdaMax,AdamG,AdaMod,AdaNorm,AdaPNM,AdaSmooth,AdEMAMix,ADOPT,AdaHessian,Adai,Adalite,AdaLomo,AdamMini,AdamP,AdamS,Adan,AggMo,Aida,AliG,Amos,Apollo,APOLLO,AvaGrad,bSAM,CAME,DAdaptAdaGrad,DAdaptAdam,DAdaptAdan,DAdaptSGD,DAdaptLion,DeMo,DiffGrad,FAdam,Fromage,FTRL,GaLore,Grams,Gravity,GrokFast,GSAM,Kate,Lamb,LaProp,LARS,Lion,LOMO,Lookahead,MADGRAD,MARS,MSVAG,Muno,Nero,NovoGrad,OrthoGrad,PAdam,PCGrad,PID,PNM,Prodigy,QHAdam,QHM,RAdam,Ranger,Ranger21,RotoGrad,SAM,ScheduleFreeSGD,ScheduleFreeAdamW,ScheduleFreeRAdam,SGDP,Shampoo,ScalableShampoo,SGDW,SignSGD,SM3,SOAP,SopihaH,SRMM,StableAdamW,SWATS,Tiger,TRAC,WSAM,Yogi,BCE,BCEFocal,Focal,FocalCosine,SoftF1,Dice,LDAM,Jaccard,Bi-Tempered,Tversky,FocalTversky,LovaszHinge,bitsandbytes,WSD,QGaLore
8
7
  Author: kozistr
9
8
  Author-email: kozistr@gmail.com
10
9
  Maintainer: kozistr
@@ -36,6 +35,7 @@ Requires-Dist: numpy (<=1.24.4) ; python_version < "3.9"
36
35
  Requires-Dist: numpy (>1.24.4) ; python_version >= "3.9"
37
36
  Requires-Dist: torch (>=1.10) ; python_version >= "3.8"
38
37
  Project-URL: Documentation, https://pytorch-optimizers.readthedocs.io/en/latest
38
+ Project-URL: Homepage, https://github.com/kozistr/pytorch_optimizer
39
39
  Project-URL: Repository, https://github.com/kozistr/pytorch_optimizer
40
40
  Description-Content-Type: text/markdown
41
41
 
@@ -51,7 +51,7 @@ Description-Content-Type: text/markdown
51
51
 
52
52
  ## The reasons why you use `pytorch-optimizer`.
53
53
 
54
- * Wide range of supported optimizers. Currently, **86 optimizers (+ `bitsandbytes`, `qgalore`, `torchao`)**, **16 lr schedulers**, and **13 loss functions** are supported!
54
+ * Wide range of supported optimizers. Currently, **89 optimizers (+ `bitsandbytes`, `qgalore`, `torchao`)**, **16 lr schedulers**, and **13 loss functions** are supported!
55
55
  * Including many variants such as `Cautious`, `AdamD`, `Gradient Centrailiaztion`
56
56
  * Easy to use, clean, and tested codes
57
57
  * Active maintenance
@@ -236,6 +236,9 @@ get_supported_optimizers(['adam*', 'ranger*'])
236
236
  | APOLLO | *SGD-like Memory, AdamW-level Performance* | [github](https://github.com/zhuhanqing/APOLLO) | <https://arxiv.org/abs/2412.05270> | [cite](https://github.com/zhuhanqing/APOLLO?tab=readme-ov-file#-citation) |
237
237
  | MARS | *Unleashing the Power of Variance Reduction for Training Large Models* | [github](https://github.com/AGI-Arena/MARS) | <https://arxiv.org/abs/2411.10438> | [cite](https://github.com/AGI-Arena/MARS/tree/main?tab=readme-ov-file#citation) |
238
238
  | SGDSaI | *No More Adam: Learning Rate Scaling at Initialization is All You Need* | [github](https://github.com/AnonymousAlethiometer/SGD_SaI) | <https://arxiv.org/abs/2411.10438> | [cite](https://github.com/AnonymousAlethiometer/SGD_SaI?tab=readme-ov-file#citation) |
239
+ | Grams | *Gradient Descent with Adaptive Momentum Scaling* | | <https://arxiv.org/abs/2412.17107> | [cite](https://ui.adsabs.harvard.edu/abs/2024arXiv241217107C/exportcitation) |
240
+ | OrthoGrad | *Grokking at the Edge of Numerical Stability* | [github](https://github.com/LucasPrietoAl/grokking-at-the-edge-of-numerical-stability) | <https://arxiv.org/abs/2501.04697> | [cite](https://github.com/LucasPrietoAl/grokking-at-the-edge-of-numerical-stability?tab=readme-ov-file#citation) |
241
+ | Adam-ATAN2 | *Scaling Exponents Across Parameterizations and Optimizers* | | <https://arxiv.org/abs/2407.05872> | [cite](https://ui.adsabs.harvard.edu/abs/2024arXiv240705872E/exportcitation) |
239
242
 
240
243
  ## Supported LR Scheduler
241
244
 
@@ -411,6 +414,10 @@ Correcting the norm of a gradient in each iteration based on the adaptive traini
411
414
 
412
415
  Updates only occur when the proposed update direction aligns with the current gradient.
413
416
 
417
+ ### Adam-ATAN2
418
+
419
+ Adam-atan2 is a new numerically stable, scale-invariant version of Adam that eliminates the epsilon hyperparameter.
420
+
414
421
  ## Frequently asked questions
415
422
 
416
423
  [here](docs/qa.md)
@@ -10,7 +10,7 @@
10
10
 
11
11
  ## The reasons why you use `pytorch-optimizer`.
12
12
 
13
- * Wide range of supported optimizers. Currently, **86 optimizers (+ `bitsandbytes`, `qgalore`, `torchao`)**, **16 lr schedulers**, and **13 loss functions** are supported!
13
+ * Wide range of supported optimizers. Currently, **89 optimizers (+ `bitsandbytes`, `qgalore`, `torchao`)**, **16 lr schedulers**, and **13 loss functions** are supported!
14
14
  * Including many variants such as `Cautious`, `AdamD`, `Gradient Centrailiaztion`
15
15
  * Easy to use, clean, and tested codes
16
16
  * Active maintenance
@@ -195,6 +195,9 @@ get_supported_optimizers(['adam*', 'ranger*'])
195
195
  | APOLLO | *SGD-like Memory, AdamW-level Performance* | [github](https://github.com/zhuhanqing/APOLLO) | <https://arxiv.org/abs/2412.05270> | [cite](https://github.com/zhuhanqing/APOLLO?tab=readme-ov-file#-citation) |
196
196
  | MARS | *Unleashing the Power of Variance Reduction for Training Large Models* | [github](https://github.com/AGI-Arena/MARS) | <https://arxiv.org/abs/2411.10438> | [cite](https://github.com/AGI-Arena/MARS/tree/main?tab=readme-ov-file#citation) |
197
197
  | SGDSaI | *No More Adam: Learning Rate Scaling at Initialization is All You Need* | [github](https://github.com/AnonymousAlethiometer/SGD_SaI) | <https://arxiv.org/abs/2411.10438> | [cite](https://github.com/AnonymousAlethiometer/SGD_SaI?tab=readme-ov-file#citation) |
198
+ | Grams | *Gradient Descent with Adaptive Momentum Scaling* | | <https://arxiv.org/abs/2412.17107> | [cite](https://ui.adsabs.harvard.edu/abs/2024arXiv241217107C/exportcitation) |
199
+ | OrthoGrad | *Grokking at the Edge of Numerical Stability* | [github](https://github.com/LucasPrietoAl/grokking-at-the-edge-of-numerical-stability) | <https://arxiv.org/abs/2501.04697> | [cite](https://github.com/LucasPrietoAl/grokking-at-the-edge-of-numerical-stability?tab=readme-ov-file#citation) |
200
+ | Adam-ATAN2 | *Scaling Exponents Across Parameterizations and Optimizers* | | <https://arxiv.org/abs/2407.05872> | [cite](https://ui.adsabs.harvard.edu/abs/2024arXiv240705872E/exportcitation) |
198
201
 
199
202
  ## Supported LR Scheduler
200
203
 
@@ -370,6 +373,10 @@ Correcting the norm of a gradient in each iteration based on the adaptive traini
370
373
 
371
374
  Updates only occur when the proposed update direction aligns with the current gradient.
372
375
 
376
+ ### Adam-ATAN2
377
+
378
+ Adam-atan2 is a new numerically stable, scale-invariant version of Adam that eliminates the epsilon hyperparameter.
379
+
373
380
  ## Frequently asked questions
374
381
 
375
382
  [here](docs/qa.md)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pytorch_optimizer"
3
- version = "3.3.2"
3
+ version = "3.3.3"
4
4
  description = "optimizer & lr scheduler & objective function collections in PyTorch"
5
5
  license = "Apache-2.0"
6
6
  authors = ["kozistr <kozistr@gmail.com>"]
@@ -14,13 +14,13 @@ keywords = [
14
14
  "AdaDelta", "AdaFactor", "AdaMax", "AdamG", "AdaMod", "AdaNorm", "AdaPNM", "AdaSmooth", "AdEMAMix", "ADOPT",
15
15
  "AdaHessian", "Adai", "Adalite", "AdaLomo", "AdamMini", "AdamP", "AdamS", "Adan", "AggMo", "Aida", "AliG", "Amos",
16
16
  "Apollo", "APOLLO", "AvaGrad", "bSAM", "CAME", "DAdaptAdaGrad", "DAdaptAdam", "DAdaptAdan", "DAdaptSGD",
17
- "DAdaptLion", "DeMo", "DiffGrad", "FAdam", "Fromage", "FTRL", "GaLore", "Gravity", "GrokFast", "GSAM", "Kate",
18
- "Lamb", "LaProp", "LARS", "Lion", "LOMO", "Lookahead", "MADGRAD", "MARS", "MSVAG", "Muno", "Nero", "NovoGrad",
19
- "PAdam", "PCGrad", "PID", "PNM", "Prodigy", "QHAdam", "QHM", "RAdam", "Ranger", "Ranger21", "RotoGrad", "SAM",
20
- "ScheduleFreeSGD", "ScheduleFreeAdamW", "ScheduleFreeRAdam", "SGDP", "Shampoo", "ScalableShampoo", "SGDW",
21
- "SignSGD", "SM3", "SOAP", "SopihaH", "SRMM", "StableAdamW", "SWATS", "Tiger", "TRAC", "WSAM", "Yogi", "BCE",
22
- "BCEFocal", "Focal", "FocalCosine", "SoftF1", "Dice", "LDAM", "Jaccard", "Bi-Tempered", "Tversky", "FocalTversky",
23
- "LovaszHinge", "bitsandbytes", "WSD", "QGaLore",
17
+ "DAdaptLion", "DeMo", "DiffGrad", "FAdam", "Fromage", "FTRL", "GaLore", "Grams", "Gravity", "GrokFast", "GSAM",
18
+ "Kate", "Lamb", "LaProp", "LARS", "Lion", "LOMO", "Lookahead", "MADGRAD", "MARS", "MSVAG", "Muno", "Nero",
19
+ "NovoGrad", "OrthoGrad", "PAdam", "PCGrad", "PID", "PNM", "Prodigy", "QHAdam", "QHM", "RAdam", "Ranger",
20
+ "Ranger21", "RotoGrad", "SAM", "ScheduleFreeSGD", "ScheduleFreeAdamW", "ScheduleFreeRAdam", "SGDP", "Shampoo",
21
+ "ScalableShampoo", "SGDW", "SignSGD", "SM3", "SOAP", "SopihaH", "SRMM", "StableAdamW", "SWATS", "Tiger", "TRAC",
22
+ "WSAM", "Yogi", "BCE", "BCEFocal", "Focal", "FocalCosine", "SoftF1", "Dice", "LDAM", "Jaccard", "Bi-Tempered",
23
+ "Tversky", "FocalTversky", "LovaszHinge", "bitsandbytes", "WSD", "QGaLore",
24
24
  ]
25
25
  classifiers = [
26
26
  "License :: OSI Approved :: Apache Software License",
@@ -97,8 +97,8 @@ select = [
97
97
  "TID", "ARG", "ERA", "RUF", "YTT", "PL", "Q"
98
98
  ]
99
99
  ignore = [
100
- "B905", "D100", "D102", "D104", "D105", "D107", "D203", "D213", "D413", "PIE790", "PLR0912", "PLR0913", "PLR0915",
101
- "PLR2004", "RUF013", "Q003", "ARG002",
100
+ "A005", "B905", "D100", "D102", "D104", "D105", "D107", "D203", "D213", "D413", "PIE790", "PLR0912", "PLR0913",
101
+ "PLR0915", "PLR2004", "RUF013", "Q003", "ARG002",
102
102
  ]
103
103
  fixable = ["ALL"]
104
104
  unfixable = ["F401"]
@@ -105,6 +105,7 @@ from pytorch_optimizer.optimizer import (
105
105
  FAdam,
106
106
  Fromage,
107
107
  GaLore,
108
+ Grams,
108
109
  Gravity,
109
110
  GrokFastAdamW,
110
111
  Kate,
@@ -115,6 +116,7 @@ from pytorch_optimizer.optimizer import (
115
116
  Muon,
116
117
  Nero,
117
118
  NovoGrad,
119
+ OrthoGrad,
118
120
  PAdam,
119
121
  PCGrad,
120
122
  Prodigy,
@@ -122,6 +124,7 @@ from pytorch_optimizer.optimizer import (
122
124
  RAdam,
123
125
  Ranger,
124
126
  Ranger21,
127
+ Ranger25,
125
128
  RotoGrad,
126
129
  SafeFP16Optimizer,
127
130
  ScalableShampoo,
@@ -266,6 +266,16 @@ class BaseOptimizer(ABC, Optimizer):
266
266
  mask.mul_(mask.numel() / (mask.sum() + 1))
267
267
  update.mul_(mask)
268
268
 
269
+ @staticmethod
270
+ def get_stable_adamw_rms(grad: torch.Tensor, exp_avg_sq: torch.Tensor, eps: float = 1e-16) -> float:
271
+ r"""Get StableAdamW RMS.
272
+
273
+ :param grad: torch.Tensor. gradient.
274
+ :param exp_avg_sq: torch.Tensor. exp_avg_sq.
275
+ :param eps: float. epsilon.
276
+ """
277
+ return grad.pow(2).div_(exp_avg_sq.clip(min=eps)).mean().sqrt_().clip_(min=1.0).item()
278
+
269
279
  @staticmethod
270
280
  def validate_range(x: float, name: str, low: float, high: float, range_type: str = '[)') -> None:
271
281
  if range_type == '[)' and not low <= x < high:
@@ -40,12 +40,14 @@ from pytorch_optimizer.optimizer.came import CAME
40
40
  from pytorch_optimizer.optimizer.dadapt import DAdaptAdaGrad, DAdaptAdam, DAdaptAdan, DAdaptLion, DAdaptSGD
41
41
  from pytorch_optimizer.optimizer.demo import DeMo
42
42
  from pytorch_optimizer.optimizer.diffgrad import DiffGrad
43
+ from pytorch_optimizer.optimizer.experimental.ranger25 import Ranger25
43
44
  from pytorch_optimizer.optimizer.fadam import FAdam
44
45
  from pytorch_optimizer.optimizer.fp16 import DynamicLossScaler, SafeFP16Optimizer
45
46
  from pytorch_optimizer.optimizer.fromage import Fromage
46
47
  from pytorch_optimizer.optimizer.ftrl import FTRL
47
48
  from pytorch_optimizer.optimizer.galore import GaLore
48
49
  from pytorch_optimizer.optimizer.gc import centralize_gradient
50
+ from pytorch_optimizer.optimizer.grams import Grams
49
51
  from pytorch_optimizer.optimizer.gravity import Gravity
50
52
  from pytorch_optimizer.optimizer.grokfast import GrokFastAdamW
51
53
  from pytorch_optimizer.optimizer.kate import Kate
@@ -61,6 +63,7 @@ from pytorch_optimizer.optimizer.msvag import MSVAG
61
63
  from pytorch_optimizer.optimizer.muon import Muon
62
64
  from pytorch_optimizer.optimizer.nero import Nero
63
65
  from pytorch_optimizer.optimizer.novograd import NovoGrad
66
+ from pytorch_optimizer.optimizer.orthograd import OrthoGrad
64
67
  from pytorch_optimizer.optimizer.padam import PAdam
65
68
  from pytorch_optimizer.optimizer.pcgrad import PCGrad
66
69
  from pytorch_optimizer.optimizer.pid import PID
@@ -282,6 +285,8 @@ OPTIMIZER_LIST: List[OPTIMIZER] = [
282
285
  LaProp,
283
286
  MARS,
284
287
  SGDSaI,
288
+ Grams,
289
+ Ranger25,
285
290
  ]
286
291
  OPTIMIZERS: Dict[str, OPTIMIZER] = {str(optimizer.__name__).lower(): optimizer for optimizer in OPTIMIZER_LIST}
287
292
 
@@ -107,13 +107,12 @@ class StableAdamW(BaseOptimizer):
107
107
  exp_avg.lerp_(grad, weight=beta1_comp)
108
108
  exp_avg_sq.mul_(beta2_hat).addcmul_(grad, grad, value=1.0 - beta2_hat)
109
109
 
110
- rms = grad.pow(2).div_(exp_avg_sq.clip(min=eps_p2)).mean().sqrt_()
111
-
112
- lr = group['lr'] / rms.clip(min=1.0)
110
+ rms = self.get_stable_adamw_rms(grad, exp_avg_sq, eps=eps_p2)
111
+ lr = group['lr'] / rms
113
112
 
114
113
  self.apply_weight_decay(
115
114
  p,
116
- p.grad,
115
+ grad,
117
116
  lr=lr,
118
117
  weight_decay=group['weight_decay'],
119
118
  weight_decouple=group['weight_decouple'],
@@ -19,7 +19,8 @@ class AdEMAMix(BaseOptimizer):
19
19
  :param fixed_decay: bool. fix weight decay.
20
20
  :param alpha: float. usually between 4 and 10 would work well.
21
21
  :param t_alpha_beta3: Optional[float]. total number of iterations is preferred when needed.
22
- :param cautious: bool. whether to use cautious feature.
22
+ :param cautious: bool. whether to use the Cautious variant.
23
+ :param stable_adamw: bool. whether to use stable AdamW variant.
23
24
  :param eps: float. term added to the denominator to improve numerical stability.
24
25
  """
25
26
 
@@ -34,6 +35,7 @@ class AdEMAMix(BaseOptimizer):
34
35
  alpha: float = 5.0,
35
36
  t_alpha_beta3: Optional[float] = None,
36
37
  cautious: bool = False,
38
+ stable_adamw: bool = False,
37
39
  eps: float = 1e-8,
38
40
  **kwargs,
39
41
  ):
@@ -45,6 +47,7 @@ class AdEMAMix(BaseOptimizer):
45
47
  self.validate_non_negative(eps, 'eps')
46
48
 
47
49
  self.cautious = cautious
50
+ self.stable_adamw = stable_adamw
48
51
 
49
52
  defaults: DEFAULTS = {
50
53
  'lr': lr,
@@ -150,6 +153,9 @@ class AdEMAMix(BaseOptimizer):
150
153
  if self.cautious:
151
154
  self.apply_cautious(update, grad)
152
155
 
156
+ if self.stable_adamw:
157
+ step_size /= self.get_stable_adamw_rms(grad, exp_avg_sq)
158
+
153
159
  update.add_(exp_avg_slow, alpha=alpha_t).div_(de_nom)
154
160
 
155
161
  p.add_(update, alpha=-step_size)
@@ -18,6 +18,7 @@ class ADOPT(BaseOptimizer):
18
18
  :param weight_decouple: bool. the optimizer uses decoupled weight decay as in AdamW.
19
19
  :param fixed_decay: bool. fix weight decay.
20
20
  :param cautious: bool. whether to use the Cautious variant.
21
+ :param stable_adamw: bool. whether to use stable AdamW variant.
21
22
  :param eps: float. term added to the denominator to improve numerical stability.
22
23
  """
23
24
 
@@ -31,6 +32,7 @@ class ADOPT(BaseOptimizer):
31
32
  weight_decouple: bool = False,
32
33
  fixed_decay: bool = False,
33
34
  cautious: bool = False,
35
+ stable_adamw: bool = False,
34
36
  eps: float = 1e-6,
35
37
  **kwargs,
36
38
  ):
@@ -41,6 +43,7 @@ class ADOPT(BaseOptimizer):
41
43
 
42
44
  self.clip_lambda = clip_lambda
43
45
  self.cautious = cautious
46
+ self.stable_adamw = stable_adamw
44
47
 
45
48
  defaults: DEFAULTS = {
46
49
  'lr': lr,
@@ -80,6 +83,7 @@ class ADOPT(BaseOptimizer):
80
83
  group['step'] = 1
81
84
 
82
85
  beta1, beta2 = group['betas']
86
+ lr: float = group['lr']
83
87
 
84
88
  for p in group['params']:
85
89
  if p.grad is None:
@@ -98,7 +102,7 @@ class ADOPT(BaseOptimizer):
98
102
  self.apply_weight_decay(
99
103
  p=p,
100
104
  grad=grad,
101
- lr=group['lr'],
105
+ lr=lr,
102
106
  weight_decay=group['weight_decay'],
103
107
  weight_decouple=group['weight_decouple'],
104
108
  fixed_decay=group['fixed_decay'],
@@ -127,6 +131,9 @@ class ADOPT(BaseOptimizer):
127
131
  else:
128
132
  update = exp_avg
129
133
 
130
- p.add_(update, alpha=-group['lr'])
134
+ if self.stable_adamw:
135
+ lr /= self.get_stable_adamw_rms(grad, exp_avg_sq)
136
+
137
+ p.add_(update, alpha=-lr)
131
138
 
132
139
  return loss
@@ -0,0 +1,184 @@
1
+ import math
2
+ from typing import Optional
3
+
4
+ import torch
5
+
6
+ from pytorch_optimizer.base.exception import NoSparseGradientError
7
+ from pytorch_optimizer.base.optimizer import BaseOptimizer
8
+ from pytorch_optimizer.base.types import BETAS, CLOSURE, DEFAULTS, LOSS, PARAMETERS
9
+
10
+
11
+ class Ranger25(BaseOptimizer):
12
+ r"""Mixin' every fancy optimizer hacks.
13
+
14
+ :param params: PARAMETERS. iterable of parameters to optimize or dicts defining parameter groups.
15
+ :param lr: float. learning rate.
16
+ :param betas: BETAS. coefficients used for computing running averages of gradient and the squared hessian trace.
17
+ :param weight_decay: float. weight decay (L2 penalty).
18
+ :param weight_decouple: bool. the optimizer uses decoupled weight decay as in AdamW.
19
+ :param fixed_decay: bool. fix weight decay.
20
+ :param alpha: float. usually between 4 and 10 would work well.
21
+ :param t_alpha_beta3: Optional[float]. total number of iterations is preferred when needed.
22
+ :param n_sma_threshold: number of SMA threshold (recommended is 5).
23
+ :param cautious: bool. whether to use the Cautious variant.
24
+ :param stable_adamw: bool. whether to use stable AdamW variant.
25
+ :param eps: float. term added to the denominator to improve numerical stability.
26
+ """
27
+
28
+ def __init__(
29
+ self,
30
+ params: PARAMETERS,
31
+ lr: float = 1e-3,
32
+ betas: BETAS = (0.9, 0.999, 0.9999),
33
+ weight_decay: float = 1e-3,
34
+ weight_decouple: bool = True,
35
+ fixed_decay: bool = False,
36
+ alpha: float = 5.0,
37
+ t_alpha_beta3: Optional[float] = None,
38
+ n_sma_threshold: int = 5,
39
+ cautious: bool = True,
40
+ stable_adamw: bool = True,
41
+ eps: float = 1e-8,
42
+ **kwargs,
43
+ ):
44
+ self.validate_learning_rate(lr)
45
+ self.validate_betas(betas)
46
+ self.validate_non_negative(alpha, 'alpha')
47
+ self.validate_non_negative(t_alpha_beta3, 't_alpha_beta3')
48
+ self.validate_non_negative(weight_decay, 'weight_decay')
49
+ self.validate_non_negative(eps, 'eps')
50
+
51
+ self.n_sma_threshold = n_sma_threshold
52
+ self.cautious = cautious
53
+ self.stable_adamw = stable_adamw
54
+
55
+ defaults: DEFAULTS = {
56
+ 'lr': lr,
57
+ 'betas': betas,
58
+ 'weight_decay': weight_decay,
59
+ 'weight_decouple': weight_decouple,
60
+ 'fixed_decay': fixed_decay,
61
+ 'alpha': alpha,
62
+ 't_alpha_beta3': t_alpha_beta3,
63
+ 'eps': eps,
64
+ }
65
+
66
+ super().__init__(params, defaults)
67
+
68
+ def __str__(self) -> str:
69
+ return 'Ranger25'
70
+
71
+ @torch.no_grad()
72
+ def reset(self):
73
+ for group in self.param_groups:
74
+ group['step'] = 0
75
+ for p in group['params']:
76
+ state = self.state[p]
77
+
78
+ state['exp_avg'] = torch.zeros_like(p)
79
+ state['exp_avg_sq'] = torch.zeros_like(p)
80
+ state['exp_avg_slow'] = torch.zeros_like(p)
81
+
82
+ @staticmethod
83
+ def schedule_alpha(t_alpha_beta3: Optional[float], step: int, alpha: float) -> float:
84
+ return alpha if t_alpha_beta3 is None else min(step * alpha / t_alpha_beta3, alpha)
85
+
86
+ @staticmethod
87
+ def schedule_beta3(t_alpha_beta3: Optional[float], step: int, beta1: float, beta3: float) -> float:
88
+ if t_alpha_beta3 is None:
89
+ return beta3
90
+
91
+ log_beta1, log_beta3 = math.log(beta1), math.log(beta3)
92
+
93
+ return min(
94
+ math.exp(
95
+ log_beta1 * log_beta3 / ((1.0 - step / t_alpha_beta3) * log_beta3 + (step / t_alpha_beta3) * log_beta1)
96
+ ),
97
+ beta3,
98
+ )
99
+
100
+ @torch.no_grad()
101
+ def step(self, closure: CLOSURE = None) -> LOSS:
102
+ loss: LOSS = None
103
+ if closure is not None:
104
+ with torch.enable_grad():
105
+ loss = closure()
106
+
107
+ for group in self.param_groups:
108
+ if 'step' in group:
109
+ group['step'] += 1
110
+ else:
111
+ group['step'] = 1
112
+
113
+ beta1, beta2, beta3 = group['betas']
114
+
115
+ bias_correction1: float = self.debias(beta1, group['step'])
116
+ bias_correction2_sq: float = math.sqrt(self.debias(beta2, group['step']))
117
+
118
+ step_size: float = group['lr'] / bias_correction1
119
+ clip: float = math.pow(group['step'], 0.25)
120
+
121
+ alpha_t: float = self.schedule_alpha(group['t_alpha_beta3'], group['step'], group['alpha'])
122
+ beta3_t: float = self.schedule_beta3(group['t_alpha_beta3'], group['step'], beta1, beta3)
123
+
124
+ for p in group['params']:
125
+ if p.grad is None:
126
+ continue
127
+
128
+ grad = p.grad
129
+ if grad.is_sparse:
130
+ raise NoSparseGradientError(str(self))
131
+
132
+ state = self.state[p]
133
+
134
+ if len(state) == 0:
135
+ state['exp_avg'] = torch.zeros_like(p)
136
+ state['exp_avg_sq'] = torch.zeros_like(p)
137
+ state['exp_avg_slow'] = torch.zeros_like(p)
138
+
139
+ self.apply_weight_decay(
140
+ p=p,
141
+ grad=grad,
142
+ lr=group['lr'],
143
+ weight_decay=group['weight_decay'],
144
+ weight_decouple=group['weight_decouple'],
145
+ fixed_decay=group['fixed_decay'],
146
+ )
147
+
148
+ exp_avg, exp_avg_sq, exp_avg_slow = state['exp_avg'], state['exp_avg_sq'], state['exp_avg_slow']
149
+
150
+ de_nom = exp_avg_sq.sqrt().clamp_(min=group['eps'])
151
+
152
+ normed_grad = grad.div(de_nom).clamp_(-clip, clip)
153
+
154
+ exp_avg.mul_(beta1).add_(normed_grad, alpha=1.0 - beta1)
155
+ exp_avg_sq.mul_(beta2).addcmul_(grad, grad, value=1.0 - beta2)
156
+ exp_avg_slow.mul_(beta3_t).add_(normed_grad, alpha=1.0 - beta3_t)
157
+
158
+ de_nom = exp_avg_sq.sqrt().div_(bias_correction2_sq).add_(group['eps'])
159
+
160
+ update = exp_avg.clone()
161
+ if self.cautious:
162
+ self.apply_cautious(update, grad)
163
+
164
+ if self.stable_adamw:
165
+ step_size /= self.get_stable_adamw_rms(grad, exp_avg_sq)
166
+
167
+ step_size, n_sma = self.get_rectify_step_size(
168
+ is_rectify=True,
169
+ step=group['step'],
170
+ lr=step_size,
171
+ beta2=beta2,
172
+ n_sma_threshold=self.n_sma_threshold,
173
+ degenerated_to_sgd=False,
174
+ )
175
+
176
+ update.add_(exp_avg_slow, alpha=alpha_t).div_(de_nom)
177
+
178
+ if n_sma >= self.n_sma_threshold:
179
+ de_nom = exp_avg_sq.sqrt().add_(group['eps'])
180
+ p.addcdiv_(update, de_nom, value=-step_size)
181
+ else:
182
+ p.add_(update, alpha=-step_size)
183
+
184
+ return loss
@@ -0,0 +1,108 @@
1
+ import math
2
+
3
+ import torch
4
+
5
+ from pytorch_optimizer.base.exception import NoSparseGradientError
6
+ from pytorch_optimizer.base.optimizer import BaseOptimizer
7
+ from pytorch_optimizer.base.types import BETAS, CLOSURE, DEFAULTS, LOSS, PARAMETERS
8
+
9
+
10
+ class Grams(BaseOptimizer):
11
+ r"""Gradient Descent with Adaptive Momentum Scaling.
12
+
13
+ :param params: PARAMETERS. iterable of parameters to optimize or dicts defining parameter groups.
14
+ :param lr: float. learning rate.
15
+ :param betas: BETAS. coefficients used for computing running averages of gradient and the squared hessian trace.
16
+ :param weight_decay: float. weight decay (L2 penalty).
17
+ :param weight_decouple: bool. decoupled weight decay.
18
+ :param eps: float. term added to the denominator to improve numerical stability.
19
+ """
20
+
21
+ def __init__(
22
+ self,
23
+ params: PARAMETERS,
24
+ lr: float = 1e-3,
25
+ betas: BETAS = (0.9, 0.999),
26
+ weight_decay: float = 0.0,
27
+ weight_decouple: bool = True,
28
+ eps: float = 1e-6,
29
+ **kwargs,
30
+ ):
31
+ self.validate_learning_rate(lr)
32
+ self.validate_betas(betas)
33
+ self.validate_non_negative(weight_decay, 'weight_decay')
34
+ self.validate_non_negative(eps, 'eps')
35
+
36
+ defaults: DEFAULTS = {
37
+ 'lr': lr,
38
+ 'betas': betas,
39
+ 'weight_decay': weight_decay,
40
+ 'weight_decouple': weight_decouple,
41
+ 'eps': eps,
42
+ }
43
+
44
+ super().__init__(params, defaults)
45
+
46
+ def __str__(self) -> str:
47
+ return 'Grams'
48
+
49
+ @torch.no_grad()
50
+ def reset(self):
51
+ for group in self.param_groups:
52
+ group['step'] = 0
53
+ for p in group['params']:
54
+ state = self.state[p]
55
+
56
+ state['exp_avg'] = torch.zeros_like(p)
57
+ state['exp_avg_sq'] = torch.zeros_like(p)
58
+
59
+ @torch.no_grad()
60
+ def step(self, closure: CLOSURE = None) -> LOSS:
61
+ loss: LOSS = None
62
+ if closure is not None:
63
+ with torch.enable_grad():
64
+ loss = closure()
65
+
66
+ for group in self.param_groups:
67
+ if 'step' in group:
68
+ group['step'] += 1
69
+ else:
70
+ group['step'] = 1
71
+
72
+ beta1, beta2 = group['betas']
73
+
74
+ bias_correction1: float = self.debias(beta1, group['step'])
75
+ bias_correction2_sq: float = math.sqrt(self.debias(beta2, group['step']))
76
+
77
+ for p in group['params']:
78
+ if p.grad is None:
79
+ continue
80
+
81
+ grad = p.grad
82
+ if grad.is_sparse:
83
+ raise NoSparseGradientError(str(self))
84
+
85
+ state = self.state[p]
86
+ if len(state) == 0:
87
+ state['exp_avg'] = torch.zeros_like(p)
88
+ state['exp_avg_sq'] = torch.zeros_like(p)
89
+
90
+ exp_avg, exp_avg_sq = state['exp_avg'], state['exp_avg_sq']
91
+ exp_avg.lerp_(grad, weight=beta1)
92
+ exp_avg_sq.mul_(beta2).addcmul_(grad, grad, value=1.0 - beta2)
93
+
94
+ update = (exp_avg / bias_correction1) / (exp_avg_sq / bias_correction2_sq).sqrt_().add_(group['eps'])
95
+ update.abs_().mul_(grad.sign())
96
+
97
+ self.apply_weight_decay(
98
+ p,
99
+ grad,
100
+ lr=group['lr'],
101
+ weight_decay=group['weight_decay'],
102
+ weight_decouple=group['weight_decouple'],
103
+ fixed_decay=False,
104
+ )
105
+
106
+ p.add_(update, alpha=-group['lr'])
107
+
108
+ return loss
@@ -0,0 +1,48 @@
1
+ import torch
2
+
3
+ from pytorch_optimizer.base.optimizer import BaseOptimizer
4
+ from pytorch_optimizer.base.types import CLOSURE, LOSS, OPTIMIZER, PARAMETERS
5
+
6
+
7
+ class OrthoGrad(BaseOptimizer):
8
+ r"""Grokking at the Edge of Numerical Stability.
9
+
10
+ A wrapper optimizer that projects gradients to be orthogonal to the current parameters before performing an update.
11
+
12
+ :param params: PARAMETERS. iterable of parameters to optimize or dicts defining parameter groups.
13
+ :param optimizer: OPTIMIZER. base optimizer.
14
+ """
15
+
16
+ def __init__(self, params: PARAMETERS, optimizer: OPTIMIZER = torch.optim.AdamW, **kwargs):
17
+ self.eps: float = 1e-30
18
+
19
+ super().__init__(params, {})
20
+ self.base_optimizer = optimizer(self.param_groups, **kwargs)
21
+
22
+ def __str__(self) -> str:
23
+ return 'OrthoGrad'
24
+
25
+ @torch.no_grad()
26
+ def reset(self):
27
+ pass
28
+
29
+ @torch.no_grad()
30
+ def orthogonalize_gradients(self, params) -> None:
31
+ for p in params:
32
+ if p.grad is None:
33
+ continue
34
+
35
+ w = p.view(-1)
36
+ g = p.grad.view(-1)
37
+
38
+ proj = torch.dot(w, g).div_(torch.dot(w, w).add_(self.eps))
39
+ g_ortho = g.to(dtype=torch.float32, copy=True).sub_(w, alpha=proj)
40
+ g_ortho_scaled = g_ortho.mul_(g.norm(2).div_(g_ortho.norm(2).add_(self.eps)))
41
+
42
+ p.grad.copy_(g_ortho_scaled.view_as(p.grad))
43
+
44
+ @torch.no_grad()
45
+ def step(self, closure: CLOSURE = None) -> LOSS:
46
+ for group in self.param_groups:
47
+ self.orthogonalize_gradients(group['params'])
48
+ return self.base_optimizer.step(closure)
@@ -16,7 +16,7 @@ class Prodigy(BaseOptimizer):
16
16
  :param params: PARAMETERS. iterable of parameters to optimize or dicts defining parameter groups.
17
17
  :param lr: float. learning rate.
18
18
  :param betas: BETAS. betas.
19
- :param beta3: float. coefficients for computing the Prodidy step-size using running averages. If set to None,
19
+ :param beta3: float. coefficients for computing the Prodigy step-size using running averages. If set to None,
20
20
  uses the value of square root of beta2.
21
21
  :param d0: float. initial D estimate for D-adaptation (default 1e-6). Rarely needs changing.
22
22
  :param d_coef: float. Coefficient in the expression for the estimate of d.
@@ -26,7 +26,8 @@ class Prodigy(BaseOptimizer):
26
26
  :param fixed_decay: bool. fix weight decay.
27
27
  :param bias_correction: bool. turn on Adam's bias correction.
28
28
  :param safeguard_warmup: bool. remove lr from the denominator of D estimate to avoid issues during warm-up stage.
29
- :param eps: float. term added to the denominator to improve numerical stability.
29
+ :param eps: float. term added to the denominator to improve numerical stability. when eps is None, use atan2 rather
30
+ than epsilon and division for parameter updates.
30
31
  """
31
32
 
32
33
  def __init__(
@@ -43,7 +44,7 @@ class Prodigy(BaseOptimizer):
43
44
  fixed_decay: bool = False,
44
45
  bias_correction: bool = False,
45
46
  safeguard_warmup: bool = False,
46
- eps: float = 1e-8,
47
+ eps: Optional[float] = 1e-8,
47
48
  **kwargs,
48
49
  ):
49
50
  self.validate_learning_rate(lr)
@@ -172,8 +173,6 @@ class Prodigy(BaseOptimizer):
172
173
 
173
174
  exp_avg, exp_avg_sq = state['exp_avg'], state['exp_avg_sq']
174
175
 
175
- de_nom = exp_avg_sq.sqrt().add_(d * group['eps'])
176
-
177
176
  self.apply_weight_decay(
178
177
  p,
179
178
  p.grad,
@@ -183,6 +182,13 @@ class Prodigy(BaseOptimizer):
183
182
  fixed_decay=group['fixed_decay'],
184
183
  )
185
184
 
186
- p.addcdiv_(exp_avg, de_nom, value=-d_lr)
185
+ de_nom = exp_avg_sq.sqrt()
186
+
187
+ if group['eps'] is not None:
188
+ de_nom.add_(d * group['eps'])
189
+ p.addcdiv_(exp_avg, de_nom, value=-d_lr)
190
+ else:
191
+ update = exp_avg.clone().atan2_(de_nom)
192
+ p.add_(update, alpha=-d_lr)
187
193
 
188
194
  return loss
@@ -81,7 +81,7 @@ class VanillaMTL(nn.Module):
81
81
  else:
82
82
  preds.append(out_i)
83
83
 
84
- return preds if len(extra_out) == 0 else preds, extra_out
84
+ return preds if len(extra_out) == 0 else (preds, extra_out)
85
85
 
86
86
  def backward(self, losses, backbone_loss=None, **kwargs):
87
87
  for loss in losses:
@@ -272,7 +272,7 @@ class RotateOnly(nn.Module):
272
272
  else:
273
273
  preds.append(out_i)
274
274
 
275
- return preds if len(extra_out) == 0 else preds, extra_out
275
+ return preds if len(extra_out) == 0 else (preds, extra_out)
276
276
 
277
277
  def backward(self, losses: Sequence[torch.Tensor], backbone_loss=None, **kwargs) -> None:
278
278
  r"""Compute the backward computations for the entire model.