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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
//! Pure-Rust end-to-end Bonsai-Image artifact: (text encoder →) DiT sampler →
//! VAE decoder → PNG.
//!
//! This is a thin wrapper over [`oxibonsai_image::pipeline::text_to_image`]: it
//! parses the example's args/env and builds a [`TextToImageCfg`], then writes
//! the returned PNG. The shared library function does the actual orchestration
//! (chaining the Qwen3-4B text encoder, the parity-validated FLUX.2 Klein DiT
//! Euler sampler, the FLUX.2 SMALL VAE decoder, and the Pure-Rust PNG encoder).
//!
//! Because this example is the parity/golden harness, it always runs in
//! golden-parity mode ([`GoldenOverride`]): the DiT init latent / position ids /
//! schedule come from the golden `.npy` dump (which is byte-identical to the
//! native `sample::*` scaffolding), so its output reproduces the earlier
//! golden-input render exactly. The native, seed-driven path (native noise +
//! native ids/schedule) is exercised by the `oxibonsai image` CLI subcommand
//! (which calls the same library function with `golden_override: None`).
//!
//! Usage:
//!
//! ```text
//! # Full Pure-Rust text→image from a PROMPT: tokenize → Qwen3 TE → 7680 cond →
//! # DiT sample → VAE → PNG. (~7-8 min for the DiT sample; the TE is seconds.)
//! cargo run --release -p oxibonsai-image --example generate -- \
//! --prompt "a tiny bonsai tree in a ceramic pot" /tmp/bonsai_rust_out.png
//!
//! # Fast iteration: reuse the golden step-3 latent, skip the sampler.
//! OXI_USE_GOLDEN_LATENT=1 cargo run --release -p oxibonsai-image \
//! --example generate -- /tmp/bonsai_rust_out.png
//!
//! # Golden-cond end-to-end (no prompt): run the DiT sampler then VAE + PNG.
//! cargo run --release -p oxibonsai-image --example generate -- /tmp/bonsai_rust_out.png
//! ```
//!
//! When `--prompt` is given, the conditioning is produced natively by the Rust
//! text encoder (no golden `cond.npy`); its cosine vs the golden cond is printed.
//!
//! Env:
//! - `OXI_USE_GOLDEN_LATENT=1` — use the golden `latent_after_step3` instead of
//! sampling (fast path).
//! - `OXI_DIT_GGUF` — DiT GGUF path (default `/tmp/parity.gguf`).
//! - `OXI_GOLDEN_DIR` — bf16 golden dir (default `/tmp/bonsai_golden/bf16`).
//! - `OXI_VAE_WEIGHTS` — VAE weights dir (default `/tmp/bonsai_golden/vae/weights`).
//! - `OXI_VAE_GOLDEN` — VAE golden dir (default `/tmp/bonsai_golden/vae`).
//! - `OXI_TE_WEIGHTS` — TE f32 weights dir (default `/tmp/bonsai_golden/te/weights`).
//! - `OXI_TE_4BIT` — path to the native 4-bit `model.safetensors`. When set, the
//! TE loads from this 2.1 GB file instead of the 15 GB f32 `.npy` dir.
//! - `OXI_TE_TOKENIZER_DIR` — dir with `tokenizer.json` (default: the 4-bit model dir).
use PathBuf;
use ExitCode;
use ;
/// Parsed CLI arguments: an optional `--prompt`, `--seed`, and the output PNG
/// path (positional or `--out`).
/// Parse `[--prompt <text>] [--seed <n>] [--out <path> | <out.png>]`
/// (order-independent). In golden-parity mode the seed has no effect (the init
/// latent is loaded from the golden dump), but it is accepted so the documented
/// commands parse cleanly.