Embeddings embeddingindex save - CyrilB1531/lodestar GitHub Wiki
Development build. This page describes
main, not a released package. The latest published Lodestar.Embeddings is 0.8.0 — read its documentation.
Home › Embeddings › Vector search
EmbeddingIndex.Save
Writes the index — configuration, ids and the vector block — out as UTF-8 JSON.
public void Save(Stream destination)
public void Save(string path)
Parameters — destination is a writable stream, flushed but never disposed: the caller owns
it. path is a file to create or overwrite, written UTF-8 without a byte-order mark.
Returns — nothing.
Exceptions — ArgumentException when the stream cannot be written to, refused before the
vectors and ids are checked (#1641), and when
an id is beyond what the JSON writer can write — the writer's own, as 0.8.0 raised it, refused
before the first byte, once the writer has accepted the stream or the file is open
(#1618,
#1646). IndexOutOfRangeException, the
writer's own as well, for a string whose escaped form passes its buffer, as 0.8.0 raised it.
ArgumentNullException when destination or path is null. InvalidDataException when any stored
vector holds a non-finite component; the message names the item and the component.
InvalidOperationException when the vector block, base64-encoded, is longer than the one array a
load decodes it into — refused before the path is opened, so a file it would replace is left whole
(#1322). IOException from the stream or file
system.
Example — a round trip through memory, ids and all.
using Lodestar.Embeddings.Search;
var index = new EmbeddingIndex(dimension: 2);
index.Add(new float[] { 1f, 0f }, "east");
using var buffer = new MemoryStream();
index.Save(buffer);
buffer.Position = 0;
EmbeddingIndex restored = EmbeddingIndex.Load(buffer);
string label = restored.GetId(0)!; // => east
Remarks — vectors are written as base64 raw little-endian bits, not as decimal text, so a reload scores bit for bit what the original scored. A decimal round trip that lost the last bit of a float would change scores by an amount too small to notice and too large to be nothing.
A non-finite component is refused here though Add accepted it. A
NaN in memory is a wrong score you can still find; in a file it becomes a wrong score that
outlives the code that made it, scoring NaN against every query the reloaded index is ever
given.
The path overload checks for that before it opens the file. Truncating a good artifact and
then refusing to write is the failure mode that would cost you the index you already had, so the
check comes first and a refused save leaves the existing file untouched.
An index past 1,000,000 vectors saves, but loads only with a raised MaxArrayLength: a load
holds the vector count to ArtifactLoadOptions'
MaxArrayLength, whose default is 1,000,000. Save does not check it, since the ceiling is the
reader's to choose.
The stream overload leaves destination open, so an index can be one entry inside a larger
archive.
Applies to — net10.0, netstandard2.0.
See also — EmbeddingIndex.Load,
EmbeddingIndex.SaveAsync, EmbeddingIndex.