solver.press

Low-rank (rank <= 128) factorisation of the first-moment optimizer state reduces optimizer state memory by ~49% on transformer architectures, and the saving is near rank-independent because rank is a small fraction of the narrowest 2-D layer at those widths. Scope: this is the MEMORY claim only, computed analytically from parameter shapes; it makes NO claim about training quality. FALSIFIED IF optimizer-state bytes computed from the parameter shapes of a d_model>=768 transformer show a saving below 25% at any rank in 4-128 with the first-moment factorisation alone.

Computer ScienceMar 6, 2026Evaluation Score: 76%

Adversarial Debate Score

57% survival rate under critique

Expert panel critique

Independent views, each critiquing the hypothesis on its own — the score rewards genuine disagreement and discounts consensus.

Gemini: Falsifiable and relevant papers support memory reduction, but the specific application to multi-agent LLMs for finance is less directly supported and could be a potential weakness.
ChatGPT: It’s falsifiable and “Taming Momentum” + “FlashOptim” plausibly support the core claim that low-rank EMA can reduce optimizer-state memory, but the hypothesis overreaches by tying this specifically to “multi-agent LLM systems for financial applications” without evidence those settings preserve lo...
Claude: The hypothesis has a plausible core—Taming Momentum's low-rank EMA reformulation does directly address optimizer memory overhead, making the memory reduction claim technically grounded—but the extension to "multi-agent LLM systems for financial applications" is entirely speculative and unsupporte...

Supporting Research Papers

Computational Result

🧪 Numerically verified· analytic optimizer-state bytes from transformer parameter shapes, ranks 4-128

Computation is the experiment in this domain.

Low-rank first-moment factorisation saves 49.6-49.9% of optimizer-state bytes on d_model 768/2048/4096 transformers and is near rank-independent: 47.7% even at rank 128 on a 7B-class model. The stated falsification condition -- a saving below 25% at any rank in 4-128 -- is not met at any point.

Method: analytic optimizer-state bytes from transformer parameter shapes, ranks 4-128 · Result: supported · Confidence: 90%

Formal Verification

Z3 logical consistency:✅ Consistent

Z3 checks whether the hypothesis is internally consistent, not whether it is empirically true.

Experimental Validation Package

This discovery has a Claude-generated validation package with a full experimental design.

Precise Hypothesis

Applying a low-rank exponential moving average (EMA) reformulation — as introduced in the Taming Momentum framework — to optimizer state matrices (specifically the first- and second-moment tensors in Adam-family optimizers) reduces peak optimizer-state memory consumption by ≥40% relative to full-rank Adam baselines, without degrading final validation loss by more than 2% (relative), when training multi-agent large language model (LLM) systems (≥7B total parameters across agents) on financial time-series or financial NLP tasks. The claim is falsifiable: if memory reduction is <40% OR validation loss degrades >2% relative under matched compute budgets, the hypothesis is refuted.

Disproof criteria:
  1. PRIMARY DISPROOF: Peak optimizer-state memory reduction (measured via torch.cuda.max_memory_allocated() delta between optimizer state initialization and peak training step) is <40% relative to full-rank Adam baseline across ≥3 independent seeds on the target architecture.
  2. PERFORMANCE DISPROOF: Final validation loss (or perplexity on held-out financial text) degrades by >2% relative (e.g., baseline perplexity 12.0 → low-rank perplexity >12.24) under identical wall-clock training budgets.
  3. THROUGHPUT DISPROOF: Tokens-per-second throughput decreases by >15% due to SVD overhead, negating memory savings with compute cost (memory-compute Pareto frontier is not improved).
  4. RANK COLLAPSE: The low-rank approximation error (Frobenius norm ||M_full - M_lowrank||_F / ||M_full||_F) exceeds 0.30 for >20% of weight matrices, indicating the approximation is too lossy to be practically useful.
  5. FINANCIAL TASK DISPROOF: On ≥2 financial downstream benchmarks (e.g., FinQA accuracy, portfolio Sharpe ratio from RL agent), the low-rank trained model scores >5% relatively worse than the full-rank baseline.
  6. SCALING DISPROOF: Memory savings do not scale with model size (i.e., savings at 70B are not meaningfully larger in absolute GB than at 7B), suggesting the effect is architecture-specific rather than general.

