Skip to main content

embroider — Jina v5 text embeddings (Rust core, PyO3)

CI crates.io docs.rs PyPI Python License

embroider turns text into vectors — Jina v5 embeddings served through ONNX Runtime from a Rust core, with optional PyO3 bindings for Python. One frozen contract covers the whole path: task prefix → tokenize → ONNX forward → last-token pooling → L2 → Matryoshka truncate → re-normalise, so every consumer lands in the same vector space.

One engine, two consumers: bobine (PDF/Office → Markdown) reuses the ONNX plumbing, okfgraph uses the full Jina v5 text-embedding contract. It began as a clean move out of OKFgraph's rust/okf-embed — an exact port of EmbeddingEngine._encode — and stays pinned against a numpy/transformers replication by OKFgraph's parity harness (tests/test_parity.py, max abs diff ≤ 1e-5).

Single backend, kept comparable: one lean runtime with no torch / transformers / optimum in the hot path, so every vector in an index stays directly comparable. If something can't be embedded exactly to contract, embroider errors loudly rather than quietly mixing vector spaces.

Install

PyPI wheels (Linux / Windows / macOS-arm64, Python 3.11–3.13) — okfgraph pulls it in automatically; standalone:

pip install embroider

From source (Rust toolchain + maturin; maturin develop needs pip, which uv venvs lack — build the wheel and install it instead):

maturin build --release
uv pip install --python <venv> target/wheels/embroider-*.whl --reinstall

Module layout

Module Role
providers provider-name matrix (cuda/rocm/directml/openvino/coreml + implicit cpu) + clone-and-fallback application (apply_providers = arena on; apply_providers_with_arena carries the flag)
probe corrected CUDA availability check (OnceLock-cached)
policy DeviceReq (auto/cpu/cuda) + Precision (auto/fp32/fp16) + explicit SessionPolicy (text_embed() vs ort_defaults())
acquire validated owner/name parsing, HF client, tokenizer-only fetch, FP16-mirror selection for the default id
error anyhow-based error plumbing (ort errors stringified at boundaries)
diag OrtReport — ORT_DYLIB_PATH value + CUDA usability for logs
jina JinaV5 + TokenizerHandle — the frozen embedding contract

The default (pure-Rust) build is Python-free — no pyo3 in downstream trees; the extension-module Cargo feature gates the PyO3 bindings and is enabled only for wheel builds (maturin), the same pattern bobine uses.

Runtime: ONNX Runtime discovery

ort loads dynamically (load-dynamic, same pin as bobine: 2.0.0-rc.13). Resolution order: ORT_DYLIB_PATH first (user override always wins), else the pip-installed onnxruntime/onnxruntime-gpu build when unset. okfgraph's resolve_ort_dylib() runs before the native module is imported, so bobine and embroider share one ORT binary — no version/CUDA drift between ingest and import.

Lifecycle: lazy session, cheap tokenizer

JinaV5.open (model download + ONNX session build) is the single expensive step. OKFgraph therefore holds a lazy proxy: construction validates the wheel import and device string eagerly, but the session opens on the first real encode — PPR search, budgeted reads, diff, and doctor stay cold.

JinaV5.open(model_id, revision=None, cache_dir=None, truncate_dim=512, device="auto", max_length=None, precision=None, cpu_arena=False): max_length caps encodes at 1..=32768 (None = 8192 compat default; .max_length reports the effective limit), precision selects weights (auto/fp32/fp16, None = auto; .precision reports the effective choice), cpu_arena=False disables the CPU arena allocator (8x lower peak RSS for ~1.4x encode time, measured on the FP32 text model).

JinaTokenizer.open fetches only tokenizer.json for exact token counts without the session. It never truncates, so counts report true length — JinaV5.count_tokens() instead reflects the session's max_length. A failed session open is cached and re-raised — configuration errors fail fast once, not once per encode.

Weight precision (auto by default)

auto follows the resolved device (CUDA → FP16, CPU → FP32), so CUDA-requested-but-missing degrades to FP32 weights instead of stranding FP16 on CPU (FP16-on-CPU runs >40x slower than FP32-CPU — measured). fp16 maps the default model id to the published FP16 mirror repo (opticsWolf/jina-embeddings-v5-text-small-retrieval-onnx-fp16); explicit model ids (omni tower, mirrors) always win untouched. An explicit fp16-on-CPU warns loudly but is honoured. Do not mix precisions in one index — FP32 vs FP16 weights shift vectors, same as mixing tuning levels.

