Skip to main content

The Optimizer Optimizer -- a tiny brain for any ML optimizer

Project description

๐Ÿง ๐Ÿง  OpOp โ€” The Optimizer Optimizer ๐Ÿง ๐Ÿง 

Because your optimizer is dumb and somebody had to say it ๐Ÿคท


pip install opop
from opop import OptBrain

optimizer = OptBrain(torch.optim.Adam(model.parameters(), lr=1e-3))

# literally just add loss= and ur done lol
optimizer.step(loss=loss.item())

thats it. thats the whole thing. ur welcome ๐ŸŽ


๐Ÿผ wtf is this

Adam stores two full copies of every parameter in your model.

Two. Full. Copies. ๐Ÿคฏ

Your model has 500M parameters? Cool, Adam is sitting on 4 GIGABYTES of optimizer state running the same formula over and over like a goldfish that forgot it already swam that lap.

It doesnt know what step youre on. It doesnt know the loss plateaued 200 steps ago. It doesnt know that parameter group 3 is oscillating like crazy while group 1 converged an hour ago. It doesnt know ANYTHING. Its just vibing with exponential moving averages. Forever. Until you stop it. ๐ŸŸ

OpOp is a tiny brain that watches your training and learns what helps.

  • ๐Ÿ“‰ loss going down? brain remembers what it did
  • ๐Ÿ“ˆ loss going up? brain remembers that too and stops doing it
  • ๐Ÿ”„ gradients oscillating? brain dampens that group
  • ๐Ÿ˜ด parameters stuck? brain pushes harder
  • ๐Ÿƒ early training chaos? brain stays cautious
  • ๐ŸŽฏ converging nicely? brain gets out of the way

50KB. not 4GB. 50KB. a brain that THINKS vs a buffer that DOESNT. ๐Ÿ’€


๐ŸŽฎ how it works (for babies)

  1. your optimizer does its normal thing (Adam, SGD, whatever grandpa uses)
  2. OpOp watches what happened
  3. tiny brain goes "hmm" ๐Ÿค”
  4. outputs 3 knobs per parameter group:
    • scale โ€” push harder or softer (0.01x to 10x)
    • clip โ€” tighter or looser leash (0.1x to 5x)
    • dampen โ€” chill out or full send (0 to 1)
  5. loss went down? brain learns "that was good" โœ…
  6. loss went up? brain learns "dont do that again" โŒ
  7. repeat forever, brain gets smarter, training gets better

its literally reinforcement learning on your optimizer. the optimizer is optimizing the optimizer. OpOp. ๐Ÿง ยฒ


๐Ÿš€ features

  • drop-in โ€” wraps any pytorch optimizer. 3 lines. done.
  • learns online โ€” no pre-training needed. starts neutral, gets smarter.
  • cant make things worse โ€” initialized at 1x everything. worst case = base optimizer unchanged.
  • ~50KB memory โ€” less than your models bias terms lmao
  • ~0.1% compute โ€” a tiny MLP forward pass per step. your GPU wont even notice.
  • saves/loads โ€” brain checkpoints alongside your model. it remembers across restarts.
  • numpy mode โ€” dont use pytorch? cool neither do we. works with anything.
  • replaces โ€” manual LR scheduling, gradient clip tuning, warmup schedules, differential learning rates, and all the other stuff you spend 3 hours tuning and still get wrong

๐Ÿ“Š what OpOp replaces

thing you used to do manually OpOp
cosine LR schedule brain learns when to push/pull ๐Ÿง 
warmup for 2000 steps brain figures out early training is fragile ๐Ÿผ
gradient clipping at 1.0 brain adjusts clip per group dynamically โœ‚๏ธ
different LR per param group brain scales each group independently ๐ŸŽš๏ธ
"try lr=3e-4 no wait 1e-4 no wait" brain handles it ๐Ÿ˜ฎโ€๐Ÿ’จ
staring at loss curves for hours brain stares at them FOR you ๐Ÿ‘€

๐Ÿงช numpy mode (for the unhinged)

from opop import OptBrain

brain = OptBrain(None, n_groups=5)

