~/ / Статьи об ИИ / Локальные LLM на VPS / Эмбеддинги в Ollama: основы поиска и RAG
Эмбеддинги в Ollama: основы поиска и RAG
Поиск, который находит фрагменты текста по смыслу, и RAG, где чат-модель отвечает по вашим собственным документам, начинаются с эмбеддингов. Ollama может создавать их на том же сервере, где работает ваша чат-модель. В этой статье разобраны запрос, модели, которые перечислены в библиотеке Ollama, настройки, влияющие на результат, и сравнение векторов, причём только по тому, что сказано в документации и на страницах библиотеки Ollama. Два инструмента на этой странице позволяют попробовать эти шаги в браузере.
Опубликовано: · 4 мин чтения · Факты проверены по документации и страницам библиотеки Ollama 2026-11-04. Модели и поля меняются, поэтому перед использованием сверяйтесь с актуальными страницами.
Что такое эмбеддинг
На странице Ollama об эмбеддингах сказано, что эмбеддинги превращают текст в числовые векторы, которые можно хранить в векторной базе данных, искать по косинусному сходству или использовать в конвейерах RAG. Длина вектора зависит от модели; на странице указано, как правило, от 384 до 1024 измерений.
Поиск создаёт эмбеддинг вопроса той же моделью и ищет сохранённые векторы, наиболее похожие на него.
Создание эмбеддингов через /api/embed
Эндпоинт — POST /api/embed. В запросе нужны model и input, причём input может быть одной строкой или массивом строк. Если передан массив, ответ содержит в поле embeddings по одному вектору на строку, в том же порядке, так что для пакета фрагментов текста достаточно одного запроса.
В документации показана и командная строка: ollama run embeddinggemma "Hello world" выводит вектор в виде массива JSON, а текст можно передать по конвейеру через echo.
| Поле | Что сказано в справочнике API |
|---|---|
| model | Обязательное. Имя модели. |
| input | Обязательное. Текст или массив текстов. |
| truncate | По умолчанию true: ввод, превышающий контекстное окно, обрезается. При false возвращается ошибка. |
| dimensions | Число измерений, для которых создаются эмбеддинги. |
| keep_alive | Как долго модель остаётся загруженной. |
| options | Параметры выполнения, например num_ctx для длины контекста. |
У Ollama есть и эндпоинт, совместимый с OpenAI, /v1/embeddings. В его документации как поддерживаемые указаны model, input в виде строки или массива строк, encoding format и dimensions, а как неподдерживаемые — массивы токенов и user.
Модели эмбеддингов в библиотеке Ollama
В библиотеке Ollama есть категория эмбеддингов. В таблице показаны шесть перечисленных там моделей, с размером и контекстным окном, которые страница тегов каждой модели указывает для последнего тега. Четыре из шести занимают меньше 1GB.
| Модель | Размер последнего тега | Контекстное окно |
|---|---|---|
| all-minilm | 46MB | 512 |
| nomic-embed-text | 274MB | 2K |
| embeddinggemma | 622MB | 2K |
| mxbai-embed-large | 670MB | 512 |
| bge-m3 | 1.2GB | 8K |
| qwen3-embedding | 4.7GB | 40K |
Другие теги меняют размер: например, библиотека указывает qwen3-embedding:0.6b с 639MB и контекстным окном 32K, а embeddinggemma:300m-qat-q4_0 — с 239MB. Качество этих моделей мы не сравнивали; страницы библиотеки не ранжируют их. Когда мы попробовали all-minilm в Ollama 0.40.11, ollama show показал длину контекста 512 и параметр num_ctx, равный 256, а длинный ввод был обрезан на 256 токенах. Проверьте ollama show для модели, которую используете.
Длинный ввод обрезается без ошибки
Контекстное окно считается в токенах. Поскольку truncate по умолчанию равен true, текст длиннее контекстного окна модели сокращается и всё равно возвращает вектор, без ошибки. Длинный документ, отправленный одним вводом, может таким образом потерять свой конец.
Помогают две вещи. Разделите длинные документы на более мелкие чанки и создавайте эмбеддинг каждого из них, что заодно позволяет поиску вернуть именно ту часть, которая отвечает на вопрос. И отправляйте truncate со значением false, чтобы Ollama возвращала ошибку, а не сокращала чанк, который всё ещё слишком длинный.
Чанкер ниже делит текст по абзацам, строкам, предложениям и пробелам, с перекрытием, и собирает один запрос /api/embed для всех чанков. Он считает символы, а не токены, потому что у каждой модели свой токенизатор, поэтому оставьте запас ниже контекстного окна.
Попробовать: RAG Text Chunker
Длины указаны в символах. Контекстное окно модели считается в токенах, а сколько токенов занимает текст, зависит от модели, поэтому оставьте запас.
Команда curl
Выполните её на компьютере, который может обратиться к Ollama. В ответе будет по одному вектору на чанк, в этом порядке.
curl http://localhost:11434/api/embed -d '{
"model": "embeddinggemma",
"input": [
"Embeddings turn text into numeric vectors. You can store them in a vector database and search them with cosine similarity, or use them in a RAG pipeline.\n\nThe length of each vector depends on the embedding model. Use the same model when you index your documents and when you embed a question.\n\n",
"Ollama'\''s /api/embed endpoint takes a single string or an array of strings. By default, input that is longer than the model'\''s context window is truncated. Set truncate to false to get an error instead.\n\n",
"Split long documents into smaller chunks before you embed them, so that each chunk fits in the context window and a search can return the part that answers the question."
],
"truncate": false
}'Чанки
Чанков: 3. Самый длинный — 294 символов.
#0 · символов: 294 · начинается со смещения 0
Embeddings turn text into numeric vectors. You can store them in a vector database and search them with cosine similarity, or use them in a RAG pipeline. The length of each vector depends on the embedding model. Use the same model when you index your documents and when you embed a question.
#1 · символов: 202 · начинается со смещения 294
Ollama's /api/embed endpoint takes a single string or an array of strings. By default, input that is longer than the model's context window is truncated. Set truncate to false to get an error instead.
#2 · символов: 169 · начинается со смещения 496
Split long documents into smaller chunks before you embed them, so that each chunk fits in the context window and a search can return the part that answers the question.
Тело JSON для /api/embed
{
"model": "embeddinggemma",
"input": [
"Embeddings turn text into numeric vectors. You can store them in a vector database and search them with cosine similarity, or use them in a RAG pipeline.\n\nThe length of each vector depends on the embedding model. Use the same model when you index your documents and when you embed a question.\n\n",
"Ollama's /api/embed endpoint takes a single string or an array of strings. By default, input that is longer than the model's context window is truncated. Set truncate to false to get an error instead.\n\n",
"Split long documents into smaller chunks before you embed them, so that each chunk fits in the context window and a search can return the part that answers the question."
],
"truncate": false
}Поля запроса по справочнику API Ollama для /api/embed, проверено 2026-11-04. Ollama API: Generate embeddings
Всё выполняется в вашем браузере. Инструмент лишь записывает команду и ничего не отправляет.
Одна модель для индексации и поиска
На странице об эмбеддингах сказано использовать одну и ту же модель эмбеддингов и для индексации, и для запросов. Длина вектора зависит от модели, поэтому у векторов двух разных моделей может не совпадать даже число измерений.
То же относится к dimensions: если вы задаёте его при индексации документов, задайте то же значение при создании эмбеддингов вопросов. Если вы меняете модель или эту настройку, создайте эмбеддинги сохранённых документов заново.
Сравнение векторов
Документация рекомендует косинусное сходство для большинства случаев семантического поиска и сообщает, что /api/embed возвращает векторы, нормализованные по L2, единичной длины. Для векторов единичной длины косинусное сходство и скалярное произведение — одно и то же число, поэтому векторная база данных, настроенная на любое из них, упорядочит результаты одинаково.
Чтобы проверить модель на своих текстах до того, как что-либо строить, создайте эмбеддинги вопроса и нескольких фрагментов текста одним запросом, поставив вопрос первым. Вставьте ответ ниже: фрагменты будут упорядочены по косинусному сходству с вопросом, а инструмент покажет, имеет ли каждый вектор единичную длину и одинаковые измерения.
Попробовать: Embedding Similarity Calculator
В примере используются выдуманные векторы единичной длины с 4 измерениями, чтобы их можно было прочитать. У настоящих эмбеддингов сотни или тысячи измерений.
Прочитано как ответ Ollama /api/embed: векторов: 4, измерений: 4. У всех векторов длина 1, поэтому косинусное сходство и скалярное произведение равны.
Ранжирование по косинусному сходству
Сравнение с #0 How do I keep a model loaded in Ollama?. Чем больше значение, тем больше сходство.
| Место | Текст | Косинус | Скалярное произведение | Расстояние |
|---|---|---|---|---|
| 1 | #1 keep_alive controls how long the model stays in memory | 0.9962 | 0.9962 | 0.0876 |
| 2 | #2 Protect Ollama with nginx and a password | 0.4037 | 0.4037 | 1.0921 |
| 3 | #3 Tomorrow's weather forecast | 0.0100 | 0.0100 | 1.4071 |
Матрица косинусного сходства
Каждая ячейка сравнивает вектор из строки с вектором из столбца.
| #0 | #1 | #2 | #3 | |
|---|---|---|---|---|
| #0 | 1.000 | 0.996 | 0.404 | 0.010 |
| #1 | 0.996 | 1.000 | 0.475 | -0.005 |
| #2 | 0.404 | 0.475 | 1.000 | -0.377 |
| #3 | 0.010 | -0.005 | -0.377 | 1.000 |
Векторы
| Текст | Измерения | Длина (норма L2) | Единичная длина |
|---|---|---|---|
| #0 How do I keep a model loaded in Ollama? | 4 | 1.000000 | Да |
| #1 keep_alive controls how long the model stays in memory | 4 | 1.000000 | Да |
| #2 Protect Ollama with nginx and a password | 4 | 1.000001 | Да |
| #3 Tomorrow's weather forecast | 4 | 1.000000 | Да |
По документации Ollama об эмбеддингах и справочнику API, проверено 2026-11-04. Ollama: Embeddings / Ollama API: Generate embeddings
Всё вычисляется в вашем браузере. Ничего никуда не отправляется.
Память на небольшом сервере
Модель эмбеддингов загружается так же, как любая другая модель. В FAQ Ollama сказано, что OLLAMA_MAX_LOADED_MODELS — число моделей, которые могут быть загружены одновременно, если они помещаются в память, — по умолчанию равно 3, умноженному на число GPU, или 3 при инференсе на CPU. Так что чат-модель и модель эмбеддингов могут оставаться загруженными вместе, если позволяет память.
Наша статья о слежении за памятью Ollama объясняет ollama ps, keep_alive и другие настройки, которые определяют, что остаётся в памяти.
Источники
Читайте дальше
- Хранение и поиск эмбеддингов Ollama в PostgreSQL с помощью pgvectorЭмбеддинги Ollama в PostgreSQL с pgvector, поиск через HNSW или IVFFlat и передача результатов в /api/chat, чтобы ответ ссылался на источники.
- Следим за памятью Ollama на небольшом VPSЧто Ollama держит в памяти, как долго и какие настройки это меняют: ollama ps, keep_alive и лимиты по официальному FAQ.
- Подключаем Dify к Ollama на собственном VPSЗапустите Dify на своём VPS и используйте Ollama как модель: установка, поля плагина, проблема адреса в Docker и эмбеддинги — по официальной документации.
- Локальная LLM без дорогого ПК: руководство для начинающих по работе через VPSНет мощного ПК? Арендуйте VPS и запустите небольшую локальную LLM из браузера: шесть шагов от оценки памяти до защищённого экрана чата, с честным описанием ограничений.