Медведь-талисман NordBastion сидит на резной каменной скамье в тёмном нордическом хранилище с ноутбуком на коленях; над стойкой серверов рядом с ним светится бирюзовая нейросетевая решётка, запечатанная в шестигранном стеклянном сосуде, а короткий поток бирюзовых токенов течёт из сосуда вниз, на его экран, за закрытой рунической дверью.
Руководство · ИИ-агенты·17 мин. чтения · 30 мин. практики

Запустить LLM на VPS.
Без GPU. Без API-ключа. Ни один промпт не покидает сервер.

Шесть шагов к языковой модели, которая отвечает на вашем собственном железе, — формула, предсказывающая скорость в токенах в секунду ещё до покупки сервера, какая модель влезет в 4, 8, 16 или 32 ГБ, аутентификация, которой в Ollama нет, и честный список задач, которые не потянет. Проверено на Debian 12.

Шесть шагов
  1. 01

    Размер

    Пропускная способность, а не ядра

  2. 02

    Установить

    Ollama

  3. 03

    Замер

    Ваши собственные токены/с

  4. 04

    Защита

    TLS + токен

  5. 05

    Подключиться

    Один base URL

  6. 06

    Ограничение

    Контекст, RAM, диск

Прежде чем начать · Арифметика

Одно деление подскажет, на что способен сервер. Сделайте это до покупки сервера.

Почти всё, что написано о локальном запуске языковых моделей, — о видеокартах, что бесполезно, если у вас виртуальный сервер. Полезная модель мышления проще, чем предполагает разговор о GPU, и умещается в одну фразу: чтобы сгенерировать один токен, плотная модель должна прочитать из памяти все свои веса. Не часть — все, и на каждый токен заново.

Один этот факт закрывает весь вопрос производительности. Скорость генерации определяется не количеством арендованных ядер, а тем, как быстро сервер способен вычитывать модель из RAM. А это значит, что потолок можно прикинуть на салфетке ещё до того, как вы что-либо потратите:

tokens per second  ≈  memory bandwidth (GB/s)  ÷  model size (GB)

Квантованная модель 8B занимает около 5 ГБ. На виртуальном сервере, где реально доступно порядка 20 ГБ/с, потолок — около четырёх токенов в секунду, а на практике вы увидите примерно половину-две трети от этого значения. Грубо говоря, три слова в секунду. Воспринимайте это как факт о характере задачи, а не как разочарование: для чат-окна это медленно, а для задачи, которая классифицирует документ и возвращает одну строку JSON, — вполне достаточно.

Ядра всё ещё важны, просто не по той причине, которую обычно предполагают. Дополнительные потоки помогают, пока не насыщают канал памяти, а на таких серверах это происходит рано — часто уже на четырёх-восьми потоках. После этой точки лишние ядра простаивают, пока всё остальное ждёт RAM. Именно поэтому шестнадцатиядерный сервер не генерирует текст в четыре раза быстрее четырёхъядерного, и именно поэтому платить за ядра в надежде на скорость — самый частый способ купить не тот тариф.

Читать быстро, писать медленно. В каждом запросе есть две фазы, и ведут они себя совершенно по-разному. Обработка промпта — prefill — это матричная операция над всем вводом сразу, упирающаяся в вычисления, и она работает в разы быстрее генерации. Формирование ответа — та самая упирающаяся в память часть, описанная выше, по одному токену за раз. Поэтому дать модели документ на две тысячи слов и попросить три предложения в ответ — комфортная нагрузка, а попросить у неё же эссе на две тысячи слов — нет. Стройте промпты вокруг этой асимметрии, и сервер на CPU покажется куда лучше, чем можно подумать по его скорости в токенах.

Тариф Оперативная память Самая крупная комфортная модель Порядок величины Назначение
Sentinel · $3.904 GB3B при Q4 (~2 ГБ)предложение в секундуКлассификация, тегирование, маршрутизация, эмбеддинги
Garrison · $7.908 GB8B при Q4 (~5 ГБ)несколько слов в секундуПо умолчанию. Суммаризация, извлечение JSON, ответы RAG
Ravelin · $16.9016 GB14B при Q4 (~9 ГБ)примерно половина от предыдущегоБолее сложные рассуждения, длинный контекст, пакетные конвейеры
Bulwark · $32.9032 GB32B при Q4 (~20 ГБ)меньше слова в секундуКачество важнее скорости. Только асинхронная работа
Citadel · $62.9064 GB70B при Q4 (~40 ГБ)минуты на ответПомещается. Не для интерактива. Ночные задачи

Размеры моделей — это обычные квантования Q4_K_M, которые жертвуют небольшой, обычно незаметной долей качества ради экономии более половины памяти. Столбец скорости — это порядок величины, выведенный из формулы выше, а не бенчмарк: смысл шага 03 именно в том, чтобы замерить свой собственный сервер, а не доверять таблице — включая эту.

