MOSS-Image SFT NVFP4 for ComfyUI

MOSS-Image SFT NVFP4, GPTQ-tuned for ComfyUI on RTX 50 GPUs, by BennyDaBall

Follow me on X @BennyDaBall_OG !

Weights update, November 2, 2026: the FP4 layers are now solved with Schur Replay GPTQ. Same file name, same size, same speed, closer to bf16.

This is an independent NVFP4 quantization of MOSS-Image SFT. The OpenMOSS team created the original model. I converted Comfy-Org's official bf16 checkpoint and packaged the quantized weights and the validation here. This is not a new base model or an official OpenMOSS release.

One file. 4.49 GB. 2.5x faster than bf16 on an RTX 5090, and faster than the official int8 too.

As far as I can tell, this is the first real NVFP4 build of MOSS-Image you can drop into stock ComfyUI. No custom nodes, no runtime patch, no GGUF loader. Load Diffusion Model, pick the file, hit Run.

Model Metadata

Key Value
License Apache-2.0 (same as the source weights)
Base Model OpenMOSS-Team/MOSS-Image-SFT (via Comfy-Org/MOSS-Image bf16)
Architecture ~5B single-stream DiT, 42 blocks, Qwen3.5-9B text encoder (unchanged)
Format ComfyUI native NVFP4 + int8 ConvRot + bf16, per-layer comfy_quant metadata
File moss_image_sft_nvfp4.safetensors, 4.49 GB
Tested on RTX 5090, ComfyUI 0.43.0, comfy-kitchen 0.2.40, PyTorch 2.14 cu130
sha256 568bf59a7fcc14c4eb516be9c23aebdf0b4f104f73f4772674a4deb215688d70

What is MOSS-Image, and why should you care?

MOSS-Image is OpenMOSS's text-to-image model, and its party trick is text. Signs, posters, labels, menus, handwritten notes, in English, Chinese, Korean, Arabic and more, spelled correctly a lot more often than you'd expect from a diffusion model. It also takes layout boxes, so you can tell it where the car goes, where the headline goes and what the headline says.

The catch: the bf16 model is 10.16 GB and takes 27 seconds per 1920x1088 image on a 5090. This build gets that down to 4.49 GB and 11 seconds while keeping the text sharp.

Hero gallery rendered with this NVFP4 file

Every image above was rendered with this NVFP4 file at 1920x1088, official template settings, best of 2 seeds, no upscaling, no inpainting, no touch-ups. The WILD cover was placed with MOSS-Image's layout boxes (Create Bounding Boxes into MOSS-Image Layout Prompt). Full-resolution PNGs are in images/hero.


The Numbers

