File size: 4,168 Bytes
5ed2951 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | """Read historical BioMod serialized names without rewriting checkpoint files.
Current interfaces use BioMod names. Legacy spellings are kept only here so
existing configuration dictionaries and tensor state dictionaries still load.
This module intentionally has no model or tensor-library imports.
"""
from typing import Dict
def normalize_biomod_decoder_type(decoder_type: str) -> str:
"""Normalize the legacy decoder option without changing the attention backend."""
if decoder_type == "performer": # Legacy serialized-config alias.
return "biomod"
return decoder_type
def _migrate_legacy_biomod_name(value: str) -> str:
"""Translate serialized pre-rename names without changing their semantics."""
replacements = (
("PATHCH", "MODULE"),
("Pathch", "Module"),
("pathch", "module"),
("PATCHES", "MODULES"),
("Patches", "Modules"),
("patches", "modules"),
("PATCH", "MODULE"),
("Patch", "Module"),
("patch", "module"),
)
for old, new in replacements:
value = value.replace(old, new)
return value
def migrate_legacy_biomod_config(config: Dict[str, object]) -> Dict[str, object]:
"""Return a BioMod-compatible copy of an older serialized configuration."""
def translate(value):
if isinstance(value, dict):
migrated = {}
for key, item in value.items():
new_key = _migrate_legacy_biomod_name(key) if isinstance(key, str) else key
if new_key in migrated:
raise ValueError(
f"Legacy configuration migration would duplicate key {new_key!r}"
)
migrated[new_key] = translate(item)
return migrated
if isinstance(value, list):
return [translate(item) for item in value]
if isinstance(value, tuple):
return tuple(translate(item) for item in value)
if isinstance(value, str):
return _migrate_legacy_biomod_name(value)
return value
migrated = translate(dict(config))
if "decoder_type" in migrated:
migrated["decoder_type"] = normalize_biomod_decoder_type(migrated["decoder_type"])
return migrated
def migrate_legacy_biomod_state_dict(state_dict):
"""Translate old state-dict key names before PyTorch performs strict loading."""
try:
migrated = state_dict.__class__()
except TypeError:
migrated = {}
for key, value in state_dict.items():
new_key = _migrate_legacy_biomod_name(key) if isinstance(key, str) else key
if new_key in migrated:
# If both spellings are supplied, prefer the explicit new spelling.
if key == new_key:
migrated[new_key] = value
continue
migrated[new_key] = value
if hasattr(state_dict, "_metadata"):
migrated._metadata = {
_migrate_legacy_biomod_name(key): value
for key, value in state_dict._metadata.items()
}
return migrated
def migrate_legacy_encoder_prefix(state_dict, prefix: str) -> None:
"""Translate one legacy language-model subtree in place before loading.
Explicit current keys take precedence if both spellings are present.
The caller supplies the full parent prefix, including its trailing dot.
"""
old_root = prefix + "performer"
new_root = prefix + "biomod"
old_prefix = old_root + "."
new_prefix = new_root + "."
for key in list(state_dict):
if isinstance(key, str) and key.startswith(old_prefix):
new_key = new_prefix + key[len(old_prefix):]
if new_key not in state_dict:
state_dict[new_key] = state_dict[key]
del state_dict[key]
metadata = getattr(state_dict, "_metadata", None)
if metadata is not None:
for key in list(metadata):
if key == old_root or key.startswith(old_prefix):
new_key = new_root + key[len(old_root):]
if new_key not in metadata:
metadata[new_key] = metadata[key]
del metadata[key]
|