Прежде чем начать · Вместимость

Что реально по силам CPU. А что нет — прямо и без экивоков.

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

Помещается с запасом. Всё, где вывод короткий, а ценность — в самом суждении, а не в объёме текста. Отнести сообщение к одной из нескольких категорий. Решить, срочный ли тикет поддержки. Извлечь пять полей из счёта в виде JSON. Сжать переписку до трёх предложений. Проставить теги документу. Переписать описание товара. Перевести короткую строку. Определить, описывают ли две записи одного и того же человека. Удалить имена из абзаца, прежде чем он куда-либо уйдёт. Каждая из этих задач потребляет длинный ввод и выдаёт короткий вывод — именно такую асимметрию CPU обрабатывает хорошо.

Помещается, но нужно терпение. Работа, на которую никто не ждёт ответа в реальном времени. Ночные пакетные задачи, обработчики очередей, ночной проход по документам за день, отчёт по расписанию. Если ничего не блокируется в ожидании ответа, скорость в токенах, невыносимая в чат-окне, вообще перестаёт иметь значение — задача, которая шесть минут выполняется в три часа ночи, — это просто задача, которая выполнилась.

Не помещается. Интерактивный ассистент, которым людям действительно приятно пользоваться: на такой скорости курсор еле ползёт, и опыт получается хуже, чем без ассистента вовсе. Генерация больших текстов — «напиши мне две тысячи слов» — где весь вывод целиком и есть медленная часть. Кодинг-агенты, перебирающие большой репозиторий, где и контекст, и требуемое качество превышают возможности небольшой модели. Всё, что требует контекста в сто тысяч токенов, — здесь один только кэш перерастёт возможности сервера. И модели для изображений или видео — это совсем другая дисциплина, которой действительно нужен GPU.

Если ваша нагрузка относится к этой последней группе, разумный ответ — не покупать более мощный CPU-сервер, а сделать гибрид. Держите локальную модель для основной массы вызовов и направляйте немногие случаи, требующие рассуждений топового уровня, в облачный API — именно такую схему для рантайма описывает руководство по запуску ИИ-агента 24/7. Там саму модель сознательно оставили за скобками. Это руководство — недостающая половина.

Шаг 01 · Размер

Покупайте под модель, а не под ядра. И оставляйте запас.

Отталкивайтесь от задачи и идите в обратную сторону. Решите, что должна делать модель, выберите наименьший размер, который с этим справится, посмотрите, сколько этот размер занимает в Q4_K_M, а затем добавьте накладные расходы:

RAM needed  =  model file  +  KV cache  +  ~2 GB for the system

  3B  Q4_K_M  ≈  2.0 GB        KV cache at 8k context   ≈  0.5–1 GB
  8B  Q4_K_M  ≈  4.9 GB        KV cache at 32k context  ≈  2–4 GB
 14B  Q4_K_M  ≈  9.0 GB
 32B  Q4_K_M  ≈ 20.0 GB
 70B  Q4_K_M  ≈ 40.0 GB

KV-кэш — это накладные расходы, о которых забывают. Каждый токен, уже присутствующий в диалоге, хранится в памяти, чтобы модель не пересчитывала его заново, и это хранилище растёт вместе с разрешённым контекстом. Удвоение контекста примерно удваивает и его. Модель, которая помещается в память при контексте 4k, может перестать помещаться при 32k — и откажет она не на первом запросе, а где-то на десятом, из-за чего это выглядит загадкой, а не банальной арифметической ошибкой.

Здесь нет плавной деградации. Когда общий объём превышает RAM, ядро не сбавляет обороты вежливо: оно начинает подкачивать веса модели туда-обратно с диска на каждом токене. Генерация за четыре секунды превращается в четыре минуты, load average уходит в десятки, и вместе с этим страдает всё остальное на сервере — база данных, веб-сервер, ваша SSH-сессия. Уместиться в память — это не оптимизация. Это обязательное условие.

В панели: Order → VPS → тариф, на который указала арифметика, образ Debian 12. Для открытия аккаунта не нужен email, ни на каком этапе не запрашивается документ, удостоверяющий личность, а счёт закрывается в Monero, Bitcoin, Lightning или любом другом поддерживаемом активе — и здесь это важнее, чем на обычном веб-сервере, по причинам, которые разбирает базовое руководство по анонимному хостингу VPS, а глава о приватности ниже применяет их конкретно к промптам.

Шаг 02 · Установка

Одна команда, один сервис. Привязан к loopback — и оставлен там.

Сначала защитите сервер — SSH только по ключу, файрвол, не пропускающий ничего лишнего, автоматические обновления безопасности. Чек-лист первого часа займёт около часа, а этот сервер вскоре будет хранить каждый ваш вопрос.

