Model reference · open weights
FlyGPT is an open-weight language model from QuixiAI. FlyGPT (INT4) weighs 7 MB; the smallest configuration that runs it is RTX 3060 12 GB.
For self-hosting, compare this build's requirements below with the GPU you plan to rent.
Summary of the QuixiAI/FlyGPT model card, 2026-10-01
What it is
| Released by | QuixiAI |
|---|---|
| Released | 2026-09-14 |
| Parameters | 2M |
| VRAM | 7 MB for the weights |
What it runs on
How much memory each request adds isn't estimated yet for this architecture. The weights need at least the cards below, plus room for the context.
| Card | Weights alone |
|---|---|
| RTX 3060 12 GB | fits |
| RTX 4060 Ti 16 GB | fits |
| RTX 3090 24 GB | fits |
| RTX 4090 24 GB | fits |
| RTX 5090 32 GB | fits |
| L40S 48 GB | fits |
| A100 80 GB | fits |
| H100 80 GB | fits |
| RTX PRO 6000 Blackwell 96 GB | fits |
| DGX Spark (GB10) 128 GB unified | fits |
| H200 141 GB | fits |
| B200 180 GB | fits |
From the model card
A character-level language model whose recurrent architecture is a real subgraph of the fruit-fly brain connectome (MaleCNS v1.0). Unlike the earlier frozen-reservoir approach in ngxson/fly-llm-hf, which keeps the connectome's synaptic weights fixed and trains only the projections and readout, FlyGPT trains one value per real synaptic connection with gradient descent while keeping the fly's edge topology fixed, and compares the result against the same neurons with degree-preserving scrambled connections across paired seeds.
Base model: QuixiAI/MaleCNS, the lossless packaging of the MaleCNS v1.0
connectivity tables. FlyGPT's graph is extracted from it deterministically (build_graph.py, revision pinned in
data/fly/build_edges.py); graph.node_id and graph.synapse_count map every edge back to that repository.
This checkpoint's wiring is the original MaleCNS wiring.
Trained. Condition real, seed 1, step 94000, validation loss 1.5778 nats/char on the fixed Tiny Shakespeare split.
This is not a biological simulation of a living fly. The "weights" in the MaleCNS release are anatomical synapse
counts; they are stored here as graph.synapse_count and are not the model's parameters.
Every number below is produced by FlyGPT's extraction script (build_graph.py), not typed by hand.
| Source | MaleCNS v1.0 flat connectome (gs://flyem-male-cns/v1.0/connectome-data/flat-connectome/) |
| Candidate pool | central brain: superclass starting with cb_ (37,108 neurons) |
| Minimum synapses per connection | 3 (engineering choice, not a biological claim) |
| Extraction | largest SCC → largest directed (k,k)-core with ≥ target nodes (k = 40) → trim by weighted degree |
| Neurons used | 5,000 |
| Directed connections used | 524,324 |
| Synaptic contacts represented | 8,300,915 |
| Largest SCC fraction | 1.0 |
| Reciprocal pairs | 93,055 |
| Input / output neurons | top 256 by out-degree / top 512 by in-degree |
| Input→output shortest path (median / p90 / max hops) | 1.0 / 1.0 / 1.0 |
| Graph hash | f82b783b7ccb5a354fc4cf3de6de4a98d75029303c55f8faae28ab807828a007 |
graph.node_id holds the MaleCNS body ids, so every neuron maps back to the release.
model.safetensors| tensor | shape | dtype | size |
|---|---|---|---|
graph.edge_index | (2, 524324) | int32 | 4.19 MB |
graph.synapse_count | (524324,) | int32 | 2.10 MB |
graph.node_id | (5000,) | int64 | 0.04 MB |
graph.input_nodes | (256,) | int64 | 0.00 MB |
graph.output_nodes | (512,) | int64 | 0.00 MB |
recurrent.edge_values | (524324,) | bfloat16 | 1.05 MB |
recurrent.bias | (5000,) | bfloat16 | 0.01 MB |
recurrent.raw_leak | (5000,) | bfloat16 | 0.01 MB |
embed.weight | (65, 32) | bfloat16 | 0.00 MB |
input_proj.weight | (256, 32) | bfloat16 | 0.02 MB |
input_proj.bias | (256,) | bfloat16 | 0.00 MB |
lm_head.weight | (65, 512) | bfloat16 | 0.07 MB |
lm_head.bias | (65,) | bfloat16 | 0.00 MB |
graph.* is the anatomy (integer, never trained). recurrent.*, embed.*, input_proj.*, lm_head.* are the
learned state, stored in bf16. The sparse recurrent matmul is rebuilt in fp32 at runtime (rows = destination,
columns = source), with each incoming edge scaled by 1/sqrt(in_degree).
character → embedding (32) → linear → 256 input neurons
proposal_i = tanh( Σ_j W_ij h_j / sqrt(in_degree_i) + external_input_i + bias_i )
h_i ← (1 − leak_i) h_i + leak_i · proposal_i (2 microsteps per character, leak_i = sigmoid(raw_leak_i))
512 output neuron states → linear → 65 logits
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
tok = AutoTokenizer.from_pretrained("QuixiAI/FlyGPT")
model = AutoModelForCausalLM.from_pretrained("QuixiAI/FlyGPT", trust_remote_code=True, dtype=torch.float32)
ids = tok("ROMEO:", return_tensors="pt").input_ids
out = model.generate(ids, max_new_tokens=300, do_sample=True, temperature=0.8)
print(tok.decode(out[0]))
# The degree-preserving scrambled control (same neurons, same degrees, shuffled wiring), for comparison:
scrambled = AutoModelForCausalLM.from_pretrained("QuixiAI/FlyGPT", subfolder="scrambled", trust_remote_code=True, dtype=torch.float32)
print(tok.decode(scrambled.generate(ids, max_new_tokens=300, do_sample=True, temperature=0.8)[0]))
# Neuron activity, for visualization: [1, T, 5000] states after each character, plus MaleCNS body ids
with torch.no_grad():
states = model(ids).state # [B, N] after the last character
body_ids = model.graph.node_id # index -> MaleCNS body id, for lookup in QuixiAI/MaleCNS
The tokenizer is strict: only the 65 characters of Tiny Shakespeare are encodable. generate() carries the neuron
state between characters instead of a KV cache.
The recurrent core has one trainable weight per real synaptic connection. With the
connectome-kernels package installed, the model's forward pass
runs on fused CUDA kernels (about 13× faster than torch.sparse, identical gradients); without it, it falls back
to torch.sparse automatically.
# Fine-tune / continue training FlyGPT on Tiny Shakespeare (character-level).
# pip install transformers safetensors
# pip install --no-build-isolation git+https://github.com/QuixiAI/connectome-kernels # fused CUDA path, ~13x faster
import requests, torch, torch.nn.functional as F
from transformers import AutoModelForCausalLM, AutoTokenizer
tok = AutoTokenizer.from_pretrained("QuixiAI/FlyGPT")
model = AutoModelForCausalLM.from_pretrained("QuixiAI/FlyGPT", trust_remote_code=True, dtype=torch.float32).cuda()
# start from the untrained initialization instead: subfolder="init"
text = requests.geQuoted from the model card on Hugging Face. The full card is behind the Hugging Face link above.