Муки выбора: как я подбирал локальную модель для кодинга на 16 ГБ VRAM и трижды менял фаворита

Прокомментировать Просмотры: 0

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

​В конечном итоге пальма первенства досталась решению, изначально отложенному «на растерзание»: громоздкой модели, балансирующей на грани жесткого квантования и казавшейся сплошным компромиссом.

​Ниже подробно описан процесс поиска идеального помощника для WordPress и фронтенд-задач на графическом ускорителе с 16 ГБ памяти. В программе — замеры скорости, нюансы квантования и неожиданно суровый экзамен по русскому языку.

Для каких задач я её искал

Моя стихия — разработка под WordPress. Типичный стек включает PHP, HTML, CSS, JavaScript, интеграцию готовой верстки и проектирование блоков Gutenberg.

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

Поскольку взаимодействие осуществлялось через OpenCode, банального умения писать код было недостаточно. Требовались полноценный вызов инструментов (function calling), адекватный русский язык и высокая скорость ответа, не заставляющая забывать суть исходного запроса. И всё это — в строгих рамках 16 ГБ VRAM с учетом контекста.

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

Эффективность оценивалась исключительно по рабочим кейсам, а производительность и потребление памяти фиксировались на следующей рабочей станции:

Компонент

Моя конфигурация

Видеокарта

GIGABYTE GeForce RTX 5060 Ti WINDFORCE MAX OC, 16 ГБ

Память GPU в диагностике

CUDA0 : RTX 5060 Ti — 16310 MiB

Процессор

AMD Ryzen 5 5600

Оперативная память

32 ГБ

Среда

Windows, llama-server.exe, PowerShell

Пакет CUDA runtime

cudart-llama-bin-win-cuda-12.4-x64

Агент для работы с проектом

OpenCode

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

Передо мной стояла прикладная задача: конвертировать готовую HTML-верстку в блоки Gutenberg посредством Carbon Fields в рамках моего базового плагин-шаблона. Модель должна была проанализировать архитектуру, распределить PHP-логику по файлам, зарегистрировать блок и сгенерировать осмысленные русскоязычные подписи для полей в админке.

Первый этап: скачать всё, что посоветовали нейросети

Пул кандидатов формировался с подачи ChatGPT, Claude и DeepSeek: я запрашивал кодинг-модели, способные поместиться в 16 ГБ, и скачивал релевантные варианты. В результате сформировался следующий арсенал:

Модель

Какие варианты пробовал

Первое впечатление

Qwen Coder 7B семейства 2.5

Q4, Q8

Оптимальна для локальных рутинных задач, в версии Q8 размещается без проблем

Qwen2.5-Coder-14B‑Instruct

Q4, Q5

Разумный компромисс между габаритами и качеством

Qwen3-Coder-30B‑A3B‑Instruct

Q4, Q3

Q4 целиком в VRAM не влез; Q3 превзошел первоначальные ожидания

Qwen3-Coder‑REAP-25B‑A3B

Q4

Успешно умещается с контекстом вплоть до 32K на моей сборке

DeepSeek‑Coder‑V2-Lite‑Instruct

Q4, Q5

Продемонстрировала аномально низкую скорость генерации

Phi-4

Четкой роли в текущей экосистеме не нашла

Модификации с 3–8 миллиардами параметров детальному сопоставлению в качестве основных флагманов не подвергались. Одну из 7B-версий я всё же оставил под мелкие подзадачи — для правки небольших фрагментов кода задействовать тяжеловесов избыточно.

Для тех, кто не до конца погружен в нюансы терминологии: квантование снижает разрядность весовых коэффициентов сети, экономя оперативную память. Маркировки вроде Q4, Q5 и Q8 отражают степень такого сжатия. Как правило, меньший объем влечет деградацию точности, однако оценивать модели исключительно по индексу после буквы Q некорректно.

У Qwen3-Coder присутствует индекс A3B, что указывает на архитектуру Mixture of Experts (MoE). Общее количество параметров составляет около 30 миллиардов, однако при обработке токена задействуется лишь около 3 миллиардов. Это оптимизирует вычислительные затраты, хотя требования к объему хранения весов остаются на уровне полновесных моделей. Детальные спецификации доступны в официальной карточке Qwen3-Coder.

