Dynamic Neural Organism (DNO): A self-evolving, growing, and pruning neural network framework.
Project description
DNO: Dynamic Neural Organism ๐งฌ
"Don't just train a model. Raise an organism."
DNO (Dynamic Neural Organism) is a PyTorch framework that treats neural networks as living, evolving biological entities. Unlike static architectures that are fixed at initialization, a DNO grows new layers, specializes into expert lobes, and prunes dead tissue โ all in real-time, based on the complexity of the data it consumes.
๐ Table of Contents
- Quickstart
- Core Philosophy
- Architecture Overview
- The DNO Lifecycle
- Advanced Mechanics
- API Reference
- Changelog
- Contributing & License
โก Quickstart
pip install dno
import torch
import torch.nn as nn
from dno import (
OrganismManager, DynamicNetwork, BaseEvolvableModule,
DnoConfig, GrowthEngine
)
# 1. Configure the organism's DNA
config = DnoConfig(training_phase='adaptive', d_model=64, entropy_threshold=0.5)
# 2. Build the body
manager = OrganismManager()
network = DynamicNetwork(manager, config)
# 3. Plant the seed (any PyTorch module)
seed = BaseEvolvableModule(nn.Linear(64, 64))
seed.dynamic_id = "seed_cortex"
seed.set_specialty("general")
network.add_layer(seed)
# 4. When the organism gets confused, it grows!
growth = GrowthEngine(network, config)
optimizer = torch.optim.Adam(network.parameters(), lr=1e-3)
# Force-grow a new expert lobe
growth.inject_layer("seed_cortex", "expert_math", optimizer=optimizer)
# Focus training only on the new expert
growth.freeze_all_except("expert_math")
print(f"๐งฌ Organism now has {len(manager.registry)} active layers")
# >>> ๐งฌ Organism now has 2 active layers
๐ง Core Philosophy
Traditional AI is like a Statue: You carve it (define architecture), polish it (train), and it stays that way forever.
DNO is like a Tree: You plant a seed (Seed Cortex). If the environment is rich (complex data), it grows branches (Expert Lobes). If a branch is useless, it withers and gets pruned.
Key Capabilities
| Feature | Description |
|---|---|
| Neurogenesis (Mitosis) | The network physically adds new layers when "confused" (High Entropy) |
| Specialized Organisms | The brain divides into a "General Core" and task-specific "Expert Lobes" |
| Dynamic Gradient Locking | Automatically freezes Core during Expert training and vice versa |
| Surgical Training Control | Manually inject layers, freeze/unfreeze specific experts |
| Smart Routing | Routes "Familiar" data to the Core and "Novel" data to Experts |
| Robust Persistence | Save/Load with automatic repair of broken or missing modules |
| Auto-Casting | Safely handles raw Token IDs (LongTensor) by auto-casting to Float32 |
| Survival Engine | Monitors layer utility via Information Gain; prunes dead tissue |
๐ Architecture Overview
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ DynamicNetwork (Body) โ
โ โ
Input โโโโโโโโโโโบ โ โโโโโโโโโโโโโโโโ โ
โ โ Seed Cortex โโโโโ General Core โ
โ โ (general) โ โ
โ โโโโโโโโฌโโโโโโโโ โ
โ โ Mitosis (Clone + Noise) โ
โ โโโโโโดโโโโโ โ
โ โผ โผ โ
โ โโโโโโโโ โโโโโโโโ โ
โ โExpertโ โExpertโ โโโ Specialized โ
โ โ Math โ โ Code โ Lobes โ
โ โโโโฌโโโโ โโโโฌโโโโ โ
โ โโโโโโฌโโโโ โ
โ โผ โ โโโโโโโบ Output
โ Smart Aggregation โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Managed by:
โโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ OrganismManager โ โ GrowthEngine โ โ SurvivalEngine โ
โ (Brain Map/Graph) โ โ (Mitosis) โ โ (Pruning/GC) โ
โโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
What happens during Mitosis?
- Cloning: The parent layer is deep-copied.
- Mutation: Variance-based noise (from optimizer state) is added to break symmetry.
- Gamma Gating: The clone enters with
gamma=0.0(IdentityWrapper) so it initially does nothing, then gradually participates. - Rewiring: The clone is connected to the same inputs/outputs as the parent (parallel branch).
- Optimizer Sync: The clone's parameters are registered to the optimizer with a high initial LR that decays (Cold Start).
๐งฌ The DNO Lifecycle
Raising a DNO involves distinct biological phases.
Phase 1: DNA Configuration (DnoConfig)
Before birth, define the organism's genetic constraints.
from dno import DnoConfig
config = DnoConfig(
# --- Lifecycle ---
training_phase='scratch', # 'scratch' (Infancy) or 'adaptive' (Adulthood)
# --- Growth Triggers ---
entropy_threshold=0.6, # Confusion > 0.6 โ consider growing
evolution_cooldown_steps=100, # Min steps between mitosis events
min_loss_improvement=0.001, # Required loss drop before allowing new growth
# --- Physical Constraints ---
max_param_count=100_000_000, # Cap at 100M parameters
vram_limit_gb=4.0, # Stop growing if VRAM exceeds 4GB
# --- Architecture Defaults ---
d_model=128, # Hidden dimension size
n_heads=4, # Attention heads for Transformer blocks
dropout_rate=0.1, # Dropout rate
# --- Survival ---
utility_threshold=0.01, # Layers below this are marked "dying"
grace_period=100, # Steps before dying layers get pruned
)
Tip: Set
manual_mode=Trueto skip auto-scaling ofd_model,n_heads, andlearning_rate.
Phase 2: Infancy (scratch Training)
Goal: Build a strong generalist core ("Seed Cortex").
Behavior: Growth is DISABLED. The model behaves like a standard, static PyTorch model.
from dno import OrganismManager, BaseEvolvableModule, DynamicNetwork
import torch
import torch.nn as nn
# 1. Initialize
manager = OrganismManager()
network = DynamicNetwork(manager, config)
# 2. Add the Seed Cortex (any PyTorch module)
seed_layer = nn.Sequential(
nn.Linear(128, 128),
nn.ReLU(),
nn.Linear(128, 10)
)
seed = BaseEvolvableModule(seed_layer)
seed.dynamic_id = "seed_cortex"
seed.set_specialty("general") # Mark as General Core
network.add_layer(seed)
# 3. Standard PyTorch training loop โ NO growth happens
optimizer = torch.optim.Adam(network.parameters(), lr=1e-3)
for epoch in range(100):
optimizer.zero_grad()
output = network(input_data)
loss = criterion(output, targets)
loss.backward()
optimizer.step()
Phase 3: Adulthood (adaptive Growth)
Goal: Adapt to new, complex tasks by growing specialized organs.
Behavior: The model monitors entropy. High confusion triggers Mitosis.
from dno import GrowthEngine
# 1. Switch Phase
config.training_phase = 'adaptive'
# 2. Initialize Growth Engine
growth_engine = GrowthEngine(network, config)
# 3. Training loop with entropy monitoring
for step in range(1000):
optimizer.zero_grad()
output = network(inputs)
loss = criterion(output, targets)
loss.backward()
optimizer.step()
# Calculate entropy manually (or use your own tracking)
with torch.no_grad():
probs = torch.softmax(output, dim=-1)
entropy = -torch.sum(probs * torch.log(probs + 1e-9), dim=-1).mean().item()
# Check growth trigger (pass recent entropy history)
entropy_history.append(entropy)
is_triggered, reason = growth_engine.check_growth_trigger(
entropy_history=entropy_history[-10:],
current_step=step,
current_loss=loss.item()
)
if is_triggered:
print(f"๐ EPIPHANY! Reason: {reason}")
# Trigger Mitosis โ clone the seed into a new expert
growth_engine.mitosis(
parent_uuid="seed_cortex",
optimizer=optimizer,
specialty_tag="expert_coding_v1"
)
# Decay new layer learning rates
growth_engine.stabilize_optimizer(optimizer)
Phase 4: Fluid Serialization (Save/Load)
Standard torch.save fails on DNOs because the architecture changes dynamically. Use the .dno format.
# Save everything (Topology + Weights + Config + History)
network.save_dno("my_organism.dno")
# Or save just the state_dict for standard PyTorch compatibility
network.save_standard("checkpoint.pt")
Loading requires a module factory โ a function that reconstructs your custom blocks by type name:
from dno import DynamicNetwork
from dno.core.blueprints import SeedBlock
def my_factory(type_name):
"""Reconstructs modules by their class name."""
if type_name == "SeedBlock":
return SeedBlock(input_dim=128, hidden_dim=256)
if type_name == "Sequential":
return nn.Sequential(nn.Linear(128, 128), nn.ReLU(), nn.Linear(128, 10))
# Return None to trigger automatic GPTModel fallback
return None
loaded_network = DynamicNetwork.load_dno("my_organism.dno", module_factory=my_factory)
Note: If the factory returns
Noneor raises an exception for a module type, DNO automatically reconstructs it as aGPTModelTransformer block. See Zombie Repair below.
๐ง Advanced Mechanics
Surgical Training Control
Use GrowthEngine to manually direct evolution โ don't wait for entropy triggers.
from dno import GrowthEngine
growth_engine = GrowthEngine(network, config)
# 1. Inject a new expert lobe (forced mitosis)
# IMPORTANT: Pass the optimizer so its parameters are registered!
growth_engine.inject_layer(
parent_tag_or_uuid="seed_cortex",
new_tag="expert_math_v1",
optimizer=optimizer,
base_lr=0.001
)
# 2. Freeze everything EXCEPT the new expert
# This prevents interference during focused training
growth_engine.freeze_all_except("expert_math_v1")
# 3. Train on math dataset...
for batch in math_dataloader:
optimizer.zero_grad()
output = network(batch)
loss = criterion(output, targets)
loss.backward()
optimizer.step()
Robust Persistence & Zombie Repair
DNO is resilient to corruption and missing class definitions. If you load a brain but the factory can't reconstruct a specific layer:
- Automatic Fallback: The broken layer is replaced with a generic
GPTModel(Transformer Decoder block). - Deep Scan & Repair: After loading, a full scan identifies and replaces any
Noneor broken modules. - Topology Preservation: All graph connections (edges, inputs, outputs) remain intact.
# Even with a broken/incomplete factory, loading succeeds
net = DynamicNetwork.load_dno("brain.dno", module_factory=lambda t: None)
# >> [WARNING] Factory failed for SeedBlock...
# >> [REPAIR] Reconstructing as default GPTModel.
# >> [OK] Organism Resurrected.
Dynamic Gradient Locking ๐
DNO automatically manages requires_grad to prevent Catastrophic Forgetting:
| Data Type | General Core | Expert Lobes |
|---|---|---|
| Familiar (CPT) | โ Training | โ๏ธ Frozen |
| Novel (SFT) | โ๏ธ Frozen | โ Training |
| Scratch Phase | โ Training | N/A (no experts yet) |
This happens automatically inside network.forward() based on entropy-based novelty detection.
Auto-Casting ๐ก๏ธ
If you pass raw LongTensor inputs (Token IDs) to a module expecting floats:
- DNO performs a Deep Scan of all submodules to check for
nn.Embeddinglayers. - If an
Embeddingis found โ data is preserved asLong(correct behavior). - If no
Embeddingโ data is auto-cast toFloat32to preventdtype mismatcherrors.
Survival Engine (Pruning) ๐งน
The SurvivalEngine acts as the organism's immune system:
from dno import SurvivalEngine
survival = SurvivalEngine(manager, config)
# Inside training loop:
# 1. Monitor utility (Information Gain via KL Divergence)
for uuid, module in manager.registry.items():
survival.calculate_information_gain(module, input_tensor, output_tensor)
# 2. Decay dying layers' weights
survival.apply_selective_decay(optimizer)
# 3. Garbage collect dead tissue
removed = survival.garbage_collect(network)
print(f"Pruned {removed} dead layers")
Layers with low utility score enter a grace period. If they don't recover, their weights decay to zero and they're removed from the graph.
๐ API Reference
Core Classes
| Class | Module | Description |
|---|---|---|
DnoConfig |
dno.config |
Dataclass with all organism parameters (growth, survival, hardware limits) |
OrganismManager |
dno.core.manager |
Central graph manager โ tracks nodes, edges, and topology |
DynamicNetwork |
dno.core.network |
The executable body โ runs forward pass through the organism graph |
BaseEvolvableModule |
dno.core.base |
Wrapper that adds biological metadata and energy tracking to any nn.Module |
GrowthEngine |
dno.core.growth |
Handles mitosis, entropy triggers, optimizer sync, and surgical controls |
SurvivalEngine |
dno.core.survival |
Monitors utility, applies weight decay, garbage collects dead layers |
Blueprint Classes
| Class | Module | Description |
|---|---|---|
SeedBlock |
dno.core.blueprints |
Specialized block with genetic masking (partial layer freezing) |
IdentityWrapper |
dno.core.blueprints |
Gamma-gated residual wrapper โ new layers enter as identity ops (gamma=0) |
GPTModel |
dno.core.blueprints |
Standard Transformer Decoder block โ used as default fallback during load |
Key Methods
| Method | Class | Description |
|---|---|---|
add_layer(module, parents) |
DynamicNetwork |
Adds a layer to the organism graph |
save_dno(path) |
DynamicNetwork |
Saves topology + weights + config as .dno zip |
save_standard(path) |
DynamicNetwork |
Saves only the state_dict (.pt format) |
load_dno(path, factory) |
DynamicNetwork |
Class method โ loads .dno with auto-repair |
mitosis(parent, optimizer, ...) |
GrowthEngine |
Clones a layer with smart noise and rewiring |
inject_layer(parent, tag, optimizer) |
GrowthEngine |
Manual mitosis trigger |
freeze_all_except(tag) |
GrowthEngine |
Freezes all modules except those matching tag |
check_growth_trigger(entropy, step) |
GrowthEngine |
Returns (bool, reason) for growth decision |
get_module(tag_or_uuid) |
OrganismManager |
Lookup by specialty tag or UUID |
list_organs() |
OrganismManager |
Returns summary of all active layers |
garbage_collect(network) |
SurvivalEngine |
Removes dead layers from graph |
Utility Functions
| Function | Module | Description |
|---|---|---|
load_dno(path, factory) |
dno |
Top-level shortcut for DynamicNetwork.load_dno |
print_organism_status(manager) |
dno.utils.dashboard |
Pretty-prints organism anatomy to terminal |
๐ Changelog
v0.3.0 โ Project Cleanup & Definitive API
- Breaking: Removed stale
organism.py(usemanager.py/OrganismManager) - New: All public classes exported from top-level
dnopackage - New:
MANIFEST.inensures README/LICENSE in distributions - Fixed:
train_demo.pyupdated with correct imports - Docs: Complete README rewrite with Quickstart, Architecture, API Reference, and Changelog
v0.2.7 โ Surgical Training Control
- New:
GrowthEngine.inject_layer()โ manual mitosis trigger - New:
GrowthEngine.freeze_all_except()โ surgical freeze - New:
OrganismManager.get_module()โ tag-based lookup - New:
OrganismManager.list_organs()โ organ summary - New:
GPTModelblueprint โ Transformer Decoder fallback - New: Robust
load_dno()with automatic Zombie Repair - New: Deep Scan & Repair on load
v0.2.6 โ Auto-Casting
- New: Deep scan for nested
nn.Embeddinglayers during auto-cast - Fixed:
LongTensorcorrectly preserved for Embedding inputs
v0.2.0 โ Specialized Organisms
- New: Data-Aware Routing (CPT vs SFT)
- New: Dynamic Gradient Locking
- New:
set_specialty()for tagging modules - New: Smart Aggregation for parallel branches
v0.1.x โ Foundation
- Core
OrganismManagergraph engine BaseEvolvableModulewith energy trackingGrowthEnginewith entropy-based mitosisSurvivalEnginewith KL-Divergence utility monitoringIdentityWrapperwith gamma gatingSeedBlockwith genetic masking- Fluid Serialization (
.dnoformat) SurvivalEnginegarbage collection- Dashboard visualization
๐ค Contributing
DNO is an open-source experiment. We welcome contributions!
- Bug Reports: Open an issue on GitHub
- Feature Ideas: New "Organs" (Memory modules, Attention variants, RL-based growth triggers)
- Pull Requests: Fork, implement, test, and submit!
๐ License
MIT License. See LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dno-0.3.2.tar.gz.
File metadata
- Download URL: dno-0.3.2.tar.gz
- Upload date:
- Size: 32.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6bbae182c61875b9117cd6beac4d22fe9ab76577ccd030110dc13b0b38c85974
|
|
| MD5 |
3835650a8b68b73f7d9fbed7a5057e5a
|
|
| BLAKE2b-256 |
a5b651308eda941f4f5a4bc32d534bfec30f81b8863a3b6db13c3a5bc6ff828e
|
File details
Details for the file dno-0.3.2-py3-none-any.whl.
File metadata
- Download URL: dno-0.3.2-py3-none-any.whl
- Upload date:
- Size: 29.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6eb74cb47a48a33dca974f7801b769a6f9ca8d14298b6bc876ebb7aa8f2d0c46
|
|
| MD5 |
4839e1ed7aa2224edc27a164d633ef6d
|
|
| BLAKE2b-256 |
110fff464feba1bc60e0a3779b1195a8b478e1e1d6be9304cbb6c5b349e9f838
|