File size: 2,439 Bytes
2f93104
 
 
1e1224e
 
4b64e0a
2f93104
 
1e1224e
2f93104
1e1224e
 
 
 
 
 
2f93104
1e1224e
 
 
 
 
 
 
 
 
 
 
 
 
97d3ebe
1e1224e
 
 
 
 
 
 
97d3ebe
4ecef43
 
97d3ebe
7206cd8
97d3ebe
 
 
 
 
 
1e1224e
2f93104
1e1224e
2f93104
1e1224e
4ecef43
 
 
 
1e1224e
2f93104
 
1e1224e
2f93104
 
1e1224e
2f93104
 
1e1224e
 
 
 
 
 
 
 
 
4b64e0a
 
 
dfcf870
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
import random
import json
import os
import uuid
import csv
import torch.nn as nn

GENOME_LOG = "genome_log.csv"
BEST_GENOME_FILE = "best_genome.json"

# Mutation bounds
MUTATION_LIMITS = {
    "num_layers": (2, 12),
    "ffn_dim": (256, 4096),
    "num_heads": (2, 16),
}

def default_config():
    return {
        "genome_id": str(uuid.uuid4()),
        "num_layers": 6,
        "ffn_dim": 1024,
        "num_heads": 8,
        "memory_enabled": True
    }

def mutate_genome(base_config, exploration_rate=0.5):
    config = base_config.copy()
    config["genome_id"] = str(uuid.uuid4())
    mutation_type = random.choice(["num_layers", "ffn_dim", "num_heads", "memory_enabled"])

    if mutation_type == "memory_enabled":
        config["memory_enabled"] = not config["memory_enabled"]
    else:
        min_val, max_val = MUTATION_LIMITS[mutation_type]
        change = int((max_val - min_val) * exploration_rate)
        delta = random.randint(-change, change)
        config[mutation_type] = max(min_val, min(max_val, config[mutation_type] + delta))

    # ✅ Ensure num_heads divides d_model cleanly
    embed_dim = 512
    if config["num_heads"] > embed_dim:
        config["num_heads"] = max(1, embed_dim // 64)
    while embed_dim % config["num_heads"] != 0:
        config["num_heads"] -= 1
        if config["num_heads"] <= 0:
            config["num_heads"] = 1
            break

    return config

def log_genome(config, score=None):
    row = [
        config.get("genome_id", ""),
        config.get("num_layers", ""),
        config.get("ffn_dim", ""),
        config.get("num_heads", ""),
        config.get("memory_enabled", ""),
        score if score is not None else ""
    ]
    file_exists = os.path.exists(GENOME_LOG)
    with open(GENOME_LOG, "a", newline="", encoding="utf-8") as f:
        writer = csv.writer(f)
        if not file_exists:
            writer.writerow(["genome_id", "num_layers", "ffn_dim", "num_heads", "memory_enabled", "score"])
        writer.writerow(row)

def save_best_genome(config):
    with open(BEST_GENOME_FILE, "w", encoding="utf-8") as f:
        json.dump(config, f)

def load_best_genome():
    if os.path.exists(BEST_GENOME_FILE):
        with open(BEST_GENOME_FILE, "r", encoding="utf-8") as f:
            return json.load(f)
    return default_config()

def build_model_from_config(config):
    from evo_model import EvoTransformerV22
    return EvoTransformerV22(config)