Memory: CPU arena off by default

cpu_arena=False registers the CPU execution provider explicitly with its arena allocator disabled — measured 8x lower peak RSS (15.3 → 1.9 GB on FP32) for ~1.4x encode time. Pass True only when peak throughput beats memory pressure.

Explicit local files (air-gapped)

JinaV5.open_files(onnx_path, tokenizer_path, truncate_dim=512, device="auto", max_length=None, cpu_arena=False) and JinaTokenizer.open_files(tokenizer_path) skip every download. The sidecar (model.onnx_data-style) must sit next to the ONNX file — ORT resolves it relative to the model path, same as the HF cache layout. Precision selection does not apply here — the files are what they are (reported precision reads fp32; pass FP16 files explicitly for FP16 weights). OKFgraph's OKFRouter(model_path=..., tokenizer_path=...) uses them (both or neither; missing files raise FileNotFoundError at construction). Same bytes in → same vectors out (test-pinned against HF acquisition).

Session/threading policy (measured)

Tuning is Level3, intra = physical-cores/2, inter = 1 — kept because it measured fastest, not because it was inherited. Reference box: Windows, 32 logical cores, CPU-only ORT 1.29, warm model cache, best-of-5 reps on 4 fixed docs (short → ~400 tokens):

Config Session cold open encode_batch (4 docs) Notes
Level3, intra=16, inter=1 (current) 4.7 s 375 ms kept
Level1, intra=16, inter=1 5.5 s 433 ms (+15%) slower and bit-different vectors
Level3, intra=32, inter=1 4.5 s 411 ms (+10%) full-logical loses to phys/2 (SMT contention)
4× encode_one vs 1× encode_batch — 389 vs 375 ms one boundary crossing saves ~3%; sequential stays
Tokenizer-only cold open 0.5 s — 9× cheaper than session open; budgeted reads stay cold

Two consequences:

  • Do not mix tuning in one index. Level1 vs Level3 fuse the graph differently, so bits differ (hashes diverged at 1e-8 formatting). Same model + same build + same tuning, or re-embed.
  • Sequential batching stays. Padded batching would waste attention on variable-length docs to save ~14 ms of boundary overhead — not worth the numerics risk.

