diff --git a/agents/inbox/2026-08-30-A38-local-model-benchmark.md b/agents/inbox/2026-08-30-A38-local-model-benchmark.md new file mode 100644 index 0000000..7e78f7d --- /dev/null +++ b/agents/inbox/2026-08-30-A38-local-model-benchmark.md @@ -0,0 +1,167 @@ +# Задание 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`.