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-генерация и автоматическая оценка
Разберём по шагам, что происходит при запуске.
- Клиент открывает диалог из 38 ходов: 29 заданий на способности плюс протокольные ходы.
- Задания собираются seeded-генераторами. Один и тот же seed даёт байт-идентичные промпты на любой машине.
- Каждый ход оценивается кодом по вычисляемому ключу, без человека-судьи и без LLM-as-judge.
- В оценку входят связная проза и проверка удержания правил вывода, заданных в начале диалога, спустя 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_XL | Unsloth Studio | 28.25 |
| IQ2_XS | Unsloth Studio | 27.50 |
| IQ3_S | Strata (llama-server) | 28.00 |
| IQ2_XS | Strata (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-файла.