Nodes/ComfyUI-MOSS-Image-Studio-Lite-SatoDive/MOSS Generate Lite (SatoDive)
ComfyUI Node

MOSS Generate Lite (SatoDive)

One node, draggable boxes, zero sampler spaghetti

By SatoDive·Created 3 days ago·Updated 2 days ago· 4
MOSS Generate Lite (SatoDive)
  • model
  • clip
  • vae
  • image
  • mask
  • image
  • final_prompt
  • report
◄prompt►
◄width1024►
◄height1024►
◄seed0►
◄steps8►
◄cfg1.0►
◄sampler_nameeuler►
◄schedulersimple►
◄denoise1.00►
◄negativensfw, worst quality, bad anatomy, watermark, jpeg artifact►
◄slgfalse►
◄mask_grow8►
◄savetrue►
◄filename_prefixMOSS/studio►
◄layout►

What you're actually looking at

MOSS-Image is OpenMOSS's image model - a 5B DiT with a Qwen3.5-9B text encoder - and ComfyUI core picked it up natively around v0.42. So the boring half is already in your install: UNETLoader, CLIPLoader with a moss_image type, VAELoader. What core doesn't give you is the part that makes the model pleasant to drive.

MOSS Generate Lite is the whole job on one panel: prompt, size, seed, steps, CFG, sampler, negative, plus two things you can't do with stock nodes - a Layout canvas where you drag boxes and give each box its own prompt and its own strictness, and mask-based inpaint that pastes the untouched pixels back exactly.

Fair warning: there's barely any community folklore about MOSS-Image yet - search the subreddits for it and you get nothing. The settings below are the author's, not a crowd's.

How it works under the hood

It's a thin wrapper, and that's the compliment. Sampling goes through ComfyUI's own common_ksampler, so you keep live previews and the real sampler/scheduler lists, and skip-layer guidance uses the built-in SkipLayerGuidanceDiTSimple on layer 22 for the first half of the steps - not a reimplementation.

Layout is the interesting mechanism. Your boxes are compiled at run time into MOSS's official one-line layout prompt: a summary.caption for the whole image plus items, each with a label (object / character / text), a caption, and a bbox in the official abs_centralized / yxyx form - pixels measured from the centre of the frame, y first. Strictness works by appending a sentence to that box's caption: at 0.5 and up, "Only this, nothing else inside this area"; at 0.9, "Exactly as described, with nothing added and nothing else inside this area." Text boxes carry their exact characters too.

At CFG 1 the negative is never encoded at all - a zeroed conditioner goes in its place - so the turbo path is genuinely cheaper, and that's why the negative prompt and SLG do nothing there. With an image connected the latent comes from a VAE encode of it; with a mask too it becomes a noise_mask inpaint with Differential Diffusion, and after decode the result is composited as original * (1 - mask) + new * mask, so everything you didn't paint keeps its exact bytes.

The fields you'll actually touch

Wire model from UNETLoader (optionally through LoraLoaderModelOnly for the speed LoRA), clip from CLIPLoader with type moss_image, vae from VAELoader with the flux2 VAE. Then:

  • prompt - what to make. With boxes on the canvas it becomes the global description instead of the whole picture.
  • steps / cfg - pair them. 8 / 1.0 with the 8-step DMD LoRA; 4 / 1.0 with a 4-step one; 25–50 / 2.5–3 with no LoRA.
  • denoise - only meaningful with an image: 0.5 nudges, 0.85 is new content, 1.0 repaints. Without one it's forced to 1, and the report says so.
  • negative / slg - both dead at CFG 1. Above it, negative defaults to the official template's list and slg turns on the layer-22 guidance.
  • mask_grow (default 8) - dilates your painted mask so the repaint bleeds past the brush stroke. Too far and it eats detail.
  • layout - JSON. Empty means no layout, and JSON that doesn't parse also means no layout, silently. Quietest way to lose an hour.

Outputs: image, final_prompt (literally the string the encoder read; on a layout run, the compiled JSON), and report (settings, seconds, and reasons - "prompt encode reused", "SLG ignored (needs CFG > 1)"). With save on it writes to output/MOSS with the workflow in the PNG.

Install

ComfyUI v0.42 or newer is a hard requirement: the pack touches comfy/ldm/moss_image and warns in the console when it's missing.

cd ComfyUI/custom_nodes
git clone https://github.com/SatoDive/ComfyUI-MOSS-Image-Studio-Lite-SatoDive
# restart ComfyUI

No pip dependencies at all - unusual and welcome. The weight is in the models, from Comfy-Org/MOSS-Image on Hugging Face: moss_image_sft_int8_convrot (or bf16) in diffusion_models, qwen3.5_9b_int8_convrot in text_encoders, flux2-vae in vae - that's Flux 2's VAE, so you may already have it. The optional 8-step turbo LoRA is MOSS-Image-SFT-8-steps-dmd by lodestones, at 1.0.

Where people get burned

The node not appearing in the menu is almost always an old ComfyUI - the console line says so. Then the loaders: the CLIP type dropdown has to be moss_image, and the VAE has to be the flux2 one. Another family's VAE decodes this model to mush and nothing warns you.

Connected an image but your width/height did nothing? The image wins, by design, and the report says "size from the image". And a 5B DiT next to a 9B encoder is not small - the bf16 pair beside your browser on an 8GB card is how you meet the swap file.

CategorySatoDive/MOSS-Image Lite

Inputs (20)

NameTypeDefaultDescription
modelMODELUNETLoader (moss_image_*) -> optional LoraLoaderModelOnly (speed LoRA).
clipCLIPCLIPLoader, type moss_image.
vaeVAEVAELoader, flux2 vae.
promptSTRINGWhat to make. With layout boxes it becomes the global description.
widthINT1024256–4096—
heightINT1024256–4096—
seedINT00–18446744073709550000—
stepsINT81–2008 with the 8-step DMD LoRA, 4 with the 4-step LoRA, 25-50 without a LoRA.
cfgFLOAT1.01–101 with a speed LoRA (fastest: the negative is not even encoded), 2.5-3 without.
sampler_nameCOMBOeuler44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38
schedulerCOMBOsimple9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3
denoiseFLOAT1.000–1With an image: 0.5 = small change, 0.85 = new content, 1 = repaint.
negativeSTRINGnsfw, worst quality, bad anatomy, watermark, jpeg artifactOnly used when CFG > 1.
slgBOOLEANfalseOfficial skip-layer guidance on the negative branch (layer 22, first half of the steps). Only works with CFG > 1.
mask_growINT80–128Inpaint: grow the painted mask by this many pixels (soft edges).
saveBOOLEANtrue—
filename_prefixSTRINGMOSS/studio—
layoutSTRINGLayout boxes as JSON (drawn on the node's canvas). Empty = no layout.
imageoptIMAGEimg2img / inpaint source (its size wins).
maskoptMASKInpaint area (paint it in Load Image's mask editor).

Outputs (3)

NameTypeDescription
imageIMAGE—
final_promptSTRINGExactly what the model read.
reportSTRING—