Install any skill in seconds. Free to start, no credit card required.
Get Started Free →**GPU**: A100 (40GB) | **Timeout**: 30min default
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-07 | ✗→✓ | ▲ Improved | — | — |
| case-12 | ✗→✓ | ▲ Improved | — | — |
| case-19 | ✗→✓ | ▲ Improved | — | — |
| case-01 | ✗→✓ | ▲ Improved | — | — |
| case-16 | ✗→✓ | ▲ Improved | — | — |
| Requirement | Minimum | Recommended | |-------------|---------|-------------| | Python | 3.10+ | 3.11 | | CUDA | 12.0+ | 12.1+ | | GPU VRAM | 24GB | 40GB (A100) | | RAM | 32GB | 64GB |
> First time? See Installation Guide to set up Modal and biomodals.
bashcd biomodals modal run modal_chai1.py \ --input-faa complex.fasta \ --out-dir predictions/
GPU: A100 (40GB) | Timeout: 30min default
bashpip install chai_lab python -c " import chai_lab from chai_lab.chai1 import run_inference # Run prediction run_inference( fasta_file='complex.fasta', output_dir='predictions/', num_trunk_recycles=3 ) "
bashgit clone https://github.com/chaidiscovery/chai-lab.git cd chai-lab pip install -e . chai-lab predict \ --fasta complex.fasta \ --output predictions/
>binder
MKTAYIAKQRQISFVKSHFSRQLE...
>target
MVLSPADKTNVKAAWGKVGAHAGE...>protein
MKTAYIAKQRQISFVKSHFSRQLE...
>ligand|smiles
CCO>protein
MKTAYIAKQRQISFVKSHFSRQLE...
>dna
ATCGATCGATCG| Parameter | Default | Range | Description | |-----------|---------|-------|-------------| | num_trunk_recycles | 3 | 1-10 | Recycles (more = better) | | num_diffn_timesteps | 200 | 50-500 | Diffusion steps | | seed | 0 | int | Random seed |
predictions/
├── pred.model_idx_0.cif # Best model (CIF format)
├── pred.model_idx_1.cif # Second model
├── scores.json # Confidence scores
├── pae.npy # PAE matrix
└── plddt.npy # pLDDT valuesNote: Chai-1 outputs CIF format. Convert to PDB if needed:
pythonfrom Bio.PDB import MMCIFParser, PDBIO parser = MMCIFParser() structure = parser.get_structure("pred", "pred.model_idx_0.cif") io = PDBIO() io.set_structure(structure) io.save("pred.model_idx_0.pdb")
pythonimport numpy as np import json # Load scores with open('predictions/scores.json') as f: scores = json.load(f) plddt = np.load('predictions/plddt.npy') pae = np.load('predictions/pae.npy') print(f"pLDDT: {plddt.mean():.3f}") print(f"pTM: {scores['ptm']:.3f}") print(f"ipTM: {scores.get('iptm', 'N/A')}")
python# Predict complex with Chai chai-lab predict --fasta binder_target.fasta --output val/ # Check ipTM > 0.5 scores = json.load(open('val/scores.json')) if scores['iptm'] > 0.5: print("Design passes validation")
python# FASTA with SMILES fasta = """ >protein MKTA... >ligand|smiles CCO """ # Chai handles both protein and small molecules
bash# Multiple sequences for fasta in sequences/*.fasta; do chai-lab predict \ --fasta "$fasta" \ --output "predictions/$(basename $fasta .fasta)" done
| Aspect | Chai-1 | AlphaFold2 | |--------|--------|------------| | MSA required | No | Yes | | Small molecules | Yes | No | | DNA/RNA | Yes | Limited | | Speed | Faster | Slower | | Accuracy | Comparable | Reference |
$ chai-lab predict --fasta complex.fasta --output predictions/
[INFO] Loading Chai-1 model...
[INFO] Running inference...
[INFO] Saved 5 models to predictions/
predictions/scores.json:
{
"ptm": 0.82,
"iptm": 0.71,
"ranking_score": 0.76
}What good output looks like:
Should I use Chai?
│
├─ What are you predicting?
│ ├─ Protein-protein complex → Chai ✓ or ColabFold
│ ├─ Protein + small molecule → Chai ✓
│ ├─ Protein + DNA/RNA → Chai ✓
│ └─ Single protein only → Use ESMFold (faster)
│
├─ Need MSA?
│ ├─ No / want speed → Chai ✓
│ └─ Yes / want accuracy → ColabFold
│
└─ Priority?
├─ Highest accuracy → ColabFold with MSA
├─ Speed / no MSA → Chai ✓
└─ Ligand binding → Chai ✓| Campaign Size | Time (A100) | Cost (Modal) | Notes | |---------------|-------------|--------------|-------| | 100 complexes | 30-60 min | ~$10 | Standard validation | | 500 complexes | 2-4h | ~$45 | Large campaign | | 1000 complexes | 5-8h | ~$90 | Comprehensive |
Per-complex: ~20-40s for typical binder-target complex.
bashfind predictions -name "*.cif" | wc -l # Should match input count
Low pLDDT: Increase num_trunk_recycles Low ipTM: Check chain order, interface region OOM errors: Use A100-80GB or reduce batch Slow prediction: Reduce num_diffn_timesteps
| Error | Cause | Fix | |-------|-------|-----| | RuntimeError: CUDA out of memory | Complex too large | Use A100-80GB or split prediction | | KeyError: 'iptm' | Single chain predicted | Ensure FASTA has multiple chains | | ValueError: invalid SMILES | Malformed ligand | Validate SMILES with RDKit | | torch.cuda.OutOfMemoryError | GPU exhausted | Reduce num_diffn_timesteps to 100 |
Next: protein-qc for filtering and ranking.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-07 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +45 percentage points is the difference between those two pass rates over the 22 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.