Согласно материалу AWS Machine Learning, голос становится основной модальностью для искусственного интеллекта, и модели Deepgram охватывают преобразование речи в текст, преобразование текста в речь и голосовых агентов. В настоящее время они обрабатывают квадриллионы аудиотокенов в год для более чем 200 000 разработчиков и 1 400 организаций. Клиенты используют их через API Deepgram или запускают в своих собственных средах, включая Amazon SageMaker AI. Для Deepgram эффективность обслуживания определяет, сколько аудио система может обработать в рамках заданного бюджета инфраструктуры. Высокие объемы пакетных рабочих нагрузок создают значительное давление на этот бюджет, поэтому чем более эффективно используется каждый час ускорителя, тем больше аудио Deepgram может обслужить на том же флоте. Это сделало эффективность вывода естественной целью, и Deepgram обратился к чипам ИИ AWS для её улучшения. Компания работала с AWS, чтобы перенести свою модель Nova-3 для преобразования речи в текст на AWS Trainium2 для оффлайн пакетных рабочих нагрузок, таких как аналитика контактных центров и медицинская транскрипция. Сотрудничество началось с того, что Deepgram представил Nova-3 в стандартном коде PyTorch. На протяжении нескольких месяцев Deepgram и команда AWS Forward Deployed Engineering (FDE) перенесли Nova-3 на AWS Trainium2 в реконструкции PyTorch и настроили его для нового оборудования. Конечная конфигурация запускает восемь реплик модели на одной инстанции Amazon Elastic Compute Cloud (Amazon EC2) trn2.3xlarge. На оффлайн пакетных рабочих нагрузках Deepgram эта настройка обрабатывала на 11–70 процентов больше аудио за доллар по сравнению с вычислительными опциями, которые использовал Deepgram ранее. Эти достижения помогают Deepgram масштабироваться эффективно, продолжать выпускать лучшие модели и предлагать их клиентам по более низким ценам. Эти преимущества могут распространиться на клиентов, которые самостоятельно размещают модели Deepgram в своих собственных виртуальных частных облаках (VPC) на Amazon SageMaker AI. Здесь Deepgram и AWS продолжают улучшать простоту настройки, надежность и наблюдаемость. В этом посте мы подробно рассматриваем полную работу по оптимизации вывода на Trainium: перенос Nova-3 на программный стек AWS Neuron, последующая настройка на уровне ядра, параллельный Rust-исполнитель, который позволяет серверу модели Deepgram вызывать Trainium, а также результаты по пропускной способности и затратам, которые мы измерили при пакетной транскрипции. Оптимизация Nova-3 для Trainium2 с использованием нативного PyTorch началась со стандартного кода PyTorch, и мы использовали TorchNeuron, нативную интеграцию PyTorch с компилятором Neuron, который поддерживает как жадное выполнение, так и torch.compile. Мы сначала запустили Nova-3 в жадном режиме на Trainium2 и проверили, какие операции переходят на CPU, затем скомпилировали с помощью torch.compile. Скомпилированный путь выполнил каждую операцию модели на Trainium2 без обнаруженных переходов на CPU. Мы скомпилировали кодировщик и декодер как отдельные статические графы формы с использованием torch.compile. На протяжении всего процесса мы проверяли числовую точность на двух уровнях: согласованность выходных данных на уровне слоя по сравнению с CPU и конечную частоту ошибок слов (WER), которая должна оставаться в соответствии с эталонными значениями Deepgram и целями. Исходя из этой рабочей базы, мы начали работу по оптимизации, заменив несколько слоев на объединенные ядра из публичной библиотеки NKI (NKILib), коллекции предварительно собранных эталонных ядер, написанных с использованием интерфейса ядра Neuron (NKI). Ядра охватывали операции, такие как объединенные проекции QKV, объединенные слои сети прямой передачи (FFN) и глубинные свертки 1D. Мы оптимизировали для пропускной способности и, следовательно, для эффективности затрат, нацеливаясь на оффлайн рабочие нагрузки вывода Deepgram. Пропускная способность сообщается как относительное увеличение по сравнению с базовой конфигурацией, а не как абсолютное количество обработанного аудио в секунду, и мы протестировали размеры пакетов от 1 до 128, чтобы найти оптимальный размер пакета для максимизации пропускной способности. Настройка на уровне ядра с Neuron Explorer и NAD. Включение ядер — это только первый шаг оптимизационного процесса: включите ядро NKI (пользовательское или из NKILib), профилируйте рабочую нагрузку, затем либо настройте существующее ядро, либо замените его новым на основе результатов профилирования. Этот цикл повторяется, пока не будет достигнута целевая производительность. На каждом этапе различная часть стека Neuron ускоряет работу: NKILib предоставляет ядра для замены, Neuron Explorer является основным инструментом для профилирования рабочих нагрузок Neuron, а набор инструментов Neuron Agentic Development (NAD) ускоряет анализ профилирования и настройку ядер через свои навыки профилирования и написания ядер. В нашем случае ядра NKILib обеспечили большую часть работы, а профилирование показало, где ручное ядро может работать лучше. Каждый раз навыки профилирования NAD помогали нам перейти от профиля Neuron Explorer к коренной причине, а навыки написания ядер NAD помогали создавать заменяющие ядра. Мы обнаружили, что в референсном ядре график разбиения повторно загружал полный набор весов проекции из внешней памяти для каждого тайла токена, поэтому пропускная способность памяти ограничивала производительность по мере увеличения количества токенов. Наше ручное ядро загружает каждый тайл веса один раз, повторно использует его для нескольких тайлов токенов и конвейеризует чтение весов с вычислениями на чипе. Это обеспечило в 2.0 раза меньшую задержку по сравнению с референсным ядром при размере пакета 96. Экспериментальное ядро NKILib сформировало операцию как неявное общее матричное умножение (GEMM), что оставило низкую загрузку Tensor Engine. Мы переписали его как цикл умножения и накопления с широковещательным использованием на векторном движке, достигнув полной загрузки движка, что более чем компенсировало меньшую пиковую пропускную способность векторного движка. Это обеспечило 1.5x ускорение по сравнению с референсным ядром при размере пакета 96. Свертки модели conv2d столкнулись с узким местом компиляции: при размере пакета более 32 эти слои не позволяли модели компилироваться как единый граф. Поскольку в NKILib не было ядра conv2d, мы написали его с нуля в NKI. Ядро прошло несколько итераций, основанных на профайлинге, следуя описанному ранее процессу, разблокировав размеры пакетов выше 32 с увеличением до 50x на модуле свертки при размерах пакетов ≤32. Каждое устройство Trainium2 имеет восемь физических NeuronCores, которые по умолчанию отображаются как четыре логических NeuronCores (LNC2). Поскольку каждая инстанция модели Nova-3 удобно помещается на одном физическом ядре, мы уменьшили количество физических ядер на логическое ядро до одного (LNC1). Эта конфигурация позволяет нам размещать восемь реплик модели (DP8) на каждом устройстве Trainium2. Входные данные обрабатываются одновременно, увеличивая пропускную способность на устройство. Параллельный исполнитель управляется очередью с крадущимися задачами с одним потоком на реплику. Стек обслуживания Deepgram написан на Rust, поэтому перенос Nova-3 на Trainium2 требовал не только компиляции модели, но и работы без Python или PyTorch в пути обслуживания. Поэтому мы создали легковесный исполнитель, в котором Rust координирует реплики модели через общую очередь с крадущимися задачами. Слой C загружает и выполняет заранее скомпилированные файлы в формате Neuron Executable File Format (NEFF) непосредственно через API Neuron Runtime (libnrt). Исполнитель интегрируется непосредственно с архитектурой обслуживания Deepgram и точно воспроизводит последовательности токенов в каждом протестированном размере пакета. Мы оценили его по сравнению с многопоточными (MT) и многопроцессорными (MP) Python-исполнителями с параллельными данными. По сравнению с базовой линией MP Rust-исполнитель полностью устраняет накладные расходы интерпретатора Python. По сравнению с базовой линией MT он дополнительно смягчает сериализацию блокировки глобального интерпретатора (GIL), так что вызовы диспетчера от параллельных рабочих потоков больше не конкурируют в одном процессе. Эти достижения имеют значение, поскольку Nova-3 выполняет последовательность небольших вызовов декодера для каждого аудиочака, что делает диспетчеризацию на стороне хоста узким местом при низких размерах пакета. Таким образом, улучшение пропускной способности является наибольшим в этом случае и остается значимым даже при максимальном размере пакета. Здесь Rust-исполнитель обеспечил 7.5% увеличение пропускной способности по сравнению с базовой линией многопроцессорного Python. Мы измерили соотношение цена-производительность как аудио, обработанное за доллар. На оффлайн пакетных рабочих нагрузках Deepgram установка Trainium2 на одном устройстве (trn2.3xlarge) обрабатывала на 11–70 процентов больше аудио за доллар по сравнению с вычислительными опциями, которые использовал Deepgram ранее. В заключение, в этом посте мы продемонстрировали, как Deepgram и AWS FDE перенесли модель Nova-3 для преобразования речи в текст на аппаратное обеспечение Trainium с использованием TorchNeuron, который обеспечивает нативную интеграцию фреймворка PyTorch для AWS Trainium. Мы улучшили производительность, заменив слои непосредственно на предварительно собранные ядра из NKILib. Затем мы оценили производительность с помощью Neuron Explorer и использовали навыки профилирования Neuron Agentic Development (NAD), чтобы запросить данные профилирования и ускорить устранение неполадок производительности. Основываясь на этих выводах, мы адаптировали исходный код ядра с использованием навыков написания ядер NAD. Наконец, мы построили легковесный Rust-исполнитель для AWS Trainium, вызывая API Neuron Runtime из Rust. Наша настройка продемонстрировала экономию затрат в оффлайн сценариях, ориентированных на пропускную способность, подтверждая AWS Trainium как жизнеспособный и эффективный вариант для рабочих нагрузок вывода Deepgram. Материал подготовлен нейросетью на основе оригинальной публикации. ИИ может ошибаться в деталях (цифры, имена, даты, цитаты) — для важной информации сверяйтесь с первоисточником.