Spaces:
Running
Running
Download src/rag_engine/embeddings.py from Jayan12321/rag-engine: direct link, hf CLI and curl.
- Browser
- Download file 2.72 kB
-
https://huggingface.co/spaces/Jayan12321/rag-engine/resolve/main/src/rag_engine/embeddings.py
- Command line
-
hf download hf://spaces/Jayan12321/rag-engine/src/rag_engine/embeddings.py
-
curl -L -o embeddings.py https://huggingface.co/spaces/Jayan12321/rag-engine/resolve/main/src/rag_engine/embeddings.py
2.72 kB
| """Embedding functions for converting text to semantic vector representations. | |
| Embeddings map human text into high-dimensional vectors such that texts with | |
| similar meanings have high cosine similarity (close to 1.0). | |
| """ | |
| import hashlib | |
| import math | |
| class HashEmbeddings: | |
| """A deterministic, zero-dependency embedding generator. | |
| Uses SHA-256 token hashing into 384 buckets. | |
| Great for instant offline demos, testing, and machines without GPUs or PyTorch. | |
| """ | |
| def __init__(self, dim=384): | |
| self.dim = dim | |
| def embed_text(self, text): | |
| """Convert a single string into a normalized float vector.""" | |
| vector = [0.0] * self.dim | |
| if not text: | |
| return vector | |
| tokens = text.lower().split() | |
| for idx, token in enumerate(tokens): | |
| digest = hashlib.sha256(token.encode("utf-8")).digest() | |
| bucket = int.from_bytes(digest[:4], "little") % self.dim | |
| # Weigh by position and presence | |
| vector[bucket] += 1.0 + (idx % 5) * 0.05 | |
| # L2 normalize | |
| squared_sum = sum(v * v for v in vector) | |
| norm = math.sqrt(squared_sum) or 1.0 | |
| return [v / norm for v in vector] | |
| def embed_documents(self, texts): | |
| """Batch embed a list of texts.""" | |
| return [self.embed_text(t) for t in texts] | |
| def embed_query(self, query): | |
| """Embed a search query.""" | |
| return self.embed_text(query) | |
| def cosine_similarity(vec_a, vec_b): | |
| """Compute cosine similarity between two unit-normalized vectors.""" | |
| if not vec_a or not vec_b or len(vec_a) != len(vec_b): | |
| return 0.0 | |
| dot_product = sum(a * b for a, b in zip(vec_a, vec_b)) | |
| return float(dot_product) | |
| def get_embedding_model(settings=None): | |
| """Factory to get the configured embedding model.""" | |
| if settings is None or getattr(settings, "use_hash_embeddings", True): | |
| return HashEmbeddings() | |
| # If requested and available, use SentenceTransformers | |
| try: | |
| from sentence_transformers import SentenceTransformer | |
| class STEmbeddings: | |
| def __init__(self, model_name): | |
| self.model = SentenceTransformer(model_name) | |
| def embed_text(self, text): | |
| return self.model.encode(text, normalize_embeddings=True).tolist() | |
| def embed_documents(self, texts): | |
| return self.model.encode(texts, normalize_embeddings=True).tolist() | |
| def embed_query(self, query): | |
| return self.embed_text(query) | |
| return STEmbeddings(settings.embedding_model) | |
| except Exception: | |
| # Fall back to HashEmbeddings if sentence-transformers is missing | |
| return HashEmbeddings() | |