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]