Блог
[результаты моделей измерены на GPU; пропускная способность платы выведена, не измерена] Одна Artix-7 200T держит слои тернарной модели на 13M параметров в собственной блочной памяти. В нашем парном эксперименте тернарная модель на 100M проходит 0,97% против 1,68% у полной точности на восьми языках, и разрыв — это компиляция, а не корректность. Модель, чаще ошибающаяся, полезна только там, где каждый ответ проверяет компилятор.
Предложение принадлежит владельцу проекта: вместо одной большой модели — сеть узких агентов, по одному на FPGA. Каждый агент получает награду за собственную работу, а открытая прошивка позволяет любому подключить своё устройство. Прежде чем что-то строить, арифметика решает, чем это может быть. Ниже ничего не измерено на плате. Цифры ёмкости — это биты блочной памяти, поделённые на 1,6 бита на тернарный вес. Цифры моделей взяты из обучающих прогонов на GPU.
| Плата | Блочная память | Тернарных весов при 1,6 бита | Слои модели на 13M |
|---|---|---|---|
| ALINX AX7203 (XC7A200T) | 13,46 Мбит | 8,41M | помещаются, 53% |
| Платы на XC7A100T | 4,98 Мбит | 3,11M | не помещаются (142%) |
| Sipeed Tang Mega 138K | 6,27 Мбит | 3,92M | не помещаются (113%) |
XC7A200T держит слои трансформера одной тернарной модели на 13M параметров. Модель на 100M не помещается ни в один из этих чипов. Ей приходится подкачивать веса из DDR3, а DDR3 на AX7203 даёт 3,2 ГБ/с — примерно пятую часть пропускной способности памяти Raspberry Pi 5. На подкачке FPGA не выигрывает.
При 13M параметров и словаре на 32 000 токенов таблица эмбеддингов, которая служит и выходной головой, занимает 8,19M из 12,62M параметров. Тернарным слоям нужно 0,89 МБ. Восьмибитной голове нужно 8,19 МБ, и она читается целиком на каждый сгенерированный токен. Именно это чтение, а не тернарная арифметика, ограничивает один поток примерно 330 токенами в секунду на AX7203. Восемь потоков, которые делят каждое чтение, дают около 2 650. JetBrains выпускает свою локальную модель для кода на 100M со словарём на 16 384 токена. Модели IGLA размером с плату сначала нужны словарь поменьше и четырёхбитная голова, а уже потом более быстрый сумматор.
Разрезать одну большую модель по узлам интернет не позволяет: если разложить модель на сотню плат, каждый токен заплатит сотней сетевых переходов. Задача — дописать одну спеку, починить другую — пересылается один раз и выполняется секунды, так что переход в 50 мс ничего не значит. Branch-Train-Merge и c-BTM обучали экспертов независимо, каждого на своём срезе данных, и направляли каждый документ одному из них. Авторы сообщают, что такие эксперты не уступают плотным моделям, обученным на том же объёме вычислений. Один эксперт на запрос — это одна плата на запрос.
| Модель | HumanEval pass@1 | pass@100 |
|---|---|---|
| Codex-12M | 2,00% | 8,58% |
| Codex-85M | 8,22% | 22,4% |
Это единственные опубликованные результаты по коду для моделей меньше 100M параметров, и они взяты из статьи о Codex. Агент на 12M, отвечающий с одной попытки, прав в 2% случаев. Сеть таких агентов, чью работу никто не проверяет, в основном производит шум. А если дать тому же агенту дешёвого и точного судью и разрешить сто попыток, он решает в 4,3 раза больше задач. При 200 токенах на попытку сто попыток занимают от 8 до 60 секунд на одной плате.
t27c превращает спеку в синтаксическое дерево, типы и сгенерированный код, а спеку, с которой не справляется, отклоняет. В самом корпусе есть собственные тесты и инварианты, а t27c test-report запускает каждый тест отдельно. Сегодня рой пользуется этим судьёй лишь отчасти: его фильтр перед слиянием проверяет структуру, а тесты гоняются по ночам на master, а не до слияния. Лейн-устройство меняет две вещи. Работником становится модель IGLA на плате владельца, а не токен провайдера. И ничто из присланного лейном не засчитывается, пока не пройдут собственные тесты спеки. Он берёт только ту работу, которую может рассудить компилятор: дописать заготовку спеки, чинить спеку, пока t27c её не примет, или перенести функцию в .t27. Рой уже записывает принятый ход как непередаваемое целое число на имя того, кто его сделал, и лейн-устройство зарабатывает так же. Тернарный вывод в целых числах воспроизводится бит в бит, поэтому любой узел может перезапустить выбранную задачу и разрешить спор, сравнив результаты. Спецификация compute-challenge в tri-net уже применяет это правило к отдельным операциям.
Аргументу про судью нужны наши собственные числа, а не только таблица Codex. Мы обучили контролируемую пару: две модели на 100M параметров, одна в полной точности, одна тернарная (b1.58), на одинаковых 10,0 млрд токенов кода, и прогнали обе через MultiPL-E (HumanEval-164, переведённый на восемь языков; n=20 сэмплов, температура 0,2, нативное исполнение).
| Язык | pass@1 FP | pass@1 тернарная | компилируется FP | компилируется тернарная |
|---|---|---|---|---|
| python | 2.35% | 1.25% | 86% | 84% |
| c++ | 1.43% | 0.12% | 59% | 47% |
| go | 1.01% | 1.23% | 45% | 46% |
| java | 2.41% | 2.18% | 62% | 55% |
| javascript | 1.68% | 1.15% | 72% | 75% |
| php | 0.68% | 0.62% | 100% | 100% |
| rust | 1.57% | 0.16% | 38% | 12% |
| typescript | 2.33% | 1.38% | 65% | 49% |
Средний pass@1 по восьми языкам: FP 1.68%, тернарная 1.01%. Полная точность впереди на семи языках из восьми; исключение — go. Самая выразительная колонка не pass@1, а компиляция: тернарная модель гораздо чаще выдаёт несобирающийся код (rust 12% против 38%). Компиляция — первый фильтр судьи, поэтому темп компиляции — естественная ступень лестницы.
Мы также измерили дистилляцию из FP-учителя в тернарного ученика на том же бюджете 2 млрд токенов: дистиллированный ученик хуже на каждом языке (смешанные биты на байт 0,897 против 0,713 у обычной кросс-энтропии) и примерно в семь раз дороже по GPU-времени. Учитель недостаточно впереди, чтобы чему-то научить. Дистилляция от этого учителя отвергнута по измерению.
Поработаем вместе
Я аудирую RTL и строю независимые побитово точные модели, затем провожу результат через синтез и, когда это полезно, проверяю на плате Artix-7. Первый модуль проверки — бесплатно.