mrna-bench 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mrna_bench-1.0.0/LICENSE +21 -0
- mrna_bench-1.0.0/PKG-INFO +160 -0
- mrna_bench-1.0.0/README.md +108 -0
- mrna_bench-1.0.0/mrna_bench/__init__.py +9 -0
- mrna_bench-1.0.0/mrna_bench/data_splitter/__init__.py +0 -0
- mrna_bench-1.0.0/mrna_bench/data_splitter/data_splitter.py +53 -0
- mrna_bench-1.0.0/mrna_bench/data_splitter/homology_split.py +200 -0
- mrna_bench-1.0.0/mrna_bench/data_splitter/sklearn_split.py +31 -0
- mrna_bench-1.0.0/mrna_bench/data_splitter/split_catalog.py +11 -0
- mrna_bench-1.0.0/mrna_bench/datasets/__init__.py +7 -0
- mrna_bench-1.0.0/mrna_bench/datasets/benchmark_dataset.py +134 -0
- mrna_bench-1.0.0/mrna_bench/datasets/dataset_catalog.py +20 -0
- mrna_bench-1.0.0/mrna_bench/datasets/dataset_utils.py +46 -0
- mrna_bench-1.0.0/mrna_bench/datasets/go_mol_func.py +51 -0
- mrna_bench-1.0.0/mrna_bench/datasets/lncrna_essentiality.py +25 -0
- mrna_bench-1.0.0/mrna_bench/datasets/mrl_sugimoto.py +51 -0
- mrna_bench-1.0.0/mrna_bench/datasets/pcg_essentiality.py +25 -0
- mrna_bench-1.0.0/mrna_bench/datasets/prot_loc.py +54 -0
- mrna_bench-1.0.0/mrna_bench/datasets/rna_hl_human.py +51 -0
- mrna_bench-1.0.0/mrna_bench/datasets/rna_hl_mouse.py +51 -0
- mrna_bench-1.0.0/mrna_bench/embedder/__init__.py +7 -0
- mrna_bench-1.0.0/mrna_bench/embedder/dataset_embedder.py +173 -0
- mrna_bench-1.0.0/mrna_bench/embedder/embedder_utils.py +31 -0
- mrna_bench-1.0.0/mrna_bench/linear_probe/__init__.py +5 -0
- mrna_bench-1.0.0/mrna_bench/linear_probe/linear_probe.py +438 -0
- mrna_bench-1.0.0/mrna_bench/loader/__init__.py +0 -0
- mrna_bench-1.0.0/mrna_bench/loader/loader.py +48 -0
- mrna_bench-1.0.0/mrna_bench/models/__init__.py +7 -0
- mrna_bench-1.0.0/mrna_bench/models/aido.py +90 -0
- mrna_bench-1.0.0/mrna_bench/models/dnabert.py +76 -0
- mrna_bench-1.0.0/mrna_bench/models/embedding_model.py +138 -0
- mrna_bench-1.0.0/mrna_bench/models/hyenadna.py +86 -0
- mrna_bench-1.0.0/mrna_bench/models/model_catalog.py +20 -0
- mrna_bench-1.0.0/mrna_bench/models/nucleotide_transformer.py +104 -0
- mrna_bench-1.0.0/mrna_bench/models/orthrus.py +135 -0
- mrna_bench-1.0.0/mrna_bench/models/rnafm.py +160 -0
- mrna_bench-1.0.0/mrna_bench/utils.py +104 -0
- mrna_bench-1.0.0/mrna_bench.egg-info/PKG-INFO +160 -0
- mrna_bench-1.0.0/mrna_bench.egg-info/SOURCES.txt +42 -0
- mrna_bench-1.0.0/mrna_bench.egg-info/dependency_links.txt +1 -0
- mrna_bench-1.0.0/mrna_bench.egg-info/requires.txt +18 -0
- mrna_bench-1.0.0/mrna_bench.egg-info/top_level.txt +1 -0
- mrna_bench-1.0.0/pyproject.toml +51 -0
- mrna_bench-1.0.0/setup.cfg +4 -0
mrna_bench-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Ian Shi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: mrna-bench
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Benchmarking suite for mRNA property prediction.
|
|
5
|
+
Author-email: "Ruian (Ian) Shi" <ian.shi@mail.utoronto.ca>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2024 Ian Shi
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Repository, https://github.com/IanShi1996/mRNABench
|
|
29
|
+
Keywords: mrna,genomic foundation model,benchmark
|
|
30
|
+
Classifier: Programming Language :: Python :: 3
|
|
31
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
32
|
+
Classifier: Operating System :: Unix
|
|
33
|
+
Requires-Python: >=3.10
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
License-File: LICENSE
|
|
36
|
+
Requires-Dist: tqdm
|
|
37
|
+
Requires-Dist: PyYAML
|
|
38
|
+
Requires-Dist: scikit-learn
|
|
39
|
+
Requires-Dist: numpy<2
|
|
40
|
+
Requires-Dist: pandas<=2.2.2
|
|
41
|
+
Requires-Dist: requests
|
|
42
|
+
Provides-Extra: base-models
|
|
43
|
+
Requires-Dist: torch==2.2.2; extra == "base-models"
|
|
44
|
+
Requires-Dist: transformers==4.29.1; extra == "base-models"
|
|
45
|
+
Requires-Dist: mamba-ssm==1.2.0.post1; extra == "base-models"
|
|
46
|
+
Requires-Dist: rna-fm==0.2.2; extra == "base-models"
|
|
47
|
+
Requires-Dist: accelerate; extra == "base-models"
|
|
48
|
+
Provides-Extra: dev
|
|
49
|
+
Requires-Dist: mypy; extra == "dev"
|
|
50
|
+
Requires-Dist: flake8; extra == "dev"
|
|
51
|
+
Requires-Dist: flake8-docstrings; extra == "dev"
|
|
52
|
+
|
|
53
|
+
# mRNABench
|
|
54
|
+
This repository contains a workflow to benchmark the embedding quality of genomic foundation models on (m)RNA specific tasks. The mRNABench contains a catalogue of datasets and training split logic which can be used to evaluate the embedding quality of several catalogued models.
|
|
55
|
+
|
|
56
|
+
**Jump to:** [Model Catalog](#model-catalog) [Dataset Catalog](#dataset-catalog)
|
|
57
|
+
|
|
58
|
+
## Setup
|
|
59
|
+
Several configurations of the mRNABench are available.
|
|
60
|
+
|
|
61
|
+
### Datasets Only
|
|
62
|
+
If you are interested in the benchmark datasets **only**, you can run:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install mrna-bench
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Full Version
|
|
69
|
+
The inference-capable version of mRNABench that can generate embeddings using
|
|
70
|
+
Orthrus, DNA-BERT2, NucleotideTransformer, RNA-FM, and HyenaDNA can be
|
|
71
|
+
installed as shown below. Note that this requires PyTorch version 2.2.2 with
|
|
72
|
+
CUDA 12.1 and Triton uninstalled (due to a DNA-BERT2 issue).
|
|
73
|
+
```bash
|
|
74
|
+
conda create --name mrna_bench python=3.10
|
|
75
|
+
conda activate mrna_bench
|
|
76
|
+
|
|
77
|
+
pip install torch==2.2.2 --index-url https://download.pytorch.org/whl/cu121
|
|
78
|
+
pip install mrna-bench[base_models]
|
|
79
|
+
pip uninstall triton
|
|
80
|
+
```
|
|
81
|
+
Inference with other models will require the installation of the model's
|
|
82
|
+
dependencies first, which are usually listed on the model's GitHub page (see below).
|
|
83
|
+
|
|
84
|
+
### Post-install
|
|
85
|
+
After installation, please run the following in Python to set where data associated with the benchmarks will be stored.
|
|
86
|
+
```python
|
|
87
|
+
import mrna_bench as mb
|
|
88
|
+
|
|
89
|
+
path_to_dir_to_store_data = "DESIRED_PATH"
|
|
90
|
+
mb.update_data_path(path_to_dir_to_store_data)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Usage
|
|
94
|
+
Datasets can be retrieved using:
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
import mrna_bench as mb
|
|
98
|
+
|
|
99
|
+
dataset = mb.load_dataset("go-mf")
|
|
100
|
+
data_df = dataset.data_df
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The mRNABench can also be used to test out common genomic foundation models:
|
|
104
|
+
```python
|
|
105
|
+
import torch
|
|
106
|
+
|
|
107
|
+
import mrna_bench as mb
|
|
108
|
+
from mrna_bench.embedder import DatasetEmbedder
|
|
109
|
+
from mrna_bench.linear_probe import LinearProbe
|
|
110
|
+
|
|
111
|
+
device = torch.device("cuda")
|
|
112
|
+
|
|
113
|
+
dataset = mb.load_dataset("go-mf")
|
|
114
|
+
model = mb.load_model("Orthrus", "orthrus-large-6-track", device)
|
|
115
|
+
|
|
116
|
+
embedder = DatasetEmbedder(model, dataset)
|
|
117
|
+
embeddings = embedder.embed_dataset()
|
|
118
|
+
embeddings = embeddings.detach().cpu().numpy()
|
|
119
|
+
|
|
120
|
+
prober = LinearProbe(
|
|
121
|
+
dataset=dataset,
|
|
122
|
+
embeddings=embeddings,
|
|
123
|
+
task="multilabel",
|
|
124
|
+
target_col="target",
|
|
125
|
+
split_type="homology"
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
metrics = prober.run_linear_probe()
|
|
129
|
+
print(metrics)
|
|
130
|
+
```
|
|
131
|
+
Also see the `scripts/` folder for example scripts that uses slurm to embed dataset chunks in parallel for reduce runtime, as well as an example of multi-seed linear probing.
|
|
132
|
+
|
|
133
|
+
## Model Catalog
|
|
134
|
+
The current models catalogued are:
|
|
135
|
+
|
|
136
|
+
| Model Name | Model Versions | Description | Citation | Supported<br>by<br>`base_models` |
|
|
137
|
+
| :--------: | ---------------------- | ------------- | :------: | :------------------------: |
|
|
138
|
+
| `Orthrus` | `orthrus_large_6_track`<br> `orthrus_base_4_track` | Mamba-based RNA FM pre-trained using contrastive learning. | [code](https://github.com/bowang-lab/Orthrus) [paper](https://www.biorxiv.org/content/10.1101/2024.10.10.617658v2)| ✅ |
|
|
139
|
+
| `AIDO.RNA` | `aido_rna_650m` <br> `aido_rna_650m_cds` <br> `aido_rna_1b600m` <br> `aido_rna_1b600m_cds` | Encoder Transformer-based RNA FM pre-trained using MLM on 42M ncRNA sequences. Version that is domain adapted to CDS is available. | [paper](https://www.biorxiv.org/content/10.1101/2024.11.28.625345v1) | |
|
|
140
|
+
| `RNA-FM` | `rna-fm` <br> `mrna-fm` | Transformer-based RNA FM pre-trained using MLM on 23M ncRNA sequences. mRNA-FM trained on CDS using codon tokenizer. | [github](https://github.com/ml4bio/RNA-FM) | ✅ |
|
|
141
|
+
| `DNABERT2` | `dnabert2` | Transformer-based DNA FM pre-trained using MLM on multispecies genomic dataset. Uses BPE and other modern architectural improvements for efficiency. | [github](https://github.com/MAGICS-LAB/DNABERT_2) | ✅ |
|
|
142
|
+
| `NucleotideTransformer` | `2.5b-multi-species` <br> `2.5b-1000g` <br> `500m-human-ref` <br> `500m-1000g` <br> `v2-50m-multi-species` <br> `v2-100m-multi-species` <br> `v2-250m-multi-species` <br> `v2-500m-multi-species` | Transformer-based DNA FM pre-trained using MLM on a variety of possible datasets at various model sizes. Sequence is tokenized using 6-mers. | [github](https://github.com/instadeepai/nucleotide-transformer) | ✅ |
|
|
143
|
+
| `HyenaDNA` | `hyenadna-large-1m-seqlen-hf` <br> `hyenadna-medium-450k-seqlen-hf` <br> `hyenadna-medium-160k-seqlen-hf` <br> `hyenadna-small-32k-seqlen-hf` <br> `hyenadna-tiny-16k-seqlen-d128-hf` | Hyena-based DNA FM pre-trained using NTP on the human reference genome. Available at various model sizes and pretraining sequence contexts. | [github](https://github.com/HazyResearch/hyena-dna) | ✅ |
|
|
144
|
+
|
|
145
|
+
### Adding a new model
|
|
146
|
+
All models should inherit from the template `EmbeddingModel`. Each model file should lazily load dependencies within its `__init__` methods so each model can be used individually without install all other models. Models must implement `get_model_short_name(model_version)` which fetches the internal name for the model. This must be unique for every model version and must not contain underscores. Models should implement either `embed_sequence` or `embed_sequence_sixtrack` (see code for method signature). New models should be added to `MODEL_CATALOG`.
|
|
147
|
+
|
|
148
|
+
## Dataset Catalog
|
|
149
|
+
The current datasets catalogued are:
|
|
150
|
+
| Dataset Name | Catalogue Identifier | Description | Tasks | Citation |
|
|
151
|
+
|---|---|---|---|---|
|
|
152
|
+
| GO Molecular Function | <code>go-mf</code> | Classification of the molecular function of a transcript's product as defined by the GO Resource. | `multilabel` | [website](https://geneontology.org/) |
|
|
153
|
+
| Mean Ribosome Load (Sugimoto) | <code>mrl‑sugimoto</code> | Mean Ribosome Load per transcript isoform as measured in Sugimoto et al. 2022. | `regression` | [paper](https://www.nature.com/articles/s41594-022-00819-2) |
|
|
154
|
+
| RNA Half-life (Human) | <code>rnahl‑human</code> | RNA half-life of human transcripts collected by Agarwal et al. 2022. | `regression` | [paper](https://genomebiology.biomedcentral.com/articles/10.1186/s13059-022-02811-x) |
|
|
155
|
+
| RNA Half-life (Mouse) | <code>rnahl‑mouse</code> | RNA half-life of mouse transcripts collected by Agarwal et al. 2022. | `regression` | [paper](https://genomebiology.biomedcentral.com/articles/10.1186/s13059-022-02811-x) |
|
|
156
|
+
| Protein Subcellular Localization | <code>prot‑loc</code> | Subcellular localization of transcript protein product defined in Protein Atlas. | `multilabel` | [website](https://www.proteinatlas.org/) |
|
|
157
|
+
| Protein Coding Gene Essentiality | <code>pcg‑ess</code> | Essentiality of PCGs as measured by CRISPR knockdown. Log-fold expression and binary essentiality available on several cell lines. | `regression` `classification`| [paper](https://www.cell.com/cell/fulltext/S0092-8674(24)01203-0)|
|
|
158
|
+
|
|
159
|
+
### Adding a new dataset
|
|
160
|
+
New datasets should inherit from `BenchmarkDataset`. Dataset names cannot contain underscores. Each new dataset should download raw data and process it into a dataframe by overriding `process_raw_data`. This dataframe should store transcript as rows, using string encoding in the `sequence` column. If homology splitting is required, a column `gene` containing gene names is required. Six track embedding also requires columns `cds` and `splice`. The target column can have any name, as it is specified at time of probing. New datasets should be added to `DATASET_CATALOG`.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# mRNABench
|
|
2
|
+
This repository contains a workflow to benchmark the embedding quality of genomic foundation models on (m)RNA specific tasks. The mRNABench contains a catalogue of datasets and training split logic which can be used to evaluate the embedding quality of several catalogued models.
|
|
3
|
+
|
|
4
|
+
**Jump to:** [Model Catalog](#model-catalog) [Dataset Catalog](#dataset-catalog)
|
|
5
|
+
|
|
6
|
+
## Setup
|
|
7
|
+
Several configurations of the mRNABench are available.
|
|
8
|
+
|
|
9
|
+
### Datasets Only
|
|
10
|
+
If you are interested in the benchmark datasets **only**, you can run:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pip install mrna-bench
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### Full Version
|
|
17
|
+
The inference-capable version of mRNABench that can generate embeddings using
|
|
18
|
+
Orthrus, DNA-BERT2, NucleotideTransformer, RNA-FM, and HyenaDNA can be
|
|
19
|
+
installed as shown below. Note that this requires PyTorch version 2.2.2 with
|
|
20
|
+
CUDA 12.1 and Triton uninstalled (due to a DNA-BERT2 issue).
|
|
21
|
+
```bash
|
|
22
|
+
conda create --name mrna_bench python=3.10
|
|
23
|
+
conda activate mrna_bench
|
|
24
|
+
|
|
25
|
+
pip install torch==2.2.2 --index-url https://download.pytorch.org/whl/cu121
|
|
26
|
+
pip install mrna-bench[base_models]
|
|
27
|
+
pip uninstall triton
|
|
28
|
+
```
|
|
29
|
+
Inference with other models will require the installation of the model's
|
|
30
|
+
dependencies first, which are usually listed on the model's GitHub page (see below).
|
|
31
|
+
|
|
32
|
+
### Post-install
|
|
33
|
+
After installation, please run the following in Python to set where data associated with the benchmarks will be stored.
|
|
34
|
+
```python
|
|
35
|
+
import mrna_bench as mb
|
|
36
|
+
|
|
37
|
+
path_to_dir_to_store_data = "DESIRED_PATH"
|
|
38
|
+
mb.update_data_path(path_to_dir_to_store_data)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Usage
|
|
42
|
+
Datasets can be retrieved using:
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
import mrna_bench as mb
|
|
46
|
+
|
|
47
|
+
dataset = mb.load_dataset("go-mf")
|
|
48
|
+
data_df = dataset.data_df
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The mRNABench can also be used to test out common genomic foundation models:
|
|
52
|
+
```python
|
|
53
|
+
import torch
|
|
54
|
+
|
|
55
|
+
import mrna_bench as mb
|
|
56
|
+
from mrna_bench.embedder import DatasetEmbedder
|
|
57
|
+
from mrna_bench.linear_probe import LinearProbe
|
|
58
|
+
|
|
59
|
+
device = torch.device("cuda")
|
|
60
|
+
|
|
61
|
+
dataset = mb.load_dataset("go-mf")
|
|
62
|
+
model = mb.load_model("Orthrus", "orthrus-large-6-track", device)
|
|
63
|
+
|
|
64
|
+
embedder = DatasetEmbedder(model, dataset)
|
|
65
|
+
embeddings = embedder.embed_dataset()
|
|
66
|
+
embeddings = embeddings.detach().cpu().numpy()
|
|
67
|
+
|
|
68
|
+
prober = LinearProbe(
|
|
69
|
+
dataset=dataset,
|
|
70
|
+
embeddings=embeddings,
|
|
71
|
+
task="multilabel",
|
|
72
|
+
target_col="target",
|
|
73
|
+
split_type="homology"
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
metrics = prober.run_linear_probe()
|
|
77
|
+
print(metrics)
|
|
78
|
+
```
|
|
79
|
+
Also see the `scripts/` folder for example scripts that uses slurm to embed dataset chunks in parallel for reduce runtime, as well as an example of multi-seed linear probing.
|
|
80
|
+
|
|
81
|
+
## Model Catalog
|
|
82
|
+
The current models catalogued are:
|
|
83
|
+
|
|
84
|
+
| Model Name | Model Versions | Description | Citation | Supported<br>by<br>`base_models` |
|
|
85
|
+
| :--------: | ---------------------- | ------------- | :------: | :------------------------: |
|
|
86
|
+
| `Orthrus` | `orthrus_large_6_track`<br> `orthrus_base_4_track` | Mamba-based RNA FM pre-trained using contrastive learning. | [code](https://github.com/bowang-lab/Orthrus) [paper](https://www.biorxiv.org/content/10.1101/2024.10.10.617658v2)| ✅ |
|
|
87
|
+
| `AIDO.RNA` | `aido_rna_650m` <br> `aido_rna_650m_cds` <br> `aido_rna_1b600m` <br> `aido_rna_1b600m_cds` | Encoder Transformer-based RNA FM pre-trained using MLM on 42M ncRNA sequences. Version that is domain adapted to CDS is available. | [paper](https://www.biorxiv.org/content/10.1101/2024.11.28.625345v1) | |
|
|
88
|
+
| `RNA-FM` | `rna-fm` <br> `mrna-fm` | Transformer-based RNA FM pre-trained using MLM on 23M ncRNA sequences. mRNA-FM trained on CDS using codon tokenizer. | [github](https://github.com/ml4bio/RNA-FM) | ✅ |
|
|
89
|
+
| `DNABERT2` | `dnabert2` | Transformer-based DNA FM pre-trained using MLM on multispecies genomic dataset. Uses BPE and other modern architectural improvements for efficiency. | [github](https://github.com/MAGICS-LAB/DNABERT_2) | ✅ |
|
|
90
|
+
| `NucleotideTransformer` | `2.5b-multi-species` <br> `2.5b-1000g` <br> `500m-human-ref` <br> `500m-1000g` <br> `v2-50m-multi-species` <br> `v2-100m-multi-species` <br> `v2-250m-multi-species` <br> `v2-500m-multi-species` | Transformer-based DNA FM pre-trained using MLM on a variety of possible datasets at various model sizes. Sequence is tokenized using 6-mers. | [github](https://github.com/instadeepai/nucleotide-transformer) | ✅ |
|
|
91
|
+
| `HyenaDNA` | `hyenadna-large-1m-seqlen-hf` <br> `hyenadna-medium-450k-seqlen-hf` <br> `hyenadna-medium-160k-seqlen-hf` <br> `hyenadna-small-32k-seqlen-hf` <br> `hyenadna-tiny-16k-seqlen-d128-hf` | Hyena-based DNA FM pre-trained using NTP on the human reference genome. Available at various model sizes and pretraining sequence contexts. | [github](https://github.com/HazyResearch/hyena-dna) | ✅ |
|
|
92
|
+
|
|
93
|
+
### Adding a new model
|
|
94
|
+
All models should inherit from the template `EmbeddingModel`. Each model file should lazily load dependencies within its `__init__` methods so each model can be used individually without install all other models. Models must implement `get_model_short_name(model_version)` which fetches the internal name for the model. This must be unique for every model version and must not contain underscores. Models should implement either `embed_sequence` or `embed_sequence_sixtrack` (see code for method signature). New models should be added to `MODEL_CATALOG`.
|
|
95
|
+
|
|
96
|
+
## Dataset Catalog
|
|
97
|
+
The current datasets catalogued are:
|
|
98
|
+
| Dataset Name | Catalogue Identifier | Description | Tasks | Citation |
|
|
99
|
+
|---|---|---|---|---|
|
|
100
|
+
| GO Molecular Function | <code>go-mf</code> | Classification of the molecular function of a transcript's product as defined by the GO Resource. | `multilabel` | [website](https://geneontology.org/) |
|
|
101
|
+
| Mean Ribosome Load (Sugimoto) | <code>mrl‑sugimoto</code> | Mean Ribosome Load per transcript isoform as measured in Sugimoto et al. 2022. | `regression` | [paper](https://www.nature.com/articles/s41594-022-00819-2) |
|
|
102
|
+
| RNA Half-life (Human) | <code>rnahl‑human</code> | RNA half-life of human transcripts collected by Agarwal et al. 2022. | `regression` | [paper](https://genomebiology.biomedcentral.com/articles/10.1186/s13059-022-02811-x) |
|
|
103
|
+
| RNA Half-life (Mouse) | <code>rnahl‑mouse</code> | RNA half-life of mouse transcripts collected by Agarwal et al. 2022. | `regression` | [paper](https://genomebiology.biomedcentral.com/articles/10.1186/s13059-022-02811-x) |
|
|
104
|
+
| Protein Subcellular Localization | <code>prot‑loc</code> | Subcellular localization of transcript protein product defined in Protein Atlas. | `multilabel` | [website](https://www.proteinatlas.org/) |
|
|
105
|
+
| Protein Coding Gene Essentiality | <code>pcg‑ess</code> | Essentiality of PCGs as measured by CRISPR knockdown. Log-fold expression and binary essentiality available on several cell lines. | `regression` `classification`| [paper](https://www.cell.com/cell/fulltext/S0092-8674(24)01203-0)|
|
|
106
|
+
|
|
107
|
+
### Adding a new dataset
|
|
108
|
+
New datasets should inherit from `BenchmarkDataset`. Dataset names cannot contain underscores. Each new dataset should download raw data and process it into a dataframe by overriding `process_raw_data`. This dataframe should store transcript as rows, using string encoding in the `sequence` column. If homology splitting is required, a column `gene` containing gene names is required. Six track embedding also requires columns `cds` and `splice`. The target column can have any name, as it is specified at time of probing. New datasets should be added to `DATASET_CATALOG`.
|
|
File without changes
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
|
|
3
|
+
import pandas as pd
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class DataSplitter(ABC):
|
|
7
|
+
"""Generates reproducible train test splits."""
|
|
8
|
+
|
|
9
|
+
@abstractmethod
|
|
10
|
+
def split_df(
|
|
11
|
+
self,
|
|
12
|
+
df: pd.DataFrame,
|
|
13
|
+
test_size: float,
|
|
14
|
+
random_seed: int
|
|
15
|
+
) -> tuple[pd.DataFrame, pd.DataFrame]:
|
|
16
|
+
"""Split dataframe into train and test dataframes.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
df: Dataframe to split.
|
|
20
|
+
test_size: Fraction of dataset to assign to test split.
|
|
21
|
+
random_seed: Random seed used during split sampling.
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
Train and test dataframes.
|
|
25
|
+
"""
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
def get_all_splits_df(
|
|
29
|
+
self,
|
|
30
|
+
df: pd.DataFrame,
|
|
31
|
+
split_ratios: tuple[float, float, float],
|
|
32
|
+
random_seed: int,
|
|
33
|
+
) -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:
|
|
34
|
+
"""Get train, validation, test splits.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
df: Dataframe to split.
|
|
38
|
+
split_ratios: Ratio of training, validation, test split size.
|
|
39
|
+
random_seed: Random seed used to generate splits.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
Dataframe containing training, validation, test splits.
|
|
43
|
+
"""
|
|
44
|
+
if sum(split_ratios) != 1:
|
|
45
|
+
raise ValueError("Split ratios must sum to 1.")
|
|
46
|
+
|
|
47
|
+
tv_split_size = split_ratios[1] + split_ratios[2]
|
|
48
|
+
test_split_size = split_ratios[2] / tv_split_size
|
|
49
|
+
|
|
50
|
+
train_df, tv_df = self.split_df(df, tv_split_size, random_seed)
|
|
51
|
+
val_df, test_df = self.split_df(tv_df, test_split_size, random_seed)
|
|
52
|
+
|
|
53
|
+
return train_df, val_df, test_df
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
import shutil
|
|
3
|
+
import zipfile
|
|
4
|
+
|
|
5
|
+
import pandas as pd
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
from mrna_bench import get_data_path
|
|
9
|
+
from mrna_bench.data_splitter.data_splitter import DataSplitter
|
|
10
|
+
from mrna_bench.utils import download_file
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def train_test_split_homologous(
|
|
14
|
+
genes: list[str],
|
|
15
|
+
homology_df: pd.DataFrame,
|
|
16
|
+
test_size: float = 0.3,
|
|
17
|
+
random_state: int | None = None
|
|
18
|
+
) -> tuple[list[int], list[int]]:
|
|
19
|
+
"""Split genes into two sets with homologous genes in the same set.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
genes: List of gene names.
|
|
23
|
+
homology_df: DataFrame with columns "gene_name" and "gene_group".
|
|
24
|
+
test_size: Fraction of data allocated to test split.
|
|
25
|
+
random_state: Defaults to None.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
Dictionary with keys "train_indices" and "test_indices" containing the
|
|
29
|
+
indices of the genes in the train and test sets respectively.
|
|
30
|
+
"""
|
|
31
|
+
# Map genes to their respective homology groups
|
|
32
|
+
homo_group_map = homology_df.set_index("gene_name")["gene_group"].to_dict()
|
|
33
|
+
|
|
34
|
+
gene_groups = np.array([homo_group_map.get(gene, None) for gene in genes])
|
|
35
|
+
|
|
36
|
+
group_to_index: dict[int, list[int]] = {}
|
|
37
|
+
|
|
38
|
+
# Populate the group_to_index dictionary
|
|
39
|
+
for i, group in enumerate(gene_groups):
|
|
40
|
+
if group is not None:
|
|
41
|
+
group_to_index.setdefault(group, []).append(i)
|
|
42
|
+
|
|
43
|
+
gene_index = np.arange(len(genes))
|
|
44
|
+
|
|
45
|
+
np.random.seed(random_state)
|
|
46
|
+
np.random.shuffle(gene_index)
|
|
47
|
+
|
|
48
|
+
len_of_train = int(len(gene_index) * (1 - test_size))
|
|
49
|
+
|
|
50
|
+
train_indices: list[int] = []
|
|
51
|
+
test_indices: list[int] = []
|
|
52
|
+
|
|
53
|
+
seen_groups = set()
|
|
54
|
+
|
|
55
|
+
for index in gene_index:
|
|
56
|
+
group = gene_groups[index]
|
|
57
|
+
if group is not None and group in seen_groups:
|
|
58
|
+
continue
|
|
59
|
+
|
|
60
|
+
seen_groups.add(group)
|
|
61
|
+
|
|
62
|
+
if len(train_indices) < len_of_train:
|
|
63
|
+
train_indices.extend(group_to_index.get(group, [index]))
|
|
64
|
+
else:
|
|
65
|
+
test_indices.extend(group_to_index.get(group, [index]))
|
|
66
|
+
|
|
67
|
+
train_indices = [int(ind) for ind in train_indices]
|
|
68
|
+
test_indices = [int(ind) for ind in test_indices]
|
|
69
|
+
|
|
70
|
+
return train_indices, test_indices
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class HomologySplitter(DataSplitter):
|
|
74
|
+
"""Homology-based data splitter.
|
|
75
|
+
|
|
76
|
+
Uses an external homology mapping file to construct train / test splits.
|
|
77
|
+
Genes which are homologous are kept within the same 'side' of the data
|
|
78
|
+
split to reduce data leakage.
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
HOMO_URL = (
|
|
82
|
+
"https://zenodo.org/records/13910050/files/"
|
|
83
|
+
"homology_maps_homologene.zip"
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
def __init__(
|
|
87
|
+
self,
|
|
88
|
+
species: list[str],
|
|
89
|
+
homology_map_path: str | None = None,
|
|
90
|
+
force_redownload: bool = False
|
|
91
|
+
):
|
|
92
|
+
"""Initialize HomologySplitter.
|
|
93
|
+
|
|
94
|
+
Homology splitting requires a dataframe mapping genes to a group
|
|
95
|
+
of homologous genes. This dataframe must have columns "gene_name" and
|
|
96
|
+
"gene_group". If homology_map_path is not specified, relationships
|
|
97
|
+
processed from homologene will be downloaded.
|
|
98
|
+
|
|
99
|
+
Homology map files should be named as: {species}_homology_map.csv
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
species: List of species that genes are from.
|
|
103
|
+
homology_map_path: Path to homology maps.
|
|
104
|
+
force_redownload: Forces redownload of homology maps.
|
|
105
|
+
"""
|
|
106
|
+
super().__init__()
|
|
107
|
+
|
|
108
|
+
if homology_map_path is None:
|
|
109
|
+
data_storage_path = get_data_path()
|
|
110
|
+
self.homology_map_path = data_storage_path + "/homology_maps"
|
|
111
|
+
|
|
112
|
+
if not Path(self.homology_map_path).exists():
|
|
113
|
+
Path(self.homology_map_path).mkdir(exist_ok=True)
|
|
114
|
+
force_redownload = True
|
|
115
|
+
else:
|
|
116
|
+
self.homology_map_path = homology_map_path
|
|
117
|
+
|
|
118
|
+
if force_redownload:
|
|
119
|
+
out = download_file(self.HOMO_URL, self.homology_map_path, True)[0]
|
|
120
|
+
|
|
121
|
+
with zipfile.ZipFile(out, "r") as zip_ref:
|
|
122
|
+
for file in zip_ref.namelist():
|
|
123
|
+
if not file.endswith("/"):
|
|
124
|
+
source = zip_ref.open(file)
|
|
125
|
+
path = Path(self.homology_map_path) / Path(file).name
|
|
126
|
+
|
|
127
|
+
with open(path, "wb") as target:
|
|
128
|
+
shutil.copyfileobj(source, target)
|
|
129
|
+
|
|
130
|
+
Path(out).unlink()
|
|
131
|
+
|
|
132
|
+
self.species = species
|
|
133
|
+
self.homology_df = self.get_homology_df()
|
|
134
|
+
|
|
135
|
+
def get_homology_df(self) -> pd.DataFrame:
|
|
136
|
+
"""Get homology dataframe for specified species.
|
|
137
|
+
|
|
138
|
+
If multiple species exists, naively merges dataframes, merging homology
|
|
139
|
+
groups if gene name overlap exists.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
Dataframe with gene names mapped to homology groups.
|
|
143
|
+
"""
|
|
144
|
+
species_maps = []
|
|
145
|
+
for s in self.species:
|
|
146
|
+
homology_dir = Path(self.homology_map_path)
|
|
147
|
+
homology_map = homology_dir / "{}_homology_map.csv".format(s)
|
|
148
|
+
if not homology_map.exists():
|
|
149
|
+
print("Homology map for species {} is missing.".format(s))
|
|
150
|
+
else:
|
|
151
|
+
species_maps.append(pd.read_csv(homology_map))
|
|
152
|
+
|
|
153
|
+
max_groups = [max(s_df["gene_group"]) for s_df in species_maps]
|
|
154
|
+
cusum_max_groups = np.cumsum(max_groups)
|
|
155
|
+
|
|
156
|
+
for i, s_df in enumerate(species_maps[1:]):
|
|
157
|
+
s_df["gene_group"] += cusum_max_groups[i]
|
|
158
|
+
|
|
159
|
+
out_df = pd.concat(species_maps, axis=0, ignore_index=True)
|
|
160
|
+
|
|
161
|
+
# Merge identical gene names
|
|
162
|
+
out_df.groupby("gene_name", as_index=False).min()
|
|
163
|
+
out_df.reset_index(drop=True, inplace=True)
|
|
164
|
+
|
|
165
|
+
return out_df
|
|
166
|
+
|
|
167
|
+
def split_df(
|
|
168
|
+
self,
|
|
169
|
+
df: pd.DataFrame,
|
|
170
|
+
test_size: float,
|
|
171
|
+
random_seed: int
|
|
172
|
+
) -> tuple[pd.DataFrame, pd.DataFrame]:
|
|
173
|
+
"""Split dataframe rows into train and test df using homology split.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
df: Dataframe to split.
|
|
177
|
+
test_size: Fraction of dataset to assign to test split.
|
|
178
|
+
random_seed: Random seed used for sampling rows during splitting.
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
Dataframe containing train data and test data.
|
|
182
|
+
"""
|
|
183
|
+
if "gene" not in df.columns:
|
|
184
|
+
raise ValueError("Gene must be column for homology split.")
|
|
185
|
+
|
|
186
|
+
genes = df["gene"]
|
|
187
|
+
|
|
188
|
+
train_indices, test_indices = train_test_split_homologous(
|
|
189
|
+
genes,
|
|
190
|
+
self.homology_df,
|
|
191
|
+
test_size,
|
|
192
|
+
random_seed
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
assert len(set(train_indices).intersection(set(test_indices))) == 0
|
|
196
|
+
|
|
197
|
+
train_df = df.iloc[train_indices]
|
|
198
|
+
test_df = df.iloc[test_indices]
|
|
199
|
+
|
|
200
|
+
return train_df, test_df
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from sklearn.model_selection import train_test_split
|
|
2
|
+
|
|
3
|
+
import pandas as pd
|
|
4
|
+
|
|
5
|
+
from mrna_bench.data_splitter.data_splitter import DataSplitter
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SklearnSplitter(DataSplitter):
|
|
9
|
+
"""Wrapper for sklearn train_test_split."""
|
|
10
|
+
|
|
11
|
+
def split_df(
|
|
12
|
+
self,
|
|
13
|
+
df: pd.DataFrame,
|
|
14
|
+
test_size: float,
|
|
15
|
+
random_seed: int
|
|
16
|
+
) -> tuple[pd.DataFrame, pd.DataFrame]:
|
|
17
|
+
"""Split dataframe into train and test split using sklearn.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
df: Dataframe to split.
|
|
21
|
+
test_size: Fraction of dataset to place in test set.
|
|
22
|
+
random_seed: Random seed used during sampling.
|
|
23
|
+
|
|
24
|
+
Return:
|
|
25
|
+
Train and test dataframes.
|
|
26
|
+
"""
|
|
27
|
+
return train_test_split(
|
|
28
|
+
df,
|
|
29
|
+
test_size=test_size,
|
|
30
|
+
random_state=random_seed
|
|
31
|
+
)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
|
|
3
|
+
from mrna_bench.data_splitter.data_splitter import DataSplitter
|
|
4
|
+
from mrna_bench.data_splitter.homology_split import HomologySplitter
|
|
5
|
+
from mrna_bench.data_splitter.sklearn_split import SklearnSplitter
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
SPLIT_CATALOG: dict[str, Callable[..., DataSplitter]] = {
|
|
9
|
+
"default": SklearnSplitter,
|
|
10
|
+
"homology": HomologySplitter
|
|
11
|
+
}
|