Spine & Adversarial Read

  • highPre-empted by published prior art (added 27 Sep 2026, analysis/optimizer_memory/PREEMPTION.md): GaLore, MoFaSGD and SMMF already deliver this capability at real scale, with MoFaSGD publishing our exact adaptive method and SMMF dominating it on every axis.
    unresolved
  • highThe memory/quality trade this EVP's ROI and commercial-value figures assume does not hold. A pre-registered two-architecture test (analysis/optimizer_memory/ACCURACY_A_RESULT.md, ACCURACY_B_RESULT.md) found no configuration that both saves meaningful memory and avoids a large compute cost: 49.2% memory saving costs 41x the measured floor, and the only safe configuration (rank 384, r/d 50%) saves only 16.6% -- far below the >=40% this package's $800K/yr and $500K-2M licensing figures are built on.
    unresolved

Closest Existing Work

Experimental Protocol

MINIMUM VIABLE TEST (MVT): Train two 7B-parameter two-agent LLM systems (actor + critic or two collaborative agents) on a financial corpus for 20,000 steps:

  • Condition A: Full-rank AdamW (baseline)
  • Condition B: Low-rank EMA AdamW (Taming Momentum, rank r=64)
  • Condition C: Low-rank EMA AdamW (rank r=128) as ablation Measure: (1) peak optimizer-state VRAM, (2) validation perplexity on FinText held-out set, (3) tokens/sec throughput, (4) Frobenius approximation error per layer. Run 3 seeds per condition. Statistical test: paired Wilcoxon signed-rank on memory measurements across layers; two-sided t-test on final validation loss.

FULL VALIDATION: Extend to 13B and 70B two-agent systems. Add financial downstream tasks (FinQA, FiNER-139, synthetic portfolio optimization RL environment). Include wall-clock-matched comparisons (not just step-matched). Add GradNorm and loss landscape sharpness (Hessian trace approximation via Hutchinson estimator) as secondary metrics.

Required datasets:
  1. Financial Pretraining Corpus:
    • FinPile or equivalent: SEC EDGAR filings 2000–2024 (~180GB text), earnings call transcripts (~40GB), financial news (Reuters/Bloomberg archive ~60GB). Total ~280GB raw, ~120GB tokenized at GPT-2 tokenizer.
    • Alternatively: RedPajama financial subset + proprietary Bloomberg corpus (if available).
  2. Financial Downstream Benchmarks:
    • FinQA (Chen et al. 2021): 8,281 QA pairs over earnings reports. HuggingFace: datasets/ibm/finqa.
    • FiNER-139: Named entity recognition in financial text. HuggingFace: datasets/nlpaueb/finer-139.
    • TAT-QA: Table-and-text QA on financial documents. GitHub: NExTplusplus/TAT-QA.
  3. Multi-Agent RL Financial Environment:
    • OpenAI Gym-compatible portfolio optimization environment (e.g., FinRL: github.com/AI4Finance-Foundation/FinRL).
    • Historical price data: Yahoo Finance API or Quandl WIKI dataset (2010–2024, ~500 tickers).
  4. Optimizer Implementation Reference:
    • Taming Momentum paper codebase (arXiv:2401.xxxxx — confirm exact citation).
    • HuggingFace Transformers + PEFT for model scaffolding.
    • DeepSpeed ZeRO-3 or FSDP for distributed training baseline.
  5. Hardware Profiling Tools:
    • NVIDIA Nsight Systems, torch.profiler, nvidia-smi dmon for memory telemetry.
    • py-spy for CPU profiling of SVD overhead.
Success:
  1. MEMORY: Peak optimizer-state VRAM reduced by ≥40% (rank-64) and ≥25% (rank-128) vs full-rank AdamW baseline, measured across all 3 seeds with p<0.05 (paired Wilcoxon).
  2. QUALITY: Final validation perplexity degrades by ≤2% relative (e.g., baseline 12.0 → low-rank ≤12.24) at rank-64; ≤1% at rank-128.
  3. THROUGHPUT: Tokens/sec reduction ≤15% vs baseline (SVD overhead is acceptable).
  4. DOWNSTREAM: FinQA exact match within 3% relative of baseline; FiNER-139 F1 within 2% relative.
  5. SCALING: At 13B two-agent scale, low-rank (rank-64) enables training on 50% fewer GPUs (4× vs 8× A100 80GB) without OOM, confirming practical hardware reduction.
  6. APPROXIMATION QUALITY: Median Frobenius error across layers ≤0.20 at rank-64.
  7. REPRODUCIBILITY: All 3 seeds agree on memory reduction within ±5 percentage points.
Failure:
  1. Memory reduction <40% at rank-64 across any 2 of 3 seeds.
  2. Validation perplexity degrades >2% relative at rank-64 (primary quality threshold).
  3. SVD overhead causes >15% throughput reduction AND memory savings <50% (i.e., compute-memory tradeoff is unfavorable).
  4. Frobenius approximation error >0.30 for >20% of layers at rank-64 (approximation too lossy).
  5. FinQA accuracy drops >5% relative (financial task performance unacceptably degraded).
  6. At 13B scale, low-rank training does NOT enable GPU count reduction (scaling claim fails).
  7. Training instability: loss spikes >3× baseline loss at any checkpoint in >1 of 3 seeds.

