Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
eb56483
idol: Idol's denoiser as a native Metal family, with tf-idol and its …
jayleaton Oct 31, 2026
6b1b074
contract: Idol's denoiser kernels through gates 1-5
jayleaton Oct 31, 2026
e99604c
idol: id_qk keeps a NaN norm as F.normalize does; the recipe and chan…
jayleaton Oct 31, 2026
3114e80
changelog: #1766 for Idol's denoiser
jayleaton Oct 31, 2026
427c746
idol: attention rounds P to fp16 before P V, so its denominator sums …
jayleaton Oct 31, 2026
94a0392
idol: the recipe names the tensor units' fp32 operand truncation (#1772)
jayleaton Oct 31, 2026
5d5e9fa
idol: the FLUX.2 VAE image encoder natively on Metal, in fp32, with t…
jayleaton Oct 31, 2026
c72a497
idol: native Metal octree and Gaussian decoders, tf-idol-decode
jayleaton Oct 31, 2026
5302c79
idol: register the decoders' nine Metal kernels with the kernel contract
jayleaton Oct 31, 2026
7824bf6
changelog: #1773 for Idol's decoders
jayleaton Oct 31, 2026
7747ed5
idol: the VAE recipe names the tensor units' fp32 operand truncation …
jayleaton Oct 31, 2026
b5a74eb
changelog: #1774 for Idol's VAE encoder
jayleaton Oct 31, 2026
4e5d028
idol: DINOv3 ViT-H+/16 image encoder on Metal, with tf-idol-dino and …
jayleaton Oct 31, 2026
61ea7b2
contract: Idol's DINOv3 kernels through gates 1-5; the recipe and cha…
jayleaton Oct 31, 2026
900b731
changelog: #1775 for Idol's DINOv3 encoder
jayleaton Oct 31, 2026
4d7de91
Merge branch 'idol-decoders' into idol-e2e
jayleaton Oct 31, 2026
169dc6e
Merge branch 'idol-vae' into idol-e2e
jayleaton Oct 31, 2026
8966bda
Merge branch 'idol-dino' into idol-e2e
jayleaton Oct 31, 2026
25b6e6f
idol: the vae case moves to idol_vae_case.py, as dino's did, so the m…
jayleaton Oct 31, 2026
8833534
idol: tf-idol-generate runs one picture end to end on Metal, both enc…
jayleaton Oct 31, 2026
192c4e9
changelog: #1780 for Idol end to end
jayleaton Oct 31, 2026
ee8343a
idol: BiRefNet background removal and preprocessing natively on Metal
jayleaton Oct 31, 2026
b0642cb
idol: tf-idol-generate takes a raw photo
jayleaton Oct 31, 2026
931d76c
changelog: #1787 for Idol's background removal
jayleaton Oct 31, 2026
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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ Each release's page on GitHub has its notes and measurements. See [the 1.0.0 rel

## Unreleased

- Idol (speridlabs/idol, image to 3D Gaussian splat), first step: its 0.37B denoiser runs natively on M5 Metal from the released checkpoint, the condition refiner once an image and all 50 guided steps on the GPU. On an M5 Ultra a forward takes 0.275 s against the publisher's SDK on torch MPS at 0.939 s, with a 1.84 GB peak footprint. Each step's velocities on the SDK's own input sit as close to an fp32 run as the SDK's own, and each joint block alone passes the same gate; `tf-idol` runs those gates from a case `tools/zig/idol_case.py` records. RePo's fp32 maps run as an fp16 hi/lo split on the tensor units, whose fp32 GEMM truncates its inputs to 10 mantissa bits (#1772). The image encoders and the decoders are not ported yet (#1766, fixes #1757). Thanks to @jayleaton.

