Skip to main content

awembed — Aither World Embed

Train a small embedding model that knows your corpus, and prove it beats the big one.

A 0.6B student trained this way on one codebase retrieved the right directory on the first try 80% of the time; the 7.85B general-purpose teacher it learned from managed 66% on the same held-out questions. The student ships as 1.06 GB of int8 with 0.999 cosine fidelity to its full-precision self. The whole run was one GPU for about two and a half hours.

The reason a small model can win is not magic: the teacher never saw your corpus. The student is trained on two signals at once — the teacher's margins between the right answer and plausible wrong ones (distillation), and your corpus's own labels (in-domain contrastive learning). For retrieval over something you own, in-domain supervision is worth more than parameters.

Install

pip install awembed              # the student side: torch + transformers
pip install "awembed[teacher]"   # also the teacher server (fastapi, einops, ...)

The recipe

# 0. Build the corpus from per-directory READINGS of your repo: one JSON per line,
#    {"rel": "<dir>", "reading": "<a paragraph on what the dir does>", "prompt_version": "v1"}.
#    Any LLM over `ls` + a few file heads produces them (~1,500 chars each is plenty);
#    a walker that writes them for you is the next thing this module grows.
#    Output: one row per question, with the right directory and K hard negatives --
#    directories that look plausible and are wrong -- split by DIRECTORY, so
#    evaluation never sees a directory that training saw. Add your own
#    question -> target pairs with --ground-truth (JSONL {"query", "target"}).
awembed corpus --readings dir_readings.jsonl --out corpus.jsonl

# 1. Before renting anything: does the teacher load and answer HERE?
awembed probe                                  # exit 0 ok / 1 failed / 2 could not judge

# 2. Capture the teacher's judgement for every row (starts the teacher server itself)
awembed capture  --corpus corpus.jsonl --seed 1 --out artifacts/

# 3. Distill the student (fp32 master + bf16 autocast; gate: the loss must fall)
awembed distill  --corpus corpus.jsonl --seed 1 --out artifacts/

# 4. Weight-only int8 export (gate: >= 0.98 mean cosine to the fp32 student)
awembed quantize --corpus corpus.jsonl --seed 1 --out artifacts/

# 5. Teacher vs untrained baseline vs student vs int8, on the held-out directories
awembed eval     --corpus corpus.jsonl --seed 1 --out artifacts/

# ...or all four artifact stages in order, stopping at the first gate that refuses:
awembed run      --corpus corpus.jsonl --seed 1 --out artifacts/

Every stage writes a sidecar (teacher_manifest.json, train_sidecar.json, quant_sidecar.json, eval_report.json) with what it measured, so the record of a run is the run. Every stage has a --self-test that runs the same code path on a thumbnail model, on CPU, offline.

What the gates refuse

stage refuses when
capture a corpus row lacks inline hard-negative text (path-only negatives teach a shortcut, not retrieval)
distill the mean loss over the last 10 steps is not below the first 10, or any step is non-finite
quantize the int8 export embeds at < 0.98 mean cosine to the fp32 student, measured through the loader the eval stage uses
eval the student does not beat the baseline on both p@1 and recall@10, or int8 holds < 98% of the student's recall@10

A run that "completed" with no learning is exactly the thing a training pipeline is best at hiding. The gates are the point.

Defaults, and what to change

  • Teacher: nvidia/NV-Embed-v2 (7.85B, CC-BY-NC-4.0 — a teacher signal only; its weights and its captured targets never ship). Any OpenAI-compatible /v1/embeddings endpoint works: pass --teacher-url to capture instead of letting it start one.
  • Student: Qwen/Qwen3-Embedding-0.6B (Apache-2.0, 1024-dim, last-token pooling). Pass --student to distill for another base.
  • Asymmetry: queries carry an instruction prefix; documents embed plain. The prefix the student was trained with is the one you must use at query time. It is written in the sidecar.
  • Two environments: the default teacher pins an older transformers than the student needs, so run teacher/probe in their own venv and point capture at it with NV_EMBED_PYTHON=/path/to/venv/bin/python.

Using the student

The student is an ordinary Hugging Face directory (artifacts/student/) — serve it with vLLM (--task embed), Text Embeddings Inference, or transformers directly. It is a new vector space (1024-dim): index into a fresh collection, do not mix it with vectors from the model you replaced.

It pairs with the rest of the Aither World family: awgraph (code graph search over your repo), awm (agent memory), awfind (ranked answers), awrecurse (documents larger than a context window), and awdk agents that consume any of those.

Licence

Apache-2.0. Models you train carry their base model's licence.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

awembed-0.1.0.tar.gz (41.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

awembed-0.1.0-py3-none-any.whl (48.1 kB view details)

Uploaded Python 3

File details

Details for the file awembed-0.1.0.tar.gz.

File metadata

  • Download URL: awembed-0.1.0.tar.gz
  • Upload date:
  • Size: 41.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.5

File hashes

Hashes for awembed-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3d602490e295d87072b15bee8c7e5ce7fe573e06453c9a0722bb8ebcb1c64fbd
MD5 c51b868e4aa8f6e1e917dfe9ef9f824b
BLAKE2b-256 5b4050fa2203853389ed522bd0c2b54e6c8b9fa72af78af5d3899cd03957afee

See more details on using hashes here.

File details

Details for the file awembed-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: awembed-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 48.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.5

File hashes

Hashes for awembed-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8e9b9e26c114562105eb0cff858306ce976fa17df081f6149997de9528f95ba1
MD5 daf9895e32637b53ea320394ee0a798f
BLAKE2b-256 82d32384bd6cafc76a7f8c6f45918bbf20c4c965a5da3c2265bdb4c51ab0ddba

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 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