1,840

GPU hours

30d

Time to result

$4,200

Min cost

$18,500

Full cost

ROI Projection

Commercial:

SUPERSEDED 27 Sep 2026 -- the named targets (Bloomberg, Refinitiv, Two Sigma, Citadel, Renaissance Technologies) can adopt GaLore or SMMF directly, both published with reference implementations and no licensing cost. There is no commercial case for licensing or productizing this method over them. Original pitch retained for the record: drop-in PyTorch optimizer (LowRankEMAAdamW), $500K-2M/enterprise consulting value, cloud-provider integration.

🔓 If proven, this unlocks

Proving this hypothesis is a prerequisite for the following downstream discoveries and applications:

  • 1low-rank-ema-for-moe-mixture-of-experts-training
  • 2memory-efficient-rlhf-multi-agent-financial-systems
  • 3low-rank-optimizer-states-for-continual-learning-finance
  • 4hardware-democratization-7b-training-on-consumer-gpus
  • 5low-rank-ema-applied-to-vision-language-financial-agents
  • 6taming-momentum-extensions-to-second-order-optimizers

Prerequisites

These must be validated before this hypothesis can be confirmed:

  • taming-momentum-original-paper-validation
  • multi-agent-llm-financial-benchmark-suite
  • low-rank-optimizer-correctness-unit-tests
  • finrl-environment-stability-verification

Implementation Sketch

# ============================================================
# LOW-RANK EMA ADAMW — CORE IMPLEMENTATION SKETCH
# ============================================================

import torch
from torch.optim import Optimizer
import torch.linalg as LA

