# well_poincare_rl Hierarchical, multi-step, hyperbolic (Poincarรฉ ball) predictor for spatiotemporal scientific fields, with PPO fine-tuning, continual learning (Replay + EWC), and explicit data/checkpoint contracts for multi-contributor use. **What this is for:** production-minded RL and representation work on *real* scientific data โ€” not demos that silently fall back to synthetic trajectories. The same codebase also supports hierarchy recovery on real taxonomic trees (PBDB), as a direct test of whether hyperbolic geometry helps where theory predicts it should. --- ## Current status | Capability | Status | |---|---| | Channel-agnostic encoder (variable C) | ๐Ÿ”’ Done โ€” verified C=2, 11, 47 | | Per-domain normalizer + same-C replay | ๐Ÿ”’ Done โ€” end-to-end multi-C | | Well adapter (channels-last โ†’ `(T,C,H,W)`) | ๐Ÿ”’ Done โ€” matches real `the_well` interface | | Live multi-stream Well (HF) | ๐Ÿ”’ setup / ๐Ÿ“‹ results โ€” see below | | Real PBDB hierarchy embedding | ๐Ÿ”’ Done โ€” 2141 nodes, Poincarรฉ > Euclidean at dim=8 | | Multi-seed / multi-dim real PBDB sweep | Open | | Attention-based channel fusion | Open | | Soft hierarchical region priors in the ball | Open (gated on multi-domain latent data) | --- ## Key results ### Track A โ€” Real multi-stream continual learning (Well) Sequential training on live Hugging Face streams, no synthetic fallback. ๐Ÿ”’ **Checkpoint-verified:** provenance `REAL_STREAMED` for all three domains, dataset names (`gray_scott_reaction_diffusion`, `active_matter`, `shear_flow`), per-domain normalizer channel counts (2, 11, 4 โ€” confirmed via each normalizer's stored tensor shape), and model architecture (channel-agnostic encoder, matching this session's redesign, not a stale checkpoint). ๐Ÿ“‹ **Reported (retention table below):** the loss values themselves. `run_multistream.py`'s checkpoint format does not currently save loss/retention history โ€” only `model`, `params`, `normalizers`, `datasets` โ€” so these numbers were not independently re-derived from a saved artifact, only structurally corroborated by everything above. | After domain | gray_scott (C=2) | active_matter (C=11) | shear_flow (C=4) | |---|---|---|---| | Domain 1 | 0.3486 | โ€” | โ€” | | Domain 2 | 0.3561 | 0.3299 | โ€” | | Domain 3 | 0.3248 | 0.3484 | 0.3358 | Replay buffer by channel count after full run: `{2: 24, 11: 24, 4: 24}` (๐Ÿ”’ structurally consistent with the checkpoint's saved normalizer shapes). Artifact: `multistream_continual_gray_scott_active_matter_shear_flow.pt` ### Track B โ€” Real PBDB hierarchy (Poincarรฉ vs Euclidean) Live taxonomy edges from Dinosauria + Mammalia (16,000 occurrence records). ๐Ÿ”’ **Checkpoint-verified, independently recomputed from raw data:** edge hash, config hash, and identity hash were all recomputed from the raw occurrence JSON using this repo's own `build_edge_list`/`hash_edge_list`/`hash_config`/ `combined_identity_hash` functions and matched the checkpoint filename and its stored `results_table` โ€” including `mean_delta_mrr` โ€” to full float precision. This is the strongest-verified result in the project. | Setting | ฮ”MRR | Verification | |---|---|---| | dim=8, softmax, c=1.0 | ๐Ÿ”’ **+0.1151** | recomputed from checkpoint | | dim=8, softmax, c=2.0 | ๐Ÿ”’ **+0.1576** | recomputed from checkpoint | Individual Poincarรฉ/Euclidean MRR values (e.g. 0.42 vs 0.305) appear in the original run log and are arithmetically consistent with the deltas above, but are ๐Ÿ“‹ reported, not ๐Ÿ”’ checkpoint-verified โ€” the checkpoint's `results_table` stores the delta and win count, not the two absolute MRR values separately. - Provenance: `REAL_PBDB_TAXONOMY` - Scale: 2141 nodes, 2172 edges - Protocol: reconstruction (train = test edges) โ€” standard for measuring embedding capacity, not link-prediction generalization - Artifact: content-addressed checkpoint under `checkpoints/` + `.meta.json` **Scope (honest):** one seed, one dimension, metrics-only checkpoint (full embedding weights not yet exported). Multi-seed / multi-dim confirmation on this graph is the natural next step, not a re-verification of what's already solid. --- ## Core contracts ### Data loading - Real paths **hard-fail** on missing data, schema mismatch, or stream failure. They never silently return synthetic data. - Synthetic data is available only via explicit APIs (`get_synthetic_dataset`, `--synthetic`). Provenance is always reported. - Tensor layout is validated against declared contracts, never guessed from shape heuristics. ### Trajectory validation Checked **before** training. Trajectories shorter than `window + pred_steps` raise `TrajectoryTooShortError` / `EmptyDatasetError` instead of being skipped inside the loop (which previously could train an epoch on zero batches). ### Dataset-reuse registry (`DatasetRegistry`) Prevents retraining on an already-consumed dataset under multi-contributor use. ``` (absent) --claim()--> IN_PROGRESS --mark_consumed()--> CONSUMED \--mark_failed()--> FAILED --allow_retry()--> (absent) ``` - Claims are atomic (`O_CREAT|O_EXCL`). - `CONSUMED` blocks future claims by default (`DatasetAlreadyUsedError`). - Explicit override: `--allow-dataset-reuse`. ### Checkpoints (`CheckpointStore`) Content-addressed: filename = `sha256(config_hash + code_hash + dataset_hash)`. - Atomic writes (temp โ†’ `os.replace()` only after success). - Partial writes (`.pt` without `.meta.json`) raise `CheckpointIntegrityError`. - Identical `(config, code, dataset)` โ†’ `DUPLICATE_EXISTS`, no redundant write. ### Structured outcomes Contract failures raise typed exceptions with stable `outcome_code` values (e.g. `NO_DATA_DIRECTORY`, `CHANNEL_COUNT_MISMATCH`, `ALREADY_CONSUMED`). --- ## Architecture (as shipped) | Component | Role | |---|---| | `MultiScaleEncoder` | Channel-agnostic: shared 1ร—1 stem per channel โ†’ mean fusion โ†’ spatial path | | `HierarchicalHyperbolicPredictor` | Multi-step prediction in the Poincarรฉ ball | | `FieldNormalizer` | Per-domain z-score; hard-rejects channel-count mismatch | | `ReplayBuffer` | Same-C (and optional spatial) filtering; clear error if mixed shapes stacked | | `WellStreamAdapter` | Converts real `the_well` samples (channels-last input/output) โ†’ `{"fields": (T,C,H,W)}` | | `DiagonalEWC` + teacher distillation | Continual learning across domains | | `HierarchyEmbedding` | Poincarรฉ / Euclidean node embeddings for taxonomy trees | | Physics losses | Spatial/temporal consistency + generalized channel-coupling (all pairs) | **Design note on variable channels:** ingestion (encoder + normalizer + replay) is solved separately from latent organization. Soft hierarchical region priors in the ball remain open and are gated on multi-domain data actually reaching a shared latent space. --- ## Running ```bash pip install torch geoopt optuna gymnasium h5py tqdm the_well # Contract tests python -m pytest tests/ -v # Synthetic full pipeline (no network) python -m src.run_full --synthetic # Real local Well-format HDF5 (hard-fails if missing/invalid) python -m src.run_full --data-root ./data/real # Live multi-stream continual run (requires HF access, e.g. Kaggle) python -m src.run_multistream \ --datasets gray_scott_reaction_diffusion active_matter shear_flow \ --max-samples 96 --epochs-per-domain 3 # Hierarchy embedding โ€” synthetic (no network) python -m src.run_hierarchy_embed --synthetic --tree-type balanced \ --branching-factor 3 --tree-depth 6 --dims 2 3 5 8 \ --loss-types softmax --burn-in-epochs 0 --c-values 1.0 2.0 \ --epochs 80 --lr 0.02 --seeds 0 1 2 # Hierarchy embedding โ€” real PBDB (requires network) python -m src.data_pbdb --discover --base-name Dinosauria --limit 5 # first python -m src.run_hierarchy_embed \ --pbdb-taxa Dinosauria Mammalia \ --dims 8 --loss-types softmax --burn-in-epochs 0 \ --c-values 1.0 2.0 --epochs 80 --lr 0.02 --seeds 0 --optimizer radam ``` Defaults that matter for Track B with current stability guards: `--burn-in-epochs 0` (ablation showed burn-in reduces ฮ”MRR under guarded `clip_to_ball` / `clamp_curvature` setup). --- ## Artifacts | File | What it is | |---|---| | `multistream_continual_gray_scott_active_matter_shear_flow.pt` | Track A model + params + per-domain normalizers + dataset list (no loss history) | | `checkpoints/.pt` + `.meta.json` | Track B metrics table + provenance (content-addressed) | | Large `*_8000.json` under data cache | Raw PBDB fetch cache only โ€” optional, regenerable | Hierarchy checkpoints currently store `results_table` (metrics), not full embedding weights. Weight export is a small follow-on if reloadable node vectors are needed. --- ## Known limitations - Multi-stream retention numbers are ๐Ÿ“‹ reported, not ๐Ÿ”’ checkpoint-verified โ€” see Track A above. The run's provenance, channel counts, and architecture are independently confirmed; the specific loss trajectory is not yet, since the current checkpoint format doesn't persist it. - Real PBDB hierarchy result is one seed / one dimension. - Channel fusion is mean-pooling (lossy). Attention fusion is the natural upgrade. - Soft region structure in the Poincarรฉ ball is intentionally deferred until multi-domain data is routinely in a shared latent. - PPO is implemented and smoke-tested; it is not the primary claim of the current verified results. - Contributors are assumed to exchange portable checkpoint + meta files; a shared remote registry is a future decision if contributor count grows. --- ## Design principles (non-negotiable) 1. **Real-data paths hard-fail.** Synthetic only via explicit opt-in. 2. **No silent shape / channel mistakes.** Prefer loud, typed errors. 3. **Provenance is first-class.** Every load reports where data came from. 4. **Checkpoints are content-addressed and atomic.** 5. **Report what the numbers say**, including when Euclidean wins or a previously recommended default (e.g. burn-in) is reversed by ablation. 6. **Verification tier is part of the claim.** "Verified" always specifies *verified how* โ€” checkpoint-recomputed and self-reported are not the same thing, and this document says which is which rather than picking one word for both. --- ## License / packaging Apache 2.0 intended for model and code release. Package layout is `src/`-based and pip-installable for local development.