REAP представляет собой отдельную ветку развития. Это базовая модель, усеченная путем удаления части экспертных блоков. Здесь модифицируется сама структура сети, а квантование накладывается уже поверх полученного результата. Метод подробно разобран в документации Cerebras.

Вместо «вроде быстро» — скрипт с замерами

На коротких запросах генерация происходит мгновенно, но стоит скормить нейросети объемный массив кода, как производительность резко падает. Субъективные ощущения в данном случае плохой советчик.

При содействии ChatGPT я написал скрипт на PowerShell для автоматизированного тестирования через llama-server.exe. Утилитный сценарий последовательно активировал различные размеры контекстного окна, фиксировал потребление видеопамяти через nvidia-smi и протоколировал показатели.

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

Производительность отслеживалась отдельно на этапе синтаксического анализа промпта (prefill) и непосредственной генерации ответа (generation). Параллельно контролировался остаток свободной VRAM в момент максимальной нагрузки.

Физический размер файла модели на накопителе не коррелирует напрямую с аппетитами VRAM. Помимо весовых коэффициентов, аппаратные ресурсы расходуются на рабочие буферы и KV-кеш, обслуживающий контекстный массив.

Вывод скрипта содержал отдельные столбцы Context и PromptTokens. Первый параметр задавал лимит окна, второй отображал реальное количество токенов во входящем пакете. В финальном стресс-тесте для режима 32K нагрузка составляла 29 491 токен из 32 768, а для теста 48K — 44 236 из 49 152. В обоих случаях речь шла о заполнении примерно на 90%, что имитировало реальный объемный контекст, а не формальное приветствие при гигантских настройках окна.

Просто скачать подходящий по весу GGUF-файл и инициализировать его в памяти — лишь полдела. Настоящий краш-тест начинается при заполнении окна «под завязку».

Первый победитель: Qwen2.5-Coder-14B Q5

Версия 7B (Q8) была закреплена за быстрыми рутинными задачами. Полноразмерная Qwen3-Coder-30B (Q3) осталась объектом экспериментов. Вариант REAP 25B (Q4) рассматривался как перспективный претендент.

В качестве основного инструмента была утверждена Qwen2.5-Coder-14B в квантовании Q5. Она полностью устраивала меня по габаритам и качеству генерируемого кода. Казалось бы, найден идеальный баланс — можно ставить точку в поисках.

Заодно я провел ревизию локального хранилища.

Модель DeepSeek‑Coder‑V2-Lite демонстрировала нездоровую, аномальную медлительность. Причину выявить не удалось, а поскольку альтернативные варианты работали стабильнее, я просто стер её.

Phi-4 также отправилась в корзину. Это универсальный 14B-релиз с заявленным окном 16K, тогда как мне требовался узкоспециализированный помощник под конкретные архитектурные паттерны. Её характеристики описаны в репозитории Microsoft. Среди уже утвержденных фаворитов сценариев для её применения не нашлось.

Засорить диск гигабайтами GGUF-файлов под всевозможные кванты элементарно. Гораздо сложнее заполучить надежный инструмент, которому не страшно доверить продакшн-окружение.

Подключаем OpenCode — и меняем фаворита

Интеграция выбранной Qwen2.5-Coder-14B в контур OpenCode произошла быстро, но разочарование последовало незамедлительно.

На запрос создать или модифицировать файл модель могла выдать JSON-ответ прямо в чат и благополучно завершить работу. Текст присутствовал на экране. Структура проекта оставалась нетронутой.

До подключения автономного агента критерием служило качество написанного кода. Теперь планка опустилась до сурового бинарного вопроса: создан запрошенный файл в директории проекта или нет?

Агентский сценарий подразумевает, что модель корректно сформирует вызов инструмента, обработает ответ и продолжит цепочку рассуждений. Сгенерировать похожий на вызов JSON недостаточно.

Для успешного function calling должны синхронизироваться модель, шаблонизатор чата, бэкенд-сервер и клиент — об этом подробно сказано в официальной документации llama.cpp. В моей конкретной конфигурации эта связка стабильно работать отказалась.

