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

LM Studio Vision API: отправить изображение и проверить ответ модели

В LM Studio Vision API отправьте изображение как base64 data URL в элементе `type: image` запроса `POST /api/v1/chat`. Сначала проверьте `capabilities.vision` и загруженный экземпляр через `GET /api/v1/models`, затем сравните описание простого тестового PNG с известным оригиналом. Успешный HTTP-ответ сам по себе не доказывает качество распознавания или отсутствие внешних сетевых соединений.

Проверено по документации 29 сентября 2026 года. Ниже протокол для версии LM Studio с нативным REST API /api/v1/chat, а не собственный прогон Modelium. Google Suggest подтверждает формулировку запроса, но не частотность; модель/веса не скачивались, распознавание не измерялось.

Когда нужен именно LM Studio Vision API?

Если уже используете LM Studio и хотите послать картинку из своего кода, нативный REST-метод POST /api/v1/chat принимает текст и элемент изображения с type: "image", data_url в формате base64 data URL s1. Это отличается от API Ollama и OpenAI-совместимого endpoint других серверов: не копируйте их JSON-поля без проверки. Для обычной установки откройте гайд LM Studio, а для другого runtime — Ollama Vision API.

Результат этого сценария — один сохранённый запрос, один ответ и ручное сравнение с оригиналом. Успешный HTTP 200 и непустой текст не устанавливают ни точность OCR, ни пригодность к реальным счетам. Начните с безопасного искусственного PNG, в котором известны две цветные половины; важные документы проверяйте позднее по собственной разметке и правилам доступа.

Что проверить до передачи изображения?

Нужны установленный LM Studio с доступным нативным REST API, скачанная именно мультимодальная LLM и включённый сервер. Запустите lms server start, проверьте lms server status и установленный у вас порт. Документация для CLI указывает bind 127.0.0.1 по умолчанию; --bind 0.0.0.0 открывает доступ за пределы localhost, поэтому для этого примера его не используйте s4. Значение 1234 ниже — документированный пример; если вы изменили порт, измените и адрес в командах s4.

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

GET /api/v1/models возвращает models[] с key, type, capabilities.vision и loaded_instances s2. Найдите строку с type: "llm" и capabilities.vision: true; type: "embedding" и текстовая LLM сюда не подходят s2. Для повторяемости запишите полный key, формат/квант из своего ответа и loaded_instances[].id, а не угадывайте имя модели по рекламному названию. Если такой модели нет, сначала изучите возможности конкретного артефакта, условия применения и ресурсы своего компьютера; не делайте вывод о минимальной памяти из size_bytes — это размер файлов модели, а не измерение её размещения s2.

Если подходящая модель скачана, но loaded_instances пуст, загрузите указанный в своём ответе key через интерфейс LM Studio или задокументированный POST /api/v1/models/load; ответ должен содержать status: "loaded" и instance_id s3. CLI lms ls показывает локальные модели, lms load --estimate-only <model_key> даёт предварительную оценку ресурса без загрузки, а lms load <model_key> выполняет её s7. Оценка до запуска — не тест пригодности, скорости или точности на вашем компьютере; не заставляйте читателя загружать неизвестную крупную модель ради примера. Если сервер настроен на JIT, это отдельная политика загрузки, которую можно проверить в Server Settings s8.

По умолчанию API-токен LM Studio не требует; в версии 0.4.0+ администратор может включить Require Authentication, после чего необходим действительный Authorization: Bearer s5. Если защищаете API, задайте LM_STUDIO_API_TOKEN локально в окружении перед скриптом, не вставляйте секрет в статью, URL, репозиторий или снимок запроса. При ошибке 401 проверьте именно настройки токена; не отключайте защиту публичного сетевого сервера ради диагностики. В Server Settings отдельно существуют опции локальной сети, CORS и разрешений MCP, которые этот тест не использует s8.

Как создать изображение с известным эталоном?

