Skip to content

Benchmark Helico on real MarinFold contact predictions (exp199 model) #11

Description

@timodonnell

Why

PR #10 established that a
genuinely MSA-free Helico, given contacts at 60% precision / 60% recall,
matches Protenix-with-MSAs on FoldBench (0.824 vs 0.837, Δ = −0.013 ± 0.026,
n.s., n=27 paired protein targets). Degrading a perfect map to 60/60 costs only
0.012 lDDT.

But those false positives are synthetic. They are drawn uniformly from the
eligible region by helico.contacts.sample_conditioning. Real predictor errors
are spatially correlated and cluster near true contacts — geometrically
plausible near-misses that the model cannot reject as inconsistent with the rest
of the map. Uniform-random false contacts are the easy case.

So the current result shows that a predictor at 60/60 suffices. This issue
tests whether MarinFold at its actual operating point suffices, which is the
question that decides the project.

Inputs

Modes to evaluate

1. Top-n contacts, pairwise vs rollout

MarinFold has two established inference recipes, and they are not
interchangeable — from exp180/build_dataset.py, the same checkpoint scores
~0.086 higher under rollout than under pairwise:

  • pairwise (exp89): autoregressive P(contact), symmetrised.
  • rollout (exp82, settled): n=100 rollouts + document resampling +
    pairwise tie-break, top-k off (#142).

Take the top-n ranked contacts from each, for n ∈ {L/5, L/2, L} where L is
the number of protein residues. That is 2 recipes × 3 values of n = 6 arms.

Feed them as a truncated top-k list: listed pairs → CONTACT_PRESENT, everything
else → CONTACT_UNKNOWN. Do not mark unlisted pairs CONTACT_ABSENT — the
model was trained on truncated lists precisely because an unlisted pair means
"did not make the cut", not "not a contact".

2. Actual rollouts, distribution of accuracies

Rather than aggregating the 100 rollouts into one ranking, feed individual
rollouts
through Helico and report the distribution of resulting lDDT — not
just the mean. Worth extracting:

  • spread across rollouts for a fixed target (how much does contact sampling
    matter to the final structure?)
  • whether Helico's own confidence (ranking_score / pLDDT) correlates with
    structural accuracy across rollouts. If it does, rollout selection without
    ground truth becomes possible
    , which is a materially different capability
    from anything measured so far.
  • best-of-N vs mean-of-N, as a headroom diagnostic. Note MarinFold already
    tracks oracle_best_of_100 as an explicitly non-deployable upper bound;
    Helico-side selection would be deployable if the correlation holds.

Suggest ~20 rollouts × ~27 targets to start, and scale if the spread is
interesting.

The comparison that actually answers the question

For every real-contact arm, measure MarinFold's realised precision and recall
against the pyconfind ground-truth map
, then run a matched synthetic arm at
that same (p, r) via HELICO_BENCH_CONTACT_PRECISION/RECALL.

real MarinFold contacts synthetic at matched (p, r)
lDDT ? ?

This is the centrepiece. Without the matched-synthetic control, a low real-contact
score is uninterpretable — it could be error rate or error structure, and those
have completely different remedies.

Implementation sketch

  1. Contact export from MarinFold. Ranked contact list per FoldBench target,
    for both recipes, plus the raw rollouts. exp20 and exp180 already score
    MarinFold on FoldBench, so target handling should mostly exist.
  2. Index alignment. MarinFold emits sequence-position pairs; Helico needs a
    token-indexed (N_tok, N_tok) matrix. Both use pyconfind contacts-v1 so the
    contact definition matches, but the mapping still has to be verified —
    helico.bench.oracle_contact_state does the analogous re-indexing from a
    ground-truth structure and is the model to follow. Add a test asserting a
    round-trip of the ground-truth map through the MarinFold export format
    reproduces oracle_contact_state exactly
    , otherwise an indexing bug will
    present as "real contacts don't work".
  3. Bench loader. A --contacts-from <file> path in modal/bench.py that
    reads an external contact list instead of deriving one. Mostly parallel to
    the existing HELICO_BENCH_ORACLE_CONTACTS plumbing.
  4. Scoring. Reuse the existing paired analysis; all arms share targets with
    the PR Contact-conditioned folding: fold from pyconfind contacts instead of MSAs #10 runs.

Watch out for

  • MarinFold training contamination. FoldBench targets were checked against
    Helico's training set (0 overlap). MarinFold's training set is different and
    must be checked separately — otherwise its contacts on these targets are
    optimistic. Note also that Helico's own validation set turned out 38%
    verbatim-contaminated, so this failure mode is live in this codebase.
  • Recipe labelling. Never mix pairwise and rollout numbers in one series;
    the ~0.086 offset would masquerade as a real effect.
  • n=27 targets. Small. Report paired differences with standard errors, not
    bare means, and don't read single-target results.
  • L definition. Fix whether L counts protein residues only, and whether
    interface contacts across chains count toward n, before generating anything.

Done when

  • Real-contact lDDT for all 6 top-n arms, each with a matched-synthetic control.
  • The rollout accuracy distribution, with the confidence-correlation check.
  • A statement of whether error structure matters, and if so, by how much.
  • Writeup appended to RESULTS_contact_conditioning.md and the design doc.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions