Skip to content

perf(moss): reuse shared modulation slices - #2208

Merged
leejet merged 2 commits into
leejet:masterfrom
mirek190:perf/moss-split-modulation
Oct 25, 2026
Merged

leejet merged 2 commits into
leejet:masterfrom
mirek190:perf/moss-split-modulation

Conversation

@mirek190

@mirek190 mirek190 commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The model constructs the six shared modulation slices once per forward graph and reuses them across diffusion blocks. Their values and the arithmetic consuming them are unchanged. This application change works with the pinned ggml.

Applies independently to the current pinned ggml; no companion backend or submodule update is required.

Related Issue / Discussion

Prepared as an independent split of #2201 following the request for separate evaluation. This patch contains only the named application change. The previous combined application/backend speedup is not attributed to it.

Additional Information

Backend used for the companion measurements: leejet/ggml#16, at 2b1e3ee0d46213cbaa901d3f97008fc14013c9ff. The pinned-backend measurements do not include those changes.

Functional compatibility with pinned ggml is separate from performance with the companion fusions. The two backend comparisons below are reported independently.

Application Native generation (s) Denoising s/step Peak VRAM (GiB)
Unmodified application (pinned ggml), two-run mean 17.925 1.7345 17.04
modulation only 18.00 1.742 17.04
Application Native generation (s) Denoising s/step Peak VRAM (GiB)
Unmodified application (companion ggml), two-run mean 16.025 1.5450 17.04
modulation only 14.91 1.433 17.04

A synthetic 42-layer graph with 3x2 image latents and 11 text tokens reduced shared-modulation slices from 252 to 6 and total nodes from 2910 to 2418. This is a graph-structure result, not the node count of the measured CUDA image graph.

RTX 3090 (SM86), Windows, CUDA 12.4; MOSS-Image-SFT-Q8_0.gguf, Qwen3.5-9B-Q8_0.gguf, FLUX.2 VAE and external tokenizer; 1024x1024, 10 Euler steps, CFG 3, flow shift 5, seed 42, empty negative prompt and batch 1. Flash Attention and automatic placement enabled; SageAttention, CUDA Graphs, profiling and conditioning cache disabled.

Every case used a fresh server process, one warmup and one timed image. Each unmodified-application baseline was tested in two processes; each candidate in one. Native generation excludes startup and HTTP/PNG transfer. Denoising time is divided by ten. These samples do not establish statistical confidence; small timing differences are not claimed as speedups. Device-wide peak VRAM was sampled every 100 ms. Clocks and power settings were not changed.

All generated RGB pixels for this patch match the unmodified CUDA reference: zero changed pixels and zero maximum channel error. This establishes equality for the tested prompt/settings, not every model, GPU, seed, shape or offload configuration. No new Vulkan inference, multi-GPU, other-model or full regression testing is claimed. Local tests, model weights and binaries are excluded from the patch.

Prompt: A Victorian portrait of a closeup Scottish 60 years old man in a kilt, mountain nature and blue sky, sharp focus, DSLR, Fujifilm XT3, full body visible.

Application base: 95ff76230889898e1bf40058ba272a3699b50dc6. Pinned ggml: a5915eb0e47adef21c3f25b889a008925ea838c2. Companion backend, where used: 2b1e3ee0d46213cbaa901d3f97008fc14013c9ff.

Checklist

Published as an independent split of #2201. The branch was merge-checked against master a85db96aa5ce2c72bd5aec326f6c5c857839a50a; the generation measurements above remain based on 95ff76230889898e1bf40058ba272a3699b50dc6. No additional images were generated for publication.

Summary by CodeRabbit

  • Refactor
    • Updated internal model processing to reuse shared modulation data across diffusion blocks. The values and calculations remain unchanged, so generated results are not intended to differ.
  • Documentation
    • Added a note describing shared modulation and compatibility with the pinned ggml version.

@coderabbitai

coderabbitai Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 81ef87ab-e1e5-45a8-9362-a4b507ce6cac
Commits

Reviewing files that changed from the base of the PR and between a85db96 and f7877e7.

Files selected for processing: 2
  • docs/moss_image.md
  • src/model/diffusion/moss_image.hpp

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

Walkthrough

The model now slices shared modulation into six tensors and passes them to non-skipped diffusion blocks. The documentation describes the reuse and notes compatibility with the pinned ggml.

Changes: Shared modulation

Layer / File(s) Summary
Block modulation interface
src/model/diffusion/moss_image.hpp
Block::forward accepts an array of six modulation tensors and uses each entry.
Model modulation flow
src/model/diffusion/moss_image.hpp, docs/moss_image.md
Model::forward slices the shared modulation tensor, expands each slice into the graph when a graph is present, and passes the array to non-skipped blocks. The runner obtains its context with get_context(gf). The documentation describes the reuse and states that values and consuming arithmetic remain unchanged.

Priority: Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Refactor

Possibly related PRs

Suggested reviewers: leejet

Merge Risk: Minimal · up to f7877

No actionable merge-blocking risk is established for this change.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 1 files. (1 skipped: 1 … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title "perf(moss): reuse shared modulation slices" names the main change: the model builds six shared modulation slices once per forward graph and reuses them across diffusion blocks. It is short,…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The pull request includes all required template sections. It clearly describes the change, related discussion, verification data, limitations, and completed checklist.
Full details: Title check

Explanation

The title "perf(moss): reuse shared modulation slices" names the main change: the model builds six shared modulation slices once per forward graph and reuses them across diffusion blocks. It is short, specific, and matches the changeset in moss_image.hpp and the docs note. It omits the benchmark context, which is not needed for a title.

Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 1 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread docs/moss_image.md Outdated
<img src="../assets/moss/sft.png" />

Use dimensions divisible by 16. The default discrete scheduler uses the upstream time shift of 5. Use `--flow-shift` to override it. The negative CFG branch skips DiT layer 22 (zero-based), matching the upstream pipeline.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes to the documentation should be removed, as they are unnecessary.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@leejet
leejet merged commit 2a5f810 into leejet:master Oct 25, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants