Center the model card on the training recipe and generation gallery
Browse files
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.
|
| 24 |
-
|
| 25 |
-
and
|
| 26 |
|
| 27 |
-
|
| 28 |
-
|
| 29 |
|
| 30 |
-
##
|
| 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 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 93 |
-
|
| 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 |
-
|
| 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
|
| 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).
|