Затем установите сам движок. Ollama — это llama.cpp с реестром моделей, REST API и systemd-юнитом в обёртке, и однострочный установщик настраивает всё три сразу:

apt update && apt install -y curl
curl -fsSL https://ollama.com/install.sh | sh

systemctl status ollama --no-pager
ss -ltnp | grep 11434
# → 127.0.0.1:11434 — loopback only. Leave it that way.

Вот эту последнюю строку стоит прочитать дважды. По умолчанию сервис слушает интерфейс loopback, и это абсолютно правильно, а самая частая ошибка следующих десяти минут — выставить OLLAMA_HOST в 0.0.0.0, потому что что-то на другом сервере не могло достучаться. Шаг 04 — это правильный способ достучаться; версии, в которой порт 11434 смотрит прямо в интернет, не существует.

Две настройки стоит выставить сразу, а не обнаруживать проблему постфактум. По умолчанию модели хранятся в /usr/share/ollama и весят немало, так что направьте это туда, где есть место. А по умолчанию модель остаётся резидентной в RAM пять минут после последнего запроса — это щедро для сервера, который занят ещё и другой работой:

systemctl edit ollama
[Service]
Environment="OLLAMA_MODELS=/var/lib/ollama/models"
Environment="OLLAMA_KEEP_ALIVE=30m"
Environment="OLLAMA_NUM_PARALLEL=1"
Environment="OLLAMA_MAX_LOADED_MODELS=1"
systemctl daemon-reload && systemctl restart ollama

Параллельные запросы и несколько загруженных моделей одинаково умножают расход памяти, а на сервере, рассчитанном ровно на одну модель, лишнего гигабайта под вторую копию просто нет. Сериализация очереди — не ограничение этого железа, а единственная конфигурация, которая не падает.

Шаг 03 · Замер

Получите собственную цифру. Чужой бенчмарк — не про ваш сервер.

Скачайте модель. Для первого замера подойдёт любая современная instruct-модель класса 8B — они достаточно близки по размеру, чтобы результат говорил о железе, а не о конкретной модели:

ollama pull llama3.1:8b        # ~4.9 GB at Q4_K_M
ollama list
ollama ps                      # nothing resident yet

Теперь запустите одну генерацию с включённым выводом таймингов. Важное число — это eval rate: токенов в секунду после того, как промпт уже прочитан:

ollama run llama3.1:8b --verbose "Reply with exactly one sentence about the Baltic Sea."
total duration:        14.2s
load duration:          3.1s
prompt eval count:        24 token(s)
prompt eval rate:      92.11 tokens/s      ← reading: fast
eval count:               38 token(s)
eval rate:              3.42 tokens/s      ← writing: the real ceiling

Две строки — два разных мира. Чтение шло на скорости около девяноста токенов в секунду; запись — на трёх с половиной. Это соотношение — та самая асимметрия из главы про арифметику, только замеренная на вашем собственном железе, и это самый полезный факт, который вы соберёте сегодня. Он говорит: давайте этому серверу длинный ввод и просите короткий вывод.

Тот же замер через API — то, что вам на самом деле нужно, если вы собираетесь автоматизировать сравнение между двумя-тремя размерами моделей:

apt install -y jq

curl -s http://127.0.0.1:11434/api/generate -d '{
  "model":  "llama3.1:8b",
  "prompt": "List three Nordic capitals.",
  "stream": false
}' | jq '{
  tokens: .eval_count,
  seconds: (.eval_duration / 1000000000),
  rate: (.eval_count / (.eval_duration / 1000000000))
}'

Замерьте размер меньше и размер больше — и на этом остановитесь. Скачайте 3B и 14B, прогоните через каждую один и тот же промпт и запишите все три показателя скорости. Теперь вы точно знаете, во что обходится этот компромисс на вашем сервере — обычно это что-то близкое к удвоению в каждую сторону, — и можете выбирать модель под задачу, а не по ощущениям. Затем удалите модели, которые не оставляете, — каждая из них весит несколько гигабайт.

Одна оговорка про первый запуск любой модели: load duration в этом выводе — это время на чтение весов с диска в RAM. Оно тратится только тогда, когда модель ещё не резидентна, а за это как раз отвечает OLLAMA_KEEP_ALIVE. Не учитывайте его при сравнении скорости и не пугайтесь — на NVMe это секунды, и происходит это один раз.

Шаг 04 · Защита

В Ollama нет аутентификации. Никакой. Не слабой — вообще никакой.