SessionPolicy::ort_defaults() exists for consumers (bobine's vision sessions) that never tuned — policy is data, never a forced default. Re-measure on new hardware/ORT before changing the policy.

Pitfall: stale onnxruntime.dll on Windows

Windows boxes can carry a stale C:\Windows\System32\onnxruntime.dll (v1.17.1 in the wild). With ORT_DYLIB_PATH unset, ort may load it and die with BadVersion { version_str: "1.17.1" }, followed by an abort at shutdown (fallout from ort's exit handler, not the root cause). Point ORT_DYLIB_PATH at a modern build — e.g. the venv's onnxruntime/capi/onnxruntime.dll. Same pitfall bobine documents in its docs/benchmarks.md.

Failure policy

Level Behaviour
Install The wheel is a core dependency of the consumer; if it is missing or fails to import, the consumer raises a clear RuntimeError with the install hint — never an ImportError from deep inside, never a silent fallback.
Device Accelerators are opportunistic: auto/cuda use CUDA when the loaded ORT registers the EP, else warn (stderr) + CPU. used_cuda reports the outcome. Never fatal. Unknown provider names warn and are skipped; registration failure degrades to CPU. precision='auto' follows the landed device (CUDA→FP16, CPU→FP32); explicit fp16-on-CPU warns but is honoured.
Encode Fail fast. No fallback at encode time — vectors must stay bit-comparable within one index.
Tokenizer No transformers in the runtime path, anywhere: internal tokenize + count_tokens() (== tokenizer.encode(t, add_special_tokens=False)) feed the context-window guard.

Contract notes

  • Session IO is discovered at load (input_ids + attention_mask required, token_type_ids fed only if declared — v5's export doesn't declare it, which is where generic runners fail). Output prefers last_hidden_state.
  • truncate_dim validated (32–1024, warning off the Matryoshka ladder). max_length validated (1..=32768, None = 8192 compat default); MAX_LENGTH / MODEL_MAX_TOKENS are exposed for the window guard. Same (text, max_length) → same vector; short inputs are bit-identical at any limit, while longer inputs change once the old truncation lifts. A 32K-token forward is O(n²) memory — size the limit to the machine.
  • Batch encoding is sequential by design (padded batches waste attention compute on variable-length docs). GIL is released during encode.
  • input_ids/attention_mask feed as int64; pooling takes the last attended token (mask_sum - 1, clamped ≥ 0).

Conformance

fixtures/golden_jina_v5_text_small.json pins the frozen vector space: 4 canonical texts × Query/Document prefixes × dims 64/512 (12 vectors) + exact token counts, generated with embroider 0.1.3 / onnxruntime 1.29.0 CPU / text-embed policy. Unchanged by 0.1.4 (max_length) and 0.1.5 (precision, cpu_arena) for short inputs at defaults. Consumers vendor this file and assert live vectors against it (abs=1e-6 — catches wrong model, pooling, prefix, or truncation; immune to cross-CPU noise). Regenerate only on an intentional contract change, which is a new minor version plus a re-index-everything notice. See COMPAT.md for the release matrix.

Testing

  • Rust unit tests (28, pure — no network, no dylib, no tokenizer file): device/precision parsing, precision-follows-device resolution, FP16 repo selection, model-id parsing, provider-matrix mapping, task-prefix idempotence, the L2 → truncate → re-normalise math, contract constants, and open()/open_files() validation (dims, max_length) firing before I/O.

    cargo test --locked
    
  • Python parity lives with the consumers: OKFgraph's tests/test_parity.py (marked slow) pins Rust output against a numpy/transformers replication across dims × tasks × texts at ≤ 1e-5; tests/test_rust_backend.py / tests/test_rust_e2e.py cover the wheel import, the count-tokens contract, and real-model encodes.

Metadata

Release files for embroider 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for embroider 0.2.0
File Size Uploaded
embroider-0.2.0.tar.gz 91.0 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for embroider 0.2.0
File
embroider-0.2.0-cp313-cp313-win_amd64.whl CPython 3.13 CPython 3.13 Windows x86-64 Details
embroider-0.2.0-cp313-cp313-manylinux_2_28_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.28+ x86-64 Details
embroider-0.2.0-cp313-cp313-macosx_11_0_arm64.whl CPython 3.13 CPython 3.13 macOS 11.0+ ARM64 Details
embroider-0.2.0-cp312-cp312-win_amd64.whl CPython 3.12 CPython 3.12 Windows x86-64 Details
embroider-0.2.0-cp312-cp312-manylinux_2_28_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.28+ x86-64 Details
embroider-0.2.0-cp312-cp312-macosx_11_0_arm64.whl CPython 3.12 CPython 3.12 macOS 11.0+ ARM64 Details
embroider-0.2.0-cp311-cp311-win_amd64.whl CPython 3.11 CPython 3.11 Windows x86-64 Details
embroider-0.2.0-cp311-cp311-manylinux_2_28_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.28+ x86-64 Details
embroider-0.2.0-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details

Total release size: 58.1 MB

Release files / embroider-0.2.0.tar.gz

Download URL embroider-0.2.0.tar.gz
Size 91.0 kB
Tags Source
SHA-256 checksum
How to use checksums
17710c5e271bbd2b89e4e9fea28d2e0a7dcff5490c2484121c7e9062fd99c42b
BLAKE2b-256 checksum
How to use checksums
ba75471b4965bccb523ba298ca7a158c5f3fd5b12de6694e4ac45093785f2b2a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release files / embroider-0.2.0-cp313-cp313-win_amd64.whl

Download URL embroider-0.2.0-cp313-cp313-win_amd64.whl
Size 5.8 MB
Tags CPython 3.13 Windows x86-64
SHA-256 checksum
How to use checksums
55b94cdd9e9a562f18407125fa399d151522185c4ba689d95dfa9a2ec583a2d1
BLAKE2b-256 checksum
How to use checksums
a3be6d94c384545d194736d5a9ca9bde442cb3894f5ea52377ff8bc5e06a3ed3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release files / embroider-0.2.0-cp313-cp313-manylinux_2_28_x86_64.whl

Download URL embroider-0.2.0-cp313-cp313-manylinux_2_28_x86_64.whl
Size 7.2 MB
Tags CPython 3.13 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
9e489bcd77400849c33c219bd884dd3e6b5a0029e275c11030649de90ad6aa6c
BLAKE2b-256 checksum
How to use checksums
67e7c0b625330175a756a31c2549d1ceaecadc0d5f380a59b22a2fcb28835934
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release files / embroider-0.2.0-cp313-cp313-macosx_11_0_arm64.whl

Download URL embroider-0.2.0-cp313-cp313-macosx_11_0_arm64.whl
Size 6.3 MB
Tags CPython 3.13 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
ed8f61d77ee9946791af59cda16ff667a0f2582f0726c21a4c29fc5c51ac1e0e
BLAKE2b-256 checksum
How to use checksums
333aa50b3a90e46f8025df8a13609914520670e518426aae0d7fab594b384824
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release files / embroider-0.2.0-cp312-cp312-win_amd64.whl

Download URL embroider-0.2.0-cp312-cp312-win_amd64.whl
Size 5.8 MB
Tags CPython 3.12 Windows x86-64
SHA-256 checksum
How to use checksums
489647f60808ebaec293cd3303bbb25d1520d15d227adf991f41ea8c35bc968b
BLAKE2b-256 checksum
How to use checksums
df6b2f4907c37843acc191d3f4d1ee6964edd840427c25550c97cb003c330aa1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release files / embroider-0.2.0-cp312-cp312-manylinux_2_28_x86_64.whl

Download URL embroider-0.2.0-cp312-cp312-manylinux_2_28_x86_64.whl
Size 7.2 MB
Tags CPython 3.12 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
b010e7647cb4b0ebf1cc98f368cbf6884c8d1e2c77d747b2620fc78c87999063
BLAKE2b-256 checksum
How to use checksums
9ad8de723e12c92ae5da45349ab32bab8d7a277b007aa60c787f15e97436f2aa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release files / embroider-0.2.0-cp312-cp312-macosx_11_0_arm64.whl

Download URL embroider-0.2.0-cp312-cp312-macosx_11_0_arm64.whl
Size 6.3 MB
Tags CPython 3.12 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
6415c174d299d0309b0cb36cb43c06a951dd04c2dd9d2985840d6e6364b002f3
BLAKE2b-256 checksum
How to use checksums
ddecb64b92b7a6d9e1a435ff7f15bb70181a09d5cf41fa6f139fcc333577b0aa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release files / embroider-0.2.0-cp311-cp311-win_amd64.whl

Download URL embroider-0.2.0-cp311-cp311-win_amd64.whl
Size 5.8 MB
Tags CPython 3.11 Windows x86-64
SHA-256 checksum
How to use checksums
c0be190df5da9fc72d28371b84dc4854a3156750eb76c7bb328a6ea9c7be0d43
BLAKE2b-256 checksum
How to use checksums
492b56b971f39f92d37dde5d376b791746fc8085b1cb428ebf70870cb73ffa43
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release files / embroider-0.2.0-cp311-cp311-manylinux_2_28_x86_64.whl

Download URL embroider-0.2.0-cp311-cp311-manylinux_2_28_x86_64.whl
Size 7.2 MB
Tags CPython 3.11 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
ae3a9a7a09de0023d93a7aa0bed28c19aed571b3c904b41da0e46b7cca447585
BLAKE2b-256 checksum
How to use checksums
0423de976ace01eac111bd8546db6b28d7069204299947daf10fa5a31f8bbaea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release files / embroider-0.2.0-cp311-cp311-macosx_11_0_arm64.whl

Download URL embroider-0.2.0-cp311-cp311-macosx_11_0_arm64.whl
Size 6.3 MB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
31390550633e60c97f19e78142718c0de3c5c48af322615e459be88fd63ba739
BLAKE2b-256 checksum
How to use checksums
803617f12f74c0748f95b2a97c0f5e6baf477ef16045838e1105990ee3a9f08a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

10 release files

0.1.5

10 release files

0.1.4

10 release files

0.1.3

10 release files

0.1.2

10 release files

0.1.1

10 release files

0.1.0

4 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page