Перейти к содержанию
modelium.
Начать с задачи
←

LM Studio Embeddings API: локальная индексация и проверка поиска

LM Studio предоставляет OpenAI-совместимый endpoint `/v1/embeddings` для загруженной embedding-модели: он возвращает векторы текстов, но не готовый поиск или ответ по документам. Сначала выберите модель, запустите локальный сервер и проверьте форму ответа, затем сравните векторы нескольких вымышленных фрагментов и вопросов. Пример с Nomic предназначен для проверки API: его карточка указывает английский язык, поэтому качество поиска по русским документам нельзя предполагать без отдельного теста.

Проверено по документации 28 сентября 2026 года. API LM Studio и карточки Nomic сверены с первоисточниками; у карточек модели закреплены ревизии 0188c9bf и e9b67630. Modelium не запускал сервер, не загружал веса и не измерял качество поиска. Команды ниже — инструкция для вашего стенда, а не отчёт о нашем прогоне. s1 s7 s8

Что делает Embeddings API и чего он не делает?

LM Studio документирует OpenAI-совместимый POST /v1/embeddings. На вход передаётся текст или массив текстов и идентификатор embedding-модели; в ответе ожидаются числовые векторы. Это не чат-модель, не хранилище документов и не готовая RAG-система: индекс, поиск ближайших фрагментов, контроль доступа к документам и генерацию ответа надо организовать отдельно. s1 s4

Практический маршрут: документы → фрагменты → embedding-модель → локальный LM Studio → векторы → сравнение с запросом → проверка найденного фрагмента → при необходимости отдельная генерация ответа. В этом гайде намеренно используется маленький набор вымышленных текстов вместо клиентских данных. Переходите к реальной базе только после проверки релевантности и сетевой изоляции на своём оборудовании. s1 s2

Как подготовить модель, железо и локальный сервер?

Установите LM Studio и возьмите embedding-модель в доступном для вашего runtime формате. Команда lms get позволяет искать и скачивать модели; флаг --gguf ограничивает поиск GGUF-файлами. Например, карточка Nomic Embed Text v1.5 GGUF описывает файлы для llama.cpp и помечает язык как en. Используйте её для учебного англоязычного теста API, а не как неподтверждённую рекомендацию для русского документооборота. Наличие файлов GGUF и публикация лицензии Apache-2.0 на карточке не доказывают пригодность каждой конкретной конфигурации LM Studio или качество выдачи; проверьте выбранный файл и применимые условия перед производством. s6 s7

В приложении выберите и загрузите скачанную embedding-модель. REST-метод LM Studio /api/v1/models/load допускает embedding и возвращает тип загруженной модели; если используете этот метод вместо интерфейса, подставьте фактический ID, а не угаданный по имени файла. Не выводите минимум RAM/VRAM из размера GGUF: доступность зависит от файла, runtime, разгрузки слоёв и вашей системы. В этом материале аппаратный порог не измерен. s4 s7

На вкладке Developer включите Start server или выполните lms server start. По документации локальный адрес по умолчанию — http://localhost:1234; не включайте доступ из локальной сети, если он не нужен. Запросите список доступных серверу моделей и запишите в журнал точный ID загруженной embedding-модели. Но GET /v1/models при включённой загрузке по требованию может показывать и просто скачанные модели: один список не доказывает, что веса уже в памяти или что данная модель вернёт embedding. s2 s3

lms server start
curl -fsS http://127.0.0.1:1234/v1/models

По умолчанию LM Studio не требует API-токен; в Server Settings можно включить обязательную аутентификацию и выдать токен с нужными правами. Не выставляйте порт наружу только потому, что тест с loopback работает. Если токен включён, передавайте Authorization: Bearer <ваш-токен> в запросах ниже; тест без этого заголовка должен быть отвергнут. Первый поиск/загрузка модели может обращаться к сети; loopback входящего API не означает офлайн-режим всей машины. s5 s6

Как получить и проверить векторы?

Укажите фактический ID из сервера, подставив его вместо значения-заглушки. Для Nomic автор модели требует добавлять search_document: к индексируемым текстам и search_query: к вопросам. Не отправляйте голые строки и не предполагайте, что API сам добавит префикс: передайте его явно. Образец LM Studio использует локальный base_url=http://localhost:1234/v1 для OpenAI-клиента. s1 s7 s8

export LM_EMBED_MODEL='ПОДСТАВЬТЕ_ID_ЗАГРУЖЕННОЙ_EMBEDDING_МОДЕЛИ'
curl -fsS http://127.0.0.1:1234/v1/embeddings \
-H 'Content-Type: application/json' \
-d "$(python3 -c 'import json,os; print(json.dumps({"model":os.environ["LM_EMBED_MODEL"],"input":["search_document: The invoice contains a supplier tax ID.","search_document: The team meets on Monday."]}))')"

