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

Это программируемая логическая интегральная схема, которую можно коммутировать внутри любым образом под конкретную задачу. Я собираюсь подключить её к «ПикоКалу» через разъём расширения, а в будущем разместить внутри корпуса — места там очень много. Не буду пока загадывать, но возможно с таким бустом удастся демонстрировать изумлённой публике быструю нейросеть в коробочке.
Теперь про LUT8 — идея в том, чтобы заменить умножение поиском по таблице и сложением для восьми активаций сразу.
Для восьми значений мы считаем таблицу сумм из 256 элементов. Если порядок в таблице представить в виде битовой маски, то получится восемь флагов (256 значений от 00000000 до 11111111) — учитывается ли каждая активация в сумме или нет. Причём таблица строится с помощью 255 сложений, на каждом шаге, кроме первого (там всегда ноль), мы используем уже вычисленную маску, отличающуюся от текущей ровно на один бит.
Дальше нам надо посчитать скалярное произведение восьми активаций и восьми весов. Веса разложены хитрым образом. Они у нас тут четырёхбитные, и восемь весов хранятся в четырёх байтах следующим образом: первый байт хранит восемь самых младших бит всех восьми весов, следующий — следующие биты и так далее.
Каждый такой байт — готовая маска, которая показывает, входит ли каждая активация в сумму или нет. Для четырёх байт мы четыре раза ходим в таблицу, умножая каждый раз на множитель — ×1, ×2, ×4, ×8. Для «ПикоКалка» это могут быть три умножения (на один умножать не нужно) или три сдвига, не принципиально, то и другое занимает один такт.
В итоге, для восьми элементов в LUT8 у нас нужно будет прочитать четыре маски, четыре раза обратиться к таблице, выполнить три умножения или сдвига и три сложения.
Комментарии 2