Программное обеспечение поглощает мир, а агенты поглощают разработку программного обеспечения. Для инженеров-программистов крайне важно развивать понимание не только агентного ПО, которое стало их важнейшим инструментом, но и того, как работает интеллектуальное ядро такого ПО посредством инференса (вывода) больших генеративных языковых моделей — если не из потребности инженера понимать и контролировать свои инструменты, то хотя бы потому, что инференс готов потреблять больше вычислительной мощности и приносить больше пользы, чем все остальные способы использования компьютеров.
Главный факт об инференс-сервисах для кодинг-агентов заключается в том, что они должны работать с чрезвычайно высокой относительной и абсолютной производительностью.
Под относительной производительностью мы понимаем большую долю от пиковой скорости или «скорости света» используемого оборудования. Под абсолютной производительностью мы понимаем, что масштаб этой пиковой скорости и объем работы, выполняемой на один запрос, очень велики. Современные ускорители матричных вычислений, такие как Tensor Cores, работают на уровне петафлопс в секунду. Большие генеративные последовательные модели, обладающие достаточным интеллектом для автоматизации разработки ПО, имеют триллионы параметров с плавающей запятой, и к каждому из них необходимо обращаться много раз в секунду, даже при обслуживании всего одного запроса.
Из-за этих требований экономически жизнеспособные инференс-сервисы для кодинг-агентов в настоящее время возможны только при работе в масштабе, достаточном для амортизации затрат на оборудование и инженерию — примерно на уровне триллионов входных и выходных токенов.
Мы сделали это и хотим поделиться тем, как именно.
В Modal мы управляем рядом таких инференс-сервисов для кодинг-агентов в этом масштабе и работаем с рядом клиентов, которые делают то же самое. Вы можете использовать наши сервисы косвенно через платформы маршрутизации инференса, такие как OpenRouter или Vercel AI Gateway, или напрямую через наши Shared Endpoints.
В этом блог-посте мы расскажем, как мы оптимизировали производительность инференса при обслуживании выводов модели Moonshot AI’s Kimi K2.6 для обеспечения работы кодинг-агентов. Хотя эта модель «старая» по меркам данной области (ей буквально сотни дней!), основы моделирования последовательностей, аппаратного обеспечения и масштабирования меняются достаточно медленно, чтобы основная история и многие детали соответствовали тому, что мы сделали для более новых моделей, которые превзошли K2.6 по интеллекту и соотношению цена-производительность, таких как Kimi K3.
Наши оптимизации позволили нам масштабировать производительность инференса на одну реплику в 2,8 раза на пользователя и в 5,6 раза в расчете на всех пользователей реплики:
Этот график соотносит опыт отдельного пользователя (декодирование токенов в секунду на пользователя, то есть интерактивность) по оси X с соотношением цена-производительность всей системы по оси Y (общее количество токенов в минуту на GPU, то есть пропускная способность токенов), при этом количество одновременных пользователей указано в каждой точке.
Если говорить проще, это разница между разорительно дорогим сервисом с UX, показанным справа внизу, и конкурентоспособным по цене сервисом с UX слева:
Затем мы масштабировали эти одноконтейнерные реплики в развертывания и сервисы. Один конкретный сервис обрабатывал сотни миллиардов токенов в день и триллионы в совокупности:
Ниже мы постараемся сделать эту инженерную производительность понятной для широкой аудитории инженеров-программистов. Делясь тем, как мы и наши клиенты можем управлять этими сервисами, мы надеемся, что это позволит вам сделать то же самое — возможно, развернув Dedicated Endpoint на Modal.
Во-первых, поймите рабочую нагрузку.
Мы разбиваем это на два раздела: понимание модели последовательностей, которая выводит ответ на каждый запрос, и понимание структуры рабочей нагрузки по запросам.
Современные кодинг-агенты поддерживаются нейронными моделями последовательностей с триллионами параметров, которые обрабатывают входные данные параллельно и выводят данные последовательно.
Современные кодинг-агенты работают на базе вероятностных генеративных моделей последовательностей Unicode, предварительно обученных в основном с помощью обучения без учителя на предсказании маскированных последовательностей и дообученных в основном путем подкрепления корректности выходного программного кода. Подобно парсеру компилятора, они работают не с «сырыми» строками, а с токенизированными последовательностями, поэтому мы называем их входные и выходные данные токенами. Поскольку мы, в конечном счете, угадываем, какими должны быть выходные токены, это называется инференсом. Если вы предпочитаете дедукцию, оставайтесь с базами данных и операционными системами.
Базовые модели последовательностей в наши дни — это нейронные сети Transformer с гибридным вниманием и смесью экспертов (Mixture-of-Experts). Эти сети применяют вычисления как для каждого токена в последовательности, так и между токенами в последовательности.
Внимание (Attention) превратилось в общий термин для вычислений между токенами. Смесь экспертов относится к динамически маршрутизируемому блочно-разреженному матричному умножению, которое выполняет большую часть вычислений для каждого токена. Эти вычисления итеративно обновляют внутреннее, или латентное, представление сети.
Для понимания того, что происходит внутри этих моделей последовательностей, см. статью Anthropic «Математическая основа для схем Transformer» (2021 год, но до сих пор актуальна).
Один прямой проход через такую нейронную сеть создает как значительное внутреннее состояние, так и распределение вероятностей для следующего токена (или токенов) в последовательности для каждой позиции. Поскольку мы предсказываем (”regress”) на основе наших собственных выходных данных («авто»), это авторегрессионное моделирование последовательностей.
Чтобы ответить на запрос клиента, мы обычно связываем несколько прямых проходов вместе следующим образом:
Прямые проходы стоят дорого, поэтому мы хотим максимально амортизировать эту работу. Большая часть работы при вычислениях для каждого токена амортизируется за счет пакетной обработки нескольких последовательностей вместе. Большая часть работы при вычислениях между токенами амортизируется за счет кэширования внутреннего состояния. По историческим причинам это называется кэшем ключей-значений (KV-кэш или просто KV), хотя современные модели, такие как Kimi, не имеют отдельных ключей и значений. Вы можете прочитать больше о «вычислениях на салфетке» в отличном блог-посте Kipply «Арифметика инференса Transformer» (2022 год, но до сих пор актуальна).
Когда прямой проход обрабатывает входные токены запроса, мы называем это префиллом (prefill), потому что он «предварительно заполняет» KV-кэш. Когда прямой проход создает выходные токены ответа, мы называем это декодированием (decode), потому что мы «декодируем» «кодирование» моделью прошлого состояния в предсказанное будущее. А как насчет прямых проходов, которые делают и то, и другое? Да, нам тоже не нравится эта терминология.
Производительность префилла в основном отслеживается по задержке завершения всех префиллов для запроса, также известной как время до первого токена (TTFT). Производительность декодирования в основном измеряется скоростью, с которой после этого создаются выходные токены, также известной как выходные токены в секунду (TPS). И то, и другое можно измерять на стороне клиента или на стороне сервера, что вызывает бесконечную путаницу.
Конкретная модель последовательностей, рассматриваемая в этом посте, — это от Moonshot AI. Эта модель параметризует свои матричные умножения примерно одним триллионом чисел (весов в своих матрицах), большинство из которых хранятся как четырехбитные целые числа (INT4).
Тем не менее, мы обслуживаем модель с использованием 4-битных чисел с плавающей запятой (FP4). Четыре бита дают всего шестнадцать различных значений, поэтому вам дополнительно требуется формат микромасштабирования для независимого масштабирования отдельных блоков внутри тензоров. Мы выбрали формат микромасштабирования NVFP4, который имеет аппаратную поддержку на уровне petaFLOP/s в тензорных ядрах графических процессоров с архитектурой Blackwell Streaming Multiprocessor, таких как B200 и B300. Поскольку мы управляем динамическим парком GPU во время ограниченных поставок вычислительных мощностей, мы готовим наше развертывание для работы как на GPU B200, так и на B300. Приведенные ниже результаты относятся ко всем GPU B200; B300 по сути аналогичны, но работают при более высокой параллельности запросов, поскольку имеют больше доступной памяти с высокой пропускной способностью (HBM) для кэширования.
В качестве основы мы выбрали движок логического вывода SGLang. Мы обнаружили несколько возможностей для повышения производительности путем внесения исправлений в движок. Как участники проекта SGLang, мы добавили эти исправления в основную ветку, описание и ссылки на которые приведены в посте ниже.
Чтобы оптимизировать UX и соотношение цены и производительности, необходимо понимать структуру этих последовательностей в разных запросах.
Когда вы обслуживаете такие модели для трафика агентов кодирования наивным способом, вы получаете плохие результаты.
Этот график показывает, что пропускная способность и интерактивность быстро падают при количестве одновременных пользователей более 6. Более того, даже до достижения этого пика интерактивность ниже ожиданий пользователей, а система работает с недостаточной эффективностью.
Поэтому отсюда вам нужно повысить интерактивность и пропускную способность, чтобы обеспечить лучшие результаты для пользователей, одновременно снижая собственные затраты. Для этого вам нужно понимать последовательности в этой рабочей нагрузке глубже, чем просто «входящие и исходящие токены».
Индивидуальные запросы на выходные токены создаются в «сессиях»: пользователь, генеративная модель и вызовы инструментов итеративно объединяются для построения башни входных последовательностей, накапливая контекст — и ценность — с течением времени. Итеративный процесс построения смысла, обнаружения информации и осмысления кажется нам фундаментальным для природы моделирования последовательностей и последовательных действий, поэтому мы ожидаем, что этот паттерн просуществует гораздо дольше, чем «агенты кодирования».
Конкретно, отдельная сессия выглядит примерно так:
То есть входная последовательность (зеленая) для каждого шага T — это вся история сессии до T (темно-зеленая), плюс что-то новое (светло-зеленая). Это имеет два ключевых последствия.
Во-первых, это означает, что запросы по своей сути имеют длинные входные последовательности по сравнению с их выходными последовательностями (розовые, выше) — в составе входных данных для шага T есть T-1 прошлых выходных последовательностей, а T исчисляется десятками. Для основной рабочей нагрузки, которую мы использовали при оптимизации и обслуживании в продакшене, это соотношение составляло 200:1; запросы содержат примерно 100 тыс. входных токенов и производят примерно 500 выходных токенов. Это означает, что большинство обработанных токенов будут входными токенами (просто проверьте количество используемых токенов в вашем программном обеспечении для агентов кодирования).
Во-вторых, это означает, что входные последовательности имеют высокое перекрытие с ранее обработанными входными последовательностями — теми, что были на шагах с 1 по T-1. Это означает, что на пути к обслуживанию шага T токены шага 1 обрабатываются T раз. Это делает кэширование абсолютно критичным — мы можем избежать линейно масштабируемых повторных вычислений, чтобы сэкономить усилия, но мы вводим линейно масштабируемое состояние, которым необходимо управлять и которое имеет свои собственные характеристики производительности. Навигация по этому компромиссу — основная инженерная задача, которую мы решим в этом посте.
Имея в виду эту картину рабочей нагрузки, мы переходим к оптимизации.
Затем оптимизируйте один реплику.
Чтобы оптимизировать производительность, создайте рабочую систему, определите узкое место, а затем устраните его. Повторяйте по мере необходимости, пока не добьетесь успеха.
Хотя нашей конечной целью была оптимизация всего сервиса, мы разбили эту проблему на две более простые: сначала оптимизировать одну реплику, а затем масштабировать от одной до многих реплик.
Мы дополнительно разделили проблему производительности одной реплики на две подзадачи: сначала максимизировать интерактивность, затем максимизировать пропускную способность без потери интерактивности.
Интерактивность в первую очередь влияет на задержку запроса. Задержка запроса и пропускная способность взаимодействуют через параллелизм, количество выполняемых запросов, путем перестановки закона Литтла:
Наши ключевые узкие места для задержки, параллелизма и пропускной способности начались в HBM графического процессора.
Нашим ключевым узким местом по задержке была пропускная способность HBM во время декодирования. Мы устранили его путем распараллеливания матричного умножения между GPU (тензорный параллелизм, TP) и путем применения пользовательского спекулятивного декодирования — выполняя больше вычислений на одну загрузку памяти, даже если эти вычисления могут не потребоваться.
Это создало узкое место для параллелизма из-за емкости HBM: сколько работы мы можем удержать в кэше, который загружается быстрее, чем мы могли бы просто пересчитать результаты. Мы устранили это путем очистки промежуточных данных в HBM, квантования промежуточных данных до более низкой точности с плавающей запятой и расширения иерархии кэша до оперативной памяти CPU с помощью HiCache. Мы использовали коэффициент попаданий в кэш (CHR) в качестве целевого показателя улучшений кэширования. CHR от 90% до 99% вполне достижимы для большинства рабочих нагрузок агентов кодирования.
Мы начали с максимизации интерактивности.
Повышение интерактивности увеличивает производительность системы, наблюдаемую отдельными пользователями. Мы решили работать над этим в первую очередь. Мы сделали этот выбор по нескольким причинам.
Во-первых, и это самое простое, мы обнаружили, что пользователям агентов кодирования нравится, и они готовы платить больше за токены, которые приходят к ним быстрее, поэтому высокая интерактивность была ключом к созданию сервиса, который хотели наши пользователи и пользователи наших клиентов.
Во-вторых, интерактивность особенно хорошо поддается улучшению с помощью спекулятивного декодирования. Поскольку это простой метод, основанный на обучении, его преимущества в производительности масштабируются вместе с вычислениями и данными: знаменитый «горький урок» машинного обучения, возвращающийся в инженерии производительности для систем машинного обучения. И мы знаем, как масштабировать обучение.
Этот выбор в пользу максимальной интерактивности имел два дополнительных преимущества, одно операционное, а другое для пропускной способности, которые были особенно важны, поскольку мы управляем динамическим, автоматически масштабируемым парком из тысяч графических процессоров.
Реплики с максимальной интерактивностью меньше и, следовательно, их легче обслуживать.
Использование нескольких процессоров вместе требует сети межсоединений (interconnect) для связи. Самым низким уровнем задержки и самой высокой пропускной способностью межсоединения для графических процессоров Nvidia является NVLink. NVLink работает в группе процессоров в «домене» определенного размера.
Одна хост-операционная система может поддерживать домен NVLink до 8 графических процессоров. Крупнейшие домены NVLink, которые обычно доступны, включают 72 ускорителя (в многоузловом домене IMEX). Использование большего количества ускорителей потребовало бы более медленного межсоединения (IB/RoCE или, что еще хуже, стандартного Ethernet). Это означает, что для максимальной интерактивности нам не следует рассчитывать на использование более 72 ускорителей на реплику — накладные расходы на связь почти наверняка перевесят любые выигрыши в задержке на запрос.
Но это не значит, что мы должны использовать 72 ускорителя.
Рассмотрите эти результаты из SemiAnalysis’s InferenceX benchmarks for this same NVFP4 Kimi K2.6 model, которые показывают пропускную способность на GPU как функцию интерактивности, с аннотациями по количеству GPU для различных развертываний:
Наивысшая интерактивность достигается при развертывании всего с восемью графическими процессорами на реплику. Более того, такая интерактивность достигается при сопоставимой пропускной способности на один GPU, что означает, что, выбирая меньший домен, мы явно не жертвуем стоимостной эффективностью пиковой пропускной способности (с учетом нашего ограничения по интерактивности).
Чтобы диаграмма оставалась читаемой, мы выбрали лишь небольшую подгруппу развертываний, наиболее похожих на наши, но эта закономерность сохраняется для большего количества типов ускорителей и большего количества моделей в тестах InferenceX (ознакомьтесь с ними ). Как правило, вы можете достичь наивысшей интерактивности при сопоставимой пропускной способности на GPU, используя всего четыре или восемь графических процессоров. Затем вы можете достичь той же совокупной пропускной способности путем масштабирования меньших реплик. Основная бессерверная платформа Modal делает такое масштабирование производительным и надежным.
Это огромная операционная победа. Меньшие и более простые единицы облегчают масштабирование. Восемь GPU могут управляться одним ядром ОС хоста. Домен NVL72, с другой стороны, состоит из девяти таких подсистем, совместно использующих адресное пространство (да, от этого стоит содрогнуться). Доступность ограничена, а контракты — длительные и негибкие.
Системы Blackwell с восемью GPU, напротив, достаточно стандартны, чтобы быть доступными на рынках по требованию и спотовых рынках, что делает обработку переменной нагрузки гораздо более экономически эффективной. Реплики с одним, двумя или четырьмя GPU, кроме того, могут быть размещены внутри одной физической машины с восемью GPU, в которой уже есть все ресурсы, необходимые для запуска еще одной реплики (веса модели, JIT-артефакты).
Конечно, если предложение вычислительных мощностей и запросы пользователей изменятся, мы с радостью пересмотрим этот выбор.
Повышение интерактивности косвенно увеличивает пропускную способность.
Сокращая задержку отдельных запросов, мы косвенно улучшаем пропускную способность, высвобождая ресурсы для новых запросов.
Рабочие нагрузки агентного кодирования являются приблизительно «замкнутыми» для каждой сессии. Сессии почти всегда представляют собой цепочки — из токенов, написанных пользователем, ответов на вызовы инструментов и выходных данных модели. Поэтому следующий запрос в сессии почти всегда поступает через некоторое время после того, как завершилась генерация предыдущего ответа. Таким образом, следующий запрос сессии некоторое время находится в состоянии ожидания вне системы вывода — для вызовов инструментов это от десятков миллисекунд до секунд с «хвостом» в минуты; для ответов пользователя — от секунд до минут с «хвостом» в часы или более.
В течение этого времени другие запросы могут обрабатываться на том же узле. Когда у вас достаточно нагрузки для активной емкости, всегда есть запросы, готовые к обработке узлом. Когда у вас достаточно емкости для активной нагрузки, всегда есть узлы, на которые можно направить запросы. И то, и другое гарантируется нашей системой быстрого автоматического масштабирования. Мы подробнее поговорим о маршрутизации запросов в разделе о масштабировании до нескольких реплик.
Используйте настраиваемое спекулятивное декодирование, чтобы выполнять больше работы каждый раз, когда вы сталкиваетесь с «узким местом» в интерактивности.
Интерактивность измеряет количество выходных токенов в секунду на пользователя. Наивно полагать, что авторегрессионные последовательные модели, такие как Transformers, производят эти токены последовательно. Душераздирающий закон Амдала наносит удар снова.
Каждый раз, когда создается токен, гигабайты или более весов модели и KV-кэша должны быть загружены из HBM графического процессора в L1-кэши потоковых мультипроцессоров, что обычно занимает больше времени, чем фактическое вычисление KV-состояния и вывода для одного следующего токена. Это создает «узкое место» в пропускной способности памяти. Параллелизм помогает создать большую пропускную способность, но это более полезно для вычислений на один токен, чем для межтокеновых вычислений, которые возникают как «узкое место» для длинных последовательностей, как это наблюдается в рабочих нагрузках кодирующих агентов.
Поэтому мы устранили это «узкое место», применив спекулятивное декодирование.
По сути, спекулятивное декодирование делает тот же выбор, что и спекулятивное выполнение в процессорах: когда у вас есть свободная операционная пропускная способность из-за последовательных зависимостей между операциями, вы можете использовать эту пропускную способность для выполнения операций, которые в итоге могут не понадобиться. Эффективная операционная пропускная способность увеличивается, если вы можете угадать операции, которые будут использованы с высокой вероятностью, и вся суть заключается в повышении этой вероятности с наименьшими затратами усилий.
Для вывода авторегрессионных последовательных моделей «трюк» для выполнения большего количества операций за итерацию заключается в том, чтобы угадать, какими будут следующие несколько токенов, используя другую, более быструю языковую модель («спекулянт» или «черновик»), а затем проверить догадки параллельно с обслуживаемой моделью («целевой» или «верификатор»).
Как и в случае со спекулятивным выполнением, это ускорение происходит без изменения поведения программы, то есть распределения вероятностей целевой модели последовательности.
Как мы описываем в нашем блоге, посвященном выпуску спекулянтов для семейства моделей Qwen 3.5 и 3.6, выигрыш от спекулятивного декодирования огромен — это целые коэффициенты, а не несколько десятков процентов.
Как ни странно, довольно легко создать спекулянт, который в среднем предсказывает четыре, восемь или даже больше следующих токенов в выводе, особенно для рабочих нагрузок кодирующих агентов. Грубо говоря, для этого есть две причины: целевая модель создает условия для успеха спекулянтов, а большинство токенов не используют весь интеллект целевой модели.
Во-первых, целевая языковая модель уже создала чрезвычайно полезные представления последовательности во время своих прямых проходов — начиная со статического встраивания каждого токена, каждый слой модели постепенно обогащает это представление, вплоть до последнего слоя «головы языкового моделирования», который превращает это представление в распределение вероятностей следующих токенов. Более того, эти представления уже хранятся в KV-кэше. Современные архитектуры спекулянтов, такие как (и производные, такие как DSpark), повторно используют это состояние в качестве входных данных, поэтому они могут быть на порядки меньше (и быстрее), чем целевая модель: стоя на плечах гигантов, они указывают, куда те могут направиться дальше.
Рассмотрим следующий пример вывода кодирующего агента:
Любой, кто использовал последние модели, может дать вам хорошую догадку о том, что идет после You’re absolutely (это никогда не бывает неправильно). А цитата взята из предыдущего ввода пользователя, поэтому, как только кавычка открывается, следующие токены становятся очень предсказуемыми.
Заглянув на уровень глубже, рассмотрим, как выглядит эта последовательность после того, как она была отформатирована специальными управляющими токенами в «шаблоне чата» модели:
Эта последовательность имеет существенную структуру, для создания которой не требуется высокий интеллект. Конечно, детали внутри этой структуры все еще важны для правильности, поэтому возможности целевой модели по-прежнему важны!
Таким образом, большая часть мощности целевой модели, вероятно, уходит на обогащение представлений этих токенов для использования при предсказании токенов на много шагов вперед. Если вы уже знаете, какими будут следующие несколько токенов, вы можете вычислить их представления параллельно.
Это не причуда и не хак: обеспечение двойного параллельного и последовательного прямого прохода является фундаментальной особенностью современных моделей последовательностей по сравнению с традиционными рекуррентными нейронными сетями. Она присутствует как в «классических» трансформерах, так и в линейных/гибридных моделях внимания, поэтому можно ожидать, что она сохранится и в дальнейшем.
По этой и другим причинам мы вложили значительные средства в спекулятивное декодирование и советуем вам сделать то же самое.
Самые быстрые спекуляторы обучаются не просто предсказывать общее поведение целевой модели, а предсказывать её поведение на конкретных наборах данных. Поскольку они небольшие, их моделирующая способность ограничена, и вы хотите использовать эту способность только для того, что действительно будет происходить в продакшене. Для специалистов по машинному обучению: функция потерь для спекулятора — это дивергенция Кульбака-Лейблера от целевой модели, что поощряет поиск моды, а не покрытие моды.
Но, как и в случае с нейронными сетями в целом, наши эксперименты показали, что лучше начинать с прочного фундамента, а затем адаптировать спекулятор к конкретной задаче — так называемая дообучение (fine-tuning). Поэтому мы сначала обучили спекулятор DFlash для Kimi K2.6 на общей смеси данных, а затем дообучили его на трассах кодирования, которые были выведены целевой моделью. Черновую модель затем можно постоянно дообучать на выходных данных целевой модели при обслуживании производственного трафика.
Мы столкнулись с одной проблемой при работе с «живым» трафиком: отображение токенов в строку, а затем повторная токенизация не является тождественным преобразованием, потому что токенизация по своей сути — это проклятый хак. Но типичное логирование, например HTTP-запросов, работает со строками, а не с токенами. Поэтому мы пропатчили SGLang, чтобы он выдавал необработанные идентификаторы токенов через sglext, и внесли этот вклад в основную ветку проекта.
Дообучение дало нам увеличение длины принятия с 5,00 до 5,84 токенов на шаг на репрезентативных трассах, что обеспечило прирост скорости на 20%.
Тензорный параллелизм оказался лучшей стратегией параллелизма для максимальной интерактивности.
Добавление большего количества инженеров к медленной задаче заставляет её занимать больше времени, но у компьютеров нет такой слабости — если правильно распараллелить работу и шардировать данные.
Основные стратегии параллелизма для вывода моделей последовательностей разделяют работу:
- в рамках одного запроса, между прямыми проходами модели (дезагрегация префилла и декодирования),
- в рамках одного прямого прохода модели, между слоями (конвейерный параллелизм),
- в рамках пакета запросов, между последовательностями (параллелизм данных),
- в рамках одной последовательности, между токенами (контекстный параллелизм),
- в рамках слоя модели, между матричными умножениями (экспертный параллелизм), и
- в рамках матричного умножения, между строками/столбцами (тензорный параллелизм).
Из этих вариантов только контекстный параллелизм, экспертный параллелизм и тензорный параллелизм разделяют работу в рамках одного запроса и, следовательно, напрямую улучшают интерактивность. Тензорный параллелизм (TP) — это самый низкий уровень распараллеливания, не считая параллелизма внутри выполнения ядер, который огромен, но выходит за рамки данной темы (мы делились некоторыми нашими наработками по этому поводу в других местах). Это означает, что оптимизации TP лучше сочетаются с другими стратегиями и поэтому являются хорошей первой целью.
Подробнее: тензорный параллелизм берет входные данные для матричного умножения и распределяет работу по обработке выходных данных между параллельными воркерами, которые, таким образом, могут шардировать матричные данные, необходимые для этой обработки, то есть веса модели. Подробнее см. статью Megatron (2019 год, но всё ещё актуальна).
Однако выбор TP4 оставил нас в очень жестких рамках по объему KV-кэша.










