Model or dataset
unconv-ai/Un-0 avatar
unconv-ai/Un-0

Un-0 generates an image by integrating coupled oscillators instead of denoising noise

Un-0: an image generator powered by a simulated system of coupled oscillators, an example of an emerging physical computing substrate.

338 stars49 forksPythonMIT

At a glance

What is it?
A PyTorch reference implementation of an image generator built on Kuramoto dynamics, with no diffusion schedule, no adversary and no iterative denoising. Six pretrained checkpoints cover CIFAR-10 and ImageNet-64, the two FID columns are scored by different evaluators and are not comparable, and ImageNet training ships a data path rather than the data.
Who is it for?
Adopt Un-0 if you want to read or extend a generator whose forward pass is an ODE solve over oscillator phases rather than a diffusion chain, and if you are willing to train on hardware in the NVIDIA A100, H200 or B200 class that the recipe was verified on.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 61 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 4, 2026, and from our analysis. They are not legal advice.

Editorial analysis

An image is a trajectory, not a denoising chain

The forward pass is an integration. Un-0 builds on Kuramoto dynamics and produces an image by integrating the phase dynamics of a population of coupled oscillators. The README is explicit about what is absent from that description: no diffusion schedule, no adversary, and no iterative denoising. That is the whole architectural claim, and it is worth sitting with before looking at any number in the results table.

The project comes from Unconventional AI, which describes itself as researching dynamical systems as a computing substrate. The stated motivation is that these systems map onto analog and physical hardware, pointing toward energy for AI on the order of 1000x lower than on today's digital accelerators. That figure is framed as a direction of travel, not as a measurement taken by this repository, and the code here is a plain PyTorch reference implementation running on GPUs.

The dependency list explains the mechanics. torchdiffeq sits alongside torch in pyproject.toml, which is the ODE solver package. Integrating phase dynamics over time is an ordinary differential equation solve, and the model class that Hugging Face rebuilds from a checkpoint is named ConditionalImplicitKuramotoGenerator, with implicit in the name.

Six checkpoints, and the number in the name is the oscillator count

Sampling from a released checkpoint takes four lines, and the architecture is reconstructed from the checkpoint's own config so the right model is built without you naming a class.

python
import torch
from un0 import ConditionalImplicitKuramotoGenerator
from torchvision.utils import save_image  # already a dependency

model = ConditionalImplicitKuramotoGenerator.from_pretrained("cifar10/n4096")

class_ids = torch.tensor([0, 1, 2, 3, 4])      # one image per listed class
images = model.sample_images(class_ids)         # (5, 3, 32, 32) in [0, 1]
save_image(images, "samples.png", nrow=5)        # writes a viewable PNG

Checkpoint names follow a {task}/n{oscillators} pattern, and cifar10/n2048 means a model trained from cifar10 with 2048 oscillators in the Kuramoto model. Six are released: cifar10/n1024, cifar10/n2048, cifar10/n4096, imagenet64/n6656, imagenet64/n10240 and imagenet64/n16384.

Device selection defaults to auto and prefers CUDA, then Apple Silicon MPS, then CPU, so the same call works on a workstation and on a cluster node without a flag. That fallback chain matters because the resolved checkpoint still has to fit in memory, and the ImageNet-64 checkpoints are two orders of magnitude larger in parameter count than the CIFAR-10 ones.

--pretrained and --checkpoint refuse to be used together

The CLI exists to lay samples out as a grid rather than to return a tensor, so inference.py collects the output into one PNG with one row per class.

bash
# All 10 CIFAR-10 classes, 10 images each → one 10×10 grid PNG:
uv run python un0/inference.py \
    --checkpoint checkpoints/cifar10/final.pt \
    --output samples/cifar10.png

# A subset of classes, from released weights → one 3×8 grid PNG:
uv run python un0/inference.py \
    --pretrained imagenet64/n16384 \
    --classes 0 1 207 \
    --samples-per-class 8 \
    --output samples/imagenet64.png

Those two invocations are the whole interface, and the constraint between them is stated plainly: --pretrained and --checkpoint are mutually exclusive, and the same CLI serves both tasks. One takes a released name from the Hugging Face Hub, the other takes a local path such as checkpoints/cifar10/final.pt, and passing both is a mistake rather than a precedence rule.

