Skip to content

Commit 72f6283

Browse files
jimmckeethclaude
andauthored
Add Embedding Options guide and model discovery script (#188)
* Add EMBEDDINGS.md guide and model discovery script (fixes #181) * fix(scripts): fix ruff lint and format violations in find_best_models.py - Replace bare `except:` with `except Exception:` (E722) - Expand inline `if x: return y` to multi-line (E701) - Break long lines >100 chars (E501) - Move docstring above imports; sort stdlib before third-party (I001) - Remove unused `numpy` and `datetime` imports (F401) - Fix `== True` comparison to use truthiness directly (E712) - Remove trailing whitespace in string literals (W291/W293) https://claude.ai/code/session_01GguRSHkNNjDxvP4o8Va2Kp * chore:formatting, fix lint errors, formatting and cleanup --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 7aa2d8f commit 72f6283

3 files changed

Lines changed: 470 additions & 0 deletions

File tree

EMBEDDINGS.md

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
# Embedding Options
2+
3+
[`cocoindex-code`](https://github.com/cocoindex-io/cocoindex-code) supports a variety of embedding models and providers. This guide helps you choose the right path for your hardware, privacy requirements, and codebase size.
4+
5+
<p align="center"><a href="https://github.com/cocoindex-io/cocoindex-code"><img width="2428" alt="cocoindex code" src="https://github.com/user-attachments/assets/d05961b4-0b7b-42ea-834a-59c3c01717ca" /></a></p>
6+
7+
## Table of Contents
8+
9+
- [Which Path Should I Choose?](#which-path-should-i-choose)
10+
- [Understanding Speed, Context, and Performance](#understanding-speed-context-and-performance)
11+
- [The `ccc init` Wizard](#the-ccc-init-wizard)
12+
- **[Local Sentence-Transformers](#sentence-transformers-local)**
13+
- **[LiteLLM Remote (Cloud Providers)](#litellm-remote-cloud-providers)**
14+
- **[LiteLLM Local](#local-litellm-providers)**
15+
- [Choosing Based on Your Content](#choosing-based-on-your-content)
16+
- [Pacing & Rate Limits](#pacing--rate-limits)
17+
18+
---
19+
20+
## Which Path Should I Choose?
21+
22+
| Path | Best For... | Key Advantage | Trade-off |
23+
| :--- | :--- | :--- | :--- |
24+
| **Local Sentence-Transformers** | Most users, laptops, quick setup. | **Fastest** (in-process), private, offline. | Larger initial pip install (`[full]`). |
25+
| **Cloud LiteLLM Remote** | Large codebases, weak local hardware. | Top performance, zero local resource usage. | Per-token costs, data leaves machine. |
26+
| **Local LiteLLM** | Power users, shared GPU resources. | Flexibility, unified model management. | Requires managing a separate server. |
27+
28+
---
29+
30+
## Understanding Speed, Context, and Performance
31+
32+
### Speed & Latency
33+
34+
- **Local Sentence-Transformers**: Typically the **fastest** option for small-to-medium models. Because it runs directly inside the `cocoindex-code` process, it avoids the network latency of Cloud APIs and the communication overhead of Local Servers (Ollama).
35+
- **Local Servers (Ollama)**: Ideal for running **heavy models** (like `mxbai-embed-large`) on a GPU. While it has slight overhead compared to in-process execution, it is much faster than running large models on a CPU.
36+
- **Cloud APIs**: Slower per-request due to network latency, but highly parallel. Best for the initial indexing of massive repositories.
37+
38+
### Does Context Size Matter?
39+
40+
Most local models have a **512-token** context window, while cloud models (OpenAI, Voyage) support **8k to 32k**.
41+
42+
In `cocoindex-code`, this matters less than you might expect due to our **Language-Aware Chunking** strategy:
43+
44+
- **Logical Boundaries**: The tool uses Tree-Sitter to understand code structure. It tries to split files at logical boundaries like functions, classes, or methods.
45+
- **Target Size**: While respecting boundaries, it targets a chunk size of **~1,000 characters** (~300 tokens).
46+
- **Compatibility**: This hybrid approach ensures code snippets are contextually coherent while remaining small enough to fit perfectly within even the smallest 512-token context windows.
47+
48+
### CPU vs. GPU
49+
50+
- The default `xs` model is optimized for **CPUs**; you likely won't see a benefit from a GPU.
51+
- For `medium` or `large` models, a GPU is highly recommended. If you have one, you can tell Sentence-Transformers to use it by adding `device: cuda` (or `mps` for Mac) to your `global_settings.yml`.
52+
53+
---
54+
55+
## The `ccc init` Wizard
56+
57+
The easiest way to configure embeddings is by running `ccc init`. On first run, it will guide you through an interactive wizard. To reconfigure later, delete `~/.cocoindex_code/global_settings.yml` and re-run.
58+
59+
1. **Provider Selection**: Choose between `sentence-transformers` (local, free) or `litellm` (cloud/local server).
60+
2. **Model Selection**: Enter a HuggingFace ID or a LiteLLM model string (e.g., `voyage/voyage-code-3`).
61+
3. **Automatic Tuning**: `ccc init` will automatically apply curated defaults (like `input_type` or `prompt_name`) and test the connection.
62+
63+
---
64+
65+
## Sentence-Transformers (Local)
66+
67+
This option runs embedding models directly on your machine using the library.
68+
69+
### Recommended Models
70+
71+
These are based on MTEB [datasets](https://huggingface.co/datasets/mteb/results) as of 13-Jun-2026.
72+
73+
| Tier | Model | Params | Code Score | Best For |
74+
| :--- | :--- | :--- | :--- | :--- |
75+
| **Micro** | [`Snowflake/arctic-embed-xs`](https://huggingface.co/Snowflake/snowflake-arctic-embed-xs) | 22M | 0.67 | Old CPUs, minimal RAM usage. |
76+
| **Small** | [`ibm-granite/granite-embedding-97m-multilingual-r2`](https://huggingface.co/ibm-granite/granite-embedding-97m-multilingual-r2) | 97M | 0.80 | Modern laptops, multilingual code. |
77+
| **Medium** | [`jinaai/jina-embeddings-v5-text-nano`](https://huggingface.co/jinaai/jina-embeddings-v5-text-nano) | 239M | **0.90** | **Performance sweet spot.** BERT-based (Fast). |
78+
| **High** | [`geevec-ai/geevec-embeddings-1.0-lite`](https://huggingface.co/geevec-ai/geevec-embeddings-1.0-lite) | 366M | **0.92** | Maximum local accuracy (needs GPU for speed). |
79+
80+
#### Other Model Options
81+
82+
The default of `Snowflake/arctic-embed-xs` is a good choice in most situations, but if you want other options...
83+
84+
- **Discovery Script**: The easiest way is to run our included script to find the current best models for your hardware: `uv run scripts/find_best_models.py`.
85+
- **MTEB v3 Leaderboard**: For manual discovery, visit the [MTEB v3 Leaderboard](https://huggingface.co/spaces/mteb/leaderboard):
86+
1. Go to the **Benchmarks** tab
87+
2. Select **Code Information Retrieval (CoIR)**.
88+
3. Filter **Model Type** to **Dense**.
89+
4. Enable the **Sentence-Transformers Compatible** toggle.
90+
5. Adjust **Model Size** to fit your hardware (e.g., `< 500M` for CPUs).
91+
- **Compatibility**: Look for **Bi-encoders** with a fixed dimension size (e.g., 384, 768, 1024). Avoid "Late Interaction" (ColBERT) or "Cross-Encoders".
92+
- **Architecture**: **Encoder** models (BERT-based) are much faster on CPUs than **Decoder** models (LLM-based).
93+
94+
### Installation & Configuration
95+
96+
Install with the `full` extra: `pip install "cocoindex-code[full]"`.
97+
98+
Example `global_settings.yml`:
99+
100+
```yaml
101+
embedding:
102+
provider: sentence-transformers
103+
model: jinaai/jina-embeddings-v5-text-nano
104+
device: cpu # Use 'cuda' or 'mps' if you have a GPU
105+
```
106+
107+
For more information, see the [Sentence-Transformers Documentation](https://sbert.net/).
108+
109+
[Back to top](#table-of-contents)
110+
111+
---
112+
113+
## LiteLLM Remote (Cloud Providers)
114+
115+
Use external API providers for high-quality embeddings via the LiteLLM bridge.
116+
117+
### Recommendations
118+
119+
Well ranked in the MTEB v3 benchmarks
120+
121+
- **Voyage AI ([`voyage-4-large`](https://docs.voyageai.com/docs/embeddings))**: Current #1 for code (Score: **0.97**).
122+
- **Gemini ([`text-embedding-004`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/text-embeddings))**: Top-tier performance (Score: **0.97**) with a generous free tier.
123+
- **OpenAI ([`text-embedding-3-small`](https://platform.openai.com/docs/guides/embeddings))**: Reliable and very cost-effective for large codebases.
124+
125+
### Configuration
126+
127+
Example for Voyage AI:
128+
129+
```yaml
130+
embedding:
131+
provider: litellm
132+
model: voyage/voyage-4-large
133+
envs:
134+
VOYAGE_API_KEY: your-api-key-here
135+
```
136+
137+
For more information, see the [LiteLLM Providers Documentation](https://docs.litellm.ai/docs/providers).
138+
139+
[Back to top](#table-of-contents)
140+
141+
---
142+
143+
## Local LiteLLM Providers
144+
145+
Connect to a local embedding server (Ollama, llama.cpp or compatible) for privacy and flexibility.
146+
147+
### Ollama
148+
149+
Ensure Ollama is running and you have pulled the model (`ollama pull jina/jina-embeddings-v5`).
150+
151+
**Suggested Models:**
152+
153+
- **Low-end**: `ollama/all-minilm`
154+
- **Mid-range**: `ollama/jina-embeddings-v5`
155+
- **High-end**: `ollama/mxbai-embed-large`
156+
157+
**Configuration:**
158+
159+
```yaml
160+
embedding:
161+
provider: litellm
162+
model: ollama/jina-embeddings-v5
163+
```
164+
165+
See the [Ollama Model Library](https://ollama.com/library?q=embedding&sort=popular) for more options.
166+
167+
---
168+
169+
### llama.cpp
170+
171+
If you prefer running `llama.cpp` directly (e.g., using `llama-server`), you can connect via the OpenAI-compatible interface.
172+
173+
**Configuration:**
174+
175+
1. Start your server: `llama-server --embedding -m your_model.gguf`
176+
2. Configure `global_settings.yml`:
177+
178+
```yaml
179+
embedding:
180+
provider: litellm
181+
model: openai/your-model-name
182+
envs:
183+
OPENAI_API_BASE: http://localhost:8080/v1
184+
OPENAI_API_KEY: "not-needed"
185+
```
186+
187+
[Back to top](#table-of-contents)
188+
189+
---
190+
191+
## Choosing Based on Your Content
192+
193+
- **Heavy Source Code**: Use **Jina v5 Nano** (Local) or **Voyage 4 Large** (Cloud). Both score >0.90 on code search benchmarks.
194+
- **Large Documentation / Files**: Models with large context windows (8k+ tokens) like **Jina v5** (32k) or **OpenAI v3 Large** (8k).
195+
- **Multilingual Projects**: **Granite 97m** (Small Local) or **Cohere Multilingual v3** (Cloud).
196+
197+
### Fine-Tuning with `indexing_params` and `query_params`
198+
199+
The `ccc init` wizard will automatically apply recommended defaults for known models.
200+
201+
**Example for LiteLLM (Voyage, Gemini):**
202+
203+
```yaml
204+
embedding:
205+
provider: litellm
206+
model: voyage/voyage-4-large
207+
indexing_params:
208+
input_type: document
209+
query_params:
210+
input_type: query
211+
```
212+
213+
**Example for Sentence-Transformers (Jina):**
214+
215+
```yaml
216+
embedding:
217+
provider: sentence-transformers
218+
model: jinaai/jina-embeddings-v5-text-nano
219+
indexing_params:
220+
prompt_name: retrieval.passage
221+
query_params:
222+
prompt_name: retrieval.query
223+
```
224+
225+
---
226+
227+
## Pacing & Rate Limits
228+
229+
When using cloud providers, you often encounter rate limits (number of requests per minute). `cocoindex-code` provides several mechanisms to manage this:
230+
231+
- **`min_interval_ms` (Pacing)**: Introduces a mandatory delay between requests (e.g., `500` for 2 req/sec).
232+
- **Automatic Retries**: The daemon automatically retries rate-limited requests (429 errors) with exponential backoff (up to 6 times).
233+
- **Batching**: `cocoindex-code` automatically batches up to 64 text chunks into a single API request to maximize throughput.
234+
235+
[Back to top](#table-of-contents)

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,8 @@ docker build -t cocoindex-code:local -f docker/Dockerfile .
391391

392392
## Configuration
393393

394+
For a detailed guide on choosing and configuring embedding models, see [EMBEDDINGS.md](EMBEDDINGS.md).
395+
394396
Configuration lives in two YAML files, both created automatically by `ccc init`.
395397

396398
### User Settings (`~/.cocoindex_code/global_settings.yml`)

0 commit comments

Comments
 (0)