embed method
Future<List<Float32List> >
embed(
- List<
String> texts, { - EmbedPurpose purpose = EmbedPurpose.document,
override
Embeds texts, returning one vector per text, in order.
Implementation
@override
Future<List<Float32List>> embed(
List<String> texts, {
EmbedPurpose purpose = EmbedPurpose.document,
}) async {
final out = List<Float32List?>.filled(texts.length, null);
final missing = <int>[];
for (var i = 0; i < texts.length; i++) {
final key = _key(texts[i], purpose);
final cached = _memory[key] ?? _load(key);
if (cached != null) {
hits++;
_remember(key, cached);
out[i] = cached;
} else {
missing.add(i);
}
}
if (missing.isNotEmpty) {
misses += missing.length;
// Embed each distinct missing text once.
final unique = <String>{for (final i in missing) texts[i]}.toList();
final vectors = await inner.embed(unique, purpose: purpose);
if (vectors.length != unique.length) {
throw LlmException(
'the embedder returned ${vectors.length} vectors for '
'${unique.length} texts',
);
}
final byText = {
for (var j = 0; j < unique.length; j++) unique[j]: vectors[j],
};
for (final i in missing) {
final v = byText[texts[i]];
if (v == null) {
throw const LlmException(
'the embedder returned vectors for different texts than it was '
'given',
);
}
final key = _key(texts[i], purpose);
_remember(key, v);
_store(key, v);
out[i] = v;
}
}
// Copies, not the cached instances: a caller that normalises a returned
// vector in place must not corrupt the cache (or another slot that points
// at the same text).
return [for (final v in out) Float32List.fromList(v!)];
}