chore: import upstream snapshot with attribution
CodeQL / Analyze (python) (push) Has been cancelled
Update Platform Components Table / update (push) Has been cancelled
Docker image release / Build base image (push) Has been cancelled
Sync docs with Docusaurus / sync (push) Has been cancelled
Tests / Check if changed (push) Has been cancelled
Tests / format (push) Has been cancelled
Tests / check-imports (push) Has been cancelled
Tests / Unit / macos-latest (push) Has been cancelled
Tests / Unit / ubuntu-latest (push) Has been cancelled
Tests / Unit / windows-latest (push) Has been cancelled
Tests / mypy (push) Has been cancelled
Tests / Integration / ubuntu-latest (push) Has been cancelled
Tests / Integration / macos-latest (push) Has been cancelled
Tests / Integration / windows-latest (push) Has been cancelled
Tests / notify-slack-on-failure (push) Has been cancelled
Tests / Mark tests as completed (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Update Platform Components Table / update (push) Has been cancelled
Docker image release / Build base image (push) Has been cancelled
Sync docs with Docusaurus / sync (push) Has been cancelled
Tests / Check if changed (push) Has been cancelled
Tests / format (push) Has been cancelled
Tests / check-imports (push) Has been cancelled
Tests / Unit / macos-latest (push) Has been cancelled
Tests / Unit / ubuntu-latest (push) Has been cancelled
Tests / Unit / windows-latest (push) Has been cancelled
Tests / mypy (push) Has been cancelled
Tests / Integration / ubuntu-latest (push) Has been cancelled
Tests / Integration / macos-latest (push) Has been cancelled
Tests / Integration / windows-latest (push) Has been cancelled
Tests / notify-slack-on-failure (push) Has been cancelled
Tests / Mark tests as completed (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import hashlib
|
||||
import math
|
||||
import random
|
||||
from collections.abc import Callable
|
||||
|
||||
# A callable that derives an embedding from the (prepared) text to embed. It receives the text and returns the
|
||||
# embedding as a list of floats.
|
||||
EmbeddingFn = Callable[[str], list[float]]
|
||||
|
||||
|
||||
def _l2_normalize(vector: list[float]) -> list[float]:
|
||||
"""Return the L2-normalized vector, so that mock embeddings behave like real (unit-length) ones."""
|
||||
norm = math.sqrt(sum(value * value for value in vector))
|
||||
if norm == 0.0:
|
||||
return vector
|
||||
return [value / norm for value in vector]
|
||||
|
||||
|
||||
def _deterministic_embedding(text: str, dimension: int) -> list[float]:
|
||||
"""
|
||||
Generate a deterministic, unit-length embedding from the given text.
|
||||
|
||||
The same text always yields the same embedding, and different texts yield different embeddings, which makes mock
|
||||
embeddings usable in retrieval pipelines and reproducible across runs and processes. The seed is derived from a
|
||||
SHA-256 digest of the text (not the process-salted built-in `hash`) to guarantee cross-process stability.
|
||||
|
||||
:param text: The text to embed.
|
||||
:param dimension: The number of dimensions of the resulting embedding.
|
||||
:returns: A deterministic, L2-normalized embedding of length `dimension`.
|
||||
"""
|
||||
digest = hashlib.sha256(text.encode("utf-8")).digest()
|
||||
seed = int.from_bytes(digest[:8], "big")
|
||||
rng = random.Random(seed)
|
||||
vector = [rng.uniform(-1.0, 1.0) for _ in range(dimension)]
|
||||
return _l2_normalize(vector)
|
||||
|
||||
|
||||
def _coerce_embedding(value: object, *, name: str) -> list[float]:
|
||||
"""
|
||||
Validate that `value` is a non-empty sequence of numbers and coerce it into a list of floats.
|
||||
|
||||
:param value: The value to validate, e.g. a user-provided fixed embedding or the output of an `embedding_fn`.
|
||||
:param name: How to refer to `value` in error messages, e.g. ``"'embedding'"``.
|
||||
"""
|
||||
if not isinstance(value, (list, tuple)) or not all(isinstance(item, (int, float)) for item in value):
|
||||
raise TypeError(f"{name} must be a sequence of numbers, got {type(value)}.")
|
||||
if len(value) == 0:
|
||||
raise ValueError(f"{name} must not be empty.")
|
||||
return [float(item) for item in value]
|
||||
|
||||
|
||||
def _estimate_usage(texts: list[str]) -> dict[str, int]:
|
||||
"""
|
||||
Roughly estimate token usage as whitespace-separated word counts.
|
||||
|
||||
This is an approximation (not real tokenization) intended to give downstream code realistic-looking metadata.
|
||||
"""
|
||||
prompt_tokens = sum(len(text.split()) for text in texts)
|
||||
return {"prompt_tokens": prompt_tokens, "total_tokens": prompt_tokens}
|
||||
Reference in New Issue
Block a user