How NNGen turns a text description into a working neural network.
Text-to-image diffusion models learn the mapping caption → pixels from millions of (image, caption) pairs. NNGen applies the same machinery one level up: it learns the mapping caption → neural network weights.
The “image” being denoised is the weight canvas: the parameter set of a fixed-size controller MLP,
8 inputs → 32 tanh → 32 tanh → 8 outputs (~1,608 parameters)
laid out as a 6×32×32 tensor (weight matrices as channels, biases in the first column, zeros padded, a validity mask marking real entries). A static mask is fed to the UNet as extra input channels; the training loss and the final decode are masked to valid entries. Weights are z-normalized per tensor with corpus statistics and clamped to ±4σ so the diffusion process operates in roughly [-1, 1] — the same regime as image pixels.
There is no public dataset of (network, description) pairs, so NNGen manufactures its own:
For the drawing demo, the corpus contains eight shapes — circle, square, triangle, pentagon, star, spiral, line, arc — while hexagon and octagon are deliberately excluded from training. They exist only as evaluation targets: if the generator produces working hexagon-drawers, it has generalized the concept of “regular polygon” in weight space.
NNGen uses the same techniques introduced for image generation, with one conceptual substitution: the data distribution being learned is not natural images but the weight space of competent controllers. Diffusion models only ever manipulate matrices of numbers — and a weight matrix is exactly that. No new generative machinery had to be invented; what changed is what the matrix means and how the corpus that teaches its meaning is produced.
| Component | Choice | Why |
|---|---|---|
| Noise process | cosine schedule, T=1000 forward steps | gradual corruption of the weight canvas |
| Denoiser | UNet (2.3M params, mvp preset), self-attention + text cross-attention | same backbone family as image diffusion, at CPU scale |
| Parameterization | v-prediction | stable targets across all noise levels |
| Text conditioning | frozen MiniLM token embeddings → cross-attention; FiLM timestep embedding | the text-to-image recipe, unchanged |
| Guidance | classifier-free (10% caption dropout), guidance 3–5 at sampling | how strongly to follow the prompt |
| Sampling | DDIM, 20–50 deterministic steps | starts from pure Gaussian noise on the canvas |
Training loss is the masked v-prediction MSE; an EMA of the weights is kept
for sampling. At generation time the UNet receives pure noise on the 6×32×32
canvas plus the prompt embedding, and removes noise step by step until a
coherent set of network parameters emerges — then the canvas is decoded
back into a standard nn.Linear MLP and executed.
pip install -r requirements.txt
# 1. mass-train controller networks for the drawing corpus
python -m dnn.corpus.train_controllers \
--tasks draw_circle,draw_square,draw_triangle,draw_pentagon,draw_star,draw_spiral,draw_line,draw_arc \
--per-task 300 --out data/corpus_draw
# 2. cache text embeddings
python -m dnn.corpus.embed_captions --corpus data/corpus_draw
# 3. train the generator
python -m dnn.train_diffusion --config mvp --corpus data/corpus_draw --run runs/draw_mvp
# 4. generate a network from a prompt (CLI)
python -m dnn.generate --prompt "..." --task draw_hexagon --ckpt runs/draw_mvp/ckpt.pt --out runs/demo
# 5. this website
python webapp/server.py --port 17656
All URLs are relative, so the site can be mounted behind a reverse proxy
at any sub-path (e.g. nngen.agrillo.it).
| Method | Path | Description |
|---|---|---|
| POST | api/generate | body {"prompt", "task", "guidance", "steps", "seed"} → {"job": id}. Generation runs in a background worker (one job at a time). |
| GET | api/job/<id> | {"status": pending|running|done|error, "result": ...} |
| GET | api/tasks | available rollout tasks |
| GET | api/status | model/checkpoint availability |
| GET | artifacts/<job>/behavior.gif | rollout of the generated network; also weights.png, report.json |
dnn/ controller.py canonical MLP, weight canvas, normalization text_encoder.py frozen MiniLM wrapper tasks/ mini-environments + draw shapes, registry corpus/ caption templates, batch trainer, storage, embeddings diffusion/ schedule, UNet, DDIM sampler + CFG, EMA train_diffusion.py training loop (EMA, checkpoints, resume) generate.py prompt → network → rollout → artifacts eval.py generated vs teacher vs random benchmark webapp/ server.py this website (stdlib HTTP server, port 17656) pages/, static/ pages and assets tests/ canvas round-trip, tasks, diffusion, e2e pipeline