class LowRankEMAAdamW(Optimizer):
    """
    AdamW with low-rank EMA reformulation (Taming Momentum).
    Stores moment tensors as rank-r SVD factors instead of full matrices.
    
    Memory: O(r*(d+k)) per weight matrix W in R^{d x k}
    vs O(d*k) for standard AdamW.
    Reduction ratio: r*(d+k) / (d*k) = r*(1/k + 1/d)
    For d=k=4096, r=64: 64*8192 / (4096*4096) = 524288/16777216 = 3.1%
    → 96.9% reduction per layer (before accounting for embeddings/biases)
    """
    
    def __init__(self, params, lr=1e-4, betas=(0.9, 0.999), eps=1e-8,
                 weight_decay=0.01, rank=64, svd_update_freq=1):
        defaults = dict(lr=lr, betas=betas, eps=eps,
                       weight_decay=weight_decay, rank=rank,
                       svd_update_freq=svd_update_freq)
        super().__init__(params, defaults)
    
    def _get_lowrank_factors(self, tensor, rank):
        """Compute truncated SVD, return low-rank factors."""
        if tensor.dim() < 2:
            return None  # scalars/biases: use full storage
        
        # Reshape to 2D if needed (e.g., conv filters)
        orig_shape = tensor.shape
        mat = tensor.reshape(tensor.shape[0], -1)
        
        # Truncated SVD — top-r components only
        # torch.linalg.svd is O(min(d,k)^2 * max(d,k))
        # For large matrices, use randomized SVD for speed
        U, S, Vh = LA.svd(mat, full_matrices=False)
        U_r = U[:, :rank]      # (d, r)
        S_r = S[:rank]         # (r,)
        Vh_r = Vh[:rank, :]    # (r, k)
        
        return U_r, S_r, Vh_r, orig_shape
    
    def _reconstruct_from_lowrank(self, U_r, S_r, Vh_r, orig_shape):
        """Reconstruct approximate moment tensor from low-rank factors."""
        mat = U_r @ torch.diag(S_r) @ Vh_r
        return mat.reshape(orig_shape)
    
    @torch.no_grad()
    def step(self, closure=None):
        loss = None
        if closure is not None:
            with torch.enable_grad():
                loss = closure()
        
        for group in self.param_groups:
            rank = group['rank']
            beta1, beta2 = group['betas']
            lr = group['lr']
            eps = group['eps']
            wd = group['weight_decay']
            svd_freq = group['svd_update_freq']
            
            for p in group['params']:
                if p.grad is None:
                    continue
                
                grad = p.grad.data
                state = self.state[p]
                
                # Initialize state
                if len(state) == 0:
                    state['step'] = 0
                    state['use_lowrank'] = (p.dim() >= 2 and 
                                           min(p.shape) > rank)
                    
                    if state['use_lowrank']:
                        # Initialize low-rank moment factors
                        # m_t (first moment) low-rank factors
                        state['m_U'], state['m_S'], state['m_Vh'], \
                            state['orig_shape'] = \
                            self._get_lowrank_factors(
                                torch.zeros_like(p.data), rank)
                        # v_t (second moment) low-rank factors  
                        state['v_U'], state['v_S'], state['v_Vh'], _ = \
                            self._get_lowrank_factors(
                                torch.zeros_like(p.data), rank)
                    else:
                        # Fallback: full storage for small tensors
                        state['exp_avg'] = torch.zeros_like(p.data)
                        state['exp_avg_sq'] = torch.zeros_like(p.data)
                
                state['step'] += 1
                t = state['step']
                
                # Weight decay
                p.data.mul_(1 - lr * wd)
                
                if state['use_lowrank']:
                    # Reconstruct current moments from low-rank factors
                    m_t = self._reconstruct_from_lowrank(
                        state['m_U'], state['m_S'], state['m_Vh'],
                        state['orig_shape'])
                    v_t = self._reconstruct_from_lowrank(
                        state['v_U'], state['v_S'], state['v_Vh'],
                        state['orig_shape'])
                    
                    # Standard EMA updates
                    m_t.mul_(beta1).add_(grad, alpha=1 - beta1)
                    v_t.mul_(beta2).addcmul_(grad, grad, value=1 - beta2)
                    
                    # Re-project to low-rank (every svd_freq steps)
                    if t % svd_freq == 0:
                        state['m_U'], state['m_S'], state['m_Vh'], _ = \
                            self._get_lowrank_factors(m_t, rank)
                        state['v_U'], state['v_S'], state['v_Vh'], _ = \
                            self._get_lowrank_factors(v_t, rank)
                    
                    # Bias correction
                    bc1 = 1 - beta1 ** t
                    bc2 = 1 - beta2 ** t
                    m_hat = m_t / bc1
                    v_hat = v_t / bc2
                    
                    # Parameter update
                    p.data.addcdiv_(m_hat, v_hat.sqrt().add_(eps),
                                   value=-lr)
                else:
                    # Standard AdamW update for small tensors
                    exp_avg = state['exp_avg']
                    exp_avg_sq = state['exp_avg_sq']
                    exp_avg.mul_(beta1).add_(grad, alpha=1-beta1)
                    exp_avg_sq.mul_(beta2).addcmul_(
                        grad, grad, value=1-beta2)
                    bc1 = 1 - beta1 ** t
                    bc2 = 1 - beta2 ** t
                    step_size = lr / bc1
                    denom = (exp_avg_sq.sqrt() / (bc2**0.5)).add_(eps)
                    p.data.addcdiv_(exp_avg, denom, value=-step_size)
        
        return loss


# ============================================================
# MULTI-AGENT TRAINING LOOP SKETCH
# ============================================================

class TwoAgentFinancialSystem:
    """
    Two-agent LLM system: Analyst + Critic
    Both trained with LowRankEMAAdamW
    """
    def __init__(self, analyst_model, critic_model, rank=64):
        self.analyst = analyst_model   # 7B LLaMA-3
        self.critic = critic_model     # 7B LLaMA-3
        
        # Shared optimizer with low-rank EMA
        all_params = (list(analyst_model.parameters()) + 
                     list(critic_model.parameters()))
        self.optimizer = LowRankEMAAdamW(
            all_params, lr=1e-4, rank=rank,
            svd_update_freq=1  # ablate: try 5, 10
        )
    
    def training_step(self, financial_text_batch):
        # Agent 1: Generate financial analysis
        analyst_output = self.analyst(financial_text_batch)
        analyst_loss = compute_lm_loss(analyst_output, financial_text_batch)
        
        # Agent 2: Critique the analysis
        critic_input = concat(financial_text_batch, analyst_output.detach())
        critic_output = self.critic(critic_input)
        critic_loss = compute_critique_loss(critic_output)
        
        # Joint loss
        total_loss = analyst_loss + 0.1 * critic_loss
        
        self.optimizer.zero_grad()
        total_loss.backward()
        torch.nn.utils.clip_grad_norm_(
            list(self.analyst.parameters()) + 
            list(self.critic.parameters()), 1.0)
        self.optimizer.step()
        
        return total_loss.item()


# ============================================================
# MEMORY PROFILING HARNESS
# ============================================================

