Upload 3 files
Browse files- model_index.json +97 -0
- nexus_worldmodel_config.py +979 -0
- nexus_worldmodel_v2.pt +2 -2
model_index.json
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"model_type": "nexus-worldmodel",
|
| 3 |
+
"version": "2.0",
|
| 4 |
+
"architecture_type": "cognitive-dynamic",
|
| 5 |
+
"framework": "pytorch",
|
| 6 |
+
"library_name": "nexus-worldmodel",
|
| 7 |
+
|
| 8 |
+
"description": "NEXUS-WorldModel v2.0 - Neural World Simulator with Full Cognitive Architecture",
|
| 9 |
+
|
| 10 |
+
"features": [
|
| 11 |
+
"EARCP (Ensemble Auto-Regulated Coherence Protocol)",
|
| 12 |
+
"LPOL Memory with 9 world-specific domains",
|
| 13 |
+
"GQA (Grouped Query Attention) for efficient memory access",
|
| 14 |
+
"Neurogenesis (dynamic neuron growth)",
|
| 15 |
+
"Energy System for cognitive resource management",
|
| 16 |
+
"Dream Phase with prioritized replay",
|
| 17 |
+
"Multi-World Buffers (physical, social, abstract, temporal)",
|
| 18 |
+
"Physics Prior (Mixture Density Network)",
|
| 19 |
+
"RoPE Attention (Rotary Positional Encoding)",
|
| 20 |
+
"VAE for visual encoding/decoding"
|
| 21 |
+
],
|
| 22 |
+
|
| 23 |
+
"files": {
|
| 24 |
+
"config": "config.json",
|
| 25 |
+
"weights": "pytorch_model.bin",
|
| 26 |
+
"cognitive_state": "cognitive_state.json",
|
| 27 |
+
"training_state": "training_state.json"
|
| 28 |
+
},
|
| 29 |
+
|
| 30 |
+
"optional_files": {
|
| 31 |
+
"optimizer": "optimizer.pt",
|
| 32 |
+
"source_code": "NEXUS_WorldModel_v2.py",
|
| 33 |
+
"config_module": "nexus_worldmodel_config.py"
|
| 34 |
+
},
|
| 35 |
+
|
| 36 |
+
"load_instructions": {
|
| 37 |
+
"python": "from nexus_worldmodel_config import load_nexus_worldmodel\nfrom NEXUS_WorldModel_v2 import NexusWorldModel\n\nmodel, config, cognitive_state, warnings = load_nexus_worldmodel(\n NexusWorldModel,\n 'amewebstudio/nexus-worldmodel-v2',\n device='cuda'\n)",
|
| 38 |
+
"note": "Use strict=False to handle dynamic architecture size mismatches"
|
| 39 |
+
},
|
| 40 |
+
|
| 41 |
+
"dynamic_components": {
|
| 42 |
+
"experts": {
|
| 43 |
+
"description": "Expert count per EARCP layer can grow during training",
|
| 44 |
+
"initial": 6,
|
| 45 |
+
"max": 12,
|
| 46 |
+
"growth_trigger": "coherence < 0.3"
|
| 47 |
+
},
|
| 48 |
+
"neurons": {
|
| 49 |
+
"description": "Neuron count in neurogenesis layer can change",
|
| 50 |
+
"initial": 64,
|
| 51 |
+
"min": 32,
|
| 52 |
+
"max": 256,
|
| 53 |
+
"birth_trigger": "coherence > 0.8",
|
| 54 |
+
"death_trigger": "usage < 0.05"
|
| 55 |
+
}
|
| 56 |
+
},
|
| 57 |
+
|
| 58 |
+
"cognitive_systems": {
|
| 59 |
+
"energy": {
|
| 60 |
+
"description": "Manages cognitive resource consumption",
|
| 61 |
+
"think_cost": 0.02,
|
| 62 |
+
"dream_cost": 0.1,
|
| 63 |
+
"regeneration": 0.05
|
| 64 |
+
},
|
| 65 |
+
"dream": {
|
| 66 |
+
"description": "Memory consolidation through prioritized replay",
|
| 67 |
+
"cycle_length": 50,
|
| 68 |
+
"duration": 10
|
| 69 |
+
},
|
| 70 |
+
"memory": {
|
| 71 |
+
"lpol_domains": 9,
|
| 72 |
+
"episodic_slots": 256,
|
| 73 |
+
"multi_scale": true
|
| 74 |
+
}
|
| 75 |
+
},
|
| 76 |
+
|
| 77 |
+
"training_info": {
|
| 78 |
+
"recommended_epochs": 15,
|
| 79 |
+
"recommended_batch_size": 32,
|
| 80 |
+
"learning_rate": 0.0001,
|
| 81 |
+
"optimizer": "AdamW",
|
| 82 |
+
"scheduler": "CosineAnnealingLR",
|
| 83 |
+
"mixed_precision": true
|
| 84 |
+
},
|
| 85 |
+
|
| 86 |
+
"author": {
|
| 87 |
+
"name": "Mike Amega (Logo)",
|
| 88 |
+
"organization": "Ame Web Studio",
|
| 89 |
+
"email": "contact@amewebstudio.com"
|
| 90 |
+
},
|
| 91 |
+
|
| 92 |
+
"license": "Apache-2.0",
|
| 93 |
+
|
| 94 |
+
"citation": {
|
| 95 |
+
"bibtex": "@software{nexus_worldmodel_2025,\n author = {Amega, Mike},\n title = {NEXUS-WorldModel: Neural World Simulator with Cognitive Architecture},\n year = {2025},\n url = {https://huggingface.co/amewebstudio/nexus-worldmodel-v2}\n}"
|
| 96 |
+
}
|
| 97 |
+
}
|
nexus_worldmodel_config.py
ADDED
|
@@ -0,0 +1,979 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
================================================================================
|
| 4 |
+
NEXUS-WorldModel v2.0 - HuggingFace Configuration System
|
| 5 |
+
================================================================================
|
| 6 |
+
|
| 7 |
+
This module provides a robust configuration system for saving/loading
|
| 8 |
+
NEXUS-WorldModel with its dynamic cognitive architecture.
|
| 9 |
+
|
| 10 |
+
Features:
|
| 11 |
+
- Compatible with HuggingFace Hub
|
| 12 |
+
- Handles dynamic components (neurogenesis, expert growth)
|
| 13 |
+
- Preserves cognitive state (energy, dream, memory)
|
| 14 |
+
- Supports incremental retraining
|
| 15 |
+
|
| 16 |
+
Author: Mike Amega (Logo) - Ame Web Studio
|
| 17 |
+
License: Apache 2.0
|
| 18 |
+
================================================================================
|
| 19 |
+
"""
|
| 20 |
+
|
| 21 |
+
import os
|
| 22 |
+
import json
|
| 23 |
+
import copy
|
| 24 |
+
from typing import Dict, List, Optional, Any, Union
|
| 25 |
+
from dataclasses import dataclass, field, asdict
|
| 26 |
+
from pathlib import Path
|
| 27 |
+
|
| 28 |
+
import torch
|
| 29 |
+
import torch.nn as nn
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
# ==============================================================================
|
| 33 |
+
# CONFIGURATION CLASSES
|
| 34 |
+
# ==============================================================================
|
| 35 |
+
|
| 36 |
+
@dataclass
|
| 37 |
+
class WorldConfig:
|
| 38 |
+
"""Configuration for the 2D World Simulation"""
|
| 39 |
+
width: int = 64
|
| 40 |
+
height: int = 64
|
| 41 |
+
channels: int = 3
|
| 42 |
+
gravity: float = 0.1
|
| 43 |
+
friction: float = 0.98
|
| 44 |
+
bounce: float = 0.8
|
| 45 |
+
max_velocity: float = 5.0
|
| 46 |
+
max_agents: int = 5
|
| 47 |
+
max_obstacles: int = 10
|
| 48 |
+
max_zones: int = 3
|
| 49 |
+
agent_radius: float = 2.0
|
| 50 |
+
dt: float = 1.0
|
| 51 |
+
|
| 52 |
+
def to_dict(self) -> Dict:
|
| 53 |
+
return asdict(self)
|
| 54 |
+
|
| 55 |
+
@classmethod
|
| 56 |
+
def from_dict(cls, d: Dict) -> "WorldConfig":
|
| 57 |
+
return cls(**{k: v for k, v in d.items() if k in cls.__dataclass_fields__})
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
@dataclass
|
| 61 |
+
class NexusWorldModelConfig:
|
| 62 |
+
"""
|
| 63 |
+
NEXUS-WorldModel v2.0 Configuration
|
| 64 |
+
|
| 65 |
+
This configuration class is designed to be:
|
| 66 |
+
1. Serializable to JSON for HuggingFace Hub
|
| 67 |
+
2. Robust to architecture changes (neurogenesis, expert growth)
|
| 68 |
+
3. Compatible with partial loading for transfer learning
|
| 69 |
+
|
| 70 |
+
Architecture Type: cognitive-dynamic
|
| 71 |
+
- Experts can grow dynamically
|
| 72 |
+
- Neurons can be born/die
|
| 73 |
+
- Memory states are persistent
|
| 74 |
+
"""
|
| 75 |
+
|
| 76 |
+
# === Model Identity ===
|
| 77 |
+
model_type: str = "nexus-worldmodel"
|
| 78 |
+
version: str = "2.0"
|
| 79 |
+
codename: str = "WorldSim-Cognitive"
|
| 80 |
+
architecture_type: str = "cognitive-dynamic"
|
| 81 |
+
|
| 82 |
+
# === Core Dimensions ===
|
| 83 |
+
d_model: int = 512
|
| 84 |
+
d_ff: int = 2048
|
| 85 |
+
n_layers: int = 8
|
| 86 |
+
n_heads: int = 8
|
| 87 |
+
dropout: float = 0.1
|
| 88 |
+
|
| 89 |
+
# === Latent Space ===
|
| 90 |
+
latent_dim: int = 256
|
| 91 |
+
latent_state_dim: int = 256
|
| 92 |
+
|
| 93 |
+
# === Action Space ===
|
| 94 |
+
action_dim: int = 5 # [no_op, up, down, left, right]
|
| 95 |
+
|
| 96 |
+
# === Sequence ===
|
| 97 |
+
max_seq_len: int = 512
|
| 98 |
+
context_length: int = 16
|
| 99 |
+
prediction_horizon: int = 8
|
| 100 |
+
|
| 101 |
+
# === VAE ===
|
| 102 |
+
encoder_channels: List[int] = field(default_factory=lambda: [32, 64, 128, 256])
|
| 103 |
+
decoder_channels: List[int] = field(default_factory=lambda: [256, 128, 64, 32])
|
| 104 |
+
kl_weight: float = 0.0001
|
| 105 |
+
|
| 106 |
+
# === LPOL Memory (9 domains) ===
|
| 107 |
+
use_lpol: bool = True
|
| 108 |
+
memory_size: int = 512
|
| 109 |
+
memory_k: int = 8
|
| 110 |
+
domain_types: List[str] = field(default_factory=lambda: [
|
| 111 |
+
'physics', 'spatial', 'temporal', 'causal',
|
| 112 |
+
'agent', 'object', 'zone', 'action', 'reward'
|
| 113 |
+
])
|
| 114 |
+
|
| 115 |
+
# === GQA (Grouped Query Attention) ===
|
| 116 |
+
use_gqa: bool = True
|
| 117 |
+
gqa_num_heads: int = 8
|
| 118 |
+
gqa_num_kv_groups: int = 2
|
| 119 |
+
|
| 120 |
+
# === Multi-Scale Memory ===
|
| 121 |
+
multi_scale_enabled: bool = True
|
| 122 |
+
st_decay: float = 0.9
|
| 123 |
+
lt_decay: float = 0.99
|
| 124 |
+
|
| 125 |
+
# === Episodic Memory ===
|
| 126 |
+
episodic_size: int = 256
|
| 127 |
+
episodic_dim: int = 128
|
| 128 |
+
|
| 129 |
+
# === Structural State ===
|
| 130 |
+
structural_dim: int = 64
|
| 131 |
+
structural_decay: float = 0.95
|
| 132 |
+
|
| 133 |
+
# === EARCP (Ensemble Auto-Regulated Coherence Protocol) ===
|
| 134 |
+
expert_types: List[str] = field(default_factory=lambda: [
|
| 135 |
+
'Physics', 'Spatial', 'Temporal', 'Causal', 'Prediction', 'Planning'
|
| 136 |
+
])
|
| 137 |
+
max_experts: int = 12
|
| 138 |
+
growth_threshold_coherence: float = 0.3
|
| 139 |
+
growth_patience: int = 10
|
| 140 |
+
|
| 141 |
+
# === Neurogenesis ===
|
| 142 |
+
neurogenesis_enabled: bool = True
|
| 143 |
+
min_neurons_per_layer: int = 32
|
| 144 |
+
max_neurons_per_layer: int = 256
|
| 145 |
+
neuron_birth_threshold: float = 0.8
|
| 146 |
+
neuron_death_threshold: float = 0.05
|
| 147 |
+
|
| 148 |
+
# === Energy System ===
|
| 149 |
+
energy_cost_think: float = 0.02
|
| 150 |
+
energy_cost_dream: float = 0.1
|
| 151 |
+
energy_regeneration: float = 0.05
|
| 152 |
+
|
| 153 |
+
# === Dream Phase ===
|
| 154 |
+
dream_enabled: bool = True
|
| 155 |
+
dream_cycle_length: int = 50
|
| 156 |
+
dream_duration: int = 10
|
| 157 |
+
prioritized_replay: bool = True
|
| 158 |
+
|
| 159 |
+
# === Internal State ===
|
| 160 |
+
internal_state_dim: int = 128
|
| 161 |
+
tension_integration_rate: float = 0.1
|
| 162 |
+
|
| 163 |
+
# === Multi-World Buffers ===
|
| 164 |
+
world_state_dim: int = 128
|
| 165 |
+
world_update_rate: float = 0.1
|
| 166 |
+
world_domains: List[str] = field(default_factory=lambda: ['physical', 'social', 'abstract', 'temporal'])
|
| 167 |
+
|
| 168 |
+
# === Physics Prior (MDN) ===
|
| 169 |
+
physics_components: int = 8
|
| 170 |
+
physics_hidden: int = 256
|
| 171 |
+
|
| 172 |
+
# === Training ===
|
| 173 |
+
batch_size: int = 32
|
| 174 |
+
learning_rate: float = 1e-4
|
| 175 |
+
epochs: int = 15
|
| 176 |
+
|
| 177 |
+
# === HuggingFace Hub ===
|
| 178 |
+
push_to_hub: bool = True
|
| 179 |
+
hub_model_id: str = "amewebstudio/nexus-worldmodel-v2"
|
| 180 |
+
|
| 181 |
+
# === World Simulation ===
|
| 182 |
+
world: WorldConfig = field(default_factory=WorldConfig)
|
| 183 |
+
|
| 184 |
+
# === Dynamic State Tracking (for save/load) ===
|
| 185 |
+
# These are updated during training and saved with the model
|
| 186 |
+
_dynamic_state: Dict = field(default_factory=lambda: {
|
| 187 |
+
'current_experts_per_layer': [], # List of expert counts per layer
|
| 188 |
+
'current_neurons': 64, # Current neuron count in neurogenesis
|
| 189 |
+
'total_births': 0,
|
| 190 |
+
'total_deaths': 0,
|
| 191 |
+
'total_dreams': 0,
|
| 192 |
+
'training_epochs_completed': 0,
|
| 193 |
+
'best_loss': float('inf')
|
| 194 |
+
})
|
| 195 |
+
|
| 196 |
+
def __post_init__(self):
|
| 197 |
+
# Initialize dynamic state for layers if empty
|
| 198 |
+
if not self._dynamic_state.get('current_experts_per_layer'):
|
| 199 |
+
self._dynamic_state['current_experts_per_layer'] = [
|
| 200 |
+
len(self.expert_types) for _ in range(self.n_layers)
|
| 201 |
+
]
|
| 202 |
+
|
| 203 |
+
def to_dict(self) -> Dict:
|
| 204 |
+
"""Convert config to dictionary for JSON serialization"""
|
| 205 |
+
d = {}
|
| 206 |
+
for key, value in self.__dict__.items():
|
| 207 |
+
if key == 'world':
|
| 208 |
+
d[key] = value.to_dict()
|
| 209 |
+
elif isinstance(value, (list, dict, str, int, float, bool, type(None))):
|
| 210 |
+
d[key] = value
|
| 211 |
+
else:
|
| 212 |
+
d[key] = str(value)
|
| 213 |
+
return d
|
| 214 |
+
|
| 215 |
+
def to_json_string(self) -> str:
|
| 216 |
+
"""Serialize config to JSON string"""
|
| 217 |
+
return json.dumps(self.to_dict(), indent=2)
|
| 218 |
+
|
| 219 |
+
def save_pretrained(self, save_directory: Union[str, Path]):
|
| 220 |
+
"""Save configuration to directory (HuggingFace standard)"""
|
| 221 |
+
save_directory = Path(save_directory)
|
| 222 |
+
save_directory.mkdir(parents=True, exist_ok=True)
|
| 223 |
+
|
| 224 |
+
# Save main config
|
| 225 |
+
config_path = save_directory / "config.json"
|
| 226 |
+
with open(config_path, 'w') as f:
|
| 227 |
+
json.dump(self.to_dict(), f, indent=2)
|
| 228 |
+
|
| 229 |
+
# Save model index for HuggingFace
|
| 230 |
+
model_index = {
|
| 231 |
+
"model_type": self.model_type,
|
| 232 |
+
"version": self.version,
|
| 233 |
+
"architecture_type": self.architecture_type,
|
| 234 |
+
"framework": "pytorch",
|
| 235 |
+
"files": {
|
| 236 |
+
"config": "config.json",
|
| 237 |
+
"weights": "pytorch_model.bin",
|
| 238 |
+
"cognitive_state": "cognitive_state.json"
|
| 239 |
+
}
|
| 240 |
+
}
|
| 241 |
+
with open(save_directory / "model_index.json", 'w') as f:
|
| 242 |
+
json.dump(model_index, f, indent=2)
|
| 243 |
+
|
| 244 |
+
print(f"✅ Configuration saved to {save_directory}")
|
| 245 |
+
|
| 246 |
+
@classmethod
|
| 247 |
+
def from_dict(cls, config_dict: Dict) -> "NexusWorldModelConfig":
|
| 248 |
+
"""Create config from dictionary"""
|
| 249 |
+
# Handle nested WorldConfig
|
| 250 |
+
if 'world' in config_dict and isinstance(config_dict['world'], dict):
|
| 251 |
+
config_dict = config_dict.copy()
|
| 252 |
+
config_dict['world'] = WorldConfig.from_dict(config_dict['world'])
|
| 253 |
+
|
| 254 |
+
# Filter to known fields
|
| 255 |
+
known_fields = set(cls.__dataclass_fields__.keys())
|
| 256 |
+
filtered = {k: v for k, v in config_dict.items() if k in known_fields}
|
| 257 |
+
|
| 258 |
+
return cls(**filtered)
|
| 259 |
+
|
| 260 |
+
@classmethod
|
| 261 |
+
def from_json_file(cls, json_file: Union[str, Path]) -> "NexusWorldModelConfig":
|
| 262 |
+
"""Load config from JSON file"""
|
| 263 |
+
with open(json_file, 'r') as f:
|
| 264 |
+
config_dict = json.load(f)
|
| 265 |
+
return cls.from_dict(config_dict)
|
| 266 |
+
|
| 267 |
+
@classmethod
|
| 268 |
+
def from_pretrained(cls, pretrained_path: Union[str, Path]) -> "NexusWorldModelConfig":
|
| 269 |
+
"""Load configuration from pretrained directory or HuggingFace Hub"""
|
| 270 |
+
pretrained_path = Path(pretrained_path)
|
| 271 |
+
|
| 272 |
+
# Try local path first
|
| 273 |
+
config_file = pretrained_path / "config.json"
|
| 274 |
+
if config_file.exists():
|
| 275 |
+
return cls.from_json_file(config_file)
|
| 276 |
+
|
| 277 |
+
# Try HuggingFace Hub
|
| 278 |
+
try:
|
| 279 |
+
from huggingface_hub import hf_hub_download
|
| 280 |
+
config_file = hf_hub_download(
|
| 281 |
+
repo_id=str(pretrained_path),
|
| 282 |
+
filename="config.json"
|
| 283 |
+
)
|
| 284 |
+
return cls.from_json_file(config_file)
|
| 285 |
+
except Exception as e:
|
| 286 |
+
raise ValueError(f"Could not load config from {pretrained_path}: {e}")
|
| 287 |
+
|
| 288 |
+
def update_dynamic_state(self, model: nn.Module):
|
| 289 |
+
"""Update dynamic state from model after training"""
|
| 290 |
+
# Get expert counts per layer
|
| 291 |
+
if hasattr(model, 'layers'):
|
| 292 |
+
self._dynamic_state['current_experts_per_layer'] = [
|
| 293 |
+
layer.get_expert_count() if hasattr(layer, 'get_expert_count') else len(self.expert_types)
|
| 294 |
+
for layer in model.layers
|
| 295 |
+
]
|
| 296 |
+
|
| 297 |
+
# Get neurogenesis stats
|
| 298 |
+
if hasattr(model, 'neurogenesis'):
|
| 299 |
+
stats = model.neurogenesis.get_stats()
|
| 300 |
+
self._dynamic_state['current_neurons'] = stats.get('total_neurons', 64)
|
| 301 |
+
self._dynamic_state['total_births'] = stats.get('total_births', 0)
|
| 302 |
+
self._dynamic_state['total_deaths'] = stats.get('total_deaths', 0)
|
| 303 |
+
|
| 304 |
+
# Get dream stats
|
| 305 |
+
if hasattr(model, 'dream'):
|
| 306 |
+
dream_stats = model.dream.get_stats()
|
| 307 |
+
self._dynamic_state['total_dreams'] = dream_stats.get('total_dreams', 0)
|
| 308 |
+
|
| 309 |
+
def get_architecture_summary(self) -> str:
|
| 310 |
+
"""Get a human-readable architecture summary"""
|
| 311 |
+
return f"""
|
| 312 |
+
╔══════════════════════════════════════════════════════════════════════╗
|
| 313 |
+
║ NEXUS-WorldModel v{self.version} Configuration ║
|
| 314 |
+
╠══════════════════════════════════════════════════════════════════════╣
|
| 315 |
+
║ Architecture Type: {self.architecture_type:47} ║
|
| 316 |
+
║ ║
|
| 317 |
+
║ Core: ║
|
| 318 |
+
║ d_model: {self.d_model:5} | d_ff: {self.d_ff:5} | n_layers: {self.n_layers:2} | n_heads: {self.n_heads:2} ║
|
| 319 |
+
║ latent_dim: {self.latent_dim:3} | action_dim: {self.action_dim} ║
|
| 320 |
+
║ ║
|
| 321 |
+
║ Memory: ║
|
| 322 |
+
║ LPOL: {len(self.domain_types)} domains | GQA: {self.gqa_num_heads} heads, {self.gqa_num_kv_groups} KV groups ║
|
| 323 |
+
║ Episodic: {self.episodic_size} slots | Memory size: {self.memory_size} ║
|
| 324 |
+
║ ║
|
| 325 |
+
║ Cognitive: ║
|
| 326 |
+
║ Experts: {len(self.expert_types)} types (max {self.max_experts}) | Neurogenesis: {'ON' if self.neurogenesis_enabled else 'OFF':3} ║
|
| 327 |
+
║ Dream Phase: {'ON' if self.dream_enabled else 'OFF':3} | Energy System: ON ║
|
| 328 |
+
║ World Buffers: {len(self.world_domains)} domains ║
|
| 329 |
+
║ ║
|
| 330 |
+
║ Dynamic State: ║
|
| 331 |
+
║ Current neurons: {self._dynamic_state.get('current_neurons', 64):3} | Births: {self._dynamic_state.get('total_births', 0):4} | Deaths: {self._dynamic_state.get('total_deaths', 0):4} ║
|
| 332 |
+
║ Dreams completed: {self._dynamic_state.get('total_dreams', 0):4} ║
|
| 333 |
+
╚══════════════════════════════════════════════════════════════════════╝
|
| 334 |
+
"""
|
| 335 |
+
|
| 336 |
+
|
| 337 |
+
# ==============================================================================
|
| 338 |
+
# COGNITIVE STATE MANAGER
|
| 339 |
+
# ==============================================================================
|
| 340 |
+
|
| 341 |
+
class CognitiveStateManager:
|
| 342 |
+
"""
|
| 343 |
+
Manages the cognitive state of NEXUS-WorldModel for save/load operations.
|
| 344 |
+
|
| 345 |
+
This is crucial for our dynamic architecture because:
|
| 346 |
+
1. Expert counts can change during training (growth)
|
| 347 |
+
2. Neuron counts can change (neurogenesis)
|
| 348 |
+
3. Memory buffers have persistent state
|
| 349 |
+
4. Energy and dream systems have state
|
| 350 |
+
|
| 351 |
+
This manager ensures proper serialization and restoration of these
|
| 352 |
+
dynamic components.
|
| 353 |
+
"""
|
| 354 |
+
|
| 355 |
+
@staticmethod
|
| 356 |
+
def extract_cognitive_state(model: nn.Module) -> Dict[str, Any]:
|
| 357 |
+
"""Extract all cognitive state from model"""
|
| 358 |
+
state = {
|
| 359 |
+
'version': '2.0',
|
| 360 |
+
'state_type': 'cognitive',
|
| 361 |
+
'components': {}
|
| 362 |
+
}
|
| 363 |
+
|
| 364 |
+
# === EARCP Layer States ===
|
| 365 |
+
if hasattr(model, 'layers'):
|
| 366 |
+
layer_states = []
|
| 367 |
+
for i, layer in enumerate(model.layers):
|
| 368 |
+
layer_state = {
|
| 369 |
+
'layer_idx': i,
|
| 370 |
+
'expert_count': layer.get_expert_count() if hasattr(layer, 'get_expert_count') else 0,
|
| 371 |
+
'low_coh_count': layer.low_coh_count.item() if hasattr(layer, 'low_coh_count') else 0
|
| 372 |
+
}
|
| 373 |
+
layer_states.append(layer_state)
|
| 374 |
+
state['components']['earcp_layers'] = layer_states
|
| 375 |
+
|
| 376 |
+
# === Neurogenesis State ===
|
| 377 |
+
if hasattr(model, 'neurogenesis'):
|
| 378 |
+
ng = model.neurogenesis
|
| 379 |
+
state['components']['neurogenesis'] = {
|
| 380 |
+
'n_neurons': ng.n_neurons.item(),
|
| 381 |
+
'usage': ng.usage.tolist(),
|
| 382 |
+
'lifetime': ng.lifetime.tolist(),
|
| 383 |
+
'births': ng.births.item(),
|
| 384 |
+
'deaths': ng.deaths.item()
|
| 385 |
+
}
|
| 386 |
+
|
| 387 |
+
# === Energy System State ===
|
| 388 |
+
if hasattr(model, 'energy'):
|
| 389 |
+
state['components']['energy'] = {
|
| 390 |
+
'energy': model.energy.energy.item(),
|
| 391 |
+
'consumed': model.energy.consumed.item()
|
| 392 |
+
}
|
| 393 |
+
|
| 394 |
+
# === Dream Phase State ===
|
| 395 |
+
if hasattr(model, 'dream'):
|
| 396 |
+
dream = model.dream
|
| 397 |
+
state['components']['dream'] = {
|
| 398 |
+
'is_dreaming': dream.is_dreaming.item(),
|
| 399 |
+
'dream_step': dream.dream_step.item(),
|
| 400 |
+
'cycles_since': dream.cycles_since.item(),
|
| 401 |
+
'total_dreams': dream.total_dreams.item(),
|
| 402 |
+
'buffer_size': len(dream.buffer)
|
| 403 |
+
}
|
| 404 |
+
|
| 405 |
+
# === Self Trace State ===
|
| 406 |
+
if hasattr(model, 'self_trace'):
|
| 407 |
+
state['components']['self_trace'] = {
|
| 408 |
+
'identity_norm': model.self_trace.identity.norm().item(),
|
| 409 |
+
'n_traces': model.self_trace.n_traces.item()
|
| 410 |
+
}
|
| 411 |
+
|
| 412 |
+
# === Memory States ===
|
| 413 |
+
if hasattr(model, 'memory'):
|
| 414 |
+
mem = model.memory
|
| 415 |
+
state['components']['memory'] = {
|
| 416 |
+
'st_norm': mem.st.norm().item(),
|
| 417 |
+
'lt_norm': mem.lt.norm().item()
|
| 418 |
+
}
|
| 419 |
+
|
| 420 |
+
# === Internal State ===
|
| 421 |
+
if hasattr(model, 'internal'):
|
| 422 |
+
state['components']['internal'] = {
|
| 423 |
+
'tension': model.internal.tension.integrate(),
|
| 424 |
+
'discomfort_norm': model.internal.discomfort.norm().item()
|
| 425 |
+
}
|
| 426 |
+
|
| 427 |
+
# === World Buffers ===
|
| 428 |
+
if hasattr(model, 'world_buffers'):
|
| 429 |
+
wb_states = {}
|
| 430 |
+
for domain, buffer in model.world_buffers.world_buffers.items():
|
| 431 |
+
wb_states[domain] = {
|
| 432 |
+
'state_norm': buffer.state.norm().item(),
|
| 433 |
+
'prediction_norm': buffer.prediction.norm().item(),
|
| 434 |
+
'surprise': buffer.surprise.item()
|
| 435 |
+
}
|
| 436 |
+
state['components']['world_buffers'] = wb_states
|
| 437 |
+
|
| 438 |
+
return state
|
| 439 |
+
|
| 440 |
+
@staticmethod
|
| 441 |
+
def save_cognitive_state(model: nn.Module, save_path: Union[str, Path]):
|
| 442 |
+
"""Save cognitive state to JSON file"""
|
| 443 |
+
state = CognitiveStateManager.extract_cognitive_state(model)
|
| 444 |
+
|
| 445 |
+
with open(save_path, 'w') as f:
|
| 446 |
+
json.dump(state, f, indent=2)
|
| 447 |
+
|
| 448 |
+
print(f"✅ Cognitive state saved to {save_path}")
|
| 449 |
+
|
| 450 |
+
@staticmethod
|
| 451 |
+
def load_cognitive_state(load_path: Union[str, Path]) -> Dict[str, Any]:
|
| 452 |
+
"""Load cognitive state from JSON file"""
|
| 453 |
+
with open(load_path, 'r') as f:
|
| 454 |
+
state = json.load(f)
|
| 455 |
+
return state
|
| 456 |
+
|
| 457 |
+
@staticmethod
|
| 458 |
+
def restore_cognitive_state(model: nn.Module, state: Dict[str, Any],
|
| 459 |
+
strict: bool = False) -> List[str]:
|
| 460 |
+
"""
|
| 461 |
+
Restore cognitive state to model.
|
| 462 |
+
|
| 463 |
+
Args:
|
| 464 |
+
model: The model to restore state to
|
| 465 |
+
state: The cognitive state dictionary
|
| 466 |
+
strict: If True, raise error on mismatch. If False, skip mismatches.
|
| 467 |
+
|
| 468 |
+
Returns:
|
| 469 |
+
List of warnings/info about restoration
|
| 470 |
+
"""
|
| 471 |
+
warnings = []
|
| 472 |
+
components = state.get('components', {})
|
| 473 |
+
|
| 474 |
+
# === Restore Energy ===
|
| 475 |
+
if 'energy' in components and hasattr(model, 'energy'):
|
| 476 |
+
model.energy.energy.fill_(components['energy']['energy'])
|
| 477 |
+
model.energy.consumed.fill_(components['energy']['consumed'])
|
| 478 |
+
warnings.append("✓ Energy state restored")
|
| 479 |
+
|
| 480 |
+
# === Restore Dream ===
|
| 481 |
+
if 'dream' in components and hasattr(model, 'dream'):
|
| 482 |
+
dream_state = components['dream']
|
| 483 |
+
model.dream.total_dreams.fill_(dream_state['total_dreams'])
|
| 484 |
+
model.dream.cycles_since.fill_(dream_state['cycles_since'])
|
| 485 |
+
warnings.append(f"✓ Dream state restored (total dreams: {dream_state['total_dreams']})")
|
| 486 |
+
|
| 487 |
+
# === Restore Self Trace ===
|
| 488 |
+
if 'self_trace' in components and hasattr(model, 'self_trace'):
|
| 489 |
+
model.self_trace.n_traces.fill_(components['self_trace']['n_traces'])
|
| 490 |
+
warnings.append("✓ Self trace state restored")
|
| 491 |
+
|
| 492 |
+
# === Restore Neurogenesis (careful - sizes may differ) ===
|
| 493 |
+
if 'neurogenesis' in components and hasattr(model, 'neurogenesis'):
|
| 494 |
+
ng_state = components['neurogenesis']
|
| 495 |
+
saved_neurons = ng_state['n_neurons']
|
| 496 |
+
current_neurons = model.neurogenesis.n_neurons.item()
|
| 497 |
+
|
| 498 |
+
if saved_neurons != current_neurons:
|
| 499 |
+
if strict:
|
| 500 |
+
raise ValueError(f"Neurogenesis mismatch: saved {saved_neurons}, current {current_neurons}")
|
| 501 |
+
warnings.append(f"⚠ Neurogenesis size mismatch: saved {saved_neurons} vs current {current_neurons}")
|
| 502 |
+
else:
|
| 503 |
+
model.neurogenesis.births.fill_(ng_state['births'])
|
| 504 |
+
model.neurogenesis.deaths.fill_(ng_state['deaths'])
|
| 505 |
+
warnings.append(f"✓ Neurogenesis state restored (neurons: {saved_neurons})")
|
| 506 |
+
|
| 507 |
+
# === Restore EARCP Layers (careful - expert counts may differ) ===
|
| 508 |
+
if 'earcp_layers' in components and hasattr(model, 'layers'):
|
| 509 |
+
for layer_state in components['earcp_layers']:
|
| 510 |
+
idx = layer_state['layer_idx']
|
| 511 |
+
if idx < len(model.layers):
|
| 512 |
+
saved_experts = layer_state['expert_count']
|
| 513 |
+
current_experts = model.layers[idx].get_expert_count()
|
| 514 |
+
|
| 515 |
+
if saved_experts != current_experts:
|
| 516 |
+
warnings.append(f"⚠ Layer {idx} expert mismatch: saved {saved_experts} vs current {current_experts}")
|
| 517 |
+
else:
|
| 518 |
+
model.layers[idx].low_coh_count.fill_(layer_state['low_coh_count'])
|
| 519 |
+
|
| 520 |
+
return warnings
|
| 521 |
+
|
| 522 |
+
|
| 523 |
+
# ==============================================================================
|
| 524 |
+
# MODEL SAVE/LOAD UTILITIES
|
| 525 |
+
# ==============================================================================
|
| 526 |
+
|
| 527 |
+
def save_nexus_worldmodel(
|
| 528 |
+
model: nn.Module,
|
| 529 |
+
config: NexusWorldModelConfig,
|
| 530 |
+
save_directory: Union[str, Path],
|
| 531 |
+
save_optimizer: bool = False,
|
| 532 |
+
optimizer: Optional[torch.optim.Optimizer] = None,
|
| 533 |
+
epoch: int = 0,
|
| 534 |
+
loss: float = 0.0
|
| 535 |
+
):
|
| 536 |
+
"""
|
| 537 |
+
Save NEXUS-WorldModel with full state for HuggingFace Hub.
|
| 538 |
+
|
| 539 |
+
Saves:
|
| 540 |
+
- config.json: Model configuration
|
| 541 |
+
- pytorch_model.bin: Model weights
|
| 542 |
+
- cognitive_state.json: Dynamic cognitive state
|
| 543 |
+
- model_index.json: HuggingFace model index
|
| 544 |
+
- training_state.json: Training progress (optional)
|
| 545 |
+
"""
|
| 546 |
+
save_directory = Path(save_directory)
|
| 547 |
+
save_directory.mkdir(parents=True, exist_ok=True)
|
| 548 |
+
|
| 549 |
+
# Update config with current dynamic state
|
| 550 |
+
config.update_dynamic_state(model)
|
| 551 |
+
config._dynamic_state['training_epochs_completed'] = epoch
|
| 552 |
+
config._dynamic_state['best_loss'] = loss
|
| 553 |
+
|
| 554 |
+
# 1. Save configuration
|
| 555 |
+
config.save_pretrained(save_directory)
|
| 556 |
+
|
| 557 |
+
# 2. Save model weights
|
| 558 |
+
weights_path = save_directory / "pytorch_model.bin"
|
| 559 |
+
torch.save(model.state_dict(), weights_path)
|
| 560 |
+
print(f"✅ Model weights saved to {weights_path}")
|
| 561 |
+
|
| 562 |
+
# 3. Save cognitive state
|
| 563 |
+
cognitive_path = save_directory / "cognitive_state.json"
|
| 564 |
+
CognitiveStateManager.save_cognitive_state(model, cognitive_path)
|
| 565 |
+
|
| 566 |
+
# 4. Save training state (for resuming)
|
| 567 |
+
training_state = {
|
| 568 |
+
'epoch': epoch,
|
| 569 |
+
'loss': loss,
|
| 570 |
+
'config_hash': hash(config.to_json_string())
|
| 571 |
+
}
|
| 572 |
+
|
| 573 |
+
if save_optimizer and optimizer is not None:
|
| 574 |
+
optimizer_path = save_directory / "optimizer.pt"
|
| 575 |
+
torch.save(optimizer.state_dict(), optimizer_path)
|
| 576 |
+
training_state['optimizer_saved'] = True
|
| 577 |
+
print(f"✅ Optimizer state saved to {optimizer_path}")
|
| 578 |
+
|
| 579 |
+
with open(save_directory / "training_state.json", 'w') as f:
|
| 580 |
+
json.dump(training_state, f, indent=2)
|
| 581 |
+
|
| 582 |
+
print(f"✅ Full model saved to {save_directory}")
|
| 583 |
+
|
| 584 |
+
|
| 585 |
+
def load_nexus_worldmodel(
|
| 586 |
+
model_class,
|
| 587 |
+
pretrained_path: Union[str, Path],
|
| 588 |
+
device: Union[str, torch.device] = 'cpu',
|
| 589 |
+
strict: bool = False
|
| 590 |
+
) -> tuple:
|
| 591 |
+
"""
|
| 592 |
+
Load NEXUS-WorldModel from pretrained directory or HuggingFace Hub.
|
| 593 |
+
|
| 594 |
+
IMPORTANT: This function handles dynamic architecture automatically!
|
| 595 |
+
- Neurogenesis: neurons may have been added/removed during training
|
| 596 |
+
- Expert Growth: experts may have been added during training
|
| 597 |
+
|
| 598 |
+
The model is automatically resized before loading weights.
|
| 599 |
+
|
| 600 |
+
Args:
|
| 601 |
+
model_class: The NexusWorldModel class
|
| 602 |
+
pretrained_path: Local path or HuggingFace repo ID
|
| 603 |
+
device: Device to load model to
|
| 604 |
+
strict: If True, require exact architecture match.
|
| 605 |
+
Default False (recommended for dynamic arch).
|
| 606 |
+
|
| 607 |
+
Returns:
|
| 608 |
+
(model, config, cognitive_state, warnings)
|
| 609 |
+
|
| 610 |
+
Usage:
|
| 611 |
+
from NEXUS_WorldModel_v2 import NexusWorldModel
|
| 612 |
+
|
| 613 |
+
model, config, cog_state, warnings = load_nexus_worldmodel(
|
| 614 |
+
NexusWorldModel,
|
| 615 |
+
"amewebstudio/nexus-worldmodel-v2",
|
| 616 |
+
device="cuda"
|
| 617 |
+
)
|
| 618 |
+
"""
|
| 619 |
+
pretrained_path = Path(pretrained_path)
|
| 620 |
+
warnings = []
|
| 621 |
+
|
| 622 |
+
# Try local path first
|
| 623 |
+
if pretrained_path.exists():
|
| 624 |
+
config_file = pretrained_path / "config.json"
|
| 625 |
+
weights_file = pretrained_path / "pytorch_model.bin"
|
| 626 |
+
checkpoint_file = pretrained_path / "nexus_worldmodel_v2.pt"
|
| 627 |
+
cognitive_file = pretrained_path / "cognitive_state.json"
|
| 628 |
+
else:
|
| 629 |
+
# Try HuggingFace Hub
|
| 630 |
+
try:
|
| 631 |
+
from huggingface_hub import hf_hub_download
|
| 632 |
+
|
| 633 |
+
config_file = hf_hub_download(str(pretrained_path), "config.json")
|
| 634 |
+
|
| 635 |
+
# Try checkpoint first (contains everything)
|
| 636 |
+
try:
|
| 637 |
+
checkpoint_file = hf_hub_download(str(pretrained_path), "nexus_worldmodel_v2.pt")
|
| 638 |
+
weights_file = None
|
| 639 |
+
except:
|
| 640 |
+
checkpoint_file = None
|
| 641 |
+
weights_file = hf_hub_download(str(pretrained_path), "pytorch_model.bin")
|
| 642 |
+
|
| 643 |
+
try:
|
| 644 |
+
cognitive_file = hf_hub_download(str(pretrained_path), "cognitive_state.json")
|
| 645 |
+
except:
|
| 646 |
+
cognitive_file = None
|
| 647 |
+
warnings.append("⚠ No cognitive_state.json found")
|
| 648 |
+
except Exception as e:
|
| 649 |
+
raise ValueError(f"Could not load from {pretrained_path}: {e}")
|
| 650 |
+
|
| 651 |
+
# 1. Load configuration
|
| 652 |
+
config = NexusWorldModelConfig.from_json_file(config_file)
|
| 653 |
+
print(f"✅ Configuration loaded")
|
| 654 |
+
|
| 655 |
+
# 2. Create model with default sizes
|
| 656 |
+
model = model_class(config)
|
| 657 |
+
model = model.to(device)
|
| 658 |
+
|
| 659 |
+
# 3. Load weights
|
| 660 |
+
if checkpoint_file and Path(checkpoint_file).exists():
|
| 661 |
+
checkpoint = torch.load(checkpoint_file, map_location=device)
|
| 662 |
+
state_dict = checkpoint.get('model', checkpoint)
|
| 663 |
+
|
| 664 |
+
# Extract training info from checkpoint
|
| 665 |
+
if 'epochs' in checkpoint:
|
| 666 |
+
warnings.append(f"ℹ Trained for {checkpoint['epochs']} epochs")
|
| 667 |
+
if 'loss' in checkpoint:
|
| 668 |
+
warnings.append(f"ℹ Final loss: {checkpoint['loss']:.4f}")
|
| 669 |
+
elif weights_file and Path(weights_file).exists():
|
| 670 |
+
state_dict = torch.load(weights_file, map_location=device)
|
| 671 |
+
else:
|
| 672 |
+
raise FileNotFoundError(f"No weights found in {pretrained_path}")
|
| 673 |
+
|
| 674 |
+
# 4. CRITICAL: Resize model to match saved dimensions
|
| 675 |
+
# This handles neurogenesis and expert growth automatically
|
| 676 |
+
if hasattr(model, 'resize_for_loading'):
|
| 677 |
+
resize_warnings = model.resize_for_loading(state_dict)
|
| 678 |
+
warnings.extend(resize_warnings)
|
| 679 |
+
else:
|
| 680 |
+
# Manual resize for older model versions
|
| 681 |
+
warnings.extend(_manual_resize_model(model, state_dict, config))
|
| 682 |
+
|
| 683 |
+
# 5. Load weights (now sizes match!)
|
| 684 |
+
try:
|
| 685 |
+
incompatible = model.load_state_dict(state_dict, strict=strict)
|
| 686 |
+
|
| 687 |
+
if hasattr(incompatible, 'missing_keys') and incompatible.missing_keys:
|
| 688 |
+
warnings.append(f"⚠ Missing {len(incompatible.missing_keys)} keys")
|
| 689 |
+
if hasattr(incompatible, 'unexpected_keys') and incompatible.unexpected_keys:
|
| 690 |
+
warnings.append(f"⚠ Unexpected {len(incompatible.unexpected_keys)} keys")
|
| 691 |
+
|
| 692 |
+
print(f"✅ Model weights loaded")
|
| 693 |
+
except RuntimeError as e:
|
| 694 |
+
if "size mismatch" in str(e):
|
| 695 |
+
warnings.append(f"❌ Size mismatch even after resize: {e}")
|
| 696 |
+
# Try loading what we can
|
| 697 |
+
model_state = model.state_dict()
|
| 698 |
+
loadable = {k: v for k, v in state_dict.items()
|
| 699 |
+
if k in model_state and model_state[k].shape == v.shape}
|
| 700 |
+
model.load_state_dict(loadable, strict=False)
|
| 701 |
+
warnings.append(f"⚠ Partially loaded {len(loadable)}/{len(state_dict)} tensors")
|
| 702 |
+
else:
|
| 703 |
+
raise
|
| 704 |
+
|
| 705 |
+
# 6. Load and restore cognitive state
|
| 706 |
+
cognitive_state = None
|
| 707 |
+
if cognitive_file and Path(cognitive_file).exists():
|
| 708 |
+
cognitive_state = CognitiveStateManager.load_cognitive_state(cognitive_file)
|
| 709 |
+
restore_warnings = CognitiveStateManager.restore_cognitive_state(
|
| 710 |
+
model, cognitive_state, strict=strict
|
| 711 |
+
)
|
| 712 |
+
warnings.extend(restore_warnings)
|
| 713 |
+
print(f"✅ Cognitive state restored")
|
| 714 |
+
|
| 715 |
+
return model, config, cognitive_state, warnings
|
| 716 |
+
|
| 717 |
+
|
| 718 |
+
def _manual_resize_model(model, state_dict: Dict[str, torch.Tensor],
|
| 719 |
+
config) -> List[str]:
|
| 720 |
+
"""
|
| 721 |
+
Manually resize model components for older model versions
|
| 722 |
+
that don't have resize_for_loading method.
|
| 723 |
+
"""
|
| 724 |
+
warnings = []
|
| 725 |
+
|
| 726 |
+
# Resize neurogenesis
|
| 727 |
+
for key, tensor in state_dict.items():
|
| 728 |
+
if 'neurogenesis.weights' in key:
|
| 729 |
+
saved_neurons = tensor.size(0)
|
| 730 |
+
if hasattr(model, 'neurogenesis'):
|
| 731 |
+
current_neurons = model.neurogenesis.n_neurons.item()
|
| 732 |
+
if current_neurons != saved_neurons:
|
| 733 |
+
if hasattr(model.neurogenesis, 'resize'):
|
| 734 |
+
model.neurogenesis.resize(saved_neurons)
|
| 735 |
+
warnings.append(f"✓ Neurogenesis: {current_neurons} → {saved_neurons}")
|
| 736 |
+
else:
|
| 737 |
+
warnings.append(f"⚠ Cannot resize neurogenesis: no resize method")
|
| 738 |
+
break
|
| 739 |
+
|
| 740 |
+
# Resize experts per layer
|
| 741 |
+
n_layers = config.n_layers if hasattr(config, 'n_layers') else 8
|
| 742 |
+
for layer_idx in range(n_layers):
|
| 743 |
+
expert_count = 0
|
| 744 |
+
for key in state_dict.keys():
|
| 745 |
+
if f'layers.{layer_idx}.experts.' in key and '.fc1.weight' in key:
|
| 746 |
+
expert_count += 1
|
| 747 |
+
|
| 748 |
+
if expert_count > 0 and hasattr(model, 'layers') and layer_idx < len(model.layers):
|
| 749 |
+
current_count = model.layers[layer_idx].get_expert_count()
|
| 750 |
+
if current_count != expert_count:
|
| 751 |
+
if hasattr(model.layers[layer_idx], 'resize_experts'):
|
| 752 |
+
model.layers[layer_idx].resize_experts(expert_count)
|
| 753 |
+
warnings.append(f"✓ Layer {layer_idx}: {current_count} → {expert_count} experts")
|
| 754 |
+
else:
|
| 755 |
+
warnings.append(f"⚠ Cannot resize layer {layer_idx}: no resize_experts method")
|
| 756 |
+
|
| 757 |
+
return warnings
|
| 758 |
+
|
| 759 |
+
|
| 760 |
+
# ==============================================================================
|
| 761 |
+
# HUGGINGFACE HUB INTEGRATION
|
| 762 |
+
# ==============================================================================
|
| 763 |
+
|
| 764 |
+
def push_to_hub(
|
| 765 |
+
model: nn.Module,
|
| 766 |
+
config: NexusWorldModelConfig,
|
| 767 |
+
repo_id: str,
|
| 768 |
+
token: Optional[str] = None,
|
| 769 |
+
commit_message: str = "Update NEXUS-WorldModel",
|
| 770 |
+
private: bool = False
|
| 771 |
+
):
|
| 772 |
+
"""
|
| 773 |
+
Push NEXUS-WorldModel to HuggingFace Hub.
|
| 774 |
+
|
| 775 |
+
Args:
|
| 776 |
+
model: The trained model
|
| 777 |
+
config: Model configuration
|
| 778 |
+
repo_id: HuggingFace repository ID (e.g., "username/model-name")
|
| 779 |
+
token: HuggingFace API token
|
| 780 |
+
commit_message: Commit message
|
| 781 |
+
private: Whether the repo should be private
|
| 782 |
+
"""
|
| 783 |
+
from huggingface_hub import HfApi, create_repo, upload_folder
|
| 784 |
+
import tempfile
|
| 785 |
+
|
| 786 |
+
# Get token
|
| 787 |
+
if token is None:
|
| 788 |
+
token = os.environ.get('HF_TOKEN')
|
| 789 |
+
|
| 790 |
+
if token is None:
|
| 791 |
+
try:
|
| 792 |
+
from kaggle_secrets import UserSecretsClient
|
| 793 |
+
token = UserSecretsClient().get_secret("HF_TOKEN")
|
| 794 |
+
except:
|
| 795 |
+
pass
|
| 796 |
+
|
| 797 |
+
if token is None:
|
| 798 |
+
raise ValueError("No HuggingFace token found. Set HF_TOKEN environment variable.")
|
| 799 |
+
|
| 800 |
+
api = HfApi()
|
| 801 |
+
|
| 802 |
+
# Create repo if needed
|
| 803 |
+
try:
|
| 804 |
+
create_repo(repo_id, token=token, private=private, exist_ok=True)
|
| 805 |
+
print(f"✅ Repository ready: {repo_id}")
|
| 806 |
+
except Exception as e:
|
| 807 |
+
print(f"⚠ Repository creation: {e}")
|
| 808 |
+
|
| 809 |
+
# Save to temp directory
|
| 810 |
+
with tempfile.TemporaryDirectory() as tmpdir:
|
| 811 |
+
save_nexus_worldmodel(
|
| 812 |
+
model=model,
|
| 813 |
+
config=config,
|
| 814 |
+
save_directory=tmpdir,
|
| 815 |
+
epoch=config._dynamic_state.get('training_epochs_completed', 0),
|
| 816 |
+
loss=config._dynamic_state.get('best_loss', 0)
|
| 817 |
+
)
|
| 818 |
+
|
| 819 |
+
# Create README
|
| 820 |
+
readme_content = create_model_card(model, config)
|
| 821 |
+
with open(os.path.join(tmpdir, "README.md"), 'w') as f:
|
| 822 |
+
f.write(readme_content)
|
| 823 |
+
|
| 824 |
+
# Upload
|
| 825 |
+
api.upload_folder(
|
| 826 |
+
folder_path=tmpdir,
|
| 827 |
+
repo_id=repo_id,
|
| 828 |
+
token=token,
|
| 829 |
+
commit_message=commit_message
|
| 830 |
+
)
|
| 831 |
+
|
| 832 |
+
print(f"✅ Model pushed to: https://huggingface.co/{repo_id}")
|
| 833 |
+
|
| 834 |
+
|
| 835 |
+
def create_model_card(model: nn.Module, config: NexusWorldModelConfig) -> str:
|
| 836 |
+
"""Create a model card for HuggingFace Hub"""
|
| 837 |
+
|
| 838 |
+
# Get dynamic stats
|
| 839 |
+
stats = config._dynamic_state
|
| 840 |
+
|
| 841 |
+
return f"""---
|
| 842 |
+
license: apache-2.0
|
| 843 |
+
language:
|
| 844 |
+
- en
|
| 845 |
+
tags:
|
| 846 |
+
- nexus-worldmodel
|
| 847 |
+
- world-model
|
| 848 |
+
- cognitive-architecture
|
| 849 |
+
- earcp
|
| 850 |
+
- lpol
|
| 851 |
+
- neurogenesis
|
| 852 |
+
- gqa
|
| 853 |
+
- pytorch
|
| 854 |
+
pipeline_tag: reinforcement-learning
|
| 855 |
+
library_name: pytorch
|
| 856 |
+
---
|
| 857 |
+
|
| 858 |
+
# NEXUS-WorldModel v{config.version}
|
| 859 |
+
|
| 860 |
+
**"Learning to Simulate Reality with Full Cognitive Architecture"**
|
| 861 |
+
|
| 862 |
+
## Model Description
|
| 863 |
+
|
| 864 |
+
NEXUS-WorldModel is a neural world simulator that uses a complete cognitive architecture to learn and predict 2D physics environments. Unlike traditional world models, it features:
|
| 865 |
+
|
| 866 |
+
- **Dynamic Architecture**: Experts and neurons grow during training
|
| 867 |
+
- **Cognitive Systems**: Energy management, dream phases, memory consolidation
|
| 868 |
+
- **Multi-Domain Memory**: 9 specialized LPOL memory domains
|
| 869 |
+
- **GQA**: Grouped Query Attention for efficient memory access
|
| 870 |
+
|
| 871 |
+
## Architecture Components
|
| 872 |
+
|
| 873 |
+
| Component | Description |
|
| 874 |
+
|-----------|-------------|
|
| 875 |
+
| **EARCP Module** | Sparse Compression + Gated Integration |
|
| 876 |
+
| **LPOL Memory** | {len(config.domain_types)} domains with GQA |
|
| 877 |
+
| **GQA** | {config.gqa_num_heads} heads, {config.gqa_num_kv_groups} KV groups |
|
| 878 |
+
| **EARCP Layers** | {config.n_layers} layers with dynamic experts |
|
| 879 |
+
| **Neurogenesis** | {'Enabled' if config.neurogenesis_enabled else 'Disabled'} |
|
| 880 |
+
| **Dream Phase** | {'Enabled' if config.dream_enabled else 'Disabled'} |
|
| 881 |
+
| **Physics Prior** | MDN with {config.physics_components} components |
|
| 882 |
+
|
| 883 |
+
## Training Information
|
| 884 |
+
|
| 885 |
+
- **Epochs Completed**: {stats.get('training_epochs_completed', 0)}
|
| 886 |
+
- **Best Loss**: {stats.get('best_loss', 'N/A')}
|
| 887 |
+
- **Parameters**: {model.count_params():,}
|
| 888 |
+
- **Current Neurons**: {stats.get('current_neurons', 64)}
|
| 889 |
+
- **Total Births**: {stats.get('total_births', 0)}
|
| 890 |
+
- **Total Deaths**: {stats.get('total_deaths', 0)}
|
| 891 |
+
- **Total Dreams**: {stats.get('total_dreams', 0)}
|
| 892 |
+
|
| 893 |
+
## Usage
|
| 894 |
+
|
| 895 |
+
```python
|
| 896 |
+
from nexus_worldmodel_config import load_nexus_worldmodel, NexusWorldModelConfig
|
| 897 |
+
from NEXUS_WorldModel_v2 import NexusWorldModel
|
| 898 |
+
|
| 899 |
+
# Load from HuggingFace Hub
|
| 900 |
+
model, config, cognitive_state, warnings = load_nexus_worldmodel(
|
| 901 |
+
NexusWorldModel,
|
| 902 |
+
"{config.hub_model_id}",
|
| 903 |
+
device="cuda"
|
| 904 |
+
)
|
| 905 |
+
|
| 906 |
+
# Or create fresh model
|
| 907 |
+
config = NexusWorldModelConfig()
|
| 908 |
+
model = NexusWorldModel(config)
|
| 909 |
+
|
| 910 |
+
# Encode observation
|
| 911 |
+
z, mu, logvar, z_d = model.encode(obs_tensor)
|
| 912 |
+
|
| 913 |
+
# Predict next state
|
| 914 |
+
prediction = model.predict_next(z, action)
|
| 915 |
+
|
| 916 |
+
# Dream/imagine trajectory
|
| 917 |
+
dream = model.dream_trajectory(z_start, action_sequence)
|
| 918 |
+
```
|
| 919 |
+
|
| 920 |
+
## Configuration
|
| 921 |
+
|
| 922 |
+
Key parameters:
|
| 923 |
+
```python
|
| 924 |
+
d_model: {config.d_model}
|
| 925 |
+
n_layers: {config.n_layers}
|
| 926 |
+
latent_dim: {config.latent_dim}
|
| 927 |
+
domain_types: {config.domain_types}
|
| 928 |
+
expert_types: {config.expert_types}
|
| 929 |
+
```
|
| 930 |
+
|
| 931 |
+
## Files
|
| 932 |
+
|
| 933 |
+
| File | Description |
|
| 934 |
+
|------|-------------|
|
| 935 |
+
| `config.json` | Model configuration |
|
| 936 |
+
| `pytorch_model.bin` | Model weights |
|
| 937 |
+
| `cognitive_state.json` | Dynamic cognitive state |
|
| 938 |
+
| `model_index.json` | HuggingFace model index |
|
| 939 |
+
|
| 940 |
+
## Important Notes
|
| 941 |
+
|
| 942 |
+
⚠️ **Dynamic Architecture**: This model has components that can grow during training:
|
| 943 |
+
- Expert count per layer may vary
|
| 944 |
+
- Neuron count in neurogenesis layer may vary
|
| 945 |
+
- Use `strict=False` when loading to handle size mismatches
|
| 946 |
+
|
| 947 |
+
## Author
|
| 948 |
+
|
| 949 |
+
**Mike Amega (Logo)** - Ame Web Studio
|
| 950 |
+
|
| 951 |
+
## License
|
| 952 |
+
|
| 953 |
+
Apache 2.0
|
| 954 |
+
"""
|
| 955 |
+
|
| 956 |
+
|
| 957 |
+
# ==============================================================================
|
| 958 |
+
# MAIN (Testing)
|
| 959 |
+
# ==============================================================================
|
| 960 |
+
|
| 961 |
+
if __name__ == "__main__":
|
| 962 |
+
# Test configuration
|
| 963 |
+
config = NexusWorldModelConfig()
|
| 964 |
+
|
| 965 |
+
print(config.get_architecture_summary())
|
| 966 |
+
|
| 967 |
+
# Test serialization
|
| 968 |
+
json_str = config.to_json_string()
|
| 969 |
+
print("\n📄 Config JSON (truncated):")
|
| 970 |
+
print(json_str[:500] + "...")
|
| 971 |
+
|
| 972 |
+
# Test save/load cycle
|
| 973 |
+
import tempfile
|
| 974 |
+
with tempfile.TemporaryDirectory() as tmpdir:
|
| 975 |
+
config.save_pretrained(tmpdir)
|
| 976 |
+
loaded = NexusWorldModelConfig.from_pretrained(tmpdir)
|
| 977 |
+
print(f"\n✅ Save/Load cycle successful")
|
| 978 |
+
print(f" Original d_model: {config.d_model}")
|
| 979 |
+
print(f" Loaded d_model: {loaded.d_model}")
|
nexus_worldmodel_v2.pt
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:61b77e3c47e91451f07ee84f6e1031561a20088ddb50cdfdaa0563934cb89d11
|
| 3 |
+
size 914665457
|