kaupane commited on
Commit
e77e9b0
·
verified ·
1 Parent(s): 29e780a

Center the model card on the training recipe and generation gallery

Browse files
Files changed (1) hide show
  1. README.md +181 -44
README.md CHANGED
@@ -15,19 +15,20 @@ tags:
15
  <p align="center"><strong>Paint with words, in English and Chinese.</strong></p>
16
 
17
  <p align="center">
 
 
18
  <a href="https://huggingface.co/spaces/kaupane/Inko">Try the demo</a> ·
19
- <a href="https://huggingface.co/kaupane/Inko">Get the model</a> ·
20
- <a href="#generate-an-image">Start creating</a>
21
  </p>
22
 
23
- Inko is a bilingual text-to-image model for paintings and illustrations. It
24
- combines a 532M-parameter flow-matching transformer with Qwen3 text conditioning
25
- and the Qwen-Image VAE.
26
 
27
- The current release contains the **600k pretrained EMA weights**. Posttraining
28
- is in progress. The model and this README will be updated after posttraining.
29
 
30
- ## A small gallery
31
 
32
  From quiet ink landscapes to sunlit watercolors and textured oils. These are
33
  selected images from the released checkpoint. Click an image to see it at full
@@ -49,14 +50,172 @@ resolution, or choose its prompt in the demo and make it your own.
49
  600k EMA · 896 × 896 · 20 Euler steps · CFG 1.
50
  [Prompts and seeds](demo/showcase/prompts.json)
51
 
52
- The demo can expand a short idea with DeepSeek prompt enhancement. It shows the
53
- prompt used for each image. Seeds randomize by default; turn this off to reuse a
54
- seed. Set width and height independently from 480 to 1600 in multiples of 16,
55
- and CFG from 0 to 10. Selecting a gallery image restores its original prompt and
56
- settings, with enhancement and seed randomization off.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
  ## Generate an image
59
 
 
 
 
 
 
 
60
  Use Python 3.12 and a CUDA GPU. The Space repository contains the inference
61
  source and its dependencies:
62
 
