EvoTransformer-v2.1 / watchdog.py
HemanM's picture
Update watchdog.py
ce1faad verified
import os
import json
import random
import torch
import firebase_admin
from firebase_admin import credentials, firestore
from evo_model import EvoTransformerForClassification, EvoTransformerConfig
from transformers import BertTokenizer
from init_model import load_model
from dashboard import evolution_accuracy_plot
# Initialize Firebase
if not firebase_admin._apps:
cred = credentials.Certificate("firebase_key.json")
firebase_admin.initialize_app(cred)
db = firestore.client()
def fetch_training_data(tokenizer):
logs_ref = db.collection("evo_feedback")
docs = logs_ref.stream()
input_ids, attention_masks, labels = [], [], []
for doc in docs:
data = doc.to_dict()
prompt = data.get("prompt", "")
winner = data.get("winner", "")
if winner and prompt:
text = prompt + " [SEP] " + winner
encoding = tokenizer(
text,
truncation=True,
padding="max_length",
max_length=128,
return_tensors="pt"
)
input_ids.append(encoding["input_ids"][0])
attention_masks.append(encoding["attention_mask"][0])
label = 0 if "1" in winner else 1
labels.append(label)
if not input_ids:
return None, None, None
return (
torch.stack(input_ids),
torch.stack(attention_masks),
torch.tensor(labels, dtype=torch.long)
)
def mutate_config():
return EvoTransformerConfig(
hidden_size=384,
num_layers=random.choice([4, 6, 8]),
num_labels=2,
num_heads=random.choice([4, 6, 8]),
ffn_dim=random.choice([512, 1024, 2048]),
use_memory=random.choice([False, True])
)
def get_architecture_summary(model):
summary = {
"Layers": getattr(model.config, "num_layers", "N/A"),
"Attention Heads": getattr(model.config, "num_heads", "N/A"),
"FFN Dim": getattr(model.config, "ffn_dim", "N/A"),
"Memory Enabled": getattr(model.config, "use_memory", "N/A"),
}
return "\n".join(f"{k}: {v}" for k, v in summary.items())
def retrain_model():
try:
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
input_ids, attention_masks, labels = fetch_training_data(tokenizer)
if input_ids is None or len(input_ids) < 2:
return "⚠️ Not enough data to retrain.", None, "Please log more feedback first."
# πŸ” Evolve architecture
config = mutate_config()
model = EvoTransformerForClassification(config)
model.train()
optimizer = torch.optim.Adam(model.parameters(), lr=2e-4)
loss_fn = torch.nn.CrossEntropyLoss()
for epoch in range(3):
optimizer.zero_grad()
outputs = model(input_ids, attention_mask=attention_masks)
loss = loss_fn(outputs, labels)
loss.backward()
optimizer.step()
print(f"Epoch {epoch+1}: Loss = {loss.item():.4f}")
# Simulate evaluation (replace later)
accuracy = round(random.uniform(0.5, 1.0), 4)
# Save accuracy + architecture to log
log_path = "trained_model/evolution_log.json"
os.makedirs("trained_model", exist_ok=True)
if os.path.exists(log_path):
with open(log_path, "r") as f:
history = json.load(f)
else:
history = []
history.append({
"accuracy": accuracy,
"num_layers": config.num_layers,
"num_heads": config.num_heads,
"ffn_dim": config.ffn_dim,
"use_memory": config.use_memory
})
with open(log_path, "w") as f:
json.dump(history, f)
# Save model
model.save_pretrained("trained_model")
print("βœ… EvoTransformer retrained and saved.")
updated_model = load_model()
arch_text = get_architecture_summary(updated_model)
plot = evolution_accuracy_plot()
return arch_text, plot, "βœ… EvoTransformer retrained successfully!"
except Exception as e:
print(f"❌ Retraining failed: {e}")
return "❌ Error", None, f"Retrain failed: {e}"
# Run directly
if __name__ == "__main__":
retrain_model()