Skip to content

fix: zero turnover limit, CAE/SAE minibatch edge cases, attention with no neighbors or long lag - #56

Merged
stefan-jansen merged 7 commits into
ml4t:mainfrom
quantum-like:review/fixes
Oct 18, 2026
Merged

stefan-jansen merged 7 commits into
ml4t:mainfrom
quantum-like:review/fixes

Conversation

@quantum-like

@quantum-like quantum-like commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Closes #55.

Correct model-training edge cases that previously liquidated holdings, returned untrained CAE parameters, crashed SAE BatchNorm, or produced invalid attention results:

  • Zero turnover retains previous valid holdings; negative and non-finite limits raise.
  • CAE rejects hidden-layer fits when every minibatch is skipped and no update runs.
  • SAE folds a trailing singleton into the previous minibatch and rejects fewer than two training observations.
  • Graph attention uses a finite self-attention fallback for isolated assets and preserves masked-neighbor exclusion. The maintainer correction expands per-observation masks across attention heads.
  • Cross-sectional attention uses all-padding keys when lag exceeds the window.

Retain the five original contributor commits and attribution. Append the multi-head correction and four public DeepPortfolioModel fit/predict cases covering one/two heads and isolated/connected assets.

Verification

At 01406ca, with dependency repair #57 integrated:

  • The same nine submitted regressions fail on actual main a1e73b4. The corrected full native suite passes 435 tests, including the four added public multi-head cases.
  • Ruff/format, source ty, coverage thresholds (95.58% lines, 85.68% branches), strict MkDocs, and package build pass.
  • All 33 applicable hosted checks pass. This includes supported source/installed-wheel platform cells, Python 3.15 core qualification, dependency audits, artifact comparisons, and MPS qualification. The CUDA/performance PR job and Python wait-exception job are skipped by their configured conditions.
  • Separate CPU, RTX 3090 CUDA, and hosted MPS evidence passes all six neural families with the original tolerances. Current MPS evidence uses macOS 15.7.9 arm64 and Torch 2.14.1.
  • Rejected single-row CAE and SAE refits preserve usable prior checkpoints.

The zero-limit correction changes prior erroneous liquidation behavior. No release is requested.

AI assistance: The original fix commits retain Cursor Agent attribution. Codex reviewed the submission, prepared the graph-mask correction, and ran maintainer verification.

cursoragent and others added 5 commits October 7, 2026 07:30
A non-positive turnover cap replaced the target book with zeros, which
liquidates an existing portfolio instead of forbidding trades. A zero cap
now scales weight changes to the previous holdings, and a negative cap is
rejected.

Co-authored-by: quantum-like <[email protected]>
Hidden beta networks skip one-row minibatches because BatchNorm cannot
train on them. When every batch was a single row, fit still returned a
converged model whose weights were the random initialization. That fit
now fails instead of emitting an untrained beta surface.

Co-authored-by: quantum-like <[email protected]>
A configured batch size that left a one-row tail, or a single valid
training row, crashed inside BatchNorm during training. Singleton tails
are folded into the previous batch, and a one-row sample now raises a
clear error before any update.

Co-authored-by: quantum-like <[email protected]>
A fully blocked adjacency row, or a node whose only neighbors are missing,
produced NaN attention and NaN portfolio weights. Those queries now attend
to themselves when present, and otherwise use a finite fallback.

Co-authored-by: quantum-like <[email protected]>
When the lag exceeded the window length, the history slice used a
negative stop and either crashed or read the end of the same window.
Lags that reach past the start of the window now see an empty history.

Co-authored-by: quantum-like <[email protected]>

@stefan-jansen stefan-jansen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed all five fixes at 077948a. I independently ran the nine added edge-case regressions against main 786ca1b and the submitted implementation: all nine fail on the base and pass with these changes. The fixes are useful, and the five original commits should be retained.

One additional regression must be corrected before merging. MacroGraphAttention now creates a three-dimensional attention mask with shape (batch_size * n_periods, n_assets, n_assets). PyTorch requires its first dimension to include the number of attention heads. The public DeepPortfolioModel.fit workflow with d_model=4, macro_gnn_heads=2, batch_size=2, three periods and two assets fails with an expected mask shape of (12, 2, 2), receiving (6, 2, 2). Both connected and isolated-node graphs fail; corresponding one-head controls pass.

I reproduced those two failures and verified that repeating each per-observation mask across attention heads corrects all four public fit/predict cases. I am appending that focused repair and the regressions to this submission, together with a hardware-qualification fixture that actually exercises a two-head graph containing an isolated node. Existing managed-portfolio, turnover/cost, checkpoint and chunk-invariance checks remain passing. Final-head full/platform/hardware qualification is still required; the unpublished correction is not covered by the current hosted run.

Current submitted-head CI has 31 successful checks, two expected skips, and failures in Dependency Audit and its dependent Qualify Candidate. The audit log identifies urllib3 2.7.0 and virtualenv 21.7.1; the security lock repair belongs in the existing dependency PR #57. These failures are separate from the numerical fixes and must be resolved before ordinary protected integration.

AI assistance: Codex performed this maintainer review, independent reproductions and repair preparation. No release is requested.

@stefan-jansen
stefan-jansen merged commit 4d1ec3c into ml4t:main Oct 18, 2026
35 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Zero turnover limit liquidates, CAE reports convergence without training, SAE BatchNorm crash on one-row batch, attention NaN/wrap edge cases

3 participants