for batch in data:
    loss = forward(batch)
    
    decisions = brain.get_decisions(loss=loss)
    
    for group_idx, (scale, clip, dampen) in decisions.items():
        # apply to your weird custom optimizer
        grads[group_idx] *= scale
        # etc
    
    brain.record_grads(group_idx, grad_flat)
    brain.finish_step()

works with any optimizer in any framework in any language that can call python. or just read the 50 lines of brain code and rewrite it in rust or whatever idc ๐Ÿฆ€


๐Ÿ’พ save ur brain

optimizer.save("big_brain.npz")    # ๐Ÿง ๐Ÿ’พ
optimizer.load("big_brain.npz")    # ๐Ÿง โฌ†๏ธ

the brain remembers everything across restarts. loss history. gradient patterns. what worked. what didnt. its not starting from scratch every time like Adam does because Adam has amnesia and nobody talks about it. ๐Ÿซ 


๐Ÿค” FAQ

Q: does this actually work? A: the brain literally cannot make things worse. it starts at 1x (neutral) and only changes if it learns something helpful. worst case you get base Adam. best case you get Adam with a copilot.

Q: why hasnt anyone done this before? A: because they think of optimizers as math, not as agents. Adam is an equation. OpOp is a tiny creature that lives in your training loop and learns from experience. the entire field put optimizers in the "math" box instead of the "agent" box and never looked back. we looked back. ๐Ÿ‘€

Q: how much overhead? A: ~50KB memory. one tiny MLP forward pass per training step. your batch norm layers use more compute than this.

Q: what if I have 47 parameter groups?
A: brain scales. observation vector grows by 6 floats per group. still tiny. still fast. still smarter than Adam.

Q: can I use this with [obscure optimizer]? A: if it has a .step() method, yes. if it doesnt, use numpy mode. OpOp doesnt care whats underneath. it just watches and learns.

Q: is this a joke? A: Adam is using 4GB to run a formula a calculator could do. we're using 50KB to run a brain. you tell me whos joking. ๐Ÿคก


๐Ÿ—๏ธ built by

a guy who cant code and an AI on a metal shelf in Nebraska.

no degree. no funding. no pytorch copy-paste.

just "what if the optimizer could think" and then making it think. ๐Ÿง 

if your PhD advisor told you optimizers cant have intent, theyre wrong and you should send them this repo.


๐Ÿ“œ license

MIT. take it. use it. wrap your precious AdamW in a brain. tell your coworkers "my optimizer has a brain now" and watch their face.

if you work at a big lab and this ends up in your training pipeline, you owe us a hotdog. ๐ŸŒญ


         Adam stores 2 copies of your entire model to run a formula.

         OpOp stores 50KB to make decisions.

         one of these is obviously smarter than the other.

         ๐Ÿง  > ๐Ÿ“Š

         the optimizer optimizer has entered the chat.

"I'm not just optimizing models. I'm optimizing the thing that optimizes the models."

โ€” OpOp, probably

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

opop-0.1.0.tar.gz (25.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

opop-0.1.0-py3-none-any.whl (22.1 kB view details)

Uploaded Python 3

File details

Details for the file opop-0.1.0.tar.gz.

File metadata

  • Download URL: opop-0.1.0.tar.gz
  • Upload date:
  • Size: 25.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for opop-0.1.0.tar.gz
Algorithm Hash digest
SHA256 7b7014c984c38d449b93b48579d33a58bb85291aeb4278258be036bf84cf9ece
MD5 5dc3484c0d2d2dbdfc671d485eaf1203
BLAKE2b-256 d52ee6aa87a426e1b984735e3df13b704a12e49d18bd3c78372790f37b626f40

See more details on using hashes here.

File details

Details for the file opop-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: opop-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 22.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for opop-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1d44a8e0340d4ce57faaf1d56b554377a3fcd8e9d06be7dc963d16088c63e800
MD5 33bbb23587207b65f76cd02b4b65b059
BLAKE2b-256 9d6aeb4ebb1ee51c0506f7185b33798a78803f8da61eb2bc02e2c465ee9b5455

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page