Commit ·
54bab0b
0
Parent(s):
HaploLM and HaploLM-VL
Browse files- .gitattributes +35 -0
- README.md +116 -0
- SC30/checkpoint.pt +3 -0
- VC/checkpoint.pt +3 -0
.gitattributes
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
README.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
library_name: pytorch
|
| 4 |
+
tags:
|
| 5 |
+
- biology
|
| 6 |
+
- genomics
|
| 7 |
+
- dna
|
| 8 |
+
- mitochondrial-dna
|
| 9 |
+
- haplogroups
|
| 10 |
+
- dna-language-model
|
| 11 |
+
---
|
| 12 |
+
|
| 13 |
+
# HaploLM
|
| 14 |
+
|
| 15 |
+
HaploLM and HaploLM-VL are the two DNA language models of the paper **Human Maternal Family Tree
|
| 16 |
+
from DNA Language Models** by Faias Satter and Aminul Islam.
|
| 17 |
+
They are trained only to predict human mitochondrial DNA and never see a haplogroup label, yet
|
| 18 |
+
they learn the human maternal family tree (Mitotree).
|
| 19 |
+
|
| 20 |
+
Code, data preparation and every test: [github.com/FaiasPromit/HaploLM](https://github.com/FaiasPromit/HaploLM)
|
| 21 |
+
|
| 22 |
+
| Folder | Model | Reads | Parameters | Training |
|
| 23 |
+
|---|---|---|---|---|
|
| 24 |
+
| `SC30/` | **HaploLM** | the whole mitochondrial sequence, base by base | 20.6M | causal (each base predicted from the bases before it), 30 epochs over 49,310 sequences |
|
| 25 |
+
| `VC/` | **HaploLM-VL** | only the person's variants (differences from the reference sequence, rCRS), about 37 per person | 11.2M | causal, 20,000 steps of 128 people (about 52 epochs over 49,259 variant lists) |
|
| 26 |
+
|
| 27 |
+
Each folder holds `checkpoint.pt`, a PyTorch file with the parameters (`model`), the settings
|
| 28 |
+
(`args`) and the training step (`step`). For HaploLM-VL, `vocab` maps every distinct variant
|
| 29 |
+
seen in training to its token. The folder names are the run names used in the GitHub repository.
|
| 30 |
+
|
| 31 |
+
## Results
|
| 32 |
+
|
| 33 |
+
| Model | Marker test | Frequency-matched | Carrier vs. relative | Held-out branches |
|
| 34 |
+
|---|---|---|---|---|
|
| 35 |
+
| Counting (no model) | .890 | .533 | .500 | .475 |
|
| 36 |
+
| HaploLM | .947 | .872 | .808 | .467 |
|
| 37 |
+
| HaploLM-VL | .955 | .939 | .965 | .502 |
|
| 38 |
+
|
| 39 |
+
- **Marker test**: AUROC for telling a person's branch markers from their private variants, by
|
| 40 |
+
the probability the model gives each variant.
|
| 41 |
+
- **Frequency-matched**: the same, with markers compared only with private variants carried by
|
| 42 |
+
about as many training people.
|
| 43 |
+
- **Carrier vs. relative** (the main score): the share of pairs in which the model finds a
|
| 44 |
+
branch marker more probable in a person who carries it than in a close relative who does not;
|
| 45 |
+
0.5 is random guessing.
|
| 46 |
+
- **Held-out branches** (negative control): the marker test on six branches excluded from
|
| 47 |
+
training. A model that relies on relationships learned during training should score near 0.5
|
| 48 |
+
here, and all models do.
|
| 49 |
+
|
| 50 |
+
Counting scores a variant by how many training people carry it. The published Evo 2, NTv3 and
|
| 51 |
+
mtDNA-FM score close to random guessing on all four tests.
|
| 52 |
+
|
| 53 |
+
## How to use
|
| 54 |
+
|
| 55 |
+
The model code is in the GitHub repository. To score the paper's tests with these checkpoints,
|
| 56 |
+
first build the data (step 1 of the repository's README), then:
|
| 57 |
+
|
| 58 |
+
```bash
|
| 59 |
+
python -c "from huggingface_hub import snapshot_download; snapshot_download('FaiasPromit/HaploLM', local_dir='runs', allow_patterns=['SC30/*', 'VC/*'])"
|
| 60 |
+
torchrun --standalone --nproc_per_node=4 scripts/score_causal_sequence_model.py --run runs/SC30
|
| 61 |
+
python scripts/train_causal_variant_list_model.py --name VC --score-only
|
| 62 |
+
```
|
| 63 |
+
|
| 64 |
+
To load HaploLM in Python and score a variant in a sequence:
|
| 65 |
+
|
| 66 |
+
```python
|
| 67 |
+
import sys
|
| 68 |
+
|
| 69 |
+
import numpy as np
|
| 70 |
+
import torch
|
| 71 |
+
from huggingface_hub import hf_hub_download
|
| 72 |
+
|
| 73 |
+
sys.path.insert(0, "HaploLM/scripts") # the scripts folder of the GitHub repository
|
| 74 |
+
from train_causal_sequence_model import CausalSequenceModel, next_base_logp
|
| 75 |
+
from train_masked_sequence_model import BASE_CODE
|
| 76 |
+
|
| 77 |
+
ck = torch.load(hf_hub_download("FaiasPromit/HaploLM", "SC30/checkpoint.pt"),
|
| 78 |
+
map_location="cpu", weights_only=False)
|
| 79 |
+
a = ck["args"]
|
| 80 |
+
model = CausalSequenceModel(a["d"], a["layers"], a["heads"], dropout=0.0)
|
| 81 |
+
model.load_state_dict(ck["model"])
|
| 82 |
+
model.eval()
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
def log_prob(seq):
|
| 86 |
+
"""log P(seq): the sum over bases of log P(base | the bases before it)."""
|
| 87 |
+
ids = torch.from_numpy(BASE_CODE[np.frombuffer(seq.encode("ascii"), np.uint8)]).long()[None]
|
| 88 |
+
with torch.no_grad():
|
| 89 |
+
lp, _ = next_base_logp(model(ids), ids)
|
| 90 |
+
return lp.double().sum().item()
|
| 91 |
+
|
| 92 |
+
# score of a variant, as in the paper:
|
| 93 |
+
# log_prob(sequence with the variant) - log_prob(the same sequence with the rCRS base there)
|
| 94 |
+
```
|
| 95 |
+
|
| 96 |
+
The sequence must be in upper case, start at position 1 of the rCRS (the repository's
|
| 97 |
+
`clean_sequences.py` rotates sequences this way) and be at most 16,768 bases long. A GPU is much
|
| 98 |
+
faster: move `model` and `ids` to `"cuda"`.
|
| 99 |
+
|
| 100 |
+
## Training data
|
| 101 |
+
|
| 102 |
+
49,310 human mitochondrial genomes from GenBank, on MITOMAP's list of full-length sequences:
|
| 103 |
+
the training set of our split. Identical sequences are always in the same set, and six
|
| 104 |
+
branches (L0a1, L3f, M9a, D4b, H13 and U2e), with everything below them, are held out of
|
| 105 |
+
training. The haplogroup labels, from HaploGrep 3 with Mitotree 2026.05.06, are used only to
|
| 106 |
+
evaluate the models.
|
| 107 |
+
|
| 108 |
+
## Limitations
|
| 109 |
+
|
| 110 |
+
- The models are trained on human mitochondrial DNA only.
|
| 111 |
+
- The answer key depends on HaploGrep and Mitotree. The tests limit the effects of errors by
|
| 112 |
+
excluding poorly assigned sequences, hotspots and the control region.
|
| 113 |
+
- Public mitochondrial data overrepresent some populations, leaving lineages common in
|
| 114 |
+
undersampled populations with fewer training examples.
|
| 115 |
+
- They are research models for studying what DNA language models learn. They are not
|
| 116 |
+
haplogroup classifiers and are not validated for medical or forensic use.
|
SC30/checkpoint.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:af819268c3f8e14ad668240423b51ca6fe4239d920343a88dc64b7a1b689ad98
|
| 3 |
+
size 82597303
|
VC/checkpoint.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8d988d0071d64a52525cfd0751822b98b5e67acf10b03a0d1b79b3c5e13661e6
|
| 3 |
+
size 45275125
|