Models and pinned downloads
The embedding, rescoring and image models Semlith runs on your machine, the accelerator packs it can fetch, and how to check each download by its digest.
Every model and accelerator component semlith downloads, with the commit, digest and size it is pinned to. Read it to check what runs on your machine or to verify a download yourself.
semlith computes vectors with three ONNX models: granite for text, a
cross-encoder for optional rescoring, and CLIP for images. They are fetched from
Hugging Face on first use, cached under ~/.cache/semlith/models (or
SEMLITH_MODEL_CACHE), and never fetched again.
Each model is pinned to a commit, and each file is verified against a SHA-256 recorded in the source. A model that changed upstream would change every answer without changing anything you can see. A file whose digest does not match is refused by name with both digests printed, and nothing is loaded. If that happens twice on a clean cache, the upstream bytes have changed and semlith needs a new release, not another download.
Text: granite-embedding-small-english-r2
The default model: 384 dimensions, int8, Apache-2.0. semlith fetches these files itself and verifies each as it is read.
- Repository:
onnx-community/granite-embedding-small-english-r2-ONNX - Commit:
1dc7835ba0cb9c76a3618d0bf0c427c97671b3c8 - Recorded in
src/embed.rsasGRANITE_REVISIONandGRANITE_FILES.
| File | SHA-256 |
|---|---|
tokenizer.json | feeb83348dcb033bc6b9d2e1f7906ca9eb2d122845000c9416d894d7c2927149 |
config.json | 1a1710c20911da8c96179716bf44058e54cca6fa7952cce77be83ef05edae3ee |
special_tokens_map.json | ea97ecdbcc73713039d8d64dbb05e3689495c96657fbd9a18f5bed381be81049 |
tokenizer_config.json | ce06781b38bb393db68c9e0709bddd31ef5d88f2c6fbb3fd9f369778fb85e451 |
onnx/model_quantized.onnx | a3fad524afc3f060216a8ddbb1ac89c9b6498fba8995b5718bde879076a2e9ba |
onnx/model_quantized.onnx_data | 1f4cf47e4adec7f7ae09db03d071ba8667e07f9a4203142c7efa8d37fe453597 |
The fp16 and fp32 exports
Two more exports of the same model, at the same commit and with the same
tokenizer files. Recorded in src/embed.rs as Variant::files; the fp16 pair is
also in src/gpu.rs as FP16_FILES, with the sizes the download is checked
against.
| Variant | File | SHA-256 | Bytes |
|---|---|---|---|
| fp16 | onnx/model_fp16.onnx | ee200de55cb2f94e858aabca54be7697a9c0805a14c858ee26ad0922b05f57d7 | 200 792 |
| fp16 | onnx/model_fp16.onnx_data | 28d16e29cd623f25cc6fa0968700c5bc31036466091a5fa06d1353c1777f050e | 97 402 880 |
| fp32 | onnx/model.onnx | cddb145cd1147ec24a3908b2ca2602b98b20a3d198365cff270b7cb26c98179e | |
| fp32 | onnx/model.onnx_data | 86a3a705d4598615894d89540ea71a3d9bbdb17a315e79edcd5dfc737222834b |
- fp16 is what the GPU lanes run. The int8 graph does not load on WebGPU.
The fp16 pair is downloaded with the WebGPU plugin, the first time a run starts
on a machine with a hardware GPU and the GPU lane on, or when CUDA is turned
on. Both files are stored in the plugin’s directory in the model cache, not in
the Hugging Face snapshot. fp16 and int8 vectors of the same text agree at
cosine 0.987 (2026-09-23 corpus). A store records how many chunks each variant
embedded in its
variantsmeta row. - fp32 is what the known-answer fixture was made with.
tests/fixtures/gpu/holds 32 chunks and their CPU fp32 vectors;semlith doctor --gpu, and every GPU lane before its first real batch, compare against them. The product never downloads fp32. A harness fetches it withSEMLITH_EMBED_VARIANT=fp32, which is not part of the documented environment.
Accelerator components
Not models, but pinned and verified the same way. Each download is streamed
through SHA-256 and deleted if its digest does not match. Each set is kept under
accel/ in the model cache, in a directory named by its pinned version. Turning
a lane off leaves the directory in place; semlith accel remove <gpu | cuda>
deletes it. Under --airgap each download is refused unless its directory was
seeded beforehand.
The WebGPU plugin
Microsoft’s WebGPU plugin execution provider, onnxruntime-ep-webgpu 0.4.0
(MIT), taken from the wheel Microsoft publishes on PyPI. semlith extracts the
plugin library, plus the two shader compilers beside it on Windows, into
accel/webgpu-0.4.0/. Recorded in src/gpu.rs as WEBGPU_VERSION and
wheel().
| Platform | Wheel | SHA-256 | Bytes |
|---|---|---|---|
| macOS (universal2) | onnxruntime_ep_webgpu-0.4.0-py3-none-macosx_14_0_universal2.whl | 8d0a91d44b43d931c3068b9134aed9770f27803e353c2b58c93e1700bb68bcca | 5 200 679 |
| Linux x86_64 | onnxruntime_ep_webgpu-0.4.0-py3-none-manylinux_2_28_x86_64.whl | 5d8c961eda91a88961cad1fb7621f389f006b18497d6ea9ecf96f729f066cbfb | 6 892 120 |
| Linux aarch64 | onnxruntime_ep_webgpu-0.4.0-py3-none-manylinux_2_28_aarch64.whl | 17f660db53b1a509c63e721ac6784a2daa1c4e91a968523ee9986505ee5b0a55 | 6 096 222 |
| Windows x86_64 | onnxruntime_ep_webgpu-0.4.0-py3-none-win_amd64.whl | 7db646669d1a2390551da675115ea125e68cb3d4d2c3a2d6e463372bf8d6ea87 | 13 149 847 |
It is fetched only after a hardware adapter is found. A machine whose only adapter is a software renderer (Mesa lavapipe or llvmpipe, SwiftShader, Microsoft WARP or the Basic Render Driver) counts as having no GPU, and nothing is downloaded.
The CUDA pack
x86_64 Linux only. Pack 1.24.4-cu12.8, recorded in src/cuda.rs as
PACK_VERSION and PARTS, with PACK_BYTES asserted against the sum of the
sizes in tests/cuda.rs. It is downloaded only after CUDA is turned on (semlith accel on cuda or the switch on the Machine limits card), and the size is stated
before the download starts: 1 891 522 804 bytes (1.89 GB) when the system
supplies none of the libraries. A library the system already has, at the pinned
version or a newer one in the same major version, is used from the system and
its wheel is not fetched. Parts are listed in load order.
| Part | Version | Source | SHA-256 | Bytes | Supplies |
|---|---|---|---|---|---|
| ONNX Runtime GPU build | 1.24.4 | GitHub release | c5f804ff5d239b436fa59e9f2fb288a39f7eb9552f6a636c8b71e792e91a8808 | 205 429 115 | libonnxruntime.so.1.24.4, libonnxruntime_providers_shared.so, libonnxruntime_providers_cuda.so |
nvidia-cuda-runtime-cu12 | 12.8.90 | PyPI wheel | adade8dcbd0edf427b7204d480d6066d33902cab2a4707dcfc48a2d0fd44ab90 | 954 765 | libcudart.so.12 |
nvidia-nvjitlink-cu12 | 12.8.93 | PyPI wheel | 81ff63371a7ebd6e6451970684f916be2eab07321b73c9d244dc2b4da7f73b88 | 39 254 836 | libnvJitLink.so.12 |
nvidia-cublas-cu12 | 12.8.4.1 | PyPI wheel | 8ac4e771d5a348c551b2a426eda6193c19aa630236b418086020df5ba9667142 | 594 346 921 | libcublasLt.so.12, libcublas.so.12 |
nvidia-cufft-cu12 | 11.3.3.83 | PyPI wheel | 4d2dd21ec0b88cf61b62e6b43564355e5222e4a3fb394cac0db101f2dd0d4f74 | 193 118 695 | libcufft.so.11 |
nvidia-curand-cu12 | 10.3.9.90 | PyPI wheel | b32331d4f4df5d6eefa0554c565b626c7216f87a06a4f56fab27c3b68a830ec9 | 63 619 976 | libcurand.so.10 |
nvidia-cuda-nvrtc-cu12 | 12.8.93 | PyPI wheel | a7756528852ef889772a84c6cd89d41dfa74667e24cca16bb31f8f061e3e9994 | 88 040 029 | libnvrtc-builtins.so.12.8, libnvrtc.so.12 |
nvidia-cudnn-cu12 | 9.10.2.21 | PyPI wheel | 949452be657fa16687d0930933f032835951ef0892b37d2d53824d1a84dc97a8 | 706 758 467 | libcudnn.so.9 and its seven sub-libraries |
The NVIDIA versions are the CUDA 12.8 set that PyTorch 2.8’s cu128 wheels pin;
ONNX Runtime’s onnxruntime-gpu[cuda,cudnn] extras resolve to the same set. The
card needs driver 525.60.13 or newer, the minimum for CUDA 12.x on Linux x86_64;
a card on an older driver is reported with that minimum and not used. On
Windows, an NVIDIA card is used through WebGPU on D3D12.
Licences. ONNX Runtime is Microsoft’s MIT-licensed release, downloaded from
its GitHub release. NVIDIA’s libraries never pass through semlith: your machine
downloads each wheel from files.pythonhosted.org, where NVIDIA publishes it —
the same bytes from the same place pip install nvidia-cudnn-cu12 would fetch —
and semlith never hosts, mirrors or ships a copy. Your use of the libraries is
governed by the licence each wheel carries (“NVIDIA Proprietary Software”), the
terms a pip install of the same wheel accepts. When a wheel includes that
licence text, semlith keeps it beside the libraries in licences/. Because
semlith does not redistribute the libraries, the redistribution terms in the
CUDA Toolkit EULA and the cuDNN Software License Agreement do not apply to it.
The Core ML pack
Apple silicon only, for the Neural Engine lane and the Core ML GPU lane. semlith
builds it: .github/workflows/packs.yml runs packs/coreml/convert.py on a
macOS runner and publishes the zip to this repository’s pack-coreml-v2
release, and src/packs.rs pins it by URL, SHA-256 and size. granite at
ibm-granite/granite-embedding-small-english-r2@2ab6fa8e is converted twice:
- for the Neural Engine: batch 4; sequence buckets 128, 192, 256, 320, 384, 512;
- for the GPU, in the standard layout: batch 8; buckets 128, 192, 256, 320, 400 (no chunk is longer than 400 tokens). These run with fp16 accumulation, which leaves the fixture’s cosine against fp32 at 0.999999.
Each layout is one multifunction model with a function per bucket, so the weights are stored once per layout.
| Asset | SHA-256 | Bytes |
|---|---|---|
semlith-coreml-2.zip | 799e4f7e8a4b1aab8335ab969bc385fcfb7baa8d62bfd14e02c8be9b0188a082 | 147 950 175 |
On the M1 Air, every Neural Engine function places 99.85 % of its operations on
the Neural Engine, and its vectors agree with the fp32 reference at cosine
0.99998 or better on the 512-chunk fixture in tests/fixtures/coreml.
The first load on a Mac compiles the models for that machine. The lane is ready once the longest bucket has compiled (39 s on the M1) and compiles the other five behind it, about three minutes in all. macOS keeps the result for the program that compiled it, which is a copy of semlith kept beside the models, so a later start is ready in about 2 s and an upgrade does not compile again. macOS empties that cache when the disk runs low: with 13 GB free on the M1 it had done so within ten minutes, and the next start compiled again.
The llama.cpp pack
Experimental. ggml-org’s own llama-server build b11146 for the platform, and
granite as GGUF f16, which semlith builds with llama.cpp’s converter at the same
build (packs/llama/convert.sh) and publishes to pack-llama-v1.
| Asset | SHA-256 | Bytes |
|---|---|---|
llama-b11146-bin-macos-arm64.tar.gz | 1ad3f9eff80edb9dbef4259ad564d1720612ef7eea48fa4afed0e54f5f3d5711 | 11 189 714 |
llama-b11146-bin-ubuntu-vulkan-x64.tar.gz | d3ce40fce7403cc93bcf5718fc46c6efb61ed9709f8e5d9f10c86bf0e30e8fb3 | 30 598 492 |
llama-b11146-bin-win-vulkan-x64.zip | 55a378aa095b466979d85075234f66d7655c7a7483222af0c006c0e55b4d7bd6 | 32 127 004 |
granite-embedding-small-english-r2-f16.gguf | e9d55517cdadcf30eb18a65ea069778dd134914dee2554959bcedd5717d8faa8 | 97 119 616 |
TensorRT for RTX and OpenVINO
Experimental, x86_64 Windows and Linux. Each is the vendor’s own ONNX Runtime plugin execution provider, downloaded from PyPI where the vendor publishes it; semlith never hosts a copy.
| Plugin | Platform | Wheel | SHA-256 | Bytes |
|---|---|---|---|---|
| TensorRT for RTX 0.4.0 (cu12) | Linux | onnxruntime_ep_nv_tensorrt_rtx_cu12-0.4.0-…manylinux_2_28_x86_64.whl | 221807b1797a6270f37dfd7981f66e25ca7483f3883bfe23ef2b6a4198fe2b10 | 167 721 016 |
| TensorRT for RTX 0.4.0 (cu12) | Windows | onnxruntime_ep_nv_tensorrt_rtx_cu12-0.4.0-…win_amd64.whl | 5d9dba6aafd8e0863f34d0e5f51ad7c7ae9a5d6a92a55fe45d9637d3a5f1e1a7 | 105 822 356 |
| OpenVINO 1.7.0 | Linux | onnxruntime_ep_openvino-1.7.0-…manylinux_2_28_x86_64.whl | 7016c5ba4154f2a2b6da87e8b8654e5e811151186fb97cc29bde5d2fabde6c93 | 51 725 826 |
| OpenVINO 1.7.0 | Windows | onnxruntime_ep_openvino-1.7.0-…win_amd64.whl | 0b48601ff6720a9fdbf06de99073665cec9b8d7983226455d4f766aa4d8be16c | 67 675 843 |
Intel’s plugin offers Intel hardware only: on a machine with an AMD CPU and no Intel GPU or NPU it offers no device, and the lane says so.
Rescoring: jina-reranker-v1-turbo-en
A cross-encoder: 37 M parameters, int8, Apache-2.0. It reads the query and a candidate together and reorders the head of the fused list. It embeds nothing and adds no candidates, so a store’s vectors do not depend on it.
It is off unless you set SEMLITH_RERANK=on. A search over one store takes
8.2 ms, and 132.2 ms with rescoring over twelve candidates — sixteen times
slower — for a small gain at the top of the list.
Turn it on when an answer matters more than a tenth of a second.
semlith setup fetches it beside the embedding model, so turning it on never
pauses a query for a download. semlith stats and semlith doctor both say
which ranking a search used.
- Repository:
jinaai/jina-reranker-v1-turbo-en - Commit:
b8c14f4e723d9e0aab4732a7b7b93741eeeb77c2 - Recorded in
src/rerank.rsasRERANK_REVISIONandRERANK_FILES.
| File | SHA-256 |
|---|---|
tokenizer.json | 0046da43cc8c424b317f56b092b0512aaaa65c4f925d2f16af9d9eeb4d0ef902 |
config.json | e050ff6a15ae9295e84882fa0e98051bd8754856cd5201395ebf00ce9f2d609b |
special_tokens_map.json | 06e405a36dfe4b9604f484f6a1e619af1a7f7d09e34a8555eb0b77b66318067f |
tokenizer_config.json | d291c6652d96d56ffdbcf1ea19d9bae5ed79003f7648c627e725a619227ce8fa |
onnx/model_quantized.onnx | 3defdef1ae34e119bd704216087743e79665934c96aebabcb6077c239dc3ae66 |
Images: CLIP ViT-B/32
Two repositories, a vision encoder and a text encoder, fixed as a pair. A query about a picture goes through CLIP’s own text encoder, never through the store’s model, because a granite vector and a CLIP vector have different lengths and describe different things.
These are fastembed’s built-in models, so fastembed resolves and caches them through its own client and semlith cannot hand it a revision. Instead, semlith checks every snapshot in the cache, not only the pinned one, before either encoder is used and again after a fetch, and refuses to load bytes that are not the ones this release was built against.
- Vision:
Qdrant/clip-ViT-B-32-visionate0c24ed0fa57fa3e4f97f30de74c51d944036ace - Text:
Qdrant/clip-ViT-B-32-textat48ca1db27cb4063eb311ec2aa7f087a808112876 - Recorded in
src/image.rsasVISION_REVISION,VISION_FILES,TEXT_REVISIONandTEXT_FILES.
| Repository | File | SHA-256 |
|---|---|---|
| vision | model.onnx | c68d3d9a200ddd2a8c8a5510b576d4c94d1ae383bf8b36dd8c084f94e1fb4d63 |
| vision | config.json | 43bfed060ab82f57833bdd09acdcc2731995cb984651732a9d2b399e63113b9c |
| vision | preprocessor_config.json | ce945ef831c9972c135b5b198a03d8eeb70478cd69c0238f24caf1903a9965e6 |
| text | model.onnx | 4dbe762b11e36488304471e439cde89da053ad7acaddbf9e096745d142ec8d8b |
| text | config.json | 4d5923d94bbc4e29864de837df14c138c12b93a0b738c64f3ca41f0c539e17b7 |
| text | tokenizer.json | b68d571997a1f81bf521fb73806740ddb91e4ed6666cb6e996c066bb289cf55b |
| text | special_tokens_map.json | 2cdb3b8331a60c92fc1e55a13e9fd61fd2293c5a51275fdcccd62b780052530e |
| text | tokenizer_config.json | 6bdcee9ccce2a16ca2b4c0c5ed00b42c50ea225f4472a8c4c1e963a2902c2881 |
| text | vocab.json | 5047b556ce86ccaf6aa22b3ffccfc52d391ea4accdab9c2f2407da5b742d4363 |
| text | merges.txt | 9fd691f7c8039210e0fced15865466c65820d09b63988b0174bfe25de299051a |
The cache directory
semlith refuses to load weights from a model cache owned by another account or
writable by other users, and names the chown or chmod that fixes it. A
directory somebody else can write to is a model somebody else chooses.
Checking a digest yourself
Hugging Face publishes the SHA-256 of every LFS file in its tree API, and the small files can be hashed directly:
curl -sSL "https://huggingface.co/onnx-community/granite-embedding-small-english-r2-ONNX/resolve/1dc7835ba0cb9c76a3618d0bf0c427c97671b3c8/tokenizer.json" \
| shasum -a 256curl -sS "https://huggingface.co/api/models/Qdrant/clip-ViT-B-32-vision/tree/e0c24ed0fa57fa3e4f97f30de74c51d944036ace?recursive=true" \
| jq -r '.[] | select(.lfs) | "\(.path) \(.lfs.oid)"'Updating a pin
Changing a model is a release, not a patch to a table. The commit and every
digest move together, docs/models.md and the constants are updated in the same
change, and CHANGELOG.md says which model moved and why. A store’s vectors are
comparable only with vectors from the model that built it.