В пустой директории создайте test.png этой программой Python 3 (только стандартная библиотека). Откройте полученный файл просмотрщиком: слева красная половина, справа синяя, текста и объектов нет. Это синтетический тест Modelium как процедура для читателя, не утверждение о том, что наша инфраструктура запускала модель.

from pathlib import Path
import struct
import zlib

w, h = 192, 96
raw = b''.join(
b'\x00' + b''.join(
b'\xff\x00\x00' if x < w // 2 else b'\x00\x00\xff'
for x in range(w)
)
for _ in range(h)
)

def chunk(tag, data):
return (struct.pack('!I', len(data)) + tag + data
+ struct.pack('!I', zlib.crc32(tag + data) & 0xffffffff))

png = (b'\x89PNG\r\n\x1a\n'
+ chunk(b'IHDR', struct.pack('!2I5B', w, h, 8, 2, 0, 0, 0))
+ chunk(b'IDAT', zlib.compress(raw))
+ chunk(b'IEND', b''))
Path('test.png').write_bytes(png)
print('Сохранён test.png')

Не заменяйте тестовую картинку приватным сканом до проверки доступа, журнала запросов и применимости условий модели. Для реальной документации одного свободного описания кадра недостаточно: нужен эталон для каждого поля.

Как вызвать нативный /api/v1/chat?

Следующий скрипт запускайте в той же директории после загрузки vision-модели. Он сам берёт единственную уже загруженную vision-LLM из /api/v1/models; при нуле или нескольких экземплярах останавливается, не выбирая модель наугад. data_url включает префикс data:image/png;base64, и содержимое PNG, а не путь test.png: так описан контракт изображения у LM Studio s1s2. Если несколько моделей подходят, разгрузите лишние или отредактируйте выбор под заранее записанный точный key, проверив возвращённый объект.

from pathlib import Path
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
import base64
import json
import os

base = 'http://127.0.0.1:1234'
headers = {'Content-Type': 'application/json'}
if os.getenv('LM_STUDIO_API_TOKEN'):
headers['Authorization'] = 'Bearer ' + os.environ['LM_STUDIO_API_TOKEN']

def read_json(path, payload=None):
request = Request(base + path, headers=headers,
data=None if payload is None else json.dumps(payload).encode('utf-8'),
method='GET' if payload is None else 'POST')
try:
with urlopen(request, timeout=180) as response:
return json.load(response)
except (HTTPError, URLError) as exc:
raise SystemExit(f'Проверьте сервер, порт, токен и модель: {exc}')

models = read_json('/api/v1/models')['models']
loaded = [(m['key'], item['id']) for m in models
if m.get('type') == 'llm' and m.get('capabilities', {}).get('vision') is True
for item in m.get('loaded_instances', [])]
if len(loaded) != 1:
raise SystemExit(f'Нужна одна загруженная vision-LLM; обнаружено: {len(loaded)}')
model_key, instance_id = loaded[0]
data_url = ('data:image/png;base64,' +
base64.b64encode(Path('test.png').read_bytes()).decode('ascii'))
result = read_json('/api/v1/chat', {
'model': model_key,
'input': [
{'type': 'text', 'content': 'Опиши цвета двух половин слева направо. Если текста нет, не выдумывай его.'},
{'type': 'image', 'data_url': data_url},
],
'stream': False,
'store': False,
})
print('model:', model_key)
print('expected loaded instance:', instance_id)
print('actual instance:', result.get('model_instance_id'))
messages = [item.get('content', '') for item in result.get('output', [])
if item.get('type') == 'message']
print('answer:', '\n'.join(messages))

stream: false позволяет читать единый JSON вместо событий SSE, а store: false отключает сохранение этого чата в механизме данного запроса; эти поля не являются гарантиями стирания сетевых или системных логов s1. Проверяйте output[] с элементом type: message, content и model_instance_id из ответа: это поля нативного API, не choices[0].message.content чужого контракта s1. Не записывайте base64-картинку или API-токен в CI-лог. Команда задаёт только локальный адрес, не проверяет все остальные соединения устройства.

