Skip to content

feat: add batched local MMseqs2-GPU features - #637

Draft
DimaMolod wants to merge 15 commits into
mainfrom
feat/mmseqs2-gpu
Draft

feat: add batched local MMseqs2-GPU features#637
DimaMolod wants to merge 15 commits into
mainfrom
feat/mmseqs2-gpu

Conversation

@DimaMolod

@DimaMolod DimaMolod commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • split local AF3 feature generation into a JAX-free GPU MSA stage and independent CPU AF3 template/finalization stage
  • use stage-specific settings and results (MsaBatchResult/MsaArtifact versus feature results); the compatibility facade translates between the two deep interfaces
  • share one lightweight, idempotent MMseqs CLI/database flag schema across entry points
  • publish each MSA atomically and write a schema-v2 completion manifest with name, basename, size, mtime, and SHA-256 for every written or reused bundle
  • reject missing, empty, or malformed MMseqs unpack output; invalid persisted bundles are removed so the next workflow DAG repairs them, while downstream AF3/template failures preserve valid MSAs
  • remove the ignored GPU sensitivity setting and include MMseqs/search/database identities in MSA cache provenance
  • retain native AF3 template processing and include template cutoff plus PDB-seqres/mmCIF identities in final-feature provenance
  • bundle pinned MMseqs2-GPU 18-8cc5c in both AF2 and AF3 images, verified by SHA-256 and mmseqs version
  • add an MSA-backend comparison harness for depth, coverage, template counts, and matched downstream inference/DockQ inputs

Scientific status

This backend remains experimental. This PR does not establish prediction-accuracy equivalence with native AF3; a representative full-database matched inference/DockQ comparison remains a merge gate.

Validation

  • full local suite with CPU JAX backend: 558 passed, 1 skipped, 24 deselected
  • focused MMseqs/feature/container tests: 45 passed
  • real CPU contract using pinned MMseqs2-GPU 18-8cc5c: 1 passed; exercised createdb -> makepaddedseqdb -> search -> result2msa -> unpackdb through the production adapter
  • the AF3 Docker compatibility stage now runs that real CPU contract automatically against /opt/mmseqs/bin/mmseqs
  • real GPU contract on A100 Slurm job 61423155 passed the production command chain and produced the expected nonempty 0.fasta
  • CI is running for 05c582ee

Companion workflow PR: KosinskiLab/AlphaPulldownSnakemake#54.

Related resident inference core PR: #636.

DimaMolod and others added 12 commits September 3, 2026 12:37
A search that returns nothing produces an MSA holding only the query. That is
legitimate for an orphan sequence but is also what a misconfigured, truncated or
half-built database produces, and provenance alone cannot tell them apart.

- record unpairedDepth/pairedDepth in each MSA bundle
- warn per protein when a bundle contains only the query, and report them in
  MsaBatchResult.query_only
- fail the MSA stage when every protein in a shard is query-only
- include the database index size in the cache signature, so a database rebuilt
  under the same identifier invalidates cached artifacts

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The composed feature path shares MsaBatch with the MSA-only stage but dropped its
query_only report, so a zero-hit search was guarded in one entry point and silent
in the other.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Which databases supply unpaired hits and which supplies paired hits was encoded as
DATABASE_NAMES[:3] and a literal "uniprot", repeated in both entry points, with the
per-database defaults duplicated between _mmseqs2_cli and feature_batch. Reordering
the tuple would have swapped paired for unpaired: a plausible-looking MSA, silently
wrong species pairing, and no error anywhere.

- feature_batch owns UNPAIRED_DATABASE_NAMES, PAIRED_DATABASE_NAME, DATABASE_NAMES
  and DEFAULT_MAX_SEQUENCES; the duplicate default table is gone
- add DatabaseSelection and database_selection(), so both entry points ask for roles
  by name instead of slicing
- validation messages derive from the same constants

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Both entry points constructed SubprocessMmseqsProcess with the default gpu=True, so
the CPU search path existed but could only be reached from tests - a site without
GPUs could not use this feature at all.

- add --mmseqs_use_gpu (default true) and pass it through from both entry points
- rename the CPU search mode from "cpu-contract" to "cpu": it is a supported mode,
  not a test fixture, and it stays distinct in bundle provenance so a cached CPU
  result is not reused for a GPU run

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
MMseqs2 sizes its target-database splits from 90% of the physical node memory via
sysconf(_SC_PHYS_PAGES), which takes no account of the cgroup a batch scheduler put
it in. On a 755 GB node with --mem=64G it therefore sizes for ~680 GB, declines to
split, and is OOM-killed instead.

- add --mmseqs_split_memory_limit and thread it into the search command
- omit the option entirely when unset, preserving today's behaviour

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

1 participant