- Idol's octree and Gaussian decoders now run natively on M5 Metal, from the denoiser's latent to the 3DGS PLY and camera. On an M5 Ultra, 262,144 Gaussians decode in 0.343 s against the SDK's 0.739 s, and 1,048,576 in 1.963 s against 4.653 s, at a 2.43 GB peak footprint against 5.64 GB. Given the SDK's probabilities and draws, every octree level's counts match, and the PLY's header and rows equal the SDK's. Both decoders sit as close to an fp32 run as the SDK's own; `tf-idol-decode` runs those gates from a `tools/zig/idol_case.py decode` case. The decoders' nine kernels are registered with the kernel contract (#1773, after #1766, for #1757). Thanks to @jayleaton.
- Idol's FLUX.2 VAE image encoder runs natively on Metal in fp32: one 1,024 x 1,024 picture to the denoiser's 4,101 condition rows, with the posterior's noise as an input. It is 0.185 s an encode on an M5 Ultra against 0.095 s for the SDK's bf16 encoder on torch MPS, and lies far closer to a float64 run: worst row 5.1e-5 against the SDK's 2.7e-2. `tf-idol-vae` gates it from a case `tools/zig/idol_case.py vae` records, with the ungated FLUX.2-klein-4B weights (#1774, after #1766, for #1757). Thanks to @jayleaton.
- Idol's DINOv3 ViT-H+/16 image encoder runs natively on M5 Metal: one 1024 x 1024 image to the denoiser's feature1 in bf16, as idol-sdk's ImageEncoder makes it, from the ungated timm weights (DINOv3 License), which `tools/zig/idol_case.py dino` shows to be Meta's gated checkpoint byte for byte and feature for feature. On an M5 Ultra an encode takes 0.120 s against the SDK's 0.261 s on torch MPS, with a 2.28 GB peak footprint. feature1 and each of the 32 blocks on torch's own input sit as close to a float32 ruler as torch's bf16 run, within the 2x gate; `tf-idol-dino` runs those gates, and its eight kernels pass the kernel contract (#1775, after #1766, for #1757). Thanks to @jayleaton.
- Idol runs end to end natively on M5 Metal: `tf-idol-generate` takes one preprocessed picture through DINOv3, the FLUX.2 VAE, the denoiser's 50 guided steps and both decoders to a 3DGS PLY and camera. On an M5 Ultra it is 29.1 s against 95.4 s for the SDK's IdolPipeline on MPS (excluding its preprocess), the denoiser 27.5 s against 93.9 s, at a 2.71 GB peak footprint against 12.88 GB. Given the SDK's starting and VAE noise the PLY's points sit as close to the SDK's as sampling resolves, and the camera's angles within 0.006 rad (#1780, after #1773, #1774 and #1775, for #1757). Thanks to @jayleaton.
- Idol's background removal and preprocessing run natively too: `tf-idol-generate` now takes a raw photo (`.png`, `.jpg`, `.jpeg` or `.webp`), with `--mode synthetic|real` and `--crop-margin X`, writes the picture the encoders saw as `preprocessed.png`, and adds `preprocess_s` and `birefnet_s` to its JSON. BiRefNet (MIT, from the Idol snapshot) runs in fp32 on Metal in 0.172 s against the SDK's 0.48 to 0.52 s preprocess, its logits within torch's own distance from a float64 ruler; Pillow's resizes, the erosion, crop and paste are byte for byte the SDK's, and the preprocessed picture differs from the SDK's in 2 pixels by 1. From a photo a generation takes 30.1 s against the SDK's 101.3 s at a 2.77 GB peak footprint against 12.88 GB (#1787, after #1780, for #1757). Thanks to @jayleaton.

- DeepSeek-V4.x: `tool_choice: "required"` and named tool calls are now constrained to the model's own DSML call markup, so those requests are held to a valid call on DeepSeek too.

- Qwen3.6-35B-A3B on CUDA: `--drafter` also takes a DFlash2 draft model, chosen by the `dflash_config` in its `config.json`; the checkpoint's own directory still drafts with its MTP layer. With `incoai/Qwen3.6-35B-A3B-DFlash2` over `nvidia/Qwen3.6-35B-A3B-NVFP4`, one GB10 decodes 130 tok/s at one stream on a 4.2K-token prompt (MTP: 99), and every drafted reply equals its plain run.
Expand Down
16 changes: 16 additions & 0 deletions docs/kernel-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,22 @@ CUDA also checks `dense_rows`' scaled epilogue (Dory's logits, fp32(bf16(x . w))
unscaled tile's outputs rounded and scaled on the host.
HIP: the RMS norm rows, a wave a row (fp32, fp16 and bf16 out) and a block a row (fp16 and bf16 out).

Metal also checks Idol's denoiser (`metal_idol*.zig`): its fp16 projections and GELU form, the split-K fp32 rows,
`id_gemm32` (true fp32 sums: the NAX fp32 path in its place is a control gate 4 must catch), the LayerNorms, RePo's
angles, the heads, the elementwise steps and the attention's four forms, each at idol-sdk's fp16 points (19 controls).
Its decoders' own kernels (`metal_idol_decoder*.zig`) are checked too: the point embedding, the stem's fp16 cast,
`to_kv`, the heads' RMS norm, the attention's four forms (P V as fp16 P hi + lo) and its fp32 short form. Each is checked
at idol-sdk's fp32 and fp16 points, with 15 controls. One drops P's lo half and must go red on heads built so that O is
P's fp16 remainder alone.
Its image encoder (`metal_idol_vae*.zig`, FLUX.2's VAE encoder in fp32) registers its convolutions (direct, implicit
GEMM and Winograd), GroupNorm's passes, the 512-wide attention and the condition rows against float64 (12 controls).
Metal also checks Idol's DINOv3 encoder (`metal_idol_dino*.zig`): its bf16 projections, LayerNorm and final F.layer_norm,
the RoPE heads, LayerScale with the residual, SwiGLU and the attention, each at transformers' bf16 points (11 controls).
Its background remover (`metal_idol_birefnet*.zig`, BiRefNet in fp32) registers the implicit GEMM convolution's nine
served forms (1x1, 3x3, 7x7; batch norm, ReLU, exact GELU, residual by a window map), the picture's 3x3, LayerNorm by
rows, by window map and as PatchMerging's gather, the shifted windows' attention, the align_corners resize, the patch
and tile copies, the modulated deformable columns, the pool, the gate and the head against float64 (21 controls).

RADIO's fused bias, activation and residual (`tf_vit_bias_act`) replaces `tf_vit_bias` then
`tf_vit_pointwise`, byte for byte.
CUDA also checks GLM-5.3-Flash's KV page kernels on a page table out of order: the latent write and the pooled keys
Expand Down
Loading