v9.1.0 — nanopore basecaller: 70% → 74% on real R9.4
A measured accuracy improvement to the Level 7 nanopore basecaller (pure NumPy, no AI),
on real captured R9.4 signal (E. coli, n=36, vs the production Guppy basecall), plus a
robustness bug sweep.
What changed
- Iterative per-read rescaling: a first Viterbi pass tells us which k-mer each
event is; the per-read scale is then refit (robust least squares) to the actual
levels of those k-mers, correcting the read's composition bias. - Tuned transitions (
p_stay0.42 → 0.50): the old value over-penalised the STAY
states that over-segmentation produces. - Measured, not assumed: per-k-mer emission noise, drift correction and EM model
re-estimation were all tried and dropped (they didn't help) — the fixed classical
model is at its ceiling. Clean ablation. - Robustness hardening: bug sweep of the new module — fixed two edge-case bugs
(empty-signal path handling; inf/nan inputs no longer crash the rescaler) and added
adversarial regression tests.
Result
Mean ~74.5%, median ~74%, range 68–82% (was 70.3% in v9.0). Reproduce it:
python tools/bench_basecaller.py. Still the classical R9-era route, still far below
neural Dorado's ~99% — the honest ceiling of a fixed model; R10 remains out of scope.
Tests
525 passing.