@@ -83,14 +242,19 @@ image = pipe(
83
  image.save("inko.png")
84
  ```
85
 
 
 
 
 
 
86
  The first load downloads Inko, [Qwen3-0.6B](https://huggingface.co/Qwen/Qwen3-0.6B)
87
  and the [REPA-E Qwen-Image VAE](https://huggingface.co/REPA-E/e2e-qwenimage-vae).
88
  Pass a local export directory to `from_pretrained` to load local Inko weights.
89
  Use `text_encoder_path` and `vae_path` for local copies of the frozen models,
90
  and `local_files_only=True` to disable downloads.
91
 
92
- The release defaults are 896 × 896 pixels, 20 Euler steps, CFG 1 and
93
- resolution-dependent time shifting. Dimensions must be multiples of 16.
94
 
95
  ```python
96
  images = pipe(
@@ -112,38 +276,11 @@ other guidance values also evaluate the empty prompt, or `negative_prompt`
112
  when supplied. CPU generators make the initial noise independent of the
113
  inference device; outputs can still vary across hardware and numerical kernels.
114
 
115
- ## Model and training
116
-
117
- | Component | Configuration |
118
- |---|---|
119
- | Transformer | Width 1152, 16 heads, 1 double-stream block and 24 single-stream blocks |
120
- | Feed-forward layers | Gated SiLU, width 3072 |
121
- | Conditioning | Frozen Qwen3-0.6B, early exit after layer 20; pooled text and time conditioning |
122
- | Latents | 16 channels, 8× spatial compression, 2×2 latent patches |
123
- | Positions | Centered image-grid rotary embeddings |
124
- | Objective | Rectified flow, integrated from noise at time 0 to image latents at time 1 |
125
- | Pretraining | Variable-aspect 256p → 640p → 896p curriculum; 600,000 optimizer updates |
126
- | Precision | FP32 solver state and times; BF16 model forwards and VAE decode |
127
-
128
- Training covers Chinese painting, Western painting, people and general scenes.
129
- Sources include museum collections, WikiArt and captioned photographs. The
130
- [dataset notes](https://github.com/Mtrya/artflow/blob/main/notes/dataset_plan.md) describe source composition and retained
131
- license metadata for each source.
132
-
133
- The [pretraining configuration](https://github.com/Mtrya/artflow/blob/main/configs/pretrain.toml) defines the full
134
- curriculum. The [recipe](https://github.com/Mtrya/artflow/blob/main/notes/pretrain_recipe.md) explains conditioning,
135
- optimizers, checkpoint handling and resolution transitions. Training targets
136
- Ascend; platform paths and credentials stay in the local `INSPIRE.md`.
137
 
138
- For training setup, install the project dependencies in an environment matched
139
- to the Ascend runtime, then inspect the launcher:
140
-
141
- ```bash
142
- python -m scripts.pretrain.launch --help
143
- ```
144
 
145
  ## Source
146
 
147
  The [Space repository](https://huggingface.co/spaces/kaupane/Inko/tree/main)
148
- contains the runnable inference code. Training code and project notes are in
149
  [the project repository](https://github.com/Mtrya/artflow).
 
15
  <p align="center"><strong>Paint with words, in English and Chinese.</strong></p>
16
 
17
  <p align="center">
18
+ <a href="#gallery">Gallery</a> ·
19
+ <a href="#training-recipe">Training recipe</a> ·
20
  <a href="https://huggingface.co/spaces/kaupane/Inko">Try the demo</a> ·
21
+ <a href="https://huggingface.co/kaupane/Inko">Get the model</a>
 
22
  </p>
23
 
24
+ Inko is a bilingual text-to-image model for paintings and illustrations. Its
25
+ 532M-parameter flow-matching transformer brings together a curated art corpus,
26
+ caption and resolution curricula, chunked Muon optimization, and Ascend training.
27
 
28
+ **Current release: 600k pretrained EMA.** Explore its images below, then follow
29
+ the recipe from data preparation through pretraining and posttraining.
30
 
31
+ ## Gallery
32
 
33
  From quiet ink landscapes to sunlit watercolors and textured oils. These are
34
  selected images from the released checkpoint. Click an image to see it at full
 
50
  600k EMA · 896 × 896 · 20 Euler steps · CFG 1.
51
  [Prompts and seeds](demo/showcase/prompts.json)
52
 
53
+ ## Training recipe
54
+
55
+ ### A corpus for painting, people, and the wider world
56
+
57
+ | Domain | Sources and coverage |
58
+ |---|---|
59
+ | Chinese painting | National Palace Museum, Taipei, and museum collections; artwork crops and captions that retain inscriptions and calligraphy |
60
+ | Western painting | WikiArt, NGA, Rijksmuseum, and the Met; oils, watercolors, and a broad range of painting traditions |
61
+ | People | Human-recaption, people supplements, and Pexels; faces, full bodies, movement, clothing, and anatomy |
62
+ | Objects and scenes | Vintage imagery, ReLAION, PD12M, Z-Image, Megalith, iNaturalist, and Pexels; objects, architecture, nature, and everyday scenes |
63
+
64
+ The pipeline cleans artwork crops and caption text, retains source and license
65
+ metadata, and precomputes Qwen-Image VAE latents. Chinese, English, and longer
66
+ captions can share one image row. Training samples an image from a weighted
67
+ source pool, then chooses a caption within that image. Extra captions therefore
68
+ expand the descriptions available for an image without multiplying its source
69
+ weight.
70
+
71
+ Each resolution has its own eligible pool. At 640p and 896p, source mass is
72
+ computed from eligible image rows: Chinese painting, WikiArt, museum painting,
73
+ and the dedicated Pexels people source receive a 1.8× multiplier; selected
74
+ supplementary pools receive 1.5×. This keeps painting and anatomy coverage
75
+ explicit as higher-resolution filtering changes the available mix. The
76
+ [corpus notes](https://github.com/Mtrya/artflow/blob/main/notes/dataset_plan.md) describe curation and caption production;
77
+ [the run configuration](https://github.com/Mtrya/artflow/blob/main/configs/pretrain.toml) records every source weight.
78
+
79
+ ### Two curricula: image resolution and caption length
80
+
81
+ A continuous **600,000-update** run progresses through three variable-aspect
82
+ resolutions. Learning-rate, optimizer, EMA, and caption-curriculum progress
83
+ carry across the resolution boundaries.
84
+
85
+ | Resolution | Optimizer updates | Configured training image rows |
86
+ |---|---:|---:|
87
+ | 256p | 1–450,000 | 1,699,951 |
88
+ | 640p | 450,001–570,000 | 1,366,193 |
89
+ | 896p | 570,001–600,000 | 649,772 |
90
+
91
+ The row counts describe separate resolution pools, not disjoint images to add
92
+ together. Caption variants stay inside their image row.
93
+
94
+ Within each image, caption sampling shifts from favoring short descriptions
95
+ with a length bias of `L⁻¹` to favoring detailed descriptions with `L⁺¹`.
96
+ The exponent changes linearly over the run. A **20% probability reserve** goes
97
+ to captions shorter than 256 tokens when available, so concise prompts remain
98
+ part of training. Caption dropout is independently sampled at 10%.
99
+
100
+ Text is encoded online with frozen Qwen3-0.6B, stopping computation after
101
+ layer 20. This lets the selected caption change across visits to an image.
102
+ Retained text can reach **2,048 tokens**; aspect-ratio and caption-length
103
+ buckets match each batch to its actual image/text workload.
104
+
105
+ ### Caption length also controls gradient share
106
+
107
+ Long descriptions receive more weight in the flow-matching objective:
108
+
109
+ ```text
110
+ w(L) = max(1, log₂(max(L, 1) / 128))
111
+ step loss = Σ wᵢ ℓᵢ / Σ wᵢ
112
+ ```
113
+
114
+ For example, 128-, 512-, and 2,048-token captions receive weights 1, 2, and 4.
115
+ Samples with dropped captions keep weight 1. The denominator includes all
116
+ micro-batches and distributed ranks in the optimizer step. Detailed captions
117
+ therefore receive a larger share of the gradient, and changing batch sizes or
118
+ accumulation does not turn that weighting into an unintended learning-rate
119
+ change. See the [weighting implementation](https://github.com/Mtrya/artflow/blob/main/src/pretrain/caption_loss_weights.py).
120
+
121
+ ### Flow matching with chunked Muon
122
+
123
+ The **532M-parameter** transformer uses one double-stream image/text block
124
+ followed by 24 single-stream blocks. It learns a rectified flow from noise to
125
+ VAE image latents, with logit-normal timestep sampling and resolution-dependent
126
+ time shifting. Pooled text and time jointly condition the blocks; QK-RMSNorm
127
+ and residual-branch RMSNorm are part of the architecture.
128
+
129
+ **Muon** optimizes hidden matrix weights. Fused QKV, modulation, and gated-FFN
130
+ matrices are split into their functional chunks before orthogonalization, with
131
+ shape scaling applied per chunk. **AdamW** handles embeddings, output layers,
132
+ normalization, and conditioning parameters. Muon's base learning rate is 0.02;
133
+ AdamW peaks at 1e-4. Ordinary AdamW weight decay is 0.01, with 0.4 on the three
134
+ shared conditioning matrices. The run uses a 20k-update warmup, continuous
135
+ cosine decay, global gradient clipping, and an EMA updated at every optimizer step.
136
+ [The complete recipe](https://github.com/Mtrya/artflow/blob/main/notes/pretrain_recipe.md) records the optimizer settings.
137
+
138
+ <details>
139
+ <summary>Architecture and inference precision</summary>
140
+
141
+ | Component | Configuration |
142
+ |---|---|
143
+ | Transformer | Width 1152, 16 heads, 1 double-stream block and 24 single-stream blocks |
144
+ | Feed-forward layers | Gated SiLU, width 3072 |
145
+ | Conditioning | Frozen Qwen3-0.6B, early exit after layer 20; pooled text and time conditioning |
146
+ | Latents | 16 channels, 8× spatial compression, 2×2 latent patches |
147
+ | Positions | Centered image-grid rotary embeddings |
148
+ | Objective | Rectified flow, integrated from noise at time 0 to image latents at time 1 |
149
+ | Pretraining | Variable-aspect 256p → 640p → 896p curriculum; 600,000 optimizer updates |
150
+ | Precision | FP32 solver state and times; BF16 model forwards and VAE decode |
151
+
152
+ </details>
153
+
154
+ ### Infrastructure built and measured for Ascend
155
+
156
+ The execution work reaches beyond the transformer forward pass. It includes
157
+ true early exit in Qwen3, a single masked slice for retained text features,
158
+ batched gradient normalization and EMA updates, and memory-aware batching.
159
+ The 24 single-stream blocks share RoPE tables and padding biases built once
160
+ per forward, avoiding repeated setup inside each block.
161
+ The earlier [CUDA execution comparison](https://github.com/Mtrya/artflow/blob/main/notes/redesign_plan.md#stage-status-and-decision-evidence)
162
+ improved from **54.99 to 72.98 samples/s** in steady state; its warm-inclusive
163
+ gain was **1.233×**.
164
+
165
+ **Ascend was qualified separately on 16×910B2C.** The early-256p comparison
166
+ measured the cumulative effect of native operators and workload planning:
167
+
168
+ | Execution path | Images/s |
169
+ |---|---:|
170
+ | Baseline | 656.29 |
171
+ | + Native fused RMSNorm | 737.68 |
172
+ | + Larger micro-batches, accumulation 1 | 765.34 |
173
+ | + Aligned 3072-wide FFN | 843.29 |
174
+ | + Native SwiGLU | **878.91** |
175
+
176
+ That is **33.9% higher throughput** and **24.8% lower update time** on the
177
+ matched early-256p workload. These rates exclude startup and periodic
178
+ monitoring; higher resolutions and longer captions have different costs.
179
+
180
+ The Ascend path also includes native masked attention.
181
+ Native RMSNorm preserves FP32 normalization and learned gains before casting
182
+ back. Native attention avoids the large saved-tensor cost of the generic
183
+ float-mask path. Bucket plans account for the resident transformer, frozen
184
+ text encoder, EMA, optimizer state, gradients, and distributed buffers under
185
+ a **52 GiB planning ceiling**, with 20 caption-length buckets per aspect ratio.
186
+
187
+ Same-stage restarts restore model, EMA, optimizers, schedules, sampler queues,
188
+ and per-rank random state. Resolution transitions construct a fresh sampler
189
+ for the new pool while carrying model and optimizer progress forward. All 16
190
+ ranks verified exact state restoration at the 640p continuation.
191
+ The [infrastructure record](https://github.com/Mtrya/artflow/blob/main/notes/infra_pretrain.md) gives measurement conditions,
192
+ operator checks, memory probes, and recovery evidence.
193
+
194
+ ### Posttraining: preference and prompt alignment
195
+
196
+ Posttraining is developed on
197
+ [`feat/posttrain`](https://github.com/Mtrya/artflow/tree/feat/posttrain).
198
+ The selected approach is **DiffusionART with attention LoRA**, starting from
199
+ the 600k EMA. It combines HPSv3 preference and VQAScore alignment rewards after
200
+ per-round standardization. The recipe uses rank-64 LoRA, Muon updates, a slow
201
+ EMA, and 20-step Euler rollouts at CFG 1.
202
+
203
+ Selection considers generated images, prompt adherence, and diversity alongside
204
+ reward scores. Fixed bilingual panels, DrawBench prompts, and held-out
205
+ comparisons provide different views of the model. The
206
+ [posttraining recipe and observations](https://github.com/Mtrya/artflow/blob/feat/posttrain/notes/posttrain_recipe.md)
207
+ record both gains and failure cases. **The public checkpoint and gallery on
208
+ this page are still the pretrained release.** Posttrained weights and their
209
+ examples will be published together.
210
 
211
  ## Generate an image
212
 
213
+ [Open the demo](https://huggingface.co/spaces/kaupane/Inko) to start with a short
214
+ idea or a gallery prompt. DeepSeek can expand your description, and the app
215
+ shows the prompt used. Seeds randomize by default. Width and height can each
216
+ range from 480 to 1600 in multiples of 16; CFG ranges from 0 to 10. Selecting a
217
+ gallery image restores its saved settings with enhancement and randomization off.
218
+
219
  Use Python 3.12 and a CUDA GPU. The Space repository contains the inference
220
  source and its dependencies:
221
 
 
242
  image.save("inko.png")
243
  ```
244
 
245
+ The default is 896 × 896, 20 Euler steps, and CFG 1.
246
+
247
+ <details>
248
+ <summary>Batch generation and local model files</summary>
249
+
250
  The first load downloads Inko, [Qwen3-0.6B](https://huggingface.co/Qwen/Qwen3-0.6B)
251
  and the [REPA-E Qwen-Image VAE](https://huggingface.co/REPA-E/e2e-qwenimage-vae).
252
  Pass a local export directory to `from_pretrained` to load local Inko weights.
253
  Use `text_encoder_path` and `vae_path` for local copies of the frozen models,
254
  and `local_files_only=True` to disable downloads.
255
 
256
+ Sampling uses resolution-dependent time shifting. Custom dimensions must be
257
+ multiples of 16.
258
 
259
  ```python
260
  images = pipe(
 
276
  when supplied. CPU generators make the initial noise independent of the
277
  inference device; outputs can still vary across hardware and numerical kernels.
278
 
279
+ </details>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
 
 
 
 
 
 
 
281
 
282
  ## Source
283
 
284
  The [Space repository](https://huggingface.co/spaces/kaupane/Inko/tree/main)
285
+ contains runnable inference code. Training code and project notes are in
286
  [the project repository](https://github.com/Mtrya/artflow).