- BrainTools - https://www.braintools.ru -
В прошлой статье я показывал, что подпись Schnorr / MuSig2 можно рассматривать не как «чёрный ящик», а как систему наблюдаемых affine-структур: через строгий BIP340 membership bridge, семейства скрытых нонсов, compression/connectivity-метрики и protocol-valid линеаризацию MuSig2 partial signatures Хабр [1]. Это меняет саму оптику: вместо «верим протоколу на слово» мы начинаем разбирать его на проверяемые математические блоки.
Следующий шаг оказался неожиданным, но логичным.
Мы перенесли ту же самую методологию в AI.
Не в смысле «взяли LLM и начали её тюнинговать». А в смысле: взяли квантованную MLX-модель и стали исследовать её внутреннюю математику [2] так же, как раньше исследовали подписи.
Объектом эксперимента стал локальный дистрибутив:
gpt-oss-20b-TurboQuant-MLX-8bit
Мы не меняли архитектуру модели, не переписывали attention и не занимались классическим fine-tuning. Мы сделали другое:
научились читать .safetensors как точную структуру;
построили детерминированный calibration cache;
начали снимать реальные BF16-активации с конкретных слоёв;
свели локальную коррекцию весов к ограниченной задаче целочисленной оптимизации;
сделали безопасную запись patch обратно в модель;
и добавили smoke-check, который проверяет, совпадает ли offline-математика с реальным runtime MLX.
Главный результат этой статьи звучит так:
мы не «улучшили модель магией», а построили exact AI-forensics pipeline, в котором квантованный слой перестаёт быть чёрным ящиком и становится наблюдаемым, проверяемым и локально корректируемым объектом.
В криптографии всё началось с очень простой идеи: если объект допускает строгую нормализацию, то его можно не только использовать, но и исследовать как геометрию скрытых параметров.
Для подписи Schnorr базовое соотношение имеет вид:
где:
— приватный ключ,
— nonce,
— challenge,
— скаляр подписи.
Это уже не «магия подписи», а линейная структура.
В AI мы сделали тот же самый ход.
Мы перестали смотреть на модель как на функцию «промпт текст» и спустились ниже — к тому месту, где живёт её внутренняя линейная алгебра:
квантованные коды,
scale/bias,
входные активации,
эталонные выходы линейного слоя.
То есть вопрос поменялся.
Не:
«Модель отвечает хорошо или плохо?»
А:
«Можно ли представить конкретный квантованный слой как точный affine-объект, наблюдать его поведение [3] и локально исправлять без разрушения всей модели?»
Вот это и есть AI-forensics.
Базой стал MLX-дистрибутив:
gpt-oss-20b-TurboQuant-MLX-8bit
Нас интересовали два конкретных слоя первого блока:
model.layers.0.self_attn.q_proj.weight
model.layers.0.mlp.router.weight
Почему именно они?
Потому что это хороший тест на два разных сценария:
слой, который может оказаться слишком «жёстким» для осмысленного patch без внешнего эталона;
слой, который, наоборот, допускает локальную корректировку.
Именно на этом контрасте и проявляется ценность метода.
Важно сразу зафиксировать: мы не меняли архитектуру модели.
Мы изменили не «мозг модели», а способ работы с ним.
.safetensors как opaque-контейнер;
квантованные веса как «что-то внутри рантайма»;
оценка модели только по финальному текстовому выходу.
точный доступ к сырому весовому представлению;
выделение кодов квантования, scale и bias;
runtime-захват входа и выхода конкретного линейного слоя;
локальная integer-оптимизация кодов;
безопасная обратная запись патча;
обязательная проверка, что математика offline не расходится с реальным исполнением.
Проще говоря:
мы превратили квантованный слой из «непрозрачной детали модели» в объект инженерной диагностики.
Первое, что пришлось сделать, — написать мост к MLX-квантованию.
Он умеет:
находить нужный тензор в модели;
читать его raw-представление;
извлекать квантованные коды;
читать BF16-масштабы и смещения;
при необходимости записывать изменённые коды обратно.
Это важный момент.
Пока веса модели воспринимаются как «готовый blob», никакой точной работы с ними не получится. Нужно сначала развернуть этот blob в нормальную математическую структуру.
Следующий шаг — calibration cache.
Мы заранее собрали стабильный набор примеров:
|
Параметр |
Значение |
|---|---|
|
Всего примеров |
768 |
|
Split |
512 |
|
Split |
256 |
|
Размер шарда |
128 |
|
Политика захвата |
|
|
Тип активаций |
|
Зачем это нужно?
Чтобы каждый следующий эксперимент был воспроизводимым. Не «кажется, стало лучше», а:
вот тот же набор,
вот тот же слой,
вот тот же вход,
вот тот же эталонный выход,
вот та же метрика ошибки [4].
Без этого всё быстро превращается в storytelling.
После этого мы добавили runtime-capture для конкретных линейных слоёв.
Для каждого выбранного примера сохранялись:
pre_linear_input
linear_output_reference
Причём именно для последнего токена.
Это очень важно.
Мы не симулируем слой отдельно от модели, а снимаем его с живого MLX-runtime. То есть дальше работаем уже не с абстрактной линейной алгеброй, а с данными, которые модель реально порождает сама.
Теперь можно записать слой в виде нормальной формулы.
Пусть строка весов разбита на блоки длины . Для строки
и блока
обозначим:
— вектор квантованных кодов длины
;
— scale;
— bias.
Тогда деквантованный блок весов задаётся как
где — вектор из единиц длины
.
Если входной вектор для примера разбит по тем же блокам:
то выход по координате равен
или, после подстановки деквантования,
Вот здесь и появляется главный мост.
Квантованный слой перестаёт быть «набором непонятных байтов» и становится affine-системой над дискретными кодами.
Для выбранного блока мы ищем новый кодовый вектор , который лучше воспроизводит reference-output, но не уезжает слишком далеко от исходного.
Оптимизационная задача имеет вид:
при ограничениях
и
Здесь:
— исходные коды блока;
— коэффициент регуляризации;
— максимально допустимое изменение одного кода.
В наших экспериментах для router-слоя использовались:
|
Параметр |
Значение |
|---|---|
|
Размер блока |
64 |
|
Ridge lambda |
16 |
|
Max code delta abs |
8 |
То есть patch изначально делался консервативным:
не переписывать слой целиком;
не менять десятки тысяч параметров без контроля;
не уходить далеко от исходной структуры;
чинить локально и в ограниченном окне.
Это ключевая граница метода.
Если в качестве цели мы используем текущий же квантованный слой, то любой exact-поиск патча даёт тривиальный оптимум: ничего не менять.
Пусть исходное состояние слоя задаётся тройкой:
и пусть функционал ошибки имеет вид
где:
для любой допустимой конфигурации;
;
ноль достигается только в точке .
Тогда минимум уже достигнут в исходном состоянии, потому что меньше нуля уйти нельзя.
Следовательно, если мы пытаемся «улучшить» слой, используя как цель сам этот слой, то лучшая стратегия — ничего не менять.
Чтобы non-identity patch был математически осмысленным, нужен внешний эталон:
реальные runtime-активации;
reference-output;
отдельный holdout.
Именно поэтому в нашей системе pipeline строится вокруг capture и holdout, а не вокруг самосравнения модели с самой собой.
Первым тестовым кандидатом был слой
model.layers.0.self_attn.q_proj.weight
Мы прогнали по нему exact-аудит.
|
Метрика |
Значение |
|---|---|
|
Total rows |
4096 |
|
Decoded width |
2880 |
|
Blocks per row |
45 |
|
Total blocks |
184320 |
|
Unique rows |
4096 |
|
Repeated rows |
0 |
|
Unique blocks |
184320 |
|
Repeated blocks |
0 |
|
Exact equal adjacent block pairs |
0 |
Это очень показательная таблица.
Слой оказался структурно «жёстким»:
без тривиальных повторов;
без клонов блоков;
без дешёвых exact-симметрий;
без готовой компрессии, которую можно было бы легко использовать для patch.
В результате финальный вывод по q_proj оказался жёстким, но правильным:
|
Итог по |
Значение |
|---|---|
|
Self-target identity optimum |
|
|
External reference required |
|
|
Non-identity patch justified |
|
|
Exact patch candidates found |
|
И это хороший результат.
Потому что система не «придумала улучшение», а доказала границу применимости метода.
Совсем другая история получилась для слоя
model.layers.0.mlp.router.weight
Для него был построен полный pipeline:
calibration cache,
runtime activation capture,
blockwise LWO-оптимизация,
holdout validation,
safe patch,
smoke-check.
|
Параметр |
Значение |
|---|---|
|
Модель |
|
|
Слой |
|
|
Train shard |
|
|
Holdout shard |
|
|
Train sample count |
4 |
|
Holdout sample count |
4 |
|
Block size |
64 |
|
Ridge lambda |
16 |
|
Max code delta abs |
8 |
На train-shard улучшение получилось почти идеальным.
|
Метрика |
Значение |
|---|---|
|
Baseline MSE |
|
|
Patched MSE |
|
|
MSE gain |
|
|
Changed blocks |
571 |
|
Changed codes total |
9067 |
На этом месте легко было бы сказать: «готово, мы вылечили слой».
Но это был бы неправильный вывод.
Train почти всегда можно улучшить. Главный вопрос — переносится ли эффект дальше.
Вот здесь начинается самое интересное.
|
Метрика |
Значение |
|---|---|
|
Baseline MSE |
|
|
Patched MSE |
|
|
MSE gain |
|
|
Transfer ratio |
|
|
Holdout improves |
|
|
Overfit suspected |
|
То есть improvement почти полностью перенёсся на отдельный shard.
Можно записать это совсем кратко:
Это уже не похоже на случайное попадание или подгонку под четыре точки. Это означает, что система действительно нашла локальную корректировку, которая несёт устойчивый эффект.
После вычисления патча его нужно было ещё записать обратно в модель.
Для этого был реализован safe patch workflow:
сохранить backup;
упаковать новые коды в U32;
записать их в .safetensors;
перечитать и проверить exact match.
|
Метрика |
Значение |
|---|---|
|
Changed blocks |
571 |
|
Changed codes total |
9067 |
|
Raw |
3335 |
|
Write applied |
|
|
Readback exact match |
|
То есть система умеет не только посчитать патч, но и корректно внедрить его в реальный модельный файл.
Именно здесь начинается инженерия, а не просто исследование на бумаге.
После записи патча был выполнен runtime smoke-check.
И вот здесь система показала, зачем вообще нужна строгая проверка.
|
Метрика |
Значение |
|---|---|
|
Input exact rows |
|
|
Output exact rows |
|
|
Input runtime vs reference MSE |
|
|
Output runtime vs reference MSE |
|
|
Output changed raw BF16 values |
|
|
Метрика |
Значение |
|---|---|
|
Input exact rows |
|
|
Output exact rows |
|
|
Input runtime vs reference MSE |
|
|
Output runtime vs reference MSE |
|
|
Output changed raw BF16 values |
|
Что это значит?
Очень просто:
вход в слой воспроизводится идеально;
а вот реальный runtime-output после записи не совпал с offline-reference, несмотря на сильный результат в solver-отчётах.
На первый взгляд это выглядит как плохая новость. На самом деле — наоборот.
Это означает, что система умеет обнаруживать расхождение между:
offline-моделью деквантования,
и реальной семантикой исполнения в MLX runtime.
То есть она не просто «генерирует патчи», а умеет поймать момент, когда красивая математика перестаёт совпадать с реальностью исполнения.
Это очень важная способность.
Чтобы не перегибать с формулировками, зафиксирую аккуратно.
Мы не меняли:
архитектуру модели;
число слоёв;
механизм attention;
tokenizer;
high-level inference pipeline.
Мы изменили логику [5] работы с её внутренними квантованными слоями:
добавили точное чтение кодов;
добавили разбор по блокам;
добавили BF16 activation capture;
добавили constrained integer patching;
добавили safe write-back;
добавили post-patch reality check.
То есть фактически мы превратили MLX-дистрибутив из «готовой коробки» в систему, которую можно инструментировать, диагностировать и хирургически править.
Если собрать всё вместе, получается уже довольно сильный capability map.
Система умеет разбирать внутреннее представление веса на уровне:
U32-кодов,
uint8-декодирования,
BF16 scale/bias,
block geometry.
Она умеет снимать реальные входы и выходы линейного слоя на настоящем MLX-runtime, а не на симуляторе.
Она умеет искать ограниченный patch для конкретных блоков без разрушения всего слоя.
Она умеет записывать корректировку обратно в .safetensors с контролем readback.
Она умеет отличать реальное улучшение от переобучения на крошечном calibration-shard.
Она умеет обнаружить, что offline-патч красив, но среда исполнения интерпретирует его иначе.
И вот это, пожалуй, одна из самых сильных возможностей системы на текущем этапе.
Чтобы статья оставалась инженерной, а не рекламной, зафиксирую и ограничения.
Мы пока не утверждаем, что:
любой слой можно исправлять одинаково успешно;
q_proj уже улучшен — нет, там система честно упёрлась в границу метода;
runtime-семантика MLX уже полностью раскодирована;
AI-ветка уже усиливает криптоаналитический recovery end-to-end;
вся lattice-ветка для AI уже production-ready.
Но мы вполне можем утверждать другое:
построена рабочая exact AI-forensics инфраструктура для квантованной MLX-модели.
И это уже немало.
Обычный fine-tuning отвечает на вопрос:
как сделать модель в среднем лучше на задаче?
Наш подход отвечает на другой вопрос:
что делает конкретный квантованный слой, как он устроен в exact-представлении, и можно ли изменить его локально, не теряя контроля над каждым шагом?
Это другой уровень доступа.
Не «подкрутить поведение [6] модели», а разобрать её внутреннюю линейную механику до уровня кодов квантования.
Именно поэтому эта AI-ветка выросла у нас не из MLOps, а из криптоанализа.
Потому что и там, и здесь задача одна и та же:
перестать верить чёрному ящику и заменить веру наблюдаемой структурой.
Если сформулировать совсем коротко, то произошло следующее.
Мы взяли gpt-oss-20b-TurboQuant-MLX-8bit и добавили к нему не «ещё один AI-скрипт», а целую exact-инфраструктуру:
bridge к .safetensors,
calibration cache,
BF16 activation capture,
constrained blockwise optimization,
safe patch,
holdout validation,
runtime smoke-check.
Подтверждённый итог на текущем этапе двойной:
router-слой действительно допускает осмысленную локальную коррекцию, причём эффект переносится на holdout;
offline-модель патча и реальная MLX runtime-семантика ещё не совпадают полностью, и система это умеет честно обнаруживать.
А значит, сегодня наша система уже умеет делать не только криптографическую forensics-диагностику, но и то же самое внутри квантованной нейросети:
выделять слой, формализовать его как affine-объект, локально исправлять и проверять, не обманывает ли нас сама среда исполнения.
Именно в этом месте AI перестаёт быть «магией модели» и становится объектом точной инженерной диагностики.
Эта работа не про «волшебное улучшение LLM». Она про другое: как перенести дисциплину криптоанализа в AI и научиться работать с квантованной моделью так же строго, как мы работаем с протоколами подписи.
То есть не «верить, что внутри что-то происходит», а видеть, измерять, патчить и проверять.
И это, похоже, только начало.
Автор: tqec
Источник [7]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/29162
URLs in this post:
[1] Хабр: https://habr.com/ru/articles/1025236/
[2] математику: http://www.braintools.ru/article/7620
[3] поведение: http://www.braintools.ru/article/9372
[4] ошибки: http://www.braintools.ru/article/4192
[5] логику: http://www.braintools.ru/article/7640
[6] поведение: http://www.braintools.ru/article/5593
[7] Источник: https://habr.com/ru/articles/1026340/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1026340
Нажмите здесь для печати.