API Ollama: curl, Python и подключение к удалённой модели
Собственный API Ollama находится под /api, совместимые endpoints — под /v1. Выберите адрес, который ожидает ваш клиент. Нативный запрос чата отправляется на /api/chat; клиенту, который сам добавляет /chat/completions, нужен base URL с окончанием /v1.
Примеры предполагают, что Ollama уже запущена. На сервере используется порт 11434. На вашем компьютере — порт 11435 через SSH-туннель из инструкции.
Проверьте сервер и имя модели
На своём компьютере с открытым туннелем:
curl --fail-with-body http://127.0.0.1:11435/api/version
curl --fail-with-body http://127.0.0.1:11435/api/tags
Используйте полное имя из ответа. Название семейства, Hugging Face repository ID и тег Ollama — разные идентификаторы.
Нативный запрос чата
curl --fail-with-body http://127.0.0.1:11435/api/chat \
-H 'Content-Type: application/json' \
-d '{"model":"qwen2.5:7b-instruct-q4_K_M","messages":[{"role":"system","content":"Answer briefly."},{"role":"user","content":"What does a database index do?"}],"stream":false,"options":{"num_ctx":4096,"num_predict":128,"temperature":0}}'
Для русского ответа замените пользовательский текст, например на «Как работает индекс базы данных?». Не меняйте промпт между сравниваемыми замерами.
stream: false возвращает один JSON-ответ. При включённом streaming нативный API выдаёт JSON-объекты, разделённые переводом строки. Это другой формат потока, чем SSE у совместимого endpoint. Финальный нативный ответ содержит счётчики для измерения скорости.
Историю нужно передавать в массиве messages. Если каждый раз отправлять только последнее сообщение пользователя, сервер не восстановит предыдущий разговор автоматически.
Python без дополнительных пакетов
import json
import urllib.request
payload = {
"model": "qwen2.5:7b-instruct-q4_K_M",
"messages": [{"role": "user", "content": "Explain a database index briefly."}],
"stream": False,
"options": {"num_ctx": 4096, "num_predict": 128},
}
request = urllib.request.Request(
"http://127.0.0.1:11435/api/chat",
data=json.dumps(payload).encode("utf-8"),
headers={"Content-Type": "application/json"},
)
with urllib.request.urlopen(request, timeout=300) as response:
result = json.load(response)
print(result["message"]["content"])
Это минимальная проверка подключения. В приложении для пользователей дополнительно обрабатывайте тайм-ауты, неуспешные HTTP-ответы и ограничения входа/выхода. Увеличение тайм-аута не поможет модели, которая не помещается в память.
OpenAI-совместимый запрос
curl --fail-with-body http://127.0.0.1:11435/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"qwen2.5:7b-instruct-q4_K_M","messages":[{"role":"user","content":"What does a database index do?"}],"max_tokens":128,"stream":false}'
Настройки совместимого клиента:
| Поле | Значение |
|---|---|
| Base URL | http://127.0.0.1:11435/v1 |
| Модель | qwen2.5:7b-instruct-q4_K_M |
| API key, если поле обязательно | Например, ollama; локальный сервер его игнорирует |
Такой ключ не аутентифицирует запросы. В этой схеме доступ обеспечивается SSH-туннелем и локальным listener. Проверьте конкретные возможности, которые нужны приложению: инструменты, структурированный вывод или streaming. Общая совместимость API не гарантирует поддержку каждой функции.
Измерьте запрос
Сохраните measure-ollama.py и выполните:
python3 measure-ollama.py --url http://127.0.0.1:11435 --runs 3 > measurements.jsonl
Первая строка — прогрев с возможной загрузкой модели. Следующие содержат полное время последовательного запроса, загрузку и скорость декодирования. Полное время включает сеть, скорость генерации считается по серверным счётчикам. Это не измерение времени до первого токена или параллельной нагрузки. Файл содержит сгенерированные ответы: проверьте их перед передачей другим людям.
Для русскоязычного измерения можно добавить --prompt "Объясни индекс базы данных в трёх предложениях.". Остальные параметры сравниваемых запусков оставьте одинаковыми.
При ошибках используйте диагностику подключения и модели.
Источники: API чата, streaming, совместимые endpoints.
Готовы запустить?
Запустить GPU-сервер