Как понять, что тест удался?

  1. GET /api/v1/models вернул конкретный vision key, а loaded_instances показал загруженный экземпляр; зафиксируйте версию LM Studio и параметры вашего запуска s2.
  2. POST /api/v1/chat вернул JSON с model_instance_id и непустым output[].content сообщения; сверяйте идентификатор с выбранным загруженным экземпляром. Ответ без подходящей загрузки, ошибку 401 и HTTP 400 фиксируйте отдельно s1s2s5.
  3. Сравните слова модели с первоначальным PNG: красный слева, синий справа, никакого текста. Перепутанные стороны, придуманный текст и отказ — результаты проверки, не повод переписать эталон. При втором тесте поменяйте цвета местами в новом файле и заранее запишите новую истину. Так можно обнаружить хотя бы часть шаблонных догадок, но нельзя вывести процент точности или надёжность OCR по двум картинкам.

Для реального теста сохраните версию приложения, key/вариант модели, входной файл или его хеш, prompt, статус ответа и ручной вердикт. Не сохраняйте персональные документы в открытом репозитории. Никаких собственных vision-измерений Modelium не проводил: всё выше — ожидаемая процедура по документации, а не протокол выполненного прогона.

Что делать при сбоях и как убрать тест?

  • Нет соединения: проверьте lms server status, порт и привязку к 127.0.0.1; не публикуйте сервер через 0.0.0.0 как обход ошибки s4.
  • 401/403: уточните Require Authentication, разрешения токена и локальную переменную окружения. Не печатайте её значение s5.
  • Нет vision-модели или она не загружена: сверяйте capabilities.vision, key и loaded_instances, затем оцените память через lms load --estimate-only либо загрузите подходящий уже скачанный экземпляр; оценка не равна фактическому RAM/VRAM s2s3s7.
  • Неверный формат изображения/ответа: передайте полный base64 data URL в элементе input с type: image; ответ ищите в output, а не в choices s1.
  • Нужен полностью закрытый контур: по документации уже скачанная модель и локальный сервер могут работать офлайн, но поиск моделей, загрузка runtime и обновления требуют сети s6. Локальный URL сам по себе не доказывает отсутствие внешних запросов: отдельно выполните сетевую проверку своей установки.

Для отката удалите только созданный вами test.png и сохранённые тестовые ответы; lms unload <model_key> может выгрузить модель из памяти, не удаляя файлы — используйте его, только если экземпляр принадлежит вашему тесту и не обслуживает других клиентов s7. Следующий шаг: подготовьте локальную LM Studio, затем выполните цветовой тест на своём компьютере и сохраните результат рядом с эталоном.

Источники

  1. LM Studio — REST API: Chat with a model — Контракт /api/v1/chat, image data_url, stream, store, output и model_instance_id; официальный HTML-снимок s1.html и SHA-256 в manifest.json.. Получено 29.09.2026.
  2. LM Studio — REST API: List your models — Схема GET /api/v1/models, key, capabilities.vision, loaded_instances, format; s2.html, manifest.json.. Получено 29.09.2026.
  3. LM Studio — REST API: Load a model — POST /api/v1/models/load и instance_id; s3.html, manifest.json.. Получено 29.09.2026.
  4. LM Studio — CLI: lms server start — Локальный bind по умолчанию, port, CORS, сетевое предупреждение; s4.html, manifest.json.. Получено 29.09.2026.
  5. LM Studio — Authentication — LM Studio 0.4.0+, настройка Require Authentication и Bearer token; s5.html, manifest.json.. Получено 29.09.2026.
  6. LM Studio — Offline Operation — Работа скачанной модели и сервера без интернета, отдельные сетевые операции; s6.html, manifest.json.. Получено 29.09.2026.
  7. LM Studio — CLI: lms load — lms ls, lms load, --estimate-only, контекст, TTL; s7.html, manifest.json.. Получено 29.09.2026.
  8. LM Studio — Server Settings — Отдельные настройки bind, auth, CORS, MCP и JIT; s8.html, manifest.json.. Получено 29.09.2026.