def profile_optimizer_memory(model, optimizer_class, rank=None, 
                              n_steps=100):
    """
    Measure optimizer state memory footprint.
    Returns: dict with memory breakdown in GB
    """
    torch.cuda.reset_peak_memory_stats()
    
    if rank is not None:
        opt = optimizer_class(model.parameters(), lr=1e-4, rank=rank)
    else:
        opt = optimizer_class(model.parameters(), lr=1e-4)
    
    # Measure after optimizer init (states allocated after first step)
    dummy_input = torch.randn(4, 512, device='cuda')
    
    mem_before_step = torch.cuda.memory_allocated() / 1e9
    
    for step in range(n_steps):
        loss = model(dummy_input).sum()
        loss.backward()
        opt.step()
        opt.zero_grad()
    
    mem_after_steps = torch.cuda.memory_allocated() / 1e9
    peak_mem = torch.cuda.max_memory_allocated() / 1e9
    
    # Isolate optimizer state memory
    param_mem = sum(p.numel() * p.element_size() 
                   for p in model.parameters()) / 1e9
    optimizer_state_mem = mem_after_steps - param_mem
    
    return {
        'total_peak_gb': peak_mem,
        'optimizer_state_gb': optimizer_state_mem,
        'param_gb': param_mem,
        'n_steps': n_steps
    }


# ============================================================
# FROBENIUS ERROR DIAGNOSTIC
# ============================================================

def compute_approximation_error(optimizer):
    """
    For each low-rank state, compute ||M - M_r||_F / ||M||_F
    Returns per-layer errors for quality monitoring.
    """
    errors = {}
    for name, state in optimizer.state.items():
        if 'use_lowrank' in state and state['use_lowrank']:
            # Reconstruct approximate moment
            m_approx = optimizer._reconstruct_from_lowrank(
                state['m_U'], state['m_S'], state['m_Vh'],
                state['orig_shape'])
            # We don't have ground truth full-rank moment here
            # Proxy: compare to a full-rank AdamW run (offline analysis)
            # During training: track singular value decay as proxy
            sv_decay = state['m_S'][-1] / state['m_S'][0]  # last/first SV ratio
            errors[str(name)] = sv_decay.item()
    return errors
Abort checkpoints:

CHECKPOINT 1 — Day 3 (Unit Test Gate): Abort condition: LowRankEMAAdamW on 125M GPT-2 toy run shows >5% perplexity degradation vs full AdamW at rank-64 over 1,000 steps. Action: Debug SVD implementation; check for numerical issues in moment reconstruction before proceeding to 7B scale. Cost saved by aborting: ~$14,000 (avoid full 7B + 13B experiments).

CHECKPOINT 2 — Day 8, Step 2,000 of Baseline Run: Abort condition: Full-rank AdamW baseline training loss is not decreasing (stuck or diverging) — indicates multi-agent training loop bug unrelated to optimizer. Action: Fix training loop before introducing low-rank variable. Cost saved: ~$12,000.

CHECKPOINT 3 — Day 10, Step 5,000 of Low-Rank Run (r=64): Abort condition: (a) Memory reduction <20% (far below 40% target, suggesting implementation error), OR (b) Validation perplexity >5% worse than baseline at same step count. Action: (a) Audit which layers are using low-rank vs full storage — likely embedding exclusion bug; (b) increase rank to 128 and re-evaluate; if still >5% degraded, abort financial downstream evaluation. Cost saved: ~$8,000.

CHECKPOINT 4 — Day 15, After Both Rank Conditions Complete: Abort condition: Neither rank-64 nor rank-128 achieves ≥40% memory reduction AND ≤2% quality degradation simultaneously (i.e., the Pareto frontier is entirely dominated by full-rank AdamW). Action: Abort scaling experiment (13B); pivot to analysis paper documenting negative result with theoretical explanation. Negative result is still publishable. Cost saved: ~$9,000 (avoid 13B experiment).

CHECKPOINT 5 — Day 20, After Financial Downstream Evaluation: Abort condition: FinQA accuracy drops >10% relative OR Sharpe ratio in RL environment is negative (agent fails to learn profitable policy with low-rank optimizer). Action: Abort commercial value claims; reframe as pure memory-efficiency paper without financial application validation. Cost saved: ~$2,000 (avoid extended RL environment runs).

CHECKPOINT 6 — Day 23, Mid-13B Scaling Experiment: Abort condition: OOM errors occur even with low-rank optimizer on 4× A100 80GB for 13B two-agent system (i.e., memory savings insufficient to enable hardware reduction). Action: Test with rank-32 (more aggressive compression) before full abort; if still OOM, abort scaling claim. Cost saved: ~$3,000.

Source

AegisMind Research
Need AI to work rigorously on your problems? AegisMind uses the same multi-model engine for personal and professional use. Get started