Repository navigation
Conversation
…reference case tool
Every pipeline of idol.metal and idol_attention.metal is registered: id_linear's eight forms (plain and GELU), id_split's two, id_gemm32, id_norm (plain, affine, modulated), id_norm32 (affine, modulated), id_norm_split, id_repo, id_qk, id_gate_add, id_embed, id_cond, id_bias32 and the attention's four forms. Each output is checked at idol-sdk's fp16 points as the range its fp32 steps allow; the NAX projections against the tensor unit's 16-deep step bound, the attention against attention_ref's formula with P at the tensor unit's fp32. Inputs at the large served shapes repeat at periods prime to every tile, so float64 stays cheap and every output is checked. 19 controls: rounding points dropped or added (gate 3), fp16 sums in id_norm32, id_repo, id_qk, id_embed and id_gemm32, and the NAX fp32 path in id_gemm32's place (gate 4), and the attention's tail keys unmasked. Gate 5 holds the 24 launches, each reserved by its source. Known finding: id_qk gives a head holding a NaN +-inf in its other outputs where F.normalize gives NaN, as Metal's max drops the NaN norm that clamp_min keeps.
…the values the units multiply
…idol_case.py dino The denoiser's feature1 [4101, 1280] from the SDK's 1024 x 1024 image, as idol-sdk's ImageEncoder makes it: transformers' DINOv3ViTModel in bf16, its last_hidden_state, then F.layer_norm in fp32. Weights from the ungated timm/vit_huge_plus_patch16_dinov3.lvd1689m (DINOv3 License), rounded to bf16 at load. Patch conv as one GEMM, class token and four registers, 2D RoPE on the patches (transformers' fp32 periods, tables bit-equal to torch's), 32 blocks of 20 heads of 64 with LayerScale and SwiGLU, rounded where torch on MPS rounds (measured): one rounding a linear or norm, two for SiLU times up and LayerScale with the residual, three for the rotary. The attention rounds P to bf16 itself. idol_case.py dino pins idol-sdk's conditioning.py, transformers 5.22.1's DINOv3 files and the weights by sha256, and writes the SDK's feature1 on MPS, a float32 CPU ruler, every block's rows and each block in float32. With --official it proves timm's weights Meta's: 550 tensors byte for byte, feature1 bit for bit. On the avocado: feature1 worst row against float32 0.1353 (torch 0.1686), 1 - cos 5.37e-5 (5.57e-5); every block on torch's own input within the 2x gate; repeat byte-identical; 0.120 s an encode against the SDK's 0.261 s on MPS.
…ngelog line Every pipeline of idol_dino.metal is registered: dn_linear_0 and dn_linear_1, dn_norm, dn_final, dn_heads, dn_scale_add, dn_swiglu and dn_attention, each checked at transformers' bf16 points. 11 controls: a bf16 rounding added or dropped (gate 3), fp16 sums in dn_norm and dn_final and P V rounded to bf16 each key block (gate 4), the attention's tail keys unmasked. Gate 5 holds the 8 launches, each reserved by its source. SUMMARY 8 kernels: 8 pass gates 1-4, 0 fail, 0 known findings; 11 controls: 11 red as planted, 0 missed; 0 limit problems
This was referenced Oct 31, 2026
Owner
|
Thanks @jayleaton. All 32 blocks pass alone, and the check that timm's file equals Meta's byte for byte is exactly the evidence we needed for the weights. The DINOv3 License terms are fine for us, as the recipe documents them. It waits on #1766; please rebase after it lands, and we'll run |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #1766 (Idol's denoiser on Metal). This branch holds #1766's commits too; its own change is the last two commits. Independent of #1767, #1773 and #1774.
What this changes
Idol's DINOv3 ViT-H+/16 image encoder on Metal: the SDK's 1024 x 1024 preprocessed image to the denoiser's
feature1[4101, 1280] (class token, four registers, 64 x 64 patches), as idol-sdk'sImageEncoderbuilds it, withtf-idol-dinoand anidol_case.py dinocase. For #1757. Details: the "DINOv3 encoder" part ofdocs/recipes/idol.md.DINOv3ViTModelin bf16 (dinov3_dtype='bf16', the pipeline's default), itslast_hidden_state(the model's own final LayerNorm), then a plain fp32F.layer_norm(eps 1e-5, no affine).zig/kernels/metal/idol_dino.metal, eight kernels of Idol's own. No shared kernel changes. Attention keeps fp32 scores and sums and rounds P to bf16 itself before P V, summing the denominator over those values (M5 tensor units truncate fp32 operands to 10 mantissa bits: gemm_nax<float> is not fp32, and attention_nax's outputs are biased low #1772).Weights and licence
timm/vit_huge_plus_patch16_dinov3.lvd1689matdd0addc09788111fa893d24799a44744ba022eee, ungated, rounded to bf16 at load asfrom_pretrained(dtype=bfloat16)rounds. These weights are under Meta's DINOv3 License, not Apache 2.0 (itsLICENSE.mdships with them); the recipe says so.The SDK reads Meta's gated
facebook/dinov3-vith16plus-pretrain-lvd1689m.idol_case.py dino --official DIRchecks that timm's file is the same model: all 550 mapped tensors (the 32 fused qkv weights as 96 thirds) equal Meta's byte for byte, Meta's q and v biases are all zero, and its only other unmapped tensor ismask_token. feature1 from timm's weights equals feature1 from Meta'sfrom_pretrainedbit for bit on MPS, and both equal the features the SDK pipeline recorded for the image.Precision
The kernels round where torch on MPS rounds, measured on random bf16 operands against float64: a linear once after its bias, LayerNorm once,
silu(g) * utwice, the rotary three times, LayerScale with the residual twice; fp32 sums and statistics. torch's bf16 SDPA on MPS matches no candidate rounding scheme (it sits about three times a bf16 rounding from the exact output), so the attention is gated on distance, not bits.Kernel contract
zig/tests/contract/metal_idol_dino*.zig:dn_linear_0,dn_linear_1,dn_norm,dn_final,dn_heads,dn_scale_add,dn_swiglu,dn_attention, each at transformers' bf16 points, with eleven controls (a bf16 rounding added or dropped, fp16 sums in the norms, P V rounded to bf16 each key block, the attention's tail keys unmasked).Receipt
94a039249; idol-sdk4702a7f0on torch 2.13.0 (MPS,ATTN_BACKEND=sdpa), transformers 5.22.1 (sha256-pinned DINOv3 files); the SDK's preprocessed avocado example.1 - cos:1 - cos5.37e-5, torch's 5.57e-5. Against the SDK's own features: cosine 0.999954, worst row 0.109;1 - costorch's times 0.84 to 1.06;dino_reference.zig's test plants a 2% error in one row and the gate fails it, though cosine alone would pass./usr/bin/time -l), 1.68 GB of it the bf16 weights; the SDK's MPS encode holds 2.24 GB of driver memory.zig build test test-golden -Dcpu=apple_m1: 585 of 585 steps, 0 fail; goldens 55 of 55 and 322 of 335, 0 unexpected differences (before the rebase onto94a039249, a docs-only change; after it, plainzig build248 of 248).zig fmt --check build.zig zig: clean.lean_check.py: 424, the same as main.Checklist
"draft": false, a resumed prompt equals a fresh one, and concurrent equals solo. (n/a.)SUMMARYline is in the receipt.