Epigenomic Sequence Models: Borzoi and Epiformer
When to Use
- Choosing between sequence-to-function model families for a specific epigenomic assay (RNA-seq coverage, ATAC-seq/DNase accessibility, variant effect prediction).
- A user asks "which model predicts chromatin accessibility from DNA sequence" or "Borzoi vs Enformer vs Epiformer" or "do I need a conservation track for this prediction."
- Debugging poor model performance caused by evaluating on the wrong output modality (e.g., using an expression model to score accessibility).
- Deciding whether a single unified model (AlphaGenome) or task-specific models are the right tradeoff for a variant-effect pipeline.
- Building a toy/benchmark predictor to sanity-check modality-specific correlations before committing to a heavyweight model download.
Version Compatibility
- Borzoi: Calico's
borzoi-pytorch / original Baskerville (TensorFlow) implementations, 2023 release.
- Epiformer: sequence + PhyloP conservation accessibility model, 2024 (Science-linked); requires a precomputed conservation bigWig/track per region.
- AlphaGenome: DeepMind/Google, 2025 unified multi-modal model (expression, splicing, chromatin, 3D contacts).
- Enformer: predecessor to Borzoi, 128 bp bin resolution — kept here only as a contrast point (see
ai-science-enformer-regulatory).
- NumPy ≥1.24, Python ≥3.10 for the toy benchmark code below (no GPU or model weights required).
Prerequisites
pip install numpy for the synthetic benchmark in this skill.
- For the real models:
pip install borzoi-pytorch (or Baskerville/TensorFlow for the original Borzoi), plus PhyloP conservation tracks (e.g., from UCSC/Ensembl) for Epiformer.
- Familiarity with
ai-science-enformer-regulatory (bin-averaged ChIP/CAGE/DNase prediction) helps frame why Borzoi's 32 bp resolution matters.
Key Distinctions
- Borzoi: sequence-only input → RNA-seq coverage at 32 bp resolution. Captures splicing, UTR usage, isoform signals.
- Epiformer: sequence + conservation track input → chromatin accessibility. Requires precomputed PhyloP scores for the region; cannot run sequence-only.
- AlphaGenome (2025): unified model for expression, splicing, chromatin, 3D contacts — avoids model-selection but is heavier compute.
- Enformer (predecessor): 128 bp bin averages of ChIP/CAGE/DNase — coarser resolution than Borzoi, different modality entirely.
| Goal |
Preferred model |
| RNA-seq coverage from sequence |
Borzoi |
| ATAC/chromatin accessibility |
Epiformer |
| Broad multi-modal variant effects |
AlphaGenome |
| Splicing triage |
SpliceAI |
Goal: Decide which model family to trust for a given epigenomic assay, and confirm the decision with a quick modality-specific correlation check rather than assuming a proxy modality works.
Approach: Build toy scoring functions that mimic each model's known input dependencies (Borzoi: promoter/enhancer motifs only; Epiformer: open-chromatin motifs + conservation), generate a synthetic benchmark with noisy "observed" targets, then measure correlation per modality — including a deliberate cross-task mismatch to show why proxying is unsafe.
import numpy as np
np.random.seed(19)
def random_dna(n: int) -> str:
"""Generate a random DNA sequence of length n over {A,C,G,T}."""
return "".join(np.random.choice(list("ACGT"), size=n))
def motif_count(seq: str, motif: str) -> int:
"""Count (overlapping) occurrences of motif in seq."""
return sum(1 for i in range(len(seq) - len(motif) + 1) if seq[i:i + len(motif)] == motif)
def toy_borzoi_expression(seq: str) -> float:
"""Borzoi-like expression score: sequence only, driven by promoter/enhancer motifs."""
score = 0.2 + 0.35 * motif_count(seq, "TATAAA") + 0.08 * motif_count(seq, "GATA")
return float(np.clip(score, 0.0, 3.0))
def toy_epiformer_accessibility(seq: str, conservation: float) -> float:
"""Epiformer-like accessibility score: sequence + conservation track (e.g. PhyloP)."""
score = 0.15 + 0.12 * motif_count(seq, "ATAC") + 0.55 * conservation
return float(np.clip(score, 0.0, 2.5))
def corr(a: np.ndarray, b: np.ndarray) -> float:
"""Pearson correlation between two 1D arrays."""
return float(np.corrcoef(a, b)[0, 1])
def modality_benchmark(n: int = 120):
"""Build a synthetic benchmark and report per-modality correlation, plus the
failure mode of using the wrong modality as a proxy.
"""
seqs = [random_dna(500) for _ in range(n)]
cons = np.random.uniform(0.1, 0.95, size=n)
true_expr = np.array([toy_borzoi_expression(s) for s in seqs]) + np.random.normal(0, 0.08, size=n)
true_acc = np.array(
[toy_epiformer_accessibility(s, c) for s, c in zip(seqs, cons)]
) + np.random.normal(0, 0.06, size=n)
pred_expr = np.array([toy_borzoi_expression(s) for s in seqs])
pred_acc = np.array([toy_epiformer_accessibility(s, c) for s, c in zip(seqs, cons)])
expr_corr = corr(pred_expr, true_expr)
acc_corr = corr(pred_acc, true_acc)
# Cross-task mismatch: using an expression score to predict accessibility.
bad_acc_proxy = (pred_expr - pred_expr.min()) / (pred_expr.max() - pred_expr.min() + 1e-9)
mismatch_corr = corr(bad_acc_proxy, true_acc)
return {"expression_corr": expr_corr, "accessibility_corr": acc_corr, "wrong_modality_corr": mismatch_corr}
if __name__ == "__main__":
results = modality_benchmark()
assert results["expression_corr"] > 0.8, "Borzoi-like model should track its own modality well"
assert results["accessibility_corr"] > 0.8, "Epiformer-like model should track its own modality well"
assert abs(results["wrong_modality_corr"]) < abs(results["expression_corr"]), (
"Cross-modality proxy should correlate much worse than the matched model"
)
print(results)
Pitfalls
- Enformer predicts 128 bp bin averages of ChIP/CAGE/DNase. Borzoi predicts RNA-seq at 32 bp — a different modality and resolution, not interchangeable.
- Epiformer cannot run without a precomputed conservation track (e.g., PhyloP) for the genome region — sequence-only input will fail or silently degrade accuracy.
- Conservation helps accessibility prediction because evolutionarily conserved non-coding regions are enriched for functional regulatory elements — dropping it removes a strong prior, not just an extra feature.
- Always benchmark a model on the output modality you actually need; using an expression-style score as a proxy for accessibility (or vice versa) looks plausible but correlates poorly (see
wrong_modality_corr above).
- AlphaGenome's unified output avoids model-selection but costs more compute — don't reach for it by default when a lighter task-specific model (Borzoi/Epiformer/SpliceAI) already covers the assay.
See Also
ai-science-enformer-regulatory — the 128 bp bin-averaged predecessor to Borzoi.
ai-science-splicing-models — SpliceAI/AlphaGenome for splicing-specific triage.
ai-science-variant-to-structure-models — downstream structural consequences of variants.
bio-atac-seq-atac-peak-calling — calling real ATAC-seq accessibility peaks from data (vs. predicting them).
Sources
1---2name: ai-science-epigenomic-sequence-models3description: Choose Borzoi (RNA-seq coverage, 32bp) vs Epiformer (sequence+PhyloP, chromatin accessibility) vs AlphaGenome for epigenomic prediction. Use when picking a model for RNA-seq, ATAC/DNase, or variant-effect scoring.4---56# Epigenomic Sequence Models: Borzoi and Epiformer78## When to Use910- Choosing between sequence-to-function model families for a specific epigenomic assay (RNA-seq coverage, ATAC-seq/DNase accessibility, variant effect prediction).11- A user asks "which model predicts chromatin accessibility from DNA sequence" or "Borzoi vs Enformer vs Epiformer" or "do I need a conservation track for this prediction."12- Debugging poor model performance caused by evaluating on the wrong output modality (e.g., using an expression model to score accessibility).13- Deciding whether a single unified model (AlphaGenome) or task-specific models are the right tradeoff for a variant-effect pipeline.14- Building a toy/benchmark predictor to sanity-check modality-specific correlations before committing to a heavyweight model download.1516## Version Compatibility1718- Borzoi: Calico's `borzoi-pytorch` / original Baskerville (TensorFlow) implementations, 2023 release.19- Epiformer: sequence + PhyloP conservation accessibility model, 2024 (Science-linked); requires a precomputed conservation bigWig/track per region.20- AlphaGenome: DeepMind/Google, 2025 unified multi-modal model (expression, splicing, chromatin, 3D contacts).21- Enformer: predecessor to Borzoi, 128 bp bin resolution — kept here only as a contrast point (see `ai-science-enformer-regulatory`).22- NumPy ≥1.24, Python ≥3.10 for the toy benchmark code below (no GPU or model weights required).2324## Prerequisites2526- `pip install numpy` for the synthetic benchmark in this skill.27- For the real models: `pip install borzoi-pytorch` (or Baskerville/TensorFlow for the original Borzoi), plus PhyloP conservation tracks (e.g., from UCSC/Ensembl) for Epiformer.28- Familiarity with `ai-science-enformer-regulatory` (bin-averaged ChIP/CAGE/DNase prediction) helps frame why Borzoi's 32 bp resolution matters.2930## Key Distinctions3132- **Borzoi**: sequence-only input → RNA-seq coverage at 32 bp resolution. Captures splicing, UTR usage, isoform signals.33- **Epiformer**: sequence + conservation track input → chromatin accessibility. Requires precomputed PhyloP scores for the region; cannot run sequence-only.34- **AlphaGenome** (2025): unified model for expression, splicing, chromatin, 3D contacts — avoids model-selection but is heavier compute.35- **Enformer** (predecessor): 128 bp bin averages of ChIP/CAGE/DNase — coarser resolution than Borzoi, different modality entirely.3637| Goal | Preferred model |38|---|---|39| RNA-seq coverage from sequence | Borzoi |40| ATAC/chromatin accessibility | Epiformer |41| Broad multi-modal variant effects | AlphaGenome |42| Splicing triage | SpliceAI |4344**Goal:** Decide which model family to trust for a given epigenomic assay, and confirm the decision with a quick modality-specific correlation check rather than assuming a proxy modality works.4546**Approach:** Build toy scoring functions that mimic each model's known input dependencies (Borzoi: promoter/enhancer motifs only; Epiformer: open-chromatin motifs + conservation), generate a synthetic benchmark with noisy "observed" targets, then measure correlation per modality — including a deliberate cross-task mismatch to show why proxying is unsafe.4748```python49import numpy as np5051np.random.seed(19)525354def random_dna(n: int) -> str:55 """Generate a random DNA sequence of length n over {A,C,G,T}."""56 return "".join(np.random.choice(list("ACGT"), size=n))575859def motif_count(seq: str, motif: str) -> int:60 """Count (overlapping) occurrences of motif in seq."""61 return sum(1 for i in range(len(seq) - len(motif) + 1) if seq[i:i + len(motif)] == motif)626364def toy_borzoi_expression(seq: str) -> float:65 """Borzoi-like expression score: sequence only, driven by promoter/enhancer motifs."""66 score = 0.2 + 0.35 * motif_count(seq, "TATAAA") + 0.08 * motif_count(seq, "GATA")67 return float(np.clip(score, 0.0, 3.0))686970def toy_epiformer_accessibility(seq: str, conservation: float) -> float:71 """Epiformer-like accessibility score: sequence + conservation track (e.g. PhyloP)."""72 score = 0.15 + 0.12 * motif_count(seq, "ATAC") + 0.55 * conservation73 return float(np.clip(score, 0.0, 2.5))747576def corr(a: np.ndarray, b: np.ndarray) -> float:77 """Pearson correlation between two 1D arrays."""78 return float(np.corrcoef(a, b)[0, 1])798081def modality_benchmark(n: int = 120):82 """Build a synthetic benchmark and report per-modality correlation, plus the83 failure mode of using the wrong modality as a proxy.84 """85 seqs = [random_dna(500) for _ in range(n)]86 cons = np.random.uniform(0.1, 0.95, size=n)8788 true_expr = np.array([toy_borzoi_expression(s) for s in seqs]) + np.random.normal(0, 0.08, size=n)89 true_acc = np.array(90 [toy_epiformer_accessibility(s, c) for s, c in zip(seqs, cons)]91 ) + np.random.normal(0, 0.06, size=n)9293 pred_expr = np.array([toy_borzoi_expression(s) for s in seqs])94 pred_acc = np.array([toy_epiformer_accessibility(s, c) for s, c in zip(seqs, cons)])9596 expr_corr = corr(pred_expr, true_expr)97 acc_corr = corr(pred_acc, true_acc)9899 # Cross-task mismatch: using an expression score to predict accessibility.100 bad_acc_proxy = (pred_expr - pred_expr.min()) / (pred_expr.max() - pred_expr.min() + 1e-9)101 mismatch_corr = corr(bad_acc_proxy, true_acc)102103 return {"expression_corr": expr_corr, "accessibility_corr": acc_corr, "wrong_modality_corr": mismatch_corr}104105106if __name__ == "__main__":107 results = modality_benchmark()108 assert results["expression_corr"] > 0.8, "Borzoi-like model should track its own modality well"109 assert results["accessibility_corr"] > 0.8, "Epiformer-like model should track its own modality well"110 assert abs(results["wrong_modality_corr"]) < abs(results["expression_corr"]), (111 "Cross-modality proxy should correlate much worse than the matched model"112 )113 print(results)114```115116## Pitfalls117118- Enformer predicts 128 bp bin averages of ChIP/CAGE/DNase. Borzoi predicts RNA-seq at 32 bp — a different modality and resolution, not interchangeable.119- Epiformer cannot run without a precomputed conservation track (e.g., PhyloP) for the genome region — sequence-only input will fail or silently degrade accuracy.120- Conservation helps accessibility prediction because evolutionarily conserved non-coding regions are enriched for functional regulatory elements — dropping it removes a strong prior, not just an extra feature.121- Always benchmark a model on the output modality you actually need; using an expression-style score as a proxy for accessibility (or vice versa) looks plausible but correlates poorly (see `wrong_modality_corr` above).122- AlphaGenome's unified output avoids model-selection but costs more compute — don't reach for it by default when a lighter task-specific model (Borzoi/Epiformer/SpliceAI) already covers the assay.123124## See Also125126- `ai-science-enformer-regulatory` — the 128 bp bin-averaged predecessor to Borzoi.127- `ai-science-splicing-models` — SpliceAI/AlphaGenome for splicing-specific triage.128- `ai-science-variant-to-structure-models` — downstream structural consequences of variants.129- `bio-atac-seq-atac-peak-calling` — calling real ATAC-seq accessibility peaks from data (vs. predicting them).130131## Sources132133- [Borzoi](https://github.com/calico/borzoi)134- [Epiformer](https://github.com/yal054/epiformer)