Skip to content

Atlas step 1: atlas-embed embedder parity spike — Gate A (#5351) - #5367

Merged
dezren39 merged 1 commit into
mainfrom
atlas-step1-embed
Nov 4, 2026
Merged

dezren39 merged 1 commit into
mainfrom
atlas-step1-embed

Conversation

@dezren39

@dezren39 dezren39 commented Nov 4, 2026 •

Copy link
Copy Markdown
Member

Step 1 of the Atlas binary+service epic (#5350), per the design of record (doc/2026-11-04T08-07-13Z_design_atlas_binary_service/ §4/§5). Implements #5351.

What lands

  • pkgs/atlas-search/ skeleton: Cargo workspace + rust-toolchain.toml pin (1.99.0, pkgs/id pattern), with the atlas-embed crate only. No CLI, no serve mode, no nix packaging (step 5).
  • atlas-embed: dynamically-loaded ONNX Runtime (ort 2.0.0-rc.15, load-dynamic — nothing downloaded at build or run time), the model's own tokenizer.json (SentencePiece Unigram, Metaspace) via tokenizers 0.22, shipped 512-token truncation default explicitly disabled (context 8192, loud error beyond), CLS pooling, full-768 f32, documents prompt-free. Lazy init is left to callers (explicit Embedder::load).
  • Fixtures + recorded generator: fixtures/embed-probes.json (token ids + f32-bit vectors, single and one fixed mixed batch) from the production Python corpus pipeline (~/atlas/v3/embed_onnx.py replicated exactly by fixtures/gen_fixtures.py). 11 probes: the five opencode#1554 spike texts, an empty string, the Atlas gate chunks 6359/15202/39430 (referenced by corpus id — their text is personal corpus content and is not copied into the repo), a 711-token corpus chunk (id 2, proves no silent truncation), and a query-shaped sentence in document mode.

Gate A — PASSED, bit-identical

Run on the laptop (never the sandbox), pinned 1.99.0 toolchain, debug and release:

probe tokens ids single max Δ (bit diffs) batch max Δ (bit diffs)
spike_fox 15 ok 0.0 (0) 0.0 (0)
spike_query_prefix 12 ok 0.0 (0) 0.0 (0)
spike_semantic 31 ok 0.0 (0) 0.0 (0)
spike_single_char 3 ok 0.0 (0) 0.0 (0)
spike_japanese 41 ok 0.0 (0) 0.0 (0)
spike_empty 2 ok 0.0 (0) 0.0 (0)
corpus_6359 57 recorded 0.0 (0) 0.0 (0)
corpus_15202 303 recorded 0.0 (0) 0.0 (0)
corpus_39430 1272 recorded 0.0 (0) 0.0 (0)
corpus_long (chunk 2) 711 recorded 0.0 (0) 0.0 (0)
query_style 13 ok 0.0 (0) 0.0 (0)

Unit tests pass; clippy clean (0 warnings); fmt clean. The gate test is #[ignore]d (it needs the model + runtime lib) with the exact invocation in its docs, so ordinary CI compiles everything and the gate runs as a laptop ceremony.

Findings worth carrying forward

  • Padding is provably inert on this fp32 graph. The corpus pipeline pads with id 0 (np.zeros), the fork's sidecar with id 1; the generator's diagnostic shows max delta 0.0 between them on every probe (the int8 graph was the padding-sensitive one). The crate replicates the corpus pipeline's 0.
  • The norm's accumulation order is load-bearing in principle: l2_normalize replicates NumPy's pairwise summation (the reference is vecs / np.linalg.norm(...)). It hit 0.0 with the faithful replica in place.
  • ort rc.15 needs &mut self for Session::run — serve mode (step 4) must wrap the embedder in a mutex or use one session per worker; there is no shared-&self run in this version.
  • Spike environment, stated plainly: the gate ran with the venv's libonnxruntime.so.1.31.1 dynamically loaded and an x86-64 libstdc++/libz on LD_LIBRARY_PATH — NOT the hermetic nix closure; that is step 5's (Atlas step 5: nix packaging (pkgs/atlas-search) + amd deploy #5355) gate.
  • Toolchain trap found: the laptop's user-wide sccache rustc-wrapper serves stale cross-toolchain artifacts when switching rustc versions (E0514). All verification above ran with RUSTC_WRAPPER= under the pinned rustup 1.99.0 toolchain (PATH clippy-driver otherwise shadows from the nix profile).
  • Timing (release, under concurrent nix-build load on the laptop — treat as upper bounds): embedder load 7.4 s; resident RSS ~1.64 GB (the fp32 graph; the int8 graph would be ~4× lighter but parity is defined against the fp32 corpus pipeline); warm single 15-token embed ~118 ms; ~362-token embed ~1.3 s. Serve-mode sizing in step 4 should use the RSS figure.

Model pin used

  • Snowflake/snowflake-arctic-embed-m-v2.0 @ HF rev 95c2741480856aa9666782eb4afe11959938017f (the laptop's existing snapshot; deploy-time provisioning is Q1/step 5)
  • onnx/model.onnx sha256 c0c53d7f49a2db60761b92b7bbf5be87a7b3cf5d92dbbd7f1b5028bd5a40aa39
  • tokenizer.json sha256 f1cc44ad7faaeec47241864835473fd5403f2da94673f3f764a77ebcb0a803ec
  • Reference pipeline: onnxruntime 1.31.1, transformers 5.21.0, python-tokenizers 0.23.3, threads intra 8 / inter 2

Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.

Create the pkgs/atlas-search/ skeleton (workspace + rust-toolchain
pin on the pkgs/id pattern) with the atlas-embed crate only:

- Snowflake arctic-embed-m-v2.0 embedder: dynamically-loaded ONNX
  Runtime (ort load-dynamic, never downloaded at build/run time),
  the model's own tokenizer.json (SentencePiece Unigram, Metaspace)
  via the tokenizers crate with the shipped 512 truncation default
  explicitly disabled (model context 8192, loud error beyond),
  CLS pooling, full-768 f32 output, documents prompt-free.
- Batching replicates the production corpus pipeline
  (~/atlas/v3/embed_onnx.py): right-pad with token id 0, attention
  mask 0. The fork sidecar's pad id 1 is bit-identical on this fp32
  graph (fixture diagnostic, max delta 0.0 on every probe), so the
  corpus pipeline's semantics are the ones recorded.
- The L2 norm replicates NumPy's pairwise summation order — the
  reference does vecs / np.linalg.norm(vecs, axis=1) and Gate A
  grants no tolerance for a differently-ordered accumulation.

Gate A: fixtures/embed-probes.json records token ids + f32-bit
vectors (single and one fixed mixed batch) from the Python pipeline
for 11 probes — the five opencode#1554 spike texts, an empty string,
the three Atlas gate chunks (6359/15202/39430, by corpus id; text
not copied, it is personal corpus content), a 711-token corpus
chunk (chunk 2, proves no silent truncation), and a query-shaped
sentence in document mode. Generated by the recorded, rerunnable
fixtures/gen_fixtures.py.

Result (laptop, pinned 1.99.0 toolchain): token ids equal on every
text probe; vectors bit-identical (max delta 0.0, 0 bit diffs)
single and batched, debug and release. Model: HF rev
95c2741480856aa9666782eb4afe11959938017f, onnx/model.onnx sha256
c0c53d7f49a2db60761b92b7bbf5be87a7b3cf5d92dbbd7f1b5028bd5a40aa39,
tokenizer.json sha256
f1cc44ad7faaeec47241864835473fd5403f2da94673f3f764a77ebcb0a803ec,
against onnxruntime 1.31.1 (the venv's libonnxruntime, dynamically
loaded — the spike environment; the hermetic nix closure is step
5's gate, #5355).

Nix packaging (flake.nix/default.nix) intentionally lands in
step 5; this step is the parity spike only.
@dezren39
dezren39 requested a review from a team as a code owner November 4, 2026 08:56
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-04T08:58:14.654689Z 1dba9d2 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Nov 4, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 48 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3b68fab8-2d7a-47b2-8650-1add7c6fd37f
Commits

Reviewing files that changed from the base of the PR and between fd961f6 and 1dba9d2.

Files ignored due to path filters: 1
  • pkgs/atlas-search/Cargo.lock is excluded by !**/*.lock
Files selected for processing: 10
  • pkgs/atlas-search/.gitignore
  • pkgs/atlas-search/Cargo.toml
  • pkgs/atlas-search/crates/atlas-embed/Cargo.toml
  • pkgs/atlas-search/crates/atlas-embed/examples/timing.rs
  • pkgs/atlas-search/crates/atlas-embed/src/lib.rs
  • pkgs/atlas-search/crates/atlas-embed/tests/gate_a.rs
  • pkgs/atlas-search/fixtures/README.md
  • pkgs/atlas-search/fixtures/embed-probes.json
  • pkgs/atlas-search/fixtures/gen_fixtures.py
  • pkgs/atlas-search/rust-toolchain.toml
  • 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

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.

1 participant