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

llm-psicotest: как проверить, что квантование не сломало поведение локальной LLM

llm-psicotest прогоняет один и тот же 38-ходовой диалог против любого OpenAI-совместимого эндпоинта и оценивает ответы кодом: разбираем запуск через CLI с seed,

Коротко

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

  1. 01

    Что такое llm-psicotest и какую проблему он решает

  2. 02

    Как устроен тест: 38 ходов, seed-генерация и автоматическая оценка

  3. 03

    Как воспроизвести прогон через CLI

  4. 04

    Что показала калибровка автора: квантования и два стека

llm-psicotest - открытый инструмент на Python, который прогоняет один и тот же 38-ходовой диалог против любого OpenAI-совместимого эндпоинта: 29 заданий на способности плюс протокольные ходы. Промпты генерируются по seed, поэтому один seed даёт байт-идентичные входы на любой машине, а каждый ход оценивается кодом по вычисляемому ключу. Автор проекта выложил описание и калибровку в сообществе LocalLLaMA (пост автора с описанием и калибровкой).

Практическая задача у инструмента одна: проверить, не сломало ли квантование поведение локальной LLM. Вы запускаете диалог на IQ2_XS, потом на IQ3_S, сравниваете результаты из 29 и видите, деградация это или шум. Инструмент требует Python 3.11+, использует только stdlib и распространяется под лицензией MIT, так что установка не тянет за собой десяток зависимостей.

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

Что такое llm-psicotest и какую проблему он решает

Когда вы меняете квантование GGUF-файла, стандартные бенчмарки часто показывают почти одинаковые цифры. Модель как будто отвечает так же уверенно, потери в два-три процента легко списать на шум. А потом выясняется, что она перестала держать формат ответа или забывает инструкцию, данную двадцать сообщений назад. Именно эту просадку llm-psicotest и пытается поймать.

Механика простая: 38 ходов в одном диалоге, 29 из них - задания на способности, остальные - протокольные ходы. Все входы детерминированы через seed, весь скоринг автоматический. Получается воспроизводимый поведенческий тест, который можно прогнать до и после смены кванта и сравнить два числа.

Чем это отличается от code-scored бенчмарков на multiple choice

Большинство code-scored бенчмарков обходят и связную прозу, и долгосрочное следование правилам за счёт multiple choice. Модель выбирает букву из четырёх вариантов, скрипт сверяет её с ключом, метрика считается чисто. Проблема в том, что такой формат почти не нагружает то, что квантование ломает первым делом: умение построить связный текст по ограничениям и удержать правила вывода, заданные в начале разговора.

llm-psicotest оценивает ответы кодом, но без вариантов ответа. В диалог входят задания на связную прозу и проверка того, держатся ли правила вывода, заданные в начале, спустя 20 ходов. Модель вроде бы отвечает по делу, но перестаёт держать формат и длинную инструкцию - и multiple choice этого не покажет, потому что там формат задан самим тестом.

Кому инструмент реально нужен

Сценарии, где тест окупается:

  • выбор GGUF-файла одной модели: IQ2_XS экономит память, но стоит проверить, не рассыпается ли поведение;
  • проверка после смены сервера или настроек инференса;
  • проверка после обновления llama-server или Unsloth Studio.

Не нужен тем, кто не запускает локальные модели и не работает с OpenAI-совместимыми эндпоинтами. Инструмент ставится без тяжёлых зависимостей, и это снижает порог входа: Python 3.11+, stdlib, MIT.

Если вы только выбираете, на чём гонять локальные модели, пригодятся разборы смежных тестов: сравнение IQ3_XXS и Bonsai Ternary PQ2 на 16 ГБ VRAM и прогон трёх квантов Qwen 3.8 на задачах AtCoder.

Как устроен тест: 38 ходов, seed-генерация и автоматическая оценка

Разберём по шагам, что происходит при запуске.

  1. Клиент открывает диалог из 38 ходов: 29 заданий на способности плюс протокольные ходы.
  2. Задания собираются seeded-генераторами. Один и тот же seed даёт байт-идентичные промпты на любой машине.
  3. Каждый ход оценивается кодом по вычисляемому ключу, без человека-судьи и без LLM-as-judge.
  4. В оценку входят связная проза и проверка удержания правил вывода, заданных в начале диалога, спустя 20 ходов.

Байт-идентичные входы - ключ ко всей конструкции. При сравнении квантований меняется только модель и стек, промпты остаются теми же. Иначе вы сравнивали бы не кванты, а разные вопросы.

Почему seed важнее, чем кажется

Без фиксированного seed сравнение квантований превращается в сравнение разных вопросов: сгенерированные задания отличаются, и разница в баллах ничего не говорит о модели. Seed убирает эту переменную.

Практический вывод: при сравнении вариантов квантования прогоняйте несколько seed и смотрите на разброс. В калибровке автора их четыре - и именно этого хватило, чтобы увидеть устойчивое расхождение между IQ3_S и IQ2_XS.

Что именно проверяет диалог: способности и протокол

Диалог делится на две части. 29 заданий на способности проверяют, что модель умеет, а протокольные ходы следят за тем, как она ведёт себя в разговоре. Отдельно стоит выделить две проверки, которые плохо ловятся multiple choice:

  • связная проза - нужно построить текст по заданным ограничениям, а не выбрать вариант;
  • долгосрочное следование правилам - правила заданы в начале, проверяются спустя 20 ходов.

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

Как воспроизвести прогон через CLI

Запуск укладывается в две команды. API-ключ задаётся через переменную окружения, дальше идёт сам прогон:

export PSICOTEST_API_KEY=***
psicotest run --base-url http://127.0.0.1:8080/v1 --model my-model --seed 7

Три параметра определяют всё остальное. --base-url - адрес OpenAI-совместимого эндпоинта: llama-server, Unsloth Studio или любой другой сервер с совместимым API. --model - имя модели на этом сервере, ровно в том виде, в каком его отдаёт сам эндпоинт. --seed - фиксирует генерацию промптов.

Флагов сверх этих трёх в описании проекта не приводится, так что не стоит досочинять их по аналогии с другими инструментами.

Что подготовить до первого запуска

Чек-лист, который экономит полчаса отладки:

  • эндпоинт поднят и отвечает по base-url;
  • имя модели совпадает с тем, что реально отдаёт сервер;
  • PSICOTEST_API_KEY выставлен в окружении;
  • seed выбран и записан;
  • параметры сервера зафиксированы: версия, размер контекста, тип KV-кэша, бюджет вывода.

Последний пункт критичен. Без него результат некуда будет вписать для сравнения - два одинаковых балла на разных настройках могут означать совершенно разное.

Как читать результат из 29

На выходе - балл из 29 по одному диалогу на один seed. Сравнивать имеет смысл только прогоны с одинаковым seed и одинаковыми настройками сервера. Если один квант дал 28, а другой 26 на разных seed, это ещё не вывод.

Смотрите на разброс по нескольким seed. Одно число почти ничего не говорит: важно, повторяется ли отрыв из прогона в прогон. И помните, что диалог один.

Что показала калибровка автора: квантования и два стека

Конфигурация калибровки: одна базовая модель Qwen3.8-Flash-Next GGUF, четыре варианта квантования и четыре seed. Модель одна - это важно для интерпретации.

КвантованиеСтекСредний балл из 29
UD-Q3_K_XLUnsloth Studio28.25
IQ2_XSUnsloth Studio27.50
IQ3_SStrata (llama-server)28.00
IQ2_XSStrata (llama-server)25.50

Разброс по квантам внутри одного стека выглядит скромно: 28.25 против 27.50 на Unsloth Studio. А вот между стеками картина интереснее.

IQ3_S против IQ2_XS: почему разница на всех seed важнее среднего

На Strata IQ3_S обошёл IQ2_XS на всех четырёх seed: 29, 28, 28 и 27 из 29 против 25, 26, 26 и 25 при одном сервере и настройках. Средние 28.00 против 25.50 удобны для сводки, но именно согласованность по seed делает вывод защищаемым.

Когда один вариант проигрывает другому в каждом прогоне, это устойчивый сигнал. Когда отрыв есть только на одном seed, а на остальных результаты сравнялись, вы смотрите на шум. Разница в 2,5 балла, которая держится на четырёх прогонах подряд, говорит о деградации поведения, а не о случайности.

Один и тот же квант на разных стеках даёт разные баллы

IQ2_XS дал среднее 27.50 из 29 на Unsloth Studio и 25.50 из 29 на Strata. Два балла разницы на одном и том же файле квантования.

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

Похожая логика работает в других практических тестах: например, в эксперименте с logit bias в llama.cpp на пяти квантизациях Qwen3.5-4B, где эффект проверяли отдельно на каждом варианте, а не по одному замеру.

Как добавить свой результат в RESULTS.md

RESULTS.md принимает строки от сообщества. Минимальный набор полей для строки:

  • модель и вариант квантования;
  • seed;
  • балл из 29;
  • версия сервера;
  • размер контекста;
  • тип KV-кэша;
  • бюджет вывода.

Зачем каждое поле. Без версии сервера и настроек два одинаковых балла могут означать разное: поведение llama-server меняется от релиза к релизу. Без размера контекста и типа KV-кэша прогон не воспроизвести - на урезанном контексте длинный диалог просто обрежется, и балл упадёт по причине, не связанной с квантованием. Бюджет вывода определяет, успеет ли модель договорить: при жёстком лимите часть заданий провалится из-за обрыва, а не из-за потери способностей.

Четыре технических поля - версия сервера, размер контекста, тип KV-кэша и бюджет вывода - превращают запись из «у меня 26 из 29» в воспроизводимый результат.

Ограничения: что llm-psicotest не покажет

Главное ограничение: результаты зависят от сервера и настроек. Одни и те же квантования дали разные результаты на Unsloth Studio и Strata, и это не баг, а свойство метода.

Второе: один диалог не заменяет полноценную оценку модели. 29 заданий в одном сценарии не покрывают кодинг, математику, длинный контекст и работу с инструментами. Если вам нужно сравнить модели по доменам, смотрите на независимый прогон Bonsai 2 на композитном наборе или на тест моделей на кодинге, pandas и локальном RAG.

Третье: калибровка автора ограничена одной базовой моделью Qwen3.8-Flash-Next GGUF, четырьмя вариантами квантования и четырьмя seed. Это не универсальный рейтинг квантований. Вывод «IQ3_S лучше IQ2_XS» относится к этой модели на этих стеках, а не к любой LLM.

Четвёртое: инструмент не даёт разбивки по типам заданий в публичном описании, поэтому по одному баллу нельзя сказать, что именно просело - формат, логика или длинная инструкция.

Итог: когда запускать llm-psicotest

Запускайте, когда меняете квантование, сервер или настройки инференса и хотите убедиться, что поведение не просело. Порядок действий: зафиксировать seed, прогнать несколько seed на каждом варианте, сравнить разброс, а не одно число, и внести строку в RESULTS.md с версией сервера, размером контекста, типом KV-кэша и бюджетом вывода.

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

Сам инструмент лежит в открытом доступе, требует Python 3.11+, обходится стандартной библиотекой и распространяется под MIT. Порог входа низкий, поэтому первый прогон против своего эндпоинта стоит сделать при следующей смене GGUF-файла.

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