Алгоритм LUT8

На сегодня нейросеть в обвязке внутри «МК-61s», запущенная на «ПикоКалке», работает со скоростью примерно 0,43 секунды на токен. Постепенно становится быстрее, но ещё на порядок быстрее не станет,  тут уже нужно что-то принципиально менять.

Последний заметный прирост производительности дал алгоритм LUT8, о котором я расскажу чуть ниже, и можно было бы на этом поставить точку, но меня уговорили приобрести ПЛИС.

Нейросеть МК-61s на ПикоКале использует алгоритм LUT8 для ускорения вычислений путём замены умножения поиском в таблице и сложением.
Вот такие примеры сейчас способна правильно решить нейросеть после нескольких дней обучения

Это программируемая логическая интегральная схема, которую можно коммутировать внутри любым образом под конкретную задачу. Я собираюсь подключить её к «ПикоКалу» через разъём расширения, а в будущем разместить внутри корпуса — места там очень много. Не буду пока загадывать, но возможно с таким бустом удастся демонстрировать изумлённой публике быструю нейросеть в коробочке.

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

Для восьми значений мы считаем таблицу сумм из 256 элементов. Если порядок в таблице представить в виде битовой маски, то получится восемь флагов (256 значений от 00000000 до 11111111) — учитывается ли каждая активация в сумме или нет. Причём таблица строится с помощью 255 сложений, на каждом шаге, кроме первого (там всегда ноль), мы используем уже вычисленную маску, отличающуюся от текущей ровно на один бит.

Дальше нам надо посчитать скалярное произведение восьми активаций и восьми весов. Веса разложены хитрым образом. Они у нас тут четырёхбитные, и восемь весов хранятся в четырёх байтах следующим образом: первый байт хранит восемь самых младших бит всех восьми весов, следующий — следующие биты и так далее.

Каждый такой байт — готовая маска, которая показывает, входит ли каждая активация в сумму или нет. Для четырёх байт мы четыре раза ходим в таблицу, умножая каждый раз на множитель — ×1, ×2, ×4, ×8. Для «ПикоКалка» это могут быть три умножения (на один умножать не нужно) или три сдвига, не принципиально, то и другое занимает один такт.

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

Комментарии 2

Алексей Сугоняев № 2
Вам будет легче разобраться с ПЛИС, LUT — там основная функциональная и структурная единица.