Model
β‘ Demo: MOSS-Image 4-Step Turbo Space
π v2.0 (2026-10-18) β major update, usage changed. The model is now Euler-native: a single
lora.safetensorsthat runs on the stock flow-matching Euler sampler (any LoRA loader, 4 steps, CFG 1) β the custom data-space sampler and thetime_embedding.safetensors/dataspace.safetensorsfiles are no longer needed and were removed from the repo root. If you used v1.x adapters, grab the old data-space variant fromcheckpoint-update-400/(it keeps its own sampler), or switch to the new one-line loader below. New users: just follow the Quickstart.
The fastest high-fidelity MOSS-Image-SFT: 4 steps, no CFG, one LoRA file, stock sampler. No custom loop, no auxiliary safetensors, no pipeline patches β it drops into any standard LoRA loader.

Both images above were generated by this model in 4 steps, no CFG β "TODAY'S SPECIAL / Flat White $4.50" and ζ·±ε€ι£ε render correctly.
License: Apache-2.0 β commercial use OK.
| Claim | Evidence |
|---|---|
Only 4-step MOSS-Image that runs on the stock sampler in any LoRA loader β ComfyUI LoraLoaderModelOnly, or diffusers via the bundled apply_lora.py (the custom pipeline has no load_lora_weights), release flow-Euler scheduler, CFG 1 | v3 is trained natively on the release schedule (anchors t = 1000/910/717/24), not adapted to it |
| Best text/numeric fidelity of any few-step MOSS-Image | 4-way head-to-head, same prompts + seeds: this model is the only one that renders "62% / 38%" correctly β darask0's rapid-moss and lodestones' lora_latest both garble secondary numbers (see strips below) |
| Bilingual text rendering (δΈζ + English) | Signage-lexicon trained v1.1+: "OPEN 24H", menus, infographics, Chinese storefronts |
| No tiling at 2048Β² | Verified 1024Β² / 1536Γ1024 / 2048Β² (tiling_probe/) |
| Works on MOSS-Image-Base too | Apply the same lora.safetensors to the Base transformer β text fidelity preserved, output slightly softer (Base's own look, per OpenMOSS). Verified: base_compat/ (community find by @lvladikov) |
| Fully packaged | All-in-one repo (pipeline + text encoder + VAE), inference.py CLI, live ZeroGPU demo, training code included |
~11 s per 1024Γ1024 image on one A100 (4 forwards, bf16 base + fp32 LoRA), no CFG, no negative prompt. Distilled via data-space DMD (arXiv 2610.12102), warm-started from lodestones/MOSS-Image-SFT-8-steps-dmd.
25% faster than the 4-step (~4.2 s vs ~5.6 s per 1024Β² image on one A100) with draft-tier quality that actually holds: correct text, single sharp subjects, clean humans. The middle anchor gives the model a layout-correction step β this is what 2 steps structurally cannot do (2-step documented on the card as a failed experiment, strips included).
Examples β 3 steps, CFG 1, same seeds as the eval strips:
| Menu | ζ·±ε€ι£ε street | Infographic | Lantern | Tea tin | Shiba Inu |
|---|---|---|---|---|---|
![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
ComfyUI: put lora_3step.safetensors (or the frozen
moss_image_sft_3step_v1.0.safetensors) in models/loras/, load it with
LoraLoaderModelOnly (strength 1.0) on the stock MOSS-Image-SFT diffusion
model, KSampler = euler / simple / 3 steps / CFG 1.0. Same base files
and sampler as the 4-step β just one fewer step. Do not run it at other step
counts (trained for exactly 3).
Speed ladder: 3-step draft (~4.2 s) β 4-step final (~5.6 s) β 6β8 steps
above 1024Β². Human examples + a 30-second video:
showcase/.
Update ComfyUI (needs the MOSS-Image support from 16 Oct 2026 β the
Load CLIP node must offer type moss_image).
Download 4 files into your ComfyUI folders:
| File | Put in | Source |
|---|---|---|
moss_image_sft_bf16.safetensors (10 GB) | models/diffusion_models/ | Comfy-Org/MOSS-Image |
qwen3.5_9b_int8_convrot.safetensors (10 GB) | models/text_encoders/ | Comfy-Org/MOSS-Image |
flux2-vae.safetensors (0.3 GB) | models/vae/ | Comfy-Org/MOSS-Image |
moss_image_sft_4step_v2.0.safetensors (1.2 GB) | models/loras/ | this repo |
Drag comfyui/moss-image-4step-turbo.json
onto the canvas and hit Queue. The workflow already has the right settings:
LoraLoaderModelOnly at strength 1.0, sampler euler / simple, 4 steps,
CFG 1.0.
β οΈ Running the default MOSS-Image template (25β50 steps, CFG 2.5β3) with this LoRA gives smudged, overcooked output β the distilled model wants 4 steps and CFG 1.0 (6β8 steps above 1024Β²). Full-quality option: load the merged fp32 single file
moss_image_sft_4step_v2.0_fp32.safetensorsinLoad Diffusion Modeland skip the LoRA entirely (see ComfyUI below).
β‘ Draft mode: swap the LoRA file for
lora_2step.safetensors(or the frozenmoss_image_sft_2step_v0.1.safetensors) and set 2 steps β ~2Γ faster previews, then flip back to the 4-step for finals.
Base bf16 transformer + this LoRA, release sampler, 4 steps, CFG 1. Note: the
custom pipeline has no load_lora_weights β use the bundled
apply_lora.py:
import torch
from diffusers import DiffusionPipeline
from apply_lora import apply_turbo_lora # ships in this repo
pipe = DiffusionPipeline.from_pretrained(
"akhaliq/MOSS-Image-SFT-4-steps", # all-in-one: also loads from base repo
custom_pipeline="pipeline_moss_image", trust_remote_code=True,
torch_dtype={"default": torch.bfloat16, "vae": torch.float32},
).to("cuda")
apply_turbo_lora(pipe.transformer) # fp32 LoRA, unmerged
image = pipe("A neon sign reading 'ζ·±ε€ι£ε ' over a rainy door",
num_inference_steps=4, guidance_scale=1.0,
generator=torch.Generator("cpu").manual_seed(1234)).images[0]
Precision: keep the LoRA unmerged in fp32 β the distillation delta is smaller than bf16's rounding step. The fp32 LoRA applied unmerged on the bf16 base (via
apply_lora.py) is the evaluated configuration; merging into bf16 degrades fine text first. For maximum quality use the merged fp32transformer/instead.
python inference.py --prompt "..." --steps 4 --out out.png
draft: python inference.py --prompt "..." --steps 2 --lora-file lora_2step.safetensors --out out.png
The lora_3step.safetensors draft LoRA uses the same base model, loader,
and scheduler settings as the 4-step β only the step count changes:
| Path | How |
|---|---|
| ComfyUI | Put lora_3step.safetensors in models/loras/, load it in the same workflow, set KSampler steps = 3 (CFG stays 1.0) |
| diffusers | apply_turbo_lora(pipe.transformer, filename="lora_3step.safetensors"), then pipe(..., num_inference_steps=3, guidance_scale=1.0) |
| Space | Pick Draft (3 steps) in the Mode radio β weights hot-swap |
| CLI | add --steps 3 --lora-file lora_3step.safetensors |
Use it for prompt iteration and composition scouting, then re-render finals at 4 steps. Do not run it at other step counts (trained for exactly 3).
Why not 2 steps? Two documented attempts (data-scaled DMD, ~$8; photo- critic + spectral, ~$7) both failed to beat the plain 2-step baseline, and the 2-step shows mode-averaging at 2 anchors β blurred/duplicated subjects (strips,
eval_3step/). The 3-step's middle anchor gives the model a layout- correction step; it's the draft tier that works. The 2-step file stays in the repo for the record.
Resolution β steps (measured, hires_probe/):
the 4-step anchors cover ~4k latent tokens. Above that, give it more steps β
same LoRA, no retrain:
| Output | Steps |
|---|---|
| β€1024Γ1024 | 4 |
| ~1536 wide | 6 |
| 2048Γ2048 | 8 |
At 4 steps above 1024Β² the output turns hazy/washed-out; at 6β8 steps it is sharp (verified 2048Β² portraits and street scenes). A multi-resolution distillation for native 4-step-at-2048 is on the roadmap.
Prompt tip for high-res (thanks @lvladikov): above 1024Β², longer, detailed prompts hold up markedly better than one-liners β short prompts ("Beautiful woman") are where haze and grid-tiling show first; a full scene description with subjects, setting, lighting and text survives much better at 1536β2048. The root cause is single-resolution training (1024Β² only); a multi-resolution bucket run is planned.
π‘ Prompt length matters at high resolution (community finding, @lvladikov): above 1024Β², short prompts ("Beautiful woman") go hazy even at 6β8 steps, while long descriptive prompts (subject, clothing, light, lens, setting) stay clean at 4. The model was trained on long scene captions β at β₯1536 wide, write a full sentence, not a noun phrase. Short prompts at high res also increase ghosting/subject cloning; a multi-resolution training run to fix this at the weights level is next.
Single-file CLI: python inference.py --prompt "..." --steps 4 --out out.png
lora.safetensors β the model. fp32 LoRA, rank 128 / alpha 128 on every
block's proj.{q,k,v,o,ffn_up_gate,ffn_down} (kohya keys). Euler-native.
Canonical name β always points at the latest release. Frozen versioned copies
are also provided so you always know exactly which version you have:
moss_image_sft_4step_v2.0.safetensors (identical to today's canonical file).
Old releases stay in their checkpoint folders (checkpoint-update-* data-space,
euler-update-* Euler).lora_3step.safetensors β 3-step draft tier (canonical), with frozen
moss_image_sft_3step_v1.0.safetensors. Same sampler settings, just
3 steps, CFG 1 β ~25% faster than the 4-step, and the draft tier that
actually works: subjects stay single and sharp (the 2-step's mode-averaging
blur/duplication is gone β the middle anchor gives the model a layout-
correction step), and primary text renders correctly. Checkpoints:
euler3-update-{50..200}/ (u200 = published, trained on 4ΓA100 DDP in 71 min).lora_2step.safetensors β 2-step experiment (kept for the record; see the
2-step ceiling note in Draft mode).transformer/ β merged fp32 transformer (LoRA baked in), for max quality
with the release pipeline.euler-update-{100..600}/ β v3 (Euler) training checkpoints, u600 = published.checkpoint-update-{250,500,750,1000}/ β v1.x data-space checkpoints
(archived; those need the data-space sampler and their bundled
time_embedding/dataspace files β see checkpoint-update-400/).inference.py, train_dmd.py, apply_lora.py β inference CLI, training
script, and the diffusers LoRA loader helper.comfyui/moss-image-4step-turbo.json β ready-to-run ComfyUI workflow.moss_image_sft_4step_v2.0_fp32.safetensors β merged fp32 single file
(LoRA baked in at full precision) for ComfyUI Load Diffusion Model.pipeline_moss_image.py β bundled
from the base repo so this repo loads standalone.Ready-to-run workflow:
comfyui/moss-image-4step-turbo.json
β native ComfyUI loaders (no custom nodes): Load Diffusion Model = the
Comfy-Org moss_image_sft_bf16.safetensors, LoraLoaderModelOnly =
moss_image_sft_4step_v2.0.safetensors (strength 1.0), KSampler = euler /
simple / 4 steps / CFG 1.0, CLIP type moss_image.
If output looks smudged/overcooked: you are almost certainly running the
default MOSS-Image template settings (25β50 steps, CFG 2.5β3) with the
distilled LoRA β set 4 steps and CFG 1.0 (6β8 steps above 1024Β², see the
resolution table). A default template ignoring the LoRA (undistilled model
at 4 steps) also produces mush; check the console for lora key not loaded.
For maximum ComfyUI quality use the merged fp32 single file
moss_image_sft_4step_v2.0_fp32.safetensors in Load Diffusion Model and
skip the LoRA entirely β standard LoRA patching casts the fp32 delta into
bf16 weights, which is where fine text is lost (see Precision).
The 4-step race β animated, same prompt + seed, live timers
(lodestones lora_latest 8-step | this model 4-step | rapid-moss 4-step):

This model finishes first (5.6 s vs 11.2 s) and is the only panel with all
numbers correct β rapid-moss slips to "48%", lora_latest invents "AUUTERT".
Full frames and the Shanghai-street race:
launch/.
π¬ Launch video with voiceover (25 s): showcase/launch_video.mp4
Static strips, 4-way, same prompts + seeds (left β right: this model (Euler, 4 steps) | v1.1 data-space 4-step | darask0 rapid-moss 4-step | lodestones lora_latest Euler 8-step):



Scorecard: this model ties the best on headline text and menus, wins numeric
fidelity outright (the infographic β both competitors garble secondary
numbers), and is the only one that needs no custom sampler. darask0's
rapid-moss still produces the liveliest street-scene compositions.
All 8 strips: v3_final/.
| Method | data-space DMD (arXiv 2610.12102) v1.x; Euler-native DMD v3 |
| Teacher | frozen MOSS-Image-SFT (bf16), CFG 3.0, negative branch skip-layer 22 |
| Fake score | base transformer (bf16) + fresh rank-128 LoRA, 1:1 update ratio |
| v1.0 | 1,000 updates from lodestones update-2600 warm start (data-space) |
| v1.1 | +400 updates, signage-lexicon + 3,000 real user prompts (fixed small-English-text class) |
| v3 | 600 updates, Euler-native, warm-started from lora_latest; anchors t = 1000/910/717/24 |
| Optimizer | Adam Ξ²β=0, grad clip 1.0, EMA 0.999 |
| Cost | ~$14 + ~$6 + ~$9 on 1Γ A100-80GB |
@misc{mossimagesft4steps2026,
title = {MOSS-Image-SFT-4-steps: 4-step DMD distillation of MOSS-Image-SFT},
author = {akhaliq},
year = {2026},
howpublished = {\url{https://huggingface.co/akhaliq/MOSS-Image-SFT-4-steps}}
}
Builds on MOSS-Image (Apache 2.0), lodestones' 8-step DMD, and Few-Step Generation via Data-Space Iteration.