File size: 4,072 Bytes
fd0b9df
f4f474d
 
fd0b9df
 
 
9d3707b
fd0b9df
 
 
 
 
 
 
 
 
2989b7e
 
 
 
 
fd0b9df
 
f4f474d
fd0b9df
53940d1
fd0b9df
36cd8ec
 
 
53940d1
fd0b9df
53940d1
 
 
 
fd0b9df
36cd8ec
 
2989b7e
 
36cd8ec
 
 
 
53940d1
fd0b9df
53940d1
 
 
 
 
 
fd0b9df
53940d1
fd0b9df
6805506
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2989b7e
6805506
 
 
 
 
53940d1
 
 
 
 
 
 
 
 
2b1f846
 
53940d1
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
---
title: NumZoo
emoji: 🦁
colorFrom: purple
colorTo: pink
sdk: gradio
sdk_version: "6.17.3"
app_file: app.py
pinned: false
license: apache-2.0
tags:
  - flux
  - text-to-image
  - kids
  - education
  - math
  - Backyard AI
  - Best Use of Modal
  - Best Demo
  - Tiny Titan
  - Off Brand
---

# 🦁 NumZoo

A mental math app for kids β€” answer questions, earn cute AI-generated animal images as rewards!

> πŸ† **Built for the [πŸ€— Hugging Face "Small Models, Big Adventures" hackathon](https://huggingface.co/build-small-hackathon).**
> A small (4B) image model, fine-tuned with a custom LoRA, turned into a delightful kids' reward loop.

## How it works

1. Enter your name
2. Pick your favourite animals 🐾 and places 🌍 (used to personalise reward images)
3. Answer math questions β€” every **3 correct answers** earns a reward image
4. Level up: **Additions β†’ Subtractions β†’ Multiplications β†’ Mix**

### See it in action

▢️ **[Demo video (Loom)](https://www.loom.com/share/c565cba49f2c4ad1bfb428e38ff4b629)** Β· πŸ“£ **[Launch post](https://x.com/goooums/status/2066500943676399814)**

| 1 Β· Pick animals & places | 2 Β· Solve math | 3 Β· Earn cute reward |
|:---:|:---:|:---:|
| ![picker](docs/app_picker.jpg) | ![quiz](docs/app_quiz.jpg) | ![reward](docs/app_reward.jpg) |

## Levels

| Level | Operation | Goal |
|-------|-----------|------|
| 1 | βž• Additions | 5 correct |
| 2 | βž– Subtractions | 5 correct |
| 3 | βœ–οΈ Multiplications | 5 correct |
| 4 | 🎲 Mix | Endless |

## Image model

Rewards are generated with **FLUX.2-klein-4B** (4B params, Apache 2.0) via πŸ€— Diffusers,
plus a **custom NumZoo style LoRA** (below). Images start generating in the background as
soon as the quiz begins, so a reward is usually ready the moment it's earned.

## ✨ Custom AI art: the NumZoo LoRA

Out of the box, FLUX.2-klein renders the same prompt in wildly different styles β€” often
photorealistic β€” which doesn't fit a soft, cozy kids' app. So we fine-tuned a **style
LoRA** that pins every reward to the same kawaii children's-book look.

**Before β†’ after** (same prompt: *"a cute baby panda on a snowy mountain top"*):

| Base FLUX.2-klein-4B | + NumZoo LoRA |
|:---:|:---:|
| ![before](docs/panda_before.jpg) | ![after](docs/panda_after.jpg) |
| photorealistic, inconsistent | cozy, on-brand, every time |

More rewards from the LoRA:

| | | |
|:---:|:---:|:---:|
| ![bunny](docs/lora_bunny.jpg) | ![unicorn](docs/lora_unicorn.jpg) | ![fox](docs/lora_fox.jpg) |

### How we made it
1. **Dataset** β€” 54 cozy scenes generated with **Qwen-Image** (12 animals Γ— 10 places,
   incl. multi-animal/multi-place combos), captioned `NUMZOO. <content>` with the style
   left *undescribed* so the trigger word carries it. See
   [`scripts/generate_dataset.py`](scripts/generate_dataset.py) and
   [`training/`](training/) for the images + captions.
2. **Training** β€” LoRA (rank 32, 1500 steps) on `FLUX.2-klein-base-4B` via
   [ostris/ai-toolkit](https://github.com/ostris/ai-toolkit), running on a **[Modal](https://modal.com) A100** (~45 min, serverless GPU).
   Reproducible setup in [`training/lora_trainer/`](training/lora_trainer/).
3. **Inference** β€” the LoRA loads on the distilled 4-step klein in `image_generator.py`;
   the app simply prepends the `NUMZOO` trigger to every prompt.

**Published LoRA:** πŸ€— [goumsss/numzoo-flux2-klein-lora](https://huggingface.co/goumsss/numzoo-flux2-klein-lora)

## Run locally

> Requires Python on Apple Silicon (arm64). Recommended: [Miniforge](https://github.com/conda-forge/miniforge).

```bash
# 1. Install dependencies
~/miniforge3/bin/pip install -r requirements.txt

# 2. Accept FLUX.2-klein-4B license on HuggingFace
#    β†’ https://huggingface.co/black-forest-labs/FLUX.2-klein-4B
#    Then log in:
hf auth login

# 3. Run
~/miniforge3/bin/python3 app.py
# Opens at http://localhost:7860
# First run downloads ~23GB of model weights (cached after that)
```

> On standard Python/pip (non-Apple Silicon):
> ```bash
> pip install -r requirements.txt
> python app.py
> ```