Soft Algebra Optimizer + O(N) Linear Attention + Streaming Anomaly Detection
Project description
Mobiu-Q v5.0
Soft Algebra for Optimization & Attention
Overview
Mobiu-Q is a framework built on Soft Algebra (nilpotent ε²=0) that provides:
- MobiuOptimizer - Stable optimization in noisy environments
- MobiuAttention 🧪 - O(N) linear attention for long sequences
- MobiuSignal 🆕 - Trading signals using Soft Algebra
- MobiuAD - Streaming anomaly detection
- TrainGuard - Safe ML training monitor
Installation
pip install mobiu-q
Quick Start
MobiuOptimizer — PyTorch (wrap your optimizer)
import torch
from mobiu_q import MobiuOptimizer
LICENSE_KEY = "your-license-key-here"
model = MyModel()
# Step 1: define your base optimizer exactly as you normally would
base_opt = torch.optim.Adam(model.parameters(), lr=3e-4)
# Step 2: wrap it — your optimizer still runs, Mobiu-Q enhances via SA
opt = MobiuOptimizer(
base_opt,
license_key=LICENSE_KEY,
method="adaptive", # standard | deep | adaptive
base_lr=3e-4, # always pass base_lr to match your optimizer's LR
boost="none", # "none" (default) | "normal" | "aggressive"
verbose=False
)
for batch in dataloader:
loss = criterion(model(batch))
opt.zero_grad()
loss.backward()
opt.step(loss.item()) # pass dynamic loss — not a static scalar
opt.end() # important: release session
MobiuOptimizer — Quantum/NumPy (MobiuQCore)
For VQE, QAOA, and black-box optimization with SPSA:
import numpy as np
from mobiu_q import MobiuQCore
LICENSE_KEY = "your-license-key-here"
params = np.random.uniform(-np.pi, np.pi, num_params)
opt = MobiuQCore(
license_key=LICENSE_KEY,
method="standard",
mode="hardware", # simulation | hardware
base_lr=0.02, # standard+hardware default
verbose=False
)
for step in range(150):
energy, grad = get_batched_energy_and_gradient(params, spsa_delta)
params = opt.step(params, grad, energy)
opt.end()
MobiuAttention (🧪 Experimental)
from mobiu_q.experimental import MobiuAttention, MobiuBlock
# Drop-in replacement for nn.MultiheadAttention — no license key needed
attn = MobiuAttention(d_model=512, num_heads=8)
out = attn(x) # x: [batch, seq, dim]
block = MobiuBlock(d_model=512, num_heads=8)
out = block(x)
MobiuAD
from mobiu_q import MobiuAD, TrainGuard
detector = MobiuAD(license_key=LICENSE_KEY)
result = detector.detect(value)
guard = TrainGuard(license_key=LICENSE_KEY)
result = guard.step(loss, gradient, val_loss)
MobiuSignal
from mobiu_q.signal import MobiuSignal
# Runs locally — no license key needed
signal = MobiuSignal(lookback=20)
result = signal.compute(prices)
if result.is_strong:
print(f"Strong {'📈' if result.is_bullish else '📉'} signal: {result.magnitude:.2f}")
backtest = signal.backtest(historical_prices, future_window=5)
print(f"Correlation: {backtest.correlation:.3f}")
print(f"Q4/Q1 Ratio: {backtest.q4_q1_ratio:.2f}x")
License Key
A license key is only required for cloud mode. In local mode (new in v5.0), no key is needed.
LICENSE_KEY = "your-license-key-here" # get one at https://app.mobiu.ai
| Tier | API Calls | Price | Includes |
|---|---|---|---|
| Free | 20/month | $0 | Cloud mode only |
| Research | Unlimited | $490/month | Cloud + local mode + priority support |
| Enterprise | Unlimited | Contact us | Self-hosted / air-gapped + SLA |
Local mode (v5.0+): Pass sa_backend="local" to run Soft Algebra in-process without any cloud calls:
from mobiu_q import MobiuOptimizer
import torch
base_opt = torch.optim.Adam(model.parameters(), lr=3e-4)
opt = MobiuOptimizer(base_opt, sa_backend="local", method="adaptive", base_lr=3e-4)
for batch in dataloader:
loss = criterion(model(batch))
opt.zero_grad(); loss.backward()
opt.step(loss.item())
opt.end()
No license key, no network calls. Numerically identical to cloud mode (parity-tested).
Note: MobiuAttention and MobiuSignal run locally in all modes — no license key required.
MobiuOptimizer
Methods
| Method | Use Case | Default LR (simulation) | Default LR (hardware) |
|---|---|---|---|
standard |
VQE, chemistry, smooth landscapes | 0.01 | 0.02 |
deep |
Deep circuits, rugged landscapes, QAOA | 0.1 | 0.1 |
adaptive |
RL, LLM fine-tuning, high-variance problems | 0.0003 | 0.0003 |
Important: Always pass base_lr= explicitly to match your base optimizer's LR and prevent auto-replacement.
Mode (mode=) is for quantum/NumPy only. In PyTorch mode, the mode parameter has no effect — your optimizer always runs at the LR you set.
Supported Base Optimizers (PyTorch mode)
Any PyTorch-compatible optimizer works. Common choices:
# Supervised learning / VQE-classical
base_opt = torch.optim.Adam(model.parameters(), lr=3e-4)
# RL / high-variance
base_opt = torch.optim.Adam(model.parameters(), lr=3e-4)
# LLM fine-tuning (LoRA)
base_opt = torch.optim.SGD(model.parameters(), lr=5e-3, momentum=0.9)
# Custom / external
from muon import Muon
base_opt = Muon(model.parameters(), lr=0.02, momentum=0.95)
Supported server-side (Quantum/NumPy mode): Adam, NAdam, AMSGrad, SGD, Momentum, LAMB.
LR Boost (optional)
The boost parameter controls a client-side learning rate engine that runs alongside Soft Algebra. Off by default (boost="none").
# Default — Soft Algebra only, no LR modification
opt = MobiuOptimizer(base_opt, license_key=KEY, method="adaptive", base_lr=3e-4)
# Gentle warmup + stagnation recovery
opt = MobiuOptimizer(base_opt, ..., boost="normal")
# Strong warmup + stagnation recovery (RL, sparse reward)
opt = MobiuOptimizer(base_opt, ..., boost="aggressive")
| Value | Warmup LR | Stagnation Spike | Smart Brake |
|---|---|---|---|
"none" |
— | — | — |
"normal" |
1.5× base_lr | 1.5× spike | ✅ cancels if improving |
"aggressive" |
3.0× base_lr | 3.0× spike | ✅ cancels if improving |
When to use boost:
| Environment | Recommended | Reason |
|---|---|---|
| Supervised learning, VQE | "none" |
Smooth loss landscape, SA sufficient |
| SB3 / stable frameworks | "normal" |
Framework manages policy updates internally |
| Portfolio / regime-switching trading | "normal" |
Stable reward signal per episode |
| PPO from scratch, sparse reward | "aggressive" |
High variance, needs strong LR push |
| MuJoCo, Atari, Crypto PPO | "aggressive" |
Sparse/delayed reward signal |
Key finding: "aggressive" hurts SB3 (60% win rate vs 70% for "normal"). SB3's internal update loop conflicts with strong LR boosts. Use "normal" for any framework that manages its own optimizer calls.
update_interval — set to 1 when optimizer.step() is called once per episode (e.g. portfolio trading, crypto). Default is 320 (standard PPO mini-batch size).
# Per-episode training loop
opt = MobiuOptimizer(base_opt, ..., boost="aggressive", update_interval=1)
Verbose feedback: set verbose=True to see what the boost engine is doing:
⚡ Boost (aggressive): attempting warmup (3.0x LR)...
💡 Boost (aggressive): warmup cancelled — training already improving
⚡ Boost (aggressive): attempting stagnation spike (3.0x LR)...
No message means training is going well on its own — no boost was applied.
Fair Benchmarking
The correct customer-view test compares Pure Adam (baseline) vs Adam wrapped by MobiuOptimizer (test). Both start from identical weights, same seed, same RNG state:
import torch
import numpy as np
# --- Shared init ---
torch.manual_seed(seed)
model_template = MyModel()
init_weights = {k: v.clone() for k, v in model_template.state_dict().items()}
# Save RNG state so both runs see identical data/noise
torch_state = torch.get_rng_state()
np_state = np.random.get_state()
# --- Baseline: Pure Adam ---
model_adam = MyModel()
model_adam.load_state_dict(init_weights)
optimizer_adam = torch.optim.Adam(model_adam.parameters(), lr=LR)
for batch in dataloader:
loss = criterion(model_adam(batch))
optimizer_adam.zero_grad()
loss.backward()
optimizer_adam.step()
# --- Restore RNG: Mobiu sees identical batches ---
torch.set_rng_state(torch_state)
np.random.set_state(np_state)
# --- Test: Adam + Mobiu-Q ---
model_mobiu = MyModel()
model_mobiu.load_state_dict(init_weights)
base_opt = torch.optim.Adam(model_mobiu.parameters(), lr=LR)
optimizer_mobiu = MobiuOptimizer(
base_opt,
license_key=LICENSE_KEY,
method="adaptive",
base_lr=LR, # prevent auto-replace
verbose=False
)
for batch in dataloader:
loss = criterion(model_mobiu(batch))
optimizer_mobiu.zero_grad()
loss.backward()
optimizer_mobiu.step(loss.item()) # pass dynamic loss
optimizer_mobiu.end()
Benchmarks
Reinforcement Learning (v4.5)
boost=none (Soft Algebra only):
| Domain | Improvement | Win Rate | Seeds | p-value |
|---|---|---|---|---|
| LunarLander-v3 (PPO) | +30.6% | 77% (23/30) | 30 | 0.000566 |
| LunarLander-v3 (SB3 PPO) | +109% | 67% (20/30) | 30 | 0.047 |
| Portfolio Trading (PPO) | +133.9% | 100% (10/10) | 10 | 0.000977 |
| MuJoCo InvertedPendulum-v5 | +17.7% | 40% (4/10) | 10 | — |
| MuJoCo Hopper-v5 | +9.8% | 70% (7/10) | 10 | — |
| Crypto Trading (BTC-like) | +168% | 95% (19/20) | 20 | 0.000002 |
| Crypto Trading (BTC-USD real) | +48.7% | 100% (20/20) | 20 | 0.000001 |
boost=aggressive (recommended for PPO from scratch):
| Domain | Improvement | Win Rate | Seeds | p-value |
|---|---|---|---|---|
| LunarLander-v3 (PPO) | +74.1% | 97% (29/30) | 30 | <0.000001 |
| MuJoCo InvertedPendulum-v5 | +68.5% | 60% (6/10) | 10 | — |
| MuJoCo Hopper-v5 | +33.4% | 90% (9/10) | 10 | — |
| Portfolio Trading (PPO) | +160.4% | 100% (10/10) | 10 | 0.000977 |
| Crypto Trading (BTC-like) | +318.1% | 95% (19/20) | 20 | 0.000002 |
| Atari Breakout | +53.1% | 100% (5/5) | 5 | — |
boost=normal (recommended for SB3 and stable frameworks):
| Domain | Improvement | Win Rate | Seeds | p-value |
|---|---|---|---|---|
| LunarLander-v3 (SB3 PPO) | +138.7% | 70% (21/30) | 30 | 0.008705 |
| Portfolio Trading (PPO) | +165.2% | 100% (10/10) | 10 | 0.000977 |
| Crypto Trading (BTC-like) | +275% | 95% (19/20) | 20 | 0.000002 |
Quantum Computing (VQE — IBM FakeFez)
| Molecule / Model | Improvement | Win Rate | Seeds |
|---|---|---|---|
| BeH₂ | +85.8% | 100% | 5 |
| HeH⁺ | +78.8% | 100% | 5 |
| H₄ Chain | +61.2% | 100% | 5 |
| H₂ | +50.6% | 100% | 5 |
| H₂O | +47.3% | 100% | 5 |
| LiH | +40.8% | 100% | 5 |
| Ferro Ising (6 spins) | +37.2% | 100% | 5 |
| Antiferro Heisenberg | +30.0% | 100% | 5 |
| Transverse Ising | +29.9% | 100% | 5 |
| Heisenberg XXZ (Δ=2.0) | +26.0% | 80% | 5 |
| C₁₃Cl₂ Half-Möbius | +20.5% | 100% | 5 |
QAOA (IBM FakeFez)
| Problem | Improvement | Win Rate | Seeds |
|---|---|---|---|
| MaxCut | +45.3% | 90% | 10 |
| Max Independent Set | +28.9% | 100% | 5 |
Machine Learning (Systematic Gradient Bias)
| Domain | Bias Source | Improvement | Win Rate |
|---|---|---|---|
| Federated Learning | Non-IID client data | +67.3% | 100% |
| Imbalanced Data | 90% majority class | +52.5% | 100% |
| Sim-to-Real | Wrong simulator physics | +47.0% | 100% |
| Noisy Labels | 30% systematic mislabeling | +40.3% | 100% |
| LLM Full Fine-tuning | Momentum optimizer | +43.5% | 100% |
| LLM LoRA Fine-tuning | Momentum optimizer | +5.6% | 100% |
Signal Processing & Black-box Optimization
| Domain | Improvement | Win Rate | Seeds |
|---|---|---|---|
| 5G Antenna Beamforming (16 elements) | +965.5% | 100% | 10 |
| Noisy Periodic (deep SA) | +547.9% | 90% | 10 |
| Beale function (shot noise) | +99.1% | 100% | 10 |
| Rosenbrock (shot noise) | +90.2% | 100% | 10 |
| Sphere (shot noise) | +81.1% | 90% | 10 |
| Rastrigin (shot noise) | +29.9% | 90% | 10 |
| Ackley (shot noise) | +27.7% | 80% | 10 |
Examples by Domain
Reinforcement Learning — PPO
import torch
import torch.nn as nn
import torch.nn.functional as F
import gymnasium as gym
from mobiu_q import MobiuOptimizer
LICENSE_KEY = "your-license-key-here"
LR = 3e-4 # industry standard for PPO
class ActorCritic(nn.Module):
def __init__(self, obs_dim, act_dim, hidden=64):
super().__init__()
self.shared = nn.Sequential(
nn.Linear(obs_dim, hidden), nn.Tanh(),
nn.Linear(hidden, hidden), nn.Tanh()
)
self.actor = nn.Linear(hidden, act_dim)
self.critic = nn.Linear(hidden, 1)
model = ActorCritic(8, 4)
base_opt = torch.optim.Adam(model.parameters(), lr=LR, eps=1e-5)
opt = MobiuOptimizer(
base_opt,
license_key=LICENSE_KEY,
method="adaptive",
base_lr=LR,
boost="aggressive", # optional: helps in high-variance RL
verbose=False
)
# PPO update inner loop
for epoch in range(n_epochs):
for batch in rollout_batches:
loss = ppo_loss(model, batch) # surrogate + value + entropy
opt.zero_grad()
loss.backward()
nn.utils.clip_grad_norm_(model.parameters(), 0.5)
opt.step(loss.item()) # pass dynamic loss
opt.end()
Reinforcement Learning — Stable-Baselines3
SB3 calls optimizer.step() internally. Use the callback pattern with set_metric():
import gymnasium as gym
import numpy as np
from stable_baselines3 import PPO
from stable_baselines3.common.callbacks import BaseCallback
from mobiu_q import MobiuOptimizer
LICENSE_KEY = "your-license-key-here"
class MobiuCallback(BaseCallback):
def __init__(self, verbose=0):
super().__init__(verbose=verbose)
self._mobiu = None
self._ep_returns = []
def _on_training_start(self):
base_opt = self.model.policy.optimizer
self._mobiu = MobiuOptimizer(
base_opt,
license_key=LICENSE_KEY,
method="adaptive",
sync_interval=50,
verbose=False
)
self.model.policy.optimizer = self._mobiu
def _on_step(self):
for info in self.locals.get("infos", []):
if "episode" in info:
self._ep_returns.append(info["episode"]["r"])
self._mobiu.set_metric(np.mean(self._ep_returns[-4:]))
return True
def _on_training_end(self):
if self._mobiu:
self._mobiu.end()
env = gym.make("LunarLander-v3")
model = PPO("MlpPolicy", env, learning_rate=3e-4, verbose=0)
model.learn(total_timesteps=200_000, callback=MobiuCallback())
Quantum Chemistry (VQE)
import numpy as np
from qiskit.circuit.library import EfficientSU2
from qiskit.quantum_info import SparsePauliOp
from qiskit_aer import AerSimulator
from qiskit.primitives import BackendEstimatorV2
from mobiu_q import MobiuQCore
try:
from qiskit_ibm_runtime.fake_provider import FakeFezV2 as FakeBackend
except ImportError:
from qiskit_ibm_runtime.fake_provider import FakeFez as FakeBackend
LICENSE_KEY = "your-license-key-here"
LR = 0.02 # standard + hardware default
# H₂ Hamiltonian
hamiltonian = SparsePauliOp.from_list([
("II", -0.4804), ("ZZ", 0.3435), ("ZI", -0.4347),
("IZ", 0.5716), ("XX", 0.0910), ("YY", 0.0910)
])
backend = AerSimulator.from_backend(FakeBackend())
estimator = BackendEstimatorV2(backend=backend)
estimator.options.default_shots = 4096
estimator.options.seed_simulator = 42
ansatz = EfficientSU2(2, reps=4, entanglement="linear")
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_ansatz = pm.run(ansatz)
isa_ops = hamiltonian.apply_layout(isa_ansatz.layout)
# Pre-generate SPSA deltas so both baseline and Mobiu see identical gradients
np.random.seed(seed * 1000)
spsa_deltas = [np.random.choice([-1, 1], size=ansatz.num_parameters)
for _ in range(NUM_STEPS)]
params = init_params.copy()
mobiu_opt = MobiuQCore(
license_key=LICENSE_KEY,
method="standard",
mode="hardware",
base_lr=LR,
verbose=False
)
for step in range(NUM_STEPS):
job = estimator.run([
(isa_ansatz, isa_ops, params),
(isa_ansatz, isa_ops, params + 0.1 * spsa_deltas[step]),
(isa_ansatz, isa_ops, params - 0.1 * spsa_deltas[step])
])
results = job.result()
energy = float(results[0].data.evs)
grad = (float(results[1].data.evs) - float(results[2].data.evs)) / 0.2 * spsa_deltas[step]
params = mobiu_opt.step(params, grad, energy)
mobiu_opt.end()
print(f"Final energy: {energy:.4f}") # H₂ ground state: -1.846 Ha
QAOA (MaxCut / MIS)
import torch
import torch.nn as nn
import numpy as np
from mobiu_q import MobiuOptimizer
LICENSE_KEY = "your-license-key-here"
LR = 0.1 # deep + hardware default
class QAOAModel(nn.Module):
def __init__(self, n_params, init_values):
super().__init__()
self.theta = nn.Parameter(torch.tensor(init_values, dtype=torch.float32))
# Wrap SGD — customer's optimizer runs, Mobiu enhances
model = QAOAModel(n_params, init_params)
base_opt = torch.optim.SGD(model.parameters(), lr=LR)
opt = MobiuOptimizer(
base_opt,
license_key=LICENSE_KEY,
method="deep",
mode="hardware",
base_lr=LR,
verbose=False
)
for step in range(100):
params_np = model.theta.detach().cpu().numpy()
energy, grad_np = get_qaoa_energy_and_gradient(params_np, spsa_deltas[step])
opt.zero_grad()
model.theta.grad = torch.tensor(grad_np, dtype=torch.float32)
opt.step(energy)
opt.end()
Machine Learning — Federated Learning
import torch
from mobiu_q import MobiuQCore
import numpy as np
LICENSE_KEY = "your-license-key-here"
LR = 0.01
params = np.random.randn(dim) * 0.5
opt = MobiuQCore(
license_key=LICENSE_KEY,
method="standard",
mode="simulation",
base_optimizer="Adam",
base_lr=LR,
verbose=False
)
for step in range(N_STEPS):
energy = global_loss(params)
gradient = federated_gradient(params, step) # biased from non-IID clients
params = opt.step(params, gradient, energy)
opt.end()
Machine Learning — Imbalanced / Noisy Labels / Sim-to-Real
Same pattern for all systematic-bias domains — just swap the gradient source:
import torch
from mobiu_q import MobiuOptimizer
LICENSE_KEY = "your-license-key-here"
LR = 0.001
model = Classifier()
base_opt = torch.optim.Adam(model.parameters(), lr=LR)
opt = MobiuOptimizer(
base_opt,
license_key=LICENSE_KEY,
method="standard",
base_lr=LR,
verbose=False
)
for batch_x, noisy_labels in train_loader:
loss = criterion(model(batch_x), noisy_labels)
opt.zero_grad()
loss.backward()
opt.step(loss.item()) # dynamic loss — Soft Algebra detects label bias
opt.end()
Why Soft Algebra Works for Systematic Bias
In all these domains the gradient is systematically biased away from the true loss direction:
- Federated: each client sees different data distribution → aggregated gradient biased
- Imbalanced: gradient dominated by majority class → minority classes underfit
- Sim-to-Real: simulator has wrong physics (friction, mass) → gradient points to wrong target
- Noisy Labels: labels consistently confused (e.g., 3↔8) → gradient points wrong way
Soft Algebra tracks the gap between gradient direction and actual loss improvement, then corrects for it. This is exactly what the realized component b_t measures.
Federated Learning — Detailed Example
import numpy as np
from mobiu_q import MobiuQCore
LICENSE_KEY = "your-license-key-here"
LR = 0.01
class FederatedTrainer:
def __init__(self, n_clients=10, non_iid_strength=0.8):
self.n_clients = n_clients
self.client_biases = [np.random.randn(dim) * non_iid_strength
for _ in range(n_clients)]
def federated_gradient(self, params, step):
np.random.seed(step)
sampled = np.random.choice(self.n_clients, size=5, replace=False)
grads = []
for c in sampled:
target = true_optimum + self.client_biases[c]
grads.append(2 * (params - target) / dim)
return np.mean(grads, axis=0)
trainer = FederatedTrainer()
params = np.random.randn(dim) * 0.5
opt = MobiuQCore(
license_key=LICENSE_KEY,
method="standard",
mode="simulation",
base_optimizer="Adam",
base_lr=LR,
verbose=False
)
for step in range(80):
energy = global_loss(params)
gradient = trainer.federated_gradient(params, step)
params = opt.step(params, gradient, energy)
opt.end()
Imbalanced Data — Detailed Example
import torch
from mobiu_q import MobiuOptimizer
LICENSE_KEY = "your-license-key-here"
LR = 0.001
# 90% class 0, 10% class 1 — gradient dominated by majority
train_loader = create_imbalanced_loader(imbalance_ratio=0.9)
model = FraudDetector()
base_opt = torch.optim.Adam(model.parameters(), lr=LR)
opt = MobiuOptimizer(
base_opt,
license_key=LICENSE_KEY,
method="standard",
base_lr=LR,
verbose=False
)
for batch_x, labels in train_loader:
loss = criterion(model(batch_x), labels)
opt.zero_grad()
loss.backward()
opt.step(loss.item()) # Soft Algebra detects majority-class bias
opt.end()
Sim-to-Real — Detailed Example
import torch
from mobiu_q import MobiuOptimizer
LICENSE_KEY = "your-license-key-here"
LR = 0.001
policy = RobotPolicy()
base_opt = torch.optim.Adam(policy.parameters(), lr=LR)
opt = MobiuOptimizer(
base_opt,
license_key=LICENSE_KEY,
method="standard",
base_lr=LR,
verbose=False
)
for step in range(80):
energy = real_world_loss(policy)
gradient = simulator_gradient(policy, step) # biased (wrong physics)
opt.zero_grad()
apply_grad_to_policy(policy, gradient)
opt.step(energy)
opt.end()
Noisy Labels — Detailed Example
import torch
from mobiu_q import MobiuOptimizer
LICENSE_KEY = "your-license-key-here"
LR = 0.001
# Systematic confusion: class i mislabeled as class (i+1) — 30% rate
train_loader = create_noisy_label_loader(noise_rate=0.3)
model = Classifier()
base_opt = torch.optim.Adam(model.parameters(), lr=LR)
opt = MobiuOptimizer(
base_opt,
license_key=LICENSE_KEY,
method="standard",
base_lr=LR,
verbose=False
)
for batch_x, noisy_labels in train_loader:
loss = criterion(model(batch_x), noisy_labels)
opt.zero_grad()
loss.backward()
opt.step(loss.item())
opt.end()
REINFORCE
import torch
import gymnasium as gym
from mobiu_q import MobiuOptimizer
LICENSE_KEY = "your-license-key-here"
LR = 3e-4
policy = torch.nn.Sequential(
torch.nn.Linear(8, 64), torch.nn.Tanh(),
torch.nn.Linear(64, 64), torch.nn.Tanh(),
torch.nn.Linear(64, 4)
)
base_opt = torch.optim.Adam(policy.parameters(), lr=LR)
opt = MobiuOptimizer(
base_opt,
license_key=LICENSE_KEY,
method="adaptive",
base_lr=LR,
verbose=False
)
env = gym.make("LunarLander-v3")
for episode in range(1000):
state, _ = env.reset()
log_probs, rewards = [], []
done = False
while not done:
logits = policy(torch.FloatTensor(state))
dist = torch.distributions.Categorical(logits=logits)
action = dist.sample()
log_probs.append(dist.log_prob(action))
state, reward, terminated, truncated, _ = env.step(action.item())
rewards.append(reward)
done = terminated or truncated
returns = []
G = 0
for r in reversed(rewards):
G = r + 0.99 * G
returns.insert(0, G)
returns = torch.tensor(returns)
returns = (returns - returns.mean()) / (returns.std() + 1e-8)
loss = sum(-lp * G for lp, G in zip(log_probs, returns))
opt.zero_grad()
loss.backward()
opt.step(loss.item()) # pass surrogate loss, not episode return
opt.end()
Trading / Finance (RL)
import torch
from mobiu_q import MobiuOptimizer
LICENSE_KEY = "your-license-key-here"
LR = 3e-4
policy = TradingPolicy() # outputs Hold/Buy/Sell
base_opt = torch.optim.Adam(policy.parameters(), lr=LR)
opt = MobiuOptimizer(
base_opt,
license_key=LICENSE_KEY,
method="adaptive",
base_lr=LR,
boost="normal", # helpful for regime-switching environments
update_interval=1, # one step() call per episode
verbose=False
)
for episode in range(500):
log_probs, rewards = collect_episode(policy, market_data)
returns = compute_returns(rewards, gamma=0.99)
loss = sum(-lp * G for lp, G in zip(log_probs, returns))
opt.zero_grad()
loss.backward()
opt.step(loss.item())
opt.end()
Custom / External Optimizers
Mobiu-Q wraps any optimizer with a standard PyTorch interface:
# Muon optimizer
from muon import Muon
base_opt = Muon(model.parameters(), lr=0.02, momentum=0.95)
opt = MobiuOptimizer(base_opt, license_key=LICENSE_KEY, method="adaptive", base_lr=0.02)
# LAMB from apex
from apex.optimizers import FusedLAMB
base_opt = FusedLAMB(model.parameters(), lr=0.001)
opt = MobiuOptimizer(base_opt, license_key=LICENSE_KEY, method="standard", base_lr=0.001)
# Adafactor from transformers
from transformers import Adafactor
base_opt = Adafactor(model.parameters(), lr=1e-3, relative_step=False)
opt = MobiuOptimizer(base_opt, license_key=LICENSE_KEY, method="adaptive", base_lr=1e-3)
Requirements: optimizer must have .step(), .zero_grad(), and .param_groups.
MobiuSignal + MobiuOptimizer Integration (RL Trading)
Use MobiuSignal features as your policy state, MobiuOptimizer as your optimizer:
from mobiu_q import MobiuOptimizer
from mobiu_q.signal import MobiuSignal
import torch, torch.nn as nn
LICENSE_KEY = "your-license-key-here"
LR = 3e-4
class TradingPolicy(nn.Module):
def __init__(self):
super().__init__()
self.net = nn.Sequential(
nn.Linear(5, 64), nn.Tanh(),
nn.Linear(64, 64), nn.Tanh(),
nn.Linear(64, 3) # Hold, Buy, Sell
)
def forward(self, features):
# features: [potential, realized, magnitude, position, pnl]
return self.net(features)
signal = MobiuSignal(lookback=20)
policy = TradingPolicy()
base_opt = torch.optim.Adam(policy.parameters(), lr=LR)
opt = MobiuOptimizer(
base_opt,
license_key=LICENSE_KEY,
method="adaptive",
base_lr=LR,
verbose=False
)
for episode in range(500):
signal.reset()
log_probs, rewards = [], []
for price in price_series:
result = signal.update(price)
if result is None:
continue
state = [result.potential, result.realized, result.magnitude, position, pnl]
logits = policy(torch.FloatTensor(state))
dist = torch.distributions.Categorical(logits=logits)
action = dist.sample()
log_probs.append(dist.log_prob(action))
rewards.append(execute_trade(action.item()))
returns = compute_returns(rewards)
loss = sum(-lp * G for lp, G in zip(log_probs, returns))
opt.zero_grad()
loss.backward()
opt.step(loss.item())
opt.end()
LLM Fine-tuning (LoRA / Full)
import torch
from mobiu_q import MobiuOptimizer
LICENSE_KEY = "your-license-key-here"
LR = 5e-3
# SGD with momentum works best for LoRA adapter layers
base_opt = torch.optim.SGD(lora_params, lr=LR, momentum=0.9)
opt = MobiuOptimizer(
base_opt,
license_key=LICENSE_KEY,
method="adaptive",
base_lr=LR,
sync_interval=50,
verbose=False
)
for epoch in range(num_epochs):
for batch in train_loader:
loss = criterion(model(batch))
opt.zero_grad()
loss.backward()
opt.step(loss.item())
# Optionally: opt.set_metric(-eval_loss) # use eval signal
opt.end()
Black-box / SPSA Optimization (Classical)
For antenna design, hyperparameter optimization, sensor calibration — landscapes similar to VQE:
import numpy as np
from mobiu_q import MobiuQCore
LICENSE_KEY = "your-license-key-here"
LR = 0.1
params = np.random.uniform(-5, 5, N_PARAMS)
opt = MobiuQCore(
license_key=LICENSE_KEY,
method="standard",
mode="hardware",
base_lr=LR,
verbose=False
)
# Pre-generate deltas — same for baseline and Mobiu (fair comparison)
np.random.seed(seed * 1000)
spsa_deltas = [np.random.choice([-1, 1], size=N_PARAMS) for _ in range(N_STEPS)]
for step in range(N_STEPS):
delta = spsa_deltas[step]
ck = 0.1 / ((step + 1) ** 0.101)
e_plus = evaluate_with_noise(params + ck * delta)
e_minus = evaluate_with_noise(params - ck * delta)
e_center = evaluate_with_noise(params)
grad = (e_plus - e_minus) / (2 * ck) * delta
params = opt.step(params, grad, e_center)
opt.end()
Known Limitations
Mobiu-Q works by detecting systematic gradient-direction bias and correcting for it. When the bias isn't there, or the signal isn't extractable, the optimizer won't help — and can occasionally hurt. This section documents the cases we've confirmed in benchmarking.
When Mobiu-Q does not help (or can hurt slightly)
1. Already-converged policies in continuous-control RL.
Mobiu-Q's strongest wins are when a base optimizer is stuck. When the base has already found a good local optimum, the additional warping sometimes perturbs rather than helps.
| Benchmark | Result | Win rate | p-value |
|---|---|---|---|
| SAC HalfCheetah-v5 (Actor+Critic wrap, already converged) | regression on some seeds | 9/20 | 0.849 (not significant) |
| SAC HalfCheetah-v5 (stuck seeds only, <-100 reward) | +163% to +309% | 100% on stuck seeds | — |
The pattern is bimodal: strong gains when the base is stuck, marginal or slightly negative when already converged. A conditional-wrapping mode (activate Mobiu-Q only when recent reward is below threshold) is planned for a future release. For now, the practical rule is: don't wrap an SAC policy that's already training well — there's nothing to fix.
2. Data-quality problems misdiagnosed as gradient bias.
Mobiu-Q specifically targets systematic direction bias in the gradient. It does not correct for label noise, feature drift, or distribution mismatch in the data itself.
| Benchmark | Bias source | Result |
|---|---|---|
| Logistics ranker (feature-level noise) | non-systematic label noise | Mobiu loses |
| Logistics ranker (random label flip) | stochastic, not directional | Mobiu loses |
If your baseline Adam is struggling because the data is noisy or mislabeled in a random (non-systematic) way, a data-cleaning pipeline will beat any optimizer change. See the "Why Soft Algebra Works for Systematic Bias" section above for when Mobiu-Q is and isn't the right tool.
When Soft Algebra is effectively off (false sense of activation)
3. Short training runs (cloud mode only).
In cloud mode, the server needs at least 3 energy samples in its history to compute curvature. With the default sync_interval=50, this means roughly 3 × sync_interval = 150 steps before Soft Algebra can meaningfully activate. Shorter runs fall back to the base optimizer — the client warns about this at end().
| Run length | Effective behavior (cloud mode) |
|---|---|
< 150 steps with default sync_interval=50 |
base Adam only (SA never computes curvature) |
| 150 – 500 steps | partial SA activation (3 – 10 syncs) |
| > 500 steps | full SA activation (≥ 10 syncs, meaningful warping) |
Local mode (v5.0+) sidesteps this entirely. sync_interval defaults to 1 in local mode, so Soft Algebra activates from step 1. If you run short benchmarks or need per-step gradient warping, use sa_backend="local".
4. Cloud connectivity (cloud mode only).
When running with sa_backend="cloud" (the default), the Cloud Function must be reachable. If it isn't (cold start, network failure, quota exceeded), the client warns once per session and falls back to the base optimizer. Local mode has no network dependency.
Hard constraints
5. Rate limit. 20 requests/second per license key. Production training at very high step rates should use sync_interval ≥ 50 (the default) — this has been tuned for typical deep-learning workloads.
6. Quantum/NumPy base optimizers. In MobiuQCore (quantum mode), the server-side base optimizer is limited to: Adam, NAdam, AMSGrad, SGD, Momentum, LAMB. No RMSprop or Adagrad. PyTorch hybrid mode has no such restriction — any optimizer with .step(), .zero_grad(), and .param_groups works.
How to tell if Mobiu-Q is actually helping
Run a fair A/B on your own problem before relying on it:
# Toggle Soft Algebra on/off with the same base optimizer, same seed, same data
opt_on = MobiuOptimizer(base_opt, license_key=KEY, use_soft_algebra=True, method="adaptive")
opt_off = MobiuOptimizer(base_opt, license_key=KEY, use_soft_algebra=False, method="adaptive")
If use_soft_algebra=False and use_soft_algebra=True give statistically similar results on your workload, your problem isn't gradient-direction-biased — Mobiu-Q is neutral on it. That's a legitimate finding, not a bug.
Troubleshooting
1. Switch Base Optimizer
| Problem Type | Recommended |
|---|---|
| LoRA / LLM | torch.optim.SGD(momentum=0.9) |
| VQE / Chemistry | torch.optim.Adam |
| QAOA | torch.optim.SGD or NAdam |
| RL / Trading | torch.optim.Adam |
| Federated / Imbalanced | torch.optim.Adam |
2. Switch Method
| Current | Try Instead |
|---|---|
standard → not improving |
adaptive |
adaptive → too noisy |
deep |
deep → slow |
standard |
3. Mode (Quantum/NumPy only)
| Current | Try Instead |
|---|---|
simulation |
hardware |
4. Adjust Learning Rate
Always pass base_lr= explicitly. If diverging, lower LR on the base optimizer. If stuck, raise it.
5. Boost not showing messages?
If you set boost="aggressive" but see no ⚡ messages:
- Check
verbose=Trueis set onMobiuOptimizer - If you call
step()once per episode, addupdate_interval=1
6. Common Fixes by Domain
| Domain | Issue | Fix |
|---|---|---|
| RL (PPO) | rewards unstable | boost="aggressive" + loss.item() |
| SB3 | can't pass loss | use callback + set_metric(reward) |
| VQE | gradient mismatch | pre-generate SPSA deltas, same for both |
| LoRA | slow convergence | SGD(momentum=0.9) + adaptive |
| Portfolio/Crypto | boost not firing | add update_interval=1 |
MobiuOptimizer — A/B Testing
To verify Soft Algebra provides value (not just LR scheduling), compare use_soft_algebra=True vs False with the same optimizer:
# SA ON
opt_on = MobiuOptimizer(base_opt, license_key=LICENSE_KEY,
use_soft_algebra=True)
# SA OFF (same LR scheduling, no nilpotent algebra)
opt_off = MobiuOptimizer(base_opt, license_key=LICENSE_KEY,
use_soft_algebra=False)
Ablation result (H₂ VQE, FakeFez, 20 seeds):
| Method | Mean Energy | Gap to Ground State | vs Baseline |
|---|---|---|---|
| Mobiu-Q SA ON (ε²=0) | -1.6678 Ha | 178 mHa | +53.8% ✅ |
| Baseline SA OFF | -1.4603 Ha | 386 mHa | — |
| Fake SA (regular ×) | -1.4597 Ha | 386 mHa | -0.2% ❌ |
- SA ON vs Baseline: 20/20 wins
- SA ON vs Fake SA: 20/20 wins
- Fake SA vs Baseline: 9/20 (random)
Conclusion: The nilpotent property ε²=0 is what drives the improvement — not LR scaling alone. Fake SA (regular multiplication) is statistically indistinguishable from the baseline. The difference between Real SA and Fake SA is 270×.
MobiuSignal 🆕
Trading signal generator using the same Soft Algebra potential/realized framework.
Validated Results (3,080 days BTC/USDT)
| Metric | Result |
|---|---|
| Spearman correlation | +0.222 (p<0.0001) |
| Q4/Q1 ratio | 1.83x larger moves |
| Precision lift | 1.18x vs random |
Mathematical Framework
Potential (aₜ) = σₜ/μₜ × scale # Normalized volatility
Realized (bₜ) = (Pₜ - Pₜ₋₁)/Pₜ₋₁ # Price change
Magnitude = √(aₜ² + bₜ²) # Signal strength
Usage
from mobiu_q.signal import MobiuSignal, backtest_signal
signal = MobiuSignal(lookback=20, vol_scale=100)
result = signal.compute(prices)
print(f"Potential: {result.potential:.3f}")
print(f"Realized: {result.realized:.3f}%")
print(f"Magnitude: {result.magnitude:.3f}")
print(f"Direction: {result.direction}") # +1, -1, or 0
print(f"Quartile: Q{result.quartile}") # 1–4 (4=strongest)
# Streaming
for price in live_price_stream:
result = signal.update(price)
if result and result.is_strong:
execute_trade(result.direction)
# Backtest
bt = signal.backtest(historical_prices, future_window=5)
print(f"Correlation: {bt.correlation:.3f} (p={bt.correlation_pvalue:.4f})")
print(f"Q4/Q1 Ratio: {bt.q4_q1_ratio:.2f}x")
Note: MobiuSignal runs 100% locally — no API calls, no license key.
MobiuAttention 🧪
Performance
| Seq Length | Transformer | MobiuAttention | Speedup |
|---|---|---|---|
| 4,096 | 16.9ms | 16.4ms | ~1x |
| 8,192 | 75.3ms | 33.8ms | 2.2x ✅ |
| 16,384 | OOM 💥 | Works | ∞ |
Tested on T4 GPU, batch=2, d_model=128
Usage
from mobiu_q.experimental import MobiuBlock
import torch.nn as nn
class LongContextLM(nn.Module):
def __init__(self, vocab, d=512, h=8, layers=6):
super().__init__()
self.embed = nn.Embedding(vocab, d)
self.blocks = nn.Sequential(*[MobiuBlock(d, h) for _ in range(layers)])
self.head = nn.Linear(d, vocab)
def forward(self, x):
return self.head(self.blocks(self.embed(x)))
model = LongContextLM(50000)
x = torch.randint(0, 50000, (1, 16384))
out = model(x) # no OOM
Combining with MobiuOptimizer
| Configuration | Result |
|---|---|
| Standard Attention + MobiuOptimizer | ✅ Best quality |
| MobiuAttention + Adam | Good for long context |
| MobiuAttention + MobiuOptimizer | May interfere — test first |
Note: MobiuAttention runs 100% locally — no license key.
🛡️ Anomaly Detection
MobiuAD — Streaming Detector
from mobiu_q import MobiuAD
detector = MobiuAD(license_key=LICENSE_KEY, method="deep")
for value in data_stream:
result = detector.detect(value)
if result.is_anomaly:
print(f"⚠️ Anomaly! Δ†={result.delta_dagger:.4f}")
TrainGuard — Safe ML Training
from mobiu_q import TrainGuard
guard = TrainGuard(license_key=LICENSE_KEY)
for epoch in range(100):
result = guard.step(loss=train_loss, gradient=grad_norm, val_loss=val_loss)
if result.alert:
if result.alert_type == 'GRADIENT_EXPLOSION':
reduce_lr()
elif result.alert_type == 'OVERFITTING':
apply_regularization()
guard.end()
MobiuAD vs PyOD
| Feature | MobiuAD | PyOD |
|---|---|---|
| Type | Streaming | Batch |
| Detects | Behavioral changes | Statistical outliers |
| Real-time | ✅ Yes | ❌ No |
| Early warning | ✅ Yes | ❌ No |
| Pattern changes | ✅ Excellent | ⚠️ Limited |
| Value outliers | ⚠️ Good | ✅ Excellent |
How It Works
Soft Algebra
SoftNumber multiplication: (a,b) × (c,d) = (ad + bc, bd)
The nilpotent property ε²=0 separates "potential" (what could happen) from "realized" (what did happen). Applied to optimization:
a_t = curvature / (curvature + mean_energy) # landscape uncertainty
b_t = improvement ∈ [-1, 1] # actual progress
trust = |real| / (|real| + |soft|) # confidence in update (φ=-1 → halt if both vanish)
lr_t = base_lr × (1 + trust × soft_factor) # adaptive scaling
In quantum optimization, the realized component captures the gap between gradient direction and actual energy improvement — exactly the signal needed to handle shot noise and SPSA variance.
Full Examples
Quantum Chemistry (VQE)
| File | Description |
|---|---|
vqe_fakefez_ibm_customer_adam.py |
H₂ on IBM FakeFez |
test_heh_customer.py |
HeH⁺ molecule |
test_h4_customer.py |
H₄ chain |
test_h2o_customer.py |
H₂O molecule |
test_lih_customer.py |
LiH molecule |
test_beh2_customer.py |
BeH₂ molecule |
vqe_c13cl2_fakefez_customer.py |
C₁₃Cl₂ Half-Möbius |
Condensed Matter Physics
| File | Description |
|---|---|
test_heisenbeg_xxz_deep.py |
Heisenberg XXZ (Δ=2.0) |
test_transverse_ising.py |
Transverse field Ising |
test_xy_model.py |
XY model |
test_ferro_ising_fair.py |
Ferromagnetic Ising |
test_antiferro_heisenberg.py |
Antiferromagnetic Heisenberg |
test_hubbard_dimer.py |
Hubbard dimer |
test_ssh_model.py |
SSH model (topological) |
test_kitaev_chain.py |
Kitaev chain |
QAOA
| File | Description |
|---|---|
test_fakefez_qaoa_new.py |
MaxCut on FakeFez |
test_fakefez_qaoa_mis_new.py |
Max Independent Set on FakeFez |
Reinforcement Learning
| File | Description |
|---|---|
ppo_lunarlander.py |
PPO from scratch, 30 seeds |
sb3_customer.py |
SB3 PPO with MobiuCallback |
test_portfolio_ppo.py |
PPO portfolio trading |
test_mujoco_customer.py |
MuJoCo InvertedPendulum + Hopper |
atari_breakout_customer.py |
Atari Breakout DQN |
crypto_trading_fair.py |
Crypto Trading PPO — BTC-like synthetic, regime switching |
crypto_trading_realdata.py |
Crypto Trading PPO — BTC-USD real daily data |
Machine Learning
| File | Description |
|---|---|
test_federated_customer.py |
Federated learning (non-IID) |
test_noisy_labels_customer.py |
Systematic label noise |
test_sim_to_real_customer.py |
Sim-to-real transfer |
test_imbalanced_customer.py |
90% class imbalance |
test_llm_finetuning_v3.py |
LoRA + Full fine-tuning |
Black-box & Signal Processing
| File | Description |
|---|---|
test_sphere.py |
Sphere (shot noise) |
test_ackley.py |
Ackley (shot noise) |
test_beale.py |
Beale (shot noise) |
test_rosenbrok.py |
Rosenbrock (shot noise) |
blackbox_spsa_customer.py |
Rastrigin + SPSA |
antenna_customer.py |
5G antenna beamforming |
periodic_benchmark.py |
Noisy periodic landscape |
Utilities & Demos
| File | Description |
|---|---|
double_mobiu_customer.py |
MobiuAttention + MobiuOptimizer |
nilpotency_ablation.py |
Real SA vs Fake SA ablation |
benchmark_behavioral_customer.py |
MobiuAD behavioral detection |
example_signal_customer.py |
MobiuSignal demo |
License
| Tier | API Calls | Price | Get Started |
|---|---|---|---|
| Free | 20/month | $0 | Sign up |
| Research | Unlimited + local mode | $490/month | Subscribe |
| Enterprise | Self-hosted + SLA | Contact us | enterprise@mobiu.ai |
Note: MobiuAttention & MobiuSignal run locally — no API calls required. MobiuOptimizer's local mode (v5.0+, sa_backend="local") also runs without cloud.
Links
Citation
@software{mobiu_q,
title={Mobiu-Q: Soft Algebra for Optimization, Attention and Anomaly Detection},
author={Mobiu Technologies},
year={2026},
url={https://mobiu.ai}
}
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mobiu_q-5.0.tar.gz.
File metadata
- Download URL: mobiu_q-5.0.tar.gz
- Upload date:
- Size: 89.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
318abf013aff7a266fc008e8ec22373bbfee49e744d1233c73fefad6ad2b742e
|
|
| MD5 |
bdffd131b17cb6bb4f13b8af743a713a
|
|
| BLAKE2b-256 |
48aaaf2db334b4d550e97ec78ad6711623be9cbaa90a3d2deb90e3c380c6780e
|
File details
Details for the file mobiu_q-5.0-py3-none-any.whl.
File metadata
- Download URL: mobiu_q-5.0-py3-none-any.whl
- Upload date:
- Size: 70.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8409a2f7f36122be3e8ecc9b6a030e92083e1fd923daf8b00df1b40477e80206
|
|
| MD5 |
661690354ead92fcfe3f95b9df2ef71f
|
|
| BLAKE2b-256 |
61f8033bf1ef2d64c355de0b3e62327803f476955ad69ed035bfb28c1cd60cf0
|