Итак, анализ возможных вариантов архитектуры AI-процессора и мотивация выбора GPGPU были изложены в Части 1. Но в чём секрет такого успеха GPGPU в техническом разрезе? Давайте попробуем немного углубиться в данную тему.
Теория
Для начала зададимся вопросом – а каков вообще теоретический предел идеального AI-вычислителя? Допустим, мы магическим образом определили оптимальную микроархитектуру и идеально её спроектировали. Можно ли определить, какова будет производительность такого решения?
Хорошая новость заключается в том, что это возможно, но при соблюдении следующих условий:
Мы остаёмся в рамках существующих моделей нейросетей и точно соблюдаем семантику их работы. Это значит, что, если модель имеет слой свёртки со входными параметрами и весами в заданном формате (например, fp16) и должна на выходе получить результирующий тензор с требуемой точностью результатов – мы получаем именно его и всегда одинаковыми алгоритмами. Т.е. все AI-вычислители должны работать в равных условиях.
Мы остаёмся в рамках синхронного цифрового дизайна. Ибо проектировать в рамках других подходов чипы такого размера, как современные AI-процессоры, человечество пока не научилось.
Мы остаёмся в рамках одного техпроцесса. Понятно, что сравнение микроархитектурных решений имеет смысл при условии единой технологической базы.
Мы говорим о производительности, ограниченной размерами одного чипа. Вопрос построения единой системы из множества вычислителей оставим архитекторам таких решений.
Мы говорим о AI-вычислителях с одинаковой функциональностью в части поддержки форматов. Понятно, что сравнивать чип с поддержкой только INT8, с чипом, имеющим полную поддержку форматов, включая FP32/FP64, не является честным.
В таком случае, можно прикинуть максимальную теоретическую производительность идеального AI-вычислителя. Как уже упоминалось в предыдущей статье, есть 2 основных фактора, влияющих на скорость работы ваших нейросетей на железе:
Теоретическая производительность в ТераОпсах (TOPS), и:
Реальная утилизация этих ТераОпсов или MFU (Model Flops Utilization — утилизация доступных на вычислителе FLOPS одним проходом модели)
Если совсем просто – вам нужно вместить на кремний как можно больше FMA-юнитов и постараться сделать так, чтобы они не простаивали и работали как можно чаще.
Давайте начнём с первого вопроса – сколько можно уместить FMA-юнитов на чип? И сколько сейчас FMA-юнитов в современных GPGPU?
Попробуем провести такого рода анализ на примере Nvidia GH100 – основной рабочей лошадки современного мира AI-вычислений. Да, уже появилась более современная микроархитектура от Nvidia – Blackwell - и набор решений B100/B200 на её базе. Но пока по ней недостаточно материалов, чтобы провести хороший анализ. В любом случае, качественная оценка принципиально не изменится. Итак, давайте посмотрим на флорплан Nvidia GH100 и попытаемся понять, сколько площади занимают интересующие нас блоки:

