{
  "@context": "https://schema.org",
  "@id": "https://aggr.aymericbeaumet.com/items/huggingface-co/2026-03-31-training-mrna-language-models-across-25-species-for-165/#webpage",
  "@type": [
    "WebPage",
    "ArchiveComponent"
  ],
  "articleBody": "## Part II: Building the Pipeline, From Structure Prediction to Codon Optimization\n\n*By OpenMed, Open-Source Agentic AI for Healthcare & Life Sciences*\n\n* * *\n\n> **TL;DR**: We built an end-to-end protein AI pipeline covering structure prediction, sequence design, and codon optimization. After comparing multiple transformer architectures for codon-level language modeling, **CodonRoBERTa-large-v2** emerged as the clear winner with a perplexity of 4.10 and a Spearman CAI correlation of 0.40, significantly outperforming ModernBERT. We then scaled to 25 species, trained 4 production models in 55 GPU-hours, and built a species-conditioned system that no other open-source project offers. Complete results, architectural decisions, and runnable code below.\n\n**Contents**\n\n1. [What We Built](https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#1-what-we-built)\n2. [The Architecture Exploration](https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#2-the-architecture-exploration)\n3. [The Pipeline](https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#3-the-pipeline)\n   - [3.1 Protein Folding](https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#31-protein-folding-with-esmfold)\n   - [3.2 Sequence Design](https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#32-sequence-design-with-proteinmpnn)\n   - [3.3 mRNA Optimization](https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#33-mrna-optimization)\n4. [Scaling to Multi-Species](https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#4-scaling-to-multi-species)\n5. [The End-to-End Workflow](https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#5-the-end-to-end-workflow)\n6. [Where This Stands and What's Next](https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#6-where-this-stands-and-whats-next)\n7. [References](https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#7-references)\n\n* * *\n\nImagine going from a therapeutic protein concept to a synthesis-ready, codon-optimized DNA sequence in an afternoon. That is the pipeline **OpenMed** set out to build, and this post documents the process from start to finish.\n\nIn Part I, we mapped the landscape of protein AI: the architectures powering structure prediction, the open-source tools available for protein design, and the ecosystem of models from AlphaFold to ESMFold. That was a survey. This is the build.\n\nAt **OpenMed**, we set out to build a complete pipeline that takes a protein idea from concept to expression-ready DNA. That means three stages: predict the 3D structure of a protein, design amino acid sequences that fold into that structure, and optimize the underlying DNA codons so the protein actually expresses in the target organism. Along the way, we ran extensive experiments comparing transformer architectures for codon optimization, scaled our best model to 25 species, and built tooling that ties it all together.\n\nThis is not a polished success story. It is a transparent account of what worked, what surprised us, and what we would do differently, with runnable code and full results at every step.\n\n* * *\n\n## 1. What We Built\n\nThe pipeline has three components, each addressing a different stage of the protein engineering workflow described in Part I. Structure prediction determines *what shape* a protein takes. Sequence design determines *which amino acids* will produce that shape. Codon optimization determines *which DNA* will produce those amino acids efficiently in a living cell.\n\n| Component             | What We Did                                                                                        | Key Result                                                                                                                   |\n| --------------------- | -------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |\n| **Protein Folding**   | ESMFold v1 predictions on 30 protein chains                                                        | Avg PTM: 0.79, working batch pipeline                                                                                        |\n| **Sequence Design**   | ProteinMPNN on scaffold 7K00                                                                       | 42% sequence recovery                                                                                                        |\n| **mRNA Optimization** | Trained multiple transformer variants on 250k CDS, then scaled to 381k sequences across 25 species | **CodonRoBERTa-large-v2**: perplexity 4.10, CAI 0.40; **Multi-species suite**: 4 models spanning 25 organisms (55 GPU-hours) |\n\nThe mRNA optimization work is where we invested the most effort, and where we have the most to share. The folding and design components use established tools (ESMFold from Meta, ProteinMPNN from the Baker Lab, both covered in depth in Part I). The codon optimization component is entirely ours: new models, new training infrastructure, new evaluation metrics.\n\n## 2. The Architecture Exploration\n\nIn Part I, we surveyed the protein AI landscape and noted that most biological language models are adaptations of NLP architectures. The open question was *which* architecture. BERT variants dominate protein modeling (ESM-2, ProtTrans), but codon sequences have different statistical properties than both natural language and amino acid sequences. Codons are triplets drawn from a small 64-token alphabet, with strong positional dependencies and species-specific usage biases. We needed to find out what works from first principles.\n\nThe core question: which transformer architecture works best for codon-level language modeling?\n\nThis matters because codon optimization is crucial for therapeutic mRNA, vaccines, and recombinant protein production. The genetic code is degenerate: the same protein can be encoded by astronomically many different DNA sequences, but some codon arrangements express 100x better than others. The Pfizer-BioNTech COVID vaccine, for example, was codon-optimized for human expression. We wanted to build a model that could learn these preferences directly from natural coding sequences, rather than relying on hand-crafted frequency tables.\n\n### The Contenders\n\nWe started with a small CodonBERT baseline (6M params, following Sanofi's published architecture) and scaled up through two families: ModernBERT, which represented the latest efficiency innovations from the NLP community, and RoBERTa, the proven workhorse behind Meta's ESM protein language models.\n\n| Model                     | Parameters | Architecture                 | Hypothesis                                            |\n| ------------------------- | ---------- | ---------------------------- | ----------------------------------------------------- |\n| **CodonBERT (baseline)**  | 6M         | BERT-tiny (6 layers)         | Minimal baseline to establish floor performance       |\n| **ModernBERT-base**       | 90M        | ModernBERT (22 layers, RoPE) | Modern innovations: long context, efficient attention |\n| **CodonRoBERTa-base**     | 92M        | RoBERTa (12 layers)          | Proven MLM architecture, same family as ESM-2         |\n| **CodonRoBERTa-large**    | 312M       | RoBERTa (24 layers)          | Test whether more parameters improve codon modeling   |\n| **CodonRoBERTa-large-v2** | 312M       | RoBERTa (24 layers, refined) | Same architecture, better hyperparameters             |\n\nThe choice of RoBERTa was deliberate. As we discussed in Part I, Meta's ESM-2 (which powers ESMFold) is itself a RoBERTa variant trained on protein sequences. We hypothesized that the same architecture family that learned amino acid patterns might also learn codon patterns. ModernBERT was the counterpoint: a 2024 architecture with RoPE embeddings, Flash Attention, and alternating local/global attention layers, representing everything the NLP community had learned since RoBERTa's 2019 release.\n\n### The Training Setup\n\nTo ensure a fair comparison, every model was trained on identical data with the same evaluation protocol. We used 250,000 coding sequences (CDS) from *E. coli* RefSeq, covering chromosome and complete assembly accessions. This is a clean, well-annotated dataset where codon usage patterns are well-characterized in the literature, giving us ground truth to validate against.\n\nOur tokenizer maps each codon to a single token: 64 codons plus 5 special tokens (PAD, UNK, CLS, SEP, MASK) for a 69-token vocabulary. This is intentionally minimal. Unlike BPE tokenizers used in NLP, where subword boundaries are statistically learned, codon boundaries are biologically defined. Every three nucleotides encode one amino acid. Our tokenizer respects this.\n\nTraining ran on 4 A100 GPUs (80GB) with FSDP sharding, using 15,000 to 25,000 steps depending on model size. All models used masked language modeling (MLM) with 15% masking rate, the same objective used by ESM-2 for protein sequences.\n\n### The Results\n\n| Model                     | Perplexity | CAI Spearman | Synonymous Recovery | Status              |\n| ------------------------- | ---------- | ------------ | ------------------- | ------------------- |\n| **CodonRoBERTa-large-v2** | 4.10       | **0.404**    | 7.7%                | **Best Overall**    |\n| **CodonRoBERTa-base**     | **4.01**   | 0.219        | **8.5%**            | **Best Efficiency** |\n| CodonRoBERTa-large        | 4.01       | 0.025        | 7.6%                | Good MLM, weak bio  |\n| ModernBERT-base           | 26.24      | 0.070        | 8.5%                | Underperformed      |\n| CodonBERT (baseline)      | 17.18      | -0.629       | 0.0%                | Baseline            |\n\nThe result was unambiguous: RoBERTa outperformed ModernBERT by 6x on perplexity (4.01 vs 26.24). This was not a marginal difference. ModernBERT, despite its modern attention patterns and efficient architecture, fundamentally underperformed the classic RoBERTa design on codon sequences.\n\n### What We Learned\n\n**1\\. Pre-trained NLP weights do not transfer to biology**\n\nWe initialized ModernBERT from its published English-language checkpoint, expecting the learned attention patterns to provide a useful starting point. They did not. Our best explanation: ModernBERT's pre-training on English text instilled inductive biases (subword frequency distributions, positional attention patterns) that actively interfere with learning codon statistics. RoBERTa, initialized randomly and trained purely on biological data, had no such baggage. This aligns with what the field has seen more broadly: ESM-2 and ProtTrans both train from scratch on biological data rather than fine-tuning from NLP checkpoints.\n\n**2\\. Hyperparameter tuning unlocked biological alignment**\n\nThis was the most surprising and practically important finding of the exploration. Compare CodonRoBERTa-large v1 and v2:\n\n| Version                     | Perplexity | CAI Spearman |\n| --------------------------- | ---------- | ------------ |\n| v1 (lr=1e-4)                | 4.01       | 0.025        |\n| v2 (lr=5e-5, longer warmup) | 4.10       | **0.404**    |\n\nSame architecture. Same data. Same number of parameters. The only differences: half the learning rate and a longer warmup (2,000 steps vs 1,000). Yet v2's predicted codon likelihoods are **16x better correlated with real biological codon preferences**, as measured by Codon Adaptation Index.\n\nThe perplexity actually got slightly *worse* (4.10 vs 4.01), which means v2 is marginally less accurate at predicting the exact masked codon. But it is dramatically better at predicting codons that biology actually uses. The slower training schedule let the model settle into representations that capture genuine biological signal rather than overfitting to surface statistics.\n\nThis is a crucial insight for anyone training biological language models: **MLM loss alone does not measure biological relevance.** Domain-specific metrics are essential. In our case, CAI correlation turned out to be the metric that separates a useful model from a technically impressive but biologically meaningless one.\n\n**3\\. The base model is remarkably efficient**\n\nCodonRoBERTa-base (92M params) achieved nearly identical perplexity to the large model (4.01 vs 4.10) with 3.4x fewer parameters and proportionally less training time. Its CAI correlation (0.219) is lower than v2's (0.404), but still well above the baseline and ModernBERT. For teams without access to multi-GPU clusters, the base model is a practical choice that captures most of the codon modeling performance at a fraction of the cost.\n\n## 3. The Pipeline\n\nIn Part I, we described the three-stage workflow that most computational protein engineering projects follow: predict structure, design sequences, optimize codons. Here we run each stage with real data and report what we actually got.\n\n1. **Fold**: Predict the 3D structure (ESMFold)\n2. **Design**: Generate sequences that fold into that structure (ProteinMPNN)\n3. **Optimize**: Choose the best codons for expression (CodonRoBERTa)\n\n* * *\n\n### 3.1 Protein Folding with ESMFold\n\n[![ESMFold Architecture: single-sequence structure prediction using the ESM-2 protein language model](https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/ty2O24OhgfrFHJJUTl7dG.jpeg)](https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/ty2O24OhgfrFHJJUTl7dG.jpeg)\n\n*ESMFold architecture. The model parses a single amino acid sequence through the ESM-2 encoder, then predicts 3D coordinates via a folding trunk and structure module. Figure from Bertoline et al., Biomolecules 2024, CC-BY 4.0.*\n\nAs covered in Part I, ESMFold is Meta's single-sequence structure predictor. It uses ESM-2, a 15-billion-parameter protein language model trained on 65 million UniRef sequences, as its backbone. The key advantage over AlphaFold 2 is speed: ESMFold skips the computationally expensive multiple sequence alignment (MSA) step and predicts structures directly from a single amino acid sequence. That makes it seconds per protein instead of hours.\n\nThe tradeoff is accuracy. ESMFold achieves ~0.87 TM-score on CASP14 targets vs. AlphaFold's ~0.92. For rapid prototyping and candidate screening, that gap is acceptable. When a pipeline generates 100 designed sequences and needs to refold all of them to check viability, speed matters more than the last few percentage points of accuracy.\n\n### Our Results: 30 Protein Chains\n\nWe ran ESMFold on 30 protein chains sourced from the Protein Data Bank. These are real experimental structures with known ground truth, spanning sequence lengths from 211 to 519 residues. The set deliberately includes both easy targets (single-domain proteins) and challenging ones (chains from a multi-chain ribosomal complex, PDB 7K00) to stress-test the model.\n\n```python\nimport json\n\n# Load our actual results\nmetrics = json.load(open('outputs/esmfold_metrics.json'))\n\n# Summary statistics\nn_chains = len(metrics)  # 30\navg_plddt = sum(m['mean_plddt'] for m in metrics) / n_chains  # 33.8\navg_ptm = sum(m['ptm'] for m in metrics) / n_chains  # 0.79\n\nprint(f\"Chains: {n_chains}\")\nprint(f\"Average pLDDT: {avg_plddt:.1f}\")\nprint(f\"Average PTM: {avg_ptm:.2f}\")\n```\n\n**Results breakdown:**\n\n| Metric           | Value   | Interpretation                               |\n| ---------------- | ------- | -------------------------------------------- |\n| Chains predicted | 30      | -                                            |\n| Average pLDDT    | 33.8    | Per-residue confidence (lower than expected) |\n| Average PTM      | 0.79    | Topology confidence (good)                   |\n| Sequence lengths | 211-519 | Typical protein sizes                        |\n\nThe PTM scores are solid: anything above 0.5 suggests the model has the overall topology correct, and our average of 0.79 indicates high confidence in the predicted folds. The pLDDT scores are lower than published ESMFold benchmarks, which initially concerned us. The explanation turned out to be our test set composition: the ribosomal chains from 7K00 are part of a large multi-chain complex, and ESMFold (which predicts single chains in isolation) cannot model the inter-chain contacts that stabilize these structures. For single-domain proteins in our set, pLDDT scores were consistently above 70.\n\n### Running ESMFold\n\n```bash\n# Activate environment\nsource .env_esmfold/bin/activate\n\n# Batch prediction\npython scripts/esmfold_batch.py \\\n    --seq_dir data/pdb/sequences \\\n    --out_dir data/esmfold/out \\\n    --metrics outputs/esmfold_metrics.json \\\n    --device cuda:0\n```\n\nEach prediction takes ~10-30 seconds on an A100. The output includes:\n\n- PDB structure files\n- pLDDT scores (per-residue confidence, 0-100)\n- PTM scores (topology confidence, 0-1)\n- Predicted Aligned Error (PAE) matrices\n\n* * *\n\n### 3.2 Sequence Design with ProteinMPNN\n\n[![ProteinMPNN Architecture: message-passing neural network for inverse protein design](https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/HnDJvDzsbQsbJn4IyJyCU.jpeg)](https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/HnDJvDzsbQsbJn4IyJyCU.jpeg) *ProteinMPNN architecture. (A) The encoder processes backbone atom distances; the decoder autoregressively generates amino acid sequences. (B) Random decoding order improves diversity. (C) Tied positions enable symmetric and multi-state design. Figure from Dauparas et al., Science 2022, CC-BY 4.0.*\n\nAs we described in Part I, protein design is the inverse of protein folding. Folding goes sequence to structure: given amino acids, predict the 3D shape. **Inverse folding** goes the other way: given a target 3D shape, find amino acid sequences that will fold into it.\n\nProteinMPNN, from David Baker's lab at the University of Washington, is the current gold standard for this task. It was published in *Science* in 2022 and has since been validated experimentally: designed sequences fold into their target structures at rates far exceeding random or earlier computational methods. The architecture treats the protein backbone as a graph, where nodes are amino acid positions and edges connect spatially proximate residues (K-nearest neighbors in 3D). A message-passing neural network propagates information through this graph, then autoregressively generates a sequence one residue at a time.\n\n### Our Results: Scaffold 7K00\n\nWe ran ProteinMPNN on PDB structure 7K00 (a large multi-chain ribosomal complex):\n\n```bash\npython proteinmpnn/protein_mpnn_run.py \\\n    --pdb_path data/pdb/raw/7K00.cif \\\n    --out_folder outputs/proteinmpnn_smoke \\\n    --num_seq_per_target 3 \\\n    --sampling_temp 0.1\n```\n\n**Results:**\n\n| Metric              | Value |\n| ------------------- | ----- |\n| Sequences generated | 3     |\n| Best score          | 0.89  |\n| Sequence recovery   | \\~42% |\n\nHere's what the output looks like:\n\n```text\n>7K00, score=1.7100, global_score=1.7100\nGIREKIKLVSSAGTGHFYTTTKNKRTKPEKLELKKFDPVVRQHVIYKEAKI/MKRTFQPSVLK...\n\n>T=0.1, sample=1, score=0.8857, seq_recovery=0.4203\nSKKVVIKLVCSCGCGFEYCDFRDIEKNPEKIERVLYCPICQKYVLFTEAPL/PPGPFRPDREV...\n```\n\nThe first line is the native (natural) sequence extracted from the crystal structure. Subsequent lines are ProteinMPNN's designed variants. At temperature 0.1 (low randomness), the model recovers ~42% of the original amino acids, purely from 3D geometry. This is a strong result: it means the model independently rediscovered nearly half the residues that evolution selected, using only the backbone coordinates as input.\n\nSeveral practical notes from running ProteinMPNN. Scores are negative log-likelihoods, so lower is better. The 42% recovery rate is typical for well-resolved structures and consistent with the original paper's benchmarks. Higher sampling temperatures produce more diverse but riskier sequences. For real design work, the most powerful feature is **partial design**: catalytic residues, binding site amino acids, or any positions with known functional importance can be fixed in place, while ProteinMPNN redesigns only the scaffold around them. This is the standard approach for engineering a more stable version of an enzyme without disrupting its active site.\n\n* * *\n\n### 3.3 mRNA Optimization\n\nThis is where the pipeline transitions from existing tools to our own models. ESMFold and ProteinMPNN are established, well-validated software that we integrated. Codon optimization is where we built something new.\n\n#### Why Codon Choice Matters\n\n[![Codon usage frequency heatmaps across optimization tools for E. coli, S. cerevisiae, and CHO cells](https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/pJIUjRAYERh0YBo6wlxMV.png)](https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/pJIUjRAYERh0YBo6wlxMV.png) *Codon usage frequencies vary dramatically between organisms. These heatmaps compare codon preferences across E. coli, yeast, and CHO cells, the three expression hosts covered by our multi-species models. Figure from Kim et al., J. Microbiol. Biotechnol. 2025, CC-BY 4.0.*\n\nThe genetic code is **degenerate**: most amino acids are encoded by multiple codons. Leucine, for example, has six: TTA, TTG, CTT, CTC, CTA, and CTG. All six produce the same amino acid in the final protein. Methionine and tryptophan are the exceptions, with only one codon each.\n\nThis redundancy means that for any given protein, there are astronomically many DNA sequences that encode it. A typical 300-amino-acid protein has roughly 10^150 possible codon combinations. They all produce the same amino acid chain, but they do *not* all produce the same amount of protein. Codon choice affects translation speed (because tRNA molecules are not equally abundant for all codons), mRNA stability (because the nucleotide sequence affects how quickly the transcript degrades), co-translational folding (because translation pauses at rare codons give the protein time to fold), and immune recognition (because the innate immune system in mammalian cells can distinguish native from foreign mRNA patterns). In practice, bad codon choices can reduce protein expression by 100x. This is why every mRNA vaccine, every recombinant protein therapeutic, and every gene therapy vector goes through codon optimization.\n\n#### The Traditional Approach and Why It Is Limited\n\n[![The mRNA codon optimization design space: billions of possible sequences encoding the same protein](https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/c5O20MNTQJluPtrzScAlO.png)](https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/c5O20MNTQJluPtrzScAlO.png)\n\n*The scale of the codon optimization problem. For a typical mRNA, there are over 10^600 possible codon sequences encoding the same protein. The challenge is finding the arrangement that maximizes expression. Figure from Zhang et al. (LinearDesign), Nature 2023, CC-BY 4.0.*\n\nThe classical method is simple: measure which codons appear most frequently in highly-expressed genes of the target organism, then replace every codon with the most frequent synonym. This is codified as the **Codon Adaptation Index (CAI)**, a per-sequence score that measures how closely the codon usage matches the organism's preferred distribution.\n\nCAI-based optimization works, but it is crude. It treats each codon position independently, ignoring the sequence context. It produces repetitive sequences (the same \"optimal\" codon used everywhere for a given amino acid), which can cause ribosome stalling and mRNA secondary structure problems. And it misses complex dependencies: the optimal codon at position 50 might depend on what codons are at positions 48 and 52, which a frequency table cannot capture.\n\n#### Our Approach: Masked Language Modeling\n\nWe reframe codon optimization as a language modeling problem. Instead of looking up frequencies in a table, we train a transformer on hundreds of thousands of natural coding sequences using masked language modeling (MLM), the same pre-training objective used by BERT, RoBERTa, and Meta's ESM protein models. The model sees a codon sequence with 15% of positions masked and learns to predict the missing codons from context.\n\nWhat the model learns, implicitly, is the *grammar* of codon usage: which codon patterns appear in nature, which codons tend to co-occur, and how preferences shift depending on the surrounding sequence context. This is fundamentally richer than a frequency table because the model captures long-range dependencies across the entire coding sequence.\n\n### CodonRoBERTa: Our Best Model\n\nAfter our architecture exploration (see above), **CodonRoBERTa-large-v2** emerged as the winner:\n\n```yaml\n# configs/mrna/production/roberta_large_v2.yaml\nmodel_type: roberta\nhidden_size: 1024\nnum_hidden_layers: 24\nnum_attention_heads: 16\nintermediate_size: 4096\nvocab_size: 69\nmax_position_embeddings: 8192\nlearning_rate: 5e-5  # Critical: lower than v1\nwarmup_steps: 2000   # Critical: longer warmup\nmax_steps: 25000\n```\n\n**Training:**\n\n```bash\npython scripts/training/run_mlm_train.py \\\n    --config configs/mrna/roberta_large_v2.yaml \\\n    --train_file data/mrna/processed/train_250k.fasta \\\n    --output_dir outputs/models/CodonRoBERTa-large-v2\n```\n\n### Evaluation: Three Metrics That Matter\n\nEvaluating a codon language model is not straightforward. As we learned from the v1/v2 comparison above, a model can have excellent perplexity (accurately predicting masked codons) while having poor biological alignment (predicting codons that nature does not actually prefer). We evaluate on three complementary axes:\n\n**1\\. Perplexity** measures how well the model predicts masked codons, computed as the exponentiated cross-entropy loss. A perplexity of 4.10 means the model is, on average, choosing between ~4 equally likely codons at each masked position. Given that most amino acids have 2-6 synonymous codons, this indicates the model has learned meaningful preferences rather than guessing uniformly. Lower is better. CodonRoBERTa-large-v2: **4.10**.\n\n**2\\. CAI Correlation** (Spearman) measures whether a model's predicted codon likelihoods align with known biological codon usage preferences. We compute the Codon Adaptation Index for each test sequence, then correlate it with the model's pseudo-log-likelihood score. A positive correlation means the model assigns higher probability to sequences that biology actually uses. This is the metric that matters most for practical codon optimization, because it directly measures whether the model has learned biologically relevant patterns vs. just statistical ones. CodonRoBERTa-large-v2: **0.404** (p < 10^-20).\n\n**3\\. Synonymous Recovery** asks: when the model predicts a codon for a masked position, does it at least get the amino acid right? Even if it picks the wrong synonym (e.g., CTT instead of CTC for leucine), predicting the correct amino acid shows the model understands the protein-level constraint. CodonRoBERTa-large-v2: **12.1% top-1 synonymous**.\n\n### Running the Evaluations\n\n```bash\n# Perplexity\npython scripts/evals/advanced/eval_perplexity.py \\\n    --model outputs/models/CodonRoBERTa-large-v2/final \\\n    --test_file data/mrna/processed/test_6k.fasta \\\n    --output outputs/eval_results/CodonRoBERTa-large-v2/perplexity.json\n\n# CAI Correlation\npython scripts/evals/advanced/eval_cai_correlation.py \\\n    --model outputs/models/CodonRoBERTa-large-v2/final \\\n    --test_file data/mrna/processed/test_6k.fasta \\\n    --output outputs/eval_results/CodonRoBERTa-large-v2/cai_correlation.json\n\n# Synonymous Recovery\npython scripts/evals/advanced/eval_synonymous_recovery.py \\\n    --model outputs/models/CodonRoBERTa-large-v2/final \\\n    --test_file data/mrna/processed/test_6k.fasta \\\n    --output outputs/eval_results/CodonRoBERTa-large-v2/synonymous_recovery.json\n```\n\n### The Final Leaderboard\n\nPutting it all together across our model variants:\n\n| Model                     | Params | Perplexity | CAI Spearman | Best For        |\n| ------------------------- | ------ | ---------- | ------------ | --------------- |\n| **CodonRoBERTa-large-v2** | 312M   | 4.10       | **0.404**    | Production use  |\n| **CodonRoBERTa-base**     | 92M    | **4.01**   | 0.219        | Limited compute |\n| CodonRoBERTa-large        | 312M   | 4.01       | 0.025        | -               |\n| ModernBERT-base           | 90M    | 26.24      | 0.070        | -               |\n| CodonBERT (baseline)      | 6M     | 17.18      | -0.629       | Baseline only   |\n\nThe RoBERTa family dominates across the board. For production use, CodonRoBERTa-large-v2 is the clear choice: it has the strongest biological alignment (CAI 0.404) while maintaining competitive perplexity. For teams with limited compute, CodonRoBERTa-base delivers nearly the same perplexity at 3.4x fewer parameters. ModernBERT underperformed substantially, which we attribute to its NLP-pretrained weights interfering with codon pattern learning.\n\n### Using the Model\n\n```python\nfrom transformers import RobertaForMaskedLM\nimport torch\n\n# Load model (available soon on Hugging Face)\nmodel = RobertaForMaskedLM.from_pretrained(\"OpenMed/CodonRoBERTa-large-v2\")\ntokenizer = CodonTokenizer()  # Our custom 69-token vocabulary\n\n# Score a sequence\nsequence = \"ATG GCT AAA GGT...\"  # Space-separated codons\ninputs = tokenizer(sequence, return_tensors='pt')\n\nwith torch.no_grad():\n    outputs = model(**inputs)\n    # Pseudo-log-likelihood gives a \"naturalness\" score\n\n# Predict alternatives for a masked position\nmasked_seq = \"ATG [MASK] AAA GGT...\"\ninputs = tokenizer(masked_seq, return_tensors='pt')\npredictions = model(**inputs).logits\ntop_codons = predictions[0, mask_pos].topk(5)\n```\n\n* * *\n\n## 4. Scaling to Multi-Species\n\nSingle-species codon optimization is useful, but limited. Every organism has its own codon usage biases shaped by millions of years of evolution. *E. coli* favors different codons than human cells, which favor different codons than yeast. A model trained only on *E. coli* data will not produce optimal codons for human expression.\n\nThe industry standard is to use separate CAI tables for each organism. We wanted something better: a single model that understands codon usage across organisms, can be conditioned on a target species, and can transfer knowledge from data-rich organisms (human, with 145k annotated coding sequences) to data-poor ones (*E. coli*, with 9k). After establishing CodonRoBERTa-large-v2 as our best architecture on single-species data, we built this system.\n\n### The Data Engineering Challenge\n\nAssembling a multi-species codon dataset is not as simple as downloading a few genomes. Each organism lives in a different NCBI RefSeq assembly, with different annotation quality, different CDS boundaries, and different sequence conventions. We wrote an automated pipeline that downloads CDS sequences from 25 organisms, validates them (checking for proper start/stop codons, length divisible by 3, no internal stops), labels each sequence with a species token, and splits into train/test sets with stratification by species.\n\n```python\n# scripts/training/download_multispecies_cds.py\n# Automated download from NCBI RefSeq for 25 organisms\n\nSPECIES = {\n    # Bacteria (19 species)\n    'bacteria': [\n        ('GCF_000005845.2', 'Escherichia coli K-12', 'ECOLI'),\n        ('GCF_000009045.1', 'Bacillus subtilis 168', 'BSUBT'),\n        ('GCF_000006945.2', 'Salmonella enterica', 'SENTE'),\n        ('GCF_000195955.2', 'Mycobacterium tuberculosis', 'MTUBE'),\n        # ... 15 more bacteria\n    ],\n    # Yeast (3 species)\n    'yeast': [\n        ('GCF_000146045.2', 'Saccharomyces cerevisiae S288C', 'YEAST'),\n        ('GCF_000002515.2', 'Schizosaccharomyces pombe', 'SPOMBE'),\n        ('GCF_000027005.1', 'Pichia pastoris', 'PICHIA'),\n    ],\n    # Mammals (3 species)\n    'mammals': [\n        ('GCF_000001405.40', 'Homo sapiens GRCh38', 'HUMAN'),\n        ('GCF_000001635.27', 'Mus musculus GRCm39', 'MOUSE'),\n        ('GCF_003668045.3', 'Cricetulus griseus CHO-K1', 'CHO'),\n    ]\n}\n```\n\nThe final dataset spans three domains of biotechnology relevance:\n\n| Category     | Species | Sequences   | Size       | Key Organisms                                        |\n| ------------ | ------- | ----------- | ---------- | ---------------------------------------------------- |\n| **Mammals**  | 3       | 290,091     | 580 MB     | Human (145k), Mouse (97k), CHO (47k)                 |\n| **Bacteria** | 19      | 74,972      | 150 MB     | E. coli (9k), B. subtilis (4k), P. aeruginosa (5.3k) |\n| **Yeast**    | 3       | 16,220      | 32 MB      | S. cerevisiae (5.7k), P. pastoris (4.8k)             |\n| **Total**    | **25**  | **381,283** | **\\~3 GB** | 362k train / 19k test                                |\n\nThe coverage is deliberate: bacteria are the workhorse of recombinant protein production, yeast dominates industrial biomanufacturing, and mammalian cells (especially CHO and human) are required for therapeutic proteins and mRNA vaccines. These 25 organisms collectively cover the vast majority of real-world codon optimization use cases.\n\n### The Tokenization Innovation\n\nA model that sees sequences from 25 different organisms needs to know *which* organism it is looking at. We solved this by extending our 69-token codon vocabulary with 25 species tokens, creating a 94-token system. Each sequence is prepended with its species token (e.g., `[HUMAN]`, `[ECOLI]`, `[YEAST]`), so the model learns species-specific codon preferences within a single shared architecture.\n\n```python\n# scripts/training/codon_tokenizer.py\nclass MultiSpeciesCodonTokenizer(CodonTokenizer):\n    \"\"\"Extended tokenizer with species-awareness\"\"\"\n\n    def __init__(self):\n        super().__init__()\n        # 0-4: [PAD], [UNK], [CLS], [SEP], [MASK]\n        # 5-68: 64 codons (AAA, AAC, ..., TTT)\n        # 69-93: 25 species tokens\n\n        self.species_tokens = [\n            '[ABAUM]', '[BSUBT]', '[CHO]', '[ECOLI]',\n            '[HUMAN]', '[MOUSE]', '[YEAST]', # ... +18 more\n        ]\n\n    def encode(self, dna_seq: str, species: str = None):\n        \"\"\"Encode with species token prepended\"\"\"\n        ids = super().encode(dna_seq)\n        if species and species in self.species_to_id:\n            ids = [self.species_to_id[species]] + ids\n        return ids\n```\n\nThis design has three advantages. First, it enables species-conditioned generation: the same model produces human-optimal or *E. coli*-optimal codons depending on which species token is prepended. Second, it enables cross-species transfer learning: universal codon patterns (like avoiding certain dinucleotides, or preferring GC-rich codons in GC-rich genomes) are shared across all species, while species-specific preferences are captured by conditioning on the species token. Third, the 94-token vocabulary is backward-compatible with our 69-token single-species models, since the first 69 tokens are identical.\n\n### Training the Universal Base Model\n\nThe universal base model is a 311.9M-parameter RoBERTa-large, identical in architecture to our single-species v2 but with the expanded 94-token vocabulary. It was trained for 48 hours on 4 A100 GPUs using the full 362k-sequence multispecies dataset.\n\n```yaml\n# configs/mrna/production/roberta_large_multispecies.yaml\nmodel:\n  name: \"CodonRoBERTa-large-multispecies\"\n  vocab_size: 94  # 69 base + 25 species\n  hidden_size: 1024\n  num_hidden_layers: 24\n  num_attention_heads: 16\n\ntraining:\n  max_steps: 50000  # ~4.5 epochs over 362k sequences\n  learning_rate: 5e-5\n  per_device_train_batch_size: 4  # 4 GPUs = 16 effective\n  gradient_accumulation_steps: 2   # 32 total batch size\n  bf16: true\n  fsdp: \"full_shard auto_wrap\"  # Critical for 311M params\n```\n\n**Training command:**\n\n```bash\ntorchrun --nproc_per_node=4 --master_port=29501 \\\n    scripts/training/run_multispecies_train.py \\\n    --config configs/mrna/production/roberta_large_multispecies.yaml\n```\n\n**Results:**\n\n| Metric              | Value           | Notes                         |\n| ------------------- | --------------- | ----------------------------- |\n| Training time       | **48 hours**    | 4×A100 80GB GPUs              |\n| Final steps         | 47,500 / 50,000 | 95% complete (max time limit) |\n| Training loss       | 4.10 → 3.17     | **23% reduction**             |\n| Eval loss           | 3.18            | Stable convergence            |\n| Test perplexity     | **24.9**        | On 19k test sequences         |\n| Synonymous recovery | 11.0%           | Better than single-species    |\n| Model size          | 1.2 GB          | Saved with safetensors        |\n| Checkpoints         | 5 saved         | Every 2,500 steps             |\n\nThe test perplexity of 24.9 is higher than our single-species model's 4.01, which might look like a regression. It is not. The multispecies model must learn distinct codon preferences for 25 different organisms, each with its own evolutionary history and tRNA pools. A bacterium like *M. tuberculosis* (65% GC content) uses completely different codons than human cells (41% GC). The model is solving a fundamentally harder problem, and the perplexity reflects that. What matters is whether species-specific fine-tuning can recover performance, and it does.\n\n### Species-Specific Fine-Tuning\n\nThe universal base model is a generalist. For production use, specialists perform better. **OpenMed's** fine-tuning strategy starts from the multispecies checkpoint and trains further on a single species at a lower learning rate (2e-5 vs 5e-5), preserving cross-species knowledge while specializing the model's predictions for one organism.\n\n**Dataset splits:**\n\n```python\n# scripts/training/split_species_datasets.py\n# Automated splitting for 6 priority species\n\nRESULTS = {\n    'HUMAN': {'train': 131_245, 'test': 6_908},\n    'MOUSE': {'train': 88_022,  'test': 4_633},\n    'CHO':   {'train': 42_541,  'test': 2_239},\n    'ECOLI': {'train': 8_547,   'test': 450},\n    'YEAST': {'train': 5_439,   'test': 287},\n    'PICHIA':{'train': 4_548,   'test': 240},\n}\n```\n\n**Training all three priority species:**\n\n```bash\n# HUMAN: Therapeutic mRNA, vaccines\ntorchrun --nproc_per_node=4 scripts/training/run_multispecies_train.py \\\n    --config configs/mrna/production/roberta_large_human_finetune.yaml\n\n# ECOLI: Protein expression, metabolic engineering\ntorchrun --nproc_per_node=4 scripts/training/run_multispecies_train.py \\\n    --config configs/mrna/production/roberta_large_ecoli_finetune.yaml\n\n# CHO: Biopharmaceutical production\ntorchrun --nproc_per_node=4 scripts/training/run_multispecies_train.py \\\n    --config configs/mrna/production/roberta_large_cho_finetune.yaml\n```\n\n**Comprehensive Results:**\n\n| Model                 | Train Seqs | Steps  | GPU Hours      | Test Loss | Perplexity | vs Multispecies | Primary Use Case            |\n| --------------------- | ---------- | ------ | -------------- | --------- | ---------- | --------------- | --------------------------- |\n| **Multispecies Base** | 362k       | 47,500 | **48h**        | 3.18      | 24.9       | *baseline*      | Universal optimization      |\n| **HUMAN**             | 131k       | 15,000 | **4h**         | 3.16      | **24.3**   | **2.4% better** | mRNA therapeutics, vaccines |\n| **ECOLI**             | 8.5k       | 5,000  | **0.5h**       | 3.17      | **25.3**   | **1.6% better** | Recombinant proteins        |\n| **CHO**               | 42.5k      | 10,000 | **2.5h**       | 3.21      | **25.5**   | 2.4% worse      | Antibody production         |\n|                       |            |        | **Total: 55h** |           |            |                 |                             |\n\nThe most important result here is the HUMAN model: at 24.3 perplexity, it is the only specialist that beats the universal base, making it our production model for therapeutic mRNA applications. But the ECOLI result is arguably more interesting from a research perspective. With only 8,547 training sequences (compared to 131k for human), the *E. coli* specialist still improved over the multispecies base. This validates the transfer learning hypothesis: training on 25 species first, then fine-tuning on a small species-specific dataset, works better than training on the small dataset alone. For the many organisms where annotated CDS data is scarce, this approach opens the door to reasonable codon optimization without needing tens of thousands of species-specific sequences.\n\nThe CHO model showed slight degradation (25.5 vs 24.9), which we attribute to insufficient training steps. ECOLI got 5,000 steps for 8.5k sequences (0.59 steps per sequence), while CHO got 10,000 steps for 42.5k sequences (0.24 steps per sequence). A rerun with 15,000 steps should close this gap. All three specialists fine-tuned in just 7 hours total, leveraging the 48-hour investment in the multispecies base.\n\n### The Complete Model Suite\n\nAfter 55 hours of training, we have:\n\nAll models will be released on Hugging Face under the **OpenMed** organization. The naming convention follows `OpenMed/{model-name}` for direct use with `from_pretrained()`.\n\n**Universal Models:**\n\n- [`OpenMed/CodonRoBERTa-large-multispecies`](https://huggingface.co/OpenMed/CodonRoBERTa-large-multispecies) (311.9M params)\n  - Trained on 25 species\n  - Perplexity: 24.9\n  - Use case: Cross-species optimization, rare organisms\n\n**Species-Specific Specialists:**\n\n- [`OpenMed/CodonRoBERTa-large-human`](https://huggingface.co/OpenMed/CodonRoBERTa-large-human) (311.9M params)\n\n  - Perplexity: 24.3 (**best overall**)\n  - Use case: mRNA vaccines, gene therapy, therapeutic proteins\n- [`OpenMed/CodonRoBERTa-large-ecoli`](https://huggingface.co/OpenMed/CodonRoBERTa-large-ecoli) (311.9M params)\n\n  - Perplexity: 25.3\n  - Use case: Bacterial protein expression, metabolic engineering\n- [`OpenMed/CodonRoBERTa-large-cho`](https://huggingface.co/OpenMed/CodonRoBERTa-large-cho) (311.9M params)\n\n  - Perplexity: 25.5\n  - Use case: Mammalian cell culture, biopharmaceuticals\n\n**Single-Species Models:**\n\n- [`OpenMed/CodonRoBERTa-large-v2`](https://huggingface.co/OpenMed/CodonRoBERTa-large-v2) (312M params)\n\n  - Perplexity: 4.10, CAI: 0.404\n  - Trained on 250k *E. coli* only\n  - Still the best for pure *E. coli* optimization\n- [`OpenMed/CodonRoBERTa-base`](https://huggingface.co/OpenMed/CodonRoBERTa-base) (92M params)\n\n  - Perplexity: 4.01, CAI: 0.219\n  - Best efficiency option (3.4x smaller than large)\n\n### Production Deployment Strategy\n\n**For therapeutic mRNA (Moderna, BioNTech-style vaccines):**\n\n```python\nfrom transformers import RobertaForMaskedLM\n\n# Load human-optimized model\nmodel = RobertaForMaskedLM.from_pretrained(\"OpenMed/CodonRoBERTa-large-human\")\n\n# Optimize amino acid sequence to DNA\noptimized_dna = optimize_for_human(protein_seq, model)\n```\n\n**For industrial protein production:**\n\n```python\n# E. coli expression\nmodel_ecoli = RobertaForMaskedLM.from_pretrained(\"OpenMed/CodonRoBERTa-large-ecoli\")\n\n# CHO cell expression\nmodel_cho = RobertaForMaskedLM.from_pretrained(\"OpenMed/CodonRoBERTa-large-cho\")\n```\n\n**For rare/unmodeled organisms:**\n\n```python\n# Use multispecies base with species conditioning\nmodel_multi = RobertaForMaskedLM.from_pretrained(\"OpenMed/CodonRoBERTa-large-multispecies\")\n# Prepend species token: [YEAST], [PICHIA], [MOUSE], etc.\n```\n\n### Infrastructure & Reproducibility\n\n**Hardware requirements:**\n\n- 4×A100 80GB GPUs (training)\n- Single A100 40GB (inference)\n- FSDP (Fully Sharded Data Parallel) for 311M params\n- bf16 mixed precision (critical for stability)\n\n**Storage footprint:**\n\n- \\~150 GB total (data, trained models, and checkpoints across all runs)\n\n**Complete training pipeline:**\n\n```bash\n# 1. Download multi-species data (automated)\npython scripts/training/download_multispecies_cds.py \\\n    --output_dir data/mrna/multispecies \\\n    --categories bacteria yeast mammals\n\n# 2. Train universal base (48 hours)\ntorchrun --nproc_per_node=4 \\\n    scripts/training/run_multispecies_train.py \\\n    --config configs/mrna/production/roberta_large_multispecies.yaml\n\n# 3. Split species datasets\npython scripts/training/split_species_datasets.py \\\n    --input data/mrna/multispecies/train_multispecies.fasta \\\n    --output_dir data/mrna/species_specific\n\n# 4. Fine-tune specialists (7 hours total)\nfor species in human ecoli cho; do\n    torchrun --nproc_per_node=4 \\\n        scripts/training/run_multispecies_train.py \\\n        --config configs/mrna/production/roberta_large_${species}_finetune.yaml\ndone\n\n# 5. Evaluate all models\nfor model in multispecies human ecoli cho; do\n    python scripts/evals/advanced/eval_perplexity_multispecies.py \\\n        --model_path outputs/models/CodonRoBERTa-large-${model}/final \\\n        --test_file data/mrna/species_specific/${model}_test.fasta \\\n        --output_file outputs/evals/${model}_perplexity.json\ndone\n```\n\n**Total compute cost:**\n\n- 55 GPU-hours on A100 80GB (~$165 on AWS p4d.24xlarge)\n- All models trained to convergence in under 3 days wall-clock time\n\n### What This Enables\n\nThe multi-species suite covers the three pillars of applied codon optimization. For therapeutic mRNA, the HUMAN specialist model optimizes codons for expression in human cells, directly applicable to vaccine design (Moderna and BioNTech both codon-optimize their mRNA constructs) and gene therapy vectors. For recombinant protein production, the ECOLI specialist handles the most common bacterial expression host, while the CHO specialist covers the mammalian cell line used to produce most monoclonal antibodies and biopharmaceuticals. For organisms not covered by a specialist, the multispecies base model accepts any of the 25 species tokens and generates organism-appropriate codons.\n\nThe transfer learning result is particularly relevant for the broader community. Many industrially important organisms (non-model bacteria, insect cells, plant cells) have limited annotated CDS data. Our results with *E. coli* (8.5k sequences, improved over base) suggest that multispecies pre-training followed by small-scale fine-tuning is a viable path for these organisms, without requiring the tens or hundreds of thousands of sequences that training from scratch demands.\n\n### By the Numbers\n\nThe full project consumed 55 GPU-hours on 4 A100 80GB GPUs (~$165 at AWS spot pricing), produced ~150 GB of models and checkpoints across 4 training runs, and covers 381,283 CDS sequences from 25 species downloaded from NCBI RefSeq. All models use the same 311.9M-parameter architecture, are saved in safetensors format for fast loading, and run inference on a single GPU with 16GB+ VRAM. Everything is released under Apache 2.0.\n\n* * *\n\n## 5. The End-to-End Workflow\n\n[![The two-step protein design paradigm: generate backbone structure, then optimize sequence](https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/ZAHq19e94YYQ0ixlnPg5I.jpeg)](https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/ZAHq19e94YYQ0ixlnPg5I.jpeg)\n\n*The modern computational protein design workflow. Structure generation (top) produces backbone coordinates; sequence optimization (bottom) finds amino acid sequences that fold into the target shape. Our pipeline adds a third step: codon optimization for expression. Figure from Kortemme, Cell 2024, CC-BY 4.0.*\n\nIn Part I, we described the protein engineering loop as a cycle of prediction, design, and optimization. Here is what that looks like in practice with **OpenMed's** pipeline. Each step feeds into the next, and the entire computational phase runs in an afternoon on a single GPU.\n\nConsider a concrete scenario: engineering a more stable version of a therapeutic enzyme that degrades too quickly in the bloodstream.\n\n**Step 1: Fold (ESMFold).** Predict the structure of the starting sequence to understand its active site and identify regions that might be destabilized. ESMFold returns a 3D structure in PDB format, per-residue confidence scores (pLDDT) highlighting uncertain regions, and an overall topology confidence metric (PTM).\n\n**Step 2: Design (ProteinMPNN).** Keep the active site fixed but redesign the scaffold for improved stability. ProteinMPNN takes the backbone coordinates, a list of immutable positions (catalytic residues), and generates 100 diverse candidate sequences, each predicted to fold into the target shape.\n\n**Step 3: Verify (ESMFold).** Refold all 100 candidates with ESMFold to confirm they still adopt the correct shape. Filter for high mean pLDDT (>80), correct topology (RMSD to original), and low clash scores.\n\n**Step 4: Optimize (CodonRoBERTa).** Take the best amino acid sequences and use CodonRoBERTa-large-v2 to generate optimal DNA sequences for expression in the target organism (*E. coli*, yeast, or mammalian cells). The model scores synonymous codon choices based on learned biological preferences, identifies contextually optimal codons rather than just globally frequent ones, and produces sequences with high CAI correlation.\n\n**Step 5: Synthesize and Test.** Order the DNA from a synthesis company, clone it into an expression vector, and test expression and activity in the lab.\n\nThis loop, from hypothesis to synthesis-ready DNA, replaces what once took months of iterative wet-lab trial and error. A researcher arrives at the bench with 5-10 computationally vetted candidates instead of one or two educated guesses. The success rate improves, the cost drops, and the design cycle compresses from months to days.\n\n* * *\n\nFor a full ecosystem overview, tool selection guide, and license reference, see Part I.\n\n* * *\n\n## 6. Where This Stands and What's Next\n\n### The Landscape\n\n**OpenMed** is not working in isolation. Two recent models push the codon/mRNA modeling frontier further:\n\n- **mRNABERT** (Xiong et al., *Nature Communications* 2025): 86M-param BERT with a dual tokenization scheme (single nucleotides for UTRs, codons for CDS) and cross-modality contrastive learning against frozen ProtT5-XL protein embeddings. Trained on 18M sequences. Achieves R^2 = 0.66 on full-length mRNA translation efficiency, a 1.6-10x improvement over prior RNA models. Code and weights available (Apache 2.0).\n\n- **NUWA** (Zhong et al., *bioRxiv* 2026): Three domain-specific RoBERTa encoders (Bacteria, Eukaryota, Archaea) with curriculum MLM and supervised contrastive learning. Trained on 115M sequences across ~25,000 species. Beats CodonBERT on 11/13 BEACON benchmark tasks. No code or weights released.\n\nBoth models train on 50-300x more data than **OpenMed** used. That is the primary gap, and we are transparent about it.\n\nHere is what **OpenMed** does that neither of them offers:\n\n1. **Species-conditioned single model.** mRNABERT has no species conditioning at all. NUWA trains three separate models (one per domain of life). We put 25 species tokens into one 94-token vocabulary and train a single model that can be prompted for any organism. More parameter-efficient, more flexible.\n\n2. **Transfer learning to low-resource organisms, validated.** We showed that fine-tuning the multispecies base on just 8.5k *E. coli* sequences improves over the base model. Neither mRNABERT nor NUWA demonstrates this.\n\n3. **Full open-source pipeline.** ESMFold + ProteinMPNN + CodonRoBERTa, end to end, with training code, configs, eval scripts, and model weights. All Apache 2.0. mRNABERT releases code but not the pipeline. NUWA releases nothing.\n\n### In Progress: CodonJEPA\n\n**OpenMed** is running a proof-of-concept for a fundamentally different approach: **Joint Embedding Predictive Architecture (JEPA) for codon sequences**.\n\nStandard MLM predicts masked *tokens*. JEPA predicts masked *embeddings*. The hypothesis: if the model is forced to predict in embedding space rather than token space, it should learn that synonymous codons (different DNA, same amino acid) are functionally equivalent. MLM cannot achieve this because it is trained to distinguish every token.\n\nThe architecture:\n\n- **Context encoder**: RoBERTa-base (768-dim, 12 layers), trained normally\n- **Target encoder**: EMA copy of the context encoder (momentum 0.990 to 0.999, no gradients)\n- **Predictor**: Lightweight 4-layer transformer (384-dim), predicts target embeddings from context\n- **Masking**: Multi-block strategy (4 contiguous blocks per sequence, 15-20% mask scale)\n- **Collapse prevention**: VICReg regularization (variance + covariance loss)\n\nEarly results from our evaluation suite (JEPA vs. MLM baseline, same data, same hyperparameters, 15k steps each):\n\n| Metric                             | CodonJEPA  | CodonMLM | Winner         |\n| ---------------------------------- | ---------- | -------- | -------------- |\n| Synonymous robustness (cosine sim) | **0.9997** | 0.9414   | JEPA           |\n| Codon-to-amino-acid probe          | 37.4%      | 100%     | MLM (expected) |\n| Taxonomy classification            | 87.8%      | 99.4%    | MLM            |\n| Effective dimensionality           | 1.67       | 18.71    | MLM            |\n\nThe synonymous robustness result is the one that matters most for our hypothesis. JEPA embeddings are nearly identical (99.97% cosine similarity) for sequences that differ only in synonymous codon choices. MLM embeddings shift significantly (94.14%). This means JEPA *does* learn that synonymous codons are interchangeable, exactly as predicted.\n\nThe open challenge: JEPA currently suffers from dimensional collapse (91.78% of variance concentrated in one component). This is a known failure mode for self-supervised methods and suggests the VICReg regularization weights need tuning. The architecture works; the training dynamics need more iteration.\n\nThis is early-stage research, not production-ready. But if the collapse problem can be solved, JEPA could produce codon embeddings that are inherently amino-acid-aware, something that MLM, by its token-level prediction objective, fundamentally cannot achieve.\n\n### Roadmap\n\n**CodonRoBERTa (scaling up)**:\n\n- Retrain on mRNABERT's public 36M-sequence dataset (Zenodo). Same architecture, same species tokens, 100x more data\n- Add cross-modality contrastive alignment with ProtT5-XL (proven by mRNABERT to boost protein property prediction)\n- Extend species-specific fine-tuning to YEAST, PICHIA, MOUSE\n- Add mRNA stability and immunogenicity prediction heads\n\n**CodonJEPA (fixing and scaling)**:\n\n- Solve dimensional collapse (stronger VICReg weights, alternative regularizers)\n- Benchmark against mRNABERT's contrastive approach on the same downstream tasks\n- If JEPA embeddings hold up, integrate as a drop-in replacement for MLM embeddings in the pipeline\n\n**Pipeline**:\n\n- Integrate RFdiffusion for *de novo* backbone generation\n- Add solubility and expression prediction heads\n- Fine-tune ESMFold on specialized domains (antibodies, enzymes)\n\n### Setup and Requirements\n\n**Hardware**:\n\n- Tested on 4×A100 GPUs (80GB)\n- Folding inference: ~16-20GB VRAM for typical proteins\n- Training: Scales with FSDP (Fully Sharded Data Parallel)\n- Minimum for inference: Single GPU with 16GB+ VRAM\n\n**Environment**:\n\n- Use `.env_esmfold` virtual environment for folding\n- For training: PyTorch 2.5.1+cu121 with flash-attn2\n- Python 3.10+ recommended\n\n**Licenses** (all commercial-friendly):\n\n- ESMFold: MIT\n- ProteinMPNN: MIT\n- OpenFold: Apache-2.0\n- Our CodonRoBERTa: Apache-2.0\n\n* * *\n\n## 7. References\n\n**OpenMed's** work builds on foundational research from Meta AI, the Baker Lab at the University of Washington, DeepMind, and the broader open-source computational biology community.\n\n### Key Papers\n\n**Protein Structure Prediction**\n\n- Jumper, J. et al. \"Highly accurate protein structure prediction with AlphaFold.\" *Nature* (2021). [DOI](https://doi.org/10.1038/s41586-021-03819-2)\n- Lin, Z. et al. \"Evolutionary-scale prediction of atomic-level protein structure with a language model.\" *Science* (2023). [DOI](https://doi.org/10.1126/science.ade2574)\n- Ahdritz, G. et al. \"OpenFold: Retraining AlphaFold2 yields new insights.\" *Nature Methods* (2024). [DOI](https://doi.org/10.1038/s41592-024-02272-z)\n\n**Protein Design**\n\n- Dauparas, J. et al. \"Robust deep learning-based protein sequence design using ProteinMPNN.\" *Science* (2022). [DOI](https://doi.org/10.1126/science.add2187)\n- Watson, J.L. et al. \"De novo design of protein structure and function with RFdiffusion.\" *Nature* (2023). [DOI](https://doi.org/10.1038/s41586-023-06415-8)\n\n**mRNA & Codon Optimization**\n\n- Cheng, J. et al. \"CodonBERT: a language model for codon optimization.\" *Nucleic Acids Research* (2024). [DOI](https://doi.org/10.1093/nar/gkae495)\n- Xiong, Y. et al. \"mRNABERT: advancing mRNA sequence design with a universal language model and comprehensive dataset.\" *Nature Communications* (2025). [DOI](https://doi.org/10.1038/s41467-025-65340-8)\n- Zhong, Y. et al. \"Large mRNA language foundation modeling with NUWA for unified sequence perception and generation.\" *bioRxiv* (2026). [DOI](https://doi.org/10.1101/2025.11.01.686058)\n- Warner, B. et al. \"ModernBERT: Smarter, Better, Faster, Longer.\" arXiv (2024). [arXiv](https://arxiv.org/abs/2412.13663)\n\n* * *\n\n## Models and Data: Coming Soon\n\nAll models, training code, and the multi-species dataset described in this post will be publicly released under the **OpenMed** organization on Hugging Face under Apache 2.0 / MIT licenses.\n\n**Models** (7 checkpoints):\n\n| Model                           | Params | HuggingFace                               |\n| ------------------------------- | ------ | ----------------------------------------- |\n| CodonRoBERTa-large-v2           | 312M   | `OpenMed/CodonRoBERTa-large-v2`           |\n| CodonRoBERTa-base               | 92M    | `OpenMed/CodonRoBERTa-base`               |\n| CodonRoBERTa-large-multispecies | 311.9M | `OpenMed/CodonRoBERTa-large-multispecies` |\n| CodonRoBERTa-large-human        | 311.9M | `OpenMed/CodonRoBERTa-large-human`        |\n| CodonRoBERTa-large-ecoli        | 311.9M | `OpenMed/CodonRoBERTa-large-ecoli`        |\n| CodonRoBERTa-large-cho          | 311.9M | `OpenMed/CodonRoBERTa-large-cho`          |\n\n**Dataset**:\n\n| Dataset           | Sequences | Species | HuggingFace                          |\n| ----------------- | --------- | ------- | ------------------------------------ |\n| Multi-species CDS | 381,283   | 25      | `OpenMed/multispecies-codon-dataset` |\n\n**Training code and evaluation scripts** will be released alongside the models.\n\nFollow [**OpenMed** on Hugging Face](https://huggingface.co/OpenMed) to be notified when models go live.\n\n* * *\n\n*The ML Engineer's Guide to Protein AI: From Protein to Optimized DNA | March 2026*\n\n[**Read Part I**: The AlphaFold Revolution, covering the landscape of protein AI.](https://huggingface.co/blog/MaziyarPanahi/protein-ai-landscape)\n\n*Questions or collaboration ideas? Reach out on Hugging Face or open a discussion on the model pages.*\n",
  "authors": [],
  "captured_at": "2026-10-04T12:50:30.804479567+00:00",
  "category": "ai",
  "content_html": "<h2>Part II: Building the Pipeline, From Structure Prediction to Codon Optimization</h2>\n<p><em>By OpenMed, Open-Source Agentic AI for Healthcare &amp; Life Sciences</em></p>\n<hr />\n<blockquote>\n<p><strong>TL;DR</strong>: We built an end-to-end protein AI pipeline covering structure prediction, sequence design, and codon optimization. After comparing multiple transformer architectures for codon-level language modeling, <strong>CodonRoBERTa-large-v2</strong> emerged as the clear winner with a perplexity of 4.10 and a Spearman CAI correlation of 0.40, significantly outperforming ModernBERT. We then scaled to 25 species, trained 4 production models in 55 GPU-hours, and built a species-conditioned system that no other open-source project offers. Complete results, architectural decisions, and runnable code below.</p>\n</blockquote>\n<p><strong>Contents</strong></p>\n<ol>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#1-what-we-built\">What We Built</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#2-the-architecture-exploration\">The Architecture Exploration</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#3-the-pipeline\">The Pipeline</a>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#31-protein-folding-with-esmfold\">3.1 Protein Folding</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#32-sequence-design-with-proteinmpnn\">3.2 Sequence Design</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#33-mrna-optimization\">3.3 mRNA Optimization</a></li>\n</ul>\n</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#4-scaling-to-multi-species\">Scaling to Multi-Species</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#5-the-end-to-end-workflow\">The End-to-End Workflow</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#6-where-this-stands-and-whats-next\">Where This Stands and What's Next</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#7-references\">References</a></li>\n</ol>\n<hr />\n<p>Imagine going from a therapeutic protein concept to a synthesis-ready, codon-optimized DNA sequence in an afternoon. That is the pipeline <strong>OpenMed</strong> set out to build, and this post documents the process from start to finish.</p>\n<p>In Part I, we mapped the landscape of protein AI: the architectures powering structure prediction, the open-source tools available for protein design, and the ecosystem of models from AlphaFold to ESMFold. That was a survey. This is the build.</p>\n<p>At <strong>OpenMed</strong>, we set out to build a complete pipeline that takes a protein idea from concept to expression-ready DNA. That means three stages: predict the 3D structure of a protein, design amino acid sequences that fold into that structure, and optimize the underlying DNA codons so the protein actually expresses in the target organism. Along the way, we ran extensive experiments comparing transformer architectures for codon optimization, scaled our best model to 25 species, and built tooling that ties it all together.</p>\n<p>This is not a polished success story. It is a transparent account of what worked, what surprised us, and what we would do differently, with runnable code and full results at every step.</p>\n<hr />\n<h2>1. What We Built</h2>\n<p>The pipeline has three components, each addressing a different stage of the protein engineering workflow described in Part I. Structure prediction determines <em>what shape</em> a protein takes. Sequence design determines <em>which amino acids</em> will produce that shape. Codon optimization determines <em>which DNA</em> will produce those amino acids efficiently in a living cell.</p>\n<table>\n<thead>\n<tr>\n<th>Component</th>\n<th>What We Did</th>\n<th>Key Result</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Protein Folding</strong></td>\n<td>ESMFold v1 predictions on 30 protein chains</td>\n<td>Avg PTM: 0.79, working batch pipeline</td>\n</tr>\n<tr>\n<td><strong>Sequence Design</strong></td>\n<td>ProteinMPNN on scaffold 7K00</td>\n<td>42% sequence recovery</td>\n</tr>\n<tr>\n<td><strong>mRNA Optimization</strong></td>\n<td>Trained multiple transformer variants on 250k CDS, then scaled to 381k sequences across 25 species</td>\n<td><strong>CodonRoBERTa-large-v2</strong>: perplexity 4.10, CAI 0.40; <strong>Multi-species suite</strong>: 4 models spanning 25 organisms (55 GPU-hours)</td>\n</tr>\n</tbody>\n</table>\n<p>The mRNA optimization work is where we invested the most effort, and where we have the most to share. The folding and design components use established tools (ESMFold from Meta, ProteinMPNN from the Baker Lab, both covered in depth in Part I). The codon optimization component is entirely ours: new models, new training infrastructure, new evaluation metrics.</p>\n<h2>2. The Architecture Exploration</h2>\n<p>In Part I, we surveyed the protein AI landscape and noted that most biological language models are adaptations of NLP architectures. The open question was <em>which</em> architecture. BERT variants dominate protein modeling (ESM-2, ProtTrans), but codon sequences have different statistical properties than both natural language and amino acid sequences. Codons are triplets drawn from a small 64-token alphabet, with strong positional dependencies and species-specific usage biases. We needed to find out what works from first principles.</p>\n<p>The core question: which transformer architecture works best for codon-level language modeling?</p>\n<p>This matters because codon optimization is crucial for therapeutic mRNA, vaccines, and recombinant protein production. The genetic code is degenerate: the same protein can be encoded by astronomically many different DNA sequences, but some codon arrangements express 100x better than others. The Pfizer-BioNTech COVID vaccine, for example, was codon-optimized for human expression. We wanted to build a model that could learn these preferences directly from natural coding sequences, rather than relying on hand-crafted frequency tables.</p>\n<h3>The Contenders</h3>\n<p>We started with a small CodonBERT baseline (6M params, following Sanofi's published architecture) and scaled up through two families: ModernBERT, which represented the latest efficiency innovations from the NLP community, and RoBERTa, the proven workhorse behind Meta's ESM protein language models.</p>\n<table>\n<thead>\n<tr>\n<th>Model</th>\n<th>Parameters</th>\n<th>Architecture</th>\n<th>Hypothesis</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>CodonBERT (baseline)</strong></td>\n<td>6M</td>\n<td>BERT-tiny (6 layers)</td>\n<td>Minimal baseline to establish floor performance</td>\n</tr>\n<tr>\n<td><strong>ModernBERT-base</strong></td>\n<td>90M</td>\n<td>ModernBERT (22 layers, RoPE)</td>\n<td>Modern innovations: long context, efficient attention</td>\n</tr>\n<tr>\n<td><strong>CodonRoBERTa-base</strong></td>\n<td>92M</td>\n<td>RoBERTa (12 layers)</td>\n<td>Proven MLM architecture, same family as ESM-2</td>\n</tr>\n<tr>\n<td><strong>CodonRoBERTa-large</strong></td>\n<td>312M</td>\n<td>RoBERTa (24 layers)</td>\n<td>Test whether more parameters improve codon modeling</td>\n</tr>\n<tr>\n<td><strong>CodonRoBERTa-large-v2</strong></td>\n<td>312M</td>\n<td>RoBERTa (24 layers, refined)</td>\n<td>Same architecture, better hyperparameters</td>\n</tr>\n</tbody>\n</table>\n<p>The choice of RoBERTa was deliberate. As we discussed in Part I, Meta's ESM-2 (which powers ESMFold) is itself a RoBERTa variant trained on protein sequences. We hypothesized that the same architecture family that learned amino acid patterns might also learn codon patterns. ModernBERT was the counterpoint: a 2024 architecture with RoPE embeddings, Flash Attention, and alternating local/global attention layers, representing everything the NLP community had learned since RoBERTa's 2019 release.</p>\n<h3>The Training Setup</h3>\n<p>To ensure a fair comparison, every model was trained on identical data with the same evaluation protocol. We used 250,000 coding sequences (CDS) from <em>E. coli</em> RefSeq, covering chromosome and complete assembly accessions. This is a clean, well-annotated dataset where codon usage patterns are well-characterized in the literature, giving us ground truth to validate against.</p>\n<p>Our tokenizer maps each codon to a single token: 64 codons plus 5 special tokens (PAD, UNK, CLS, SEP, MASK) for a 69-token vocabulary. This is intentionally minimal. Unlike BPE tokenizers used in NLP, where subword boundaries are statistically learned, codon boundaries are biologically defined. Every three nucleotides encode one amino acid. Our tokenizer respects this.</p>\n<p>Training ran on 4 A100 GPUs (80GB) with FSDP sharding, using 15,000 to 25,000 steps depending on model size. All models used masked language modeling (MLM) with 15% masking rate, the same objective used by ESM-2 for protein sequences.</p>\n<h3>The Results</h3>\n<table>\n<thead>\n<tr>\n<th>Model</th>\n<th>Perplexity</th>\n<th>CAI Spearman</th>\n<th>Synonymous Recovery</th>\n<th>Status</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>CodonRoBERTa-large-v2</strong></td>\n<td>4.10</td>\n<td><strong>0.404</strong></td>\n<td>7.7%</td>\n<td><strong>Best Overall</strong></td>\n</tr>\n<tr>\n<td><strong>CodonRoBERTa-base</strong></td>\n<td><strong>4.01</strong></td>\n<td>0.219</td>\n<td><strong>8.5%</strong></td>\n<td><strong>Best Efficiency</strong></td>\n</tr>\n<tr>\n<td>CodonRoBERTa-large</td>\n<td>4.01</td>\n<td>0.025</td>\n<td>7.6%</td>\n<td>Good MLM, weak bio</td>\n</tr>\n<tr>\n<td>ModernBERT-base</td>\n<td>26.24</td>\n<td>0.070</td>\n<td>8.5%</td>\n<td>Underperformed</td>\n</tr>\n<tr>\n<td>CodonBERT (baseline)</td>\n<td>17.18</td>\n<td>-0.629</td>\n<td>0.0%</td>\n<td>Baseline</td>\n</tr>\n</tbody>\n</table>\n<p>The result was unambiguous: RoBERTa outperformed ModernBERT by 6x on perplexity (4.01 vs 26.24). This was not a marginal difference. ModernBERT, despite its modern attention patterns and efficient architecture, fundamentally underperformed the classic RoBERTa design on codon sequences.</p>\n<h3>What We Learned</h3>\n<p><strong>1. Pre-trained NLP weights do not transfer to biology</strong></p>\n<p>We initialized ModernBERT from its published English-language checkpoint, expecting the learned attention patterns to provide a useful starting point. They did not. Our best explanation: ModernBERT's pre-training on English text instilled inductive biases (subword frequency distributions, positional attention patterns) that actively interfere with learning codon statistics. RoBERTa, initialized randomly and trained purely on biological data, had no such baggage. This aligns with what the field has seen more broadly: ESM-2 and ProtTrans both train from scratch on biological data rather than fine-tuning from NLP checkpoints.</p>\n<p><strong>2. Hyperparameter tuning unlocked biological alignment</strong></p>\n<p>This was the most surprising and practically important finding of the exploration. Compare CodonRoBERTa-large v1 and v2:</p>\n<table>\n<thead>\n<tr>\n<th>Version</th>\n<th>Perplexity</th>\n<th>CAI Spearman</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>v1 (lr=1e-4)</td>\n<td>4.01</td>\n<td>0.025</td>\n</tr>\n<tr>\n<td>v2 (lr=5e-5, longer warmup)</td>\n<td>4.10</td>\n<td><strong>0.404</strong></td>\n</tr>\n</tbody>\n</table>\n<p>Same architecture. Same data. Same number of parameters. The only differences: half the learning rate and a longer warmup (2,000 steps vs 1,000). Yet v2's predicted codon likelihoods are <strong>16x better correlated with real biological codon preferences</strong>, as measured by Codon Adaptation Index.</p>\n<p>The perplexity actually got slightly <em>worse</em> (4.10 vs 4.01), which means v2 is marginally less accurate at predicting the exact masked codon. But it is dramatically better at predicting codons that biology actually uses. The slower training schedule let the model settle into representations that capture genuine biological signal rather than overfitting to surface statistics.</p>\n<p>This is a crucial insight for anyone training biological language models: <strong>MLM loss alone does not measure biological relevance.</strong> Domain-specific metrics are essential. In our case, CAI correlation turned out to be the metric that separates a useful model from a technically impressive but biologically meaningless one.</p>\n<p><strong>3. The base model is remarkably efficient</strong></p>\n<p>CodonRoBERTa-base (92M params) achieved nearly identical perplexity to the large model (4.01 vs 4.10) with 3.4x fewer parameters and proportionally less training time. Its CAI correlation (0.219) is lower than v2's (0.404), but still well above the baseline and ModernBERT. For teams without access to multi-GPU clusters, the base model is a practical choice that captures most of the codon modeling performance at a fraction of the cost.</p>\n<h2>3. The Pipeline</h2>\n<p>In Part I, we described the three-stage workflow that most computational protein engineering projects follow: predict structure, design sequences, optimize codons. Here we run each stage with real data and report what we actually got.</p>\n<ol>\n<li><strong>Fold</strong>: Predict the 3D structure (ESMFold)</li>\n<li><strong>Design</strong>: Generate sequences that fold into that structure (ProteinMPNN)</li>\n<li><strong>Optimize</strong>: Choose the best codons for expression (CodonRoBERTa)</li>\n</ol>\n<hr />\n<h3>3.1 Protein Folding with ESMFold</h3>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/ty2O24OhgfrFHJJUTl7dG.jpeg\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/ty2O24OhgfrFHJJUTl7dG.jpeg\" alt=\"ESMFold Architecture: single-sequence structure prediction using the ESM-2 protein language model\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></a></p>\n<p><em>ESMFold architecture. The model parses a single amino acid sequence through the ESM-2 encoder, then predicts 3D coordinates via a folding trunk and structure module. Figure from Bertoline et al., Biomolecules 2024, CC-BY 4.0.</em></p>\n<p>As covered in Part I, ESMFold is Meta's single-sequence structure predictor. It uses ESM-2, a 15-billion-parameter protein language model trained on 65 million UniRef sequences, as its backbone. The key advantage over AlphaFold 2 is speed: ESMFold skips the computationally expensive multiple sequence alignment (MSA) step and predicts structures directly from a single amino acid sequence. That makes it seconds per protein instead of hours.</p>\n<p>The tradeoff is accuracy. ESMFold achieves ~0.87 TM-score on CASP14 targets vs. AlphaFold's ~0.92. For rapid prototyping and candidate screening, that gap is acceptable. When a pipeline generates 100 designed sequences and needs to refold all of them to check viability, speed matters more than the last few percentage points of accuracy.</p>\n<h3>Our Results: 30 Protein Chains</h3>\n<p>We ran ESMFold on 30 protein chains sourced from the Protein Data Bank. These are real experimental structures with known ground truth, spanning sequence lengths from 211 to 519 residues. The set deliberately includes both easy targets (single-domain proteins) and challenging ones (chains from a multi-chain ribosomal complex, PDB 7K00) to stress-test the model.</p>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-python\">import</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">json</span></span></span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Load our actual results\n</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">metrics</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">json</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">load</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">open</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">outputs/esmfold_metrics.json<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Summary statistics\n</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">n_chains</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">len</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">metrics</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>  <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> 30\n</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">avg_plddt</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">sum</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">m</span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-begin syntax-python\">[</span></span><span class=\"syntax-meta syntax-item-access syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">mean_plddt<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-end syntax-python\">]</span></span> <span class=\"syntax-meta syntax-expression syntax-generator syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-for syntax-generator syntax-python\">for</span> <span class=\"syntax-meta syntax-generic-name syntax-python\">m</span> <span class=\"syntax-keyword syntax-control syntax-flow syntax-for syntax-in syntax-python\">in</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">metrics</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">/</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">n_chains</span></span>  <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> 33.8\n</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">avg_ptm</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">sum</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">m</span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-begin syntax-python\">[</span></span><span class=\"syntax-meta syntax-item-access syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">ptm<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-end syntax-python\">]</span></span> <span class=\"syntax-meta syntax-expression syntax-generator syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-for syntax-generator syntax-python\">for</span> <span class=\"syntax-meta syntax-generic-name syntax-python\">m</span> <span class=\"syntax-keyword syntax-control syntax-flow syntax-for syntax-in syntax-python\">in</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">metrics</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">/</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">n_chains</span></span>  <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> 0.79\n</span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">print</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-storage syntax-type syntax-string syntax-python\">f</span><span class=\"syntax-meta syntax-string syntax-interpolated syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-interpolated syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">Chains: </span><span class=\"syntax-meta syntax-interpolation syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-interpolation syntax-begin syntax-python\">{</span><span class=\"syntax-source syntax-python syntax-embedded\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">n_chains</span></span></span></span><span class=\"syntax-meta syntax-interpolation syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-interpolation syntax-end syntax-python\">}</span></span><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">print</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-storage syntax-type syntax-string syntax-python\">f</span><span class=\"syntax-meta syntax-string syntax-interpolated syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-interpolated syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">Average pLDDT: </span><span class=\"syntax-meta syntax-interpolation syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-interpolation syntax-begin syntax-python\">{</span><span class=\"syntax-source syntax-python syntax-embedded\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">avg_plddt</span></span></span><span class=\"syntax-meta syntax-format-spec syntax-python\"><span class=\"syntax-constant syntax-other syntax-format-spec syntax-python\">:.1f</span></span></span><span class=\"syntax-meta syntax-interpolation syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-interpolation syntax-end syntax-python\">}</span></span><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">print</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-storage syntax-type syntax-string syntax-python\">f</span><span class=\"syntax-meta syntax-string syntax-interpolated syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-interpolated syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">Average PTM: </span><span class=\"syntax-meta syntax-interpolation syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-interpolation syntax-begin syntax-python\">{</span><span class=\"syntax-source syntax-python syntax-embedded\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">avg_ptm</span></span></span><span class=\"syntax-meta syntax-format-spec syntax-python\"><span class=\"syntax-constant syntax-other syntax-format-spec syntax-python\">:.2f</span></span></span><span class=\"syntax-meta syntax-interpolation syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-interpolation syntax-end syntax-python\">}</span></span><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n</span></span></code></pre>\n<p><strong>Results breakdown:</strong></p>\n<table>\n<thead>\n<tr>\n<th>Metric</th>\n<th>Value</th>\n<th>Interpretation</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Chains predicted</td>\n<td>30</td>\n<td>-</td>\n</tr>\n<tr>\n<td>Average pLDDT</td>\n<td>33.8</td>\n<td>Per-residue confidence (lower than expected)</td>\n</tr>\n<tr>\n<td>Average PTM</td>\n<td>0.79</td>\n<td>Topology confidence (good)</td>\n</tr>\n<tr>\n<td>Sequence lengths</td>\n<td>211-519</td>\n<td>Typical protein sizes</td>\n</tr>\n</tbody>\n</table>\n<p>The PTM scores are solid: anything above 0.5 suggests the model has the overall topology correct, and our average of 0.79 indicates high confidence in the predicted folds. The pLDDT scores are lower than published ESMFold benchmarks, which initially concerned us. The explanation turned out to be our test set composition: the ribosomal chains from 7K00 are part of a large multi-chain complex, and ESMFold (which predicts single chains in isolation) cannot model the inter-chain contacts that stabilize these structures. For single-domain proteins in our set, pLDDT scores were consistently above 70.</p>\n<h3>Running ESMFold</h3>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> Activate environment</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-source syntax-shell\">source</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> .env_esmfold/bin/activate</span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> Batch prediction</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">python</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> scripts/esmfold_batch.py <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>seq_dir</span> data/pdb/sequences <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>out_dir</span> data/esmfold/out <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>metrics</span> outputs/esmfold_metrics.json <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>device</span> cuda:0</span>\n</span></span></code></pre>\n<p>Each prediction takes ~10-30 seconds on an A100. The output includes:</p>\n<ul>\n<li>PDB structure files</li>\n<li>pLDDT scores (per-residue confidence, 0-100)</li>\n<li>PTM scores (topology confidence, 0-1)</li>\n<li>Predicted Aligned Error (PAE) matrices</li>\n</ul>\n<hr />\n<h3>3.2 Sequence Design with ProteinMPNN</h3>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/HnDJvDzsbQsbJn4IyJyCU.jpeg\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/HnDJvDzsbQsbJn4IyJyCU.jpeg\" alt=\"ProteinMPNN Architecture: message-passing neural network for inverse protein design\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></a> <em>ProteinMPNN architecture. (A) The encoder processes backbone atom distances; the decoder autoregressively generates amino acid sequences. (B) Random decoding order improves diversity. (C) Tied positions enable symmetric and multi-state design. Figure from Dauparas et al., Science 2022, CC-BY 4.0.</em></p>\n<p>As we described in Part I, protein design is the inverse of protein folding. Folding goes sequence to structure: given amino acids, predict the 3D shape. <strong>Inverse folding</strong> goes the other way: given a target 3D shape, find amino acid sequences that will fold into it.</p>\n<p>ProteinMPNN, from David Baker's lab at the University of Washington, is the current gold standard for this task. It was published in <em>Science</em> in 2022 and has since been validated experimentally: designed sequences fold into their target structures at rates far exceeding random or earlier computational methods. The architecture treats the protein backbone as a graph, where nodes are amino acid positions and edges connect spatially proximate residues (K-nearest neighbors in 3D). A message-passing neural network propagates information through this graph, then autoregressively generates a sequence one residue at a time.</p>\n<h3>Our Results: Scaffold 7K00</h3>\n<p>We ran ProteinMPNN on PDB structure 7K00 (a large multi-chain ribosomal complex):</p>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">python</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> proteinmpnn/protein_mpnn_run.py <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>pdb_path</span> data/pdb/raw/7K00.cif <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>out_folder</span> outputs/proteinmpnn_smoke <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>num_seq_per_target</span> 3 <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>sampling_temp</span> 0.1</span>\n</span></span></code></pre>\n<p><strong>Results:</strong></p>\n<table>\n<thead>\n<tr>\n<th>Metric</th>\n<th>Value</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Sequences generated</td>\n<td>3</td>\n</tr>\n<tr>\n<td>Best score</td>\n<td>0.89</td>\n</tr>\n<tr>\n<td>Sequence recovery</td>\n<td>~42%</td>\n</tr>\n</tbody>\n</table>\n<p>Here's what the output looks like:</p>\n<pre><code class=\"language-text\"><span class=\"code-snippet\">&gt;7K00, score=1.7100, global_score=1.7100\nGIREKIKLVSSAGTGHFYTTTKNKRTKPEKLELKKFDPVVRQHVIYKEAKI/MKRTFQPSVLK...\n\n&gt;T=0.1, sample=1, score=0.8857, seq_recovery=0.4203\nSKKVVIKLVCSCGCGFEYCDFRDIEKNPEKIERVLYCPICQKYVLFTEAPL/PPGPFRPDREV...\n</span></code></pre>\n<p>The first line is the native (natural) sequence extracted from the crystal structure. Subsequent lines are ProteinMPNN's designed variants. At temperature 0.1 (low randomness), the model recovers ~42% of the original amino acids, purely from 3D geometry. This is a strong result: it means the model independently rediscovered nearly half the residues that evolution selected, using only the backbone coordinates as input.</p>\n<p>Several practical notes from running ProteinMPNN. Scores are negative log-likelihoods, so lower is better. The 42% recovery rate is typical for well-resolved structures and consistent with the original paper's benchmarks. Higher sampling temperatures produce more diverse but riskier sequences. For real design work, the most powerful feature is <strong>partial design</strong>: catalytic residues, binding site amino acids, or any positions with known functional importance can be fixed in place, while ProteinMPNN redesigns only the scaffold around them. This is the standard approach for engineering a more stable version of an enzyme without disrupting its active site.</p>\n<hr />\n<h3>3.3 mRNA Optimization</h3>\n<p>This is where the pipeline transitions from existing tools to our own models. ESMFold and ProteinMPNN are established, well-validated software that we integrated. Codon optimization is where we built something new.</p>\n<h4>Why Codon Choice Matters</h4>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/pJIUjRAYERh0YBo6wlxMV.png\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/pJIUjRAYERh0YBo6wlxMV.png\" alt=\"Codon usage frequency heatmaps across optimization tools for E. coli, S. cerevisiae, and CHO cells\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></a> <em>Codon usage frequencies vary dramatically between organisms. These heatmaps compare codon preferences across E. coli, yeast, and CHO cells, the three expression hosts covered by our multi-species models. Figure from Kim et al., J. Microbiol. Biotechnol. 2025, CC-BY 4.0.</em></p>\n<p>The genetic code is <strong>degenerate</strong>: most amino acids are encoded by multiple codons. Leucine, for example, has six: TTA, TTG, CTT, CTC, CTA, and CTG. All six produce the same amino acid in the final protein. Methionine and tryptophan are the exceptions, with only one codon each.</p>\n<p>This redundancy means that for any given protein, there are astronomically many DNA sequences that encode it. A typical 300-amino-acid protein has roughly 10^150 possible codon combinations. They all produce the same amino acid chain, but they do <em>not</em> all produce the same amount of protein. Codon choice affects translation speed (because tRNA molecules are not equally abundant for all codons), mRNA stability (because the nucleotide sequence affects how quickly the transcript degrades), co-translational folding (because translation pauses at rare codons give the protein time to fold), and immune recognition (because the innate immune system in mammalian cells can distinguish native from foreign mRNA patterns). In practice, bad codon choices can reduce protein expression by 100x. This is why every mRNA vaccine, every recombinant protein therapeutic, and every gene therapy vector goes through codon optimization.</p>\n<h4>The Traditional Approach and Why It Is Limited</h4>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/c5O20MNTQJluPtrzScAlO.png\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/c5O20MNTQJluPtrzScAlO.png\" alt=\"The mRNA codon optimization design space: billions of possible sequences encoding the same protein\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></a></p>\n<p><em>The scale of the codon optimization problem. For a typical mRNA, there are over 10^600 possible codon sequences encoding the same protein. The challenge is finding the arrangement that maximizes expression. Figure from Zhang et al. (LinearDesign), Nature 2023, CC-BY 4.0.</em></p>\n<p>The classical method is simple: measure which codons appear most frequently in highly-expressed genes of the target organism, then replace every codon with the most frequent synonym. This is codified as the <strong>Codon Adaptation Index (CAI)</strong>, a per-sequence score that measures how closely the codon usage matches the organism's preferred distribution.</p>\n<p>CAI-based optimization works, but it is crude. It treats each codon position independently, ignoring the sequence context. It produces repetitive sequences (the same &quot;optimal&quot; codon used everywhere for a given amino acid), which can cause ribosome stalling and mRNA secondary structure problems. And it misses complex dependencies: the optimal codon at position 50 might depend on what codons are at positions 48 and 52, which a frequency table cannot capture.</p>\n<h4>Our Approach: Masked Language Modeling</h4>\n<p>We reframe codon optimization as a language modeling problem. Instead of looking up frequencies in a table, we train a transformer on hundreds of thousands of natural coding sequences using masked language modeling (MLM), the same pre-training objective used by BERT, RoBERTa, and Meta's ESM protein models. The model sees a codon sequence with 15% of positions masked and learns to predict the missing codons from context.</p>\n<p>What the model learns, implicitly, is the <em>grammar</em> of codon usage: which codon patterns appear in nature, which codons tend to co-occur, and how preferences shift depending on the surrounding sequence context. This is fundamentally richer than a frequency table because the model captures long-range dependencies across the entire coding sequence.</p>\n<h3>CodonRoBERTa: Our Best Model</h3>\n<p>After our architecture exploration (see above), <strong>CodonRoBERTa-large-v2</strong> emerged as the winner:</p>\n<pre><code class=\"language-yaml\"><span class=\"code-snippet\" data-language=\"YAML\"><span class=\"syntax-source syntax-yaml\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-yaml\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-line syntax-number-sign syntax-yaml\">#</span> configs/mrna/production/roberta_large_v2.yaml\n</span><span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">model_type</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\">roberta</span>\n<span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">hidden_size</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-yaml\">1024</span>\n<span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">num_hidden_layers</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-yaml\">24</span>\n<span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">num_attention_heads</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-yaml\">16</span>\n<span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">intermediate_size</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-yaml\">4096</span>\n<span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">vocab_size</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-yaml\">69</span>\n<span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">max_position_embeddings</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-yaml\">8192</span>\n<span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">learning_rate</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\">5e-5</span>  <span class=\"syntax-comment syntax-line syntax-number-sign syntax-yaml\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-line syntax-number-sign syntax-yaml\">#</span> Critical: lower than v1\n</span><span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">warmup_steps</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-yaml\">2000</span>   <span class=\"syntax-comment syntax-line syntax-number-sign syntax-yaml\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-line syntax-number-sign syntax-yaml\">#</span> Critical: longer warmup\n</span><span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">max_steps</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-yaml\">25000</span>\n</span></span></code></pre>\n<p><strong>Training:</strong></p>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">python</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> scripts/training/run_mlm_train.py <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>config</span> configs/mrna/roberta_large_v2.yaml <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>train_file</span> data/mrna/processed/train_250k.fasta <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>output_dir</span> outputs/models/CodonRoBERTa-large-v2</span>\n</span></span></code></pre>\n<h3>Evaluation: Three Metrics That Matter</h3>\n<p>Evaluating a codon language model is not straightforward. As we learned from the v1/v2 comparison above, a model can have excellent perplexity (accurately predicting masked codons) while having poor biological alignment (predicting codons that nature does not actually prefer). We evaluate on three complementary axes:</p>\n<p><strong>1. Perplexity</strong> measures how well the model predicts masked codons, computed as the exponentiated cross-entropy loss. A perplexity of 4.10 means the model is, on average, choosing between ~4 equally likely codons at each masked position. Given that most amino acids have 2-6 synonymous codons, this indicates the model has learned meaningful preferences rather than guessing uniformly. Lower is better. CodonRoBERTa-large-v2: <strong>4.10</strong>.</p>\n<p><strong>2. CAI Correlation</strong> (Spearman) measures whether a model's predicted codon likelihoods align with known biological codon usage preferences. We compute the Codon Adaptation Index for each test sequence, then correlate it with the model's pseudo-log-likelihood score. A positive correlation means the model assigns higher probability to sequences that biology actually uses. This is the metric that matters most for practical codon optimization, because it directly measures whether the model has learned biologically relevant patterns vs. just statistical ones. CodonRoBERTa-large-v2: <strong>0.404</strong> (p &lt; 10^-20).</p>\n<p><strong>3. Synonymous Recovery</strong> asks: when the model predicts a codon for a masked position, does it at least get the amino acid right? Even if it picks the wrong synonym (e.g., CTT instead of CTC for leucine), predicting the correct amino acid shows the model understands the protein-level constraint. CodonRoBERTa-large-v2: <strong>12.1% top-1 synonymous</strong>.</p>\n<h3>Running the Evaluations</h3>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> Perplexity</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">python</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> scripts/evals/advanced/eval_perplexity.py <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>model</span> outputs/models/CodonRoBERTa-large-v2/final <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>test_file</span> data/mrna/processed/test_6k.fasta <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>output</span> outputs/eval_results/CodonRoBERTa-large-v2/perplexity.json</span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> CAI Correlation</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">python</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> scripts/evals/advanced/eval_cai_correlation.py <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>model</span> outputs/models/CodonRoBERTa-large-v2/final <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>test_file</span> data/mrna/processed/test_6k.fasta <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>output</span> outputs/eval_results/CodonRoBERTa-large-v2/cai_correlation.json</span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> Synonymous Recovery</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">python</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> scripts/evals/advanced/eval_synonymous_recovery.py <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>model</span> outputs/models/CodonRoBERTa-large-v2/final <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>test_file</span> data/mrna/processed/test_6k.fasta <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>output</span> outputs/eval_results/CodonRoBERTa-large-v2/synonymous_recovery.json</span>\n</span></span></code></pre>\n<h3>The Final Leaderboard</h3>\n<p>Putting it all together across our model variants:</p>\n<table>\n<thead>\n<tr>\n<th>Model</th>\n<th>Params</th>\n<th>Perplexity</th>\n<th>CAI Spearman</th>\n<th>Best For</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>CodonRoBERTa-large-v2</strong></td>\n<td>312M</td>\n<td>4.10</td>\n<td><strong>0.404</strong></td>\n<td>Production use</td>\n</tr>\n<tr>\n<td><strong>CodonRoBERTa-base</strong></td>\n<td>92M</td>\n<td><strong>4.01</strong></td>\n<td>0.219</td>\n<td>Limited compute</td>\n</tr>\n<tr>\n<td>CodonRoBERTa-large</td>\n<td>312M</td>\n<td>4.01</td>\n<td>0.025</td>\n<td>-</td>\n</tr>\n<tr>\n<td>ModernBERT-base</td>\n<td>90M</td>\n<td>26.24</td>\n<td>0.070</td>\n<td>-</td>\n</tr>\n<tr>\n<td>CodonBERT (baseline)</td>\n<td>6M</td>\n<td>17.18</td>\n<td>-0.629</td>\n<td>Baseline only</td>\n</tr>\n</tbody>\n</table>\n<p>The RoBERTa family dominates across the board. For production use, CodonRoBERTa-large-v2 is the clear choice: it has the strongest biological alignment (CAI 0.404) while maintaining competitive perplexity. For teams with limited compute, CodonRoBERTa-base delivers nearly the same perplexity at 3.4x fewer parameters. ModernBERT underperformed substantially, which we attribute to its NLP-pretrained weights interfering with codon pattern learning.</p>\n<h3>Using the Model</h3>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-from syntax-python\">from</span></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-meta syntax-import-source syntax-python\"> <span class=\"syntax-meta syntax-import-path syntax-python\"><span class=\"syntax-meta syntax-import-name syntax-python\">transformers</span></span> <span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-python\">import</span></span></span></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"> <span class=\"syntax-meta syntax-generic-name syntax-python\">RobertaForMaskedLM</span></span>\n<span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-python\">import</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">torch</span></span></span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Load model (available soon on Hugging Face)\n</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">model</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">RobertaForMaskedLM</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">from_pretrained</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">OpenMed/CodonRoBERTa-large-v2<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">tokenizer</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">CodonTokenizer</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>  <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Our custom 69-token vocabulary\n</span>\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Score a sequence\n</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">sequence</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">ATG GCT AAA GGT...<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>  <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Space-separated codons\n</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">inputs</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">tokenizer</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">sequence</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">return_tensors</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">pt<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n<span class=\"syntax-meta syntax-statement syntax-with syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-with syntax-python\">with</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">torch</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">no_grad</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-section syntax-block syntax-with syntax-python\">:</span></span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">outputs</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">model</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">*</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">*</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">inputs</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n    <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Pseudo-log-likelihood gives a &quot;naturalness&quot; score\n</span>\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Predict alternatives for a masked position\n</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">masked_seq</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">ATG [MASK] AAA GGT...<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">inputs</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">tokenizer</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">masked_seq</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">return_tensors</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">pt<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">predictions</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">model</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">*</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">*</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">inputs</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">logits</span>\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">top_codons</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">predictions</span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-begin syntax-python\">[</span></span><span class=\"syntax-meta syntax-item-access syntax-arguments syntax-python\"><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">0</span>, <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">mask_pos</span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-end syntax-python\">]</span></span><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">topk</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">5</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n</span></span></code></pre>\n<hr />\n<h2>4. Scaling to Multi-Species</h2>\n<p>Single-species codon optimization is useful, but limited. Every organism has its own codon usage biases shaped by millions of years of evolution. <em>E. coli</em> favors different codons than human cells, which favor different codons than yeast. A model trained only on <em>E. coli</em> data will not produce optimal codons for human expression.</p>\n<p>The industry standard is to use separate CAI tables for each organism. We wanted something better: a single model that understands codon usage across organisms, can be conditioned on a target species, and can transfer knowledge from data-rich organisms (human, with 145k annotated coding sequences) to data-poor ones (<em>E. coli</em>, with 9k). After establishing CodonRoBERTa-large-v2 as our best architecture on single-species data, we built this system.</p>\n<h3>The Data Engineering Challenge</h3>\n<p>Assembling a multi-species codon dataset is not as simple as downloading a few genomes. Each organism lives in a different NCBI RefSeq assembly, with different annotation quality, different CDS boundaries, and different sequence conventions. We wrote an automated pipeline that downloads CDS sequences from 25 organisms, validates them (checking for proper start/stop codons, length divisible by 3, no internal stops), labels each sequence with a species token, and splits into train/test sets with stratification by species.</p>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> scripts/training/download_multispecies_cds.py\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Automated download from NCBI RefSeq for 25 organisms\n</span>\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">SPECIES</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span>\n    <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Bacteria (19 species)\n</span>    <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">bacteria<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span>\n        <span class=\"syntax-meta syntax-group syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">GCF_000005845.2<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">Escherichia coli K-12<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">ECOLI<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span>\n        <span class=\"syntax-meta syntax-group syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">GCF_000009045.1<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">Bacillus subtilis 168<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">BSUBT<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span>\n        <span class=\"syntax-meta syntax-group syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">GCF_000006945.2<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">Salmonella enterica<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">SENTE<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span>\n        <span class=\"syntax-meta syntax-group syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">GCF_000195955.2<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">Mycobacterium tuberculosis<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">MTUBE<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span>\n        <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> ... 15 more bacteria\n</span>    <span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>\n    <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Yeast (3 species)\n</span>    <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">yeast<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span>\n        <span class=\"syntax-meta syntax-group syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">GCF_000146045.2<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">Saccharomyces cerevisiae S288C<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">YEAST<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span>\n        <span class=\"syntax-meta syntax-group syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">GCF_000002515.2<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">Schizosaccharomyces pombe<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">SPOMBE<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span>\n        <span class=\"syntax-meta syntax-group syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">GCF_000027005.1<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">Pichia pastoris<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">PICHIA<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span>\n    <span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>\n    <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Mammals (3 species)\n</span>    <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">mammals<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span>\n        <span class=\"syntax-meta syntax-group syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">GCF_000001405.40<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">Homo sapiens GRCh38<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">HUMAN<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span>\n        <span class=\"syntax-meta syntax-group syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">GCF_000001635.27<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">Mus musculus GRCm39<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">MOUSE<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span>\n        <span class=\"syntax-meta syntax-group syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">GCF_003668045.3<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">Cricetulus griseus CHO-K1<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">CHO<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span>\n    <span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span>\n<span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span>\n</span></span></code></pre>\n<p>The final dataset spans three domains of biotechnology relevance:</p>\n<table>\n<thead>\n<tr>\n<th>Category</th>\n<th>Species</th>\n<th>Sequences</th>\n<th>Size</th>\n<th>Key Organisms</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Mammals</strong></td>\n<td>3</td>\n<td>290,091</td>\n<td>580 MB</td>\n<td>Human (145k), Mouse (97k), CHO (47k)</td>\n</tr>\n<tr>\n<td><strong>Bacteria</strong></td>\n<td>19</td>\n<td>74,972</td>\n<td>150 MB</td>\n<td>E. coli (9k), B. subtilis (4k), P. aeruginosa (5.3k)</td>\n</tr>\n<tr>\n<td><strong>Yeast</strong></td>\n<td>3</td>\n<td>16,220</td>\n<td>32 MB</td>\n<td>S. cerevisiae (5.7k), P. pastoris (4.8k)</td>\n</tr>\n<tr>\n<td><strong>Total</strong></td>\n<td><strong>25</strong></td>\n<td><strong>381,283</strong></td>\n<td><strong>~3 GB</strong></td>\n<td>362k train / 19k test</td>\n</tr>\n</tbody>\n</table>\n<p>The coverage is deliberate: bacteria are the workhorse of recombinant protein production, yeast dominates industrial biomanufacturing, and mammalian cells (especially CHO and human) are required for therapeutic proteins and mRNA vaccines. These 25 organisms collectively cover the vast majority of real-world codon optimization use cases.</p>\n<h3>The Tokenization Innovation</h3>\n<p>A model that sees sequences from 25 different organisms needs to know <em>which</em> organism it is looking at. We solved this by extending our 69-token codon vocabulary with 25 species tokens, creating a 94-token system. Each sequence is prepended with its species token (e.g., <code>[HUMAN]</code>, <code>[ECOLI]</code>, <code>[YEAST]</code>), so the model learns species-specific codon preferences within a single shared architecture.</p>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> scripts/training/codon_tokenizer.py\n</span><span class=\"syntax-meta syntax-class syntax-python\"><span class=\"syntax-storage syntax-type syntax-class syntax-python\">class</span> <span class=\"syntax-entity syntax-name syntax-class syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">MultiSpeciesCodonTokenizer</span></span><span class=\"syntax-meta syntax-class syntax-inheritance syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-inheritance syntax-begin syntax-python\">(</span></span></span><span class=\"syntax-meta syntax-class syntax-inheritance syntax-python\"><span class=\"syntax-entity syntax-other syntax-inherited-class syntax-python\">CodonTokenizer</span><span class=\"syntax-punctuation syntax-section syntax-inheritance syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-class syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-class syntax-begin syntax-python\">:</span></span>\n    <span class=\"syntax-comment syntax-block syntax-documentation syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-python\">&quot;&quot;&quot;</span>Extended tokenizer with species-awareness<span class=\"syntax-punctuation syntax-definition syntax-comment syntax-end syntax-python\">&quot;&quot;&quot;</span></span>\n\n<span class=\"syntax-meta syntax-function syntax-python\">    <span class=\"syntax-storage syntax-type syntax-function syntax-python\">def</span> <span class=\"syntax-entity syntax-name syntax-function syntax-python\"><span class=\"syntax-support syntax-function syntax-magic syntax-python\">__init__</span></span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-python\">(</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">self</span><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-function syntax-begin syntax-python\">:</span></span>\n        <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">super</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-support syntax-function syntax-magic syntax-python\">__init__</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n        <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> 0-4: [PAD], [UNK], [CLS], [SEP], [MASK]\n</span>        <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> 5-68: 64 codons (AAA, AAC, ..., TTT)\n</span>        <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> 69-93: 25 species tokens\n</span>\n        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-language syntax-python\">self</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">species_tokens</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span>\n            <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">[ABAUM]<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">[BSUBT]<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">[CHO]<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">[ECOLI]<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span>\n            <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">[HUMAN]<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">[MOUSE]<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">[YEAST]<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span> <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> ... +18 more\n</span>        <span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span>\n\n<span class=\"syntax-meta syntax-function syntax-python\">    <span class=\"syntax-storage syntax-type syntax-function syntax-python\">def</span> <span class=\"syntax-entity syntax-name syntax-function syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">encode</span></span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-python\">(</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">self</span><span class=\"syntax-punctuation syntax-separator syntax-parameters syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">dna_seq</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-annotation syntax-python\"><span class=\"syntax-punctuation syntax-separator syntax-annotation syntax-parameter syntax-python\">:</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-type syntax-python\">str</span></span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-separator syntax-parameters syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">species</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-annotation syntax-python\"><span class=\"syntax-punctuation syntax-separator syntax-annotation syntax-parameter syntax-python\">:</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-type syntax-python\">str</span></span> </span><span class=\"syntax-meta syntax-function syntax-parameters syntax-default-value syntax-python\"><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-constant syntax-language syntax-python\">None</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-function syntax-begin syntax-python\">:</span></span>\n        <span class=\"syntax-comment syntax-block syntax-documentation syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-python\">&quot;&quot;&quot;</span>Encode with species token prepended<span class=\"syntax-punctuation syntax-definition syntax-comment syntax-end syntax-python\">&quot;&quot;&quot;</span></span>\n        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">ids</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">super</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">encode</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">dna_seq</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n        <span class=\"syntax-meta syntax-statement syntax-if syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-conditional syntax-python\">if</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">species</span></span> <span class=\"syntax-keyword syntax-operator syntax-logical syntax-python\">and</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">species</span></span> <span class=\"syntax-keyword syntax-operator syntax-logical syntax-python\">in</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-language syntax-python\">self</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">species_to_id</span></span><span class=\"syntax-punctuation syntax-section syntax-block syntax-conditional syntax-python\">:</span></span>\n            <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">ids</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-language syntax-python\">self</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">species_to_id</span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-begin syntax-python\">[</span></span><span class=\"syntax-meta syntax-item-access syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">species</span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-end syntax-python\">]</span></span><span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">+</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">ids</span></span>\n        <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">ids</span></span>\n</span></span></code></pre>\n<p>This design has three advantages. First, it enables species-conditioned generation: the same model produces human-optimal or <em>E. coli</em>-optimal codons depending on which species token is prepended. Second, it enables cross-species transfer learning: universal codon patterns (like avoiding certain dinucleotides, or preferring GC-rich codons in GC-rich genomes) are shared across all species, while species-specific preferences are captured by conditioning on the species token. Third, the 94-token vocabulary is backward-compatible with our 69-token single-species models, since the first 69 tokens are identical.</p>\n<h3>Training the Universal Base Model</h3>\n<p>The universal base model is a 311.9M-parameter RoBERTa-large, identical in architecture to our single-species v2 but with the expanded 94-token vocabulary. It was trained for 48 hours on 4 A100 GPUs using the full 362k-sequence multispecies dataset.</p>\n<pre><code class=\"language-yaml\"><span class=\"code-snippet\" data-language=\"YAML\"><span class=\"syntax-source syntax-yaml\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-yaml\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-line syntax-number-sign syntax-yaml\">#</span> configs/mrna/production/roberta_large_multispecies.yaml\n</span><span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">model</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span>\n  <span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">name</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-yaml\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-yaml\">&quot;</span>CodonRoBERTa-large-multispecies<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-yaml\">&quot;</span></span>\n  <span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">vocab_size</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-yaml\">94</span>  <span class=\"syntax-comment syntax-line syntax-number-sign syntax-yaml\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-line syntax-number-sign syntax-yaml\">#</span> 69 base + 25 species\n</span>  <span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">hidden_size</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-yaml\">1024</span>\n  <span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">num_hidden_layers</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-yaml\">24</span>\n  <span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">num_attention_heads</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-yaml\">16</span>\n\n<span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">training</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span>\n  <span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">max_steps</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-yaml\">50000</span>  <span class=\"syntax-comment syntax-line syntax-number-sign syntax-yaml\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-line syntax-number-sign syntax-yaml\">#</span> ~4.5 epochs over 362k sequences\n</span>  <span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">learning_rate</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\">5e-5</span>\n  <span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">per_device_train_batch_size</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-yaml\">4</span>  <span class=\"syntax-comment syntax-line syntax-number-sign syntax-yaml\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-line syntax-number-sign syntax-yaml\">#</span> 4 GPUs = 16 effective\n</span>  <span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">gradient_accumulation_steps</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-yaml\">2</span>   <span class=\"syntax-comment syntax-line syntax-number-sign syntax-yaml\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-line syntax-number-sign syntax-yaml\">#</span> 32 total batch size\n</span>  <span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">bf16</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-constant syntax-language syntax-boolean syntax-yaml\">true</span>\n  <span class=\"syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml\"><span class=\"syntax-entity syntax-name syntax-tag syntax-yaml\">fsdp</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml\">:</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-yaml\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-yaml\">&quot;</span>full_shard auto_wrap<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-yaml\">&quot;</span></span>  <span class=\"syntax-comment syntax-line syntax-number-sign syntax-yaml\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-line syntax-number-sign syntax-yaml\">#</span> Critical for 311M params\n</span></span></span></code></pre>\n<p><strong>Training command:</strong></p>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">torchrun</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> --</span>nproc_per_node</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-option syntax-shell\">=</span>4<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> --</span>master_port</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-option syntax-shell\">=</span>29501 <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span>    scripts/training/run_multispecies_train.py <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>config</span> configs/mrna/production/roberta_large_multispecies.yaml</span>\n</span></span></code></pre>\n<p><strong>Results:</strong></p>\n<table>\n<thead>\n<tr>\n<th>Metric</th>\n<th>Value</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Training time</td>\n<td><strong>48 hours</strong></td>\n<td>4×A100 80GB GPUs</td>\n</tr>\n<tr>\n<td>Final steps</td>\n<td>47,500 / 50,000</td>\n<td>95% complete (max time limit)</td>\n</tr>\n<tr>\n<td>Training loss</td>\n<td>4.10 → 3.17</td>\n<td><strong>23% reduction</strong></td>\n</tr>\n<tr>\n<td>Eval loss</td>\n<td>3.18</td>\n<td>Stable convergence</td>\n</tr>\n<tr>\n<td>Test perplexity</td>\n<td><strong>24.9</strong></td>\n<td>On 19k test sequences</td>\n</tr>\n<tr>\n<td>Synonymous recovery</td>\n<td>11.0%</td>\n<td>Better than single-species</td>\n</tr>\n<tr>\n<td>Model size</td>\n<td>1.2 GB</td>\n<td>Saved with safetensors</td>\n</tr>\n<tr>\n<td>Checkpoints</td>\n<td>5 saved</td>\n<td>Every 2,500 steps</td>\n</tr>\n</tbody>\n</table>\n<p>The test perplexity of 24.9 is higher than our single-species model's 4.01, which might look like a regression. It is not. The multispecies model must learn distinct codon preferences for 25 different organisms, each with its own evolutionary history and tRNA pools. A bacterium like <em>M. tuberculosis</em> (65% GC content) uses completely different codons than human cells (41% GC). The model is solving a fundamentally harder problem, and the perplexity reflects that. What matters is whether species-specific fine-tuning can recover performance, and it does.</p>\n<h3>Species-Specific Fine-Tuning</h3>\n<p>The universal base model is a generalist. For production use, specialists perform better. <strong>OpenMed's</strong> fine-tuning strategy starts from the multispecies checkpoint and trains further on a single species at a lower learning rate (2e-5 vs 5e-5), preserving cross-species knowledge while specializing the model's predictions for one organism.</p>\n<p><strong>Dataset splits:</strong></p>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> scripts/training/split_species_datasets.py\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Automated splitting for 6 priority species\n</span>\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">RESULTS</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span>\n    <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">HUMAN<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">train<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">131_245</span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">test<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">6_908</span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>\n    <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">MOUSE<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">train<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">88_022</span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>  <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">test<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">4_633</span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>\n    <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">CHO<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span>   <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">train<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">42_541</span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>  <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">test<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">2_239</span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>\n    <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">ECOLI<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">train<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">8_547</span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>   <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">test<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">450</span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>\n    <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">YEAST<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">train<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">5_439</span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>   <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">test<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">287</span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>\n    <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">PICHIA<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span><span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">train<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">4_548</span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>   <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\">test<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">240</span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>\n<span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span>\n</span></span></code></pre>\n<p><strong>Training all three priority species:</strong></p>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> HUMAN: Therapeutic mRNA, vaccines</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">torchrun</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> --</span>nproc_per_node</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-option syntax-shell\">=</span>4 scripts/training/run_multispecies_train.py <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>config</span> configs/mrna/production/roberta_large_human_finetune.yaml</span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> ECOLI: Protein expression, metabolic engineering</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">torchrun</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> --</span>nproc_per_node</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-option syntax-shell\">=</span>4 scripts/training/run_multispecies_train.py <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>config</span> configs/mrna/production/roberta_large_ecoli_finetune.yaml</span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> CHO: Biopharmaceutical production</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">torchrun</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> --</span>nproc_per_node</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-option syntax-shell\">=</span>4 scripts/training/run_multispecies_train.py <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>config</span> configs/mrna/production/roberta_large_cho_finetune.yaml</span>\n</span></span></code></pre>\n<p><strong>Comprehensive Results:</strong></p>\n<table>\n<thead>\n<tr>\n<th>Model</th>\n<th>Train Seqs</th>\n<th>Steps</th>\n<th>GPU Hours</th>\n<th>Test Loss</th>\n<th>Perplexity</th>\n<th>vs Multispecies</th>\n<th>Primary Use Case</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Multispecies Base</strong></td>\n<td>362k</td>\n<td>47,500</td>\n<td><strong>48h</strong></td>\n<td>3.18</td>\n<td>24.9</td>\n<td><em>baseline</em></td>\n<td>Universal optimization</td>\n</tr>\n<tr>\n<td><strong>HUMAN</strong></td>\n<td>131k</td>\n<td>15,000</td>\n<td><strong>4h</strong></td>\n<td>3.16</td>\n<td><strong>24.3</strong></td>\n<td><strong>2.4% better</strong></td>\n<td>mRNA therapeutics, vaccines</td>\n</tr>\n<tr>\n<td><strong>ECOLI</strong></td>\n<td>8.5k</td>\n<td>5,000</td>\n<td><strong>0.5h</strong></td>\n<td>3.17</td>\n<td><strong>25.3</strong></td>\n<td><strong>1.6% better</strong></td>\n<td>Recombinant proteins</td>\n</tr>\n<tr>\n<td><strong>CHO</strong></td>\n<td>42.5k</td>\n<td>10,000</td>\n<td><strong>2.5h</strong></td>\n<td>3.21</td>\n<td><strong>25.5</strong></td>\n<td>2.4% worse</td>\n<td>Antibody production</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td><strong>Total: 55h</strong></td>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n</tbody>\n</table>\n<p>The most important result here is the HUMAN model: at 24.3 perplexity, it is the only specialist that beats the universal base, making it our production model for therapeutic mRNA applications. But the ECOLI result is arguably more interesting from a research perspective. With only 8,547 training sequences (compared to 131k for human), the <em>E. coli</em> specialist still improved over the multispecies base. This validates the transfer learning hypothesis: training on 25 species first, then fine-tuning on a small species-specific dataset, works better than training on the small dataset alone. For the many organisms where annotated CDS data is scarce, this approach opens the door to reasonable codon optimization without needing tens of thousands of species-specific sequences.</p>\n<p>The CHO model showed slight degradation (25.5 vs 24.9), which we attribute to insufficient training steps. ECOLI got 5,000 steps for 8.5k sequences (0.59 steps per sequence), while CHO got 10,000 steps for 42.5k sequences (0.24 steps per sequence). A rerun with 15,000 steps should close this gap. All three specialists fine-tuned in just 7 hours total, leveraging the 48-hour investment in the multispecies base.</p>\n<h3>The Complete Model Suite</h3>\n<p>After 55 hours of training, we have:</p>\n<p>All models will be released on Hugging Face under the <strong>OpenMed</strong> organization. The naming convention follows <code>OpenMed/{model-name}</code> for direct use with <code>from_pretrained()</code>.</p>\n<p><strong>Universal Models:</strong></p>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/OpenMed/CodonRoBERTa-large-multispecies\"><code>OpenMed/CodonRoBERTa-large-multispecies</code></a> (311.9M params)\n<ul>\n<li>Trained on 25 species</li>\n<li>Perplexity: 24.9</li>\n<li>Use case: Cross-species optimization, rare organisms</li>\n</ul>\n</li>\n</ul>\n<p><strong>Species-Specific Specialists:</strong></p>\n<ul>\n<li>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/OpenMed/CodonRoBERTa-large-human\"><code>OpenMed/CodonRoBERTa-large-human</code></a> (311.9M params)</p>\n<ul>\n<li>Perplexity: 24.3 (<strong>best overall</strong>)</li>\n<li>Use case: mRNA vaccines, gene therapy, therapeutic proteins</li>\n</ul>\n</li>\n<li>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/OpenMed/CodonRoBERTa-large-ecoli\"><code>OpenMed/CodonRoBERTa-large-ecoli</code></a> (311.9M params)</p>\n<ul>\n<li>Perplexity: 25.3</li>\n<li>Use case: Bacterial protein expression, metabolic engineering</li>\n</ul>\n</li>\n<li>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/OpenMed/CodonRoBERTa-large-cho\"><code>OpenMed/CodonRoBERTa-large-cho</code></a> (311.9M params)</p>\n<ul>\n<li>Perplexity: 25.5</li>\n<li>Use case: Mammalian cell culture, biopharmaceuticals</li>\n</ul>\n</li>\n</ul>\n<p><strong>Single-Species Models:</strong></p>\n<ul>\n<li>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/OpenMed/CodonRoBERTa-large-v2\"><code>OpenMed/CodonRoBERTa-large-v2</code></a> (312M params)</p>\n<ul>\n<li>Perplexity: 4.10, CAI: 0.404</li>\n<li>Trained on 250k <em>E. coli</em> only</li>\n<li>Still the best for pure <em>E. coli</em> optimization</li>\n</ul>\n</li>\n<li>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/OpenMed/CodonRoBERTa-base\"><code>OpenMed/CodonRoBERTa-base</code></a> (92M params)</p>\n<ul>\n<li>Perplexity: 4.01, CAI: 0.219</li>\n<li>Best efficiency option (3.4x smaller than large)</li>\n</ul>\n</li>\n</ul>\n<h3>Production Deployment Strategy</h3>\n<p><strong>For therapeutic mRNA (Moderna, BioNTech-style vaccines):</strong></p>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-from syntax-python\">from</span></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-meta syntax-import-source syntax-python\"> <span class=\"syntax-meta syntax-import-path syntax-python\"><span class=\"syntax-meta syntax-import-name syntax-python\">transformers</span></span> <span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-python\">import</span></span></span></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"> <span class=\"syntax-meta syntax-generic-name syntax-python\">RobertaForMaskedLM</span></span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Load human-optimized model\n</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">model</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">RobertaForMaskedLM</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">from_pretrained</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">OpenMed/CodonRoBERTa-large-human<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Optimize amino acid sequence to DNA\n</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">optimized_dna</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">optimize_for_human</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">protein_seq</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">model</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n</span></span></code></pre>\n<p><strong>For industrial protein production:</strong></p>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> E. coli expression\n</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">model_ecoli</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">RobertaForMaskedLM</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">from_pretrained</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">OpenMed/CodonRoBERTa-large-ecoli<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> CHO cell expression\n</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">model_cho</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">RobertaForMaskedLM</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">from_pretrained</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">OpenMed/CodonRoBERTa-large-cho<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n</span></span></code></pre>\n<p><strong>For rare/unmodeled organisms:</strong></p>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Use multispecies base with species conditioning\n</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">model_multi</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">RobertaForMaskedLM</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">from_pretrained</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">OpenMed/CodonRoBERTa-large-multispecies<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Prepend species token: [YEAST], [PICHIA], [MOUSE], etc.\n</span></span></span></code></pre>\n<h3>Infrastructure &amp; Reproducibility</h3>\n<p><strong>Hardware requirements:</strong></p>\n<ul>\n<li>4×A100 80GB GPUs (training)</li>\n<li>Single A100 40GB (inference)</li>\n<li>FSDP (Fully Sharded Data Parallel) for 311M params</li>\n<li>bf16 mixed precision (critical for stability)</li>\n</ul>\n<p><strong>Storage footprint:</strong></p>\n<ul>\n<li>~150 GB total (data, trained models, and checkpoints across all runs)</li>\n</ul>\n<p><strong>Complete training pipeline:</strong></p>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> 1. Download multi-species data (automated)</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">python</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> scripts/training/download_multispecies_cds.py <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>output_dir</span> data/mrna/multispecies <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>categories</span> bacteria yeast mammals</span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> 2. Train universal base (48 hours)</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">torchrun</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> --</span>nproc_per_node</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-option syntax-shell\">=</span>4 <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span>    scripts/training/run_multispecies_train.py <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>config</span> configs/mrna/production/roberta_large_multispecies.yaml</span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> 3. Split species datasets</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">python</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> scripts/training/split_species_datasets.py <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>input</span> data/mrna/multispecies/train_multispecies.fasta <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">    --</span>output_dir</span> data/mrna/species_specific</span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> 4. Fine-tune specialists (7 hours total)</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-keyword syntax-control syntax-for syntax-shell\">for</span><span class=\"syntax-meta syntax-group syntax-for syntax-shell\"> species <span class=\"syntax-keyword syntax-control syntax-in syntax-shell\">in</span> human ecoli cho</span><span class=\"syntax-keyword syntax-operator syntax-logical syntax-continue syntax-shell\">;</span> <span class=\"syntax-keyword syntax-control syntax-do syntax-shell\">do</span>\n    <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">torchrun</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> --</span>nproc_per_node</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-option syntax-shell\">=</span>4 <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span>        scripts/training/run_multispecies_train.py <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">        --</span>config</span> configs/mrna/production/roberta_large_<span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-punctuation syntax-section syntax-expansion syntax-parameter syntax-begin syntax-shell\">{</span></span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">species</span></span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-section syntax-expansion syntax-parameter syntax-end syntax-shell\">}</span></span>_finetune.yaml</span>\n<span class=\"syntax-keyword syntax-control syntax-done syntax-shell\">done</span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> 5. Evaluate all models</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span><span class=\"syntax-keyword syntax-control syntax-for syntax-shell\">for</span><span class=\"syntax-meta syntax-group syntax-for syntax-shell\"> model <span class=\"syntax-keyword syntax-control syntax-in syntax-shell\">in</span> multispecies human ecoli cho</span><span class=\"syntax-keyword syntax-operator syntax-logical syntax-continue syntax-shell\">;</span> <span class=\"syntax-keyword syntax-control syntax-do syntax-shell\">do</span>\n    <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">python</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> scripts/evals/advanced/eval_perplexity_multispecies.py <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">        --</span>model_path</span> outputs/models/CodonRoBERTa-large-<span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-punctuation syntax-section syntax-expansion syntax-parameter syntax-begin syntax-shell\">{</span></span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">model</span></span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-section syntax-expansion syntax-parameter syntax-end syntax-shell\">}</span></span>/final <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">        --</span>test_file</span> data/mrna/species_specific/<span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-punctuation syntax-section syntax-expansion syntax-parameter syntax-begin syntax-shell\">{</span></span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">model</span></span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-section syntax-expansion syntax-parameter syntax-end syntax-shell\">}</span></span>_test.fasta <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">        --</span>output_file</span> outputs/evals/<span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-variable syntax-shell\">$</span><span class=\"syntax-punctuation syntax-section syntax-expansion syntax-parameter syntax-begin syntax-shell\">{</span></span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-variable syntax-other syntax-readwrite syntax-shell\">model</span></span><span class=\"syntax-meta syntax-group syntax-expansion syntax-parameter syntax-shell\"><span class=\"syntax-punctuation syntax-section syntax-expansion syntax-parameter syntax-end syntax-shell\">}</span></span>_perplexity.json</span>\n<span class=\"syntax-keyword syntax-control syntax-done syntax-shell\">done</span>\n</span></span></code></pre>\n<p><strong>Total compute cost:</strong></p>\n<ul>\n<li>55 GPU-hours on A100 80GB (~$165 on AWS p4d.24xlarge)</li>\n<li>All models trained to convergence in under 3 days wall-clock time</li>\n</ul>\n<h3>What This Enables</h3>\n<p>The multi-species suite covers the three pillars of applied codon optimization. For therapeutic mRNA, the HUMAN specialist model optimizes codons for expression in human cells, directly applicable to vaccine design (Moderna and BioNTech both codon-optimize their mRNA constructs) and gene therapy vectors. For recombinant protein production, the ECOLI specialist handles the most common bacterial expression host, while the CHO specialist covers the mammalian cell line used to produce most monoclonal antibodies and biopharmaceuticals. For organisms not covered by a specialist, the multispecies base model accepts any of the 25 species tokens and generates organism-appropriate codons.</p>\n<p>The transfer learning result is particularly relevant for the broader community. Many industrially important organisms (non-model bacteria, insect cells, plant cells) have limited annotated CDS data. Our results with <em>E. coli</em> (8.5k sequences, improved over base) suggest that multispecies pre-training followed by small-scale fine-tuning is a viable path for these organisms, without requiring the tens or hundreds of thousands of sequences that training from scratch demands.</p>\n<h3>By the Numbers</h3>\n<p>The full project consumed 55 GPU-hours on 4 A100 80GB GPUs (~$165 at AWS spot pricing), produced ~150 GB of models and checkpoints across 4 training runs, and covers 381,283 CDS sequences from 25 species downloaded from NCBI RefSeq. All models use the same 311.9M-parameter architecture, are saved in safetensors format for fast loading, and run inference on a single GPU with 16GB+ VRAM. Everything is released under Apache 2.0.</p>\n<hr />\n<h2>5. The End-to-End Workflow</h2>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/ZAHq19e94YYQ0ixlnPg5I.jpeg\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/ZAHq19e94YYQ0ixlnPg5I.jpeg\" alt=\"The two-step protein design paradigm: generate backbone structure, then optimize sequence\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></a></p>\n<p><em>The modern computational protein design workflow. Structure generation (top) produces backbone coordinates; sequence optimization (bottom) finds amino acid sequences that fold into the target shape. Our pipeline adds a third step: codon optimization for expression. Figure from Kortemme, Cell 2024, CC-BY 4.0.</em></p>\n<p>In Part I, we described the protein engineering loop as a cycle of prediction, design, and optimization. Here is what that looks like in practice with <strong>OpenMed's</strong> pipeline. Each step feeds into the next, and the entire computational phase runs in an afternoon on a single GPU.</p>\n<p>Consider a concrete scenario: engineering a more stable version of a therapeutic enzyme that degrades too quickly in the bloodstream.</p>\n<p><strong>Step 1: Fold (ESMFold).</strong> Predict the structure of the starting sequence to understand its active site and identify regions that might be destabilized. ESMFold returns a 3D structure in PDB format, per-residue confidence scores (pLDDT) highlighting uncertain regions, and an overall topology confidence metric (PTM).</p>\n<p><strong>Step 2: Design (ProteinMPNN).</strong> Keep the active site fixed but redesign the scaffold for improved stability. ProteinMPNN takes the backbone coordinates, a list of immutable positions (catalytic residues), and generates 100 diverse candidate sequences, each predicted to fold into the target shape.</p>\n<p><strong>Step 3: Verify (ESMFold).</strong> Refold all 100 candidates with ESMFold to confirm they still adopt the correct shape. Filter for high mean pLDDT (&gt;80), correct topology (RMSD to original), and low clash scores.</p>\n<p><strong>Step 4: Optimize (CodonRoBERTa).</strong> Take the best amino acid sequences and use CodonRoBERTa-large-v2 to generate optimal DNA sequences for expression in the target organism (<em>E. coli</em>, yeast, or mammalian cells). The model scores synonymous codon choices based on learned biological preferences, identifies contextually optimal codons rather than just globally frequent ones, and produces sequences with high CAI correlation.</p>\n<p><strong>Step 5: Synthesize and Test.</strong> Order the DNA from a synthesis company, clone it into an expression vector, and test expression and activity in the lab.</p>\n<p>This loop, from hypothesis to synthesis-ready DNA, replaces what once took months of iterative wet-lab trial and error. A researcher arrives at the bench with 5-10 computationally vetted candidates instead of one or two educated guesses. The success rate improves, the cost drops, and the design cycle compresses from months to days.</p>\n<hr />\n<p>For a full ecosystem overview, tool selection guide, and license reference, see Part I.</p>\n<hr />\n<h2>6. Where This Stands and What's Next</h2>\n<h3>The Landscape</h3>\n<p><strong>OpenMed</strong> is not working in isolation. Two recent models push the codon/mRNA modeling frontier further:</p>\n<ul>\n<li>\n<p><strong>mRNABERT</strong> (Xiong et al., <em>Nature Communications</em> 2025): 86M-param BERT with a dual tokenization scheme (single nucleotides for UTRs, codons for CDS) and cross-modality contrastive learning against frozen ProtT5-XL protein embeddings. Trained on 18M sequences. Achieves R^2 = 0.66 on full-length mRNA translation efficiency, a 1.6-10x improvement over prior RNA models. Code and weights available (Apache 2.0).</p>\n</li>\n<li>\n<p><strong>NUWA</strong> (Zhong et al., <em>bioRxiv</em> 2026): Three domain-specific RoBERTa encoders (Bacteria, Eukaryota, Archaea) with curriculum MLM and supervised contrastive learning. Trained on 115M sequences across ~25,000 species. Beats CodonBERT on 11/13 BEACON benchmark tasks. No code or weights released.</p>\n</li>\n</ul>\n<p>Both models train on 50-300x more data than <strong>OpenMed</strong> used. That is the primary gap, and we are transparent about it.</p>\n<p>Here is what <strong>OpenMed</strong> does that neither of them offers:</p>\n<ol>\n<li>\n<p><strong>Species-conditioned single model.</strong> mRNABERT has no species conditioning at all. NUWA trains three separate models (one per domain of life). We put 25 species tokens into one 94-token vocabulary and train a single model that can be prompted for any organism. More parameter-efficient, more flexible.</p>\n</li>\n<li>\n<p><strong>Transfer learning to low-resource organisms, validated.</strong> We showed that fine-tuning the multispecies base on just 8.5k <em>E. coli</em> sequences improves over the base model. Neither mRNABERT nor NUWA demonstrates this.</p>\n</li>\n<li>\n<p><strong>Full open-source pipeline.</strong> ESMFold + ProteinMPNN + CodonRoBERTa, end to end, with training code, configs, eval scripts, and model weights. All Apache 2.0. mRNABERT releases code but not the pipeline. NUWA releases nothing.</p>\n</li>\n</ol>\n<h3>In Progress: CodonJEPA</h3>\n<p><strong>OpenMed</strong> is running a proof-of-concept for a fundamentally different approach: <strong>Joint Embedding Predictive Architecture (JEPA) for codon sequences</strong>.</p>\n<p>Standard MLM predicts masked <em>tokens</em>. JEPA predicts masked <em>embeddings</em>. The hypothesis: if the model is forced to predict in embedding space rather than token space, it should learn that synonymous codons (different DNA, same amino acid) are functionally equivalent. MLM cannot achieve this because it is trained to distinguish every token.</p>\n<p>The architecture:</p>\n<ul>\n<li><strong>Context encoder</strong>: RoBERTa-base (768-dim, 12 layers), trained normally</li>\n<li><strong>Target encoder</strong>: EMA copy of the context encoder (momentum 0.990 to 0.999, no gradients)</li>\n<li><strong>Predictor</strong>: Lightweight 4-layer transformer (384-dim), predicts target embeddings from context</li>\n<li><strong>Masking</strong>: Multi-block strategy (4 contiguous blocks per sequence, 15-20% mask scale)</li>\n<li><strong>Collapse prevention</strong>: VICReg regularization (variance + covariance loss)</li>\n</ul>\n<p>Early results from our evaluation suite (JEPA vs. MLM baseline, same data, same hyperparameters, 15k steps each):</p>\n<table>\n<thead>\n<tr>\n<th>Metric</th>\n<th>CodonJEPA</th>\n<th>CodonMLM</th>\n<th>Winner</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Synonymous robustness (cosine sim)</td>\n<td><strong>0.9997</strong></td>\n<td>0.9414</td>\n<td>JEPA</td>\n</tr>\n<tr>\n<td>Codon-to-amino-acid probe</td>\n<td>37.4%</td>\n<td>100%</td>\n<td>MLM (expected)</td>\n</tr>\n<tr>\n<td>Taxonomy classification</td>\n<td>87.8%</td>\n<td>99.4%</td>\n<td>MLM</td>\n</tr>\n<tr>\n<td>Effective dimensionality</td>\n<td>1.67</td>\n<td>18.71</td>\n<td>MLM</td>\n</tr>\n</tbody>\n</table>\n<p>The synonymous robustness result is the one that matters most for our hypothesis. JEPA embeddings are nearly identical (99.97% cosine similarity) for sequences that differ only in synonymous codon choices. MLM embeddings shift significantly (94.14%). This means JEPA <em>does</em> learn that synonymous codons are interchangeable, exactly as predicted.</p>\n<p>The open challenge: JEPA currently suffers from dimensional collapse (91.78% of variance concentrated in one component). This is a known failure mode for self-supervised methods and suggests the VICReg regularization weights need tuning. The architecture works; the training dynamics need more iteration.</p>\n<p>This is early-stage research, not production-ready. But if the collapse problem can be solved, JEPA could produce codon embeddings that are inherently amino-acid-aware, something that MLM, by its token-level prediction objective, fundamentally cannot achieve.</p>\n<h3>Roadmap</h3>\n<p><strong>CodonRoBERTa (scaling up)</strong>:</p>\n<ul>\n<li>Retrain on mRNABERT's public 36M-sequence dataset (Zenodo). Same architecture, same species tokens, 100x more data</li>\n<li>Add cross-modality contrastive alignment with ProtT5-XL (proven by mRNABERT to boost protein property prediction)</li>\n<li>Extend species-specific fine-tuning to YEAST, PICHIA, MOUSE</li>\n<li>Add mRNA stability and immunogenicity prediction heads</li>\n</ul>\n<p><strong>CodonJEPA (fixing and scaling)</strong>:</p>\n<ul>\n<li>Solve dimensional collapse (stronger VICReg weights, alternative regularizers)</li>\n<li>Benchmark against mRNABERT's contrastive approach on the same downstream tasks</li>\n<li>If JEPA embeddings hold up, integrate as a drop-in replacement for MLM embeddings in the pipeline</li>\n</ul>\n<p><strong>Pipeline</strong>:</p>\n<ul>\n<li>Integrate RFdiffusion for <em>de novo</em> backbone generation</li>\n<li>Add solubility and expression prediction heads</li>\n<li>Fine-tune ESMFold on specialized domains (antibodies, enzymes)</li>\n</ul>\n<h3>Setup and Requirements</h3>\n<p><strong>Hardware</strong>:</p>\n<ul>\n<li>Tested on 4×A100 GPUs (80GB)</li>\n<li>Folding inference: ~16-20GB VRAM for typical proteins</li>\n<li>Training: Scales with FSDP (Fully Sharded Data Parallel)</li>\n<li>Minimum for inference: Single GPU with 16GB+ VRAM</li>\n</ul>\n<p><strong>Environment</strong>:</p>\n<ul>\n<li>Use <code>.env_esmfold</code> virtual environment for folding</li>\n<li>For training: PyTorch 2.5.1+cu121 with flash-attn2</li>\n<li>Python 3.10+ recommended</li>\n</ul>\n<p><strong>Licenses</strong> (all commercial-friendly):</p>\n<ul>\n<li>ESMFold: MIT</li>\n<li>ProteinMPNN: MIT</li>\n<li>OpenFold: Apache-2.0</li>\n<li>Our CodonRoBERTa: Apache-2.0</li>\n</ul>\n<hr />\n<h2>7. References</h2>\n<p><strong>OpenMed's</strong> work builds on foundational research from Meta AI, the Baker Lab at the University of Washington, DeepMind, and the broader open-source computational biology community.</p>\n<h3>Key Papers</h3>\n<p><strong>Protein Structure Prediction</strong></p>\n<ul>\n<li>Jumper, J. et al. &quot;Highly accurate protein structure prediction with AlphaFold.&quot; <em>Nature</em> (2021). <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://doi.org/10.1038/s41586-021-03819-2\">DOI</a></li>\n<li>Lin, Z. et al. &quot;Evolutionary-scale prediction of atomic-level protein structure with a language model.&quot; <em>Science</em> (2023). <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://doi.org/10.1126/science.ade2574\">DOI</a></li>\n<li>Ahdritz, G. et al. &quot;OpenFold: Retraining AlphaFold2 yields new insights.&quot; <em>Nature Methods</em> (2024). <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://doi.org/10.1038/s41592-024-02272-z\">DOI</a></li>\n</ul>\n<p><strong>Protein Design</strong></p>\n<ul>\n<li>Dauparas, J. et al. &quot;Robust deep learning-based protein sequence design using ProteinMPNN.&quot; <em>Science</em> (2022). <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://doi.org/10.1126/science.add2187\">DOI</a></li>\n<li>Watson, J.L. et al. &quot;De novo design of protein structure and function with RFdiffusion.&quot; <em>Nature</em> (2023). <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://doi.org/10.1038/s41586-023-06415-8\">DOI</a></li>\n</ul>\n<p><strong>mRNA &amp; Codon Optimization</strong></p>\n<ul>\n<li>Cheng, J. et al. &quot;CodonBERT: a language model for codon optimization.&quot; <em>Nucleic Acids Research</em> (2024). <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://doi.org/10.1093/nar/gkae495\">DOI</a></li>\n<li>Xiong, Y. et al. &quot;mRNABERT: advancing mRNA sequence design with a universal language model and comprehensive dataset.&quot; <em>Nature Communications</em> (2025). <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://doi.org/10.1038/s41467-025-65340-8\">DOI</a></li>\n<li>Zhong, Y. et al. &quot;Large mRNA language foundation modeling with NUWA for unified sequence perception and generation.&quot; <em>bioRxiv</em> (2026). <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://doi.org/10.1101/2025.11.01.686058\">DOI</a></li>\n<li>Warner, B. et al. &quot;ModernBERT: Smarter, Better, Faster, Longer.&quot; arXiv (2024). <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://arxiv.org/abs/2412.13663\">arXiv</a></li>\n</ul>\n<hr />\n<h2>Models and Data: Coming Soon</h2>\n<p>All models, training code, and the multi-species dataset described in this post will be publicly released under the <strong>OpenMed</strong> organization on Hugging Face under Apache 2.0 / MIT licenses.</p>\n<p><strong>Models</strong> (7 checkpoints):</p>\n<table>\n<thead>\n<tr>\n<th>Model</th>\n<th>Params</th>\n<th>HuggingFace</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>CodonRoBERTa-large-v2</td>\n<td>312M</td>\n<td><code>OpenMed/CodonRoBERTa-large-v2</code></td>\n</tr>\n<tr>\n<td>CodonRoBERTa-base</td>\n<td>92M</td>\n<td><code>OpenMed/CodonRoBERTa-base</code></td>\n</tr>\n<tr>\n<td>CodonRoBERTa-large-multispecies</td>\n<td>311.9M</td>\n<td><code>OpenMed/CodonRoBERTa-large-multispecies</code></td>\n</tr>\n<tr>\n<td>CodonRoBERTa-large-human</td>\n<td>311.9M</td>\n<td><code>OpenMed/CodonRoBERTa-large-human</code></td>\n</tr>\n<tr>\n<td>CodonRoBERTa-large-ecoli</td>\n<td>311.9M</td>\n<td><code>OpenMed/CodonRoBERTa-large-ecoli</code></td>\n</tr>\n<tr>\n<td>CodonRoBERTa-large-cho</td>\n<td>311.9M</td>\n<td><code>OpenMed/CodonRoBERTa-large-cho</code></td>\n</tr>\n</tbody>\n</table>\n<p><strong>Dataset</strong>:</p>\n<table>\n<thead>\n<tr>\n<th>Dataset</th>\n<th>Sequences</th>\n<th>Species</th>\n<th>HuggingFace</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Multi-species CDS</td>\n<td>381,283</td>\n<td>25</td>\n<td><code>OpenMed/multispecies-codon-dataset</code></td>\n</tr>\n</tbody>\n</table>\n<p><strong>Training code and evaluation scripts</strong> will be released alongside the models.</p>\n<p>Follow <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/OpenMed\"><strong>OpenMed</strong> on Hugging Face</a> to be notified when models go live.</p>\n<hr />\n<p><em>The ML Engineer's Guide to Protein AI: From Protein to Optimized DNA | March 2026</em></p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/MaziyarPanahi/protein-ai-landscape\"><strong>Read Part I</strong>: The AlphaFold Revolution, covering the landscape of protein AI.</a></p>\n<p><em>Questions or collaboration ideas? Reach out on Hugging Face or open a discussion on the model pages.</em></p>\n",
  "content_markdown": "## Part II: Building the Pipeline, From Structure Prediction to Codon Optimization\n\n*By OpenMed, Open-Source Agentic AI for Healthcare & Life Sciences*\n\n* * *\n\n> **TL;DR**: We built an end-to-end protein AI pipeline covering structure prediction, sequence design, and codon optimization. After comparing multiple transformer architectures for codon-level language modeling, **CodonRoBERTa-large-v2** emerged as the clear winner with a perplexity of 4.10 and a Spearman CAI correlation of 0.40, significantly outperforming ModernBERT. We then scaled to 25 species, trained 4 production models in 55 GPU-hours, and built a species-conditioned system that no other open-source project offers. Complete results, architectural decisions, and runnable code below.\n\n**Contents**\n\n1. [What We Built](https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#1-what-we-built)\n2. [The Architecture Exploration](https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#2-the-architecture-exploration)\n3. [The Pipeline](https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#3-the-pipeline)\n   - [3.1 Protein Folding](https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#31-protein-folding-with-esmfold)\n   - [3.2 Sequence Design](https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#32-sequence-design-with-proteinmpnn)\n   - [3.3 mRNA Optimization](https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#33-mrna-optimization)\n4. [Scaling to Multi-Species](https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#4-scaling-to-multi-species)\n5. [The End-to-End Workflow](https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#5-the-end-to-end-workflow)\n6. [Where This Stands and What's Next](https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#6-where-this-stands-and-whats-next)\n7. [References](https://huggingface.co/blog/OpenMed/training-mrna-models-25-species#7-references)\n\n* * *\n\nImagine going from a therapeutic protein concept to a synthesis-ready, codon-optimized DNA sequence in an afternoon. That is the pipeline **OpenMed** set out to build, and this post documents the process from start to finish.\n\nIn Part I, we mapped the landscape of protein AI: the architectures powering structure prediction, the open-source tools available for protein design, and the ecosystem of models from AlphaFold to ESMFold. That was a survey. This is the build.\n\nAt **OpenMed**, we set out to build a complete pipeline that takes a protein idea from concept to expression-ready DNA. That means three stages: predict the 3D structure of a protein, design amino acid sequences that fold into that structure, and optimize the underlying DNA codons so the protein actually expresses in the target organism. Along the way, we ran extensive experiments comparing transformer architectures for codon optimization, scaled our best model to 25 species, and built tooling that ties it all together.\n\nThis is not a polished success story. It is a transparent account of what worked, what surprised us, and what we would do differently, with runnable code and full results at every step.\n\n* * *\n\n## 1. What We Built\n\nThe pipeline has three components, each addressing a different stage of the protein engineering workflow described in Part I. Structure prediction determines *what shape* a protein takes. Sequence design determines *which amino acids* will produce that shape. Codon optimization determines *which DNA* will produce those amino acids efficiently in a living cell.\n\n| Component             | What We Did                                                                                        | Key Result                                                                                                                   |\n| --------------------- | -------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |\n| **Protein Folding**   | ESMFold v1 predictions on 30 protein chains                                                        | Avg PTM: 0.79, working batch pipeline                                                                                        |\n| **Sequence Design**   | ProteinMPNN on scaffold 7K00                                                                       | 42% sequence recovery                                                                                                        |\n| **mRNA Optimization** | Trained multiple transformer variants on 250k CDS, then scaled to 381k sequences across 25 species | **CodonRoBERTa-large-v2**: perplexity 4.10, CAI 0.40; **Multi-species suite**: 4 models spanning 25 organisms (55 GPU-hours) |\n\nThe mRNA optimization work is where we invested the most effort, and where we have the most to share. The folding and design components use established tools (ESMFold from Meta, ProteinMPNN from the Baker Lab, both covered in depth in Part I). The codon optimization component is entirely ours: new models, new training infrastructure, new evaluation metrics.\n\n## 2. The Architecture Exploration\n\nIn Part I, we surveyed the protein AI landscape and noted that most biological language models are adaptations of NLP architectures. The open question was *which* architecture. BERT variants dominate protein modeling (ESM-2, ProtTrans), but codon sequences have different statistical properties than both natural language and amino acid sequences. Codons are triplets drawn from a small 64-token alphabet, with strong positional dependencies and species-specific usage biases. We needed to find out what works from first principles.\n\nThe core question: which transformer architecture works best for codon-level language modeling?\n\nThis matters because codon optimization is crucial for therapeutic mRNA, vaccines, and recombinant protein production. The genetic code is degenerate: the same protein can be encoded by astronomically many different DNA sequences, but some codon arrangements express 100x better than others. The Pfizer-BioNTech COVID vaccine, for example, was codon-optimized for human expression. We wanted to build a model that could learn these preferences directly from natural coding sequences, rather than relying on hand-crafted frequency tables.\n\n### The Contenders\n\nWe started with a small CodonBERT baseline (6M params, following Sanofi's published architecture) and scaled up through two families: ModernBERT, which represented the latest efficiency innovations from the NLP community, and RoBERTa, the proven workhorse behind Meta's ESM protein language models.\n\n| Model                     | Parameters | Architecture                 | Hypothesis                                            |\n| ------------------------- | ---------- | ---------------------------- | ----------------------------------------------------- |\n| **CodonBERT (baseline)**  | 6M         | BERT-tiny (6 layers)         | Minimal baseline to establish floor performance       |\n| **ModernBERT-base**       | 90M        | ModernBERT (22 layers, RoPE) | Modern innovations: long context, efficient attention |\n| **CodonRoBERTa-base**     | 92M        | RoBERTa (12 layers)          | Proven MLM architecture, same family as ESM-2         |\n| **CodonRoBERTa-large**    | 312M       | RoBERTa (24 layers)          | Test whether more parameters improve codon modeling   |\n| **CodonRoBERTa-large-v2** | 312M       | RoBERTa (24 layers, refined) | Same architecture, better hyperparameters             |\n\nThe choice of RoBERTa was deliberate. As we discussed in Part I, Meta's ESM-2 (which powers ESMFold) is itself a RoBERTa variant trained on protein sequences. We hypothesized that the same architecture family that learned amino acid patterns might also learn codon patterns. ModernBERT was the counterpoint: a 2024 architecture with RoPE embeddings, Flash Attention, and alternating local/global attention layers, representing everything the NLP community had learned since RoBERTa's 2019 release.\n\n### The Training Setup\n\nTo ensure a fair comparison, every model was trained on identical data with the same evaluation protocol. We used 250,000 coding sequences (CDS) from *E. coli* RefSeq, covering chromosome and complete assembly accessions. This is a clean, well-annotated dataset where codon usage patterns are well-characterized in the literature, giving us ground truth to validate against.\n\nOur tokenizer maps each codon to a single token: 64 codons plus 5 special tokens (PAD, UNK, CLS, SEP, MASK) for a 69-token vocabulary. This is intentionally minimal. Unlike BPE tokenizers used in NLP, where subword boundaries are statistically learned, codon boundaries are biologically defined. Every three nucleotides encode one amino acid. Our tokenizer respects this.\n\nTraining ran on 4 A100 GPUs (80GB) with FSDP sharding, using 15,000 to 25,000 steps depending on model size. All models used masked language modeling (MLM) with 15% masking rate, the same objective used by ESM-2 for protein sequences.\n\n### The Results\n\n| Model                     | Perplexity | CAI Spearman | Synonymous Recovery | Status              |\n| ------------------------- | ---------- | ------------ | ------------------- | ------------------- |\n| **CodonRoBERTa-large-v2** | 4.10       | **0.404**    | 7.7%                | **Best Overall**    |\n| **CodonRoBERTa-base**     | **4.01**   | 0.219        | **8.5%**            | **Best Efficiency** |\n| CodonRoBERTa-large        | 4.01       | 0.025        | 7.6%                | Good MLM, weak bio  |\n| ModernBERT-base           | 26.24      | 0.070        | 8.5%                | Underperformed      |\n| CodonBERT (baseline)      | 17.18      | -0.629       | 0.0%                | Baseline            |\n\nThe result was unambiguous: RoBERTa outperformed ModernBERT by 6x on perplexity (4.01 vs 26.24). This was not a marginal difference. ModernBERT, despite its modern attention patterns and efficient architecture, fundamentally underperformed the classic RoBERTa design on codon sequences.\n\n### What We Learned\n\n**1\\. Pre-trained NLP weights do not transfer to biology**\n\nWe initialized ModernBERT from its published English-language checkpoint, expecting the learned attention patterns to provide a useful starting point. They did not. Our best explanation: ModernBERT's pre-training on English text instilled inductive biases (subword frequency distributions, positional attention patterns) that actively interfere with learning codon statistics. RoBERTa, initialized randomly and trained purely on biological data, had no such baggage. This aligns with what the field has seen more broadly: ESM-2 and ProtTrans both train from scratch on biological data rather than fine-tuning from NLP checkpoints.\n\n**2\\. Hyperparameter tuning unlocked biological alignment**\n\nThis was the most surprising and practically important finding of the exploration. Compare CodonRoBERTa-large v1 and v2:\n\n| Version                     | Perplexity | CAI Spearman |\n| --------------------------- | ---------- | ------------ |\n| v1 (lr=1e-4)                | 4.01       | 0.025        |\n| v2 (lr=5e-5, longer warmup) | 4.10       | **0.404**    |\n\nSame architecture. Same data. Same number of parameters. The only differences: half the learning rate and a longer warmup (2,000 steps vs 1,000). Yet v2's predicted codon likelihoods are **16x better correlated with real biological codon preferences**, as measured by Codon Adaptation Index.\n\nThe perplexity actually got slightly *worse* (4.10 vs 4.01), which means v2 is marginally less accurate at predicting the exact masked codon. But it is dramatically better at predicting codons that biology actually uses. The slower training schedule let the model settle into representations that capture genuine biological signal rather than overfitting to surface statistics.\n\nThis is a crucial insight for anyone training biological language models: **MLM loss alone does not measure biological relevance.** Domain-specific metrics are essential. In our case, CAI correlation turned out to be the metric that separates a useful model from a technically impressive but biologically meaningless one.\n\n**3\\. The base model is remarkably efficient**\n\nCodonRoBERTa-base (92M params) achieved nearly identical perplexity to the large model (4.01 vs 4.10) with 3.4x fewer parameters and proportionally less training time. Its CAI correlation (0.219) is lower than v2's (0.404), but still well above the baseline and ModernBERT. For teams without access to multi-GPU clusters, the base model is a practical choice that captures most of the codon modeling performance at a fraction of the cost.\n\n## 3. The Pipeline\n\nIn Part I, we described the three-stage workflow that most computational protein engineering projects follow: predict structure, design sequences, optimize codons. Here we run each stage with real data and report what we actually got.\n\n1. **Fold**: Predict the 3D structure (ESMFold)\n2. **Design**: Generate sequences that fold into that structure (ProteinMPNN)\n3. **Optimize**: Choose the best codons for expression (CodonRoBERTa)\n\n* * *\n\n### 3.1 Protein Folding with ESMFold\n\n[![ESMFold Architecture: single-sequence structure prediction using the ESM-2 protein language model](https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/ty2O24OhgfrFHJJUTl7dG.jpeg)](https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/ty2O24OhgfrFHJJUTl7dG.jpeg)\n\n*ESMFold architecture. The model parses a single amino acid sequence through the ESM-2 encoder, then predicts 3D coordinates via a folding trunk and structure module. Figure from Bertoline et al., Biomolecules 2024, CC-BY 4.0.*\n\nAs covered in Part I, ESMFold is Meta's single-sequence structure predictor. It uses ESM-2, a 15-billion-parameter protein language model trained on 65 million UniRef sequences, as its backbone. The key advantage over AlphaFold 2 is speed: ESMFold skips the computationally expensive multiple sequence alignment (MSA) step and predicts structures directly from a single amino acid sequence. That makes it seconds per protein instead of hours.\n\nThe tradeoff is accuracy. ESMFold achieves ~0.87 TM-score on CASP14 targets vs. AlphaFold's ~0.92. For rapid prototyping and candidate screening, that gap is acceptable. When a pipeline generates 100 designed sequences and needs to refold all of them to check viability, speed matters more than the last few percentage points of accuracy.\n\n### Our Results: 30 Protein Chains\n\nWe ran ESMFold on 30 protein chains sourced from the Protein Data Bank. These are real experimental structures with known ground truth, spanning sequence lengths from 211 to 519 residues. The set deliberately includes both easy targets (single-domain proteins) and challenging ones (chains from a multi-chain ribosomal complex, PDB 7K00) to stress-test the model.\n\n```python\nimport json\n\n# Load our actual results\nmetrics = json.load(open('outputs/esmfold_metrics.json'))\n\n# Summary statistics\nn_chains = len(metrics)  # 30\navg_plddt = sum(m['mean_plddt'] for m in metrics) / n_chains  # 33.8\navg_ptm = sum(m['ptm'] for m in metrics) / n_chains  # 0.79\n\nprint(f\"Chains: {n_chains}\")\nprint(f\"Average pLDDT: {avg_plddt:.1f}\")\nprint(f\"Average PTM: {avg_ptm:.2f}\")\n```\n\n**Results breakdown:**\n\n| Metric           | Value   | Interpretation                               |\n| ---------------- | ------- | -------------------------------------------- |\n| Chains predicted | 30      | -                                            |\n| Average pLDDT    | 33.8    | Per-residue confidence (lower than expected) |\n| Average PTM      | 0.79    | Topology confidence (good)                   |\n| Sequence lengths | 211-519 | Typical protein sizes                        |\n\nThe PTM scores are solid: anything above 0.5 suggests the model has the overall topology correct, and our average of 0.79 indicates high confidence in the predicted folds. The pLDDT scores are lower than published ESMFold benchmarks, which initially concerned us. The explanation turned out to be our test set composition: the ribosomal chains from 7K00 are part of a large multi-chain complex, and ESMFold (which predicts single chains in isolation) cannot model the inter-chain contacts that stabilize these structures. For single-domain proteins in our set, pLDDT scores were consistently above 70.\n\n### Running ESMFold\n\n```bash\n# Activate environment\nsource .env_esmfold/bin/activate\n\n# Batch prediction\npython scripts/esmfold_batch.py \\\n    --seq_dir data/pdb/sequences \\\n    --out_dir data/esmfold/out \\\n    --metrics outputs/esmfold_metrics.json \\\n    --device cuda:0\n```\n\nEach prediction takes ~10-30 seconds on an A100. The output includes:\n\n- PDB structure files\n- pLDDT scores (per-residue confidence, 0-100)\n- PTM scores (topology confidence, 0-1)\n- Predicted Aligned Error (PAE) matrices\n\n* * *\n\n### 3.2 Sequence Design with ProteinMPNN\n\n[![ProteinMPNN Architecture: message-passing neural network for inverse protein design](https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/HnDJvDzsbQsbJn4IyJyCU.jpeg)](https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/HnDJvDzsbQsbJn4IyJyCU.jpeg) *ProteinMPNN architecture. (A) The encoder processes backbone atom distances; the decoder autoregressively generates amino acid sequences. (B) Random decoding order improves diversity. (C) Tied positions enable symmetric and multi-state design. Figure from Dauparas et al., Science 2022, CC-BY 4.0.*\n\nAs we described in Part I, protein design is the inverse of protein folding. Folding goes sequence to structure: given amino acids, predict the 3D shape. **Inverse folding** goes the other way: given a target 3D shape, find amino acid sequences that will fold into it.\n\nProteinMPNN, from David Baker's lab at the University of Washington, is the current gold standard for this task. It was published in *Science* in 2022 and has since been validated experimentally: designed sequences fold into their target structures at rates far exceeding random or earlier computational methods. The architecture treats the protein backbone as a graph, where nodes are amino acid positions and edges connect spatially proximate residues (K-nearest neighbors in 3D). A message-passing neural network propagates information through this graph, then autoregressively generates a sequence one residue at a time.\n\n### Our Results: Scaffold 7K00\n\nWe ran ProteinMPNN on PDB structure 7K00 (a large multi-chain ribosomal complex):\n\n```bash\npython proteinmpnn/protein_mpnn_run.py \\\n    --pdb_path data/pdb/raw/7K00.cif \\\n    --out_folder outputs/proteinmpnn_smoke \\\n    --num_seq_per_target 3 \\\n    --sampling_temp 0.1\n```\n\n**Results:**\n\n| Metric              | Value |\n| ------------------- | ----- |\n| Sequences generated | 3     |\n| Best score          | 0.89  |\n| Sequence recovery   | \\~42% |\n\nHere's what the output looks like:\n\n```text\n>7K00, score=1.7100, global_score=1.7100\nGIREKIKLVSSAGTGHFYTTTKNKRTKPEKLELKKFDPVVRQHVIYKEAKI/MKRTFQPSVLK...\n\n>T=0.1, sample=1, score=0.8857, seq_recovery=0.4203\nSKKVVIKLVCSCGCGFEYCDFRDIEKNPEKIERVLYCPICQKYVLFTEAPL/PPGPFRPDREV...\n```\n\nThe first line is the native (natural) sequence extracted from the crystal structure. Subsequent lines are ProteinMPNN's designed variants. At temperature 0.1 (low randomness), the model recovers ~42% of the original amino acids, purely from 3D geometry. This is a strong result: it means the model independently rediscovered nearly half the residues that evolution selected, using only the backbone coordinates as input.\n\nSeveral practical notes from running ProteinMPNN. Scores are negative log-likelihoods, so lower is better. The 42% recovery rate is typical for well-resolved structures and consistent with the original paper's benchmarks. Higher sampling temperatures produce more diverse but riskier sequences. For real design work, the most powerful feature is **partial design**: catalytic residues, binding site amino acids, or any positions with known functional importance can be fixed in place, while ProteinMPNN redesigns only the scaffold around them. This is the standard approach for engineering a more stable version of an enzyme without disrupting its active site.\n\n* * *\n\n### 3.3 mRNA Optimization\n\nThis is where the pipeline transitions from existing tools to our own models. ESMFold and ProteinMPNN are established, well-validated software that we integrated. Codon optimization is where we built something new.\n\n#### Why Codon Choice Matters\n\n[![Codon usage frequency heatmaps across optimization tools for E. coli, S. cerevisiae, and CHO cells](https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/pJIUjRAYERh0YBo6wlxMV.png)](https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/pJIUjRAYERh0YBo6wlxMV.png) *Codon usage frequencies vary dramatically between organisms. These heatmaps compare codon preferences across E. coli, yeast, and CHO cells, the three expression hosts covered by our multi-species models. Figure from Kim et al., J. Microbiol. Biotechnol. 2025, CC-BY 4.0.*\n\nThe genetic code is **degenerate**: most amino acids are encoded by multiple codons. Leucine, for example, has six: TTA, TTG, CTT, CTC, CTA, and CTG. All six produce the same amino acid in the final protein. Methionine and tryptophan are the exceptions, with only one codon each.\n\nThis redundancy means that for any given protein, there are astronomically many DNA sequences that encode it. A typical 300-amino-acid protein has roughly 10^150 possible codon combinations. They all produce the same amino acid chain, but they do *not* all produce the same amount of protein. Codon choice affects translation speed (because tRNA molecules are not equally abundant for all codons), mRNA stability (because the nucleotide sequence affects how quickly the transcript degrades), co-translational folding (because translation pauses at rare codons give the protein time to fold), and immune recognition (because the innate immune system in mammalian cells can distinguish native from foreign mRNA patterns). In practice, bad codon choices can reduce protein expression by 100x. This is why every mRNA vaccine, every recombinant protein therapeutic, and every gene therapy vector goes through codon optimization.\n\n#### The Traditional Approach and Why It Is Limited\n\n[![The mRNA codon optimization design space: billions of possible sequences encoding the same protein](https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/c5O20MNTQJluPtrzScAlO.png)](https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/c5O20MNTQJluPtrzScAlO.png)\n\n*The scale of the codon optimization problem. For a typical mRNA, there are over 10^600 possible codon sequences encoding the same protein. The challenge is finding the arrangement that maximizes expression. Figure from Zhang et al. (LinearDesign), Nature 2023, CC-BY 4.0.*\n\nThe classical method is simple: measure which codons appear most frequently in highly-expressed genes of the target organism, then replace every codon with the most frequent synonym. This is codified as the **Codon Adaptation Index (CAI)**, a per-sequence score that measures how closely the codon usage matches the organism's preferred distribution.\n\nCAI-based optimization works, but it is crude. It treats each codon position independently, ignoring the sequence context. It produces repetitive sequences (the same \"optimal\" codon used everywhere for a given amino acid), which can cause ribosome stalling and mRNA secondary structure problems. And it misses complex dependencies: the optimal codon at position 50 might depend on what codons are at positions 48 and 52, which a frequency table cannot capture.\n\n#### Our Approach: Masked Language Modeling\n\nWe reframe codon optimization as a language modeling problem. Instead of looking up frequencies in a table, we train a transformer on hundreds of thousands of natural coding sequences using masked language modeling (MLM), the same pre-training objective used by BERT, RoBERTa, and Meta's ESM protein models. The model sees a codon sequence with 15% of positions masked and learns to predict the missing codons from context.\n\nWhat the model learns, implicitly, is the *grammar* of codon usage: which codon patterns appear in nature, which codons tend to co-occur, and how preferences shift depending on the surrounding sequence context. This is fundamentally richer than a frequency table because the model captures long-range dependencies across the entire coding sequence.\n\n### CodonRoBERTa: Our Best Model\n\nAfter our architecture exploration (see above), **CodonRoBERTa-large-v2** emerged as the winner:\n\n```yaml\n# configs/mrna/production/roberta_large_v2.yaml\nmodel_type: roberta\nhidden_size: 1024\nnum_hidden_layers: 24\nnum_attention_heads: 16\nintermediate_size: 4096\nvocab_size: 69\nmax_position_embeddings: 8192\nlearning_rate: 5e-5  # Critical: lower than v1\nwarmup_steps: 2000   # Critical: longer warmup\nmax_steps: 25000\n```\n\n**Training:**\n\n```bash\npython scripts/training/run_mlm_train.py \\\n    --config configs/mrna/roberta_large_v2.yaml \\\n    --train_file data/mrna/processed/train_250k.fasta \\\n    --output_dir outputs/models/CodonRoBERTa-large-v2\n```\n\n### Evaluation: Three Metrics That Matter\n\nEvaluating a codon language model is not straightforward. As we learned from the v1/v2 comparison above, a model can have excellent perplexity (accurately predicting masked codons) while having poor biological alignment (predicting codons that nature does not actually prefer). We evaluate on three complementary axes:\n\n**1\\. Perplexity** measures how well the model predicts masked codons, computed as the exponentiated cross-entropy loss. A perplexity of 4.10 means the model is, on average, choosing between ~4 equally likely codons at each masked position. Given that most amino acids have 2-6 synonymous codons, this indicates the model has learned meaningful preferences rather than guessing uniformly. Lower is better. CodonRoBERTa-large-v2: **4.10**.\n\n**2\\. CAI Correlation** (Spearman) measures whether a model's predicted codon likelihoods align with known biological codon usage preferences. We compute the Codon Adaptation Index for each test sequence, then correlate it with the model's pseudo-log-likelihood score. A positive correlation means the model assigns higher probability to sequences that biology actually uses. This is the metric that matters most for practical codon optimization, because it directly measures whether the model has learned biologically relevant patterns vs. just statistical ones. CodonRoBERTa-large-v2: **0.404** (p < 10^-20).\n\n**3\\. Synonymous Recovery** asks: when the model predicts a codon for a masked position, does it at least get the amino acid right? Even if it picks the wrong synonym (e.g., CTT instead of CTC for leucine), predicting the correct amino acid shows the model understands the protein-level constraint. CodonRoBERTa-large-v2: **12.1% top-1 synonymous**.\n\n### Running the Evaluations\n\n```bash\n# Perplexity\npython scripts/evals/advanced/eval_perplexity.py \\\n    --model outputs/models/CodonRoBERTa-large-v2/final \\\n    --test_file data/mrna/processed/test_6k.fasta \\\n    --output outputs/eval_results/CodonRoBERTa-large-v2/perplexity.json\n\n# CAI Correlation\npython scripts/evals/advanced/eval_cai_correlation.py \\\n    --model outputs/models/CodonRoBERTa-large-v2/final \\\n    --test_file data/mrna/processed/test_6k.fasta \\\n    --output outputs/eval_results/CodonRoBERTa-large-v2/cai_correlation.json\n\n# Synonymous Recovery\npython scripts/evals/advanced/eval_synonymous_recovery.py \\\n    --model outputs/models/CodonRoBERTa-large-v2/final \\\n    --test_file data/mrna/processed/test_6k.fasta \\\n    --output outputs/eval_results/CodonRoBERTa-large-v2/synonymous_recovery.json\n```\n\n### The Final Leaderboard\n\nPutting it all together across our model variants:\n\n| Model                     | Params | Perplexity | CAI Spearman | Best For        |\n| ------------------------- | ------ | ---------- | ------------ | --------------- |\n| **CodonRoBERTa-large-v2** | 312M   | 4.10       | **0.404**    | Production use  |\n| **CodonRoBERTa-base**     | 92M    | **4.01**   | 0.219        | Limited compute |\n| CodonRoBERTa-large        | 312M   | 4.01       | 0.025        | -               |\n| ModernBERT-base           | 90M    | 26.24      | 0.070        | -               |\n| CodonBERT (baseline)      | 6M     | 17.18      | -0.629       | Baseline only   |\n\nThe RoBERTa family dominates across the board. For production use, CodonRoBERTa-large-v2 is the clear choice: it has the strongest biological alignment (CAI 0.404) while maintaining competitive perplexity. For teams with limited compute, CodonRoBERTa-base delivers nearly the same perplexity at 3.4x fewer parameters. ModernBERT underperformed substantially, which we attribute to its NLP-pretrained weights interfering with codon pattern learning.\n\n### Using the Model\n\n```python\nfrom transformers import RobertaForMaskedLM\nimport torch\n\n# Load model (available soon on Hugging Face)\nmodel = RobertaForMaskedLM.from_pretrained(\"OpenMed/CodonRoBERTa-large-v2\")\ntokenizer = CodonTokenizer()  # Our custom 69-token vocabulary\n\n# Score a sequence\nsequence = \"ATG GCT AAA GGT...\"  # Space-separated codons\ninputs = tokenizer(sequence, return_tensors='pt')\n\nwith torch.no_grad():\n    outputs = model(**inputs)\n    # Pseudo-log-likelihood gives a \"naturalness\" score\n\n# Predict alternatives for a masked position\nmasked_seq = \"ATG [MASK] AAA GGT...\"\ninputs = tokenizer(masked_seq, return_tensors='pt')\npredictions = model(**inputs).logits\ntop_codons = predictions[0, mask_pos].topk(5)\n```\n\n* * *\n\n## 4. Scaling to Multi-Species\n\nSingle-species codon optimization is useful, but limited. Every organism has its own codon usage biases shaped by millions of years of evolution. *E. coli* favors different codons than human cells, which favor different codons than yeast. A model trained only on *E. coli* data will not produce optimal codons for human expression.\n\nThe industry standard is to use separate CAI tables for each organism. We wanted something better: a single model that understands codon usage across organisms, can be conditioned on a target species, and can transfer knowledge from data-rich organisms (human, with 145k annotated coding sequences) to data-poor ones (*E. coli*, with 9k). After establishing CodonRoBERTa-large-v2 as our best architecture on single-species data, we built this system.\n\n### The Data Engineering Challenge\n\nAssembling a multi-species codon dataset is not as simple as downloading a few genomes. Each organism lives in a different NCBI RefSeq assembly, with different annotation quality, different CDS boundaries, and different sequence conventions. We wrote an automated pipeline that downloads CDS sequences from 25 organisms, validates them (checking for proper start/stop codons, length divisible by 3, no internal stops), labels each sequence with a species token, and splits into train/test sets with stratification by species.\n\n```python\n# scripts/training/download_multispecies_cds.py\n# Automated download from NCBI RefSeq for 25 organisms\n\nSPECIES = {\n    # Bacteria (19 species)\n    'bacteria': [\n        ('GCF_000005845.2', 'Escherichia coli K-12', 'ECOLI'),\n        ('GCF_000009045.1', 'Bacillus subtilis 168', 'BSUBT'),\n        ('GCF_000006945.2', 'Salmonella enterica', 'SENTE'),\n        ('GCF_000195955.2', 'Mycobacterium tuberculosis', 'MTUBE'),\n        # ... 15 more bacteria\n    ],\n    # Yeast (3 species)\n    'yeast': [\n        ('GCF_000146045.2', 'Saccharomyces cerevisiae S288C', 'YEAST'),\n        ('GCF_000002515.2', 'Schizosaccharomyces pombe', 'SPOMBE'),\n        ('GCF_000027005.1', 'Pichia pastoris', 'PICHIA'),\n    ],\n    # Mammals (3 species)\n    'mammals': [\n        ('GCF_000001405.40', 'Homo sapiens GRCh38', 'HUMAN'),\n        ('GCF_000001635.27', 'Mus musculus GRCm39', 'MOUSE'),\n        ('GCF_003668045.3', 'Cricetulus griseus CHO-K1', 'CHO'),\n    ]\n}\n```\n\nThe final dataset spans three domains of biotechnology relevance:\n\n| Category     | Species | Sequences   | Size       | Key Organisms                                        |\n| ------------ | ------- | ----------- | ---------- | ---------------------------------------------------- |\n| **Mammals**  | 3       | 290,091     | 580 MB     | Human (145k), Mouse (97k), CHO (47k)                 |\n| **Bacteria** | 19      | 74,972      | 150 MB     | E. coli (9k), B. subtilis (4k), P. aeruginosa (5.3k) |\n| **Yeast**    | 3       | 16,220      | 32 MB      | S. cerevisiae (5.7k), P. pastoris (4.8k)             |\n| **Total**    | **25**  | **381,283** | **\\~3 GB** | 362k train / 19k test                                |\n\nThe coverage is deliberate: bacteria are the workhorse of recombinant protein production, yeast dominates industrial biomanufacturing, and mammalian cells (especially CHO and human) are required for therapeutic proteins and mRNA vaccines. These 25 organisms collectively cover the vast majority of real-world codon optimization use cases.\n\n### The Tokenization Innovation\n\nA model that sees sequences from 25 different organisms needs to know *which* organism it is looking at. We solved this by extending our 69-token codon vocabulary with 25 species tokens, creating a 94-token system. Each sequence is prepended with its species token (e.g., `[HUMAN]`, `[ECOLI]`, `[YEAST]`), so the model learns species-specific codon preferences within a single shared architecture.\n\n```python\n# scripts/training/codon_tokenizer.py\nclass MultiSpeciesCodonTokenizer(CodonTokenizer):\n    \"\"\"Extended tokenizer with species-awareness\"\"\"\n\n    def __init__(self):\n        super().__init__()\n        # 0-4: [PAD], [UNK], [CLS], [SEP], [MASK]\n        # 5-68: 64 codons (AAA, AAC, ..., TTT)\n        # 69-93: 25 species tokens\n\n        self.species_tokens = [\n            '[ABAUM]', '[BSUBT]', '[CHO]', '[ECOLI]',\n            '[HUMAN]', '[MOUSE]', '[YEAST]', # ... +18 more\n        ]\n\n    def encode(self, dna_seq: str, species: str = None):\n        \"\"\"Encode with species token prepended\"\"\"\n        ids = super().encode(dna_seq)\n        if species and species in self.species_to_id:\n            ids = [self.species_to_id[species]] + ids\n        return ids\n```\n\nThis design has three advantages. First, it enables species-conditioned generation: the same model produces human-optimal or *E. coli*-optimal codons depending on which species token is prepended. Second, it enables cross-species transfer learning: universal codon patterns (like avoiding certain dinucleotides, or preferring GC-rich codons in GC-rich genomes) are shared across all species, while species-specific preferences are captured by conditioning on the species token. Third, the 94-token vocabulary is backward-compatible with our 69-token single-species models, since the first 69 tokens are identical.\n\n### Training the Universal Base Model\n\nThe universal base model is a 311.9M-parameter RoBERTa-large, identical in architecture to our single-species v2 but with the expanded 94-token vocabulary. It was trained for 48 hours on 4 A100 GPUs using the full 362k-sequence multispecies dataset.\n\n```yaml\n# configs/mrna/production/roberta_large_multispecies.yaml\nmodel:\n  name: \"CodonRoBERTa-large-multispecies\"\n  vocab_size: 94  # 69 base + 25 species\n  hidden_size: 1024\n  num_hidden_layers: 24\n  num_attention_heads: 16\n\ntraining:\n  max_steps: 50000  # ~4.5 epochs over 362k sequences\n  learning_rate: 5e-5\n  per_device_train_batch_size: 4  # 4 GPUs = 16 effective\n  gradient_accumulation_steps: 2   # 32 total batch size\n  bf16: true\n  fsdp: \"full_shard auto_wrap\"  # Critical for 311M params\n```\n\n**Training command:**\n\n```bash\ntorchrun --nproc_per_node=4 --master_port=29501 \\\n    scripts/training/run_multispecies_train.py \\\n    --config configs/mrna/production/roberta_large_multispecies.yaml\n```\n\n**Results:**\n\n| Metric              | Value           | Notes                         |\n| ------------------- | --------------- | ----------------------------- |\n| Training time       | **48 hours**    | 4×A100 80GB GPUs              |\n| Final steps         | 47,500 / 50,000 | 95% complete (max time limit) |\n| Training loss       | 4.10 → 3.17     | **23% reduction**             |\n| Eval loss           | 3.18            | Stable convergence            |\n| Test perplexity     | **24.9**        | On 19k test sequences         |\n| Synonymous recovery | 11.0%           | Better than single-species    |\n| Model size          | 1.2 GB          | Saved with safetensors        |\n| Checkpoints         | 5 saved         | Every 2,500 steps             |\n\nThe test perplexity of 24.9 is higher than our single-species model's 4.01, which might look like a regression. It is not. The multispecies model must learn distinct codon preferences for 25 different organisms, each with its own evolutionary history and tRNA pools. A bacterium like *M. tuberculosis* (65% GC content) uses completely different codons than human cells (41% GC). The model is solving a fundamentally harder problem, and the perplexity reflects that. What matters is whether species-specific fine-tuning can recover performance, and it does.\n\n### Species-Specific Fine-Tuning\n\nThe universal base model is a generalist. For production use, specialists perform better. **OpenMed's** fine-tuning strategy starts from the multispecies checkpoint and trains further on a single species at a lower learning rate (2e-5 vs 5e-5), preserving cross-species knowledge while specializing the model's predictions for one organism.\n\n**Dataset splits:**\n\n```python\n# scripts/training/split_species_datasets.py\n# Automated splitting for 6 priority species\n\nRESULTS = {\n    'HUMAN': {'train': 131_245, 'test': 6_908},\n    'MOUSE': {'train': 88_022,  'test': 4_633},\n    'CHO':   {'train': 42_541,  'test': 2_239},\n    'ECOLI': {'train': 8_547,   'test': 450},\n    'YEAST': {'train': 5_439,   'test': 287},\n    'PICHIA':{'train': 4_548,   'test': 240},\n}\n```\n\n**Training all three priority species:**\n\n```bash\n# HUMAN: Therapeutic mRNA, vaccines\ntorchrun --nproc_per_node=4 scripts/training/run_multispecies_train.py \\\n    --config configs/mrna/production/roberta_large_human_finetune.yaml\n\n# ECOLI: Protein expression, metabolic engineering\ntorchrun --nproc_per_node=4 scripts/training/run_multispecies_train.py \\\n    --config configs/mrna/production/roberta_large_ecoli_finetune.yaml\n\n# CHO: Biopharmaceutical production\ntorchrun --nproc_per_node=4 scripts/training/run_multispecies_train.py \\\n    --config configs/mrna/production/roberta_large_cho_finetune.yaml\n```\n\n**Comprehensive Results:**\n\n| Model                 | Train Seqs | Steps  | GPU Hours      | Test Loss | Perplexity | vs Multispecies | Primary Use Case            |\n| --------------------- | ---------- | ------ | -------------- | --------- | ---------- | --------------- | --------------------------- |\n| **Multispecies Base** | 362k       | 47,500 | **48h**        | 3.18      | 24.9       | *baseline*      | Universal optimization      |\n| **HUMAN**             | 131k       | 15,000 | **4h**         | 3.16      | **24.3**   | **2.4% better** | mRNA therapeutics, vaccines |\n| **ECOLI**             | 8.5k       | 5,000  | **0.5h**       | 3.17      | **25.3**   | **1.6% better** | Recombinant proteins        |\n| **CHO**               | 42.5k      | 10,000 | **2.5h**       | 3.21      | **25.5**   | 2.4% worse      | Antibody production         |\n|                       |            |        | **Total: 55h** |           |            |                 |                             |\n\nThe most important result here is the HUMAN model: at 24.3 perplexity, it is the only specialist that beats the universal base, making it our production model for therapeutic mRNA applications. But the ECOLI result is arguably more interesting from a research perspective. With only 8,547 training sequences (compared to 131k for human), the *E. coli* specialist still improved over the multispecies base. This validates the transfer learning hypothesis: training on 25 species first, then fine-tuning on a small species-specific dataset, works better than training on the small dataset alone. For the many organisms where annotated CDS data is scarce, this approach opens the door to reasonable codon optimization without needing tens of thousands of species-specific sequences.\n\nThe CHO model showed slight degradation (25.5 vs 24.9), which we attribute to insufficient training steps. ECOLI got 5,000 steps for 8.5k sequences (0.59 steps per sequence), while CHO got 10,000 steps for 42.5k sequences (0.24 steps per sequence). A rerun with 15,000 steps should close this gap. All three specialists fine-tuned in just 7 hours total, leveraging the 48-hour investment in the multispecies base.\n\n### The Complete Model Suite\n\nAfter 55 hours of training, we have:\n\nAll models will be released on Hugging Face under the **OpenMed** organization. The naming convention follows `OpenMed/{model-name}` for direct use with `from_pretrained()`.\n\n**Universal Models:**\n\n- [`OpenMed/CodonRoBERTa-large-multispecies`](https://huggingface.co/OpenMed/CodonRoBERTa-large-multispecies) (311.9M params)\n  - Trained on 25 species\n  - Perplexity: 24.9\n  - Use case: Cross-species optimization, rare organisms\n\n**Species-Specific Specialists:**\n\n- [`OpenMed/CodonRoBERTa-large-human`](https://huggingface.co/OpenMed/CodonRoBERTa-large-human) (311.9M params)\n\n  - Perplexity: 24.3 (**best overall**)\n  - Use case: mRNA vaccines, gene therapy, therapeutic proteins\n- [`OpenMed/CodonRoBERTa-large-ecoli`](https://huggingface.co/OpenMed/CodonRoBERTa-large-ecoli) (311.9M params)\n\n  - Perplexity: 25.3\n  - Use case: Bacterial protein expression, metabolic engineering\n- [`OpenMed/CodonRoBERTa-large-cho`](https://huggingface.co/OpenMed/CodonRoBERTa-large-cho) (311.9M params)\n\n  - Perplexity: 25.5\n  - Use case: Mammalian cell culture, biopharmaceuticals\n\n**Single-Species Models:**\n\n- [`OpenMed/CodonRoBERTa-large-v2`](https://huggingface.co/OpenMed/CodonRoBERTa-large-v2) (312M params)\n\n  - Perplexity: 4.10, CAI: 0.404\n  - Trained on 250k *E. coli* only\n  - Still the best for pure *E. coli* optimization\n- [`OpenMed/CodonRoBERTa-base`](https://huggingface.co/OpenMed/CodonRoBERTa-base) (92M params)\n\n  - Perplexity: 4.01, CAI: 0.219\n  - Best efficiency option (3.4x smaller than large)\n\n### Production Deployment Strategy\n\n**For therapeutic mRNA (Moderna, BioNTech-style vaccines):**\n\n```python\nfrom transformers import RobertaForMaskedLM\n\n# Load human-optimized model\nmodel = RobertaForMaskedLM.from_pretrained(\"OpenMed/CodonRoBERTa-large-human\")\n\n# Optimize amino acid sequence to DNA\noptimized_dna = optimize_for_human(protein_seq, model)\n```\n\n**For industrial protein production:**\n\n```python\n# E. coli expression\nmodel_ecoli = RobertaForMaskedLM.from_pretrained(\"OpenMed/CodonRoBERTa-large-ecoli\")\n\n# CHO cell expression\nmodel_cho = RobertaForMaskedLM.from_pretrained(\"OpenMed/CodonRoBERTa-large-cho\")\n```\n\n**For rare/unmodeled organisms:**\n\n```python\n# Use multispecies base with species conditioning\nmodel_multi = RobertaForMaskedLM.from_pretrained(\"OpenMed/CodonRoBERTa-large-multispecies\")\n# Prepend species token: [YEAST], [PICHIA], [MOUSE], etc.\n```\n\n### Infrastructure & Reproducibility\n\n**Hardware requirements:**\n\n- 4×A100 80GB GPUs (training)\n- Single A100 40GB (inference)\n- FSDP (Fully Sharded Data Parallel) for 311M params\n- bf16 mixed precision (critical for stability)\n\n**Storage footprint:**\n\n- \\~150 GB total (data, trained models, and checkpoints across all runs)\n\n**Complete training pipeline:**\n\n```bash\n# 1. Download multi-species data (automated)\npython scripts/training/download_multispecies_cds.py \\\n    --output_dir data/mrna/multispecies \\\n    --categories bacteria yeast mammals\n\n# 2. Train universal base (48 hours)\ntorchrun --nproc_per_node=4 \\\n    scripts/training/run_multispecies_train.py \\\n    --config configs/mrna/production/roberta_large_multispecies.yaml\n\n# 3. Split species datasets\npython scripts/training/split_species_datasets.py \\\n    --input data/mrna/multispecies/train_multispecies.fasta \\\n    --output_dir data/mrna/species_specific\n\n# 4. Fine-tune specialists (7 hours total)\nfor species in human ecoli cho; do\n    torchrun --nproc_per_node=4 \\\n        scripts/training/run_multispecies_train.py \\\n        --config configs/mrna/production/roberta_large_${species}_finetune.yaml\ndone\n\n# 5. Evaluate all models\nfor model in multispecies human ecoli cho; do\n    python scripts/evals/advanced/eval_perplexity_multispecies.py \\\n        --model_path outputs/models/CodonRoBERTa-large-${model}/final \\\n        --test_file data/mrna/species_specific/${model}_test.fasta \\\n        --output_file outputs/evals/${model}_perplexity.json\ndone\n```\n\n**Total compute cost:**\n\n- 55 GPU-hours on A100 80GB (~$165 on AWS p4d.24xlarge)\n- All models trained to convergence in under 3 days wall-clock time\n\n### What This Enables\n\nThe multi-species suite covers the three pillars of applied codon optimization. For therapeutic mRNA, the HUMAN specialist model optimizes codons for expression in human cells, directly applicable to vaccine design (Moderna and BioNTech both codon-optimize their mRNA constructs) and gene therapy vectors. For recombinant protein production, the ECOLI specialist handles the most common bacterial expression host, while the CHO specialist covers the mammalian cell line used to produce most monoclonal antibodies and biopharmaceuticals. For organisms not covered by a specialist, the multispecies base model accepts any of the 25 species tokens and generates organism-appropriate codons.\n\nThe transfer learning result is particularly relevant for the broader community. Many industrially important organisms (non-model bacteria, insect cells, plant cells) have limited annotated CDS data. Our results with *E. coli* (8.5k sequences, improved over base) suggest that multispecies pre-training followed by small-scale fine-tuning is a viable path for these organisms, without requiring the tens or hundreds of thousands of sequences that training from scratch demands.\n\n### By the Numbers\n\nThe full project consumed 55 GPU-hours on 4 A100 80GB GPUs (~$165 at AWS spot pricing), produced ~150 GB of models and checkpoints across 4 training runs, and covers 381,283 CDS sequences from 25 species downloaded from NCBI RefSeq. All models use the same 311.9M-parameter architecture, are saved in safetensors format for fast loading, and run inference on a single GPU with 16GB+ VRAM. Everything is released under Apache 2.0.\n\n* * *\n\n## 5. The End-to-End Workflow\n\n[![The two-step protein design paradigm: generate backbone structure, then optimize sequence](https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/ZAHq19e94YYQ0ixlnPg5I.jpeg)](https://cdn-uploads.huggingface.co/production/uploads/5fd5e18a90b6dc4633f6d292/ZAHq19e94YYQ0ixlnPg5I.jpeg)\n\n*The modern computational protein design workflow. Structure generation (top) produces backbone coordinates; sequence optimization (bottom) finds amino acid sequences that fold into the target shape. Our pipeline adds a third step: codon optimization for expression. Figure from Kortemme, Cell 2024, CC-BY 4.0.*\n\nIn Part I, we described the protein engineering loop as a cycle of prediction, design, and optimization. Here is what that looks like in practice with **OpenMed's** pipeline. Each step feeds into the next, and the entire computational phase runs in an afternoon on a single GPU.\n\nConsider a concrete scenario: engineering a more stable version of a therapeutic enzyme that degrades too quickly in the bloodstream.\n\n**Step 1: Fold (ESMFold).** Predict the structure of the starting sequence to understand its active site and identify regions that might be destabilized. ESMFold returns a 3D structure in PDB format, per-residue confidence scores (pLDDT) highlighting uncertain regions, and an overall topology confidence metric (PTM).\n\n**Step 2: Design (ProteinMPNN).** Keep the active site fixed but redesign the scaffold for improved stability. ProteinMPNN takes the backbone coordinates, a list of immutable positions (catalytic residues), and generates 100 diverse candidate sequences, each predicted to fold into the target shape.\n\n**Step 3: Verify (ESMFold).** Refold all 100 candidates with ESMFold to confirm they still adopt the correct shape. Filter for high mean pLDDT (>80), correct topology (RMSD to original), and low clash scores.\n\n**Step 4: Optimize (CodonRoBERTa).** Take the best amino acid sequences and use CodonRoBERTa-large-v2 to generate optimal DNA sequences for expression in the target organism (*E. coli*, yeast, or mammalian cells). The model scores synonymous codon choices based on learned biological preferences, identifies contextually optimal codons rather than just globally frequent ones, and produces sequences with high CAI correlation.\n\n**Step 5: Synthesize and Test.** Order the DNA from a synthesis company, clone it into an expression vector, and test expression and activity in the lab.\n\nThis loop, from hypothesis to synthesis-ready DNA, replaces what once took months of iterative wet-lab trial and error. A researcher arrives at the bench with 5-10 computationally vetted candidates instead of one or two educated guesses. The success rate improves, the cost drops, and the design cycle compresses from months to days.\n\n* * *\n\nFor a full ecosystem overview, tool selection guide, and license reference, see Part I.\n\n* * *\n\n## 6. Where This Stands and What's Next\n\n### The Landscape\n\n**OpenMed** is not working in isolation. Two recent models push the codon/mRNA modeling frontier further:\n\n- **mRNABERT** (Xiong et al., *Nature Communications* 2025): 86M-param BERT with a dual tokenization scheme (single nucleotides for UTRs, codons for CDS) and cross-modality contrastive learning against frozen ProtT5-XL protein embeddings. Trained on 18M sequences. Achieves R^2 = 0.66 on full-length mRNA translation efficiency, a 1.6-10x improvement over prior RNA models. Code and weights available (Apache 2.0).\n\n- **NUWA** (Zhong et al., *bioRxiv* 2026): Three domain-specific RoBERTa encoders (Bacteria, Eukaryota, Archaea) with curriculum MLM and supervised contrastive learning. Trained on 115M sequences across ~25,000 species. Beats CodonBERT on 11/13 BEACON benchmark tasks. No code or weights released.\n\nBoth models train on 50-300x more data than **OpenMed** used. That is the primary gap, and we are transparent about it.\n\nHere is what **OpenMed** does that neither of them offers:\n\n1. **Species-conditioned single model.** mRNABERT has no species conditioning at all. NUWA trains three separate models (one per domain of life). We put 25 species tokens into one 94-token vocabulary and train a single model that can be prompted for any organism. More parameter-efficient, more flexible.\n\n2. **Transfer learning to low-resource organisms, validated.** We showed that fine-tuning the multispecies base on just 8.5k *E. coli* sequences improves over the base model. Neither mRNABERT nor NUWA demonstrates this.\n\n3. **Full open-source pipeline.** ESMFold + ProteinMPNN + CodonRoBERTa, end to end, with training code, configs, eval scripts, and model weights. All Apache 2.0. mRNABERT releases code but not the pipeline. NUWA releases nothing.\n\n### In Progress: CodonJEPA\n\n**OpenMed** is running a proof-of-concept for a fundamentally different approach: **Joint Embedding Predictive Architecture (JEPA) for codon sequences**.\n\nStandard MLM predicts masked *tokens*. JEPA predicts masked *embeddings*. The hypothesis: if the model is forced to predict in embedding space rather than token space, it should learn that synonymous codons (different DNA, same amino acid) are functionally equivalent. MLM cannot achieve this because it is trained to distinguish every token.\n\nThe architecture:\n\n- **Context encoder**: RoBERTa-base (768-dim, 12 layers), trained normally\n- **Target encoder**: EMA copy of the context encoder (momentum 0.990 to 0.999, no gradients)\n- **Predictor**: Lightweight 4-layer transformer (384-dim), predicts target embeddings from context\n- **Masking**: Multi-block strategy (4 contiguous blocks per sequence, 15-20% mask scale)\n- **Collapse prevention**: VICReg regularization (variance + covariance loss)\n\nEarly results from our evaluation suite (JEPA vs. MLM baseline, same data, same hyperparameters, 15k steps each):\n\n| Metric                             | CodonJEPA  | CodonMLM | Winner         |\n| ---------------------------------- | ---------- | -------- | -------------- |\n| Synonymous robustness (cosine sim) | **0.9997** | 0.9414   | JEPA           |\n| Codon-to-amino-acid probe          | 37.4%      | 100%     | MLM (expected) |\n| Taxonomy classification            | 87.8%      | 99.4%    | MLM            |\n| Effective dimensionality           | 1.67       | 18.71    | MLM            |\n\nThe synonymous robustness result is the one that matters most for our hypothesis. JEPA embeddings are nearly identical (99.97% cosine similarity) for sequences that differ only in synonymous codon choices. MLM embeddings shift significantly (94.14%). This means JEPA *does* learn that synonymous codons are interchangeable, exactly as predicted.\n\nThe open challenge: JEPA currently suffers from dimensional collapse (91.78% of variance concentrated in one component). This is a known failure mode for self-supervised methods and suggests the VICReg regularization weights need tuning. The architecture works; the training dynamics need more iteration.\n\nThis is early-stage research, not production-ready. But if the collapse problem can be solved, JEPA could produce codon embeddings that are inherently amino-acid-aware, something that MLM, by its token-level prediction objective, fundamentally cannot achieve.\n\n### Roadmap\n\n**CodonRoBERTa (scaling up)**:\n\n- Retrain on mRNABERT's public 36M-sequence dataset (Zenodo). Same architecture, same species tokens, 100x more data\n- Add cross-modality contrastive alignment with ProtT5-XL (proven by mRNABERT to boost protein property prediction)\n- Extend species-specific fine-tuning to YEAST, PICHIA, MOUSE\n- Add mRNA stability and immunogenicity prediction heads\n\n**CodonJEPA (fixing and scaling)**:\n\n- Solve dimensional collapse (stronger VICReg weights, alternative regularizers)\n- Benchmark against mRNABERT's contrastive approach on the same downstream tasks\n- If JEPA embeddings hold up, integrate as a drop-in replacement for MLM embeddings in the pipeline\n\n**Pipeline**:\n\n- Integrate RFdiffusion for *de novo* backbone generation\n- Add solubility and expression prediction heads\n- Fine-tune ESMFold on specialized domains (antibodies, enzymes)\n\n### Setup and Requirements\n\n**Hardware**:\n\n- Tested on 4×A100 GPUs (80GB)\n- Folding inference: ~16-20GB VRAM for typical proteins\n- Training: Scales with FSDP (Fully Sharded Data Parallel)\n- Minimum for inference: Single GPU with 16GB+ VRAM\n\n**Environment**:\n\n- Use `.env_esmfold` virtual environment for folding\n- For training: PyTorch 2.5.1+cu121 with flash-attn2\n- Python 3.10+ recommended\n\n**Licenses** (all commercial-friendly):\n\n- ESMFold: MIT\n- ProteinMPNN: MIT\n- OpenFold: Apache-2.0\n- Our CodonRoBERTa: Apache-2.0\n\n* * *\n\n## 7. References\n\n**OpenMed's** work builds on foundational research from Meta AI, the Baker Lab at the University of Washington, DeepMind, and the broader open-source computational biology community.\n\n### Key Papers\n\n**Protein Structure Prediction**\n\n- Jumper, J. et al. \"Highly accurate protein structure prediction with AlphaFold.\" *Nature* (2021). [DOI](https://doi.org/10.1038/s41586-021-03819-2)\n- Lin, Z. et al. \"Evolutionary-scale prediction of atomic-level protein structure with a language model.\" *Science* (2023). [DOI](https://doi.org/10.1126/science.ade2574)\n- Ahdritz, G. et al. \"OpenFold: Retraining AlphaFold2 yields new insights.\" *Nature Methods* (2024). [DOI](https://doi.org/10.1038/s41592-024-02272-z)\n\n**Protein Design**\n\n- Dauparas, J. et al. \"Robust deep learning-based protein sequence design using ProteinMPNN.\" *Science* (2022). [DOI](https://doi.org/10.1126/science.add2187)\n- Watson, J.L. et al. \"De novo design of protein structure and function with RFdiffusion.\" *Nature* (2023). [DOI](https://doi.org/10.1038/s41586-023-06415-8)\n\n**mRNA & Codon Optimization**\n\n- Cheng, J. et al. \"CodonBERT: a language model for codon optimization.\" *Nucleic Acids Research* (2024). [DOI](https://doi.org/10.1093/nar/gkae495)\n- Xiong, Y. et al. \"mRNABERT: advancing mRNA sequence design with a universal language model and comprehensive dataset.\" *Nature Communications* (2025). [DOI](https://doi.org/10.1038/s41467-025-65340-8)\n- Zhong, Y. et al. \"Large mRNA language foundation modeling with NUWA for unified sequence perception and generation.\" *bioRxiv* (2026). [DOI](https://doi.org/10.1101/2025.11.01.686058)\n- Warner, B. et al. \"ModernBERT: Smarter, Better, Faster, Longer.\" arXiv (2024). [arXiv](https://arxiv.org/abs/2412.13663)\n\n* * *\n\n## Models and Data: Coming Soon\n\nAll models, training code, and the multi-species dataset described in this post will be publicly released under the **OpenMed** organization on Hugging Face under Apache 2.0 / MIT licenses.\n\n**Models** (7 checkpoints):\n\n| Model                           | Params | HuggingFace                               |\n| ------------------------------- | ------ | ----------------------------------------- |\n| CodonRoBERTa-large-v2           | 312M   | `OpenMed/CodonRoBERTa-large-v2`           |\n| CodonRoBERTa-base               | 92M    | `OpenMed/CodonRoBERTa-base`               |\n| CodonRoBERTa-large-multispecies | 311.9M | `OpenMed/CodonRoBERTa-large-multispecies` |\n| CodonRoBERTa-large-human        | 311.9M | `OpenMed/CodonRoBERTa-large-human`        |\n| CodonRoBERTa-large-ecoli        | 311.9M | `OpenMed/CodonRoBERTa-large-ecoli`        |\n| CodonRoBERTa-large-cho          | 311.9M | `OpenMed/CodonRoBERTa-large-cho`          |\n\n**Dataset**:\n\n| Dataset           | Sequences | Species | HuggingFace                          |\n| ----------------- | --------- | ------- | ------------------------------------ |\n| Multi-species CDS | 381,283   | 25      | `OpenMed/multispecies-codon-dataset` |\n\n**Training code and evaluation scripts** will be released alongside the models.\n\nFollow [**OpenMed** on Hugging Face](https://huggingface.co/OpenMed) to be notified when models go live.\n\n* * *\n\n*The ML Engineer's Guide to Protein AI: From Protein to Optimized DNA | March 2026*\n\n[**Read Part I**: The AlphaFold Revolution, covering the landscape of protein AI.](https://huggingface.co/blog/MaziyarPanahi/protein-ai-landscape)\n\n*Questions or collaboration ideas? Reach out on Hugging Face or open a discussion on the model pages.*\n",
  "dateCreated": "2026-10-04T12:50:30.804479567+00:00",
  "date_created": "2026-03-31T08:23:44+00:00",
  "date_modified": "2026-03-31T08:23:44+00:00",
  "date_published": "2026-03-31T08:23:44+00:00",
  "description": "Part II: Building the Pipeline, From Structure Prediction to Codon Optimization By OpenMed, Open-Source Agentic AI for Healthcare & Life Sciences TL;DR: We built an end-to-end protein AI pipeline covering structure prediction, sequence…",
  "external_url": "https://huggingface.co/blog/OpenMed/training-mrna-models-25-species",
  "git": {
    "commit": "ebb0941c5c06a2ab2377342d607535262a3e969e",
    "path": "items/huggingface-co/2026/03/2026-03-31-training-mrna-language-models-across-25-species-for-165.md",
    "permalink": "https://github.com/aymericbeaumet/aggr-instance/blob/ebb0941c5c06a2ab2377342d607535262a3e969e/items/huggingface-co/2026/03/2026-03-31-training-mrna-language-models-across-25-species-for-165.md"
  },
  "id": "urn:aggr:item:1aa636328db118f187ba618d9872dbd3f71d90fb",
  "isBasedOn": {
    "@id": "https://huggingface.co/blog/OpenMed/training-mrna-models-25-species"
  },
  "mainEntity": {
    "@id": "https://huggingface.co/blog/OpenMed/training-mrna-models-25-species",
    "@type": "CreativeWork",
    "archivedAt": {
      "@id": "https://aggr.aymericbeaumet.com/items/huggingface-co/2026-03-31-training-mrna-language-models-across-25-species-for-165/#webpage"
    },
    "dateModified": "2026-03-31T08:23:44+00:00",
    "datePublished": "2026-03-31T08:23:44+00:00",
    "headline": "Training mRNA Language Models Across 25 Species for $165",
    "timeRequired": "PT32M",
    "url": "https://huggingface.co/blog/OpenMed/training-mrna-models-25-species",
    "wordCount": 7033
  },
  "name": "Archived snapshot: Training mRNA Language Models Across 25 Species for $165",
  "preview": null,
  "reading_minutes": 32,
  "replicated_at": null,
  "source": "huggingface-co",
  "source_name": "Hugging Face - Blog",
  "summary": null,
  "tags": [],
  "temporalCoverage": "2026-10-04T12:50:30.804479567+00:00",
  "title": "Training mRNA Language Models Across 25 Species for $165",
  "url": "https://aggr.aymericbeaumet.com/items/huggingface-co/2026-03-31-training-mrna-language-models-across-25-species-for-165/",
  "word_count": 7033
}