Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions docs/Model Support.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
[Lens](#lens) | MMDiT | 2026 | Microsoft | 4B | Minimal | Modern, lightweight, eh quality |
[Ideogram 4](#ideogram-4) | DiT | 2026 | Ideogram AI | 9B | Yes | Modern, advanced on input understanding |
[Krea 2](#krea-2) | DiT | 2026 | Krea AI | 12B | Yes | Modern, extremely smart and great quality |
[Boogu](#boogu) | MMDiT | 2026 | Boogu | 10B | Minimal | Modern, fast |

Old or bad options also tracked listed via [Obscure Model Support](/docs/Obscure%20Model%20Support.md):

Expand Down Expand Up @@ -693,6 +694,24 @@ For upscaling with SD3, the `Refiner Do Tiling` parameter is highly recommended
- **Scheduler:** Default is fine.
- **Sigma Shift:** Defaults to `1.15`

# Boogu

- [Boogu](<https://huggingface.co/Boogu>) is supported in SwarmUI!
- It is a 10B model, derived from OmniGen, that comes in three separate variants - **Base**, **Edit**, and **Turbo**:
- **Base**: [Comfy-Org/Boogu-Image - Base FP8](<https://huggingface.co/Comfy-Org/Boogu-Image/resolve/main/diffusion_models/boogu_image_base_fp8_scaled.safetensors>)
- **Edit** - image editing, takes a prompt image as a reference: [Comfy-Org/Boogu-Image - Edit FP8](<https://huggingface.co/Comfy-Org/Boogu-Image/resolve/main/diffusion_models/boogu_image_edit_fp8_scaled.safetensors>)
- Or the NVFP4 (6 gigs) here: [Comfy-Org/Boogu-Image - Edit nvfp4](<https://huggingface.co/Comfy-Org/Boogu-Image/resolve/main/diffusion_models/boogu_image_edit_nvfp4.safetensors>)
- **Turbo** - very fast, low step counts: [Comfy-Org/Boogu-Image - Turbo FP8](<https://huggingface.co/Comfy-Org/Boogu-Image/resolve/main/diffusion_models/boogu_image_turbo_fp8_scaled.safetensors>)
- Or the NVFP4 (6 gigs) here: [Comfy-Org/Boogu-Image - Turbo nvfp4](<https://huggingface.co/Comfy-Org/Boogu-Image/resolve/main/diffusion_models/boogu_image_turbo_nvfp4.safetensors>)
- Uses the Flux.1 VAE and a Qwen3-VL8B text encoder, both downloaded and handled automatically.
- For editing, use the `Edit` model and give it a prompt image - SwarmUI automatically wires it in as the reference.
- **Parameters:** recommendations differ between the Base, Edit, and Turbo models:
- **Sampler**: For Turbo, use LCM, otherwise default is fine, DPM++ 2M is recommended as a bit better than Euler for these models.
- **Scheduler:** For Turbo, use SGM Uniform, otherwise default is fine.
- **CFG Scale:** For Turbo, `1`, otherwise normal CFG ranges (around `4`).
- **Steps:** For Turbo, `4` is recommended, otherwise `20` as normal.
- **Resolution:** Side length `1024` is the default.
- **Sigma Shift:** Default is `3.16`.

# Video Models

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def encode(self, clip, steps: int, prompt: str, width: int, height: int, target_
def tokenize(text: str):
nonlocal images
if clip_vision_output is not None:
return clip.tokenize(text, llama_template=llama_template, image_embeds=clip_vision_output.mm_projected)
return clip.tokenize(text, llama_template=llama_template if llama_template else None, image_embeds=clip_vision_output.mm_projected)
elif images is not None:
if append_images:
image_prompt = ""
Expand All @@ -83,7 +83,7 @@ def tokenize(text: str):
text = image_prompt + text
else:
text = text + image_prompt
return clip.tokenize(text, llama_template=llama_template, images=images)
return clip.tokenize(text, llama_template=llama_template if llama_template else None, images=images)
else:
return clip.tokenize(text)

Expand Down
16 changes: 10 additions & 6 deletions src/BuiltinExtensions/ComfyUIBackend/WorkflowGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -769,9 +769,9 @@ public List<JArray> LoadPromptImagesForMainRef(List<Image> images)
public (JArray, JArray, JArray, JArray) BuildInputImageHandling(List<JArray> images, JArray pos, JArray neg, JArray latent)
{
JArray imgNeg = null;
if (IsKontext() || IsOmniGen() || IsQwenImage() || IsAnyFlux2())
if (IsKontext() || IsOmniGen() || IsQwenImage() || IsAnyFlux2() || IsBoogu())
{
if (IsOmniGen() || IsQwenImageEditPlus())
if (IsOmniGen() || IsQwenImageEditPlus() || IsBoogu())
{
imgNeg = neg;
}
Expand Down Expand Up @@ -803,7 +803,7 @@ void makeRefLatent(JArray image)
}
if (img is not null)
{
if (IsQwenImageEditPlus())
if (IsQwenImageEditPlus() || IsBoogu())
{
neg = imgNeg;
}
Expand Down Expand Up @@ -970,6 +970,10 @@ public string CreateKSampler(JArray model, JArray pos, JArray neg, JArray latent
defsampler ??= "lcm";
defscheduler ??= "simple";
}
else if (IsBoogu())
{
defscheduler ??= "simple";
}
// TODO: Registry of model default preferences instead of this
else if (IsFlux() || IsWanVideo() || IsWanVideo22() || IsOmniGen() || IsQwenImage() || IsZImage() || IsZetaChroma() || IsErnie() || IsHiDreamO1() || IsLens() || IsPixelDiT() || IsKrea2())
{
Expand Down Expand Up @@ -1301,7 +1305,7 @@ public JArray GetPromptImage(bool fixSize, bool promptSize = false, int index =
doesFit = false;
}
}
else if (IsQwenImageEditPlus() && promptSize)
else if ((IsBoogu() || IsQwenImageEditPlus()) && promptSize)
{
target = 384;
doesFit = false;
Expand Down Expand Up @@ -2345,7 +2349,7 @@ public JArray CreateConditioningDirect(string prompt, JArray clip, T2IModel mode
["text"] = prompt
}, id);
}
else if (IsIdeogram4() || IsKrea2())
else if (IsIdeogram4() || IsKrea2() || (IsBoogu() && isPositive))
{
JArray imageNode = GetPromptImage(true, true, 0);
for (int i = 1; i < 10; i++)
Expand Down Expand Up @@ -2373,7 +2377,7 @@ public JArray CreateConditioningDirect(string prompt, JArray clip, T2IModel mode
["target_height"] = height,
["guidance"] = UserInput.Get(T2IParamTypes.FluxGuidanceScale, defaultGuidance),
["images"] = imageNode,
["llama_template"] = "krea2" // TODO: Ideogram preferred template?
["llama_template"] = IsBoogu() ? null : "krea2" // TODO: Ideogram preferred template?
}, id);
}
else if (IsQwenImageEdit() && (isPositive || IsQwenImageEditPlus()) && (qwenImage = GetPromptImage(true, true)) is not null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ public bool IsQwenImageEditPlus()
/// <summary>Returns true if the current model is Krea 2.</summary>
public bool IsKrea2() => IsModelCompatClass(T2IModelClassSorter.CompatKrea2);

/// <summary>Returns true if the current model is Boogu.</summary>
public bool IsBoogu() => IsModelCompatClass(T2IModelClassSorter.CompatBoogu);

/// <summary>Returns true if the current model is Hunyuan Video (original / v1).</summary>
public bool IsHunyuanVideo() => IsModelCompatClass(T2IModelClassSorter.CompatHunyuanVideo);

Expand Down Expand Up @@ -1136,6 +1139,11 @@ public void LoadClip3(string type, string modelA, string modelB, string modelC)
helpers.LoadClip("krea2", helpers.GetQwen3vl_4bModel());
helpers.DoVaeLoader(UserInput.SourceSession?.User?.Settings?.VAEs?.DefaultQwenVAE, "qwen-image", "qwen-image-vae");
}
else if (IsBoogu())
{
helpers.LoadClip("boogu", helpers.GetQwen3vl_8bModel());
helpers.DoVaeLoader(UserInput.SourceSession?.User?.Settings?.VAEs?.DefaultFluxVAE, "flux-1", "flux-ae");
}
else if (IsFlux() && (LoadingClip is null || LoadingVAE is null || UserInput.Get(T2IParamTypes.T5XXLModel) is not null || UserInput.Get(T2IParamTypes.ClipLModel) is not null))
{
helpers.LoadClip2("flux", helpers.GetT5XXLModel(), helpers.GetClipLModel());
Expand Down Expand Up @@ -1419,7 +1427,7 @@ public void LoadClip3(string type, string modelA, string modelB, string modelC)
});
LoadingModel = [samplingNode, 0];
}
else if (IsZImage() || IsAceStep15() || IsAnima() || IsKrea2())
else if (IsZImage() || IsAceStep15() || IsAnima() || IsKrea2() || IsBoogu())
{
string samplingNode = CreateNode("ModelSamplingAuraFlow", new JObject()
{
Expand Down
9 changes: 8 additions & 1 deletion src/Text2Image/T2IModelClassSorter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ public static T2IModelCompatClass
CompatPixelDiT = RegisterCompat(new() { ID = "pixeldit", ShortCode = "PixDiT", LorasTargetTextEnc = false }),
CompatIdeogram4 = RegisterCompat(new() { ID = "ideogram-4", ShortCode = "Ideo4", LorasTargetTextEnc = false, VaeFamily = VaeFlux2 }),
CompatKrea2 = RegisterCompat(new() { ID = "krea-2", ShortCode = "Krea2", LorasTargetTextEnc = false, VaeFamily = VaeQwenImage }),
CompatBoogu = RegisterCompat(new() { ID = "boogu", ShortCode = "Boogu", LorasTargetTextEnc = false, VaeFamily = VaeFlux1 }),
// Audio models
CompatAceStep15 = RegisterCompat(new() { ID = "ace-step-1_5", ShortCode = "Ace15", IsAudioModel = true }),
// Obscure old random ones
Expand Down Expand Up @@ -236,7 +237,8 @@ bool isZImageLora(JObject h) => (hasLoraKey(h, "layers.0.adaLN_modulation.0") &&
bool isChromaRadiance(JObject h) => hasKey(h, "nerf_image_embedder.embedder.0.bias");
bool isPiD(JObject h) => h.ContainsKey("net.lq_proj.latent_proj.0.weight") && h.ContainsKey("net.pixel_blocks.0.attn.q_norm.weight") && h.ContainsKey("net.pixel_blocks.0.compress_to_attn.weight");
bool isPixelDiT(JObject h) => h.ContainsKey("core.pixel_embedder.proj.weight") && h.ContainsKey("core.pixel_blocks.0.attn.q_norm.weight") && h.ContainsKey("core.pixel_blocks.0.compress_to_attn.weight") && !isPiD(h);
bool isOmniGen(JObject h) => h.ContainsKey("time_caption_embed.timestep_embedder.linear_2.weight") && h.ContainsKey("context_refiner.0.attn.norm_k.weight");
bool isOmniGen(JObject h) => h.ContainsKey("time_caption_embed.timestep_embedder.linear_2.weight") && h.ContainsKey("context_refiner.0.attn.norm_k.weight") && !isBoogu(h);
bool isBoogu(JObject h) => hasKey(h, "double_stream_layers.0.img_instruct_attn.processor.img_to_q.weight") && hasKey(h, "double_stream_layers.0.img_instruct_attn.processor.instruct_to_q.weight");
bool isQwenImage(JObject h) => (h.ContainsKey("time_text_embed.timestep_embedder.linear_1.bias") && h.ContainsKey("img_in.bias") && (h.ContainsKey("transformer_blocks.0.attn.add_k_proj.bias") || h.ContainsKey("transformer_blocks.0.attn.add_qkv_proj.bias")))
|| (h.ContainsKey("model.diffusion_model.time_text_embed.timestep_embedder.linear_1.bias") && h.ContainsKey("model.diffusion_model.img_in.bias") && (h.ContainsKey("model.diffusion_model.transformer_blocks.0.attn.add_k_proj.bias") || h.ContainsKey("model.diffusion_model.transformer_blocks.0.attn.add_qkv_proj.bias")));
bool isQwenImageEdit2511(JObject h) => h.ContainsKey("__index_timestep_zero__");
Expand Down Expand Up @@ -865,6 +867,11 @@ JToken GetEmbeddingKey(JObject h)
{
return isLongcat(h);
}});
// ====================== Boogu ======================
Register(new() { ID = "boogu", CompatClass = CompatBoogu, Name = "Boogu", StandardWidth = 1024, StandardHeight = 1024, IsThisModelOfClass = (m, h) =>
{
return isBoogu(h);
}});
// ====================== Audio Models ======================
Register(new() { ID = "ace-step-1_5", CompatClass = CompatAceStep15, Name = "Ace Step 1.5", IsThisModelOfClass = (m, h) =>
{
Expand Down
Loading