- Fix What's new → link in Info banner (now a proper <a> tag, always clickable) - Replace 4-stat CardGroup on index with inline premium stats row - Convert every <CardGroup>/<Card> block site-wide to markdown bullet lists: content sections → bold-title bullets with sub-bullets, nav cards → [Title](href) — description - Add cursor-animated list item hover effects to custom.css: green inset left border, subtle background tint, marker color change on hover - Affects index, getting-started, quickstart, concepts, modules, faq, architecture, installation, cookbook, glossary, learning-more, explorer-setup, cli-setup, community, contributing-guide, governance, citation, project-license, all integrations pages, and all 20+ reference module pages
22 KiB
title, description, icon
| title | description | icon |
|---|---|---|
| Embeddings Module | Text and graph embedding generation: FastEmbed, Sentence-Transformers, OpenAI, BGE: with pooling strategies and provider-agnostic API. | vector-square |
semantica.embeddings converts text and graph structures into dense vector representations:
- Provider-agnostic API: FastEmbed (default, ONNX, no GPU), Sentence-Transformers, OpenAI, BGE
- Powers semantic search, entity resolution, GraphRAG retrieval, and deduplication
GraphEmbeddingManagerembeds KG nodes and edges for graph database backends- Five pooling strategies: Mean (default), Max, CLS, Attention, Hierarchical
check_available_providers()shows which backends are installed in your environment
Why Embeddings Matter
Raw text can't be compared mathematically. Embeddings translate meaning into geometry: two semantically similar sentences produce vectors that are close together in high-dimensional space, even when they share no words.
Semantica uses embeddings for:
- Semantic search: find knowledge graph nodes by meaning, not just keywords
- Entity resolution: detect that "Apple Inc." and "Apple Computer" refer to the same entity
- Deduplication:
semantic_v2strategy measures entity similarity via embedding distance - GraphRAG retrieval: hybrid vector + graph traversal for grounded LLM answers
- Semantic chunking: detect topic shift boundaries in
TextSplitter(method="semantic_transformer")
Exported Classes
| Class | Role |
|---|---|
EmbeddingGenerator |
Provider-agnostic entry point: handles batching and provider selection |
TextEmbedder |
Text embedding with automatic batch processing; default uses FastEmbed |
GraphEmbeddingManager |
Embed KG nodes and edges for GraphRAG and graph databases |
VectorEmbeddingManager |
Prepare and format embeddings for vector database backends |
OpenAIStore |
OpenAI text-embedding-3-small / text-embedding-3-large provider |
BGEStore |
BAAI/bge models via sentence-transformers |
FastEmbedStore |
ONNX-accelerated local embeddings: no CUDA required |
LlamaStore |
Placeholder store: not production-ready; do not use for embeddings |
MeanPooling |
Default pooling strategy: best for retrieval and clustering |
What You Get
- EmbeddingGenerator — Main entry point: provider-agnostic, handles batching automatically across all backends.
- TextEmbedder — Text-specific with automatic batching and progress tracking. Default method is FastEmbed.
- GraphEmbeddingManager — Node and edge embeddings for graph databases: Neo4j, NetworkX, FalkorDB.
- VectorEmbeddingManager — Prepare, normalize, and format embeddings for FAISS, Weaviate, Qdrant, and Milvus.
- Provider Stores —
OpenAIStore,BGEStore,FastEmbedStore, andProviderStoreFactory. - Pooling Strategies — Mean, Max, CLS, Attention, and Hierarchical: control token-to-vector aggregation.
Provider Setup
ONNX-accelerated local embeddings. No GPU required, no API key. Best starting point.```bash
pip install "semantica[fastembed]"
```
```python
from semantica.embeddings import EmbeddingGenerator
# FastEmbed is the default: no config needed
generator = EmbeddingGenerator()
embedding = generator.generate_embeddings("Text about AI")
```
<Check>
Default model is `BAAI/bge-small-en-v1.5`. Zero cost, zero GPU, works on any machine.
</Check>
<Warning>
**FastEmbed ignores the `device` parameter.** FastEmbed uses ONNX Runtime and manages its own execution providers: passing `device="cuda"` has no effect. Switch to `method="sentence_transformers"` if you need explicit GPU control.
</Warning>
```bash
pip install semantica # sentence-transformers included
```
```python
from semantica.embeddings import EmbeddingGenerator
generator = EmbeddingGenerator(config={
"text": {
"method": "sentence_transformers",
"model_name": "all-MiniLM-L6-v2",
}
})
```
Popular models: `all-MiniLM-L6-v2` (fast, small), `all-mpnet-base-v2` (balanced), `BAAI/bge-large-en-v1.5` (high accuracy).
<Warning>
**Sequence length limits.** Most sentence-transformers models have a 512-token limit. Text beyond that is silently truncated. Use `TextSplitter(method="hierarchical")` + `HierarchicalPooling` for long documents.
</Warning>
```bash
pip install semantica
```
```python
from semantica.embeddings import BGEStore, EmbeddingGenerator
store = BGEStore(model="BAAI/bge-large-en-v1.5")
embedding = store.embed("Text about AI")
# Or switch model on an existing EmbeddingGenerator
generator = EmbeddingGenerator()
generator.set_text_model("sentence_transformers", "BAAI/bge-large-en-v1.5")
```
```bash
pip install "semantica[llm-openai]"
export OPENAI_API_KEY="sk-..."
```
```python
import os
from semantica.embeddings import OpenAIStore
store = OpenAIStore(
api_key=os.getenv("OPENAI_API_KEY"),
model="text-embedding-3-small", # or text-embedding-3-large
)
embedding = store.embed("Text about AI")
```
| Model | Dimensions | Best for |
| :---- | :--------- | :-------- |
| `text-embedding-3-small` | 1536 | Cost-efficient retrieval |
| `text-embedding-3-large` | 3072 | Highest accuracy workloads |
Check which providers are installed in your environment:
from semantica.embeddings import check_available_providers
providers = check_available_providers()
# → {"sentence_transformers": True, "fastembed": True, "openai": False}
Getting Started
EmbeddingGenerator is the fastest path to embeddings: the default method is FastEmbed (ONNX, no GPU needed):
from semantica.embeddings import EmbeddingGenerator
# Default: FastEmbed with BAAI/bge-small-en-v1.5
generator = EmbeddingGenerator()
# Embed a single text
embedding = generator.generate_embeddings("Text about AI")
# Embed a batch
embeddings = generator.generate_embeddings(["Text about AI", "Machine learning concepts"])
# Compare two embeddings (cosine similarity: 0.0 to 1.0)
score = generator.compare_embeddings(embeddings[0], embeddings[1], method="cosine")
print(f"Similarity: {score:.3f}")
To switch provider after construction:
# Switch to a sentence-transformers model
generator.set_text_model("sentence_transformers", "all-MiniLM-L6-v2")
# Switch to BGE large
generator.set_text_model("sentence_transformers", "BAAI/bge-large-en-v1.5")
Quick Start
```python from semantica.embeddings import EmbeddingGenerator# Default: FastEmbed, free, runs locally with no GPU
generator = EmbeddingGenerator()
# Use sentence-transformers instead
generator = EmbeddingGenerator(config={"text": {"method": "sentence_transformers", "model_name": "all-MiniLM-L6-v2"}})
```
# Batch → 2D array (n_texts, dim)
embeddings = generator.generate_embeddings(["Text about AI", "Machine learning concepts"])
```
manager = VectorEmbeddingManager()
embeddings = np.array([...], dtype=np.float32)
metadata = [{"text": "doc 1"}, {"text": "doc 2"}]
result = manager.prepare_for_vector_db(embeddings, metadata=metadata, backend="faiss")
# result["vectors"] → normalized float32 array
# result["ids"] → ["vec_0", "vec_1", ...]
# result["metadata"] → formatted metadata list
```
Supported Models
| Provider | Model | Dimension | Speed | Best For |
|---|---|---|---|---|
fastembed |
BAAI/bge-small-en-v1.5 |
384 | Very fast | Default: CPU-optimised, no GPU required |
sentence_transformers |
all-MiniLM-L6-v2 |
384 | Fast | Good balance of speed and quality |
sentence_transformers |
all-mpnet-base-v2 |
768 | Medium | Higher retrieval quality |
sentence_transformers |
BAAI/bge-large-en-v1.5 |
1024 | Medium | State-of-the-art retrieval accuracy |
openai |
text-embedding-3-small |
1536 | API | Cost-effective OpenAI embedding |
openai |
text-embedding-3-large |
3072 | API | Highest quality via OpenAI API |
EmbeddingGenerator
```python from semantica.embeddings import EmbeddingGenerator# Default: FastEmbed with BAAI/bge-small-en-v1.5
generator = EmbeddingGenerator()
embeddings = generator.generate_embeddings(texts)
similarity = generator.compare_embeddings(embeddings[0], embeddings[1])
```
**Best for:** CPU-only production, lowest latency without GPU. Default: works out of the box.
generator = EmbeddingGenerator()
generator.set_text_model("sentence_transformers", "all-MiniLM-L6-v2")
embeddings = generator.generate_embeddings(texts)
```
**Best for:** higher-quality retrieval when GPU is available, or when fine-tuned models are needed.
store = OpenAIStore(api_key=os.getenv("OPENAI_API_KEY"), model="text-embedding-3-small")
embedding = store.embed("Hello world")
```
**Best for:** highest quality (`text-embedding-3-large`), or matching an existing OpenAI pipeline.
# Use CUDA via sentence-transformers
generator = EmbeddingGenerator(config={"text": {"method": "sentence_transformers", "device": "cuda"}})
# Apple Silicon (M1/M2/M3)
generator = EmbeddingGenerator(config={"text": {"method": "sentence_transformers", "device": "mps"}})
```
GPU is only applicable with sentence-transformers. FastEmbed uses ONNX and does not use `device`.
Constructor Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
config |
dict |
None |
Config dict; config["text"] is passed to TextEmbedder |
**kwargs |
Additional key/value config merged into config |
Use generator.set_text_model(method, model_name) to switch the embedding model after construction.
TextEmbedder
Direct text embedding with batch processing:
from semantica.embeddings import TextEmbedder
# Default: FastEmbed with BAAI/bge-small-en-v1.5
embedder = TextEmbedder()
# Single text → 1D array
embedding = embedder.embed_text("A knowledge graph connects entities with typed relationships.")
# Batch → 2D array (n_texts, dim)
embeddings = embedder.embed_batch(["First text", "Second text", "Third text"])
# Per-sentence embeddings
sentence_embeddings = embedder.embed_sentences("First sentence. Second sentence.")
# Get embedding dimension
dim = embedder.get_embedding_dimension()
TextEmbedder Constructor Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
model_name |
str |
"BAAI/bge-small-en-v1.5" |
Model name to load |
method |
str |
"fastembed" |
Embedding method: "fastembed" or "sentence_transformers" |
device |
str |
"cpu" |
Device for sentence-transformers: "cpu", "cuda", "mps". Ignored for FastEmbed. |
normalize |
bool |
True |
L2-normalize output vectors |
Key behaviours:
- If FastEmbed or sentence-transformers is unavailable, falls back to a 128-dimensional hash-based embedding. Hash embeddings are deterministic but not semantic: do not use in production.
- Large batches are chunked internally by the underlying library to avoid OOM.
Provider Stores
Use provider stores directly when you need fine-grained control over a single backend:
from semantica.embeddings import (
OpenAIStore, BGEStore, FastEmbedStore,
ProviderStoreFactory,
)
import os
# OpenAI
store = OpenAIStore(api_key=os.getenv("OPENAI_API_KEY"), model="text-embedding-3-small")
embedding = store.embed("Hello world")
# BGE (Sentence-Transformers wrapper): pass model_name= not model=
store = BGEStore(model_name="BAAI/bge-large-en-v1.5")
embedding = store.embed("Hello world")
# FastEmbed: ONNX runtime, no CUDA required
store = FastEmbedStore(model_name="BAAI/bge-small-en-v1.5")
embedding = store.embed("Hello world")
# FastEmbedStore also has an efficient batch method
embeddings = store.embed_batch(["text1", "text2", "text3"])
# Auto-select from a name string: useful in config-driven pipelines
# Supported providers: "openai", "bge", "fastembed"
store = ProviderStoreFactory.create(provider="bge", model_name="BAAI/bge-large-en-v1.5")
Pooling Strategies
Pooling aggregates a set of embeddings into a single vector: useful when you have multiple chunk embeddings to combine:
```python from semantica.embeddings import MeanPoolingpooler = MeanPooling()
pooled = pooler.pool(token_embeddings) # shape: (hidden_dim,)
```
**Best for:** retrieval, semantic search, and clustering: averages all contributions.
pooler = MaxPooling()
pooled = pooler.pool(token_embeddings)
```
**Best for:** capturing the presence of any feature: takes the max activation per dimension.
pooler = CLSPooling()
pooled = pooler.pool(token_embeddings)
```
**Best for:** classification-style tasks; models explicitly trained with CLS pooling (BERT).
pooler = HierarchicalPooling()
# chunk_size is passed at pool time, not at construction
pooled = pooler.pool(token_embeddings, chunk_size=10)
```
**Best for:** long documents: chunk-level mean pooling, then global mean pooling across chunks.
| Strategy | When to Use |
| :-------- | :----------- |
| `mean` | Default for retrieval, semantic search, and clustering |
| `max` | When you want to capture the presence of any feature, not average presence |
| `cls` | Classification-style tasks; models explicitly trained with CLS pooling (BERT) |
| `attention` | When token importance varies significantly; slower but more accurate |
| `hierarchical` | Long documents with many chunks; combines chunk-level then global pooling |
```python
from semantica.embeddings import PoolingStrategyFactory
pooler = PoolingStrategyFactory.create(strategy="mean")
```
GraphEmbeddingManager
Embed graph nodes and edges for storage in graph databases:
from semantica.embeddings import GraphEmbeddingManager
manager = GraphEmbeddingManager()
entities = [
{"id": "e1", "text": "Apple Inc.", "type": "Organization"},
{"id": "e2", "text": "Tim Cook", "type": "Person"},
]
relationships = [
{"source": "e2", "target": "e1", "type": "CEO_OF"}
]
# Embed entities → dict of {id: np.ndarray}
node_embeddings = manager.embed_entities(entities)
# Embed relationships → dict of {id: np.ndarray}
edge_embeddings = manager.embed_relationships(relationships)
# Or prepare everything at once for a graph DB backend
result = manager.prepare_for_graph_db(entities, relationships, backend="neo4j")
# result["node_embeddings"] → {id: np.ndarray}
# result["edge_embeddings"] → {id: np.ndarray}
# result["nodes"] → entities with "embedding" field added
# result["edges"] → relationships with "embedding" field added
Supported backends: "neo4j", "networkx", "falkordb"
VectorEmbeddingManager
Prepare and validate embeddings for vector database storage:
from semantica.embeddings import VectorEmbeddingManager
import numpy as np
manager = VectorEmbeddingManager()
embeddings = np.random.rand(5, 384).astype(np.float32)
metadata = [{"text": f"doc_{i}", "category": "science"} for i in range(5)]
# Prepare for FAISS
result = manager.prepare_for_vector_db(embeddings, metadata=metadata, backend="faiss")
# result["vectors"] → L2-normalized float32 array
# result["ids"] → ["vec_0", "vec_1", ...]
# result["metadata"] → formatted metadata list
# Validate dimensions before insertion
is_valid = manager.validate_dimensions(embeddings, backend="milvus")
# Prepare multiple batches at once
combined = manager.batch_prepare([embeddings_a, embeddings_b], backend="qdrant")
Supported backends: "faiss", "weaviate", "qdrant", "milvus"
Common Workflows
```python from semantica.embeddings import TextEmbedderembedder = TextEmbedder() # default: FastEmbed
texts = [
"Apple Inc. was founded by Steve Jobs.",
"Microsoft was co-founded by Bill Gates.",
"Amazon was started by Jeff Bezos.",
]
# All at once: more efficient than calling embed_text() per item
embeddings = embedder.embed_batch(texts)
print(f"Shape: {embeddings.shape}") # (3, 384)
```
# Check what's installed
available = check_available_providers()
# → {"sentence_transformers": True, "fastembed": True, "openai": False}
# Use the fastest available provider
generator = EmbeddingGenerator()
if available["fastembed"]:
generator.set_text_model("fastembed", "BAAI/bge-small-en-v1.5")
elif available["sentence_transformers"]:
generator.set_text_model("sentence_transformers", "all-MiniLM-L6-v2")
embeddings = generator.generate_embeddings(texts)
```
manager = GraphEmbeddingManager()
entities = [{"id": "n1", "text": "Python"}, {"id": "n2", "text": "Django"}]
node_embeddings = manager.embed_entities(entities)
# {"n1": array([...]), "n2": array([...])}
```
generator = EmbeddingGenerator()
query = generator.generate_embeddings("knowledge graph databases")
corpus = generator.generate_embeddings([
"graph databases store relationships",
"relational databases use tables",
"knowledge graphs model entity relationships",
])
scores = [calculate_similarity(query, doc, method="cosine") for doc in corpus]
ranked = sorted(zip(scores, range(len(scores))), reverse=True)
for score, idx in ranked:
print(f"{score:.3f} {['graph databases store...', 'relational databases...', 'knowledge graphs...'][idx]}")
```
Similarity Computation
from semantica.embeddings import calculate_similarity
# Cosine similarity: direction only, not magnitude; most common for text
score = calculate_similarity(embedding_a, embedding_b, method="cosine")
# → 0.0 (orthogonal / unrelated) to 1.0 (identical direction)
# Euclidean distance converted to similarity
score = calculate_similarity(embedding_a, embedding_b, method="euclidean")
Convenience Functions
from semantica.embeddings import (
embed_text, generate_embeddings, calculate_similarity,
pool_embeddings, check_available_providers,
)
# Single text: fastest path
emb = embed_text("Hello world", method="sentence_transformers")
# Batch
embs = generate_embeddings(["text1", "text2"], method="default")
# Pool multiple embeddings into one
pooled = pool_embeddings(embs, method="mean")
# Check which providers are installed
providers = check_available_providers()
# → {"sentence_transformers": True, "fastembed": True, "openai": False}
- Vector Store — Store and search the generated embeddings.
- Split — Chunk text before embedding for better retrieval quality.
- KG Module — Distance Intelligence uses graph embeddings for semantic neighbourhoods.
- Deduplication — Semantic deduplication uses embedding distance for entity resolution.