Кто не знаком с указанными на схеме аббревиатурами, расшифруем:
SM – Streaming Multiprocessor. Основное вычислительное ядро, включающее в себя вычислительные блоки, тензорные ядра, управляющую логику и кэши первого уровня (L1I и L1D)
TPC - Texture Processing Cluster. В контексте AI-вычислений, это просто объединение 2-х SM, имеющее общую шину обращений к кешу второго уровня (L2D)
CPC - Compute Processing Cluster. Объединение 3-х TPC, позволяющее на уровне программной модели Cuda использовать определённые фичи GPGPU.
GPC - GPU Processing Clusters. Объединение 3-х CPC. Аналогично предыдущему пункту, используется для поддержки свойств программной модели Cuda.
L2$ - кэш данных второго уровня
Crossbar – блок, осуществляющий связь вычислительной части GPGPU (SM, TPC, CPC, GPC) с данными (L2 кэш, память)
HBM PHY – аналоговая часть высокоскоростного интерфейса, осуществляющего связь кристалла GPGPU с HBM (High Bandwidth Memory)
Для начала надо сделать ремарку – мы помним (помним, да?), что физический предел размера одного чипа (обусловленный технологическим процессом) составляет 33х26 = 858 мм^2. С учётом технологических нюансов, этот размер реально ещё несколько меньше, поэтому заявленные 814 мм^2 для Nvidia GH100 близко к максимуму.
Примерное соотношение площади, которую занимают блоки, выглядит вот так:
Blocks |
Percent of Total Area |
Streaming Multiprocessors (SMs) |
50% |
L2 Cache |
15% |
PHYs, Controllers, Interconnect, etc. |
35% |
Основная вычислительная нагрузка для GPGPU находится в SM (всего их 144 на данном чипе).
Практически все ТераОпсы в случае GH100 нам дают тензорные блоки (Tensor Cores). Оценка размера их площади по отношения к размеру SM даёт примерно 30%. Также заметную площадь занимают обычные блоки перемножения fp16/fp32/fp64, но, так как они вносят небольшой процент в общую вычислительную мощность GPGPU и имеют существенно меньшую плотность размещения блоков FMA, ими мы пренебрежём. Считаем, что именно плотность размещения FMA в тензорных блоках является для нас целевой.
Таким образом, получается, что теоретически мы могли бы увеличить количество FMA на кремнии примерно в 2*3 = 6 раз.
Теперь разберёмся со второй часть нашего уравнения производительности – утилизацией флопсов (MFU). В предыдущей статье приводилась таблица, где MFU для GPGPU оценивалась примерно в 50%. Понятно, что это некоторая «средняя температура по больнице», но будем опираться в наших качественных оценках на неё.
Итак - теоретический предел идеального AI-вычислителя составляет примерно х12 от GPGPU Nvidia GH100 (в 6 раз больше FMA и в 2 раза больше утилизация). Эту цифру полезно держать в уме, когда в очередной раз появляются громкие заявления в прессе о том, что сделали AI-вычислитель «в сто-пятьсот раз быстрее Nvidia». Более того, это абсолютно идеальная оценка. Реальная будет куда ниже, давайте попробуем её также прикинуть (пусть и менее точно):
Очевидно, что забить всю площадь чипа SM-ками (или их аналогами, осуществляющими непосредственно вычисления) – не получится. Вы никуда не денетесь от установки высокоскоростных интерфейсов, с помощью которых будете получать данные извне. Поэтому те 35%, которые ушли на «обвязку» сильно сократить не удастся.
-
Как ни крути, а от наличия какого-то количества памяти на чипе в виде SRAM (в GPGPU это включает в себя L2 Cache, но не только) вам не уйти. Пока пропускные способности высокоскоростных интерфейсов не позволяют прокачивать столько данных, чтобы «накормить» вычислительные блоки. И если вы не будете хранить и переиспользовать данные на чипе, вся вычислительная мощь будет уходить в пустоту и утилизация упадёт до нулевой отметки. Поэтому, как раз бОльшее количество SRAM на вычислителе и стремление к повышению утилизации, является основным подходом, с помощью которого конкуренты пытаются обыграть NVidia:
AI Chip
SRAM, MB (ориентировочно, с учётом регистров)
TFlops, FP16/BF16
MB per TFlops
Nvidia GH100
133
1000
0,133
Google TPUv4
170
275
0,62
Groq
230
188
1,22
SambaNova
520
638
0,82
Здесь хорошо видно, что и по количеству самой SRAM, и по соотношению количества памяти к вычислительной мощности, все альтернативные подходы превосходят GPGPU от Nvidia. При этом, никто не достигает количества FMA, сравнимому с Nvidia. Собственно, здесь во многом и кроется секрет и направление того, как Data Flow процессоры пытаются обыгрывать GPGPU - за счёт большего количества памяти на чипе и, соответственно, лучшей утилизации меньшего количества Flops’ов.
Опять-таки, в реальности, нельзя заполнить весь чип только тензорными блоками. Современные нейросети используют функции активации, для которых необходимы трансцедентные операции, требуют работы с векторами и преобразованием расположения данных. Это всё потребует дополнительной логики в железе.
Давайте резюмируем. Если отойти от чисто теоретических рассуждений и принять во внимание реальное положение дел, то соперничать с современными GPGPU в части увеличения количества Flops’ов на чипе сложно. Скорее всего, это значение близко к максимуму, и никто из конкурирующих подходов здесь не смог и вряд ли сможет обойти GPGPU. Поэтому, речь в реальности может идти скорее о попытке разработать AI-чип, превосходящий GPGPU по утилизации вычислительной мощности. Если мы берём в качестве некоторой усреднённой цифры утилизацию в 50% (как было указано выше), то предел повышения производительности составляет максимум 2 раза. Но из предыдущей статьи мы видим, что утилизация в 50% является вполне неплохим результатом, который не так просто достичь.
Теперь немного заглянем вглубь архитектуры GPGPU и попробуем хотя бы поверхностно разобраться с теми механизмами, которые позволяют данному классу вычислителей достигать высоких цифр утилизации вычислительных блоков.
Архитектура GPGPU
Итак, на верхнем уровне, Nvidia GH100 состоит из набора SM-ок и общего L2-кэша и выглядит следующим образом:

