# Jeff 0.8B: модель, которая отвечает за миллисекунды — кому она нужна

> AI Release · @ai_release1 · https://ai-release.org/guides/jeff-0-8b-lokalno.html

## TL;DR
- Время выполнения: 25 минут (без учёта скачивания весов модели)
- Уровень сложности: Intermediate
- Понадобится: Linux/macOS или Windows 10/11 + WSL2; Ollama либо llama.cpp; `curl`; `jq`; файл весов или доступ к реестру моделей; nexa-bridge (репозиторий `NexaEthos/nexa-bridge` на GitHub), если машина с моделью стоит за NAT
- Требования к RAM/VRAM и точный тег модели в реестре сверьте с карточкой модели и документацией: в исходных материалах этих цифр нет

## Требования и подготовка
![Иллюстрация к разделу «Требования и подготовка»](https://ai-release.org/guides/img/jeff-0-8b-lokalno-ru-1.jpg?v=1793867788)


- ОС: Linux x86_64/arm64, macOS или Windows 10/11 с WSL2 — сервер инференса запускается из терминала.
- Сервер инференса: Ollama (быстрый старт) или llama.cpp (если у вас GGUF-файл). Оба варианта nexa-bridge поддерживает как источники моделей — наравне с vLLM и LM Studio.
- `curl` и `jq` — чтобы снимать HTTP-коды, время ответа и разбирать JSON.
- Свободное место под веса. Ориентир масштаба: Qwen 3.8 27B весит 17 ГБ и работает на ноутбуке; файл 0.8B-модели меньше, но точный размер берите из карточки модели.
- Права обычного пользователя; root не нужен, порт по умолчанию слушается на localhost.
- Если модель должна быть доступна клиентам вне локальной сети — доступ к репозиторию `NexaEthos/nexa-bridge`. Проброс портов и белый IP не требуются.

Чек-лист перед стартом:

- [ ] `ollama --version` печатает строку с версией
- [ ] `curl --version` и `jq --version` отвечают без ошибок
- [ ] на диске достаточно места под веса (сверьте с карточкой модели)
- [ ] известен точный тег модели или путь к `.gguf`-файлу

**Пример:** `ollama --version` → строка `ollama version is <номер>`; если команда не найдена — установщик не попал в `PATH`, перезапустите терминал.

## Шаг 1. Поднимаем локальный инференс и получаем первый ответ

**Что сделать:** запустить сервер, подключить веса 0.8B-модели и отправить один запрос.

**Зачем:** миллисекунды можно мерить только на живом процессе, который держит веса в памяти. Всё дальнейшее — обёртки над этим портом, поэтому сначала база.

**Как проверить:** сервер отвечает на HTTP, модель возвращает осмысленный текст.

```bash
ollama serve
```

Во втором терминале:

```bash
ollama pull <тег-модели>
ollama run <тег-модели> "Извлеки город из адреса: Москва, ул. Тверская, 1"
```

**Пример:** на экране сначала идёт `pulling manifest`, затем ответ вида `Москва`. Если такой задачи в карточке модели нет — сверьтесь с документацией, какие форматы промпта она ожидает.

Вариант на llama.cpp, если у вас файл весов:

```bash
llama-server -m ./<файл-модели>.gguf --host 127.0.0.1 --port 8080 -c 2048
curl -s http://localhost:8080/health
```

Ожидаемый вывод: `{"status":"ok"}`.

Почему это работает: `llama-server` загружает веса один раз и отдаёт HTTP-интерфейс, поэтому каждый следующий запрос не тратит время на чтение файла с диска. Именно на этом шаге появляется первая честная цифра — время до ответа без сетевого плеча.

Первый запуск локальной модели вручную (установка, выбор квантования, проверка железа) разобран пошагово в гайде [«Как запустить ИИ-модель локально на своём компьютере»](https://ai-release.org/guides/kak-zapustit-ii-model-lokalno-na-svoem-kompyutere-gayd.html?utm_source=tg&utm_medium=channel&utm_campaign=guide_inline&utm_content=guide_to_guide).

## Шаг 2. Выставляем OpenAI-совместимый эндпоинт (и выводим его из-за NAT)
![Иллюстрация к разделу «Шаг 2. Выставляем OpenAI-совместимый эндпоинт (и выводим его из-за NAT)»](https://ai-release.org/guides/img/jeff-0-8b-lokalno-ru-2.jpg?v=1793867792)


**Что сделать:** перевести клиента на путь `/v1/chat/completions`, а если машина с моделью спрятана за NAT — поставить перед ней nexa-bridge.

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

**Как проверить:** эндпоинт отдаёт список моделей, а тестовый запрос возвращает JSON с ответом.

```bash
export OPENAI_BASE_URL=http://localhost:11434/v1
export OPENAI_API_KEY=ollama
curl -s "$OPENAI_BASE_URL/models" | jq -r '.data[].id'
```

Ожидаемо: список идентификаторов, среди них `<тег-модели>`. Ключ `ollama` — заглушка: локальный сервер не проверяет авторизацию, но клиенты требуют непустое значение.

**Пример** запроса из Python:

```python
import os, time, requests

base = os.environ["OPENAI_BASE_URL"].rstrip("/")
payload = {
    "model": "<тег-модели>",
    "messages": [{"role": "user", "content": "Извлеки город: Москва, ул. Тверская, 1"}],
    "stream": False,
}
t0 = time.perf_counter()
r = requests.post(f"{base}/chat/completions", json=payload, timeout=30)
print(r.status_code, round((time.perf_counter() - t0) * 1000), "ms")
print(r.json()["choices"][0]["message"]["content"])
```

Ожидаемый результат: `200` и число миллисекунд, затем текст ответа. Если вместо этого пришёл `404` — вернитесь к шагу 1: имя модели в запросе не совпадает с тем, что реально лежит на сервере.

Если модель стоит на машине за NAT, наружу её выводит nexa-bridge — OpenAI-совместимый прокси на Rust с исходящим туннелем для vLLM, Ollama, LM Studio и llama.cpp. Машина остаётся за NAT, открывать порты и настраивать проброс не нужно: соединение идёт изнутри наружу. Команды установки и конфиг лежат в README репозитория `NexaEthos/nexa-bridge` — сверьтесь с документацией, в исходном материале их нет.

## Шаг 3. Замеряем миллисекунды и решаем, кому модель нужна
![Иллюстрация к разделу «Шаг 3. Замеряем миллисекунды и решаем, кому модель нужна»](https://ai-release.org/guides/img/jeff-0-8b-lokalno-ru-3.jpg?v=1793867795)


**Что сделать:** снять 20 замеров на реальном промпте вашего сценария и посчитать p50 и p95.

**Зачем:** «отвечает за миллисекунды» — это не свойство модели, а результат замера на вашем железе, вашей длине контекста и вашем промпте. Одно число без методики ничего не доказывает.

**Как проверить:** у вас есть min/median/max по 20 запросам и понятно, укладывается ли p95 в бюджет задачи.

```bash
for i in $(seq 1 20); do
  curl -s -o /dev/null -w "%{time_starttransfer}\n" \
    "$OPENAI_BASE_URL/chat/completions" \
    -H "Content-Type: application/json" \
    -d '{"model":"<тег-модели>","stream":true,"messages":[{"role":"user","content":"Извлеки город: Москва, ул. Тверская, 1"}]}'
done | sort -n | awk '{a[NR]=$1} END {print "min="a[1], "median="a[int((NR+1)/2)], "max="a[NR]}'
```

**Пример** вывода: `min=0.061 median=0.078 max=0.193` — секунды; ваши числа будут другими, важно соотношение median и max. Флаг `"stream":true` обязателен: при `false` метрика `time_starttransfer` фиксируется только после генерации всего ответа и показывает не время до первого токена, а полное время.

| Сценарий | Что мерить | Условие приёмки |
|---|---|---|
| Маршрутизация и классификация запроса | p95 на коротком промпте | p95 укладывается в бюджет сценария, метка верная на вашей выборке |
| Извлечение полей (адрес, сумма, дата) | p50 и доля корректных разборов | качество проверено на 20–30 своих примерах |
| Автодополнение в редакторе | время до первого токена | задержка не ощущается при наборе текста |
| Длинная генерация | полное время ответа | модель не обрывает ответ на вашем лимите контекста |

Кому такая модель нужна по итогам замера: тем сценариям, где p95 укладывается в бюджет и где задача — короткая нормализация или извлечение, а не длинное рассуждение. Если узкое место — не скорость, а приватность, полный селф-хост большой модели не обязателен: в разборе про PII-фильтр используется self-hosted `guardrails-llm-filter` от Cloud.ru (Apache-2.0) как прокси перед облачной моделью, в режиме `enforce` он заменяет персональные данные плейсхолдерами, в `detect` — только пишет в журнал. Что вообще есть на рынке моделей под другие задачи — в подборке [«Лучшие нейросети и ИИ-модели 2026»](https://ai-release.org/guides/luchshie-nejroseti-i-modeli-2026.html?utm_source=tg&utm_medium=channel&utm_campaign=guide_inline&utm_content=guide_to_guide).

## Возможные проблемы и решения

**Проблема. Модель не влезает в память при запуске**

- Ошибка: `Error: model requires more system memory (3.1 GiB) than is available (2.0 GiB)`
- Причина: выбранный вариант весов или слишком длинный контекст не помещаются в доступную RAM/VRAM; числа в сообщении у вас будут свои.
- Решение: уменьшить контекст (`llama-server ... -c 1024`), взять более компактное квантование из карточки модели и проверить, что память не занята прошлым процессом: `ollama ps`, затем при необходимости остановить лишнюю модель.

**Проблема. Клиент не видит сервер**

- Ошибка: `curl: (7) Failed to connect to localhost port 11434 after 0 ms: Couldn't connect to server`
- Причина: сервер инференса не запущен или слушает другой порт (например, `8080` у `llama-server`).
- Решение: поднять сервер (`ollama serve`) и сверить переменную `OPENAI_BASE_URL` с фактическим портом: `curl -s http://localhost:11434/api/tags | jq`.

**Проблема. Запрос приходит, но модель не находится**

- Ошибка: `{"error":{"message":"model \"<тег-модели>\" not found, try pulling it first","type":"api_error"}}`
- Причина: имя модели в теле запроса не совпадает с тем, что загружено на сервере (опечатка в теге или веса ещё не скачаны).
- Решение: посмотреть реальные идентификаторы (`curl -s http://localhost:11434/api/tags | jq -r '.models[].name'`) и подставить точный в `"model"`, либо скачать веса: `ollama pull <тег-модели>`.

## Резюме и следующие шаги

Модель на 0.8B нужна там, где замер p95 на вашем промпте укладывается в бюджет задачи, а качество проверено на собственной выборке, — остальным достаточно облака с PII-фильтром. Следующий шаг: прогнать 20–30 реальных примеров через `/v1/chat/completions` и зафиксировать в тикете медиану и p95 вместе с версией весов.

## FAQ

**Jeff 0.8B — это сколько параметров и хватит ли ноутбука?**
0.8B — примерно 0.8 млрд параметров, это заметно меньше, чем 27B-модель Qwen 3.8 весом 17 ГБ, которая работает на ноутбуке. Точные требования к памяти и размер файла сверьте с карточкой модели.

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

**Нужно ли открывать порты, если машина с моделью за NAT?**
Нет. nexa-bridge — прокси на Rust с исходящим туннелем: соединение устанавливается изнутри, проброс портов и белый IP не требуются. Порядок запуска — в README репозитория.

**Что делать, если качество 0.8B не хватает, а данные нельзя отдавать в облако?**
Вариант из практики — оставить облачную модель, но поставить перед ней PII-фильтр: `guardrails-llm-filter` в режиме `enforce` маскирует персональные данные плейсхолдерами. Учтите риск из того же разбора: при сбое маскирования запрос может уйти без обработки, поэтому такой сбой надо отслеживать как инцидент.