The --classes flag takes class indices rather than names, which is why the second example can mix 0, 1 and 207 against an ImageNet-64 checkpoint and get a three-row grid. Nothing in the CLI validates that those indices mean what you think, since class-to-label mapping lives in the dataset rather than in the tool.

The two FID columns are scored by different evaluators

The results tables report FID for the released checkpoints by oscillator count, and they sit side by side in a way that invites a comparison the documentation explicitly forbids. CIFAR-10 is scored with clean-fid and ImageNet-64 with the OpenAI ADM evaluator, which is called the field-standard ImageNet-64 number. Because those are different benchmarks measured by different code, the two columns are not directly comparable.

Within each column, more oscillators buy a better score at a much higher parameter count. On CIFAR-10: cifar10/n4096 has 19.4M parameters and a clean-FID of 8.86, cifar10/n2048 has 4.9M and 9.38, and cifar10/n1024 has 1.3M and 11.16. On ImageNet-64: imagenet64/n16384 has 322M parameters and an ADM FID of 6.74, imagenet64/n10240 has 130M and 8.04, and imagenet64/n6656 has 57M and 8.36.

That trend is the one thing the two columns do agree on, and it is also the reason the small checkpoints exist: cifar10/n1024 is a 1.3M parameter model that anyone with a laptop GPU can sample from. Both training pipelines are trained separately, so a CIFAR-10 number says nothing about the ImageNet-64 numbers and vice versa.

ImageNet-64 ships a data path, not your data

CIFAR-10 training is self-contained. The first run downloads uoft-cs/cifar10, roughly 170 MB, into the HuggingFace cache with no account or token required, and later runs are instant.

ImageNet-64 is the opposite, and the README marks the difference with a blockquote rather than a footnote. Training does not download anything for you. What the repository provides is the reference 64x64 preprocessing transform and a reference filesystem-backed dataloader, and you supply the source ImageNet images and adapt the loader to your own storage. The stated goal is enough to reproduce the data path, not a turnkey download.

The preprocessing is where the FID comparability is won or lost. preprocess_imagenet in scripts/imagenet_preprocessing.py does a box-then-bicubic resize with a center crop, chosen to match OpenAI's VIRTUAL_imagenet64_labeled.npz and the ADM pipeline so the resulting FID can be set beside ADM, EDM and DiT numbers. Get that transform subtly wrong and your 6.74 becomes a different measurement of a different dataset.

The entry point also differs: un0/train_imagenet.py rather than un0/train_cifar10.py, with the 1000-class model built by build_imagenet64_model.

The cu128 index has no macOS wheels, so uv resolves per platform

The dependency pinning is where the difference between the cluster and the laptop shows up. pyproject.toml declares an explicit uv index named pytorch-cu128 pointing at the PyTorch CUDA 12.8 wheel index, and then routes torch and torchvision to it under a marker that excludes macOS.

The reasoning is given in a comment: the cu128 index ships Linux and Windows wheels only, so on the GPU clusters the CUDA build is pulled, while on macOS the resolution falls back to default PyPI wheels, which include MPS support. There is no separate lockfile per platform and no instruction to edit anything by hand, which is the part that makes it worth reading rather than skipping.

The declared ranges are worth noting too. requires-python is >=3.11,<3.14, so 3.14 is excluded rather than merely untested, and torch is pinned at >=2.11.0 with torchvision at >=0.26.0. The base runtime dependencies are datasets, huggingface_hub, numpy, Pillow, torchdiffeq, torchvision and tqdm, with pytest and ruff in the dev group and clean-fid in the eval group. Setup itself is one command.

bash
uv sync --group dev

The logging group is separate and optional, and without it no Weights and Biases calls are made at all.

Precomputed DINO features apply to batch reals only, and only with queue mode off

There is one performance escape hatch in the CIFAR-10 recipe, and its conditions are narrow enough to be worth stating exactly. To skip live DINO feature extraction on batch reals while leaving generator-side DINO live, you precompute a view bank once and then train with --queue-size 0 and --precomputed-dino-features.

bash
# One-time: CUDA required; writes data/cifar10_train_dino_views.pt (~1.7 GiB bf16)
uv run python scripts/precompute_dino_features.py \
    --output data/cifar10_train_dino_views.pt

uv run python un0/train_cifar10.py \
    --checkpoint-dir checkpoints/cifar10 \
    --queue-size 0 \
    --precomputed-dino-features data/cifar10_train_dino_views.pt

