Перейти к содержанию
Публикация AiManual

Локальный 27B на двух GPU: чему учит ночной марафон по кодингу

Qwen 27B на llama.cpp с tensor-split между RTX 4080 SUPER и RTX A4000 за сутки собрала два инструмента для локального агентского harness. Разбираем правила мара

Коротко

Что будет в материале

  1. 01

    Что именно произошло: 27B на двух GPU и два инструмента за сутки

  2. 02

    Память агента должна жить в файлах, а не в контексте

  3. 03

    Мелкие фазы и машинная проверка: как не утонуть в красных тестах

  4. 04

    Ограничения, которые нельзя игнорировать

Qwen 27B под llama.cpp с tensor-split между RTX 4080 SUPER и RTX A4000 за примерно сутки автономной работы собрала два небольших инструмента: мониторинг LLM-эндпоинта и графики загрузки GPU. Задача выполнялась внутри локального агентского harness с веб-интерфейсом, где модель сама правила файлы, запускала проверки и возвращалась к работе после сжатия контекста. Разбор кейса опубликовал владелец стенда на r/LocalLLaMA: What I learned letting a local 27B run overnight long-horizon coding on my own rig.

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

Роли распределились честно: модель написала большую часть кода, человек по имени Jan задавал правила, принимал или отклонял решения, отсекал плохие пути и отвечал за релиз. Автор называет это парным процессом, а не «AI всё сделал сам». Отдельная деталь: контекст сжался прямо посреди сборки, и работа этого не заметила, потому что состояние лежало в файлах, а не в окне модели.

Что именно произошло: 27B на двух GPU и два инструмента за сутки

Сценарий простой по описанию и непростой по исполнению. Локальная модель получает задачу на длинную дистанцию, работает без постоянного присмотра, а результат к утру должен запускаться и делать что-то полезное. К концу цикла накопилось два инструмента для правой панели (rightbar) агентского harness с веб-интерфейсом. Ни один из них не тянет на продукт: это небольшие утилиты, которые решают конкретную задачу самого разработчика.

Конфигурация: Qwen 27B, llama.cpp и tensor-split между RTX 4080 SUPER и RTX A4000

Модель работала в квантованном виде на llama.cpp, а слои распределялись между двумя картами разного класса: RTX 4080 SUPER и RTX A4000. Режим tensor-split позволяет разложить одну модель по нескольким GPU, когда целиком в память одной карты она не помещается или когда хочется задействовать оба ускорителя. Практический нюанс в том, что карты различаются по вычислительной мощности, поэтому распределение слоёв и параметры запуска приходится подбирать, а не брать наугад.

Точных значений tensor-split, распределения слоёв по картам и скорости генерации в отчёте нет, поэтому здесь они не приводятся. Известно, что модель запускалась в квантованном виде и что квантизацию меняли прямо посреди сборки: с Q6 на Q4. Этот эпизод позже обернулся отдельной проблемой, о которой ниже.

Что было собрано: мониторинг LLM-эндпоинта и графики загрузки GPU

Первый инструмент следит за LLM-эндпоинтом, на котором работает сама модель. Второй рисует графики загрузки GPU. Оба встраиваются в правую панель веб-интерфейса harness, то есть в то место, где разработчик и так смотрит на состояние агента. Смысл понятен: когда модель сутками занимает инференс, полезно видеть, что сервер жив, отвечает и не залип, а карты не ушли в перегрев или простой.

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

Память агента должна жить в файлах, а не в контексте

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

Статус-файл как интерфейс возобновления после сжатия контекста

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

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

Дополнительный контекст о том, как агентские harness ошибаются на уровне состояния и reasoning-блоков, разобран в материале про странные блоки размышлений в Qwen Flash Next.

Мелкие фазы и машинная проверка: как не утонуть в красных тестах

Второе правило касается нарезки работы. Задача делится на фазы, у каждой фазы есть критерии приёмки, и проверка идёт машиной: тесты, typecheck, curl по HTTP-эндпоинту. Человеческий просмотр подключается вторым, после того как автоматика сказала «зелёно». Обратный порядок съедает время и внимание.

Acceptance notes и правило одного слайса

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

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

Тесты против несуществующего контракта: типичная ошибка

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

Второй пример из отчёта: устаревший хост плюс новый клиент дали пустую панель. Проблему закрыли null-guards и регрессионным тестом, который подаёт старую JSON-структуру. Это ровно тот случай, когда машинная проверка ловит несовместимость версий раньше, чем её увидит человек.

