Silent all-NaN embeddings when a model file is incompatible with the runtime (0.8.0 still ships the fp16 jina-de model fixed by #623)
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 3.2k
- Forks
- 248
- Avg merge
- 4d 8h
- Merged PRs (30d)
- 4
Description
Summary
TextEmbedding can return vectors that are entirely NaN without raising, warning, or
logging anything. Downstream this is worse than a hard failure: cosine similarity becomes
NaN, ranking silently degenerates to input order, and a vector search appears to work
while returning meaningless results.
I ran into this through jinaai/jina-embeddings-v2-base-de, which is the case already fixed
on main by #623, but the silent-NaN behavior itself looks independent of that model.
Reproduction
from fastembed import TextEmbedding
import numpy as np
m = TextEmbedding(model_name="jinaai/jina-embeddings-v2-base-de")
v = np.array(list(m.embed(["Ein Testsatz."]))[0])
print(v.shape, np.isnan(v).sum()) # (768,) 768 -- no warning, no error
Environment: fastembed 0.8.0 (current PyPI), onnxruntime 1.29.0, providers
['AzureExecutionProvider', 'CPUExecutionProvider'], Python 3.12.12, Windows 11 x86_64.
Every one of the 768 components is NaN. Nothing on stderr, no exception, exit code 0.
Two separate points
1. The fp16 jina-de mapping is fixed on main but not released
#623 ("use original jina de model instead of fp16 due to onnxruntime up...") was merged
2026-04-15 and main now carries model_file="onnx/model.onnx". The newest PyPI release is
0.8.0 from 2026-03-23, so every pip install fastembed still gets the fp16 mapping and, on
onnxruntime >= 1.23, silently produces NaN. Is a release planned? This currently reaches
anyone selecting that model through a downstream package.
As a workaround on 0.8.0, onnx/model_quantized.onnx (int8, 154 MB) works correctly on CPU
and is both smaller and faster than the fp32 file main switched to — in my measurements ~5x
faster than bge-small-en-v1.5 on the same corpus. Possibly worth considering as the
mapping, though I have not compared int8 vs fp32 output quality.
2. The silent part is the more general problem
Independently of which file is mapped, a NaN result is not detectable by callers without
explicitly checking, and nothing in the docs suggests that is necessary. A cheap guard would
turn a silent data-corruption bug into an actionable error, for example checking the first
batch's output once per model load and raising something like
RuntimeError: model '<name>' produced non-finite embeddings with provider '<provider>'.
That would have surfaced #623's root cause immediately at the call site rather than as
unexplained ranking behavior downstream.
I am happy to open a PR for the guard if you think it is worth having and can point me at
where you would want the check to live.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the TextEmbedding model-loading and embed path, then inspect the model mapping changed by #623. Reproduce the all-NaN output with jinaai/jina-embeddings-v2-base-de and determine where a non-finite-output check belongs. Done means the incompatible model produces an actionable failure instead of silently returning NaN vectors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- machine-learning
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100