Здесь стоит сразу отметить один фундаментальный момент. Хотя, на первый взгляд, в такой архитектуре нет ничего особенного, она имеет одну важную проблему – как программировать множество имеющихся вычислительных устройств. И именно эту задачу решает CUDA – Compute Unified Device Architecture. Вопреки частым заблуждениям, что Cuda - это некоторый язык программирования или API, Cuda - является именно программно-аппаратной моделью, позволяющей эффективно использовать GPGPU. И данная модель полагается на определённые аппаратные свойства, отсутствие которых может существенно снизить производительность написанного кода. Ключевые аспекты данной аппаратной поддержки скрыты в архитектуре SM:

Вот так выглядит общее описание архитектуры SM от Nvidia (в первом приближении, дизайн Streaming Multiprocessor всех GPGPU идейно аналогичен). В первом приближении идея проста – поток инструкций, приходящих из L0/L1 ICache через логику планировщиков варпов (Warp Scheduler) попадает в Backend, где происходит считывание данных и исполнение команд на соответствующих исполнительных блоках. Задача – обеспечить максимальную загрузку вычислительных блоков. Если она выполняется, значит процессор работает эффективно.
В такой архитектуре есть 3 ключевых момента (второстепенных, конечно же, больше), чтобы «всё было хорошо»:
Подходящий класс задачи для такого рода архитектуры. Надо понимать, что GPGPU хорошо работает только для определённого рода задач – обладающих высокой параллельностью и хорошей степенью локальности по данным. Данное условие обеспечивает модель Cuda и сам алгоритм задачи, написанный программистом. И именно потому, что алгоритмы, используемые в задачах ИИ, обладают такого рода свойствами, GPGPU являются аппаратным базисом в данной области.
Warp Scheduler. Это блок, позволяющий каждый такт процессора переключаться на готовый к исполнению Warp – набор из 32 потоков, исполняемых синхронно. Логика Warp Scheduler, по сути, реализует идею SMT (Simultaneous multithreading), часто применяемой в процессорах общего назначения. Только ввиду большого количества исполняемых потоков, данный подход доведен до максимума и можно говорить о технике массовой мультипоточности. В каком-то смысле, в вычислителях, нацеленных на исполнение кода, обладающего высоким параллелизмом, Warp Scheduler выполняет функцию Out-of-Order (OoO) логики в CPU.
Register File/L1 DCache. Дизайн блоков памяти, где хранятся обрабатываемые данные, существенно отличается от того, что применяется при разработке CPU. Архитектура GPGPU диктует необходимость обеспечивать высокую пропускную способность в части работы с потоками, зачастую в ущерб задержке (latency) исполнения каждой команды.
Именно эти пункты позволяют GPGPU быть эффективным на широком круге приложений, и, в первую очередь – на интересующих нас задачах ИИ.
Описание всех нюансов архитектуры современных GPGPU – это масштаб докторской диссертации. Тем более, что описание многих вещей требует, зачастую, немалое количество достаточно специализированных знаний. Тем не менее, попробуем хотя бы немного приоткрыть завесу того, каким образом осуществляется разработка такого рода сложных вычислителей и насколько мы в этом преуспели.
Наш скромный опыт
Разработка более-менее конкурентного GPGPU является достаточно нетривиальной задачей. Причём, как с точки зрения создания непосредственно железа, так и точки зрения разработки минимального объема стека программного обеспечения, позволяющего пользователям использовать ваше аппаратное решение.
Главной проблемой, как можно догадаться, было отсутствие минимальных компетенций по созданию GPGPU в России. На состояние 2-х летней давности таких людей в стране просто не было. Поэтому, первыми задачами, которые стояли, были следующие:
Провести исследование общедоступных материалов (статей, презентаций, диссертационных работ, открытых проектов).
На базе проведенных исследований разработать микроархитектуру IP-блока GPGPU.
Разработать систему команд (ISA), обеспечивающую работу IP-блока GPGPU.
Реализовать функциональный симулятор ISA.
Реализовать потактовый симулятор, реализующий разработанную микроархитектуру.
Первый пункт сразу таил в себе неприятные неожиданности. Как в итоге выяснилось, большинство публичных материалов являются достаточно бесполезными в части дизайна непосредственно железа. Понятно, что трудно ожидать продуктового уровня решений от опенсорсных проектов типа Vortex GPU или Simty. Но вот от мировой академической науки были куда большие ожидания. То, что в России вообще нет никаких минимально серьёзных исследований на тему архитектуры GPGPU – печальный, но ожидаемый факт. Но, как оказалось, статьи и диссертационные работы мировой академической науки в целом далеки от реальностей промышленного дизайна железа. Также, занимательным фактом оказалось то, что, несмотря на, казалось бы, большую открытость компании AMD и доступность приличной части системного кода в опенсорсе, открытую ISA (в отличие от NVidia, где она полностью закрыта) – исследование принципов работы GPGPU на решениях AMD оказалось намного сложнее. Лидерство компании NVidia в нише GPGPU привела к тому, что все самые интересные и минимально полезные исследования принципов работы такого класса вычислителей проводились на картах зелёной компании. Что привело к ситуации, что о них мы знаем намного больше, чем, казалось бы, об открытых AMD. Про остальные GPGPU, существующие на рынке, говорить не приходится – это микроскопическая доля с фактически нулевой информацией о деталях работы.
Отдельная боль – программные симуляторы. В самом начале казалось, мы имеем полный спектр вариантов – GPGPU-sim, AccelSim, Navisim, Gem5 с AMD GCN3. Не вдаваясь в подробности – всё это великолепие вы можете выбросить в урну. Вопрос вызывают статьи, написанные на основе данных, полученных с запусков данных симуляторов. Что они на самом деле замеряют – для нас до сих пор загадка. Функциональный и потактовый симуляторы в нашем случае были разработаны самостоятельно на базе инфраструктуры gem5. Здесь однозначный вывод – решите разрабатывать свой GPGPU – не надейтесь на опенсорс.
Следующая проблема - крайне медленная скорость потактовой симуляция, т.к. приходится моделировать устройство очень высокой вычислительной мощности. Сама по себе симуляция, как правило, работает в однопоточном режиме, при этом моделируется устройство, исполняющее десятки, сотни или даже тысячи операций в такт. В результате, симуляция одного прохода сети уровня Resnet50/YoloV4 легко может занимать 10+ часов. При таких параметрах анализ производительности и тюнинг микроархитектурных решений становится крайне затратным процессом, серьёзно замедляющим скорость разработки.
Тем не менее, успешно преодолев все ожидаемые и не очень сложности, первые 5 пунктов были реализованы. В итоге мы получили:
Документ с описанием архитектуры (ISA) GPGPU, состоящий текущий момент примерно из 400 страниц и 150 инструкций.
Функциональный симулятор, способный запускать все команды ISA.
Примерно 100 страниц в Wiki с подробным описанием микроархитектуры GPGPU.
Потактовый симулятор разработанной микроархитектуры, показывающий, что мы достигаем в среднем примерно 80% микроархитектурной скорости в сравнении с титанами индустрии в лице Nvidia/AMD (понятно, что речь идёт о базовых бенчмарках с идентичными алгоритмами вроде перемножения матриц/свёртки/сложения векторов).
Дальнейшие задачи, стоящие перед командой, хотя и более прямолинейные, но местами ещё более сложные и объёмные:
Имплементация разработанной микроархитектуры GPGPU на RTL.
Анализ производительности и улучшение микроархитектурных решений.
Верификация разработанного IP-блока GPGPU.
Создание FPGA-прототипа.
Реализация большого количества системного ПО – драйвер, рантайм, компилятор и т.д.
Проектирование финального ASIC с разработанным IP-блоком GPGPU.
Данные пункты находятся в разной степени готовности. Гурманов постараемся заинтриговать такой картинкой:

Больше подробностей в следующих статьях, как говорится, stay tuned!
GPGPU – а что с графикой?
Предвосхищая данный вопрос, отвечаем - в первой версии работа чипа в режиме обычного графического процессора (GPU) не планируется. Причины простые:
Необходима имплементация и верификация специализированных аппаратных блоков для графики (таких как Texture, ROP), что требует дополнительных инженерных ресурсов и компетенций (на текущий момент в России практически отсутствующих).
Требуется большие затраты на разработку специализированного графического программного стека.
Рыночные перспективы GPU даже на российском рынке выглядят, мягко говоря, крайне туманными.
Поэтому, в данный момент, по понятным причинам, фокус на поддержку AI-функционала. Тем не менее, потенциально, AI GPGPU достаточно несложно апгрейдится до обычного GPU. В будущем, эту опцию можно рассмотреть.
А можно поучаствовать?

Думаю, ни у кого не вызывает сомнение, что разработка столь сложного ASIC – крутая и крайне интересная штука! Поэтому, если слова RTL-дизайн, физический дизайн или верификация не являются для вас чужими – у вас есть шанс поучаствовать в разработке линейки современных AI-процессоров и узнать все секреты GPGPU из первых рук.
Особенно хотелось бы отметить большой объём работы по верификации. Именно качеством и объёмом верификации зачастую отличается IP-блок продуктового уровня от «чего-то работающего». С ростом сложности дизайнов растут и затраты на верификацию, переваливая более чем за половину всех трудозатрат разработки:

Поэтому, опытным верификаторам будем рады особенно! :-)
В общем, если вы чувствуете, что обладаете компетенциями, способными принести пользу делу разработки GPGPU - можно писать в личку или откликаться на вакансии вот тут.
Со своей стороны, мы постараемся, по возможности, держать читателей Хабра в курсе проекта и делиться новостями и интересными техническими аспектами разработки.
novoselov
В текущей ситуации делать графический чип не имеет никакого смысла, так что правильно что сосредоточились на чисто AI. В плане поддержки кажется лучше ориентироваться на PyTorch, а не на CUDA, но это уже холиварный вопрос.
Из описанного не увидел что у вас с сетью? nVidia выигрывает еще и за счет того что предоставляет сразу готовую экосистему где каждый компонент оптимизирован под общее решение (недаром они покупали Mellanox). Вот один из перспективных вариантов. В этом плане лучше сразу ориентироваться на общий дизайн стойки, чтобы не было узких мест. Альтернативное видение облачного компьютера можно посмотреть тут
Смотрели ли вы в сторону Tesla Dojo? Там помимо нестандартных технических решений обещают детерминированный порядок исполнения, что позволяет делать более глубокую оптимизацию на программном уровне.
Armmaster Автор
Это несколько разные вещи. По сути, поддержка Cuda даёт автоматически поддержку PyTorch, т.к. там есть cuda-backend.
Это вопрос для следующих проектов. В моей голове для "взрослого" конкурентного продукта с точки зрения HW необходимо решить 3 ключевых задачи:
Разработать хорошее вычислительное ядро GPGPU (то, что у Nvidia называется SM)
Разработать качественную подсистему памяти (L2-кэш, интерконнект, GPDDR/HBM и т.д.)
Разработать сетевой интерконнект, позволяющий объединять вычислители в кластер.
На самом деле каждая из этих задач - очень сложная, и решить их все вместе сразу невозможно. Поэтому надо двигаться последовательно, от п.1 к п.3