File size: 2,580 Bytes
6805506
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
# NumZoo LoRA — training setup (reproducible)

These are the exact files used to train the **NumZoo style LoRA** for FLUX.2-klein-4B
on [Modal](https://modal.com) using [ostris/ai-toolkit](https://github.com/ostris/ai-toolkit).

- **Published LoRA:** https://huggingface.co/goumsss/numzoo-flux2-klein-lora
- **Base model:** `black-forest-labs/FLUX.2-klein-base-4B` (train on base, infer on distilled)
- **Trainer:** ai-toolkit · **Compute:** Modal A100 · ~45 min · LoRA rank 32, 1500 steps

## Files
| File | Role |
|------|------|
| `run_modal.py` | Modal app (image, GPU, volume, secret) — **rewritten for Modal ≥ 1.0** |
| `numzoo_klein.yaml` | ai-toolkit training config (`arch: flux2_klein_4b`, trigger, sample prompts) |

## The dataset
The 54 training images + captions live one level up in [`../`](../) (`image_001.jpg` +
`image_001.txt`, …). They were generated with **Qwen-Image** (see
[`../../scripts/generate_dataset.py`](../../scripts/generate_dataset.py)) and captioned
`NUMZOO. <content>` — content only, no style words, so the trigger learns the style.

## How to reproduce
```bash
# 1. Clone ai-toolkit and drop these in
git clone https://github.com/ostris/ai-toolkit
cp run_modal.py        ai-toolkit/run_modal.py
cp numzoo_klein.yaml   ai-toolkit/config/numzoo_klein.yaml
cp -r <dataset>        ai-toolkit/numzoo-dataset      # the 54 image+txt pairs

# 2. Modal: install, auth, and store your HF token (needs the base-model license accepted)
pip install modal && modal token new
modal secret create huggingface HF_TOKEN=hf_xxx

# 3. Train (from inside ai-toolkit/) — checkpoints + samples land on the volume
cd ai-toolkit
modal run run_modal.py --config-file-list-str=/root/ai-toolkit/config/numzoo_klein.yaml

# 4. Download results, pick the best checkpoint (we used step 1250)
modal volume get flux-lora-models numzoo_klein_lora ./lora_output
```

## Gotchas we hit (so you don't)
- **Modal ≥ 1.0 removed `modal.Mount`**`run_modal.py` here uses `Image.add_local_dir`
  + `add_local_file` instead, and moves heavy imports inside the container function.
- **pip `resolution-too-deep`** with unpinned deps — we install from ai-toolkit's own
  pinned `requirements.txt` (which also pins the diffusers commit that supports FLUX.2),
  plus `torch==2.7.1`/`torchvision`/`torchaudio` first.
- **Gated base model** — accept the license for `FLUX.2-klein-base-4B` on HF first.
- **Trigger rendered as text** at inference — append `no text` to the prompt; the
  distilled 4-step klein otherwise draws the `NUMZOO` trigger as a literal sign.