Убедитесь, что ответ содержит data с двумя элементами и в каждом embedding есть непустой вектор конечных чисел одинаковой размерности. Ошибка типа «модель не поддерживает embeddings» означает, что выбрана не та модель или несовместимый формат/runtime; HTTP 200 без проверки формы ещё не подтверждает пригодность результата. Количество, размерность, точный ID и конфигурацию нужно сохранить вместе с индексом. s1 s4

Как на своём компьютере проверить ближайший фрагмент?

Составьте три вымышленных англоязычных фрагмента: счёт с налоговым идентификатором, расписание встречи и акт с суммой. До запуска запишите ожидаемый первый фрагмент для двух вопросов: про идентификатор — счёт, про сумму акта — акт. Следующий сценарий отправляет документы и запросы в одну и ту же модель, вычисляет косинусную близость и показывает порядок. Это проверка, которую должен выполнить читатель; конкретное ранжирование здесь не измерялось. Префиксы следуют карточке модели. s1 s7 s8

python3 - <<'PY'
import json, math, os, urllib.request
model = os.environ['LM_EMBED_MODEL']
base = 'http://127.0.0.1:1234/v1/embeddings'
docs = [
'The invoice contains a supplier tax ID.',
'The team meets on Monday.',
'The delivery acceptance note contains the total amount.',
]
questions = [
('Where is the supplier tax ID?', 0),
('Which record contains the total amount?', 2),
]
def embed(texts):
payload = json.dumps({'model': model, 'input': texts}).encode()
req = urllib.request.Request(base, payload, {'Content-Type': 'application/json'})
with urllib.request.urlopen(req, timeout=120) as response:
data = json.load(response)['data']
data = sorted(data, key=lambda item: item['index'])
vectors = [item['embedding'] for item in data]
assert len(vectors) == len(texts) and vectors and len(vectors[0]) > 0
assert all(len(v) == len(vectors[0]) and all(math.isfinite(x) for x in v) for v in vectors)
return vectors
def cosine(a, b):
na = math.sqrt(sum(x*x for x in a))
nb = math.sqrt(sum(x*x for x in b))
assert na > 0 and nb > 0
return sum(x*y for x, y in zip(a, b)) / (na*nb)
dv = embed(['search_document: ' + text for text in docs])
qv = embed(['search_query: ' + q for q, _ in questions])
for (question, expected), vector in zip(questions, qv):
scores = [cosine(vector, item) for item in dv]
ranking = sorted(range(len(docs)), key=lambda i: scores[i], reverse=True)
print(json.dumps({'question': question, 'expected_first': expected,
'actual_first': ranking[0], 'ranking': ranking,
'scores': scores, 'dimensions': len(vector)}))
PY

Если ожидаемый фрагмент не оказался первым, не называйте этот опыт удачным: проверьте ID модели, префиксы, порядок data[*].index, размерность, текст и разбиение документов. Этот учебный тест не является оценкой качества RAG в бизнесе. Для русских УПД, счетов и актов не переносите результат английского примера: карточка Nomic GGUF маркирована en. Выберите модель с документированной поддержкой нужного языка и проверенным форматом запуска, разметьте отдельный набор русских запросов и ожидаемых фрагментов, посчитайте recall@k = «число запросов с нужным фрагментом в первых k» / «число размеченных запросов» и разберите ошибки вручную. s7 s8

Какие ограничения важно сохранить при внедрении?

Все фрагменты индекса и запросы должны проходить через одну согласованную модель, формат префиксов и размерность. При смене модели или предобработки индекс надо пересчитать; иначе сравнение векторов перестанет быть контролируемым экспериментом. API, возвращающий вектор, не доказывает отсутствие исходящих запросов при подготовке модели или безопасность доступа к чужим документам. Для артикула или точного реквизита сравните векторный поиск с гибридным поиском: смысловая близость не гарантирует точное посимвольное совпадение. s1 s7

После проверки остановите сервер через интерфейс или lms server stop, убедитесь, что 127.0.0.1:1234 больше не отвечает, и сохраните ID/версию модели, формат GGUF, параметры загрузки, входные тексты, размерность, ранжирование и дату прогона. Если нужен другой runtime, сравните отдельный гайд vLLM Embeddings API; основной следующий шаг для этого материала — протокол оценки поиска на собственных документах. s2 s4

Источники

  1. LM Studio — OpenAI-compatible Embeddings. Получено 28.09.2026.
  2. LM Studio — Local API server. Получено 28.09.2026.
  3. LM Studio — OpenAI-compatible List Models. Получено 28.09.2026.
  4. LM Studio — REST Load a model. Получено 28.09.2026.
  5. LM Studio — API Token Authentication. Получено 28.09.2026.
  6. LM Studio — lms get CLI. Получено 28.09.2026.
  7. Nomic Embed Text v1.5 GGUF — карточка на закреплённой ревизии — revision 0188c9bf409793f810680a5a431e7b899c46104c. Получено 28.09.2026.
  8. Nomic Embed Text v1.5 — оригинальная карточка и префиксы — revision e9b6763023c676ca8431644204f50c2b100d9aab. Получено 28.09.2026.