Это та часть руководства, которая предотвращает неприятности, поэтому скажем прямо, без смягчений: у API Ollama нет ни пароля, ни токена, ни модели пользователей, ни системы разрешений. Всё, что способно открыть TCP-соединение к порту 11434, может генерировать текст на вашем CPU, перечислять скачанные вами модели, скачивать новые и удалять те, которыми вы пользуетесь. Здесь нечего включить, потому что включать попросту нечего.

Порт 11434 сканируют непрерывно — причина очевидна: открытый сервер моделей — это чужие бесплатные вычисления. Симптом — не алерт. Это сервер, который две недели подряд кажется медленным, и график трафика, не совпадающий ни с чем, что вы делали. Держите сервис на loopback и поставьте перед ним что-то, что спрашивает, кто звонит.

Если модель не нужна никому за пределами этого сервера, остановитесь здесь — вы уже закончили. Loopback плюс файрвол — исчерпывающий ответ, а агент, автоматизация или веб-приложение на том же VPS достучатся до модели через 127.0.0.1 без всего, что описано дальше. Продолжайте только если к модели должно обращаться что-то с другого сервера.

Прокси и токен. Сгенерируйте длинный случайный токен, направьте A-запись на сервер и дайте Caddy заняться и сертификатом, и дверью на входе:

openssl rand -hex 32      # → the bearer token, store it in a password manager
apt install -y caddy

/etc/caddy/Caddyfile

llm.example.com {
    @unauthorised not header Authorization "Bearer PASTE_THE_HEX_TOKEN_HERE"
    respond @unauthorised "unauthorised" 401

    reverse_proxy 127.0.0.1:11434 {
        # Generation is slow by nature — do not let the proxy give up first.
        transport http {
            read_timeout 10m
        }
    }
}
systemctl reload caddy
ufw allow 80,443/tcp
ufw status                # 11434 must appear nowhere

В выборе bearer-токена вместо базовой аутентификации есть своё изящество. Ollama отдаёт OpenAI-совместимый API, и каждый клиент OpenAI отправляет свой ключ ровно в этом заголовке, поэтому только что сгенерированный токен становится тем самым API-ключом, который ваши приложения уже умеют передавать. Никакой кастомный заголовок не нужен, а ротация доступа — это одна строка в Caddyfile и одна переменная окружения на стороне вызывающего.

Проверьте с другого сервера, не с этого самого. Первый вызов должен быть отклонён, а второй — получить ответ:

curl -s -o /dev/null -w '%{http_code}\n' https://llm.example.com/api/tags
# → 401

curl -s https://llm.example.com/api/tags -H "Authorization: Bearer THE_TOKEN" | jq '.models[].name'
# → the list of models you pulled

Если модель будут вызывать агенты, а не вы сами, вопрос защищённости заслуживает более полного разбора в руководстве по размещению удалённого MCP-сервера — те же рассуждения про TLS, токены и то, что откуда должно быть доступно, только применительно к сервису, который раздаёт инструменты, а не токены.

Шаг 05 · Подключение

Один base URL, и всё уже умеет с ним работать. Меняете одну строку.

Ollama отдаёт OpenAI-совместимый интерфейс на /v1 наряду со своим собственным API. В этом вся история интеграции: всё, что написано под OpenAI, — официальные SDK, обёртки фреймворков, узлы автоматизации — начинает работать после смены base URL и ключа, и больше ничего менять не нужно.

curl -s https://llm.example.com/v1/chat/completions \
  -H "Authorization: Bearer THE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama3.1:8b",
    "messages": [{"role":"user","content":"Reply with the word OK."}]
  }' | jq -r '.choices[0].message.content'

На Python от облачной настройки отличаются только две строки в начале:

from openai import OpenAI

client = OpenAI(
    base_url="https://llm.example.com/v1",
    api_key="THE_TOKEN",
)

r = client.chat.completions.create(
    model="llama3.1:8b",
    messages=[{"role": "user", "content": "Classify: 'the invoice is overdue'"}],
)
print(r.choices[0].message.content)

Попросите JSON — получите JSON. Самая полезная возможность для автоматизации — это ограниченный вывод. Ollama умеет заставить ответ быть валидным JSON, а не просто надеяться на дисциплинированность модели, и это превращает небольшую модель из ненадёжного рассказчика в надёжный парсер — именно в этом разница между workflow, который работает без присмотра, и тем, который ломается на каждом сороковом элементе:

curl -s http://127.0.0.1:11434/api/generate -d '{
  "model":  "llama3.1:8b",
  "prompt": "Extract the total and the currency: Invoice 4021, 1 249,90 EUR due 30 days.",
  "format": "json",
  "stream": false
}' | jq -r .response
# → {"total": 1249.90, "currency": "EUR"}

