#!/usr/bin/env python3 """ app.py — HuggingFace Spaces demo for Competitive Docking Memory (CDM) Language Model DuoNeural — Archon + Jesse Caldwell + Aura — 2026 Gradio 5 compatible. Routing gate visualization (not Logit Lens). """ import json import torch import gradio as gr from huggingface_hub import hf_hub_download model = None tokenizer = None DEVICE = "cpu" MODEL_REPO = "DuoNeural/CDM-V2-TinyStories-37M" SLOT_COLORS = [ "#FF6B6B","#4ECDC4","#45B7D1","#96CEB4","#FECA57","#FF9FF3","#54A0FF","#5F27CD", "#00D2D3","#FF9F43","#C8D6E5","#8395A7","#EE5A24","#009432","#C4E538","#A3CB38", ] EXAMPLES = [ "Once upon a time there was a little girl named Lily.", "Tom loved trains more than anything else in the world.", "The rabbit hopped through the sunny meadow looking for", "In a small village there lived a clever fox named", "She wanted to play outside but the weather was", ] SLOT_ROLES = { 11: "PUNCT", # 0-indexed — slot 11 specializes on punctuation (step5000: 71%, step30k: 88%) 9: "AGENCY", # character agency verbs 0: "IDENTITY",# character names / pronouns 15: "VERBS", # action verbs 5: "ARTICLES",# articles & modifiers } def load_model(): global model, tokenizer if model is not None: return from transformers import GPT2TokenizerFast from cdm_model_v2 import CDMConfigV2, CDMLanguageModelV2 tokenizer = GPT2TokenizerFast.from_pretrained("gpt2") tokenizer.pad_token = tokenizer.eos_token model_pt_path = hf_hub_download(repo_id=MODEL_REPO, filename="model.pt") config_path = hf_hub_download(repo_id=MODEL_REPO, filename="config.json") with open(config_path) as f: cfg_dict = json.load(f) cfg = CDMConfigV2( vocab_size=cfg_dict.get("vocab_size", 50257), d_model=cfg_dict.get("d_model", 384), n_layers=cfg_dict.get("n_layers", 8), n_heads=cfg_dict.get("n_heads", 8), n_kv_heads=cfg_dict.get("n_kv_heads", 4), d_ff=cfg_dict.get("d_ff", 1024), K=cfg_dict.get("K", 16), max_len=cfg_dict.get("max_len", 512), ) ckpt = torch.load(model_pt_path, map_location=DEVICE, weights_only=False) model = CDMLanguageModelV2(cfg) model.load_state_dict(ckpt.get("model_state", ckpt)) model = model.to(DEVICE) model.eval() print("Loading CDM model on startup...") try: load_model() print("Model loaded OK") except Exception as e: print(f"Startup load failed (will retry on first request): {e}") def gate_to_css_color(base_hex: str, intensity: float) -> str: """Blend base color with dark background by intensity (0-1).""" r = int(base_hex[1:3], 16) g = int(base_hex[3:5], 16) b = int(base_hex[5:7], 16) bg = 10 r2 = int(bg + (r - bg) * intensity) g2 = int(bg + (g - bg) * intensity) b2 = int(bg + (b - bg) * intensity) return f"#{r2:02x}{g2:02x}{b2:02x}" def generate_and_visualize(prompt: str, max_new_tokens: int, temperature: float, top_k: int): if model is None: try: load_model() except Exception as e: return f"[Model load failed: {e}]", "
Model not loaded.
", "" ids = tokenizer.encode(prompt, return_tensors="pt").to(DEVICE) generated_text, snapshots = model.generate_with_slots( ids, max_new=int(max_new_tokens), tokenizer=tokenizer, temperature=float(temperature), top_k=int(top_k), ) K = model.cfg.K # ── Routing gate heatmap table ──────────────────────────────────────────── rows = [] slot_token_counts = [[] for _ in range(K)] # track which tokens route to each slot for tok_str, all_layer_gates, winner in snapshots: tok_display = tok_str.replace("<","<").replace(">",">").replace(" ","·").strip() or "⏎" last_gates = all_layer_gates[-1] # final layer gate distribution # Track routing for summary slot_token_counts[winner].append(tok_str.strip()) # Winner badge win_color = SLOT_COLORS[winner % len(SLOT_COLORS)] winner_label = SLOT_ROLES.get(winner, f"S{winner+1}") tok_cell = ( f'Cell brightness = routing affinity. ★ = slots with known specialization (probe-confirmed). → label = winning slot for each token. Watch S12 light up for punctuation! (slot 11, 0-indexed)
| Token → Winner | {slot_headers}
|---|