comfyui-stanno / README.md
oldman-dev's picture
Update README.md
05a2213 verified
---
license: mit
language:
- en
tags:
- comfyui
- custom-nodes
- stanno
- nodes
---
# STANNO — Neural Networks That Train Neural Networks
A modern, open-source Python library implementing the **Artificial Neurogenesis Network** concept from US Patent 5,852,815 (Thaler, 1998). One network (the trainer) decides how another network (the trainee) should update its weights — no backpropagation needed. Multiple STANNOs can be chained into cascade pipelines, and any trained STANNO can be turned into a data scanner that finds matching rows in large datasets.
> **Attribution**: This is a faithful, open-source implementation of Thaler's patented design with modern extensions (cascading, data scanning, ComfyUI integration). The original patent has expired. All core concepts are credited to the original patent.
## ⚠️ What STANNO Is (and Isn't)
**STANNO is specialized**, not a drop-in replacement for PyTorch.
**Good for:**
- Anomaly detection (reconstruction-based scoring)
- Online/continual learning (one-sample-at-a-time updates)
- Interpretable weight modification (see exactly what changes)
- Multi-stage cascade pipelines (encoder → bottleneck → decoder, end-to-end)
- Semantic data scanning (find rows in a large dataset that match learned distribution)
- ComfyUI creative workflows (style transfer via dream mode)
**NOT for:**
- General regression (accuracy ~0.4, use PyTorch instead)
- Image generation alone (need Stable Diffusion + nodes)
- High-throughput training (slow NumPy)
For details, see [STANNO_IS_NOT.md](./STANNO_IS_NOT.md).
**What you can do with this:**
**Train networks on your data:**
```python
from stanno import STANNO
from stanno.config.schema import STANNOConfig
import numpy as np
config = STANNOConfig(layers=[784, 256, 10])
stanno = STANNO(config)
stanno.fit(x_train, y_train, epochs=100)
predictions = stanno.predict(x_test)
```
**Chain into cascade pipelines:**
```python
from stanno import STANNO, STANNOConfig, CascadeSTANNO
# Encoder-decoder autoencoder
enc = STANNO(STANNOConfig(layers=[768, 256, 64], learning_rate=0.05))
dec = STANNO(STANNOConfig(layers=[64, 256, 768], learning_rate=0.05))
ae = CascadeSTANNO([enc, dec])
ae.fit(embeddings, embeddings, epochs=200) # end-to-end gradient cascade
# Extract compressed representations
codes = ae.intermediate_output(embeddings, stage=0) # (N, 64)
# Freeze the encoder, continue adapting the decoder
ae.freeze(0)
ae.fit(new_domain_embeddings, new_domain_embeddings, epochs=100)
```
**Scan large datasets for matching rows (DSANNO):**
```python
from stanno import STANNO, STANNOConfig, DSANNO
# Train on known-good data
detector = STANNO(STANNOConfig(layers=[64, 128, 64], learning_rate=0.05))
detector.fit(normal_data, normal_data, epochs=200)
scanner = DSANNO(detector, mode="reconstruction")
# Auto-calibrate threshold from training distribution
threshold = scanner.calibrate_threshold(normal_data, percentile=95)
# Find matching rows in a large corpus
result = scanner.scan(large_corpus, threshold=threshold)
matching = large_corpus[result.matched_indices()]
# Or retrieve the top-k best matches
indices, scores, _ = scanner.top_k(large_corpus, k=20)
# Stream huge files without loading all at once
for batch_result in scanner.scan_stream(file_batches, threshold=threshold):
process(batch_result.matched_indices())
```
**Detect when inputs are unusual (anomaly filter):**
```python
from stanno.integration.filter import STANNOFilter
# Train on normal data
stanno.fit(normal_data, normal_data, epochs=50)
# Score new input
score, metadata = stanno_filter.score(new_input)
# score ranges [0, 1]: low = normal, high = anomaly
```
**Generate variations via "dream mode":**
```python
# Start with a seed input, add noise, generate a sequence
dream_sequence = stanno.dream(
num_steps=64,
input_seed=seed_vector,
noise_sigma=0.1 # controls creativity
)
```
**Use in ComfyUI workflows (9 nodes):**
- Load/create STANNO models
- Train on image batches
- Score/filter images
- Inject dream creativity into CLIP conditioning
- Apply dream output as LoRA-style patches
- Route images by style match
- Scan image batches for best matches with auto-calibrated thresholds
- Build multi-stage cascade autoencoders
## Why use STANNO?
- **Interpretable**: You can see exactly what the trainer does to weights. No black-box backprop.
- **Flexible**: Three trainer types (Fixed, LocalRule, Evolutionary) fit different problems.
- **Learnable**: The trainer itself can adapt (meta-learning).
- **Cascadable**: Chain STANNOs into multi-stage pipelines with end-to-end gradient flow across stages.
- **Scannable**: Turn any trained STANNO into a semantic scanner over large datasets.
- **No autodiff**: Works with NumPy. No GPU required (but supports PyTorch if you have it).
- **ComfyUI ready**: Nine custom nodes for image generation workflows.
## Install
```bash
pip install git+https://github.com/nitroxido/stanno.git
```
## Quick examples
### Regression on sin(x)
```bash
python -m stanno train --config examples/sin_regression.json
python -m stanno predict --config examples/sin_regression.json --input 0.5
python -m stanno dream --config examples/sin_regression.json
```
### Autoencoder on images
```python
from stanno import STANNO
from stanno.config.schema import STANNOConfig
import numpy as np
# Reshape images to flat vectors (B, H*W*C)
x = images.reshape(images.shape[0], -1).astype('float32')
# Autoencoder: input and output have same size
config = STANNOConfig(layers=[x.shape[1], 256, x.shape[1]])
stanno = STANNO(config)
stanno.fit(x, x, epochs=100, batch_size=32)
# Get reconstruction
x_reconstructed = stanno.predict(x[:10])
```
### Online learning (continual)
```python
from stanno.integration.continual import ContinualSTANNO
cont = ContinualSTANNO(stanno)
for sample, label in data_stream:
loss = cont.observe(sample, label)
if cont.steps % 100 == 0:
test_loss = cont.test_loss(x_test, y_test)
print(f"Step {cont.steps}: train_loss={loss:.4f}, test_loss={test_loss:.4f}")
```
### Anomaly scoring
```python
from stanno.config.schema import FilterConfig
from stanno.integration.filter import STANNOFilter
# Train on normal embeddings
stanno.fit(normal_embeddings, normal_embeddings, epochs=50)
# Create filter
filt = STANNOFilter(stanno, FilterConfig(anomaly_threshold=0.7))
# Score new embedding
score, info = filt.score(new_embedding)
print(f"Anomaly score: {score:.3f} (0=normal, 1=anomaly)")
if info["blocked"]:
print("Blocked: input is too unusual")
```
## How it works
**The core idea:**
- **TraineeNet**: A neural network with weights you want to train.
- **TrainerNet**: Another network that looks at the TraineeNet's internal state (activations, errors, weights) and computes how to update those weights.
- **No backprop**: The update formula is explicit, not learned via autodiff.
- **Cascades**: Multiple TraineeNet+TrainerNet pairs can be chained so that gradient signals flow backward across stage boundaries, enabling end-to-end training of multi-stage pipelines.
- **Scanning**: Any trained STANNO can be used as a similarity function to scan and rank rows in large datasets by how closely they match the learned distribution.
**The three trainer types:**
| Type | Mechanism | Best for |
|------|-----------|----------|
| **Fixed** | 4-module design (patent 5852815A), cascade-aware | Baseline, reproducibility, understanding the concept |
| **LocalRule** | Shared MLP per synapse | Adaptive training, interpretability |
| **Evolutionary** | Evolve per-layer scales (ES) | Unconventional problems, when autodiff fails |
## Technical details
- **Backend agnostic**: Uses NumPy by default, but can swap in PyTorch.
- **Variable architecture**: Networks can be any depth (list of layer sizes).
- **Configurable feedback**: Dream mode can "repeat" outputs, use a learned "linear" projection, or "zero" them.
- **Pickle-serializable**: Save/load trained models easily.
## Benchmark
On sin(x) regression (512 samples, 100 epochs):
```
Fixed MSE=0.047
LocalRule MSE=0.021 (learnable rules = better fit)
Evolutionary MSE=0.053
```
## For ComfyUI users
The [comfyui-stanno](https://github.com/[your-username]/comfyui-stanno) custom node package provides nine nodes in the **STANNO** category:
| Node | What it does |
|------|--------------|
| **STANNOLoad** | Create or load a model (JSON config or .pkl file) |
| **STANNOTrainImages** | Train on image batches |
| **STANNOScoreImages** | Filter images by reconstruction error |
| **STANNODreamCond** | Modify CLIP embeddings with dream mode |
| **STANNODynamicLoRA** | Apply learned style as LoRA patches |
| **STANNOCompositeCheck** | Route images to whichever of two STANNOs matches best |
| **STANNOScan** | DSANNO scanner: auto-calibrated threshold + top-k image retrieval |
| **STANNOCascadeLoad** | Create or load a multi-stage CascadeSTANNO |
| **STANNOCascadeTrainImages** | Train a cascade end-to-end on an image batch |
Install via ComfyUI-Manager or manually.
## Patent & Attribution
**STANNO is an open-source implementation of US Patent 5,852,815** (*Artificial Neurogenesis Network*), filed by Stephen L. Thaler. The patent has expired (US utility patents: 20 years from filing). We fully acknowledge and credit all core architectural concepts to the original patent.
**This implementation adds:**
- Modern Python/NumPy/PyTorch backend
- CascadeSTANNO (multi-stage gradient cascade)
- DSANNO (data scanning and semantic search)
- Three trainer types (Fixed, LocalRule, Evolutionary)
- ComfyUI integration (9 custom nodes)
- CLI tools for common tasks
See **Citation** below for how to cite the original patent and this implementation.
## Citation
If you use STANNO in research, cite the original patent:
```bibtex
@patent{thaler1998artificial,
title={Artificial neurogenesis network},
author={Thaler, Stephen L},
year={1998},
number={5852815},
institution={United States Patent}
}
```
And mention this implementation:
```bibtex
@software{stanno2026,
title={STANNO: Self-Training Artificial Neural Network Object},
author={Raides J. Rodríguez},
year={2026},
url={https://github.com/nitroxido/stanno}
}
```
## Questions?
- **Bug report**: Open an issue on GitHub
- **Question**: Start a discussion
- **Feature request**: Describe what you want to build
## License
MIT
## Core Package
This integration requires the [stanno](https://huggingface.co/oldman-dev/stanno)
core package.
Install with:
```bash
pip install git+https://github.com/nitroxido/stanno.git
``` {data-source-line="259"}