|
| 1 | +--- |
| 2 | +title: LlamaEmbedding |
| 3 | +class_name: LlamaEmbedding |
| 4 | +last_updated: 2026-04-27 |
| 5 | +version_target: "latest" |
| 6 | +--- |
| 7 | + |
| 8 | +# LlamaEmbedding |
| 9 | + |
| 10 | +## Overview |
| 11 | + |
| 12 | +`LlamaEmbedding` is a specialized class for high-performance Text Embedding and Reranking. It inherits from the base `Llama` class but is optimized for vector operations. |
| 13 | + |
| 14 | +### Support Embeddings & Rerank Model: |
| 15 | + |
| 16 | + |
| 17 | +| Model | Type | Link | Status | |
| 18 | +|--------------------|-----------|--------------------------------------------------------|--------------| |
| 19 | +| `bge-m3` | Embedding |[bge-m3-GGUF](https://huggingface.co/gpustack/bge-m3-GGUF) | Useful ✅ | |
| 20 | +|`bge-reranker-v2-m3`| Rerank |[bge-reranker-v2-m3-GGUF](https://huggingface.co/gpustack/bge-reranker-v2-m3-GGUF) | Useful ✅ | |
| 21 | +|`qwen3-reranker`| Rerank |[Qwen3-Reranker-GGUF](https://huggingface.co/JamePeng2023/Qwen3-Reranker-GGUF) | Useful ✅ | |
| 22 | + |
| 23 | +**Core Features:** |
| 24 | +1. **Auto-configuration**: Automatically sets `embeddings=True`. |
| 25 | +2. **Streaming Batch**: Handles massive datasets without OOM (Out Of Memory). |
| 26 | +3. **Native Reranking Support**: Specifically handles `LLAMA_POOLING_TYPE_RANK` models (like BGE-Reranker, Qwen3-Reranker). It correctly identifies classification heads to output scalar relevance scores instead of high-dimensional vectors. |
| 27 | +4. **Advanced Normalization**: Implements MaxInt16, Taxicab (L1), and Euclidean (L2) normalization strategies using NumPy for optimal performance and compatibility with various vector databases. |
| 28 | + |
| 29 | +## Constructor `__init__` |
| 30 | + |
| 31 | +| Parameter | Type | Default | Description | |
| 32 | +|-----------|------|---------|-------------| |
| 33 | +| `model_path` | str | Required | Path to the GGUF model file. | |
| 34 | +| `n_ctx` | int | 0 | Text context window size (0 = model default). | |
| 35 | +| `n_batch` | int | 512 | Maximum prompt processing batch size. | |
| 36 | +| `n_ubatch` | int | 512 | Physical batch size. | |
| 37 | +| `pooling_type` | int | `LLAMA_POOLING_TYPE_UNSPECIFIED` (-1) | Pooling strategy used by the model: `LLAMA_POOLING_TYPE_RANK` (4) for rerankers, `LLAMA_POOLING_TYPE_UNSPECIFIED` (-1) for embeddings. | |
| 38 | +| `n_gpu_layers` | int | 0 | Number of layers offloaded to GPU (0 = CPU only, -1 = all layers). | |
| 39 | +| `verbose` | bool | True | Whether to print debug information. | |
| 40 | +| `**kwargs` | Any | — | Extra arguments passed to the `Llama` base class (e.g., `n_batch`, `n_ctx`, `verbose`). | |
| 41 | + |
| 42 | +### Initialization Logic |
| 43 | + |
| 44 | +1. Forces `embeddings=True` to enable embedding support. |
| 45 | +2. Sets `kv_unified=True` to enable unified KV Cache, allowing arbitrary sequence IDs in a batch without "invalid seq_id" errors. |
| 46 | +3. Passes `pooling_type` to the parent class constructor. |
| 47 | + |
| 48 | +## Core Methods |
| 49 | + |
| 50 | +### `embed(input, normalize=NORM_MODE_EUCLIDEAN, truncate=True, separator=None, return_count=False)` |
| 51 | + |
| 52 | +**Description**: Computes embedding vectors for input text (standard embeddings or reranking scores). |
| 53 | + |
| 54 | +| Parameter | Type | Default | Description | |
| 55 | +|-----------|------|---------|-------------| |
| 56 | +| `input` | `Union[str, List[str], List[List[int]]]` | — | Input format: string (can be split), list of strings, or list of integer lists (token IDs). | |
| 57 | +| `normalize` | int | `NORM_MODE_EUCLIDEAN` (2) | Vector normalization mode (see below). | |
| 58 | +| `truncate` | bool | True | Whether to truncate input. | |
| 59 | +| `separator` | str | None | Separator for splitting string input into multiple documents. | |
| 60 | +| `return_count` | bool | False | If True, returns `(embeddings, token_count)`. | |
| 61 | + |
| 62 | +**Normalization Modes:** |
| 63 | +- `NORM_MODE_NONE` (-1): No normalization. |
| 64 | +- `NORM_MODE_MAX_INT16` (0): Max absolute value normalization (scaled to 32760). |
| 65 | +- `NORM_MODE_TAXICAB` (1): L1 Taxicab norm. |
| 66 | +- `NORM_MODE_EUCLIDEAN` (2): L2 Euclidean norm. |
| 67 | +- `NORM_MODE_PNORM` (>2): p-norm normalization. |
| 68 | + |
| 69 | +**Returns:** |
| 70 | +- `return_count=False`: List of embedding vectors. |
| 71 | +- `return_count=True`: Tuple `(embeddings, token_count)`. |
| 72 | + |
| 73 | +**Internal Logic:** |
| 74 | +1. Determines mode based on `pooling_type`: `LLAMA_POOLING_TYPE_NONE` (token-level), `LLAMA_POOLING_TYPE_RANK` (rerank), or other (sequence-level). |
| 75 | +2. Uses streaming batch decoding to process embeddings in chunks. |
| 76 | +3. For token-level mode, extracts and normalizes per-token vectors. |
| 77 | +4. For sequence-level mode, extracts sequence vectors and normalizes. |
| 78 | +5. Supports `separator` for splitting input into multiple documents. |
| 79 | + |
| 80 | +### `rank(query, documents)` |
| 81 | + |
| 82 | +**Description**: Calculates relevance scores for a list of documents against a query using a Reranking model. |
| 83 | + |
| 84 | +| Parameter | Type | Description | |
| 85 | +|-----------|------|-------------| |
| 86 | +| `query` | str | Search query string. | |
| 87 | +| `documents` | `List[str]` | List of candidate document strings to be scored. | |
| 88 | + |
| 89 | +**Returns**: List of float scores, where higher values indicate greater relevance. |
| 90 | + |
| 91 | +**Internal Logic:** |
| 92 | +1. Checks if model is a reranker (`pooling_type == LLAMA_POOLING_TYPE_RANK`). |
| 93 | +2. Attempts to retrieve the built-in 'rerank' chat template. |
| 94 | +3. If template exists: dynamically replaces `{query}` and `{document}` and tokenizes; otherwise, manually constructs `[BOS] Query [SEP] Doc [EOS]` sequence. |
| 95 | +4. Executes embedding inference (`embed`), returning raw logits/scores. |
| 96 | +5. For generative rerankers (e.g., Qwen3-Reranker, output dim = 2), uses `yes_logit` as relevance score. |
| 97 | + |
| 98 | +### `create_embedding(input, model=None, normalize=NORM_MODE_EUCLIDEAN, output_format="json")` |
| 99 | + |
| 100 | +**Description**: High-level API compatible with OpenAI format. |
| 101 | + |
| 102 | +| Parameter | Type | Default | Description | |
| 103 | +|-----------|------|---------|-------------| |
| 104 | +| `input` | `Union[str, List[str]]` | — | Input text or list of texts. | |
| 105 | +| `model` | str | None | Model name (optional, uses `self.model_path` if None). | |
| 106 | +| `normalize` | int | `NORM_MODE_EUCLIDEAN` (2) | Normalization mode. | |
| 107 | +| `output_format` | str | "json" | Output format: 'json', 'json+', or 'array'. | |
| 108 | + |
| 109 | +**Output Formats:** |
| 110 | +- `'json'`: OpenAI-style dictionary list. |
| 111 | +- `'json+'`: OpenAI dictionary list + cosine similarity matrix. |
| 112 | +- `'array'`: Raw Python list (`List[float]` or `List[List[float]]`). |
| 113 | + |
| 114 | +**Returns**: Data structure according to `output_format`. |
| 115 | + |
| 116 | +## Deprecated / Changed APIs |
| 117 | + |
| 118 | +- **Note**: The TODO comments `# TODO(JamePeng): Needs more extensive testing with various embedding and reranking models.` indicate that support for various embedding and reranking models may be incomplete. Further testing is recommended. |
| 119 | + |
| 120 | +## Best Practices & Common Patterns |
| 121 | + |
| 122 | +1. **Select Correct `pooling_type`**: |
| 123 | + - Standard embeddings: `LLAMA_POOLING_TYPE_UNSPECIFIED (-1)`. |
| 124 | + - Reranker models: `LLAMA_POOLING_TYPE_RANK (4)`. |
| 125 | + - Token-level embeddings: `LLAMA_POOLING_TYPE_NONE (0)`. |
| 126 | + |
| 127 | +2. **Batch Optimization for Large Datasets**: |
| 128 | + - Adjust `n_batch` and `n_ubatch` to balance performance and memory. |
| 129 | + - Streaming processing avoids OOM for large datasets. |
| 130 | + |
| 131 | +3. **Normalization Selection**: |
| 132 | + - Vector databases typically prefer L2 normalization (Euclidean), but other norms may be needed in specific scenarios. |
| 133 | + |
| 134 | +4. **Reranker Models**: |
| 135 | + - Ensure `pooling_type` is set to `LLAMA_POOLING_TYPE_RANK`. |
| 136 | + - Note that output is scalar scores, not vectors. |
| 137 | + |
| 138 | +5. **Performance Tuning**: |
| 139 | + - For GPU acceleration, set `n_gpu_layers` to -1 (recommended). |
| 140 | + - Use `verbose=True` for debugging configuration. |
| 141 | + |
| 142 | +## Example Code |
| 143 | + |
| 144 | +### 1. Text Embeddings (Vector Search) |
| 145 | + |
| 146 | +To generate embeddings, use the `LlamaEmbedding` class. It automatically configures the model for vector generation. |
| 147 | + |
| 148 | +```python |
| 149 | +from llama_cpp.llama_embedding import LlamaEmbedding, LLAMA_POOLING_TYPE_NONE |
| 150 | + |
| 151 | +# Initialize the model (automatically sets embeddings=True) |
| 152 | +llm = LlamaEmbedding(model_path="path/to/bge-m3.gguf", n_gpu_layers=-1, pooling_type=LLAMA_POOLING_TYPE_NONE) |
| 153 | + |
| 154 | +# 1. Simple usage (OpenAI-compatible format) |
| 155 | +response = llm.create_embedding("Hello, world!") |
| 156 | +print(response['data'][0]['embedding']) |
| 157 | + |
| 158 | +# 2. Batch processing (High Performance) |
| 159 | +# You can pass a large list of strings; the streaming batcher handles memory automatically. |
| 160 | +documents = ["Hello, world!", "Goodbye, world!", "Llama is cute."] * 100 |
| 161 | +embeddings = llm.embed(documents) # Returns a list of lists (vectors) |
| 162 | + |
| 163 | +print(f"Generated {len(embeddings)} vectors.") |
| 164 | +``` |
| 165 | + |
| 166 | +**Advanced Output Formats:** |
| 167 | +You can request raw arrays or cosine similarity matrices directly: |
| 168 | + |
| 169 | +```python |
| 170 | +from llama_cpp.llama_embedding import LlamaEmbedding, LLAMA_POOLING_TYPE_NONE |
| 171 | + |
| 172 | +# Initialize the model (automatically sets embeddings=True) |
| 173 | +llm = LlamaEmbedding(model_path="path/to/bge-m3.gguf", n_gpu_layers=-1, pooling_type=LLAMA_POOLING_TYPE_NONE) |
| 174 | + |
| 175 | +# Returns raw List[float] instead of a dictionary wrapper |
| 176 | +vector = llm.create_embedding("Text", output_format="array") |
| 177 | + |
| 178 | +# Returns a similarity matrix (A @ A.T) in the response |
| 179 | +# Note: Requires numpy installed |
| 180 | +response = llm.create_embedding( |
| 181 | + ["apple", "fruit", "car"], |
| 182 | + output_format="json+" |
| 183 | +) |
| 184 | +print(response["cosineSimilarity"]) |
| 185 | +``` |
| 186 | + |
| 187 | +### 2. Reranking (Cross-Encoder Scoring) |
| 188 | + |
| 189 | +Reranking models (like `bge-reranker`) take a **Query** and a list of **Documents** as input and output a relevance score (scalar) for each document. |
| 190 | + |
| 191 | +> **Important:** You must explicitly set `pooling_type` to `LLAMA_POOLING_TYPE_RANK` (4) when initializing the model. |
| 192 | +
|
| 193 | +```python |
| 194 | +import llama_cpp |
| 195 | +from llama_cpp.llama_embedding import LlamaEmbedding |
| 196 | + |
| 197 | +# Initialize a Reranking model |
| 198 | +ranker = LlamaEmbedding( |
| 199 | + model_path="path/to/qwen3-reranker-0.6b-q8_0.gguf", |
| 200 | + pooling_type=llama_cpp.LLAMA_POOLING_TYPE_RANK, # Crucial for Rerankers! |
| 201 | + n_gpu_layers=-1, |
| 202 | + n_ctx=0 |
| 203 | +) |
| 204 | + |
| 205 | +query = "What causes Rain?" |
| 206 | +docs = [ |
| 207 | + "Clouds are made of water droplets...", # Relevant |
| 208 | + "To bake a cake you need flour...", # Irrelevant |
| 209 | + "Rain is liquid water in the form of droplets..." # Highly Relevant |
| 210 | +] |
| 211 | + |
| 212 | +# Calculate relevance scores |
| 213 | +# Logic: Constructs inputs like "[BOS] query [SEP] doc [EOS]" automatically |
| 214 | +scores = ranker.rank(query, docs) |
| 215 | + |
| 216 | +# Result: List of floats (higher means more relevant) |
| 217 | +print(scores) |
| 218 | +# e.g., [0.0011407170677557588, 5.614783731289208e-05, 0.7173627614974976] -> The 3rd doc is the best match |
| 219 | +``` |
| 220 | + |
| 221 | +### 3. Normalization |
| 222 | + |
| 223 | +The `embed` method supports various mathematical normalization strategies via the `normalize` parameter. |
| 224 | + |
| 225 | +| Normalization modes | $Integer$ | Description | Formula | |
| 226 | +|---------------------|-----------|---------------------|---------| |
| 227 | +| NORM_MODE_NONE | $-1$ | none | |
| 228 | +| NORM_MODE_MAX_INT16 | $0$ | max absolute int16 | $\Large{{32760 * x_i} \over\max \lvert x_i\rvert}$ |
| 229 | +| NORM_MODE_TAXICAB | $1$ | taxicab | $\Large{x_i \over\sum \lvert x_i\rvert}$ |
| 230 | +| NORM_MODE_EUCLIDEAN | $2$ | euclidean (default) | $\Large{x_i \over\sqrt{\sum x_i^2}}$ |
| 231 | +| NORM_MODE_PNORM | $>2$ | p-norm | $\Large{x_i \over\sqrt[p]{\sum \lvert x_i\rvert^p}}$ |
| 232 | + |
| 233 | +This is useful for optimizing storage or preparing vectors for cosine similarity search (which requires L2 normalization). |
| 234 | + |
| 235 | +```python |
| 236 | +from llama_cpp.llama_embedding import ( |
| 237 | + LLAMA_POOLING_TYPE_NONE, |
| 238 | + NORM_MODE_MAX_INT16, |
| 239 | + NORM_MODE_TAXICAB, |
| 240 | + NORM_MODE_EUCLIDEAN |
| 241 | +) |
| 242 | + |
| 243 | +# Initialize the model (automatically sets embeddings=True) |
| 244 | +llm = LlamaEmbedding(model_path="path/to/bge-m3.gguf", n_gpu_layers=-1, pooling_type=LLAMA_POOLING_TYPE_NONE) |
| 245 | + |
| 246 | +# Taxicab (L1) |
| 247 | +vec_l1 = llm.embed("text", normalize=NORM_MODE_TAXICAB) |
| 248 | + |
| 249 | +# Default is Euclidean (L2) - Standard for vector databases |
| 250 | +vec_l2 = llm.embed("text", normalize=NORM_MODE_EUCLIDEAN) |
| 251 | + |
| 252 | +# Max Absolute Int16 - Useful for quantization/compression |
| 253 | +vec_int16 = llm.embed("text", normalize=NORM_MODE_MAX_INT16) |
| 254 | + |
| 255 | +# Raw Output (No Normalization) - Get the raw floating point values from the model |
| 256 | +embeddings_raw = llm.embed(["search query", "document text"], normalize=NORM_MODE_NONE) |
| 257 | +``` |
| 258 | + |
| 259 | +## Notes |
| 260 | + |
| 261 | +- This class is in development; some features may be unstable, especially reranking model support. |
| 262 | +- Performance issues can be addressed by adjusting `n_batch`, `n_ubatch`, and `n_gpu_layers`. |
| 263 | +- For custom models, manual `pooling_type` configuration may be required to match model behavior. |
0 commit comments