Skip to content

Refactor for Sentence Transformer >5.4 and zarr >3 - #64

Merged
mengerj merged 93 commits into
mainfrom
dev-claude
Jun 24, 2026
Merged

Refactor for Sentence Transformer >5.4 and zarr >3#64
mengerj merged 93 commits into
mainfrom
dev-claude

Conversation

@mengerj

@mengerj mengerj commented Jun 19, 2026

Copy link
Copy Markdown
Owner

Align closer to new Sentence Transformer multimodal approach.
Improve memory efficiency by not registering initial embeddings with the model (full embedding matrix into memory), but using a mapped memory file.
Update and trim dependancies.
Remove benchmarking logic from this repo into a new benchmark-repo
Prepare for PyPi release

Claude (dev-claude) and others added 30 commits May 27, 2026 07:31
- VectorStore: disk-backed vector lookup using numpy memmap
  - Construction from numpy, DataFrame, dict, AnnData (obs/var)
  - Batch lookup, persistence (save/load), float16 support
  - Memory-efficient: only accessed rows paged into RAM
- Comprehensive test suite (22 tests across 6 test classes)
- Refactoring roadmap document (REFACTOR_ROADMAP.md)
- New src/mmcontext/modules/ package with MMContextModule extending
  sentence-transformers InputModule (v5.4+ preprocess() API)
- Dual-mode preprocessing: text via AutoTokenizer, omics via VectorStore
  lookup or direct vector input (obs and var cases)
- Forward produces unified features dict: token_embeddings, attention_mask,
  modality_ids (0=text, 1=omics, 2=pad)
- Text encoder freezing/unfreezing with partial layer support
- Save/load roundtrip (VectorStore intentionally excluded from saved state)
- 27 tests covering preprocess, forward, properties, freezing, persistence
- Bump sentence-transformers dependency to >=5.4 in pyproject.toml
- Import fallback for both v5.4+ and v5.0 import paths
- Dual projection heads (text_proj, omics_proj) dispatched by modality_ids
- Three modes: Identity, Linear+LayerNorm, MLP+LayerNorm
- LayerNorm instead of BatchNorm1d (handles single-token omics inputs)
- Pad tokens (modality_id=2) pass through as zeros
- Save/load via safetensors with config roundtrip
- 18 tests: forward, mixed batch, gradient flow, identity, persistence
- Updated modules/__init__.py to export AdapterModule
… tokens

- Multi-head self-attention applied only to omics tokens (modality_id=1)
- Text tokens pass through unchanged; pad tokens zeroed
- Uses nn.TransformerEncoder with pre-LayerNorm (norm_first=True)
- Per-sample gather/scatter handles variable-length gene sequences
- Trivial for obs-level (L=1): degenerates to feedforward, safe to include
- Configurable: input_dim, num_heads, num_layers, feedforward_dim, dropout
- Save/load via safetensors + config roundtrip
- 20 tests: passthrough, transformation, masking, gradient flow, persistence
- Updated modules/__init__.py to export OmicsAttentionModule
…ore, training script

- Full SentenceTransformer pipeline integration tests (encode, save/load, training)
- Rename omics preprocess key from token_embeddings to input_values for
  compatibility with ST training collator's collect_features suffix matching
- Forward still writes token_embeddings for downstream module compatibility
- Memory-efficient VectorStore preparation from zarr adata links (reads only
  needed obsm rows, never loads full AnnData)
- Training script for cxg_schaefer_tiny dataset with wandb integration
- Fix fp16 test pollution of session-scoped stubs
- Post-training save/load roundtrip test
…P.md

- Move old architecture to _legacy/: mmcontextencoder, adapters, omicsencoder,
  onehot, cell_sentence_transformer
- Update all imports (tests, scripts, embed) to _legacy path
- Export modules + io from top-level __init__.py
- ROADMAP.md: architecture overview, eval framework analysis, missing features,
  test gaps, and file map for future development
updates:
- [github.com/tox-dev/pyproject-fmt: v2.5.0 → v2.23.0](tox-dev/pyproject-fmt@v2.5.0...v2.23.0)
- [github.com/astral-sh/ruff-pre-commit: v0.9.3 → v0.15.15](astral-sh/ruff-pre-commit@v0.9.3...v0.15.15)
- [github.com/pre-commit/pre-commit-hooks: v5.0.0 → v6.0.0](pre-commit/pre-commit-hooks@v5.0.0...v6.0.0)
…cture

- AdapterModule: add freeze_text_proj/unfreeze_text_proj/freeze_omics_proj/unfreeze_omics_proj helpers
- UnfreezeTextEncoderCallback: use isinstance(model[0], MMContextModule) and call model[0].unfreeze_text_encoder() instead of old text_encoder attribute path
- UnfreezeAdapterCallback: find AdapterModule by iterating model.children() (works at any pipeline position); use new projection-level freeze/unfreeze methods
- tests/test_adapter_callback.py: 18 tests covering epoch-based unfreezing (before/at/after target, fractional epochs, once-only guard), adapter at positions 1 and 2, independent text/omics unfreeze schedules, and warning paths

Closes #50

