T.I.T.S. β€” Terrible Imagegen TranSformer

A 16M-parameter text-to-image diffusion model that draws excellent buses, passable pizza, and no birds whatsoever. Trained from scratch in 7.5 hours on one RTX 4060 Ti, for roughly the electricity cost of a load of laundry.

It is bad on purpose, honestly. The math is textbook DDPM, nothing was sabotaged, and no corners were cut except the one that matters: it has 16 million parameters, which in 2026 is a rounding error. Stable Diffusion has 860M. Flux has 12B. T.I.T.S. has slightly fewer parameters than the number of pixels in the images it is trying to make.

Also, despite the name, it is not a transformer. It's a UNet with a single attention layer bolted to the bottom. The acronym came first. The architecture was never consulted and has no comment.

samples

Final samples. Rows: "a motorcycle parked on the street", "a dog on a couch", "a plate of pizza", "a red bus on a city street". Four samples each, guidance 3.0. Note that row 4 is doing great and row 2 is a war crime.

What it can and cannot do

Prompt Result Grade
Buses, streets, vehicles Windows. Wheels. A red front end. An actual bus. A-
Pizza, plates of food Melted cheese, red toppings, crust. You would eat it. B
Motorcycles Two wheels, handlebars, roughly the correct number of each C+
Dogs, cats, people Fleshy blobs arranged on furniture F
Birds Immaculate foliage. Zero birds. F
Dragons, castles, anime Abstract expressionism (unintentional) N/A

The pattern is boxes yes, animals no. A bus is a rectangle with windows in it. A dog is a deformable mammal photographed from four hundred angles in four hundred lighting conditions. Sixteen million parameters can afford exactly one of those.

bird

"a blue tit on a branch" at guidance 6. It rendered the branch, the leaves, the dappled light, and the general feeling of being in a garden. Then it clocked off for the day.

Specs

Parameters 16.10M (image model) + frozen CLIP text encoder
Architecture TinyUNet β€” base_ch=64, mults (1,1,2,4), 2 res blocks/stage, one lonely self-attention layer at 16Γ—16
Resolution 128Γ—128, pixel space (no VAE, no latents, no shortcuts)
Text conditioning Frozen CLIP ViT-B/32 pooled embedding β†’ FiLM in every ResBlock
Diffusion Linear-beta DDPM, 1000 steps, Ξ΅-prediction, ancestral sampling with xβ‚€ clipping
Guidance Classifier-free, 10% caption dropout during training. Default scale 3.0
Training data COCO Captions β€” 113,287 images, 566,747 captions, all of it from 2014
Training 3 epochs / 53,130 steps / batch 32 / AdamW @ 2e-4 / bf16 / EMA 0.9995
Hardware 1Γ— RTX 4060 Ti (8GB), 7.5 hours, ~117W, shared with a browser
Final loss 0.0209
Inference ~13s per image, which is 13s longer than you'll want to wait

Usage

pip install -r requirements.txt
python sample.py --checkpoint tits_epoch3.pt --prompt "a red bus on a city street" \
    --num_images 4 --guidance 3.0 --upscale 2 --out bus.png

Ask it for a bus. It's really good at buses. Let it have this.

--guidance is the classifier-free guidance scale: 1 = off, 3 = good, 6 = saturated, 10 = radioactive. Raising it does not summon a bird. This was tested thoroughly and at some personal cost.

The checkpoint ships ema_state_dict (used by default, much cleaner) and model_state_dict. Optimizer state was stripped, so this is for inference, not for resuming. You do not want to resume this.

Training your own

python prepare_data.py --out_dir data --image_size 128   # streams COCO, saves at 128px
./run_training.sh                                        # 3 epochs, ~7.5h on a 4060 Ti

prepare_data.py streams from HF and only ever writes the downscaled images, so the 19GB source never touches your disk. Resumable, because it will be interrupted. run_training.sh --resume checkpoints/latest.pt picks up from the last save (every 2000 steps).

Things learned the hard way

  • Web-scraped alt-text data comes with watermarks. Attempt one used CC3M. Roughly 1 in 10 images had an Alamy or Shutterstock watermark visible even at 64Γ—64, and the model was well on its way to concluding that a professional photograph has a grey bar across the middle. Switched to COCO. COCO is clean, if permanently stuck in 2014.
  • Vanilla DDPM ancestral sampling drifts. Without clipping predicted xβ‚€ each step, a small model's errors compound over 1000 steps until every image is the same shade of burnt orange. One .clamp(-1, 1) fixes it. Attempt one looked like a house fire.
  • Classifier-free guidance is not optional. Without caption dropout the prompt gently suggests rather than instructs, and every output converges on the platonic average COCO photograph, which is a beige room with something in it.
  • EMA goes through a blue phase. Early in training the averaged weights still contain a few percent of the random initialization, and everything comes out smurf-colored. It passes.
  • Raising the resolution made it dangerously competent. The README originally warned that bumping past 64Γ—64 would quietly turn this into a real model. At 128Γ—128 it started producing buses you could identify. Consider this a cautionary tale.

evolution

Step 2,000 of 53,130, back when it only made weather.

Limitations and intended use

For entertainment, education, and finding out exactly where 16M parameters runs out of road. Not for production. Inherits every bias in COCO, and its worldview ends in 2014 β€” it has never seen a modern phone, an e-scooter, or a Tesla, and it is happier that way.

Citation

Please don't.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Dataset used to train M1n1A1/MiniAI-terrible-imagegen-transformer