Короче. Я обещал показать, ЧТО Я ВООБЩЕ ТАМ СОБРАЛ 😃
Сразу: это не «ещё один трансформер». Я специально пытался уйти от внимания как основной идеи.
В обычном attention модель каждый новый токен сравнивает с прошлой историей через ключи и значения. И чем длиннее история — тем больше всего этого добра надо хранить. Отсюда KV-cache и вся эта прекрасная инженерная жизнь вокруг него.
У меня логика другая.
История не хранится как список. Она постоянно сворачивается в состояние фиксированного размера.Причём не в одно.
А в ЧЕТЫРЕ.Первая память — быстрая. Реагирует почти мгновенно.
Вторая — медленнее.
Третья — вязкая.
Четвёртая — почти постоянная.
То есть текст для модели существует сразу в нескольких временных масштабах.
Не «позиция 15237».
А скорее:
что произошло только что / недавно / давно / очень давно.И дальше начинается самое интересное. Вместо обычного RoPE, где вращаются query/key в зависимости от позиции, у меня
вращается сама память. У каждого временного слоя своя скорость вращения. Получается что-то вроде часов, которые идут с разной скоростью, но смотрят на один и тот же поток текста.
Новое состояние записывается примерно так:старая память → повернуть → чуть затушить → добавить новую информацию.И всё это не растёт вместе с контекстом.
Хоть 1 000 токенов прошло, хоть 100 000 — размер recurrent-state тот же.
Дальше — адресация.Сначала я игрался с проективной геометрией: представлял признаки не просто векторами, а направлениями и углами между ними.
Часть вариантов, кстати, оказалась хуже обычных положительных признаков 😃
Но из этих экспериментов вылезла более интересная штука:
signed cosine + вращаемая память.
То есть теперь направление важно вместе со знаком, а временная фаза встроена прямо в динамику состояния.
И вот именно это неожиданно начало работать.
Дальше был инженерный ад. Сначала я считал рекуррентную динамику через FFT. Математически красиво. Инженерно — куча промежуточных комплексных массивов, FFT, IFFT, память летит в потолок.
Я выкинул это из inference и написал Triton kernel. Теперь схема буквально такая:
токен → Q/K/V → повернуть recurrent-state → записать → тут же считать cosine-read.В одном GPU kernel.
Без KV-cache.
Потом пришлось вручную писать backward.И оказалось, что назад по затухающей системе просто так идти нельзя — численная ошибка взрывается.
Решение оказалось смешным: checkpoint состояния каждые 8 токенов.
После этого градиенты custom Triton backward совпали с PyTorch до примерно
10⁻⁹.
То есть это уже не «ну вроде обучается».
Это реально та же математика.
Что получилось в тестах?На WikiText-103
я дал обычному attention ФОРУ.Та же ширина. Та же глубина. Такой же FFN.Из-за этого attention получился вообще
13.1 млн параметров, а моя модель —
8.0 млн.
То есть у attention примерно на
64% больше параметров.
И всё равно:
512 токенов:
1.96 NLL против 2.35
2048 токенов:
2.03 против 2.39
8192 токенов:
2.01 против 2.40
32768 токенов:
2.03 против 2.45
Но самое странное даже не это.
Модель обучалась на длине 512. А на
32768 практически не потеряла качество. Вот это меня уже реально заинтересовало. Потому что я изначально хотел не просто «сделать ещё одну модель».
Я хотел проверить идею:
можно ли заменить историю токенов не памятью о каждом токене, а несколькими постоянно вращающимися временными состояниями фиксированного размера?
Пока ответ выглядит как:похоже, да.Но пока без фанфар.Сейчас следующий нормальный тест:
BPE, 20 миллионов обучающих токенов, контекст 1024, потом проверка на 4k / 16k / 65k.Если оно переживёт и это...
...тогда уже будет совсем интересно 😃
🦆🦆🦆
Поддержать канал ₽ / $ / ₿