В связке автоматизации действует то же самое: в n8n есть отдельный узел Ollama, а его узел OpenAI принимает произвольный base URL, так что существующий workflow переходит на локальный инференс правкой одного credential. Руководство по самостоятельному хостингу n8n описывает сам движок автоматизации; по возможности разнесите их по разным серверам, потому что движок, простаивающий на 700 МБ, и модель, которой нужно пять гигабайт, — плохие соседи на восьмигигабайтном сервере.

И эндпоинт эмбеддингов — вот где этот сервер действительно окупается. Модели эмбеддингов на два порядка меньше генеративных моделей и делают один проход на фрагмент, ничего не генерируя, поэтому CPU обрабатывает их со скоростью, которая ощущается почти мгновенной:

ollama pull nomic-embed-text      # ~275 MB

curl -s http://127.0.0.1:11434/api/embed -d '{
  "model": "nomic-embed-text",
  "input": ["the first chunk of a document", "the second chunk"]
}' | jq '.embeddings | length'
Шаг 06 · Ограничение

Ничем не ограниченный сервер моделей заберёт себе все ресурсы. Задайте ему границы.

Ограничьте контекст. Длина контекста — главный регулятор расхода памяти, а значение по умолчанию щедрее, чем нужно небольшому серверу. Задайте его глобально исходя из того, что реально требуется вашему самому длинному промпту, — большинство задач классификации и извлечения комфортно укладываются в четыре тысячи токенов, — а для редких запросов, которым нужно больше, повышайте его точечно:

Environment="OLLAMA_CONTEXT_LENGTH=4096"
curl -s http://127.0.0.1:11434/api/generate -d '{
  "model": "llama3.1:8b",
  "prompt": "…a long document…",
  "options": { "num_ctx": 16384 },
  "stream": false
}'

Решите, как долго модель будет оставаться в памяти. Резидентная модель отвечает мгновенно, но держит в заложниках несколько гигабайт памяти. На сервере, выделенном только под инференс, держите её загруженной постоянно; на общем сервере дайте ей выгружаться через некоторое время. Это значение можно задавать и на уровне запроса, так что ночной пакетный процесс может закрепить модель на время своей работы и выгрузить её по завершении:

OLLAMA_KEEP_ALIVE=-1     # resident until the service restarts
OLLAMA_KEEP_ALIVE=30m    # a sensible default on a shared box
OLLAMA_KEEP_ALIVE=0      # unload immediately after each request

ollama ps                # what is resident right now, and how much it holds

Сериализуйте очередь. Два одновременных запроса к одной модели не выполняются вдвое быстрее; они конкурируют за один и тот же насыщенный канал памяти, и каждый становится медленнее, а если Ollama решит загрузить вторую копию, чтобы их обслужить, серверу не хватит RAM. На таком классе железа один запрос за раз, с очередью перед ним, — это одновременно и самая быстрая, и единственная безопасная конфигурация, поэтому ещё на шаге 02 OLLAMA_NUM_PARALLEL и OLLAMA_MAX_LOADED_MODELS зафиксировали в единицу.

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

ollama list
du -sh /var/lib/ollama/models
ollama rm mistral:7b qwen2.5:14b

И наконец, делайте резервные копии того, что невоспроизводимо. Веса модели к этому не относятся — их вернёт обычный pull. А вот что действительно стоит хранить в репозитории — это конфигурация, Caddyfile, токен, промпты, которые вы дорабатывали три недели, и, если вы его построили, векторный индекс для поиска. Руководство по зашифрованным резервным копиям описывает механику; список того, что нужно включить для этого сервера, короткий, и его стоит записать.

Хорошая часть · Поиск

Где CPU опровергает этот довод. Эмбеддинги — это не медленно.

Всё сказанное выше касалось генерации — той части, которую CPU выполняет медленно. Поиск (retrieval) — это вторая половина большинства полезных систем, и она полностью переворачивает картину: именно поэтому самый дешёвый тариф на этой странице способен приносить настоящую пользу, даже если вы никогда не сгенерируете на нём ни одного токена.

Модель эмбеддингов превращает фрагмент текста в вектор. Она измеряется сотнями мегабайт, а не гигабайтами, делает ровно один прямой проход на каждый фрагмент, и здесь нет пословного цикла, который упирался бы в пропускную способность памяти. На том же сервере, где модель 8B пишет три слова в секунду, модель эмбеддингов пройдёт библиотеку документов со скоростью, похожей на копирование файлов.

Вот как это выглядит. Разбейте документы на фрагменты по несколько сотен слов. Постройте эмбеддинг каждого фрагмента один раз и сохраните вектор. В момент вопроса постройте эмбеддинг самого вопроса, найдите несколько ближайших фрагментов и передайте их модели вместе с вопросом. Для хранения не нужно ничего экзотического: базы SQLite с векторным расширением хватит на десятки тысяч фрагментов на одном VPS, а PostgreSQL с pgvector покроет и куда больший объём. Отдельная векторная база данных — это нормально захотеть позже, но ненужная зависимость в первый день.