Ограничения, которые нельзя игнорировать

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

Нет браузера: как проверять UI без визуального контроля

У модели нет браузера. «Визуальная проверка» на практике сводилась к grep по минифицированному JS-бандлу в поисках нужных маркеров. Это даёт ответ на вопрос «присутствует ли фрагмент в сборке», но ничего не говорит о том, как интерфейс выглядит и ведёт себя. Реальные UI-баги находил человек по скриншотам и ревью, а не модель через «видение». Считать grep полноценной заменой визуальному тестированию нельзя.

Неприкосновенный UI и LLM-сервер: почему агент может встать в очередь сам к себе

Основной интерфейс человека и LLM-сервер были помечены как неприкосновенные. Причина техническая: модель делит слот инференса с сервером, который она же мониторит. Один неосторожный POST к этому серверу, и агент встаёт в очередь сам к себе или зависает без присмотра.

Это иллюстрация того, почему границы исполнения для агента лучше делать жёсткими. Схожий разбор, где агент без прав всё равно изменил запись через downstream-узел, есть в кейсе про runtime-контроль на n8n, DeepSeek и HubSpot.

OOM и смена квантизации: почему заметки устаревают

Загрузка ещё одной крупной модели на те же GPU может привести к OOM и убить текущий процесс. То есть на время длинного марафона стенд фактически занят одной задачей, и эксперименты с другими моделями на тех же картах ставят под удар саму сборку.

Второй риск тоньше. Смена квантизации с Q6 на Q4 посреди сборки сделала недействительными все числа в собственных заметках модели. Формулировка автора: перепроверяй, не доверяй вчерашнему себе. Любые измерения, зафиксированные до смены кванта, надо считать черновиком. Чек-лист того, какие параметры модели вообще стоит фиксировать перед сменой рабочего стека, собран в разборе про оценку новых AI-моделей без шума вокруг релизов.

Человек и модель: честное распределение ролей

Формулировка «AI написал два инструмента» описывает процесс неточно. Модель действительно написала большую часть кода, но контур принятия решений оставался за человеком. Это и есть парный процесс: у модели длинное дыхание и высокая скорость на объёме, у человека правила, приоритеты и ответственность за выпуск.

Кто принимал решения и кто отвечал за релиз

Jan задавал правила игры, принимал или отклонял предложенные варианты, отсекал плохие пути и делал ship call, то есть решение о выпуске. Он же находил реальные баги интерфейса по скриншотам и ревью. Модель в это время держала темп и не теряла контекст задачи, пока та была разложена по файлам.

Источник этой части: тот же отчёт на r/LocalLLaMA. Похожий сюжет с длинными сценариями, где оператор нужен рядом, описан в эксперименте про Qwen 3.8 Flash Next в Baldur's Gate 2.

Практические выводы: что стоит перенять, а что зависит от контекста

Из марафона выжимаются несколько правил, которые можно применить к любой локальной агентской сборке:

  • Память агента хранится в файлах. Статус-файл перезаписывается после каждого шага и служит интерфейсом возобновления для свежего агента без памяти.
  • Работа режется на мелкие фазы с acceptance notes. Проверка сначала машинная: тесты, typecheck, curl. Человеческий просмотр идёт вторым.
  • Нельзя опережать последнюю верификацию больше чем на один слайс.
  • Основной интерфейс человека и LLM-сервер не трогаем. Агент, который делит слот инференса с мониторируемым сервером, иначе встаёт в очередь сам к себе.
  • Ещё одна крупная модель на те же GPU может вызвать OOM и убить процесс. На время марафона стенд занят одной задачей.
  • После смены квантизации все прежние числа и заметки требуют повторной верификации.
  • Человек задаёт правила, принимает решения и отвечает за релиз. Это условие работы схемы, а не вежливая приписка.

Границы применимости тоже стоит держать в голове. Опыт собран на одной конфигурации: Qwen 27B, llama.cpp, RTX 4080 SUPER и RTX A4000, один прогон длительностью около суток и два небольших инструмента. Переносить эти выводы на большие проекты, другие кванты или иную связку GPU можно только с поправкой на собственные проверки. Первое, что имеет смысл сделать на своём стенде, - завести статус-файл и правило одного слайса: они не требуют железа и сразу снижают цену любой ошибки агента.

Подписаться на канал