VisualInference commited on
Commit
99d9a77
·
verified ·
1 Parent(s): adf9175

Card: compare --turbo with the full model only; plain-language rewrite

Browse files
.gitattributes CHANGED
@@ -38,3 +38,6 @@ assets/hero_pebbles.jpg filter=lfs diff=lfs merge=lfs -text
38
  assets/same_seed.jpg filter=lfs diff=lfs merge=lfs -text
39
  assets/lichen.jpg filter=lfs diff=lfs merge=lfs -text
40
  assets/schedule.png filter=lfs diff=lfs merge=lfs -text
 
 
 
 
38
  assets/same_seed.jpg filter=lfs diff=lfs merge=lfs -text
39
  assets/lichen.jpg filter=lfs diff=lfs merge=lfs -text
40
  assets/schedule.png filter=lfs diff=lfs merge=lfs -text
41
+ assets/hero.jpg filter=lfs diff=lfs merge=lfs -text
42
+ assets/pairs.jpg filter=lfs diff=lfs merge=lfs -text
43
+ assets/repetition_test.jpg filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -19,15 +19,15 @@ tags:
19
 
20
  # MOSS-Image-SFT Turbo for Apple Silicon (MLX)
21
 
22
- A few-step sampler for [OpenMOSS-Team/MOSS-Image-SFT](https://huggingface.co/OpenMOSS-Team/MOSS-Image-SFT) on Macs: **15 network passes instead of 100**. That is about **2 minutes** per ~1 MP image on an M4 Pro, instead of about 12½ (**6.2×**). It stays close to what the full 50-step model draws for the same seed, including its textures and lettering, and it does not "stamp" repeated texture the way DMD turbo adapters do.
23
 
24
- **Code:** [moss-image-mlx](https://github.com/felix-ab/moss-image-mlx) (`--turbo`) · **Write-up:** [how it was designed and measured](https://github.com/felix-ab/moss-image-turbo-research/blob/main/docs/technical-writeup.md) · **Base tiers:** [8bit](https://huggingface.co/VisualInference/MOSS-Image-SFT-MLX-8bit), [compact](https://huggingface.co/VisualInference/MOSS-Image-SFT-MLX-compact)
25
 
26
- ![Wet river pebbles, same seed: full model at 50 steps, the new turbo, and a DMD-adapter turbo, with 100% crops](assets/hero_pebbles.jpg)
27
 
28
- *A held-out prompt never used in training, seed 101, 8bit tier, 100% crops below. The turbo keeps the full model's pebbles. A DMD-adapter turbo (a community adapter plus 2 original-model steps) turns them into uniform glossy beads.*
29
 
30
- This repository holds only the trained student: a rank-64 LoRA on the SFT transformer (252 projections, fp32, 595 MB). The package downloads it automatically.
31
 
32
  ## Quickstart
33
 
@@ -36,60 +36,64 @@ pip install -U moss-image-mlx # 0.2.0 or newer
36
  moss-mlx "A highway LED sign at sunset that reads \"HELLO MLX\"" --turbo -o sign.png
37
  ```
38
 
39
- - **First run:** it downloads the 8-bit MOSS-Image tier, this student (pinned to a fixed revision) and the destripe adapter, then caches them.
40
- - **Sizes:** trained at ~1 MP in 9 aspect ratios, from 768×1360 through 1024×1024 to 1360×768. Set them with `--width` and `--height`.
41
- - **More images:** `--seeds 1,2,3` renders several seeds with one load; `--batch jobs.jsonl` renders many prompts.
42
- - **Ignored in turbo mode:** `--steps` and `--shift`. `--turbo-weights FILE` uses a local copy of the student.
43
- - **Requirements:** an Apple Silicon Mac. It was measured on the 8bit tier, the default on Macs with ≥ 24 GB.
44
 
45
- ## Results
 
 
 
 
46
 
47
- The comparison is against the destriped official sampler (50 steps, CFG 3, block-22 skip) on **32 held-out prompts**, each at its own aspect ratio, seed 101:
48
 
49
- | | **This turbo** | DMD-adapter turbo | Full model, 50 steps |
50
- |---|---|---|---|
51
- | Network passes | **15** | 10 | 100 |
52
- | Time per ~1 MP image (M4 Pro, 8bit) | **~119 s** | ~80 s | ~743 s |
53
- | Peak memory | 9.4 GB | 9.3 GB | 9.3 GB |
54
- | Stamped texture (DINOv2 repetition, excess over the full model; materials + nature, n = 8) | **−0.006** | +0.063 | 0 |
55
- | Fine detail (high-frequency energy vs the full model) | **−0.004** | −0.022 | 0 |
56
- | Mean \|luma difference\| from the full model's image | **0.090** | 0.124 | 0 |
57
- | Brightness difference | +0.011 | −0.049 | 0 |
58
- | English text, OCR character recall (n = 4) | 0.947 | 0.951 | 0.934 |
59
 
60
- The package's sampler reproduces the research images bit for bit. The metrics are defined in [how-the-numbers-work.md](https://github.com/felix-ab/moss-image-turbo-research/blob/main/docs/how-the-numbers-work.md).
 
 
 
 
 
 
 
 
61
 
62
- ![Four held-out prompts, full model at 50 steps beside the turbo with the same seed: a croissant, a novel cover, a fox in snow and a Chinese tea wrapper](assets/same_seed.jpg)
63
 
64
- ![Lichen on a stone wall, same seed: full model, turbo and a DMD-adapter turbo with 100% crops; the DMD turbo stamps identical rosettes](assets/lichen.jpg)
65
 
66
  ## How it works
67
 
68
- ![The official sampler's 100 passes vs the turbo's 15: 5 student passes, a 2-pass guided step at slot 2, and an 8-pass original-model finish](assets/schedule.png)
 
 
 
 
 
 
 
69
 
70
- 1. **Student, 6 steps, no CFG.** It covers the composition part of the original model's own 50-step trajectory (σ 1 → .671).
71
- - **Training:** regression onto that trajectory, with no distribution matching. Teacher data comes from about 2,000 prompts at ~1 MP in 9 aspect ratios (English and Chinese text, JSON layouts, people, products, places, materials).
72
- - **Targets:** on the student's own drifted states, the teacher is re-run from where the student actually is. In a controlled ablation, targets that snap back to the stored path ghosted a face and garbled Chinese characters; these targets did neither.
73
- 2. **One guided original-model step** replaces the student's third step (slot 2, σ .957 → .919). The step was tried in each of the 6 slots. Only there did it repair both a ghosted shop-sign headline and an infographic title (7 prompts, one seed; confirmed on the held-out set).
74
- 3. **The original model finishes** with 4 DPM-Solver++(2M) evaluations (σ .671 → 0). From an exact mid-trajectory state, this finish is 4.6× closer to the 50-step image than a distilled finish.
75
- 4. **Destripe throughout:** [nynxz's destripe LoRA](https://huggingface.co/nynxz/MOSS-Image) runs at 1.5. The teacher data was destriped too.
76
 
77
- Passes: 5 student + 2 guided + 8 finish = 15. The student was trained on rented A100s for about $37.
78
 
79
- **Why not distill the whole trajectory?** Exact cached 50-step states, finished by a DMD adapter, still stamp. The more distilled steps run in the middle of the trajectory, the more stamping appears. So the distilled network stays out of the band where texture is organized. The [technical write-up](https://github.com/felix-ab/moss-image-turbo-research/blob/main/docs/technical-writeup.md) has the evidence for each decision and what failed. The [research repo](https://github.com/felix-ab/moss-image-turbo-research) has the full lab notebook.
80
 
81
  ## Limitations
82
 
83
- - **Small, dense text** slips more often than with the full model (OCR 0.957 vs 0.970 on 8 prompts).
84
- - **Regular geometry** can come out more organic than it should: a chain-link fence shadow, rows of machines.
85
- - **Compositions** usually follow the full model for the same seed, but not always.
86
  - **Untested:** sizes outside ~1 MP and the 9 trained aspect ratios; the compact and bf16 tiers with `--turbo`; the Base checkpoint (the CLI refuses `--transformer` in turbo mode).
87
- - **Evidence size:** 1–2 seeds and 7–32 prompts per comparison, with visual checks by the author and the project owner. There is no FID or KID at scale.
88
 
89
  ## License and credits
90
 
91
  Apache-2.0.
92
  - **Base model:** MOSS-Image SFT, © OpenMOSS, Apache-2.0.
93
- - **Destripe adapter:** by nynxz, Apache-2.0.
94
- - **DMD adapter in the comparisons:** by lodestones; used only as a baseline, not shipped here.
95
  - **This work** is independent and not affiliated with OpenMOSS.
 
19
 
20
  # MOSS-Image-SFT Turbo for Apple Silicon (MLX)
21
 
22
+ A fast sampler for [OpenMOSS-Team/MOSS-Image-SFT](https://huggingface.co/OpenMOSS-Team/MOSS-Image-SFT) on Macs. It uses **15 network passes instead of 100**: about **2 minutes** per ~1 MP image on an M4 Pro instead of about 12½ (**6.2×**). It stays close to the image the full 50-step model draws for the same seed, including its textures and lettering.
23
 
24
+ **Code:** [moss-image-mlx](https://github.com/felix-ab/moss-image-mlx) (`--turbo`) · **Write-up:** [how I designed and measured it](https://github.com/felix-ab/moss-image-turbo-research/blob/main/docs/technical-writeup.md) · **Base tiers:** [8bit](https://huggingface.co/VisualInference/MOSS-Image-SFT-MLX-8bit), [compact](https://huggingface.co/VisualInference/MOSS-Image-SFT-MLX-compact)
25
 
26
+ ![Wet river pebbles at actual size: the full model at 50 steps above, --turbo below, same prompt and seed](assets/hero.jpg)
27
 
28
+ *Both crops show the same image region at actual size, from the same prompt and seed. The prompt was not in the training set.*
29
 
30
+ This repository holds only the trained LoRA: rank 64 on the SFT transformer (252 projections, fp32, 595 MB). The package downloads it for you.
31
 
32
  ## Quickstart
33
 
 
36
  moss-mlx "A highway LED sign at sunset that reads \"HELLO MLX\"" --turbo -o sign.png
37
  ```
38
 
39
+ - **First run:** the package downloads the 8-bit MOSS-Image tier, this LoRA (pinned to a fixed revision) and the stripe-removal LoRA, then caches them.
40
+ - **Sizes:** I trained it at ~1 MP in 9 aspect ratios, from 768×1360 through 1024×1024 to 1360×768. Set the size with `--width` and `--height`.
41
+ - **More images:** `--seeds 1,2,3` renders several seeds with one model load; `--batch jobs.jsonl` renders many prompts.
42
+ - **Ignored in turbo mode:** `--steps` and `--shift`. `--turbo-weights FILE` uses a local copy of the LoRA.
43
+ - **Hardware:** an Apple Silicon Mac. I measured everything on the 8bit tier, the default on Macs with ≥ 24 GB.
44
 
45
+ ## Speed
46
+
47
+ ![Time per image on an M4 Pro: 12 min 23 s for the full model, 1 min 59 s for --turbo](assets/speed.png)
48
+
49
+ Each network pass takes as long as before; `--turbo` simply needs 15 instead of 100. Peak memory is 9.4 GB (9.3 GB for the full model).
50
 
51
+ ## Results
52
 
53
+ I compared `--turbo` with the full model's own image (50 steps, CFG 3, with the stripe-removal LoRA) on **32 prompts that were not in the training set**, each at its own aspect ratio, seed 101:
 
 
 
 
 
 
 
 
 
54
 
55
+ | | `--turbo` | Full model, 50 steps |
56
+ |---|---|---|
57
+ | Network passes | **15** | 100 |
58
+ | Time per ~1 MP image (M4 Pro, 8bit) | **~119 s** | ~743 s |
59
+ | Average pixel difference from the full model's image (0–1 scale) | 0.090 | 0 |
60
+ | Repeated-texture score, relative to the full model (materials and nature prompts, n = 8) | −0.006 (no extra repetition) | 0 |
61
+ | Fine detail (high-frequency energy), relative to the full model | −0.004 | 0 |
62
+ | Brightness, relative to the full model | +0.011 | 0 |
63
+ | English text read back correctly by OCR (n = 4) | 94.7% | 93.4% |
64
 
65
+ The package's sampler reproduces the research images bit for bit. [how-the-numbers-work.md](https://github.com/felix-ab/moss-image-turbo-research/blob/main/docs/how-the-numbers-work.md) defines each measure.
66
 
67
+ ![Four pairs, full model left and --turbo right, same seed: a beekeeper, a novel cover, a Chinese tea wrapper and a croissant](assets/pairs.jpg)
68
 
69
  ## How it works
70
 
71
+ ![The official sampler's 100 passes vs the 15 of --turbo](assets/schedule.png)
72
+
73
+ 1. **A small LoRA sets the composition** in 5 steps without CFG. I trained it on the full model's own sampling paths for about 2,000 prompts (English and Chinese text, layouts, people, products, places, materials). When the LoRA drifted off a saved path during training, I reran the full model from where the LoRA was and trained on that result. Pulling it straight back to the saved path instead produced double exposures.
74
+ 2. **The full model takes one step with CFG** among those early steps (the third), where the shapes of large letters form. I tried that step at each of the 6 positions; only the third repaired both a garbled shop sign and an infographic title.
75
+ 3. **The full model draws the fine detail** in 4 DPM-Solver++(2M) steps, with no distilled steps.
76
+ 4. **Every pass applies [nynxz's stripe-removal LoRA](https://huggingface.co/nynxz/MOSS-Image)** at 1.5. I applied it to the training data too.
77
+
78
+ Training cost about $37 on rented A100s.
79
 
80
+ **Why not distill every step?** I took the full model's saved intermediate states and finished them with a DMD-distilled LoRA, a common way to build few-step models. The more DMD steps it took in the middle of sampling, the more it turned natural textures into repeating patterns:
 
 
 
 
 
81
 
82
+ ![Lichen on a stone wall: the full model, then the full model's saved states after 42, 35 and 14 steps finished with 2, 3 and 6 DMD steps](assets/repetition_test.jpg)
83
 
84
+ So this LoRA learns to follow the full model's own path for each seed, and the full model finishes the image. The [technical write-up](https://github.com/felix-ab/moss-image-turbo-research/blob/main/docs/technical-writeup.md) has the evidence for each decision and what failed; the [research repo](https://github.com/felix-ab/moss-image-turbo-research) has the full lab notebook.
85
 
86
  ## Limitations
87
 
88
+ - **Small, dense text** has a few more errors than with the full model (OCR 95.7% vs 97.0% on 8 prompts).
89
+ - **Regular patterns**, like a chain-link fence shadow or rows of machines, can come out irregular.
90
+ - **Compositions** usually match the full model for the same seed, but not always.
91
  - **Untested:** sizes outside ~1 MP and the 9 trained aspect ratios; the compact and bf16 tiers with `--turbo`; the Base checkpoint (the CLI refuses `--transformer` in turbo mode).
92
+ - **Evidence size:** each comparison uses 1–2 seeds and 7–32 prompts, and I checked the images by eye. I did not compute FID or KID at scale.
93
 
94
  ## License and credits
95
 
96
  Apache-2.0.
97
  - **Base model:** MOSS-Image SFT, © OpenMOSS, Apache-2.0.
98
+ - **Stripe-removal LoRA:** by nynxz, Apache-2.0.
 
99
  - **This work** is independent and not affiliated with OpenMOSS.
assets/{hero_pebbles.jpg → hero.jpg} RENAMED
File without changes
assets/{same_seed.jpg → pairs.jpg} RENAMED
File without changes
assets/{lichen.jpg → repetition_test.jpg} RENAMED
File without changes
assets/schedule.png CHANGED

Git LFS Details

  • SHA256: d14174623dcc86b42c44ed1c8822a97253300a97d3eac77a1f90f940e2cbf182
  • Pointer size: 131 Bytes
  • Size of remote file: 111 kB

Git LFS Details

  • SHA256: 5f166a5dffdde5017003a98db24c038bcfa9edc525886fe16aecbceee5505e30
  • Pointer size: 130 Bytes
  • Size of remote file: 94.9 kB
assets/speed.png ADDED