Co-authored-by: mengerj <mengerj@users.noreply.github.com>
- dependabot.yml: weekly grouped pip + github-actions updates targeting dev-claude
- codeql.yaml: Python semantic code scanning on push/PR + weekly
- dependabot-auto-merge.yaml: auto-merge patch/minor Dependabot PRs after CI
Added configuration for Python dependencies and GitHub Actions updates.
Bumps the actions-all group with 3 updates: [actions/checkout](https://github.com/actions/checkout), [actions/setup-python](https://github.com/actions/setup-python) and [codecov/codecov-action](https://github.com/codecov/codecov-action).


Updates `actions/checkout` from 4 to 6
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v4...v6)

Updates `actions/setup-python` from 5 to 6
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](actions/setup-python@v5...v6)

Updates `codecov/codecov-action` from 3 to 6
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](codecov/codecov-action@v3...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions-all
- dependency-name: actions/setup-python
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions-all
- dependency-name: codecov/codecov-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions-all
...

Signed-off-by: dependabot[bot] <support@github.com>
ci: add Dependabot, CodeQL, and Dependabot auto-merge
- Add missing docstring to main() in scripts/train_tiny.py (D103)
- Add TYPE_CHECKING guard for pd/ad imports in vector_store.py (F821)
- Use `list | tuple` union syntax in isinstance call (UP038)
- Remove unused variables device, attended_samples, sample_indices in omics_attention_module.py (F841)
- Replace generator expressions with set comprehensions in test_adapter_module.py (C401)
- Remove unused features_no_prompt variable in test_mmcontext_module.py (F841)

Co-authored-by: mengerj <mengerj@users.noreply.github.com>
pre-commit-ci Bot and others added 19 commits June 10, 2026 08:55
Lean zarr/h5ad loaders: read only obs + requested obsm layer (Fixes #61)
Bumps the actions-all group with 5 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `4` | `6` |
| [actions/upload-artifact](https://github.com/actions/upload-artifact) | `4` | `7` |
| [github/codeql-action](https://github.com/github/codeql-action) | `3` | `4` |
| [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) | `2` | `3` |
| [codecov/codecov-action](https://github.com/codecov/codecov-action) | `6` | `7` |



Updates `actions/checkout` from 4 to 6
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v4...v6)

Updates `actions/upload-artifact` from 4 to 7
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](actions/upload-artifact@v4...v7)

Updates `github/codeql-action` from 3 to 4
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@v3...v4)

Updates `dependabot/fetch-metadata` from 2 to 3
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](dependabot/fetch-metadata@v2...v3)

Updates `codecov/codecov-action` from 6 to 7
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](codecov/codecov-action@v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions-all
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions-all
- dependency-name: codecov/codecov-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions-all
- dependency-name: dependabot/fetch-metadata
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions-all
- dependency-name: github/codeql-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions-all
...

Signed-off-by: dependabot[bot] <support@github.com>
updates:
- [github.com/tox-dev/pyproject-fmt: v2.23.0 → v2.24.1](tox-dev/pyproject-fmt@v2.23.0...v2.24.1)
- [github.com/astral-sh/ruff-pre-commit: v0.15.15 → v0.15.17](astral-sh/ruff-pre-commit@v0.15.15...v0.15.17)
[pre-commit.ci] pre-commit autoupdate
…ude/actions-all-e1e150180b

ci: bump the actions-all group across 1 directory with 5 updates
- Remove embed/ files: embed_pipeline, model_utils, dataset_utils,
  cellwhisperer_utils, scsa_utils (multi-model orchestration → benchmark)
- Remove eval/ files: eval_pipeline, embedding_alignment, umap_plotter
- Move collect_adata_subset to io/_adata_subset
- Update __init__.py for embed/, eval/, io/
- Clean utils.py: remove Hydra helpers, dead imports
- Bump version to 2.0.0, slim core deps
- Add optional dep groups: [eval], [train]
- Rewrite README for v2.0 architecture
- _read_obs_names_zarr: anndata 0.13.x with zarr 3.x stores array elements
  as zarr Groups (encoded format); detect this and fall back to read_elem
  instead of calling group[:] which fails in zarr 3.x path-join code
- _select_rows_float32: switch from get_orthogonal_selection (deprecated in
  zarr 3.x) to arr.oindex which works in both zarr 2.x and 3.x
- test_bad_ds: replace chained assignment bad_df3["col"][0] = ... (silently
  a no-op under pandas 3.x Copy-on-Write) with bad_df3.at[0, "col"] = ...
- test_best_label_annotation: replace series[i] integer indexing (raises
  KeyError on non-integer index in pandas 3.x) with series.iloc[i]
- remove .claude/settings.local.json (local settings file, not for repo)

Co-authored-by: mengerj <mengerj@users.noreply.github.com>
Comment thread src/mmcontext/io/prepare_store.py Fixed
Comment thread src/mmcontext/io/prepare_store.py Fixed
Comment thread scripts/train_config.py Fixed
Comment thread scripts/train_tiny.py Fixed
Comment thread tests/conftest.py Fixed
Comment thread tests/test_adapter_module.py Fixed
store = VectorStore.from_numpy(sample_matrix, sample_ids, path=path)

with pytest.raises(KeyError, match="unknown_cell"):
store["unknown_cell"]
Comment thread tests/test_prepare_store.py Fixed
Comment thread tests/test_prepare_store.py Fixed
Comment thread tests/test_sentence_transformer_integration.py Fixed
mengerj and others added 9 commits June 19, 2026 11:28
…ring sanitization'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
@mengerj
mengerj merged commit cbe4f35 into main Jun 24, 2026
15 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.

2 participants