Аналоговые вычисления для искусственного интеллекта: как делать MAC-операцию при помощи закона Ома
Присутствие нейронных сетей в нашей жизни становится все более распространенным, от голосовых ассистентов до узкоспециальных САПР. Несмотря на то, что область применения нейросетей расширяется, их потенциал все еще сильно ограничен удручающей энергоэффективностью существующих хардверных решений. Специализированные AI-чипы выходят в производство, как горячие пирожки, а ожидаемый рост энергопотребления нагруженных AI датацентров уже скоро позволит им отобрать у атомных электростанций звание главного врага всех экоактивистов. Разумеется, над решением проблемы энергопотребления AI или, будем честны, над решением проблемы энергопотребления цифрового умножения работает огромное количество исследователей по всему миру, на всех возможных уровнях абстракции, от математиков-фундаментальщиков до разработчиков передовых литографов.
А дальше, как это регулярно случается, внезапно оказалось, что все новое — это хорошо забытое старое, и спасение может заключаться в том, чтобы откопать давно забытые за бесперпективностью аналоговые вычисления и посмотреть на них свежим вглядом в свете новых задач.
Как вы себе представляете аналоговый вычислитель
Как аналоговый AI-вычислитель выглядит на самом деле. На картинке — аналоговый чип для решения некоторых простых задач распознавания изображений.
— Нейронные сети «программируются» при помощи варьирования «весов» соединений между нейронами (синапсов). Сигнал, подаваемый на вход системы, проходя через синапс, умножается на его «вес». Как правило, к одному нейрону подходят несколько синапсов, значения их выходов суммируются, и к сумме применяется некоторая нелинейная функция активации. Таким образом, подавляющее большинство вычислительных операций нейронной сети сводится к умножению с накоплением (MAC). Эффективность выполнения MAC-операции является одним из критичных параметров для определения производительности нейронных процессоров.
Структурная диаграмма нейрона, выполняющего умножение с накоплением и активацию
Фундаментально нейронные сети, как и многие другие виды вычислений, могут быть реализованы как на цифровых, так и на аналоговых платформах, но на практике цифровые вычисления уже много десятилетий доминируют, фактически сделав само слово «аналоговый» синонимом чего-то древнего и дремучего. Не в последнюю очередь — потому, что КМОП-технология очень хорошо приспособлена для реализации цифровых схем, а практически неукоснительное выполнение закона Мура на протяжении многих десятилетий сделало ее практически монопольной микроэлектронной технологией. Поэтому практически что угодно делается на КМОП: процессоры, память, драйверы электродвигателей, микросхемы стеклоподъемников, матрицы фотоаппаратов — список такой длинный, что проще перечислить исключения, требующие каких-то выдающихся параметров и одновременно не требующие высокой степени интеграции. А там, где уже есть КМОП, все рано или поздно переходит в цифровой вид, будь то управление обратной связью DC/DC-преобразователя, Software-Defined Radio или цифровой микрофон — практически всегда выгоднее всего поставлять на любой источник аналогового сигнала АЦП, к любому актюатору — драйвер, а между ними все делать в цифровом виде.
Нейросетки, казалось бы, идеально подходят как пример задачи, которую удобно решать в цифровом виде — они огромные, вычислительно сложные и очень сильно выигрывают от миниатюризации и повышения энергоэффективности «железа» выполняющего вычисления. Проблема состоит в том, что цифровое умножение, являющееся ключевой операцией в машинном обучении, крайне ресурсозатратно. Простой 4-битный КМОП-умножитель требует несколько сотен транзисторов. 8-битная схема требует несколько тысяч. Про то, что для работы с floating point необходимо делать FPU, полагаю, не стоит даже и начинать.
Структурная схема цифрового умножителя 4×4 бита. Каждый блок HA (half adder) — это 12–20 транзисторов, каждый блок FA (full adder) — 25–40 транзисторов.
При этом, даже при небольшой точности, «стоимость» умножения усугубляется необходимостью обработки больших объемов данных — входных данных и весов. В современных сложных цифровых системах быстродействие и энергопотребление повсеместно определяются не самыми вычислительными блоками, и передачей данных — так называемым «фон Неймановскими бутылочным горлышком». Веса, будучи статическими значениями (по крайней мере, во время инференса), тем не менее, требуют удобного доступа, то есть или очень быстрой шины, или локального хранения памяти рядом с вычислительным блоком. Такой подход наиболее эффективен в случае, если у нас не один большой вычислительный блок (скажем, ядро микропроцессора), а много маленьких, каждый со своим собственным хранилищем весов. К сожалению, этот подход плохо работает в случае сложных ветвящихся алгоритмов, являющихся типовой нагрузкой CPU, и именно поэтому современные процессоры в большинстве своем — это RISC-машины с относительно скромным количеством ядер, а не какие-нибудь VLIW или «тысячекоры». Но существует также и широкий класс задач, где ветвлений или совсем нет, или очень мало, а данных много, и их можно обрабатывать параллельно. Например, к этим задачам относится обработка изображений и нейросети. Именно поэтому многие GPU и TPU построены на принципе множества небольших вычислительных ядер с хардверными умножителями и локальной памятью, и именно в силу схожести этих задач выполнять нейросетевые вычисления на GPU радикально эффективнее, чем на CPU. Такого рода системы в контексте AI сейчас называют «near-memory compute», потому что память весов располагается намного ближе (и физически, и архитектурно) к вычислительным элементам.
Это, впрочем, никак не решает проблему того, что цифровое умножение крайне накладно, и чем больше его надо делать, тем хуже становится ситуация. Огромное количество научных и прикладных работ посвящены тому, как уменьшить разрядность весов и данных в нейросетях без существенной потери точности инференса. Про floating point уже никто толком даже не упоминает, в ход идут int8, int4 или даже «полтора бита» (множество весов, состоящее из -1, 0, +1). Ограниченно-точные сети могут быть полезны не только для огромных LLM, но и для разного рода небольших приложений, вроде умных сенсоров, промышленного интернета вещей и других мест, где можно существенно улучшить энергопотребление, надежность и безопасность за счет локальной обработки чувствительных сырых данных без отправки их на мощные облачные серверы. Действительно же, самый лучший способ защитить свои данные — просто не отправлять их в облако.
Но даже малоразрядные цифровые умножители — это огромное количество транзисторов и на сам умножитель, и на память, ведь даже простая статическая ячейка кэш-памяти — это целых шесть транзисторов. Можно ли как-то перевернуть игру? Теоретически — да, но для этого придется преодолеть скепсис и вернуться к давно забытому старому.
Аналоговый подход к вычислениям считался устаревшим на протяжении десятилетий, и на то были и есть причины. В аналоговых системах существует множество физических и технологических ограничений. Снижение точности и повторяемости результатов вычисления из-за разного рода неидеальностей было одной из причин быстрого роста цифровых технологий и повсеместного отказа от аналога. Да и о какой повторяемости результатов можно говорить, если пороговое напряжение типичного МОП-транзистора может изменяться в пару раз просто из-за изменения температур чипа? На практике в аналоговых вычислительных системах сложно достичь точности, соответствующей более чем четырем цифровым битам (здесь имеется в виду ENOB), а достижение точности выше 8 бит обычно требует радикального усложнения схемотехники и каких-то совсем нетривиальных решений.
Но ведь точность и в восемь, и даже в четыре бита вполне может быть достаточной именно для нейросетей, так? И в этой ситуации аналоговые решения могут предложить то, чего нет у цифры — компактность. Однако аналоговые реализации могут быть очень привлекательными в случаях, когда удовлетворительна точность около 8 бит из-за их простоты и энергоэффективности, и поэтому разработчики микросхем снова рассматривают аналоговые решения. Так как может работать аналоговая MAC?
Ее можно реализовать с помощью… закона Ома. Он гласит, что ток равен напряжению, деленному на сопротивление — или напряжению, умноженному на проводимость резистора. При этом несколько токов можно суммировать, просто подключив весовые резисторы параллельно друг к другу. Итого, для выполнения одного умножения нам нужен один (!) резистор, точность номинала которого и соответствует точности веса в нейросетке — и еще один резистор для того, чтобы получить выходное напряжение из суммы токов. Такой резистор нужен один на целый нейрон (в котором могут быть десятки и сотни весов), так что им для простоты сравнений можно пренебречь.
Но где найти резистор в КМОП-технологии, да еще желательно программируемый? Традиционные поликремниевые или диффузионные резисторы, используемые в аналоговой схемотехнике, вряд ли подойдут: слишком громоздкие. Собственно, единственный тип компактных элементов в КМОП-технологии — это транзисторы. Тут будет кстати вспомнить, что слово «транзистор» является сокращением слова «transresistance», то есть собственно «переходное сопротивление». То, что нужно, не правда ли? Осталось только придумать, как управлять сопротивлением этого транзистора, не используя для этого очень много других транзисторов.
Решением этой задачи является NOR flash память. В обычной «цифровой» флэш-памяти у запоминающего транзистора есть два состояния — «открыт» и «закрыт», регулируемых наличием или отсутствием заряда на плавающем затворе. Но на плавающий затвор можно закладывать заряд по чуть-чуть, плавно регулируя проводимость транзистора. Эта регулировка нелинейная, что затрудняет процесс и снижает точность, но, тем не менее, на ячейке флэш-памяти вполне реально добиться шестнадцати хорошо различимых величин проводимости, то есть эффективной разрядности в четыре бита. И под «вполне реально» я имеют в виду «можно пойти и купить соответствующий IP-блок для ряда популярных техпроцессов нескольких крупных фабрик».
Структурная схема вычислительного блока in-memory computing на основе популярной в индустрии ячейки NOR Flash ESF3. Модуль можно купить для многих техпроцессов TSMC, Globlafoundries, UMC, Samsung и некоторых других фабрик.
Массив флэш-памяти позволяет использовать строки как входы для данных, а столбцы — как входы нейронов, на которых суммируются токи с резисторов. Массив X на Y ячеек позволяет реализовать один слой нейросети из X нейронов с Y синапсами у каждого нейрона. На рисунке ниже показан пример такого соединения эквивалентных сопротивлений (еще показаны некоторые паразитные элементы). Каждый выходной ток Ii является взвешенной суммой напряжений V1-Vn, а проводимости элементов Gij — веса нейросети.
Принципиальная структура массива памяти, используемая для создания «вычислений в памяти»
MAC-операция в такой конструкции, как нетрудно заметить, вычисляется непосредственно внутри массива памяти, и такого рода схемы так и называют — «in-memory computing», и рассматривают как следующий логичный шаг после перехода от фон Неймановских архитектур с разделением памяти и вычислений к near-memory, характерным для GPU.
А вот примерно так распознавание изображений с помощью аналогового in-memory computing выглядит на практике. На это диаграмме в качестве запоминающих элементов показаны мемристоры.
Подход in-memory computing может быть реализован многими разными способами (об этом чуть позже), но вариант со флэш-памятью — самый инженерно проработанный. Он имеет два недостатка. Ячейки флэш-памяти, хоть и состоят из одного транзистора, по меркам современных цифровых техпроцессов довольно громоздки, и, вообще говоря, практически не скейлятся ниже 45 нм. Кроме того, любой массив памяти содержит соединения типа «все со всеми», но далеко не каждая нейронная сеть нуждается в таком количестве синапсов. Более того, очень большая часть нейросетей — это так называемые «разреженные» (sparse) сети. В них большая часть ячеек памяти не будет использоваться и дефицитная площадь чипа не будет потрачена эффективно. Разумеется, можно и нужно оптимизировать архитектуры нейросетей для того, чтобы уменьшить разреженность и увеличить процент эффективного использования массива. Но даже в такой ситуации половина площади, а то и больше, будет потрачена впустую.
Хороший пример реализации такого подхода — чипы компании Mythic AI. Их M1076 включает 76 вычислительный блоков, каждый из которых содержит массив 1024×1024 ячеек памяти и RISC-V ядро для управления и конфигурации. Чип может вместить до 80 миллионов int8 или int4 весов и, по заверению разработчиков, потребляет всего 3–4 Вт в активном режиме. Заявленная энергоэффективность — 0.3–0.5 пДж/MAC, что в 3–4 раза лучше, чем у NVIDIA (при том, что чип Mythic произведен на дешевом 40 нм техпроцессе).
Блок-схема аналогового нейропроцессора компании Mythic AI
Разумеется, такая конструкция на таких проектных нормах получается совершенно монструозного размера, поэтому одной из ключевых задач ученых, вовлеченных в касающиеся AI технологические исследования, является разработка компактных ячеек энергонезависимой памяти — более компактных, чем NOR flash и, в идеале, не содержащих транзисторов, а выполненных в верхних слоях металлизации, чтобы схемы доступа управления можно было разместить под памятью.
Вариантов здесь очень много — MRAM, FRAM, PCM, ReRAM, мемристоры — и для каждого вида есть множество перспективных вариантов. Или уже не очень перспективных, как случилось с не оправдавшей ожиданий Intel и Micron памятью 3D Xpoint.
Дерево технологий emerging NVM
Несмотря на множество сложностей, так называемые emerging NVM активно развиваются, и MRAM уже есть в серийном предложении нескольких фабрик и скажем, в новейших моделях микроконтроллеров STM32. Однако, с точки зрения аналоговой реализации MAC-операции, все несколько более печально, потому что большинство новых разработок в сфере NVM работает бинарно, что вполне достаточно для конфигурационной памяти микроконтроллера, но не подходит для многобитного аналогового веса. Впрочем, некоторый прогресс есть и тут: недавно многобитные мемристоры представила японская корпорация TDK, а американский стартап TetraMem вообще обещает точность 11 бит на элемент, достигаемую с помощью хитрой двухступенчатой процедуры записи.
Забавная особенность решительно всех видов emerging NVM — то, что состояния запоминающего элемента различаются сопротивлением. С одной стороны, это логично, ведь резистор — это один из фундаментальных линейных пассивных компонентов. Но ведь «один из», а не единственный!
Фундаментальные линейные пассивные элементы и связывающие их уравнения
На рисунке выше показаны все четыре фундаментальных линейных пассивных компонента — резистор, конденсатор, индуктивность и мемристор, а также уравнения, которыми эти элементы связывают разные физические величины. Нетрудно видеть, что рисунок очень симметричный, и если MAC-операцию можно реализовать при помощи резистора, то и с остальными компонентами это может быть возможно, так? Да, так, но, как это обычно бывает, кроме красивой теории, есть некоторые технологические нюансы.
Уравнение работы резистора — I = V / R, или, точнее, dI = dV / R.
Аналогичное уравнение для конденсатора — Q = T * I, или dQ = C * dV.
Если мы хотим получить в качестве выходного сигнала напряжение на конденсаторе, мы уравнение преобразуется в dV = d (I * T) / C. Принципиальная разница между резистором и конденсатором здесь заключается в том, что в уравнении для конденсатора участвуют не три, а четыре величины. Это означает, что у проектировщика схемы есть больше гибкости, но и сложностей тоже больше.
Существует много разных вариантов запоминающего элемента на основе конденсатора. Выходной величиной удобнее всего иметь напряжение или заряд, а вот входом может быть либо ток, либо время, и тогда вес будет произвольной комбинацией двух оставшихся параметров. Например, схема может получать выходное напряжение, заряжая фиксированный конденсатор в течение фиксированного времени с помощью тока, определенного весом. Альтернативно, выходное напряжение может быть получено при зарядке конденсатора, номинал которого является весом, в течение фиксированного времени, а входным сигналом будет ток зарядки.
Реализация MAC-операции с весом, задаваемым временем зарядки конденсатора
На рисунке выше показана схема, где конденсатор фиксирован, а вес определяется временем зарядки. С одной стороны, MAC-операция в такой схеме проводится на одном конденсаторе. С другой стороны, схема точного задания временного интервала — это громоздкий таймер, работающий на большой частоте, требующий наличия на чипе PLL. Кроме того, вся конструкция вполне может быть серьезно зависима от PVT (изменений в параметрах элементов, температуры и питания чипа). Выглядит, к сожалению, и громоздко, и не очень энергоэффективно.
Можно попробовать перейти в область работы с зарядами вместо напряжений, как это часто делается в популярных у аналоговых дизайнеров схемах на переключаемых конденсаторах. В этом случае основное уравнение будет Q = C * V, а суммирование заряда получится относительно простым.
Реализация MAC-операции с помощью ЦАП
На рисунке выше для реализации веса нейросети используется ЦАП (цифро-аналоговый преобразователь) с емкостной матрицей. Значение емкости определяется цифровым кодом, что является наиболее подходящим способом программирования конденсатора. Обычно у ЦАП фиксированное опорное напряжение, и он генерирует выходной сигнал в соответствии с цифровым входом. Здесь же цифровой вход трактуется как вес, а вместо опорного напряжения мы подаем входное, умножая его на заданный конденсатором вес. Такой подход исключает точное время и высокие частоты, делая выходной сигнал стабильным и точным. Однако даже очень простой ЦАП представляет собой сложную и крупную схему, площадью в сотни, если не тысячи квадратных микрон. Решением этой проблемы мог бы быть компактный переменный конденсатор (memcapacitor). Научные работы в этом направлении активно ведутся в последние годы, но пока что далеки от промышленного внедрения и находятся в среднем на более ранних стадиях, чем аналогичные работы по мемристорам.
К вопросу о собственно мемристорах — их тоже можно использовать, и тоже несколькими разными способами. Мемристор был теоретически предсказан намного позже, чем получили распространение другие полупроводниковые приборы, а надежные реализации и вовсе появились совсем недавно. Основное уравнение мемристора связывает электрический заряд, протекший через мемристор, с суммарным магнитным потоком. Номинал мемристора — мемсопротивление — имеет размерность Вебер/Кулон, которые после сокращения дают… Ом. То есть, мемристор, будучи фундаментально другим элементом, может вести себя, как резистор, сопротивление которого зависит от протекшего через него заряда. Отсуда, собственно, и название — «резистор с памятью», и основное применение, которое заключается в том, что мемристоры используют к программируемые резисторы. Если рабочий ток намного меньше тока перезаписи, то влиянием рабочего тока на сопротивление можно пренебречь на значительных промежутках времени, и мемристор будет действительно вести себя как программируемый сильными токовыми импульсами резистор, очень похоже на многие другие типы emerging NVM.
Пример компактной реализации мемристора в форм-факторе перемычки между двумя слоями металических межсоединений
Основная причина, по которой мемристорам уделяется так много внимания — их потенциальная компактность. Существует уже много разных реализаций мемристора в виде многослойного вертикального бутерброда из разных материалов. Такая реализация не тратит драгоценную транзисторную площадь и теоретически может иметь размер в буквально несколько сотен квадратных нанометров. То же самое, впрочем, верно и для MRAM и ReRAM.
Последний из четырех базовых линейных элементов — индуктивность. С ней все так сложно и технологически, и фундаментально, что катушки никто серьезно не рассматривает для микросхем с большой степенью интеграции. Во-первых, индуктивность в принципе требует высокой частоты для того, чтобы нормально работать, и поэтому не может применяться в малопотребляющих схемах. Во-вторых, чем меньше геометрические размеры катушки, чем выше необходимая частота. Ну и самое главное — характерные размеры катушек индуктивности в принципе на пару порядков больше, чем то, что можно серьезно рассматривать. Если вы когда-нибудь видели кристалл любого радиочастотного чипа, то вы точно видели там катушки на полкристалла.
Радиочастотный чип VCO. Размеры катушек индуктивности говорят сами за себя
Заключение
Мы рассмотрели различные теоретические и практические варианты реализации операции умножения-накопления в аналоговой форме на основе разных полупроводниковых приборов. Это направление разработки «железа» для AI находится в весьма зачаточной стадии, особенно если сравнивать с хорошо проработанными цифровыми реализациями — не только на видеокартах, сейчас уже даже в микроконтроллерах начали появляться небольшие встроенные нейроускорители.
Вероятнее всего, аналоговые реализации AI, даже если «выстрелят», так или иначе останутся нишевыми решениями — в силу принципиально ограниченной на уровне 4–8 бит точности, сложных производственных технологий и многих других объективных причин. Но в условиях, когда AI применяется приблизительно везде, даже «отдельные ниши» вполне могут быть многомиллиардными рынками, особенно если мы говорим про обработку изображений или копеечные, но исключительно многотиражные умные сенсоры для интернета вещей.
Кроме того, технический и технологический прогресс не стоят на месте, так что элементная база для подобных вычислений стремительно улучшается, а число стартапов, пытающихся в отдельных нишах коммерциализировать уже существующие наработки, прямо сегодня исчисляется десятками, если даже не сотнями. Наибольшие успехи сейчас у in-memory computing на базе флэш-памяти, и у разного рода нишевых решений, в основном касающихся умных сенсоров и производимых на довольно старых по цифровым меркам проектных нормах — 90–65–40 нм, где сходятся между собой низкая стоимость и высокая энергоэффективность.