А вот Qwen3-Coder‑REAP-25B‑A3B влилась в рабочие процессы OpenCode значительно органичнее. Она исполняла системные команды, оперировала файлами и демонстрировала отличный уровень кодинга. При этом в формате Q4 оставался достаточный резерв под 32K-контекст.

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

Второй фаворит засыпался на русском языке

Мои блоки Gutenberg критически зависят от русскоязычных названий полей. Это ключевой элемент интерфейса: контент-менеджер должен видеть интуитивно понятные метки в административной панели.

Я не ставил перед нейросетью задачу сочинять художественную прозу. Требовалось лишь сформировать массив подписей для Carbon Fields. Казалось бы, если архитектура успешно справляется с бэкендом на PHP, проблем с базовым русским лексиконом возникнуть не должно.

Однако именно на этом рубеже REAP потерпела фиаско. Добиться стабильно чистого русского языка в заголовках не удавалось. Я корректировал системные промпты, вводил жесткие ограничения и запреты, но итоговый результат стабильно разочаровывал.

Код генерировался исправно. Инструменты вызывались. А вот на локализации полей мы зашли в тупик.

Ручное переписывание сгенерированных меток после каждого запуска не входило в мои планы.

Пришлось вернуться к полноразмерной Qwen3-Coder-30B‑A3B‑Instruct в квантовании Q3. Она мгновенно распарсила промпт и выдала корректные русскоязычные заголовки.

Оставалось лишь договориться с лимитами видеопамяти.

Q3 бывает очень разным

Полноразмерная модель 30B в первоначальной конфигурации позволяла комфортно работать с контекстом лишь в пределах 24K. Требовалось масштабирование.

Особенно показательны оказались результаты тестов стандартного пресета Q3_K_M:

Настроенный контекст

Генерация

16K

63,8 токена/с

32K

1,57 токена/с

При переходе к 32K скорость обвалилась практически в сорок рублей — простите, в сорок раз. Работать на скорости полтора токена в секунду не представлялось возможным, поэтому начался поиск альтернатив.

Тогда я обратил внимание на альтернативные варианты квантования от команды Unsloth:

Вариант Qwen3-Coder-30B‑A3B‑Instruct

Примерный размер файла

Q3_K_M

14,7 ГБ

UD-Q3_K_XL

13,8 ГБ

UD-IQ3_XXS

12,8 ГБ

Метраж указан для файлов из репозитория Unsloth. Это объем файлов на SSD-накопителе, а не прямые замеры потребления VRAM.

Изначально симпатии были на стороне UD-Q3_K_XL: он обеспечивал экономию памяти относительно Q3_K_M и выглядел менее радикальным компромиссом по сравнению со зловещим суффиксом IQ3_XXS.

Но горький опыт предыдущих бенчмарков отучил меня слепо доверять буквенным индексам в названиях файлов.

Финальный замер: почти одинаковая скорость, разный запас памяти

Ниже приведены метрики двух запусков при сконфигурированном окне в 32 768 токенов и входящем потоке из 29 491 токена:

Метрика

UD‑IQ3_XXS

UD‑Q3_K_XL

VRAM после загрузки, MiB*

14 717

15 605

Пиковая VRAM, MiB*

14 794

15 666

Прирост от загрузки до пика, MiB*

77

61

Свободно на пике, MiB*

1 517

645

Обработка входа, токенов/с

1 863,13

1 718,98

Генерация, токенов/с

42,32

42,04

77 MiB — это дельта между состоянием покоя после старта и пиковой нагрузкой, однако данный показатель не отражает суммарные затраты на контекст: параметр LoadedMB фиксировался уже после инициализации сервера с заданными параметрами. Таблица демонстрирует общую задействованную память GPU с учетом инфраструктурных накладных расходов.

По скорости генерации зафиксирована ничья: 42,32 против 42,04 токена в секунду.

А вот свободный буфер памяти кардинально различался: у конфигурации UD-IQ3_XXS в резерве оставалось на 872 MiB больше — 1 517 против 645 МБ. Более чем двукратное преимущество в свободном пространстве при идентичной производительности.

Реальных отличий в качестве генерации кода на моих задачах обнаружено не было. Отдавать модели UD-Q3_K_XL почти гигабайт драгоценной памяти не имело ни малейшего смысла.

