Lumina-Image 2.0 β€” one 3.27 GB file, no Python

Alpha-VLLM/Lumina-Image-2.0 β€” text encoder, DiT and VAE β€” packed into a single CMF file and run by a pure-Rust engine. No torch, no diffusers, no CUDA install, no C++ toolchain: one binary, one file, and the GPU it finds.

What it buys you is deployment, not speed: 3.27 GB against the reference checkout's 19.8, 3.25 GB of VRAM against 10.5, and nothing to install. What it costs is time on hardware that can run the reference β€” the numbers are below, unedited.

The same image, both ways

cortiq q4tp against the diffusers reference

Left: this file, 4-bit, rendered by cortiq on Vulkan. Right: the diffusers reference in bf16 on CUDA. Same prompt, same seed, same 30 steps at CFG 4, and β€” through CMF_INIT_LATENT β€” the same starting noise, without which the two sample different noise and no pixel comparison means anything.

22.3 dB PSNR, mean difference 11.8 of 255. The composition, pose and light are the same; the fur, the branches and the snow texture are not identical. Four-bit weights cost detail, not the picture.

Measured

One machine, both arms, 2026-08-06: NVIDIA RTX PRO 6000 Blackwell + 48-thread AMD EPYC 9B45, cortiq 0.5.58 against diffusers 0.39 / torch 2.11. 512 Γ— 512, 30 steps, CFG 4, seed 7, end to end.

this file (cortiq) reference (diffusers)
GPU render 14.7 s (Vulkan) 2.2 s (CUDA, bf16)
GPU, first image incl. load 14.7 s 11.8 s
GPU peak VRAM 3.25 GB 10.5 GB
CPU render, 48 threads 468 s 158 s (fp32)
CPU peak RSS 3.16 GB 20.6 GB
On disk 3.27 GB 19.8 GB
Runtime dependencies none torch + diffusers + CUDA

The reference is still 6.7Γ— faster on a card this size and 3Γ— on the CPU. If your machine can hold 20 GB of weights and a torch stack, run the reference β€” it is faster, and it is the thing this file was made from.

The gap was 36Γ— two releases ago. What closed most of it, in order of size: the fused block stopped allocating its 300 MB of scratch on every one of 1560 calls per image; both GEMM tiles were laid out 16 floats to a row and read down the column, so the sixteen threads of a row shared one memory bank of 32 and every read serialised; attention ran one head at a time behind a shared score buffer, at 34 workgroups on a 150-SM card; and the GEMM now runs on the card's matrix units β€” tensor cores on NVIDIA β€” through cooperative matrices at f16 16Γ—16 with an f32 accumulator, which took the isolated kernel from 5 605 to 50 730 GFLOP/s.

That last one moves the image in its last bits, since the multiplies are f16 where they were f32. It does not move it away from the reference: the tensor path measures 22.5 dB against it and the scalar path 22.3. The matrix units are used only where the adapter reports that exact shape, and CMF_COOP=0 turns them off.

Where this file is the better answer: machines that cannot. Apple silicon with no CUDA, a laptop with 13 GB free, a shipped application that cannot carry a Python environment, an offline box, an image pipeline that has to start in one second rather than twelve.

Apple silicon

MacBook Air M4 (fanless, 24 GB), Metal, same settings, cortiq 0.5.57:

30 steps
512 Γ— 512 212 s
256 Γ— 256 67 s

Under 0.5.57 a render also leaves the CPU alone β€” the wait for each command buffer used to spin, which cost a performance core and, on a fanless machine, some of the GPU's power budget. It is 2% of one core now, down from 100%.

The reference is not measured on this machine: its 19.8 GB does not fit the free disk, which is the point of the comparison rather than a gap in it.

Run it

cargo install cortiq-cli          # pure Rust; needs >= 0.5.57
hf download infosave/Lumina-Image-2.0cmf lumina-q4tp.cmf --local-dir .

cortiq imagine lumina-q4tp.cmf \
  --prompt "a red fox sitting in snow at sunset, photorealistic, detailed fur" \
  --height 512 --width 512 --steps 30 --seed 7 --out fox.ppm

