Python gRPC sidecar wrapping AlphaFold2 (monomer/multimer structure prediction) with first-class MSA caching.
MSA generation (jackhmmer/hhblits, or ColabFold's MMseqs2 search) dominates AF2
wall-clock, so the MSA cache is an explicit API surface (QueryMsaCache +
MsaCachePolicy), not an implementation detail. The real model resolves the MSA
through the cache, shells out to colabfold_batch under the shared cancellable-
subprocess runner, parses the ranked PDBs (with pLDDT/pTM/ipTM), and uploads them
as content-addressed artifacts.
Implements AF2Service from
FoldForge/proto, vendored here as a git
submodule at ./proto. Every sidecar exposes the same shape: a server-streaming
Run that emits ProgressEvent heartbeats and ends with a RunResult or
ErrorDetail.
git clone --recurse-submodules git@github.com:FoldForge/sidecar-af2.git
cd sidecar-af2
python3.13 -m venv .venv && source .venv/bin/activate # Python >= 3.10 required
pip install -e ".[dev]"
./scripts/gen_proto.sh # generate stubs into src/foldforge_af2/gen/
pytest -q # MSA-cache + ColabFold parser fixtures + gRPC integration
# Start the server. NOTE: there is no __main__ / console-script — invoke serve():
python -c "from foldforge_af2.server import serve; serve()" # :50064Install model deps (GPU box) with pip install -e ".[model]"; the durable S3/R2
MSA-cache backend needs the [storage] extra (boto3).
| var | default | meaning |
|---|---|---|
FOLDFORGE_SIDECAR_BIND |
0.0.0.0:50064 |
gRPC bind address |
FOLDFORGE_SIDECAR_WORKERS |
4 |
gRPC thread-pool size |
FOLDFORGE_SIDECAR_MOCK |
1 (on) |
mock model (GPU-free); unset for the real CLI |
FOLDFORGE_R2_ENDPOINT |
(empty) | object store — set ⇒ durable S3/R2 MSA cache + artifact upload; empty ⇒ in-memory cache + compute-only |
FOLDFORGE_R2_BUCKET |
foldforge |
artifact + MSA bucket |
FOLDFORGE_GPU_TYPE |
A100-80G |
advertised GPU type |
FOLDFORGE_CANCEL_POLL_INTERVAL_S |
1.0 |
cooperative-cancel poll interval (#M2) |
FOLDFORGE_CANCEL_GRACE_PERIOD_S |
10.0 |
SIGTERM→SIGKILL grace on cancel (#M2) |
src/foldforge_af2/msa_cache.py is fully implemented and exercised in both modes:
QueryMsaCache+ theUSE_CACHE/FORCE_RECOMPUTE/CACHE_ONLYpolicies (a CACHE_ONLY miss fails the step so cold work routes off-GPU).- A pluggable
CacheBackend: in-memory by default,S3Backend(R2 in prod, MinIO for local tests) whenFOLDFORGE_R2_ENDPOINTis set — durable across restarts and shared across replicas. Keys aresha256(sequence). - The cache stores real a3m bytes (not a placeholder) with a real alignment depth, so a real MSA builder's output survives a store → restart → fetch round trip. Verified against live MinIO.
Real-model code is complete; GPU inference is the only gated part.
- Mock mode (
FOLDFORGE_SIDECAR_MOCK=1, default) streams realisticProgressEvents and returns a synthetic content-addressed PDB — the full orchestrator → sidecar → object-store path (and the MSA cache) runs with no GPU. - Real mode (
model.py+colabfold.py) resolves the MSA via the cache, shells out tocolabfold_batchunderfoldforge_subprocess.run_cancellable(process-group kill on cancel, #M2), parses ranked predictions, and uploads. The inference call needs a GPU + LocalColabFold;_require()raises a clear error when the CLI is absent. Seedocs/GPU-DEPLOY.mdfor the GPU runbook.
GPU-free verification (MSA-cache a3m round-trip, ColabFold parser fixtures, cancel/
group-kill, gRPC client-cancel, mock e2e) all pass via pytest.
FoldForge's code here is Apache-2.0. AlphaFold2 itself is separate: the AF2
code is Apache-2.0 but its published parameters are CC BY-NC 4.0 (non-commercial) —
this sidecar does not redistribute them, and commercial use of AF2 weights is not
permitted without a separate arrangement. See the org's THIRD-PARTY-MODELS.md.