Same machine, same template (er_sde, simple, 25 steps, cfg 2.5, the template's negative prompt). Speed is ComfyUI's own execution time per image, median of 5 warm runs, a fresh seed every run so nothing gets cached. Peak VRAM is the whole GPU (text encoder, VAE and my ~3.3 GB desktop included).

Model File s/img 1920x1088 s/img 1024x1024 Peak VRAM
bf16 (Comfy-Org) 10.16 GB 27.04 12.98 22.1 GB
int8 ConvRot (Comfy-Org) 5.41 GB 11.79 5.37 17.6 GB
NVFP4 (this repo) 4.49 GB 10.96 4.92 16.2 GB

So: 2.5x faster than bf16, 7-8% faster than int8, 56% smaller than bf16, 17% smaller than int8.

How close is it to the original? Same prompt, same seed, measured against fresh bf16 renders on 66 pairs: 18 prompts x 3 seeds at 1920x1088 (fashion, cinematic, product, posters, anime, horror, glamour, layout boxes) plus 6 prompts x 2 seeds at 1024x1024 (an English sign, the official Chinese fridge-note prompt, an English/Arabic/Korean sign, a portrait, a sky gradient and a busy night market). Lower LPIPS = closer to bf16.

Model LPIPS SSIM PSNR Color shift (R, G, B)
int8 ConvRot (Comfy-Org) 0.094 0.917 24.8 dB +3.4, +1.7, +0.8
NVFP4 (this repo) 0.143 0.876 22.1 dB +2.9, +0.9, +0.3

No warm tint, no color drift. For scale: the "just quantize every block to FP4" recipe scores LPIPS 0.362 with a +27, +21, +6 warm color shift (12-image check). That recipe is why this repo exists. More on that below.

Text check. Every string in the 1024x1024 text prompts was read back letter by letter by a reader that didn't know which image came from which model (16 strings per model):

Model Exact strings Letter errors
NVFP4 (this repo) 15/16 2 (Arabic)
int8 ConvRot 15/16 2 (Arabic)
bf16 13/16 5

Yes, the 4-bit file ties int8 and edges out the original here. No, I'm not going to pretend that means it's smarter than bf16. It's a small sample, so read it as "no text regression", which is the part that matters. The one miss is a single Arabic dot on one seed, and bf16 and int8 miss that exact dot too.


Same prompts, same seeds

bf16 on the left, this NVFP4 on the right. Same prompt, same seed, same everything.

bf16 vs NVFP4, same prompts and seeds

bf16 vs NVFP4, text and signage

2048x1152 night market, bf16 vs NVFP4, 100% crop

At 2048x1152, 100% crop: no mesh, streaking or banding. Same prompt, same seed.

Honest take: same-seed images can land a little differently in layout (int8's do too), but color, contrast, detail and text hold up. Comfy-Org's int8 is still closer to bf16 pixel for pixel. This one trades some of that for speed and size.


Quick Start

  1. Download moss_image_sft_nvfp4.safetensors into ComfyUI/models/diffusion_models/.
  2. Open the official MOSS-Image template (image_moss_image_t2i).
  3. In Load Diffusion Model, pick moss_image_sft_nvfp4.safetensors and leave weight_dtype on default.
  4. Text encoder and VAE stay the same as the template (for example qwen3.5_9b_w4a8_gptq with CLIP type moss_image, and flux2-vae_small).
  5. Run.

Requirements:

  • ComfyUI with MOSS-Image support (0.41.3 or newer; I tested 0.42.1).
  • An RTX 50-series / Blackwell GPU for native FP4. On older cards ComfyUI falls back to dequantizing the FP4 layers. It works, it's just slow. Grab Comfy-Org's int8 file instead if that's you.

Verified settings:

UNET: moss_image_sft_nvfp4.safetensors (weight_dtype default)
Text Encoder: qwen3.5_9b_w4a8_gptq.safetensors (type moss_image)
VAE: flux2-vae_small.safetensors
Steps: 25
CFG: 2.5
Sampler: er_sde
Scheduler: simple
Latent: EmptyFlux2LatentImage, 1-2 megapixels

Under the Hood: what's actually in the file?

Layers Format Why
qkv, o, ffn_up_gate in blocks 0-23 (72 layers) NVFP4, Schur Replay GPTQ These blocks are FP4-safe, so they get the fast Blackwell FP4 tensor cores
qkv, o, ffn_up_gate in blocks 24-41 int8 ConvRot The late blocks are where 4-bit hurts, measured below
ffn_down in all 42 blocks int8 ConvRot Speed, not quality: see "the SiTU problem"
Embedders, 2-block text refiner, time embedding, both modulations, final layer, norms (17 layers) bf16 Tiny, run once per step, not worth a single bit of risk
  • NVFP4 layers are ComfyUI's native format: 4-bit e2m1 weights, one e4m3 scale per 16 weights, one fp32 scale per tensor, activations quantized on the fly (W4A4). Nothing extra stored, no calibration scales.
  • The int8 ConvRot layers are copied byte for byte from Comfy-Org's moss_image_sft_int8_convrot.safetensors. They did good work, I kept it.
  • Every block carries the same comfy_kitchen_int8 attention setting as Comfy-Org's int8 file.

How we got here (the short version of a long two days)

  1. The obvious recipe failed. Every block linear in FP4, everything else bf16, round-to-nearest. 3.33 GB, very tempting. It came out slower than int8 and gave every image a warm, oversaturated, golden-hour-filter look nobody asked for.
  2. The SiTU problem. MOSS uses a soft-capped gated activation ("SiTU") in front of each ffn_down. Comfy-Org's int8 kernel fuses it into its quantize step. The FP4 path runs it as a pile of separate little kernels, which ate about 30% of every forward pass. The FP4 matrix multiplies themselves are great (cutlass3x_sm120 ... block_scaled_ue4m3xe2m1, ~40% faster than int8's), so the fix is simple: ffn_down stays int8, everything else gets to sprint.
  3. Finding the tint. I replayed the exact bf16 denoiser inputs through the quantized model and measured where the error came from. Almost all of it was a global color bias, almost all of it from rounding the 4-bit weights, and almost all of it in blocks 28-41.
  4. GPTQ fixed the weights. Instead of rounding each weight on its own, GPTQ rounds each layer so its output stays as close to bf16 as possible on real MOSS activations (30 calibration prompts, both CFG branches, 13 of the 25 steps, none of them reused in the tests). Each 16-weight block scale is picked by trying all 126 FP8 codes. Result: per-layer output error down 4-6x, and the tint gone.
  5. A block-by-block sweep picked the int8 tail. With GPTQ weights, I protected one block at a time and measured the gain on held-out prompts. Sensitivity climbs steadily with depth (block 41 matters most, then 40, 39...), and blocks 0-26 are basically free to run in FP4. So the last 18 blocks keep int8, the first 24 run FP4.
  6. Checked it like I meant it. File read back against the converter's own math, loaded through the stock loader, speed raced, A/B'd against bf16, text read back letter by letter.
  7. Schur Replay on top of GPTQ. Inside the GPTQ loop, every 16-weight block tries a window of FP8 scales (arXiv 2609.36654), replays GPTQ's error correction for each one, and keeps the scale with the lowest real output error. It beat plain GPTQ on all 72 FP4 layers, and on full renders it holds bf16's composition (layout, faces, signs) more often. I also tried pushing FP4 deeper (blocks 0-29, 0-35, all 42); every one of those landed further from bf16, so the late blocks keep int8.

Verification & Proof

  • Speed: 5 warm runs per model, fresh seeds, ComfyUI execution timestamps.
  • Quality: LPIPS / SSIM / PSNR / color shift against same-seed bf16 on 66 pairs at 1920x1088 and 1024x1024, bf16 re-rendered fresh on the same ComfyUI.
  • Every FP4 tensor in the file decodes in comfy-kitchen to exactly the codes the solver picked.
  • Text: blind letter-by-letter read, scored by edit distance over letters and digits in any script.
  • Prompts used for tuning and prompts used for testing never overlap.

Limitations

  • Mixed precision, not FP4 everywhere. The FP4 share is the part that helps on Blackwell without hurting the picture.
  • Not tested with LoRAs. Heads up: ComfyUI requantizes FP4 layers when it patches a LoRA onto them.
  • My numbers are from one RTX 5090. Other Blackwell cards should see the same ranking, not necessarily the same seconds.
  • Diffusion is still diffusion. A good file won't save a bad seed.

Acknowledgements

  • OpenMOSS for MOSS-Image (OpenMOSS-Team/MOSS-Image-SFT), Apache-2.0.
  • Comfy-Org for native ComfyUI support, the bf16 repack and the int8 ConvRot layers (Comfy-Org/MOSS-Image), Apache-2.0.
  • comfy-kitchen for the NVFP4 runtime, the GPTQ authors (Frantar et al.) for the rounding trick that saved this build, and the Schur Replay authors (arXiv 2609.36654) for the scale search.
  • My local power utility provider, for once again sustaining the research grid.

This repo is released under Apache-2.0, same as the source weights. Not affiliated with OpenMOSS or Comfy-Org.

Quantized & tested locally with care by BennyDaBall.

Follow me on X @BennyDaBall_OG !

Downloads last month
3,492
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support

Model tree for BennyDaBall/MOSS-Image-SFT-NVFP4

Quantized
(48)
this model

Collection including BennyDaBall/MOSS-Image-SFT-NVFP4

Paper for BennyDaBall/MOSS-Image-SFT-NVFP4