ONNX and QHexRT embedding providers ignore normalize=false
Follow-up from #841 by @ayaangazali -- thanks again for that PR!
What
Now that the commons proto adapter forwards EmbeddingsOptions.normalize=false as RAC_EMBEDDINGS_NORMALIZE_NONE, the llamacpp and MLX engines honour it -- but the ONNX and QHexRT embedding providers don't. engines/onnx/onnx_embedding_provider.cpp:626 and :788 call normalize_vector(pooled) unconditionally on both the single and batch paths, and qhexrt_embeddings_ops.cpp:7/:44 return the plan's always-L2-normalized vector regardless of the caller's request.
Why it matters
A caller asking for a raw pooled vector gets one only when the model happens to run on llamacpp or MLX -- the same API call returns different semantics depending on which engine backs the loaded model. The Electron feature test (bindings/electron/test/feature/embeddings.feature.test.ts:141-166) currently asserts unit-length output for normalize=NONE against the ONNX MiniLM model, which is itself evidence of the gap.
Suggested approach
- In
onnx_embedding_provider.cpp, skipnormalize_vector(pooled)on both the single and batch paths whenoptions->normalize == RAC_EMBEDDINGS_NORMALIZE_NONE. - In QHexRT, either honour the flag the same way or explicitly document/reject
normalize=falsefor that backend. - Flip the Electron feature test's assertion once ONNX honours the flag.
Done when
- ONNX and QHexRT embedding providers return raw pooled vectors when
normalize=falseis requested. - The Electron feature test reflects the corrected behavior.
Not blocking #841. @ayaangazali, you know this code well now -- you're welcome to take this one if you're interested.
Opened with help from Claude Code and Codex.
Reviewed with help from Claude Code and Codex.
Source: RunanywhereAI/runanywhere-sdks