The GPU is used when one is visible β€” Metal on macOS, Vulkan or DX12 elsewhere. CMF_GPU=0 forces the CPU. cortiq gpu prints what the engine sees; if it names llvmpipe rather than your card, the Vulkan loader has found a software driver and the run will crawl.

Output is P6 PPM β€” no image library is linked into the engine. Convert with sips -s format png fox.ppm --out fox.png on macOS, convert fox.ppm fox.png with ImageMagick, or ffmpeg -i fox.ppm fox.png.

Flags that matter: --steps (30 is the default and a good trade), --cfg (4.0 default; ≀ 1 disables classifier-free guidance and halves the work at some prompt-adherence cost), --seed, --height/--width (multiples of 16).

Vulkan and DX12 need β‰₯ 0.5.54. Before it, 512 Γ— 512 died on the first step: one SwiGLU dispatch asks for 75060 workgroups where a wgpu dimension holds 65535. Do not set CMF_DIT_FUSED=0 there either β€” the per-op path renders a visibly wrong image at 512 Γ— 512 (11.0 dB against the CPU reference, where the default fused path is at 28.2). Both are fixed or defaulted correctly in 0.5.54 and later.

Reproduce the comparison

pip install torch diffusers transformers accelerate
hf download Alpha-VLLM/Lumina-Image-2.0 --local-dir lumina-ref

python3 tools/bench_lumina.py --ref lumina-ref --cmf lumina-q4tp.cmf \
    --cortiq ./target/release/cortiq                 # the timings above
python3 tools/bench_lumina.py --ref lumina-ref --cmf lumina-q4tp.cmf \
    --cortiq ./target/release/cortiq --same-noise    # the image pair

The script is in the engine repository. --same-noise writes the reference's starting latent and hands it to cortiq through CMF_INIT_LATENT (needs β‰₯ 0.5.56).

Which file

Two layouts of the same weights β€” same 4-bit grid, same images.

file size notes
lumina-q4tp.cmf 3.27 GB take this one. Needs cortiq β‰₯ 0.5.40
lumina-q4t.cmf 3.45 GB the older layout, for cortiq < 0.5.40

q4tp keeps the nibbles byte-identical and stores each tile's scale as a 5-bit rung on a per-row ladder instead of a standalone f16 β€” the scale field was 11% of a q4t file. Rendering speed is unchanged (interleaved at 256px/8 steps on an M4: 26 and 27 s against 27 and 26), and so is the image: 43.6 dB against the q4t render, 0.31% mean pixel difference.

Any existing .cmf converts in place, no checkpoint needed:

cortiq requant lumina-q4t.cmf --output lumina-q4tp.cmf --quant q4tp

What is in the file

The whole pipeline, not just the transformer: Gemma-2 text encoder + Next-DiT + FLUX VAE + the tokenizer, 888 tensors, 5.27B parameters across the three stages, in one mmap-served file that checks its own integrity. Projections are q4_tiled; modulation and embeddings stay q8, the VAE f16, norms f32.

Fidelity

The engine mirrors the diffusers Lumina2Pipeline: the system-prompt template, Gemma hidden_states[-2] as caption features, FlowMatchEulerDiscrete with static shift 6, the model called at t = 1 βˆ’ Οƒ, CFG with per-row norm rescaling and the sign flip before the Euler step. The 22.3 dB above is what remains after that: 4-bit weights, int8 activations on the CPU arm, and a device working in f32 where the reference works in bf16.

CPU and GPU renders of the same seed also differ from each other β€” same cause, and a flow-matching sampler grows small differences over its steps. On the card above, 4 steps at 512 Γ— 512: 28.2 dB between them.

Reproduce the packing

cortiq imagine-pack <diffusers-root> --quant q4t --out lumina-q4t.cmf

<diffusers-root> is the Lumina-Image-2.0 checkout with tokenizer/, text_encoder/, transformer/, vae/. Takes ~9 minutes and streams shard by shard.

License

Apache-2.0, inherited from the base model. Weights Β© Alpha-VLLM; this repackaging only changes the storage format.

The engine, converter and format spec: https://github.com/infosave2007/cmf

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for infosave/Lumina-Image-2.0cmf

Finetuned
(17)
this model

Space using infosave/Lumina-Image-2.0cmf 1