Почему это важнее скорости. Посмотрите, чего касается каждая половина. Этап генерации видит один вопрос и несколько абзацев. Этап эмбеддинга видит <em>каждый документ, которым вы владеете</em> — весь архив, каждый договор, каждую заметку, каждое сообщение, пропущенные через модель по фрагменту за раз. Если этот этап работает через облачный эндпоинт, весь ваш корпус документов был передан третьей стороне ради индексации. Если он работает на вашем собственном сервере, не сдвинулось ничего.

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

Два соседних руководства на этом сайте делают эту схему наглядной. Локальный SearXNG даёт уровню поиска приватный фронтенд для открытого веба, а не корпус документов; локальное хранилище документов даёт как раз этот корпус. Оба они, вместе с моделью, укладываются в тарифы, которые в месяц стоят дешевле одного облачного места.

Уровень под моделью

Чувствительная часть — это промпты. Не ответы — вопросы.

Люди рассуждают о приватности моделей так, будто риск кроется в выводе. Это не так. Вывод — типовой текст; тысяча других людей получили что-то похожее. Уличающий артефакт — это ввод, а год вводов складывается в на редкость полный портрет организации.

Подумайте, что на самом деле содержит журнал запросов. Договор, который вы вставили, чтобы получить его краткое содержание. Письмо клиента, которое вы попросили классифицировать, — вместе с самим клиентом. Медицинское заключение, цифру зарплаты, заявление об увольнении, которое вы черновили, код из непубличного репозитория. А вокруг всего этого — метаданные: какие вопросы, в каком порядке, в какой час, с какого адреса, на протяжении скольких месяцев. Никто не подписывает документ со словами «вот наша стратегия» — но последовательность вопросов и есть этот документ, честно собранный вами самими, запрос за запросом.

Уровень первый — что хранит сам эндпоинт. Серьёзные провайдеры публикуют серьёзные политики, и добросовестные из них действительно не обучаются на трафике бизнес-API. Но это не то же самое, что обещание не хранить его. Запросы обычно хранятся какое-то время для контроля злоупотреблений, доступны сотрудникам при определённых условиях и могут быть предоставлены по судебному запросу — именно так и должна работать крупная платформа, и именно поэтому это неподходящее место для текста, который вы не отправили бы по почте незнакомцу. У модели на вашем собственном сервере такого лога нет, если вы сами его не заведёте.

Уровень второй — личность, к которой привязан лог. Само по себе хранение — лишь половина риска. Вторая половина — это ключ, к которому оно привязано: аккаунт, название компании, платёжный адрес, карта. Именно эта связка превращает «кто-то спрашивал про поглощение конкурента» в «эта компания спрашивала, в тот самый вторник». Убрать облачную модель из уравнения — убрать хранение; убрать личность с сервера — убрать связку. VPS, открытый без email и документа, удостоверяющего личность, в скандинавской юрисдикции, оплаченный в Monero, — вторая половина того же самого решения.

Уровень третий — логи, которые пишете вы сами. Самостоятельный хостинг не убирает риск, а переносит его, и стоит трезво понимать, куда именно. Ваше приложение, скорее всего, логирует собственные промпты. Обратный прокси логирует каждую строку запроса. Отладочная сессия двухмесячной давности оставила подробный вывод в журнале. Сама модель между вызовами не хранит ничего, а вот окружающая её инфраструктура может хранить всё — поэтому осознанно решите, что именно записывается, задайте срок хранения и держите этот лог по тем же стандартам, которые вы не были готовы принять от кого-то другого.

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

Заметки с практики · Шесть ловушек

Шесть способов разочароваться в этом подходе. Пяти из них можно избежать.

Ловушка 01 · Память

Сервер завис, а не просто замедлился

Модель вместе с KV-кэшем превысила объём RAM, и ядро начало подкачивать веса на каждом токене. Либо помещайтесь в память, либо берите размер меньше — среднего варианта нет.

Ловушка 02 · Открытость

Кто-то чужой пользовался вашим CPU

OLLAMA_HOST выставили в 0.0.0.0, чтобы заработал клиент. У API нет вообще никакой аутентификации, а 11434 сканируют. Loopback плюс прокси, проверяющий токен.

Ловушка 03 · Ожидания

Работает, но печатает как факс

Для интерактивного ассистента выбрали модель 32B. Подбирайте размер под сценарий: интерактиву нужна модель поменьше, качеству — асинхронная работа.

Ловушка 04 · Контекст

Первый запрос прошёл нормально, десятый еле полз

Растущий диалог увеличивает кэш, а вся история перечитывается на каждом ходе. Ограничьте контекст и начинайте новый диалог вместо бесконечного наращивания.

