Unify BioMod interfaces and centralize checkpoint compatibility
Browse filesUse the bundled BioModEncoder, BioModLM and BioModLM_GO interfaces throughout. Remove obsolete CLI aliases and the external attention fallback. Centralize legacy configuration and state-dictionary translation in biomod_compat.py and document the shared asset. Model weights, paired configuration, datasets and unrelated files remain unchanged.
- BioMod/README.md +3 -0
- BioMod/biomod.py +1 -2
- BioMod/cell_annotation/train.py +1 -2
- BioMod/models_biomod.py +6 -95
- README.md +4 -0
- model_dependencies/biomod_compat.py +111 -0
- model_dependencies/pytorch_cont/__init__.py +2 -2
- model_dependencies/pytorch_cont/ding_models.py +23 -11
- model_dependencies/pytorch_cont/pytorch.py +24 -12
- model_dependencies/pytorch_cont/pytorch_old.py +24 -12
BioMod/README.md
CHANGED
|
@@ -156,6 +156,7 @@ $BIOMOD_ROOT/model_dependencies/ # Shared gene mappings, gene lists
|
|
| 156 |
│ ├── pytorch.py
|
| 157 |
│ ├── pytorch_old.py
|
| 158 |
│ └── reversible.py
|
|
|
|
| 159 |
├── gene2ens.csv
|
| 160 |
├── selected_gene2vec_27k.npy
|
| 161 |
└── selected_genes_27k.txt
|
|
@@ -351,6 +352,8 @@ files and shows which entries are missing.
|
|
| 351 |
Check `BIOMOD_ROOT` for shell commands or `PROJECT_ROOT` in a notebook, and verify that the BioMod model weights, matching
|
| 352 |
`.pkl` configuration, gene2vec file, gene list, gene mapping, and
|
| 353 |
`pytorch_cont/` directory exist at the paths listed under Shared Assets.
|
|
|
|
|
|
|
| 354 |
|
| 355 |
### No space left on device
|
| 356 |
|
|
|
|
| 156 |
│ ├── pytorch.py
|
| 157 |
│ ├── pytorch_old.py
|
| 158 |
│ └── reversible.py
|
| 159 |
+
├── biomod_compat.py # Legacy checkpoint and configuration compatibility
|
| 160 |
├── gene2ens.csv
|
| 161 |
├── selected_gene2vec_27k.npy
|
| 162 |
└── selected_genes_27k.txt
|
|
|
|
| 352 |
Check `BIOMOD_ROOT` for shell commands or `PROJECT_ROOT` in a notebook, and verify that the BioMod model weights, matching
|
| 353 |
`.pkl` configuration, gene2vec file, gene list, gene mapping, and
|
| 354 |
`pytorch_cont/` directory exist at the paths listed under Shared Assets.
|
| 355 |
+
Keep `biomod_compat.py` alongside that directory so existing serialized
|
| 356 |
+
configurations and checkpoint field names can be translated during loading.
|
| 357 |
|
| 358 |
### No space left on device
|
| 359 |
|
BioMod/biomod.py
CHANGED
|
@@ -65,7 +65,6 @@
|
|
| 65 |
sys.path.insert(0, str(SOURCE_DIR))
|
| 66 |
from models_biomod import (
|
| 67 |
BioMod,
|
| 68 |
-
normalize_biomod_decoder_type,
|
| 69 |
sanitize_biomod_config,
|
| 70 |
)
|
| 71 |
from biomod_dataset import BioModSCDataset, load_biomod_data
|
|
@@ -115,7 +114,7 @@
|
|
| 115 |
help='Reconstruct loss aggregation method: gene_mean=masked gene equal weight (current); module_mean=masked module equal weight (MAE style)')
|
| 116 |
parser.add_argument("--recon_target_level", type=str, default="gene", choices=["gene", "module_mean_value"],
|
| 117 |
help='Reconstruction target granularity: gene=gene-by-gene reconstruction; module_mean_value=decoder directly outputs the module mean and calculates the loss with the target mean')
|
| 118 |
-
parser.add_argument("--decoder_type", type=
|
| 119 |
help='decoder type: none=directly use encoder to output predictions; simple=no token mixing; biomod=decoder self-attention; cross_attn=only masked->visible cross-attention')
|
| 120 |
parser.add_argument("--decoder_gene_agg", action='store_true',
|
| 121 |
help='The reconstruction head is changed to module->gene aggregation and then gene-level reconstruction (off by default to facilitate comparison with the old module_head)')
|
|
|
|
| 65 |
sys.path.insert(0, str(SOURCE_DIR))
|
| 66 |
from models_biomod import (
|
| 67 |
BioMod,
|
|
|
|
| 68 |
sanitize_biomod_config,
|
| 69 |
)
|
| 70 |
from biomod_dataset import BioModSCDataset, load_biomod_data
|
|
|
|
| 114 |
help='Reconstruct loss aggregation method: gene_mean=masked gene equal weight (current); module_mean=masked module equal weight (MAE style)')
|
| 115 |
parser.add_argument("--recon_target_level", type=str, default="gene", choices=["gene", "module_mean_value"],
|
| 116 |
help='Reconstruction target granularity: gene=gene-by-gene reconstruction; module_mean_value=decoder directly outputs the module mean and calculates the loss with the target mean')
|
| 117 |
+
parser.add_argument("--decoder_type", type=str, default="biomod", choices=["none", "simple", "biomod", "cross_attn"],
|
| 118 |
help='decoder type: none=directly use encoder to output predictions; simple=no token mixing; biomod=decoder self-attention; cross_attn=only masked->visible cross-attention')
|
| 119 |
parser.add_argument("--decoder_gene_agg", action='store_true',
|
| 120 |
help='The reconstruction head is changed to module->gene aggregation and then gene-level reconstruction (off by default to facilitate comparison with the old module_head)')
|
BioMod/cell_annotation/train.py
CHANGED
|
@@ -1173,9 +1173,8 @@ def parse_args():
|
|
| 1173 |
parser.add_argument("--max_cells", type=int, default=None)
|
| 1174 |
|
| 1175 |
parser.add_argument("--config_pkl", type=str, default=str(WEIGHTS_DIR / "BioMod.pkl"))
|
| 1176 |
-
# Retain the legacy CLI spelling as a compatibility alias.
|
| 1177 |
parser.add_argument(
|
| 1178 |
-
"--biomod_checkpoint",
|
| 1179 |
type=str,
|
| 1180 |
default=str(WEIGHTS_DIR / "BioMod.pth"),
|
| 1181 |
dest='biomod_checkpoint',
|
|
|
|
| 1173 |
parser.add_argument("--max_cells", type=int, default=None)
|
| 1174 |
|
| 1175 |
parser.add_argument("--config_pkl", type=str, default=str(WEIGHTS_DIR / "BioMod.pkl"))
|
|
|
|
| 1176 |
parser.add_argument(
|
| 1177 |
+
"--biomod_checkpoint",
|
| 1178 |
type=str,
|
| 1179 |
default=str(WEIGHTS_DIR / "BioMod.pth"),
|
| 1180 |
dest='biomod_checkpoint',
|
BioMod/models_biomod.py
CHANGED
|
@@ -15,25 +15,12 @@
|
|
| 15 |
if os.path.isdir(model_dependencies_dir) and model_dependencies_dir not in sys.path:
|
| 16 |
sys.path.insert(0, model_dependencies_dir)
|
| 17 |
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
except ImportError:
|
| 25 |
-
try:
|
| 26 |
-
from pytorch_cont.pytorch import (
|
| 27 |
-
Performer as BioModEncoder,
|
| 28 |
-
Always,
|
| 29 |
-
cast_tuple,
|
| 30 |
-
)
|
| 31 |
-
except ImportError:
|
| 32 |
-
from performer_pytorch.performer_pytorch import (
|
| 33 |
-
Performer as BioModEncoder,
|
| 34 |
-
Always,
|
| 35 |
-
cast_tuple,
|
| 36 |
-
)
|
| 37 |
import torch
|
| 38 |
from torch import nn
|
| 39 |
import torch.nn.functional as F
|
|
@@ -41,82 +28,6 @@
|
|
| 41 |
import numpy as np
|
| 42 |
|
| 43 |
|
| 44 |
-
def normalize_biomod_decoder_type(decoder_type: str) -> str:
|
| 45 |
-
"""Normalize the legacy decoder option without changing the attention backend."""
|
| 46 |
-
if decoder_type == "performer": # Legacy CLI and serialized-config alias.
|
| 47 |
-
return "biomod"
|
| 48 |
-
return decoder_type
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
def _migrate_legacy_biomod_name(value: str) -> str:
|
| 52 |
-
"""Translate serialized pre-rename names without changing their semantics."""
|
| 53 |
-
replacements = (
|
| 54 |
-
("PATHCH", "MODULE"),
|
| 55 |
-
("Pathch", "Module"),
|
| 56 |
-
("pathch", "module"),
|
| 57 |
-
("PATCHES", "MODULES"),
|
| 58 |
-
("Patches", "Modules"),
|
| 59 |
-
("patches", "modules"),
|
| 60 |
-
("PATCH", "MODULE"),
|
| 61 |
-
("Patch", "Module"),
|
| 62 |
-
("patch", "module"),
|
| 63 |
-
)
|
| 64 |
-
for old, new in replacements:
|
| 65 |
-
value = value.replace(old, new)
|
| 66 |
-
return value
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
def migrate_legacy_biomod_config(config: Dict[str, object]) -> Dict[str, object]:
|
| 70 |
-
"""Return a BioMod-compatible copy of an older serialized configuration."""
|
| 71 |
-
def translate(value):
|
| 72 |
-
if isinstance(value, dict):
|
| 73 |
-
migrated = {}
|
| 74 |
-
for key, item in value.items():
|
| 75 |
-
new_key = _migrate_legacy_biomod_name(key) if isinstance(key, str) else key
|
| 76 |
-
if new_key in migrated:
|
| 77 |
-
raise ValueError(
|
| 78 |
-
f"Legacy configuration migration would duplicate key {new_key!r}"
|
| 79 |
-
)
|
| 80 |
-
migrated[new_key] = translate(item)
|
| 81 |
-
return migrated
|
| 82 |
-
if isinstance(value, list):
|
| 83 |
-
return [translate(item) for item in value]
|
| 84 |
-
if isinstance(value, tuple):
|
| 85 |
-
return tuple(translate(item) for item in value)
|
| 86 |
-
if isinstance(value, str):
|
| 87 |
-
return _migrate_legacy_biomod_name(value)
|
| 88 |
-
return value
|
| 89 |
-
|
| 90 |
-
migrated = translate(dict(config))
|
| 91 |
-
if "decoder_type" in migrated:
|
| 92 |
-
migrated["decoder_type"] = normalize_biomod_decoder_type(migrated["decoder_type"])
|
| 93 |
-
return migrated
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
def migrate_legacy_biomod_state_dict(state_dict):
|
| 97 |
-
"""Translate old state-dict key names before PyTorch performs strict loading."""
|
| 98 |
-
try:
|
| 99 |
-
migrated = state_dict.__class__()
|
| 100 |
-
except TypeError:
|
| 101 |
-
migrated = {}
|
| 102 |
-
|
| 103 |
-
for key, value in state_dict.items():
|
| 104 |
-
new_key = _migrate_legacy_biomod_name(key) if isinstance(key, str) else key
|
| 105 |
-
if new_key in migrated:
|
| 106 |
-
# If both spellings are supplied, prefer the explicit new spelling.
|
| 107 |
-
if key == new_key:
|
| 108 |
-
migrated[new_key] = value
|
| 109 |
-
continue
|
| 110 |
-
migrated[new_key] = value
|
| 111 |
-
|
| 112 |
-
if hasattr(state_dict, "_metadata"):
|
| 113 |
-
migrated._metadata = {
|
| 114 |
-
_migrate_legacy_biomod_name(key): value
|
| 115 |
-
for key, value in state_dict._metadata.items()
|
| 116 |
-
}
|
| 117 |
-
return migrated
|
| 118 |
-
|
| 119 |
-
|
| 120 |
def normalize_fusion_method(fusion_method: str) -> str:
|
| 121 |
if fusion_method == "expression_only_mlp":
|
| 122 |
return "add"
|
|
|
|
| 15 |
if os.path.isdir(model_dependencies_dir) and model_dependencies_dir not in sys.path:
|
| 16 |
sys.path.insert(0, model_dependencies_dir)
|
| 17 |
|
| 18 |
+
from biomod_compat import (
|
| 19 |
+
migrate_legacy_biomod_config,
|
| 20 |
+
migrate_legacy_biomod_state_dict,
|
| 21 |
+
normalize_biomod_decoder_type,
|
| 22 |
+
)
|
| 23 |
+
from pytorch_cont.pytorch import BioModEncoder, Always, cast_tuple
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
import torch
|
| 25 |
from torch import nn
|
| 26 |
import torch.nn.functional as F
|
|
|
|
| 28 |
import numpy as np
|
| 29 |
|
| 30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
def normalize_fusion_method(fusion_method: str) -> str:
|
| 32 |
if fusion_method == "expression_only_mlp":
|
| 33 |
return "add"
|
README.md
CHANGED
|
@@ -81,6 +81,9 @@ architecture and gene-module definitions.
|
|
| 81 |
|
| 82 |
The model components are bundled under
|
| 83 |
[`model_dependencies/pytorch_cont/`](model_dependencies/pytorch_cont/).
|
|
|
|
|
|
|
|
|
|
| 84 |
Optional [Hallmark and Reactome source definitions](model_dependencies/biomod_data_sources/)
|
| 85 |
are kept in `biomod_data_sources/`. They are separate from the default checkpoint
|
| 86 |
runtime definitions in `biomod_data_all/`.
|
|
@@ -275,6 +278,7 @@ BioMod/ # Project root: s
|
|
| 275 |
│ │ ├── pytorch.py
|
| 276 |
│ │ ├── pytorch_old.py
|
| 277 |
│ │ └── reversible.py
|
|
|
|
| 278 |
│ ├── gene2ens.csv
|
| 279 |
│ ├── selected_gene2vec_27k.npy
|
| 280 |
│ └── selected_genes_27k.txt
|
|
|
|
| 81 |
|
| 82 |
The model components are bundled under
|
| 83 |
[`model_dependencies/pytorch_cont/`](model_dependencies/pytorch_cont/).
|
| 84 |
+
Legacy serialized names are handled by
|
| 85 |
+
[`biomod_compat.py`](model_dependencies/biomod_compat.py) when loading existing
|
| 86 |
+
checkpoints; the original checkpoint files remain unchanged.
|
| 87 |
Optional [Hallmark and Reactome source definitions](model_dependencies/biomod_data_sources/)
|
| 88 |
are kept in `biomod_data_sources/`. They are separate from the default checkpoint
|
| 89 |
runtime definitions in `biomod_data_all/`.
|
|
|
|
| 278 |
│ │ ├── pytorch.py
|
| 279 |
│ │ ├── pytorch_old.py
|
| 280 |
│ │ └── reversible.py
|
| 281 |
+
│ ├── biomod_compat.py # Legacy checkpoint and configuration compatibility
|
| 282 |
│ ├── gene2ens.csv
|
| 283 |
│ ├── selected_gene2vec_27k.npy
|
| 284 |
│ └── selected_genes_27k.txt
|
model_dependencies/biomod_compat.py
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Read historical BioMod serialized names without rewriting checkpoint files.
|
| 2 |
+
|
| 3 |
+
Current interfaces use BioMod names. Legacy spellings are kept only here so
|
| 4 |
+
existing configuration dictionaries and tensor state dictionaries still load.
|
| 5 |
+
This module intentionally has no model or tensor-library imports.
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
from typing import Dict
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def normalize_biomod_decoder_type(decoder_type: str) -> str:
|
| 12 |
+
"""Normalize the legacy decoder option without changing the attention backend."""
|
| 13 |
+
if decoder_type == "performer": # Legacy serialized-config alias.
|
| 14 |
+
return "biomod"
|
| 15 |
+
return decoder_type
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def _migrate_legacy_biomod_name(value: str) -> str:
|
| 19 |
+
"""Translate serialized pre-rename names without changing their semantics."""
|
| 20 |
+
replacements = (
|
| 21 |
+
("PATHCH", "MODULE"),
|
| 22 |
+
("Pathch", "Module"),
|
| 23 |
+
("pathch", "module"),
|
| 24 |
+
("PATCHES", "MODULES"),
|
| 25 |
+
("Patches", "Modules"),
|
| 26 |
+
("patches", "modules"),
|
| 27 |
+
("PATCH", "MODULE"),
|
| 28 |
+
("Patch", "Module"),
|
| 29 |
+
("patch", "module"),
|
| 30 |
+
)
|
| 31 |
+
for old, new in replacements:
|
| 32 |
+
value = value.replace(old, new)
|
| 33 |
+
return value
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
def migrate_legacy_biomod_config(config: Dict[str, object]) -> Dict[str, object]:
|
| 37 |
+
"""Return a BioMod-compatible copy of an older serialized configuration."""
|
| 38 |
+
def translate(value):
|
| 39 |
+
if isinstance(value, dict):
|
| 40 |
+
migrated = {}
|
| 41 |
+
for key, item in value.items():
|
| 42 |
+
new_key = _migrate_legacy_biomod_name(key) if isinstance(key, str) else key
|
| 43 |
+
if new_key in migrated:
|
| 44 |
+
raise ValueError(
|
| 45 |
+
f"Legacy configuration migration would duplicate key {new_key!r}"
|
| 46 |
+
)
|
| 47 |
+
migrated[new_key] = translate(item)
|
| 48 |
+
return migrated
|
| 49 |
+
if isinstance(value, list):
|
| 50 |
+
return [translate(item) for item in value]
|
| 51 |
+
if isinstance(value, tuple):
|
| 52 |
+
return tuple(translate(item) for item in value)
|
| 53 |
+
if isinstance(value, str):
|
| 54 |
+
return _migrate_legacy_biomod_name(value)
|
| 55 |
+
return value
|
| 56 |
+
|
| 57 |
+
migrated = translate(dict(config))
|
| 58 |
+
if "decoder_type" in migrated:
|
| 59 |
+
migrated["decoder_type"] = normalize_biomod_decoder_type(migrated["decoder_type"])
|
| 60 |
+
return migrated
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def migrate_legacy_biomod_state_dict(state_dict):
|
| 64 |
+
"""Translate old state-dict key names before PyTorch performs strict loading."""
|
| 65 |
+
try:
|
| 66 |
+
migrated = state_dict.__class__()
|
| 67 |
+
except TypeError:
|
| 68 |
+
migrated = {}
|
| 69 |
+
|
| 70 |
+
for key, value in state_dict.items():
|
| 71 |
+
new_key = _migrate_legacy_biomod_name(key) if isinstance(key, str) else key
|
| 72 |
+
if new_key in migrated:
|
| 73 |
+
# If both spellings are supplied, prefer the explicit new spelling.
|
| 74 |
+
if key == new_key:
|
| 75 |
+
migrated[new_key] = value
|
| 76 |
+
continue
|
| 77 |
+
migrated[new_key] = value
|
| 78 |
+
|
| 79 |
+
if hasattr(state_dict, "_metadata"):
|
| 80 |
+
migrated._metadata = {
|
| 81 |
+
_migrate_legacy_biomod_name(key): value
|
| 82 |
+
for key, value in state_dict._metadata.items()
|
| 83 |
+
}
|
| 84 |
+
return migrated
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
def migrate_legacy_encoder_prefix(state_dict, prefix: str) -> None:
|
| 88 |
+
"""Translate one legacy language-model subtree in place before loading.
|
| 89 |
+
|
| 90 |
+
Explicit current keys take precedence if both spellings are present.
|
| 91 |
+
The caller supplies the full parent prefix, including its trailing dot.
|
| 92 |
+
"""
|
| 93 |
+
old_root = prefix + "performer"
|
| 94 |
+
new_root = prefix + "biomod"
|
| 95 |
+
old_prefix = old_root + "."
|
| 96 |
+
new_prefix = new_root + "."
|
| 97 |
+
for key in list(state_dict):
|
| 98 |
+
if isinstance(key, str) and key.startswith(old_prefix):
|
| 99 |
+
new_key = new_prefix + key[len(old_prefix):]
|
| 100 |
+
if new_key not in state_dict:
|
| 101 |
+
state_dict[new_key] = state_dict[key]
|
| 102 |
+
del state_dict[key]
|
| 103 |
+
|
| 104 |
+
metadata = getattr(state_dict, "_metadata", None)
|
| 105 |
+
if metadata is not None:
|
| 106 |
+
for key in list(metadata):
|
| 107 |
+
if key == old_root or key.startswith(old_prefix):
|
| 108 |
+
new_key = new_root + key[len(old_root):]
|
| 109 |
+
if new_key not in metadata:
|
| 110 |
+
metadata[new_key] = metadata[key]
|
| 111 |
+
del metadata[key]
|
model_dependencies/pytorch_cont/__init__.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
| 1 |
-
# Export the bundled
|
| 2 |
-
from pytorch_cont.pytorch import
|
|
|
|
| 1 |
+
# Export the bundled BioMod attention implementation.
|
| 2 |
+
from pytorch_cont.pytorch import BioModLM, BioModEncoder, FastAttention, SelfAttention
|
model_dependencies/pytorch_cont/ding_models.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
|
|
| 1 |
from pytorch_cont.pytorch import *
|
| 2 |
import torch.nn as nn
|
| 3 |
from torch_geometric.nn import SGConv
|
|
@@ -125,7 +126,7 @@ def get_similarity_network(gene_list, data_path, num_similar_genes_go_graph):
|
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
-
class
|
| 129 |
def __init__(
|
| 130 |
self,
|
| 131 |
*,
|
|
@@ -189,17 +190,28 @@ class PerformerLM_GO(nn.Module):
|
|
| 189 |
gene2vec_file = gene2vec_file)
|
| 190 |
print('dropout')
|
| 191 |
self.dropout = nn.Dropout(emb_dropout)
|
| 192 |
-
print('
|
| 193 |
-
self.
|
| 194 |
self.norm = nn.LayerNorm(dim)
|
| 195 |
# self.to_out = nn.Linear(dim, num_tokens) if not tie_embed else None
|
| 196 |
self.to_out = nn.Linear(dim, 1) if not tie_embed else None
|
| 197 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 198 |
def check_redraw_projections(self):
|
| 199 |
-
self.
|
| 200 |
|
| 201 |
def fix_projection_matrices_(self):
|
| 202 |
-
self.
|
| 203 |
|
| 204 |
def forward(self, x, return_encodings = False, output_attentions = False, **kwargs):
|
| 205 |
b, n, device = *x.shape, x.device
|
|
@@ -213,11 +225,11 @@ class PerformerLM_GO(nn.Module):
|
|
| 213 |
x += self.go_conv(x)
|
| 214 |
x = self.dropout(x)
|
| 215 |
|
| 216 |
-
#
|
| 217 |
layer_pos_emb = self.layer_pos_emb(x)
|
| 218 |
|
| 219 |
if output_attentions:
|
| 220 |
-
x, attn_weights = self.
|
| 221 |
# norm and to logits
|
| 222 |
x = self.norm(x)
|
| 223 |
if return_encodings:
|
|
@@ -228,7 +240,7 @@ class PerformerLM_GO(nn.Module):
|
|
| 228 |
|
| 229 |
return (x @ self.token_emb.weight.t()), attn_weights
|
| 230 |
else:
|
| 231 |
-
x = self.
|
| 232 |
|
| 233 |
# norm and to logits
|
| 234 |
x = self.norm(x)
|
|
@@ -318,17 +330,17 @@ class DualEncoderSCFM(nn.Module):
|
|
| 318 |
gene2vec_file = gene2vec_file)
|
| 319 |
self.dropout = nn.Dropout(emb_dropout)
|
| 320 |
|
| 321 |
-
self.mini_encoder =
|
| 322 |
local_attn_heads, local_window_size, causal, ff_mult, nb_features, feature_redraw_interval, reversible, ff_chunks, generalized_attention, kernel_fn, use_scalenorm, use_rezero, ff_glu, ff_dropout, attn_dropout, cross_attend, no_projection, auto_check_redraw, qkv_bias)
|
| 323 |
|
| 324 |
self.base_to_large = nn.Linear(base_dim, large_dim)
|
| 325 |
self.large_in_norm = nn.LayerNorm(large_dim)
|
| 326 |
-
self.large_encoder =
|
| 327 |
local_attn_heads, local_window_size, causal, ff_mult, nb_features, feature_redraw_interval, reversible, ff_chunks, generalized_attention, kernel_fn, use_scalenorm, use_rezero, ff_glu, ff_dropout, attn_dropout, cross_attend, no_projection, auto_check_redraw, qkv_bias)
|
| 328 |
self.large_to_base = nn.Linear(large_dim, base_dim)
|
| 329 |
self.large_to_base_out_norm = nn.LayerNorm(base_dim)
|
| 330 |
|
| 331 |
-
self.decoder =
|
| 332 |
local_attn_heads, local_window_size, causal, ff_mult, nb_features, feature_redraw_interval, reversible, ff_chunks, generalized_attention, kernel_fn, use_scalenorm, use_rezero, ff_glu, ff_dropout, attn_dropout, cross_attend, no_projection, auto_check_redraw, qkv_bias)
|
| 333 |
self.decode_norm = nn.LayerNorm(base_dim)
|
| 334 |
|
|
|
|
| 1 |
+
from biomod_compat import migrate_legacy_encoder_prefix
|
| 2 |
from pytorch_cont.pytorch import *
|
| 3 |
import torch.nn as nn
|
| 4 |
from torch_geometric.nn import SGConv
|
|
|
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
+
class BioModLM_GO(nn.Module):
|
| 130 |
def __init__(
|
| 131 |
self,
|
| 132 |
*,
|
|
|
|
| 190 |
gene2vec_file = gene2vec_file)
|
| 191 |
print('dropout')
|
| 192 |
self.dropout = nn.Dropout(emb_dropout)
|
| 193 |
+
print('BioMod')
|
| 194 |
+
self.biomod = BioModEncoder(dim, depth, heads, dim_head, local_attn_heads, local_window_size, causal, ff_mult, nb_features, feature_redraw_interval, reversible, ff_chunks, generalized_attention, kernel_fn, use_scalenorm, use_rezero, ff_glu, ff_dropout, attn_dropout, cross_attend, no_projection, auto_check_redraw, qkv_bias)
|
| 195 |
self.norm = nn.LayerNorm(dim)
|
| 196 |
# self.to_out = nn.Linear(dim, num_tokens) if not tie_embed else None
|
| 197 |
self.to_out = nn.Linear(dim, 1) if not tie_embed else None
|
| 198 |
|
| 199 |
+
def _load_from_state_dict(
|
| 200 |
+
self, state_dict, prefix, local_metadata, strict,
|
| 201 |
+
missing_keys, unexpected_keys, error_msgs,
|
| 202 |
+
):
|
| 203 |
+
"""Normalize historical encoder prefixes before loading parameters."""
|
| 204 |
+
migrate_legacy_encoder_prefix(state_dict, prefix)
|
| 205 |
+
super()._load_from_state_dict(
|
| 206 |
+
state_dict, prefix, local_metadata, strict,
|
| 207 |
+
missing_keys, unexpected_keys, error_msgs,
|
| 208 |
+
)
|
| 209 |
+
|
| 210 |
def check_redraw_projections(self):
|
| 211 |
+
self.biomod.check_redraw_projections()
|
| 212 |
|
| 213 |
def fix_projection_matrices_(self):
|
| 214 |
+
self.biomod.fix_projection_matrices_()
|
| 215 |
|
| 216 |
def forward(self, x, return_encodings = False, output_attentions = False, **kwargs):
|
| 217 |
b, n, device = *x.shape, x.device
|
|
|
|
| 225 |
x += self.go_conv(x)
|
| 226 |
x = self.dropout(x)
|
| 227 |
|
| 228 |
+
# BioMod encoder layers
|
| 229 |
layer_pos_emb = self.layer_pos_emb(x)
|
| 230 |
|
| 231 |
if output_attentions:
|
| 232 |
+
x, attn_weights = self.biomod(x, pos_emb = layer_pos_emb, output_attentions = output_attentions, **kwargs)
|
| 233 |
# norm and to logits
|
| 234 |
x = self.norm(x)
|
| 235 |
if return_encodings:
|
|
|
|
| 240 |
|
| 241 |
return (x @ self.token_emb.weight.t()), attn_weights
|
| 242 |
else:
|
| 243 |
+
x = self.biomod(x, pos_emb = layer_pos_emb, output_attentions = output_attentions, **kwargs)
|
| 244 |
|
| 245 |
# norm and to logits
|
| 246 |
x = self.norm(x)
|
|
|
|
| 330 |
gene2vec_file = gene2vec_file)
|
| 331 |
self.dropout = nn.Dropout(emb_dropout)
|
| 332 |
|
| 333 |
+
self.mini_encoder = BioModEncoder(base_dim, mini_enc_depth, mini_enc_heads, mini_enc_dim_head,
|
| 334 |
local_attn_heads, local_window_size, causal, ff_mult, nb_features, feature_redraw_interval, reversible, ff_chunks, generalized_attention, kernel_fn, use_scalenorm, use_rezero, ff_glu, ff_dropout, attn_dropout, cross_attend, no_projection, auto_check_redraw, qkv_bias)
|
| 335 |
|
| 336 |
self.base_to_large = nn.Linear(base_dim, large_dim)
|
| 337 |
self.large_in_norm = nn.LayerNorm(large_dim)
|
| 338 |
+
self.large_encoder = BioModEncoder(large_dim, large_enc_depth, large_enc_heads, large_enc_dim_head,
|
| 339 |
local_attn_heads, local_window_size, causal, ff_mult, nb_features, feature_redraw_interval, reversible, ff_chunks, generalized_attention, kernel_fn, use_scalenorm, use_rezero, ff_glu, ff_dropout, attn_dropout, cross_attend, no_projection, auto_check_redraw, qkv_bias)
|
| 340 |
self.large_to_base = nn.Linear(large_dim, base_dim)
|
| 341 |
self.large_to_base_out_norm = nn.LayerNorm(base_dim)
|
| 342 |
|
| 343 |
+
self.decoder = BioModEncoder(base_dim, dec_depth, dec_heads, dec_dim_head,
|
| 344 |
local_attn_heads, local_window_size, causal, ff_mult, nb_features, feature_redraw_interval, reversible, ff_chunks, generalized_attention, kernel_fn, use_scalenorm, use_rezero, ff_glu, ff_dropout, attn_dropout, cross_attend, no_projection, auto_check_redraw, qkv_bias)
|
| 345 |
self.decode_norm = nn.LayerNorm(base_dim)
|
| 346 |
|
model_dependencies/pytorch_cont/pytorch.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
|
|
| 1 |
import math
|
| 2 |
from pathlib import Path
|
| 3 |
import numpy as np
|
|
@@ -238,7 +239,7 @@ class FastAttention(nn.Module):
|
|
| 238 |
import fast_transformers.causal_product.causal_product_cuda
|
| 239 |
self.causal_linear_fn = partial(causal_linear_attention)
|
| 240 |
except ImportError:
|
| 241 |
-
print('unable to import cuda code for
|
| 242 |
self.causal_linear_fn = causal_linear_attention_noncuda
|
| 243 |
|
| 244 |
@torch.no_grad()
|
|
@@ -472,16 +473,16 @@ class Gene2VecPositionalEmbedding(nn.Module):
|
|
| 472 |
t = torch.arange(x.shape[1], device=x.device)
|
| 473 |
return self.emb(t)
|
| 474 |
|
| 475 |
-
#
|
| 476 |
|
| 477 |
-
class
|
| 478 |
def __init__(
|
| 479 |
self,
|
| 480 |
dim, # dimension
|
| 481 |
depth, # layers
|
| 482 |
heads, # heads
|
| 483 |
dim_head, # dim of head
|
| 484 |
-
local_attn_heads = 0, # num of local attention heads, (heads - local_attn_heads) is
|
| 485 |
local_window_size = 256, # window size of local attention
|
| 486 |
causal = False, # autoregressive or not
|
| 487 |
ff_mult = 4, # dim of intermediate features after attention / dim of input features
|
|
@@ -576,7 +577,7 @@ class TwoLayerMLP(nn.Module):
|
|
| 576 |
x = self.fc2(x)
|
| 577 |
return x
|
| 578 |
|
| 579 |
-
class
|
| 580 |
def __init__(
|
| 581 |
self,
|
| 582 |
*,
|
|
@@ -626,17 +627,28 @@ class PerformerLM(nn.Module):
|
|
| 626 |
self.layer_pos_emb = Always(None)
|
| 627 |
print('dropout')
|
| 628 |
self.dropout = nn.Dropout(emb_dropout)
|
| 629 |
-
print('
|
| 630 |
-
self.
|
| 631 |
self.norm = nn.LayerNorm(dim)
|
| 632 |
# self.to_out = nn.Linear(dim, num_tokens) if not tie_embed else None
|
| 633 |
self.to_out = nn.Linear(dim, 1) if not tie_embed else None
|
| 634 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 635 |
def check_redraw_projections(self):
|
| 636 |
-
self.
|
| 637 |
|
| 638 |
def fix_projection_matrices_(self):
|
| 639 |
-
self.
|
| 640 |
|
| 641 |
def forward(self, x, return_encodings = False, output_attentions = False, **kwargs):
|
| 642 |
b, n, device = *x.shape, x.device
|
|
@@ -649,11 +661,11 @@ class PerformerLM(nn.Module):
|
|
| 649 |
x += self.pos_emb(x)
|
| 650 |
x = self.dropout(x)
|
| 651 |
|
| 652 |
-
#
|
| 653 |
layer_pos_emb = self.layer_pos_emb(x)
|
| 654 |
|
| 655 |
if output_attentions:
|
| 656 |
-
x, attn_weights = self.
|
| 657 |
# norm and to logits
|
| 658 |
x = self.norm(x)
|
| 659 |
if return_encodings:
|
|
@@ -664,7 +676,7 @@ class PerformerLM(nn.Module):
|
|
| 664 |
|
| 665 |
return (x @ self.token_emb.weight.t()), attn_weights
|
| 666 |
else:
|
| 667 |
-
x = self.
|
| 668 |
|
| 669 |
# norm and to logits
|
| 670 |
x = self.norm(x)
|
|
|
|
| 1 |
+
from biomod_compat import migrate_legacy_encoder_prefix
|
| 2 |
import math
|
| 3 |
from pathlib import Path
|
| 4 |
import numpy as np
|
|
|
|
| 239 |
import fast_transformers.causal_product.causal_product_cuda
|
| 240 |
self.causal_linear_fn = partial(causal_linear_attention)
|
| 241 |
except ImportError:
|
| 242 |
+
print('unable to import cuda code for autoregressive BioMod attention. will default to the memory inefficient non-cuda version')
|
| 243 |
self.causal_linear_fn = causal_linear_attention_noncuda
|
| 244 |
|
| 245 |
@torch.no_grad()
|
|
|
|
| 473 |
t = torch.arange(x.shape[1], device=x.device)
|
| 474 |
return self.emb(t)
|
| 475 |
|
| 476 |
+
# BioMod encoder
|
| 477 |
|
| 478 |
+
class BioModEncoder(nn.Module):
|
| 479 |
def __init__(
|
| 480 |
self,
|
| 481 |
dim, # dimension
|
| 482 |
depth, # layers
|
| 483 |
heads, # heads
|
| 484 |
dim_head, # dim of head
|
| 485 |
+
local_attn_heads = 0, # num of local attention heads, (heads - local_attn_heads) is number of global attention heads
|
| 486 |
local_window_size = 256, # window size of local attention
|
| 487 |
causal = False, # autoregressive or not
|
| 488 |
ff_mult = 4, # dim of intermediate features after attention / dim of input features
|
|
|
|
| 577 |
x = self.fc2(x)
|
| 578 |
return x
|
| 579 |
|
| 580 |
+
class BioModLM(nn.Module):
|
| 581 |
def __init__(
|
| 582 |
self,
|
| 583 |
*,
|
|
|
|
| 627 |
self.layer_pos_emb = Always(None)
|
| 628 |
print('dropout')
|
| 629 |
self.dropout = nn.Dropout(emb_dropout)
|
| 630 |
+
print('BioMod')
|
| 631 |
+
self.biomod = BioModEncoder(dim, depth, heads, dim_head, local_attn_heads, local_window_size, causal, ff_mult, nb_features, feature_redraw_interval, reversible, ff_chunks, generalized_attention, kernel_fn, use_scalenorm, use_rezero, ff_glu, ff_dropout, attn_dropout, cross_attend, no_projection, auto_check_redraw, qkv_bias)
|
| 632 |
self.norm = nn.LayerNorm(dim)
|
| 633 |
# self.to_out = nn.Linear(dim, num_tokens) if not tie_embed else None
|
| 634 |
self.to_out = nn.Linear(dim, 1) if not tie_embed else None
|
| 635 |
|
| 636 |
+
def _load_from_state_dict(
|
| 637 |
+
self, state_dict, prefix, local_metadata, strict,
|
| 638 |
+
missing_keys, unexpected_keys, error_msgs,
|
| 639 |
+
):
|
| 640 |
+
"""Normalize historical encoder prefixes before loading parameters."""
|
| 641 |
+
migrate_legacy_encoder_prefix(state_dict, prefix)
|
| 642 |
+
super()._load_from_state_dict(
|
| 643 |
+
state_dict, prefix, local_metadata, strict,
|
| 644 |
+
missing_keys, unexpected_keys, error_msgs,
|
| 645 |
+
)
|
| 646 |
+
|
| 647 |
def check_redraw_projections(self):
|
| 648 |
+
self.biomod.check_redraw_projections()
|
| 649 |
|
| 650 |
def fix_projection_matrices_(self):
|
| 651 |
+
self.biomod.fix_projection_matrices_()
|
| 652 |
|
| 653 |
def forward(self, x, return_encodings = False, output_attentions = False, **kwargs):
|
| 654 |
b, n, device = *x.shape, x.device
|
|
|
|
| 661 |
x += self.pos_emb(x)
|
| 662 |
x = self.dropout(x)
|
| 663 |
|
| 664 |
+
# BioMod encoder layers
|
| 665 |
layer_pos_emb = self.layer_pos_emb(x)
|
| 666 |
|
| 667 |
if output_attentions:
|
| 668 |
+
x, attn_weights = self.biomod(x, pos_emb = layer_pos_emb, output_attentions = output_attentions, **kwargs)
|
| 669 |
# norm and to logits
|
| 670 |
x = self.norm(x)
|
| 671 |
if return_encodings:
|
|
|
|
| 676 |
|
| 677 |
return (x @ self.token_emb.weight.t()), attn_weights
|
| 678 |
else:
|
| 679 |
+
x = self.biomod(x, pos_emb = layer_pos_emb, output_attentions = output_attentions, **kwargs)
|
| 680 |
|
| 681 |
# norm and to logits
|
| 682 |
x = self.norm(x)
|
model_dependencies/pytorch_cont/pytorch_old.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
|
|
| 1 |
import math
|
| 2 |
from pathlib import Path
|
| 3 |
import numpy as np
|
|
@@ -238,7 +239,7 @@ class FastAttention(nn.Module):
|
|
| 238 |
import fast_transformers.causal_product.causal_product_cuda
|
| 239 |
self.causal_linear_fn = partial(causal_linear_attention)
|
| 240 |
except ImportError:
|
| 241 |
-
print('unable to import cuda code for
|
| 242 |
self.causal_linear_fn = causal_linear_attention_noncuda
|
| 243 |
|
| 244 |
@torch.no_grad()
|
|
@@ -462,16 +463,16 @@ class Gene2VecPositionalEmbedding(nn.Module):
|
|
| 462 |
t = torch.arange(x.shape[1], device=x.device)
|
| 463 |
return self.emb(t)
|
| 464 |
|
| 465 |
-
#
|
| 466 |
|
| 467 |
-
class
|
| 468 |
def __init__(
|
| 469 |
self,
|
| 470 |
dim, # dimension
|
| 471 |
depth, # layers
|
| 472 |
heads, # heads
|
| 473 |
dim_head, # dim of head
|
| 474 |
-
local_attn_heads = 0, # num of local attention heads, (heads - local_attn_heads) is
|
| 475 |
local_window_size = 256, # window size of local attention
|
| 476 |
causal = False, # autoregressive or not
|
| 477 |
ff_mult = 4, # dim of intermediate features after attention / dim of input features
|
|
@@ -566,7 +567,7 @@ class TwoLayerMLP(nn.Module):
|
|
| 566 |
x = self.fc2(x)
|
| 567 |
return x
|
| 568 |
|
| 569 |
-
class
|
| 570 |
def __init__(
|
| 571 |
self,
|
| 572 |
*,
|
|
@@ -616,17 +617,28 @@ class PerformerLM(nn.Module):
|
|
| 616 |
self.layer_pos_emb = Always(None)
|
| 617 |
print('dropout')
|
| 618 |
self.dropout = nn.Dropout(emb_dropout)
|
| 619 |
-
print('
|
| 620 |
-
self.
|
| 621 |
self.norm = nn.LayerNorm(dim)
|
| 622 |
# self.to_out = nn.Linear(dim, num_tokens) if not tie_embed else None
|
| 623 |
self.to_out = nn.Linear(dim, 1) if not tie_embed else None
|
| 624 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 625 |
def check_redraw_projections(self):
|
| 626 |
-
self.
|
| 627 |
|
| 628 |
def fix_projection_matrices_(self):
|
| 629 |
-
self.
|
| 630 |
|
| 631 |
def forward(self, x, return_encodings = False, output_attentions = False, **kwargs):
|
| 632 |
b, n, device = *x.shape, x.device
|
|
@@ -639,11 +651,11 @@ class PerformerLM(nn.Module):
|
|
| 639 |
x += self.pos_emb(x)
|
| 640 |
x = self.dropout(x)
|
| 641 |
|
| 642 |
-
#
|
| 643 |
layer_pos_emb = self.layer_pos_emb(x)
|
| 644 |
|
| 645 |
if output_attentions:
|
| 646 |
-
x, attn_weights = self.
|
| 647 |
# norm and to logits
|
| 648 |
x = self.norm(x)
|
| 649 |
if return_encodings:
|
|
@@ -654,7 +666,7 @@ class PerformerLM(nn.Module):
|
|
| 654 |
|
| 655 |
return (x @ self.token_emb.weight.t()), attn_weights
|
| 656 |
else:
|
| 657 |
-
x = self.
|
| 658 |
|
| 659 |
# norm and to logits
|
| 660 |
x = self.norm(x)
|
|
|
|
| 1 |
+
from biomod_compat import migrate_legacy_encoder_prefix
|
| 2 |
import math
|
| 3 |
from pathlib import Path
|
| 4 |
import numpy as np
|
|
|
|
| 239 |
import fast_transformers.causal_product.causal_product_cuda
|
| 240 |
self.causal_linear_fn = partial(causal_linear_attention)
|
| 241 |
except ImportError:
|
| 242 |
+
print('unable to import cuda code for autoregressive BioMod attention. will default to the memory inefficient non-cuda version')
|
| 243 |
self.causal_linear_fn = causal_linear_attention_noncuda
|
| 244 |
|
| 245 |
@torch.no_grad()
|
|
|
|
| 463 |
t = torch.arange(x.shape[1], device=x.device)
|
| 464 |
return self.emb(t)
|
| 465 |
|
| 466 |
+
# BioMod encoder
|
| 467 |
|
| 468 |
+
class BioModEncoder(nn.Module):
|
| 469 |
def __init__(
|
| 470 |
self,
|
| 471 |
dim, # dimension
|
| 472 |
depth, # layers
|
| 473 |
heads, # heads
|
| 474 |
dim_head, # dim of head
|
| 475 |
+
local_attn_heads = 0, # num of local attention heads, (heads - local_attn_heads) is number of global attention heads
|
| 476 |
local_window_size = 256, # window size of local attention
|
| 477 |
causal = False, # autoregressive or not
|
| 478 |
ff_mult = 4, # dim of intermediate features after attention / dim of input features
|
|
|
|
| 567 |
x = self.fc2(x)
|
| 568 |
return x
|
| 569 |
|
| 570 |
+
class BioModLM(nn.Module):
|
| 571 |
def __init__(
|
| 572 |
self,
|
| 573 |
*,
|
|
|
|
| 617 |
self.layer_pos_emb = Always(None)
|
| 618 |
print('dropout')
|
| 619 |
self.dropout = nn.Dropout(emb_dropout)
|
| 620 |
+
print('BioMod')
|
| 621 |
+
self.biomod = BioModEncoder(dim, depth, heads, dim_head, local_attn_heads, local_window_size, causal, ff_mult, nb_features, feature_redraw_interval, reversible, ff_chunks, generalized_attention, kernel_fn, use_scalenorm, use_rezero, ff_glu, ff_dropout, attn_dropout, cross_attend, no_projection, auto_check_redraw, qkv_bias)
|
| 622 |
self.norm = nn.LayerNorm(dim)
|
| 623 |
# self.to_out = nn.Linear(dim, num_tokens) if not tie_embed else None
|
| 624 |
self.to_out = nn.Linear(dim, 1) if not tie_embed else None
|
| 625 |
|
| 626 |
+
def _load_from_state_dict(
|
| 627 |
+
self, state_dict, prefix, local_metadata, strict,
|
| 628 |
+
missing_keys, unexpected_keys, error_msgs,
|
| 629 |
+
):
|
| 630 |
+
"""Normalize historical encoder prefixes before loading parameters."""
|
| 631 |
+
migrate_legacy_encoder_prefix(state_dict, prefix)
|
| 632 |
+
super()._load_from_state_dict(
|
| 633 |
+
state_dict, prefix, local_metadata, strict,
|
| 634 |
+
missing_keys, unexpected_keys, error_msgs,
|
| 635 |
+
)
|
| 636 |
+
|
| 637 |
def check_redraw_projections(self):
|
| 638 |
+
self.biomod.check_redraw_projections()
|
| 639 |
|
| 640 |
def fix_projection_matrices_(self):
|
| 641 |
+
self.biomod.fix_projection_matrices_()
|
| 642 |
|
| 643 |
def forward(self, x, return_encodings = False, output_attentions = False, **kwargs):
|
| 644 |
b, n, device = *x.shape, x.device
|
|
|
|
| 651 |
x += self.pos_emb(x)
|
| 652 |
x = self.dropout(x)
|
| 653 |
|
| 654 |
+
# BioMod encoder layers
|
| 655 |
layer_pos_emb = self.layer_pos_emb(x)
|
| 656 |
|
| 657 |
if output_attentions:
|
| 658 |
+
x, attn_weights = self.biomod(x, pos_emb = layer_pos_emb, output_attentions = output_attentions, **kwargs)
|
| 659 |
# norm and to logits
|
| 660 |
x = self.norm(x)
|
| 661 |
if return_encodings:
|
|
|
|
| 666 |
|
| 667 |
return (x @ self.token_emb.weight.t()), attn_weights
|
| 668 |
else:
|
| 669 |
+
x = self.biomod(x, pos_emb = layer_pos_emb, output_attentions = output_attentions, **kwargs)
|
| 670 |
|
| 671 |
# norm and to logits
|
| 672 |
x = self.norm(x)
|