А если всё‑таки попробовать 48K?

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

Вот результаты прогона на 48K:

Метрика

Прогон на 48K

Настроенный контекст

49 152 токена

Фактический вход

44 236 токенов

VRAM после загрузки

15 878 MiB

Пиковая VRAM

15 937 MiB

Прирост от загрузки до пика

59 MiB

Свободно на пике

374 MiB

Обработка входа

1 419,72 токена/с

Генерация

22,68 токена/с

Контекст 48K покорился, но в резерве осталось всего 374 MiB. Скорость генерации упала до 22,68 токена/с, что почти вдвое медленнее показателей UD-IQ3_XXS на 32K.

Попытка замахнуться на 65K закономерно завершилась аварийным завершением процесса по нехватке памяти. Заветные честные 64K остались излишне оптимистичной иллюзией.

Для ежедневных задач я зафиксировал планку на отметке 32K: около 42 токенов в секунду и комфортный запас прочности по VRAM. Штурмовать 48K можно, но оставлять менее 400 мегабайт буфера для стабильной продакшн-среды опрометчиво.

Финальным выбором стала следующая конфигурация:

Qwen3-Coder-30B-A3B-Instruct-UD-IQ3_XXS.gguf

Название звучит как команда терминала. Зато утилита полноценно взаимодействует с инструментами OpenCode, решает задачи по WordPress и фронтенду, а также генерирует грамотные русские подписи, на которых забуксовал REAP. Это полноценный весовой массив без вырезания экспертов, пусть и с агрессивным квантованием. После инициализации 32K-контекста остается 1 517 MiB свободного пространства — примерно 1.48 GiB чистой VRAM.

С чего я начинал бы тесты сегодня

На старте я оценивал ответы чата по умозрительным критериям качества кода, хотя фокус изначально следовало сместить на проверку агентских функций.

Теперь тестирование начиналось бы с простейшего, но комплексного кейса: прочитать файл, внести правки через инструмент, сгенерировать программный код и заполнить русскоязычные метки. Лишь прошедшие этот фильтр кандидаты должны подвергаться замерам производительности и емкости контекста.

Qwen2.5-Coder-14B устраивала по качеству кода, но провалилась в агентском контуре. REAP отлично взаимодействовала с OpenCode, но не справилась с локализацией. Полноразмерная Qwen3-Coder удовлетворила меня и по генерации, и по интеграции в пайплайн автоматизации, хотя и потребовала ювелирного подбора квантования.

Именно поэтому итоговый выбор оказался гораздо сложнее банального принципа «бери модель покрупнее в Q4».

Параллельно с тестированием моделей я постоянно дорабатывал системные промпты: объяснял архитектуру плагина, регламентировал структуру генерируемых блоков. Объем инструкций рос лавинообразно.

В итоге рабочий промпт раздулся до четырехсот строк. Блок скомпилировался без ошибок, но тут же возник закономерный вопрос: где грань между полезным сводом правил и программным кодом, который я почему-то изложил на естественном языке? Модель выбрана, теперь предстоит разобраться с этой методологической дилеммой.

В планах под текущую Qwen3-Coder-30B значится аппаратный апгрейд: рассматривается покупка второй видеокарты на 16 ГБ ради экспериментов с квантованием Q4–Q5 и расширенным контекстом. Насколько успешной окажется двухчиповая конфигурация — тема для отдельного цикла тестов.

В перспективе я планирую аналогичным образом протестировать универсальные языковые модели и vision-решения для работы с графикой. Но это уже совсем другие истории.

Первоначальный план казался банальным: подобрать модель под имеющуюся видеокарту. В итоге я подобрал модель и начал подыскивать к ней вторую видеокарту.

О подобных инженерных экспериментах, разработке под WordPress и буднях разработчика я пишу в Telegram-канале «Вла’д Лебедкин | Stack & Life». Заглядывайте, если любопытно, как локальные нейросети уживаются с инженером в тесных рамках 16 ГБ VRAM.

 

Источник

Поделиться:

Похожие статьи

Поиск по играм, новостям и статьям…

Введите не менее двух символов

Введите не менее двух символов