Ловушка 05 · Резидентность

Пять гигабайт исчезли, а ничего не запущено

Модель намеренно остаётся резидентной после последнего вызова. Настройте OLLAMA_KEEP_ALIVE под свой сервер и сначала смотрите ollama ps, прежде чем винить что-то ещё.

Ловушка 06 · Диск

Диск заполнили модели, которые вы сравнили один раз

Четыре кандидата по пять гигабайт каждый, и ни один не удалён. Сделайте ollama rm частью самого сравнения и проверяйте каталог моделей, когда срабатывают предупреждения о месте на диске.

FAQ · Локальные модели

Вопросы, и ответы на них.

Десять вопросов, которые определяют, подходит ли модель только на CPU для задачи, которую вы задумали.

Реально ли запустить LLM без GPU?

Да, с одной честной оговоркой насчёт скорости. Квантованная модель прекрасно работает на обычных серверных CPU — веса лежат в RAM, вычисления вполне по силам, и ничто в этом процессе не требует видеокарты. То, что покупает GPU, — это пропускная способность памяти, а именно она задаёт скорость генерации. Поэтому сервер только на CPU ответит корректно и полностью — где-то от нескольких до нескольких десятков слов в секунду, в зависимости от модели. Это медленно для чат-окна и вполне нормально для работы, которую люди реально автоматизируют: классифицировать сообщение, вытащить структурированный JSON из документа, суммировать страницу, построить эмбеддинг текста для поиска, переписать абзац. Вопрос никогда не в том, «может ли» — а в том, «с какой скоростью, и важна ли эта скорость для конкретной задачи».

Сколько токенов в секунду стоит ожидать?

Считайте сами, а не доверяйте чужим бенчмаркам — включая наши. Плотная модель читает из памяти все свои веса, чтобы сгенерировать один токен, поэтому потолок скорости — примерно пропускная способность памяти, делённая на размер модели. Модель 3B, квантованная примерно до 2 ГБ, на сервере с реальной пропускной способностью 20 ГБ/с даёт потолок около 10 токенов в секунду; 7B при 4,4 ГБ — около 4,5; 32B при 20 ГБ — меньше 1. Реальные цифры оказываются ниже потолка — считайте это 50–70 процентами — и зависят от сервера, соседей по хосту и количества потоков. Обработка промпта — это совсем другое дело: она упирается в вычисления, а не в память, работает в разы быстрее, и именно поэтому суммировать длинный документ комфортно, а вести чат с большой моделью — нет.

С какой модели начать при 8 ГБ?

Instruct-модель класса 8B в Q4_K_M занимает около 4,5–5 ГБ и оставляет место для операционной системы и KV-кэша. Этот размер — текущая золотая середина: достаточно хороша, чтобы надёжно следовать инструкциям, выдавать валидный JSON по запросу, суммировать, классифицировать и переписывать текст; и при этом достаточно компактна, чтобы оставаться отзывчивой. Меньше неё модель 3B по-настоящему полезна для классификации, тегирования и маршрутизации и работает примерно вдвое быстрее. Больше — модель 14B заметно лучше справляется с многошаговыми рассуждениями и работает примерно вдвое медленнее, что оправданно для пакетной обработки и плохо подходит для чего-либо интерактивного. Начните с 8B, измерьте, а дальше двигайтесь в ту сторону, куда укажет измерение.

Сколько RAM реально нужно модели?

Размер квантованного файла, плюс KV-кэш, плюс место для системы — и всё это должно поместиться целиком, потому что сбой здесь выглядит не как замедление, а как коллапс. Когда модель не помещается, ядро начинает сбрасывать веса модели на диск, и генерация, которая должна занимать четыре секунды, занимает четыре минуты, а load average уходит в десятки. Рабочее правило для Q4_K_M: модель 3B — около 2 ГБ, 8B — около 5 ГБ, 14B — около 9 ГБ, 32B — около 20 ГБ, 70B — около 40 ГБ. Добавьте два гигабайта на Debian и его сервисы и ещё от одного до четырёх — на KV-кэш, в зависимости от допустимой длины контекста. И берите тариф на ступень выше расчётного, а не впритык.

Ollama или llama.cpp?

Ollama и есть llama.cpp, только с реестром моделей, REST API и обёрткой в виде сервиса systemd. Используйте Ollama, если нет особой причины поступить иначе: одна команда установки, ollama pull вместо поиска файлов GGUF по интернету, OpenAI-совместимый эндпоинт и разумные значения по умолчанию для числа потоков и памяти. Берите llama.cpp напрямую, когда нужен флаг, которого нет в Ollama, когда нужно закрепить конкретную сборку ради воспроизводимости, или когда вы запускаете одну модель с одной конфигурацией навсегда и не хотите, чтобы демон что-то за вас решал. Оба варианта гоняют одни и те же веса с одной и той же скоростью; вся разница — в эксплуатации.