The index correspondence has to hold exactly: row i in the bank matches HuggingFace train index i. And queue mode is incompatible with this path, so the flag combination is fixed rather than tunable.

The other memory knob is --dino-batch-size, which sets the microbatch used inside DINO feature extraction without changing the optimizer batch or the feature definition. Its default is 64 for CIFAR-10 and 256 for ImageNet-64, and a memory-rich GPU can push it to 1024 to cut feature-extraction overhead. Multi-GPU runs use torchrun with eight processes and match a reference effective batch of 8192, and every hyperparameter in the recipe is a CLI flag rather than a config file, which is discoverable with --help.

Version 0.1.0 with no releases at all

The package metadata is minimal and honest about its own maturity. Version 0.1.0, licence MIT, author Unconventional, Inc., description Kuramoto-based image generation, and a setuptools build with a single package directory. Training is stated as verified on NVIDIA B200, H200 and A100 GPUs, which is the actual hardware floor for reproducing the reference numbers.

There are no GitHub releases to track, so pinning means pinning a commit rather than a version tag, and the last push landed on 2026-08-12. The repository is not archived.

The top-level listing gives a sense of what a research repository leaves on the table: scripts/, tests/, an ablation_study directory, a ruff-base.toml that the project config extends, a CLAUDE.md, and assets. The presence of an ablation directory alongside a plain reference implementation suggests the interesting experiments are reproducible from here, and the per-file ruff ignores are unusually long, which is a sign of a codebase that has been shaped to satisfy a linter rather than written to satisfy one.

For a research artefact rather than a dependency, none of that is a criticism. It does mean you should read the training code before assuming a configuration transfer to your own setup.

Editorial conclusion

Adopt Un-0 if you want to read or extend a generator whose forward pass is an ODE solve over oscillator phases rather than a diffusion chain, and if you are willing to train on hardware in the NVIDIA A100, H200 or B200 class that the recipe was verified on. Do not adopt it expecting turnkey ImageNet-64 reproduction, since the repository ships the preprocessing transform and a reference dataloader and expects you to supply the source images, and do not read the two FID columns as one leaderboard, because clean-FID and the ADM evaluator score different benchmarks. Before committing, check three things: that your Python sits between 3.11 and 3.14, that the package version 0.1.0 and the absence of any GitHub release mean you track commits rather than tags, and whether the roughly 1000x energy claim about analog hardware is one you intend to treat as a research direction rather than a measured result, since the repository states it as a pointer and not as a benchmark.

Frequently asked questions

What does Unconventional AI do?

It researches dynamical systems as a computing substrate, mapping them onto analog and physical hardware. The stated motivation is energy for AI on the order of 1000x lower than on today's digital accelerators, which the company presents as a direction rather than a measured result.

How does Un-0 generate an image without a diffusion model?

It integrates the phase dynamics of a population of coupled oscillators following Kuramoto dynamics. The README states there is no diffusion schedule, no adversary and no iterative denoising, and the generator class is ConditionalImplicitKuramotoGenerator with torchdiffeq as the ODE solver dependency.

Which checkpoints does Un-0 release and what do the names mean?

Six, named {task}/n{oscillators}: cifar10/n1024, cifar10/n2048, cifar10/n4096, imagenet64/n6656, imagenet64/n10240 and imagenet64/n16384. cifar10/n2048 is a model trained from cifar10 with 2048 oscillators in the Kuramoto model.

Can I reproduce the Un-0 ImageNet-64 training without downloading ImageNet?

No. Unlike CIFAR-10, ImageNet-64 training does not download anything for you. The repository provides the reference 64x64 preprocessing transform and a reference filesystem-backed dataloader, and you supply the source images and adapt the loader to your own storage.

Are the Un-0 CIFAR-10 and ImageNet-64 FID numbers comparable?

No. CIFAR-10 is scored with clean-fid and ImageNet-64 with the OpenAI ADM evaluator, and the README states the two columns are not directly comparable. More oscillators improve FID within each column, at much higher parameter counts.

Official sources

  1. Issues
  2. License: MIT
  3. Project website
  4. README
  5. unconv-ai/Un-0 on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/unconv-ai-un-0.svg)](https://hysenlabs.com/projects/unconv-ai-un-0)