Локальный кодер выдаёт 13,6 токена в секунду, и владелец хочет понять, есть ли модель быстрее при сопоставимом качестве. Базовая линия снята ревьюером на живом сервере и вписана в задание, чтобы не мерилась заново: Qwen3.8-27B даёт 13,6 ток/с генерации, Qwen3-4B — 124,1, разница почти девятикратная. Цена контекста измерена точно: 39 КиБ на токен у 27B и 81,5 у 4B. Отдельно измерен диск, и он оказался узким местом: Crucial BX500 без DRAM, 187 МБ/с мимо кэша, NVMe на машине нет. Загрузка 19-гигабайтной модели с холодного диска занимает около 100 секунд. Первый замер дал 4,1 ГБ/с, но это было чтение из кэша оперативной памяти — случай вписан в задание как предупреждение. Из списка владельца проверкой отклонён gpt-oss:120b: в карточке модели прямо указано 80 ГБ и H100. Остальные отсортированы по пригодности для V100, где скорость определяется активными параметрами, а не общим размером, поэтому модели MoE поставлены первыми. Главное требование задания: мерить качество, а не только скорость. Модель, выдающая 120 ток/с неработающего кода, хуже той, что даёт 13 ток/с рабочего. Нужен набор из настоящих правок по репозиторию, а не синтетические задачки. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
167 lines
13 KiB
Markdown
167 lines
13 KiB
Markdown
# Задание A38: сравнение локальных моделей на железе владельца
|
||
|
||
## Дата поступления
|
||
2026-08-30
|
||
|
||
## База
|
||
|
||
Ветка ревьюера `review/a28-a31-fixes` (`ab2ee12`).
|
||
|
||
```
|
||
git fetch origin --prune
|
||
git checkout -b antigravity/a38-model-benchmark origin/review/a28-a31-fixes
|
||
```
|
||
|
||
В `main` напрямую не пушить.
|
||
|
||
## Порядок исполнения
|
||
|
||
Два прохода: **Flash** реализует, **Pro** проводит аудит. Пункт **P0-6** написан для аудитора.
|
||
|
||
Выполнять **после A34 и A35**. Задание исследовательское: оно не чинит продукт, а отвечает на вопрос, какой моделью его обслуживать.
|
||
|
||
---
|
||
|
||
## Задача
|
||
|
||
У владельца локальный кодер работает медленно, и он хочет понять, есть ли модель быстрее при сопоставимом качестве.
|
||
|
||
## Что измерено ревьюером — это базовая линия, заново не мерить
|
||
|
||
Всё снято на живом сервере `192.168.1.81`, Tesla V100-PCIE-32GB.
|
||
|
||
**Скорость двух работающих моделей, одинаковый запрос на генерацию кода:**
|
||
|
||
```
|
||
Qwen3.8-27B Q4_K_M (порт 8081) генерация 13,6 ток/с промпт 95,9 ток/с
|
||
Qwen3-4B-Instruct (порт 8082) генерация 124,1 ток/с промпт 503,5 ток/с
|
||
```
|
||
|
||
Разница почти девятикратная. 200 токенов у 27B заняли 14,6 секунды.
|
||
|
||
**Память видеокарты, цена контекста измерена точно:**
|
||
|
||
```
|
||
27B: база 18 000 МиБ + 39 КиБ на токен контекста
|
||
4B: база 2 760 МиБ + 81,5 КиБ на токен контекста
|
||
всего 32 768 МиБ
|
||
```
|
||
|
||
**Диск, где лежат модели, — узкое место:**
|
||
|
||
```
|
||
/dev/sdc Crucial BX500 480G, SATA SSD без DRAM
|
||
чтение мимо кэша: 187 МБ/с
|
||
NVMe на машине отсутствует
|
||
оперативная память: 62 ГБ, доступно 42
|
||
свободно на диске: 313 ГБ
|
||
```
|
||
|
||
При 187 МБ/с загрузка 19-гигабайтной модели с холодного диска занимает около **100 секунд**. Это надо учитывать при планировании прогонов: время загрузки нельзя путать со скоростью работы.
|
||
|
||
**Особенность железа, определяющая выбор кандидатов.** V100 — это Volta 2017 года: нет BF16, нет FP8, нет MXFP4, и производительность упирается в пропускную способность памяти. Значит скорость генерации определяется **активными** параметрами, а не общим размером. Модели MoE здесь в выигрышном положении, и проверить это — часть задания.
|
||
|
||
## P0-1. Инфраструктура сравнения
|
||
|
||
Держать несколько крупных моделей в памяти одновременно невозможно: сейчас две занимают 30,2 ГБ из 32,7.
|
||
|
||
Поставить **llama-swap** (`mostlygeek/llama-swap`, Go, MIT): прокси читает поле `model` из запроса, поднимает нужный `llama-server`, ненужный выгружает по таймауту и освобождает видеопамять. Для хаба это один OpenAI-совместимый адрес — `local_adapter` работает с ним без изменений.
|
||
|
||
Требования:
|
||
|
||
1. Ставится **рядом** с работающими службами, не ломая их. Владелец пользуется сервером ежедневно.
|
||
2. Конфигурация описывает каждую модель отдельной записью; таймаут выгрузки настраивается.
|
||
3. Проверить, что после выгрузки видеопамять **действительно освобождается** — замером `nvidia-smi`, а не по документации.
|
||
4. Откат: если llama-swap мешает, службы `qwen-coder` и `qwen-compressor` возвращаются в прежний вид одной командой. Описать как.
|
||
|
||
## P0-2. Кандидаты
|
||
|
||
Список владельца, отсортированный ревьюером по пригодности для этого железа.
|
||
|
||
**Проверено и отклонено:**
|
||
|
||
| Модель | Причина |
|
||
|---|---|
|
||
| `gpt-oss:120b` | В карточке модели: **80 ГБ**, H100 или MI300X. 117B параметров. На 32 ГБ не помещается. |
|
||
|
||
**Приоритет для прогона:**
|
||
|
||
| Порядок | Модель | Почему |
|
||
|---|---|---|
|
||
| 1 | `nvidia/Nemotron-Cascade-2-30B-A3B` | MoE, около 3B активных: ожидается кратный прирост скорости при качестве крупной модели |
|
||
| 2 | DeepSeek Coder V2 Lite | MoE и специализация на коде |
|
||
| 3 | Qwen2.5 Coder 14B и 32B | плотная, заточена под код: проверка «специализация против размера» |
|
||
| 4 | Granite 4.2 8B | заявлена сильной на длинном контексте |
|
||
| 5 | Phi-4 14B, Qwen3 14B | плотные общего назначения, для полноты |
|
||
| 6 | `gpt-oss 20B` | 21B всего, 3,6B активных, но поставляется в MXFP4, которого V100 не поддерживает: нужна сборка GGUF в обычном квантовании, эффективность будет ниже заявленной |
|
||
|
||
Точные имена сборок GGUF брать **у источника**, а не придумывать. Модель не нашлась или нет подходящего квантования — так и записать в отчёт, а не заменять похожей.
|
||
|
||
## P0-3. Что измерять
|
||
|
||
**Скорость** — объективна и меряется просто:
|
||
|
||
- генерация, токенов в секунду;
|
||
- обработка промпта, токенов в секунду;
|
||
- время холодной загрузки модели;
|
||
- занятая видеопамять.
|
||
|
||
**Качество — важнее скорости, и именно его обычно не меряют.** Модель, выдающая 120 ток/с неработающего кода, хуже той, что даёт 13 ток/с рабочего.
|
||
|
||
Собрать набор из **10–15 настоящих задач** по этому репозиторию, с известным правильным результатом: взять реальные правки из истории git, где видно, что требовалось и что получилось. Синтетические задачки вроде «слить два отсортированных списка» ничего не покажут — на них справляются все.
|
||
|
||
Оценивать: код запускается; тесты проходят; правка делает то, что требовалось; модель следует инструкции, а не пишет вокруг неё. Уже видна разница в поведении: на одинаковом запросе 27B выдала чистый код, а 4B начала с «Sure! Here's a Python function» и развёрнутого docstring.
|
||
|
||
**Длинный контекст — отдельно.** Кодер поднят до 196608, и деградация качества на большом объёме на коротких задачах не видна. Нужен хотя бы один замер на реально длинном входе.
|
||
|
||
## P0-4. Отчёт, по которому можно принять решение
|
||
|
||
Таблица: модель, размер файла, занятая видеопамять, генерация ток/с, промпт ток/с, время загрузки, результат по задачам, поведение на длинном контексте.
|
||
|
||
Плюс вывод в одну строку на каждую модель: годится ли она заменой нынешнему кодеру и почему.
|
||
|
||
**Ничего не менять в конфигурации владельца по итогам.** Задание исследовательское: рекомендация даётся, решение принимает он.
|
||
|
||
## P0-5. Честность измерений
|
||
|
||
1. **Кэш искажает всё.** Первый замер ревьюера дал 4,1 ГБ/с чтения с диска, хотя настоящая скорость 187 МБ/с — файл лежал в кэше оперативной памяти. Замеры скорости диска делать с `iflag=direct`, замеры генерации — после прогрева, и указывать, какой именно случай меряется.
|
||
2. **Одинаковые условия.** Один и тот же промпт, одна температура, одно квантование по возможности. Разное квантование сравнивать нельзя, не оговорив этого.
|
||
3. **Сервер рабочий.** Прогоны не должны надолго лишать владельца локальной модели. Согласовать окно.
|
||
4. Ни одного числа, которого не дал замер.
|
||
|
||
## P0-6. Аудит вторым проходом
|
||
|
||
1. **Числа из головы.** Проверить, что каждая цифра в отчёте получена запуском, а не взята из карточки модели или из общих соображений.
|
||
2. **Кэш** — убедиться, что скорости не измерены по прогретому кэшу без оговорки.
|
||
3. **Качество действительно оценено**, а не заменено скоростью.
|
||
4. **Конфигурация владельца не изменена.**
|
||
5. **Побочные изменения** объяснить.
|
||
6. **Пропущенный пункт назвать пропущенным.**
|
||
|
||
---
|
||
|
||
## Ограничения
|
||
|
||
- Работающие службы не ломать; откат описать.
|
||
- Модели качать в `/srv/ai/models/`, места 313 ГБ.
|
||
- Ничего не менять в маршрутизации и конфигурации хаба.
|
||
- Тег `v0.1.1` не создавать.
|
||
|
||
## Критерии приёмки
|
||
|
||
1. Ветка в `origin`, `git status` чист.
|
||
2. llama-swap поставлен, выгрузка освобождает видеопамять — подтверждено замером `nvidia-smi`; откат описан и проверен.
|
||
3. Прогнаны кандидаты из P0-2 в указанном порядке; недоступные названы недоступными.
|
||
4. По каждой модели: скорость генерации и промпта, видеопамять, время холодной загрузки — измерены.
|
||
5. Набор из 10–15 настоящих задач составлен; результат по каждой модели приведён.
|
||
6. Есть замер на длинном контексте.
|
||
7. Таблица и вывод по каждой модели приложены.
|
||
8. Конфигурация владельца не изменена.
|
||
9. Отчёт: `START_HEAD`, `FINAL_HEAD`, `origin/main`, `git status`.
|
||
|
||
## Главное
|
||
|
||
Нынешний кодер выдаёт 13,6 токена в секунду — для интерактивной работы это тяжело. Вопрос не в том, какая модель быстрее на бумаге, а в том, какая быстрее **при том же качестве на настоящих задачах владельца**. Сравнение, измеряющее только скорость, ответа не даст.
|
||
|
||
## Порядок сдачи
|
||
Передать точный `FINAL_COMMIT_SHA`.
|