Насколько локальная модель уступает большим облачным?

Нет, и притворяться иначе — только зря терять время. Передовая модель за API крупнее всего, что поместится на виртуальном сервере, и она будет лучше в сложных рассуждениях, длинном контексте и коде. А вот в чём небольшая локальная модель по-настоящему конкурентоспособна — так это в огромной середине реальной работы: определить, к какой из шести категорий относится письмо, извлечь пять полей из счёта, сжать переписку поддержки, переписать описание, проставить теги документу, решить, описывают ли две записи одного и того же человека. Для задач такого класса разрыв между 8B и передовой моделью небольшой, разница в стоимости — колоссальная, а разница в приватности — абсолютная. Продуктивная позиция не «заменить API», а «перестать отправлять туда те девяносто процентов, которым никогда не нужно было никуда уходить».

Есть ли в Ollama аутентификация?

Нет — вообще никакой, и это самый важный операционный факт в этом руководстве. Нет ни пароля, ни токена, ни модели пользователей. Любой, кто может открыть TCP-соединение к порту 11434, может генерировать текст, получать список ваших моделей, скачивать новые и удалять существующие. Этот порт постоянно сканируют, и незащищённые инстансы находят и используют как бесплатные вычислительные ресурсы посторонние люди — сначала это проявляется как необъяснимый load average, а потом как счёт за трафик. Держите Ollama привязанной к 127.0.0.1, поставьте перед ней обратный прокси, завершайте TLS на нём и требуйте bearer-токен или клиентский сертификат на уровне прокси. Если модель не нужна никому за пределами сервера, не открывайте её вообще.

Может ли n8n или мой агент использовать локальную модель?

Да, и обычно для этого достаточно одного поля. Ollama отдаёт OpenAI-совместимый API на /v1, так что любой клиент, где можно задать base URL, — SDK от OpenAI, LangChain, узел OpenAI в n8n, большинство агентных фреймворков — заработает с ней, если указать https://your-host/v1 и отправить в качестве ключа любую непустую строку. У n8n есть и отдельный узел Ollama. На практике хорошо работает гибридная схема: направляйте основной, скучный, высокообъёмный поток вызовов на локальную модель, а облачный API оставляйте на те немногие шаги, где реально нужны рассуждения топового уровня, с фолбэком на случай, если локальная модель откажется выдать валидный JSON.

Имеет ли смысл считать эмбеддинги на CPU?

Это самая выгодная вещь на всей этой странице. Модели эмбеддингов крошечные — десятки-сотни мегабайт, а не гигабайты, — и делают один прямой проход на фрагмент без пословной генерации, так что CPU расправляется с ними без труда. Это значит, что вся поисковая половина системы RAG — индексация документов, эмбеддинг запроса, поиск ближайших фрагментов — комфортно работает на самом дешёвом тарифе, и это как раз та половина, которая касается каждого вашего документа. Даже если вы решите, что этап генерации должен жить в облачном API, перенос этапа эмбеддинга на собственный сервер удержит ваш корпус подальше от чужого.

Зачем вообще держать модель у себя, если API быстрее и дешевле?

Три причины, в порядке возрастания значимости. У стоимости есть форма: API дешевле — пока не перестаёт быть дешевле, и у workflow, классифицирующего пятьдесят тысяч сообщений в месяц, счёт растёт, а у VPS за $7.90 — нет. Доступность: никаких рейт-лимитов, никакого устаревания модели, под которую вы всё построили, никаких сбоев на чужой странице статуса. И решающая причина — ваши промпты — самый откровенный текст, который вы производите. Не ответы, а вопросы. Что вы спрашивали, о ком, в какой день, в каком порядке. Облачный эндпоинт видит всё это, привязанным к платёжной личности. Модель, работающая на арендованном без документа сервере, в скандинавской юрисдикции, оплаченном в Monero, видит тот же текст и не отчитывается ни перед кем.

Получите железо

Nordic VPS для модели, которая отвечает только вам. Без KYC, оплата криптовалютой.

Garrison (4 vCPU, 8 ГБ, 240 ГБ NVMe, $7.90/мес.) тянет модель 8B с запасом на KV-кэш и систему — с этого тарифа стоит начинать большинству. Ravelin удваивает память для 14B и длинных контекстов. Никакой почты при регистрации, никакого документа, удостоверяющего личность, и никакой платы за токены.

Последняя проверка · 2026-08-24 · Источники · Документация и справочник API Ollama, документация llama.cpp, документация обратного прокси Caddy, опубликованные карточки моделей для упомянутых квантованных сборок · Периодичность · ежегодно