Repository navigation
moss_image: MOSS-Image-Base's transformer on the Metal runtime (new family, denoiser) - #1457
BobClawblaw wants to merge 6 commits into
Conversation
|
Thanks @BobClawblaw, this is a tidy component. It changes no shared kernel source, its eleven kernels are in the contract with planted controls, and it reads the released bf16 weights as published. It's also checked step by step against the publisher's own pipeline. On main A few small things:
We'll run the contract and one |
41790d9 to
88626eb
Compare
|
Thanks, Ash. All three points are fixed in
On the M5 Ultra, the rebased A correction to one claim in the description. The "closer to float32 in 6 of 8" ruler ran the transformer in float32 but kept torch's bf16 encoder rows. With the encoder in float32 too ( |
zig/src/families/moss_image runs MOSS-Image-Base's 5B joint transformer from the released bf16 diffusers checkpoint. A prompt's rows go through the input projection and the two refiner blocks once. At each step the image and prompt rows go through every joint block together, under one modulation from the timestep. The card's guidance runs two passes a step, the second with the empty negative prompt and block 22 skipped. Activations are bf16, rounded once per elementwise op as the publisher's torch code rounds them. Every sum is fp32, and there is no int8. Biased projections take fp32 sums from the prefill split-K GEMM (one part), then add the bias and round once, as a bf16 GEMM's bias epilogue does. The bf16 projections reuse the Qwen-VL tower's tfp::gemm_nax, and attention reuses the prefill tfp::attention_nax template in its full form. The time MLP and the modulation run on the host once a timestep, with the sinusoid in float64. tf-moss-image checks the transformer against a case from tools/zig/moss_image_case.py, which runs the publisher's own pipeline_moss_image.py (prompt encoder, transformer, scheduler, decoder) in torch. The case holds both branches' velocities at every step on the pipeline's own input; then the whole guided schedule runs and is timed. A case from `start` holds only the prompts, the schedule and the noise, and makes a picture. Gate 5 holds the family's 11 launches.
…s tensor units required mi_norm (plain and modulated), mi_qk (both row layouts), mi_situ (both), mi_gate_add, mi_bias and the three attention forms, each output checked at the bf16 points the publisher's torch code rounds at; eight controls each drop or add one rounding point and must go red at gate 3. The launches move to kernels.zig so the tests run the engine's own dispatch. mi_attention_10 goes: no L picks it. The family is qualified on the M5 alone and refuses a GPU without tensor units.
tf-moss-image no longer leaks the first prompt when the second fails, Model.load says why it refuses a GPU without tensor units, and moss_image_case.py imports the checkpoint's pipeline_moss_image.py only when its sha256 is the pinned revision's (the docs say so, with the download line).
… and with the encoder in float32
88626eb to
6aa5937
Compare
|
A small update: the head is now On the M5 Ultra, the rebased head still gives the fox case's byte-identical latents, and |
|
Thanks @BobClawblaw, all three are in.
We merged it onto current main. fmt and lean are clean, One small thing for the recipe: Next we'll run |
…'s follow-up tool
|
Thanks, Ash. You're right: this tree's |
|
Landed on main with your authorship (e82837273 onwards, 2551c57 with the changelog). On our M5 Ultra: |
What this changes
Fixes #1456. Adds
moss_image: MOSS-Image-Base's 5B joint transformer as a native Metal denoiser, from the released bf16 checkpoint as published. It is the same kind of component as Qwen-Image's (#948). The prompt encoder (Qwen3.5) and the image decoder are not ported:tools/zig/moss_image_case.pyruns them through the publisher's ownpipeline_moss_image.pyto prepare cases and decode pictures. The family does not register with the lane engine, the server orfamilies.detect.zig/src/families/moss_image(config check, weights, host time MLP and modulation, launches, model), and its kernels inzig/kernels/metal/moss_image.metal.tfp::gemm_naxand the prefill split-K GEMM (fp32 sums for the biased projections). Attention istfp::attention_naxin its full (non-causal) form. No shared kernel changes.tf-moss-imagechecks both guidance branches of every step against the publisher's pipeline on the same inputs, then runs and times the whole guided schedule.Receipt
772283b6b(code) on mainb30d5b9d3.OpenMOSS-Team/MOSS-Image-Base@85975793d8b3d432f1b6e27f352abaa4c2a4c0d3.exact --fp32-encoder, a follow-up tool that this PR's case tool does not have; it comes with the prompt encoder, moss_image: the Qwen3.5 prompt encoder as a native Metal forward #1459), torch bf16 averages 32.5 dB and ours 31.2 dB: six cases are within 0.5 dB or favor ours, and two sticky-note seeds favor torch's by 4.6 and 8.7 dB. Those 8 ran on an earlier build of this family (0b69e127); this head gives byte-identical latents on both cases above.tf-kernel-contract --only "moss image"on the M5 Ultra:mi_norm(plain and modulated),mi_qk(separate and packed q k v rows),mi_situ(both layouts),mi_gate_add(in place),mi_bias, and the attention's three forms.attention_ref's float64 formula and bf16-P bound. Its gate 4 uses equal scores over values whose sums reach about 2^22 and cancel.--offlinecannot compile the tensor-op source for M1/M2 (N/A, as for FSR's tensor kernels), and the family refuses those chips.zig build test,test-golden,test-kernel-contract,test-server-security test-pull-security,fuzz-cortheon,dev-tools -Doptimize=Debug.zig fmt --check build.zig zig.tools/zig/lean_check.py: 428 problems, the same as main.tf-kernel-contractneeds atf-rotary-sweepreceipt for this macOS compiler (FlashNext's rotary probes), unrelated to this change.atc overlap: four LFM2 pull requests (#1377, #1391, #1393, #1394) touch the same registration lists (sources.zig,registry.zig,metal_main.zig). Each conflict is one appended line, for whichever lands second.A recipe that builds this head and makes pictures with the publisher's encoder and decoder: https://github.com/BobClawblaw/moss-image-base-bf16-m5-ultra
Checklist
"draft": false, a resumed prompt equals a fresh one, and concurrent equals solo. (n/a: no drafts, prompt state or concurrency)SUMMARYline is in the receipt.