Глубокое погружение в масштабный инференс LLM — Харшул Джайн (Audible) и Танмай Сах (Независимый исследователь ИИ)
AAI Engineer
컴퓨터/소프트웨어경제 뉴스AI/미래기술
스크립트
00:00:00Итак, всем добрый день. Меня зовут Харшал Джайн, а это Танмиш. И мы
00:00:21хотели бы поприветствовать всех на этом двухчасовом воркшопе по инференсу LLM.
00:00:26Цель этого воркшопа — понять эту область с базовых
00:00:33принципов, погрузиться в нее глубже и разобраться, что происходит во всей
00:00:39индустрии. Немного предыстории о нас. Я старший разработчик ПО в
00:00:47Audible. Последние пять лет я занимаюсь созданием платформ данных ML/AI, а
00:00:53помимо этого пишу открытое руководство по инференсу LLM. И
00:00:59Танмай — старший специалист по количественному моделированию в Xi'an's Bank Corporation. Он
00:01:06недавно защитил докторскую и ведет активные исследования в области агентных
00:01:12верификаторов и моделей мира. Давайте быстро поднимем руки. Кто здесь впервые сталкивается с инференсом LLM?
00:01:24Хорошо, отлично. А кто уже развертывал такие модели в продакшене? Кто
00:01:33занимался их тюнингом и обслуживанием продакшн-трафика? Отлично. Этот
00:01:42воркшоп рассчитан на начинающих и тех, кто уже имеет средний уровень. Все
00:01:48слайды и упражнения находятся в репозитории, я скоро им поделюсь. Вот краткая
00:01:56повестка дня нашего воркшопа. Мы начнем с постановки проблемы. Попробуем
00:02:01понять основные болевые точки, связанные с инференсом LLM. Затем разберем причины
00:02:08возникновения этих проблем и выстроим фундамент. После этого мы перейдем к двум
00:02:14видам оптимизации: оптимизации самих моделей и оптимизации
00:02:19сервиинга. Затем мы познакомимся с различными серверами для инференса,
00:02:25которые доступны для развертывания решений LLM в продакшене. Покажем результаты
00:02:32бенчмарков и схему принятия решений о том, какой движок выбрать.
00:02:39Отлично. Чтобы понять болевые точки, сначала нужно узнать, что такое инференс LLM. Ну,
00:02:47многие из нас, наверное, уже знают это. Но в общем, всё, что вы просите сделать ваш ИИ,
00:02:55будь то генерация видео, аудио, анализ текста, медицинских отчетов или
00:03:02налоговых счетов, всё это представляет собой инференс LLM. И сегодня этот рынок оценивается примерно в 23 миллиарда долларов.
00:03:12Недавно в Semi-analysis сообщили, что если обрабатывать поисковые запросы Google с помощью LLM, потребуется колоссальная сумма в 36 миллиардов долларов.
00:03:25При этом стоимость одного запроса должна быть меньше 0,5 цента, чтобы поисковый бизнес оставался прибыльным.
00:03:33С другой стороны, Business Insider отмечает, что ИИ нужно внедрять грамотно, и каждому придется начать аудит и учет использования токенов.
00:03:43И всё это происходит почему? Потому что аппаратные ресурсы ограничены, вычисления обходятся дорого, а инференс дорог.
00:03:50И по мере роста потребности в использовании ИИ стоимость этого инференса растет всё больше и больше.
00:04:03Эта статистика старая, от OpenAI, но она все еще актуальна.
00:04:11Если посмотреть на затраты на обучение GPT-3, они составили около 4,6 миллиона долларов. Это были разовые расходы.
00:04:19Но если вы посмотрите на расходы на инференс, они носят постоянный характер, поскольку это операционные затраты, которые масштабируются с каждым новым пользователем, с каждым токеном и с каждой сессией, запускаемой в ИИ.
00:04:36И с этим можно бороться лишь двумя способами. Первый способ — сократить использование токенов.
00:04:47Альтернатива — попытаться оптимизировать решения для инференса как поставщик услуг инференса для ваших клиентов и для себя самого.
00:04:58И из-за этого мы видим, как постоянно появляется всё больше и больше новых решений.
00:05:06Поэтому идея заключается в том, чтобы заложить те основы, которые помогут нам понимать и оценивать любые новинки.
00:05:18Итак, для начала мы проведем короткую демонстрацию различных болевых точек, связанных с инференсом.
00:05:28У нас есть репозиторий.
00:05:31Вы можете клонировать его или открыть прямо на GitHub.
00:05:36Он называется «LLM inference at scale».
00:05:39Немного предыстории: около четырех месяцев назад, когда я ничего не знал об инференсе LLM, я начал его изучать.
00:05:46Я заметил, что множество ресурсов разбросано повсюду.
00:05:49Поэтому мы начали собирать всё вместе в одном месте, чтобы это принесло пользу людям.
00:05:55Давайте я выйду из режима слайд-шоу и перейду в расширенный режим.
00:06:11Да, в этом репозитории, если вы посмотрите на файл README, там есть ссылка на слайды.
00:06:27Это будет папка, где лежит файл PPTX и отчет по бенчмаркам.
00:06:34Вы всегда можете скачать их, а для демонстрации у нас есть пара блокнотов Jupyter.
00:06:43Мы сотрудничаем с Molab, альтернативой Google Colab, которая предоставляет бесплатный графический процессор RTX 6000.
00:06:54Это видеокарта со 100 ГБ оперативной памяти, и мы уже настроили эти блокноты, чтобы вам было удобно экспериментировать, а все ресурсы и настройки уже подготовлены заранее.
00:07:09Мы начнем с простой демонстрации А.
00:07:16Пожалуй, сейчас я посмотрю.
00:07:31Да, когда дело доходит до инференса, вам нужно запустить его на определенной модели, верно?
00:07:40Поэтому для нашего воркшопа мы используем простую модель Mistral 7B.
00:07:45Это небольшая модель размером около 15 ГБ.
00:07:49Мы собираемся загрузить ее в графический процессор.
00:07:53И также посмотрим на некоторые характеристики GPU.
00:07:58Видим, что мы работаем на 6000 Blackwell.
00:08:01И вы можете подумать, что я не запускаю ячейки, потому что не доверяю конференции по Wi-Fi.
00:08:08Да, поэтому я просто пройдусь по результатам, которые мы получили ранее.
00:08:18У нас есть GPU с объемом памяти 102 ГБ.
00:08:22Теперь первое, что приходит мне в голову: как выглядит потребление памяти при выполнении инференса LLM?
00:08:31Я загружаю эту модель и вижу: так, здесь занято 15 ГБ.
00:08:37То есть у меня остается примерно 87,5 ГБ.
00:08:40И теперь, когда я делаю инференс, я замечаю, что чем больше входных данных я передаю, тем больше памяти мне требуется.
00:08:52Она растет медленно, но все же растет.
00:08:56Представьте, если длина контекста составляет около 4 000, 16 000 или 32 000 токенов.
00:09:03В таком случае объем памяти может значительно увеличиться, и вы можете столкнуться с проблемами нехватки памяти (OOM).
00:09:12Безусловно, это ваша первая проблема — рост памяти с увеличением количества токенов.
00:09:18В виде простой визуализации это выглядит следующим образом.
00:09:24Вторая проблема, с которой вы столкнетесь, — время генерации первого токена очень, очень велико.
00:09:32Мы измеряем это метрикой под названием TTFT.
00:09:35Это сокращение.
00:09:37И когда вы пытаетесь измерить TTFT в зависимости от размера входа, вы увидите, что чем длиннее контекст, тем выше задержка TTFT.
00:09:52Итак, у нас есть две проблемы.
00:09:54Память растет вместе с размером токенов.
00:09:56TTFT увеличивается вместе с размером токенов.
00:09:59Правда, не токенов, а контекста.
00:10:07И третье — это пропускная способность.
00:10:09Пропускная способность — это то, сколько токенов вы можете обслужить в секунду.
00:10:13И сколько пользователей вы можете обслужить в секунду.
00:10:16Если вы возьмете самую простую, ванильную реализацию на своей локальной машине, она будет работать очень последовательно.
00:10:24Поэтому, если вы отправите пять запросов, все они будут обрабатываться последовательно, а не параллельно.
00:10:31И из-за этого выполнение вашего запроса занимает больше времени, если у вас много пользователей.
00:10:40Вот эти три проблемы.
00:10:43Есть и четвертая.
00:10:44Я здесь о ней не рассказывал.
00:10:45Наверное, мы придем к этому пониманию по мере продвижения вперед.
00:10:48Но давайте запомним эти три проблемы: память, TTFT и пропускная способность.
00:10:55Отлично.
00:10:56Я вернусь к слайдам.
00:11:02Хорошо.
00:11:03Идеально.
00:11:04Так что должно быть это.
00:11:17Видно?
00:11:18Да.
00:11:19Видно.
00:11:20Видно.
00:11:21Да.
00:11:22Видно.
00:11:23Видно.
00:11:24Видно.
00:11:25Да.
00:11:26Видно.
00:11:27Видно.
00:11:28Да.
00:11:29Видно.
00:11:30Да.
00:11:31Видно.
00:11:32Да.
00:11:33Видно.
00:11:34Да.
00:11:35Видно.
00:11:36Видно.
00:11:37Да.
00:11:38Видно.
00:11:39Да.
00:11:40Видно.
00:11:41Да.
00:11:42Видно.
00:11:43Да.
00:11:44Видно.
00:11:45Да.
00:11:46Да.
00:11:47Итак, в этом репозитории, если вы посмотрите на папку воркшопа, то увидите файл README, а в самом README
00:11:55содержатся все ссылки, слайды и демоверсии.
00:12:01Это работает?
00:12:06Хорошо.
00:12:07Идеально.
00:12:09Хорошо.
00:12:10Идеально.
00:12:16Хорошо.
00:12:17Давайте начнем разбираться с основами.
00:12:19Давайте начнем понимать причины, стоящие за этими болевыми точками.
00:12:25И для этого нам нужно взглянуть на этот пайплайн инференса.
00:12:32Итак, у нас есть входной текст.
00:12:35В этом тексте может быть любое количество слов.
00:12:38Вы преобразуете их в токены.
00:12:41Для простоты можно считать, что одно слово равно одному токену.
00:12:46Затем вы преобразуете их в эмбеддинги и отправляете в трансформеры.
00:12:53Там 32 слоя трансформера, но это специфично для Mistral 7.
00:12:58У разных моделей разное количество слоев.
00:13:01И затем вы генерируете новый токен.
00:13:04И этот токен по сути возвращается на вход.
00:13:06Затем вы генерируете следующий токен, и это продолжается.
00:13:09Теперь во всей этой конвейерной обработке вы увидите, что 95% вычислений уходит на эти слои трансформера.
00:13:18Поэтому стоит посмотреть на то, что происходит внутри этого слоя трансформера.
00:13:24Внутри этого слоя трансформера есть и другие слои.
00:13:28У вас есть слой нормализации.
00:13:30У вас есть слой внимания.
00:13:32У вас есть полносвязный слой и так далее.
00:13:35И слой внимания, я думаю, стал очень и очень известным.
00:13:40Все знают работу “Attention is all you need”.
00:13:42Думаю, это всем хорошо известно.
00:13:44Итак, внимание — это наиболее ресурсоемкий слой.
00:13:48И нам нужно понять, что происходит внутри этого слоя внимания.
00:13:53Итак, что делает внимание?
00:13:56Если у вас есть входной текст, ему нужно найти оценки внимания каждого токена по отношению ко всем предыдущим токенам.
00:14:05И чтобы сделать это, ему нужно спроецировать каждый токен в пространство ключей, запросов и значений.
00:14:14Так что проще говоря, поймите вот что.
00:14:20Если у вас 10 токенов, то ему нужно 10 разных векторов запросов, ключей и значений.
00:14:26Если токенов 100, вам понадобятся 100 векторов ключей и значений.
00:14:31Если токенов 1000, вам понадобятся 1000 векторов ключей и значений.
00:14:35И таким образом количество векторов ключей и значений увеличивается с ростом размера входа.
00:14:45И если вы рассчитаете размер KV на токен для Mistral 7B, он составит 131 KV.
00:14:54Это потому, что у вас есть два вектора: K и V.
00:14:59Вам нужно умножить размер.
00:15:02Один вектор имеет размерность 128.
00:15:04Вам нужно умножить это на 32 слоя трансформера.
00:15:08И затем вам нужно умножить это на головы KV.
00:15:11Для Mistral 7b это головы KV.
00:15:15Это не 32, потому что он использует другой тип механизма внимания, о котором мы обязательно поговорим.
00:15:23Но да, размер KV на один токен составляет около 131 KV.
00:15:30Теперь представьте, что у вас контекст на 4K, тогда этот размер становится равным примерно половине гигабайта.
00:15:37Если сделать контекст на 16K, этот размер составит 2,1 ГБ.
00:15:42Теперь умножьте это на количество пользователей.
00:15:45Допустим, вы можете обслуживать нескольких пользователей одновременно.
00:15:49В то же время на этом GPU у вас может получиться 42 ГБ с контекстом 4K и 80 пользователями.
00:15:58И если ваш GPU имеет объем всего, скажем, 24 ГБ, у вас уже заканчивается память.
00:16:04Поэтому вы не можете обслуживать столько пользователей с таким контекстом.
00:16:11Чтобы визуализировать это, посмотрите на память GPU.
00:16:14В памяти GPU хранятся веса модели, которые являются довольно фиксированными.
00:16:19Это предварительно обученные веса.
00:16:21Есть также фиксированные накладные расходы.
00:16:24Они тоже меняются, но не так сильно.
00:16:29В целом можно считать их фиксированными.
00:16:32И есть оставшаяся память.
00:16:35Эта оставленная память используется вашей KV-памятью, то есть векторами ключей и значений.
00:16:41Допустим, у вас один пользователь.
00:16:46Вы можете обслуживать только такое количество векторов ключей и значений или токенов, которое помещается во всю эту оставшуюся память в 80 ГБ.
00:17:00Мы можем показать это и на простом примере.
00:17:07Хорошо, отлично.
00:17:08Хорошо, отлично.
00:17:08Дайте посмотреть, смогу ли я это запустить.
00:17:14Хорошо, отлично.
00:17:15Дайте посмотреть, смогу ли я это запустить.
00:17:15Куда это делось?
00:17:15Хорошо, отлично.
00:17:16Дайте посмотреть, смогу ли я это запустить.
00:17:21Куда это делось?
00:17:22Хорошо, отлично.
00:17:23Хорошо, отлично.
00:17:24Да.
00:17:25Да.
00:17:25Итак, вы увидите... дайте посмотреть, смогу ли я это запустить.
00:17:31Дайте посмотреть, смогу ли я это запустить.
00:17:33Дайте посмотреть, смогу ли я это запустить.
00:17:34Дайте посмотреть, смогу ли я это запустить.
00:17:35Дайте посмотреть, смогу ли я это запустить.
00:17:36Дайте посмотреть, смогу ли я это запустить.
00:17:37Хорошо, отлично.
00:17:38Да.
00:17:39Итак, вы увидите, что GPU подключен.
00:17:43Хорошо, отлично.
00:17:44Да.
00:17:45Итак, вы увидите, что GPU подключен.
00:17:56Итак, здесь мы просто пытаемся подтвердить объем памяти на основе расчетов и нашей интуиции.
00:18:13которую мы выстроили.
00:18:14Память модели составляет, скажем, если у вас 7 миллиардов параметров и вы используете
00:18:1916-битную точность,
00:18:20ваш общий объем памяти составит 14,6 ГБ.
00:18:23Вы можете проверить это с помощью математических расчетов.
00:18:27Итак, если сделать все эти расчеты, получается 14,6 ГБ.
00:18:33Теперь переходим к KV и размеру KV.
00:18:37Итак, этот размер KV составляет примерно 131 KV на токен.
00:18:42И если вы произведете эти расчеты и попытаетесь это визуализировать...
00:18:47О, конечно.
00:18:52Подождите.
00:18:53Хорошо.
00:18:54И давайте просто визуализируем это.
00:19:07Хорошо, отлично.
00:19:10Отлично.
00:19:11Да.
00:19:12Итак, это график использования памяти.
00:19:15Как видите, по мере увеличения контекста потребление памяти растет.
00:19:21Другой важный момент заключается в том, что с ростом числа пользователей память также увеличивается.
00:19:28Поэтому, если вы хотите обслуживать 160 пользователей на одном GPU, вы можете поддерживать
00:19:37лишь меньшую длину контекста.
00:19:40Всегда существует компромисс между длиной контекста, которую вы можете обслуживать, и тем, сколько затрат
00:19:47вы можете сэкономить, разместив нескольких пользователей или одновременных пользователей на одном GPU.
00:19:54Так что вам всегда приходится идти на этот компромисс.
00:19:57И мы разберем это на следующих слайдах.
00:20:06Не могли бы вы повторить, пожалуйста?
00:20:10Прошу прощения.
00:20:11Я вас не слышу.
00:20:12Видите ли вы другой пул с разной длиной контекста, чтобы можно было обслуживать нужную память
00:20:25для правильного...?
00:20:26Да.
00:20:27Круто.
00:20:28Круто.
00:20:29Хорошо.
00:20:30Хорошо.
00:20:31Итак, вернемся назад.
00:20:32Итак, это была память.
00:20:33Нам нужно понять, почему у нас было большее время до первого токена при увеличении длины контекста.
00:20:53ов.
00:20:54Для этого нам нужно понять две фазы инференса.
00:20:58Эти фазы называются фазой предварительного заполнения (pre-fill) и фазой декодирования.
00:21:01Думаю, вы все видели много статей, но мы просто хотели это объяснить.
00:21:06Итак, когда вы отправляете множество входных токенов, вы хотите построить упомянутые ключи и векторы значений для всех токенов.
00:21:20Затем вы хотите вычислить оценки внимания каждого токена по отношению к предыдущим.
00:21:27Вся эта операция очень сильно завязана на матричные вычисления.
00:21:31Это очень ресурсоемкая вычислительная операция.
00:21:34И мы все знаем, что GPU отлично подходят для тяжелых вычислительных нагрузок.
00:21:41Поэтому мы называем фазу префилла ограниченной вычислительной мощностью (compute-bound).
00:21:46И ее выполнение занимает некоторое время.
00:21:49Время, необходимое для завершения этой фазы, и есть время до первого токена (TTFT).
00:21:55Так что если у вас больше входных токенов, вам нужно генерировать больше векторов ключ-значение.
00:22:02Вам нужно выполнять гораздо больше вычислений внимания.
00:22:05И из-за этого время TTFT становится все более медленным.
00:22:12В то время как при генерации одного токена вам нужно продолжать делать это для других токенов, последовательно, один за другим.
00:22:20Но в этом процессе каждый раз приходится выстраивать векторы ключей и значений для всех предыдущих токенов, что аналогично этапу пре-филла.
00:22:30То есть вы формировали векторы ключей и значений там, и делаете это здесь.
00:22:34Но на этапе декодирования вы вычисляете матрицу внимания только для нового токена.
00:22:40И именно поэтому он требует гораздо меньше вычислительных ресурсов.
00:22:45Кроме того, его называют ограниченным по пропускной способности памяти.
00:22:48Чуть позже мы разберем, почему его так называют.
00:22:54Итак, на классической временной шкале фазы пре-филла и декодирования выглядят следующим образом.
00:22:59Время, затрачиваемое на пре-филл, — это время до получения первого токена.
00:23:03А время, затрачиваемое на каждый шаг декодирования, — это, по сути, ваша задержка между токенами.
00:23:12Это четвертая метрика, о которой вам нужно беспокоиться.
00:23:18Сколько времени уходит на шаг декодирования?
00:23:21Хорошо.
00:23:22Ладно.
00:23:23Отлично.
00:23:24Теперь почему шаг декодирования или само декодирование занимает время?
00:23:34И почему эту операцию называют ограниченной по памяти?
00:23:38Давайте попробуем разобраться в этом.
00:23:40Чтобы понять это, нам нужно посмотреть, как в общих чертах устроена работа с матрицами на GPU.
00:23:47Итак, у графического процессора есть два типа памяти.
00:23:50У вас есть память с высокой пропускной способностью.
00:23:52И у вас есть разделяемая память.
00:23:55Память с высокой пропускной способностью имеет больший объем, но меньшую скорость передачи.
00:24:01Под меньшей пропускной способностью я имею в виду, что данные из нее передаются с меньшей скоростью.
00:24:06По сравнению с разделяемой памятью: она меньше по размеру, но обладает очень и очень высокой пропускной способностью.
00:24:13Это значит, что вы можете передавать данные в нее и обратно с огромной скоростью.
00:24:19Поэтому, когда вам нужно выполнить матричные вычисления, вы должны извлекать данные кусками из памяти с высокой пропускной способностью.
00:24:27Загрузить их в разделяемую память.
00:24:30Выполнить вычисления.
00:24:32И записать результат обратно в память с высокой пропускной способностью.
00:24:38На этапе пре-филла эту матричную операцию требуется выполнить всего один раз.
00:24:46Но на этапе декодирования вам приходится делать такие вычисления снова и снова, поскольку каждый отдельный токен генерируется последовательно.
00:24:59И в результате неважно, насколько быстро идет декодирование, ведь вы можете переносить данные из основной памяти в разделяемую только с определенной скоростью.
00:25:14Потому что вы ограничены пропускной способностью основной памяти.
00:25:18И именно это определяет предел генерации токенов — с какой скоростью вы реально можете выдавать токены на этапе декодирования.
00:25:32Если посмотреть на график производительности (Roofline), то слева находится область, ограниченная пропускной способностью памяти.
00:25:42Математически она определяется арифметической интенсивностью.
00:25:47Арифметическая интенсивность — это количество операций с плавающей точкой, выполняемых на один байт передаваемых данных.
00:25:55На этапе декодирования, поскольку вы передаете много данных — например, векторы ключей и значений всех предыдущих токенов, веса модели,
00:26:08но выполняете при этом меньше вычислений, так как считаете внимание только для одного токена,
00:26:13арифметическая интенсивность оказывается очень низкой.
00:26:18А на этапе пре-филла вы передаете данные один раз, но затем выполняете огромный объем вычислений.
00:26:27Поэтому его арифметическая интенсивность очень высока.
00:26:30Теперь вам с математической точки зрения понятно, почему арифметическая интенсивность пре-филла намного выше, чем у декодирования.
00:26:44Хорошо.
00:26:46Это еще одна небольшая демонстрация.
00:26:51Так.
00:26:52Каждый раз мне нужно...
00:26:53Хорошо.
00:26:54Ладно.
00:26:55Отлично.
00:26:56Надеюсь, с этим все понятно.
00:26:58Итак, да.
00:26:59Мы снова загружаем модель.
00:27:04Теперь перейдем к затратам на пре-филл.
00:27:09По сути, мы берем входной текст и пытаемся оценить время, которое требуется на выполнение шага пре-филла.
00:27:22Мы видим, что с увеличением размера входных токенов время пре-филла возрастает.
00:27:28И именно по этой причине увеличивается время до первого токена.
00:27:33Затем переходим ко времени декодирования.
00:27:36Время декодирования в среднем остается примерно на одном уровне.
00:27:41И если не учитывать холодный старт, время декодирования находится примерно на уровне средней линии.
00:27:50Хотя оно по-прежнему зависит от размера входных данных.
00:27:57Нельзя сказать, что это константа.
00:28:00Это происходит потому, что по-прежнему нужно вытягивать из памяти векторы ключей и значений для всех предыдущих токенов.
00:28:07Поэтому на шаге декодирования все равно наблюдается небольшой рост времени.
00:28:15И перед нами классический график производительности (Roofline).
00:28:20Так.
00:28:22Хорошо.
00:28:23Презентация.
00:28:24Ладно.
00:28:25Хорошо.
00:28:26Понятно.
00:28:27А теперь давайте разберем аспект пропускной способности.
00:28:43Вам нужно понять, скольких пользователей вы реально сможете обслуживать.
00:28:48Мы уже видели схему памяти GPU, где показано, что часть памяти остается свободной для роста векторов ключей и значений.
00:28:56Хорошо.
00:28:57Допустим, у вас всего один пользователь.
00:29:01Каков суммарный объем кэша KV, который вы можете поддержать?
00:29:09Он определяется лимитом контекста.
00:29:11Максимальное число пользователей, которое вы можете обслужить — это доступный объем памяти GPU, деленный на размер KV-данных на одного пользователя.
00:29:25В результате вычислений мы получаем количество одновременных пользователей.
00:29:32Теперь предположим, что GPU и модель зафиксированы, поэтому размер KV на один токен является постоянным.
00:29:46Остаются только два изменяющихся параметра: контекст и число одновременных пользователей.
00:29:53Если вы хотите обслуживать больше пользователей одновременно, вам придется уменьшить длину контекста.
00:29:57А уменьшение длины контекста может ухудшить качество.
00:30:02Таким образом, это два параметра, между которыми приходится искать баланс.
00:30:09Но можете ли вы на практике обслужить максимальное число одновременных пользователей?
00:30:17В идеальном мире — пожалуй, нет, поскольку у каждого бизнеса есть соглашение об уровне обслуживания (SLO) по задержке.
00:30:27Помните, я говорил, что время декодирования возрастает при увеличении объема входных данных.
00:30:37Оно также растет при увеличении числа пользователей.
00:30:40В конечном итоге ваша задержка между токенами тоже увеличивается при большем размере батча.
00:30:51Время до первого токена (TTFT) также страдает.
00:30:53Появляется третий параметр, о котором нужно беспокоиться — это задержка.
00:30:58Итак, у нас есть три измерения: качество, задержка и пропускная способность.
00:31:04Получается такой треугольник компромиссов, где приходится выбирать между ними.
00:31:11Для премиального чат-приложения вы, безусловно, захотите поставить на первое место качество и задержку.
00:31:21Вы не захотите заставлять пользователей ждать слишком долго, по крайней мере, минимизируя задержки.
00:31:30Вы можете пожертвовать количеством поддерживаемых на GPU пользователей и взять эти расходы на себя, проявляя заботу о клиентах.
00:31:39А если речь идет об асинхронных задачах агентов, то здесь приоритетом будут качество и пропускная способность.
00:31:53Поскольку это долго выполняющиеся задачи.
00:31:56И вам захочется выполнять как можно больше задач параллельно, но с очень высоким качеством.
00:32:06И часто нам кажется: если GPU очень дорогая, значит, она нам не подходит.
00:32:19Но оказывается, что именно она может обеспечить наименьшую стоимость за миллион токенов.
00:32:27Однако нужно уметь доверять своим расчетам максимального числа пользователей и делать эти оценки правильно.
00:32:40У нас есть... сейчас я... отлично.
00:32:55Что касается калькулятора емкости, здесь есть ссылка на Colab, так как я с ним работал.
00:33:01Мне пришлось уходить от всей библиотеки виджетов, а времени не было.
00:33:16Поэтому из лени я просто взял Colab.
00:33:20Прошу прощения у моего лаба.
00:33:23Итак, моя видеопамять подключена.
00:33:34Хорошо.
00:33:45Видимо, Wi-Fi.
00:33:46Ладно, отлично.
00:34:02Здесь мы указали различные видеокарты, их объем VRAM, пропускную способность, операции с плавающей точкой и стоимость в час.
00:34:11Затем мы создали простой калькулятор емкости.
00:34:19Это визуализатор KV, где при увеличении количества токенов видно, как растет размер кэша KV.
00:34:29А при увеличении числа пользователей размер увеличивается гораздо быстрее.
00:34:37Давайте запустим этот калькулятор емкости.
00:34:47Мы выбрали модель с 7 миллиардами параметров.
00:34:56Установили точность FP16.
00:35:01При выборе GPU нужно сначала зафиксировать тот параметр, который волнует вас больше всего.
00:35:15Для премиального чата, как я упоминал, это определенно задержка.
00:35:21А для асинхронных задач вторым параметром является минимальный размер батча, который нужно обрабатывать на одной GPU.
00:35:31Сначала нужно зафиксировать эти значения.
00:35:34Итак, я рассуждаю применительно к премиальному чат-приложению.
00:35:39Я могу ориентироваться на задержку в 10 миллисекунд.
00:35:44Минимальный размер батча меня не особо волнует.
00:35:46То есть меня устроит, пожалуй, двойка.
00:35:53Хорошо.
00:35:54Пусть будет около семи одновременных пользователей на одной GPU.
00:35:59Лимит контекста также очень важен для меня, поскольку я хочу заботиться и о качестве.
00:36:07И я вижу определенные варианты среди GPU.
00:36:10Например, H100 на 80 ГБ стоит около 8 долларов в час.
00:36:15А как насчет RTX 3090?
00:36:19Или нет?
00:36:20Да.
00:36:21То есть это примерно 10 долларов в час.
00:36:24Итак, если проделать все те вычисления пропускной способности, о которых мы говорили ранее, вы сможете узнать стоимость миллиона токенов.
00:36:34Это может быть очень-очень, это может быть меньше.
00:36:37Поэтому вам нужно проводить такие расчеты, фиксируя эти параметры, и выбирать GPU так, чтобы снизить расходы на инференс.
00:36:49Так что это хотя бы первый шаг, который можно сделать для оптимизации инференса.
00:36:56Хорошо.
00:37:01Итак, следующий слайд.
00:37:04Позвольте мне.
00:37:08Ладно, отлично.
00:37:10И теперь следующий пункт — оптимизация моделей.
00:37:15Мы в основном заложили фундамент, поняв некоторые болевые точки, причины их возникновения и почему это происходило.
00:37:23Как мы можем решить проблему с емкостью GPU.
00:37:29Нам нужно понять, что мы можем сделать, что еще мы можем с этим поделать.
00:37:33Речь пойдет об оптимизации моделей, и я бы хотел пригласить Танмая.
00:37:39Он может рассказать об оптимизации моделей подробнее, учитывая, что он работал над этим во время своих исследований.
00:37:47Ладно.
00:37:48Хорошо.
00:37:49Я могу управлять.
00:37:50Я могу управлять.
00:37:54Да.
00:37:55Сюда.
00:37:56Так.
00:37:57Всем привет.
00:37:58Проверка связи.
00:37:59Меня наконец-то слышно?
00:38:00Да.
00:38:01Хорошо.
00:38:02Итак, привет.
00:38:03Я Танмай Шах.
00:38:04Я работаю старшим квант-моделлером, а также исследователем в области ИИ.
00:38:08Основное внимание я уделяю верификации агентов, а сейчас строю модели мира.
00:38:13Итак, вернемся к оптимизации моделей.
00:38:16Прежде чем мы начнем, я создал исследовательский шаблон, чтобы нам было проще понять все эти сложные вещи.
00:38:25Наш шаблон прост.
00:38:28Сначала мы определяем проблему.
00:38:30Второй шаг — решаем проблему с помощью двух алгоритмов.
00:38:34Это шуточные алгоритмы.
00:38:35Итак, первый алгоритм называется «алгоритм страуса».
00:38:39Всякий раз, когда мы видим проблему, прямо как страус, мы прячем голову в песок.
00:38:46Мы поступим точно так же.
00:38:47Всякий раз, сталкиваясь с проблемой, мы будем просто игнорировать ее.
00:38:51Так что это важный алгоритм, которому нам следует следовать.
00:38:55Второй созданный алгоритм называется «алгоритм чемпионата мира».
00:38:59Например, мы не знаем, кто выиграет этот чемпионат мира по футболу.
00:39:03Поэтому организаторы разбили 48 команд на 12 групп.
00:39:11Затем раунд 32 команды, и сейчас как раз идет этот этап.
00:39:16Затем 1/8 финала, четвертьфиналы, полуфиналы и финал.
00:39:21Таким образом, они разбивают задачу на более мелкие подзадачи, и полезные результаты продвигаются дальше.
00:39:30Ту же самую аналогию или тот же алгоритм мы используем, чтобы понять оптимизацию моделей и все остальное.
00:39:38Ну что же, давайте начнем.
00:39:41Допустим, у меня есть один GPU H100.
00:39:46Мне нужно использовать эту открытую модель под названием GPT OSS со 120 миллиардами параметров.
00:39:54И сейчас, кажется, она обучена в формате BF16, а вес ее составляет 240 гигабайт.
00:40:02Что мне делать?
00:40:04Вот такая у нас проблема.
00:40:07Первое, с чем приходится иметь дело: 240 гигабайт и 80-гигабайтная H100.
00:40:16При этом модель должна поместиться всего на одном GPU, а не на нескольких.
00:40:21Что же мы можем сделать?
00:40:22Думаю, простейший шаг — просто сжать ее.
00:40:27Но как ее сжать?
00:40:29Это еще одна задача.
00:40:30Если сжать формат BF16 до FP8, размер составит около 120 гигабайт.
00:40:38Но наш GPU H100 по-прежнему имеет емкость 80 гигабайт.
00:40:42Поэтому, полагаю, они сжали ее еще сильнее до MXFP4.
00:40:49И размер, кажется, составляет около 65 гигабайт.
00:40:53Это то, что мы можем сделать — сжатие, но возникает вопрос.
00:40:59И здесь мы используем наш «алгоритм страуса».
00:41:03Мы предполагаем, что при сжатии большой модели до меньшего размера потери качества отсутствуют.
00:41:10Второе — в этом случае, ладно, да.
00:41:16Итак, в данном случае на этом слайде мы использовали Mistral 7B.
00:41:20То есть 7 миллиардов параметров.
00:41:22Это небольшая модель, 7 миллиардов параметров.
00:41:25Если умножить это на два байта, вес получается около...
00:41:3114,5 гигабайт, что легко поместится в H100 или даже в A40.
00:41:38Затем, что мы можем сделать с Mistral 7B — вместо сжатия до FP16 мы можем применить другие методы, такие как int8, int4 или nf4.
00:41:53По сути, нам нужно просто применить «алгоритм страуса» и верить, что потери качества как таковой не происходит.
00:42:01Но нам также необходимо доказать это математически путем тестирования на каком-нибудь внешнем бенчмарке, чтобы понять, работает это или нет.
00:42:10И это относится к посттренировочной квантизации.
00:42:16Эту процедуру также можно проводить во время дообучения.
00:42:20Такого рода квантизацию можно выполнять и тогда.
00:42:22Это относится к квантизации с учетом обучения.
00:42:25Итак, давайте перейдем к нашей следующей проблеме.
00:42:31У нас есть огромные матрицы.
00:42:37Просто представьте матрицу A размерностью 1000 на 1000 и другую матрицу 1000 на 1000.
00:42:51Если перемножить эти две матрицы, количество операций будет равно 1000 в кубе.
00:43:00И с точки зрения вычислений это определенная проблема.
00:43:06Поэтому нам бы хотелось, чтобы матричное умножение происходило быстро и экономило память.
00:43:13Что же нам делать?
00:43:15У нас гигантская матрица.
00:43:17Хорошо, давайте возьмем эту: 4096 на 4096.
00:43:23Что нам предпринять для решения проблемы ускорения работы и экономии памяти при размере 4096 на 4096?
00:43:33Итак, первое — мы воспользуемся нашим алгоритмом кубка мира.
00:43:37Мы можем выбрать произвольное число и разбить блок по вертикали.
00:43:42Не имеет особого значения, что именно вы выбираете.
00:43:45Допустим, у нас 4096 столбцов.
00:43:51Мы разобьем их на группы по 128 столбцов в каждой.
00:43:57То есть 128, 128, 128, 128, 128 по вертикали.
00:44:03В результате деления 4096 мы получим 32 блока.
00:44:09Что же произойдет благодаря этому?
00:44:13Если мы разделим матрицу по вертикали, мы сможем использовать несколько GPU для ускорения процесса.
00:44:21Такой подход называется многоголовым вниманием (Multi-Head Attention).
00:44:26Что еще мы можем сделать?
00:44:29У нас есть большая матрица, как я уже упоминал, используя «алгоритм страуса».
00:44:36Наша главная проблема — размерность.
00:44:39Мы можем сделать следующее: вместо того чтобы держать все 31 вертикальный блок, мы просто отбросим 31 блок.
00:44:49И предположим, что одного блока вполне достаточно для обработки всех запросов.
00:44:57Наши потери будут практически ничтожными.
00:45:00И в итоге мы приходим к такому алгоритму.
00:45:04Этот алгоритм называется вниманием с одним запросом (Multi-Query Attention).
00:45:08Как мы видим, сейчас мы находимся на двух разных полюсах.
00:45:12Один из них — многоголовое внимание, где мы разделяем данные на 32 блока и используем разные GPU или параллельную обработку.
00:45:22А одновременно с этим мы просто отбрасываем 31 блок.
00:45:26И называем это вниманием с одним запросом.
00:45:31Поэтому для обеих крайностей нам следует найти какой-то компромиссный вариант.
00:45:38Можно сказать, что вместо выбрасывания всех 31 блоков мы, возможно, сгруппируем некоторые из них вместе.
00:45:49И предположим, что похожие блоки будут обрабатывать схожие типы запросов.
00:45:58Этот метод относится к вниманию с группированными запросами (GQA), которое сейчас очень популярно.
00:46:04Группированное внимание применяется даже в Mistral и других моделях.
00:46:11Итак, теперь мы понимаем, что у нас есть большая матрица.
00:46:16Мы можем делить ее так, как хотим, и с помощью математических расчетов
00:46:19доказать, что потери практически несущественны.
00:46:23Что же еще мы можем сделать?
00:46:25Затем, после этого внимания с группированными запросами...
00:46:34Посмотрите, у нас есть большая матрица.
00:46:38Одна часть — ключи, другая — значения.
00:46:42Давайте сожмем эту матрицу в скрытый вектор (latent vector).
00:46:47А затем разработаем алгоритм восстановления исходной матрицы из этого скрытого вектора.
00:46:55Подобная стратегия относится к следующему направлению.
00:46:59Многоголовое скрытое внимание (MLA).
00:47:02Но опять же, здесь возникают проблемы с RoPE, так как RoPE зависит от позиций, а этот подход — нет.
00:47:10Поэтому нужно также добавить индексы для ключей, чтобы их можно было сопоставлять.
00:47:16И снова главный вопрос: зачем мы перемножаем все эти огромные матрицы?
00:47:25Потому что так устроен механизм внимания: каждый токен обращает внимание на каждый токен.
00:47:33Так что насчет того, чтобы не обращать внимание на все предыдущие токены, а фокусироваться только на тех, которые действительно важны для нас?
00:47:42Итак, эта сфера сейчас активно развивается.
00:47:46Это относится к разреженному вниманию DeepSeek.
00:47:51Да-да.
00:47:53И, да, в общем, понятно.
00:47:56Дальше.
00:47:59Да, следующий пункт — Flash Attention.
00:48:02В Flash Attention основная проблема заключается в том, что...
00:48:09сейчас, вернее, не сейчас, а прямо сейчас почти все используют Flash Attention, но так было и в 2022 или 2023 году.
00:48:20В общем, это работает следующим образом.
00:48:23Это работает так: матрицы Q и K, запросов и ключей, находились в памяти HBM.
00:48:34Они сначала загружаются в тензорное ядро, выполняются некие вычисления, а затем результаты записываются обратно в HBM.
00:48:47И этот процесс повторяется многократно.
00:48:51Поэтому в Flash Attention сделали следующее: вместо умножения целых матриц...
00:48:59они разделили их, подобно алгоритму World Cup, разбив большие матрицы на небольшие блоки,
00:49:05и помещают в SBM только эти мелкие блоки, чтобы ускорить процесс умножения,
00:49:13при этом отслеживая три переменные для вычисления онлайн-softmax.
00:49:20Да, это чистая математика: если у нас есть многоголовое внимание с 524 ключами и значениями,
00:49:34то все зависит от желаемой группировки: если вместо 32 голов KV мы хотим использовать только 8 голов KV,
00:49:47мы получаем четырехкратное сжатие в этом многоголовом латентном внимании.
00:49:54Эта формула зависит от конкретной модели и количества слоев в ней.
00:50:00В оригинальной статье DeepSeek, кажется, использовалась размерность 128, точнее, я не помню точную размерность, но...
00:50:11согласно ей, они использовали один латентный вектор размерностью 512 и около 64 для индекса RoPE,
00:50:23после чего показали, что это в 56 раз сильнее сжато по сравнению с многоголовым вниманием.
00:50:32Хорошо.
00:50:33Да, итак, это диаграмма компромиссов; здесь мы, кажется, еще не говорили о линейном внимании или Mamba.
00:50:50Главная проблема заключается во всех этих матричных умножениях, сейчас все используют внимание.
00:50:56Допустим, в будущем мы не захотим использовать внимание и вместо последовательной генерации токенов перейдем к диффузионным моделям,
00:51:07где все генерируется одновременно — тогда изменятся и все эти алгоритмы.
00:51:14Но здесь у них есть еще два варианта: линейное внимание и Mamba.
00:51:19Судя по этому слайду, если мы ничего не сжимаем, то MHA просто распараллеливает процесс.
00:51:29Потерь качества нет, это хорошо, а затем идет групповое внимание с запросами (GQA) и DSA — то, что используют практически все модели.
00:51:42Да.
00:51:43Думаю, то же самое мы приводим в сводной таблице внимания: качество MHA хорошее, пропускная способность — нормальная.
00:51:56Что касается группового внимания с запросами, оно зависит от вашего сценария использования: качество почти как у многоголового внимания, но контекст тоже очень важен.
00:52:10Многозапросное внимание — это одна из крайностей.
00:52:13Мы почему-то предполагаем, что нам нужен всего один блок, и все запросы будут соотноситься с этими меньшими блоками.
00:52:24Поэтому качество у MQA не такое уж высокое.
00:52:29А многоголовое латентное внимание... Если вы пробовали модели DeepSeek, они отлично справляются с качеством, не говоря уже о скользящем окне.
00:52:44Все это такие техники, как настройка окон и т. д. Линейное внимание предлагает сначала все суммировать, а затем выполнять поиск, а Mamba — это просто модель в пространстве состояний, да.
00:53:09Для оптимизации моделей у нас также есть два блокнота.
00:53:28Так, мне нужно перейти к этому.
00:53:35Хорошо, что насчет квантования, например, демо — оно уже запущено? Нет.
00:53:51Позвольте мне запустить его.
00:53:54Итак, мы загружаем модель, например, Mistral 7B.
00:54:10Этот вариант — с базовым показателем FP16.
00:54:20Подождите.
00:54:21Оно запустилось?
00:54:21Подождите.
00:54:22Оно запустилось?
00:54:23Так.
00:54:24Выполнение заняло две миллисекунды.
00:54:27Это выполнилось?
00:54:28Хорошо.
00:54:29Да, на этот раз модель загружается с точностью FP16.
00:54:35Хорошо.
00:54:36Выполнение заняло две миллисекунды.
00:54:40Это выполнилось?
00:54:41Хорошо.
00:54:42Да, на этот раз модель загружается с точностью FP16.
00:54:47Wi-Fi.
00:54:58Это займет время.
00:55:03Ладно.
00:55:08Да, потому что веса скачиваются из Hugging Face.
00:55:14А?
00:55:17Да, Colab работает онлайн.
00:55:22Да.
00:55:23Потому что ему нужно сделать сетевой запрос к Hugging Face и выполнить скачивание.
00:55:30Не знаю, но загрузка, похоже, занимает время.
00:55:35Хорошо.
00:55:36Окей.
00:55:37Ладно.
00:55:38Хорошо.
00:55:39Окей.
00:55:40Здесь мы видим, что объем памяти составляет около 15 ГБ при точности FP16.
00:56:00Мы пытаемся сделать двукратное сжатие с помощью int8, как говорил Талмуд.
00:56:15Хорошо.
00:56:16Мы видим, что объем памяти теперь составляет около 0,7, 0,5 ГБ.
00:56:21Это значит, что теперь у вас больше памяти для роста вашего кэша KV.
00:56:27Это означает, что вы можете либо работать с большим лимитом контекста, либо обслуживать больше одновременных пользователей.
00:56:36Если использовать int4, вы по сути выполняете четырехкратное сжатие.
00:56:41При таком четырехкратном сжатии объем будет еще меньше.
00:56:45Думаю, около 3-4 ГБ.
00:56:50Да, 4,5 ГБ.
00:56:51И да.
00:56:52Так что это, подождите.
00:56:53Это просто базовый график с теоретическими цифрами.
00:57:09Мы не проводим здесь никаких тестов пропускной способности.
00:57:12Но обычно можно заметить рост доступной памяти.
00:57:15Соответственно, у вас будет и немного более высокая пропускная способность.
00:57:21Судя по изученным нами бенчмаркам, сжатие int8 имеет...
00:57:26да, оно обеспечивает меньшую пропускную способность.
00:57:32Хорошо.
00:57:33Затем идет демо, посвященное механизмам внимания.
00:57:42Итак, что касается внимания, хорошо.
00:57:45Мне нужно это запустить.
00:57:58Хорошо.
00:57:59Итак, оно выполнилось.
00:58:02О.
00:58:03Подождите.
00:58:04Почему написано, что GPU не обнаружен?
00:58:09По идее, GPU должен обнаруживаться.
00:58:18О.
00:58:19Ладно.
00:58:29Подождите.
00:58:30Секунду.
00:58:30Подождите.
00:58:50Это удивляет.
00:58:57Кажется, по какой-то причине он не может обнаружить GPU.
00:59:05У нас ведь есть здесь GPU.
00:59:11Ладно.
00:59:12Неважно.
00:59:14Да.
00:59:14Но основная идея здесь заключалась в том, что по мере перехода к сжатию вычислений с использованием различных механизмов внимания...
00:59:26от многоголового к групповому вниманию с запросами, а затем к MLA,
00:59:33вы начнете замечать определенные оптимизации.
00:59:38Кажется, вчера вечером мы проводили бенчмаркинг.
00:59:43Я хотел исправить этот момент.
00:59:45Там было не 56 раз.
00:59:48А 14 раз.
00:59:50В общем, в демо была допущена ошибка в расчетах, где не было умножения на количество слоев.
01:00:02Да.
01:00:03Так что приношу извинения за это.
01:00:04Таким образом, экономия от MLA составляет около 14 раз по сравнению с многоголовым вниманием.
01:00:15Теперь, когда мы понимаем болевые точки, основы и одну сторону оптимизаций — оптимизацию моделей, — мы хотим поговорить о том, что можно сделать со стороны обслуживания.
01:00:31Первое: мы видели, что при выполнении простого шага декодирования вы подтягиваете веса модели, а затем пересчитываете векторы ключей и значений для всех предыдущих токенов,
01:00:50хотя вы уже вычислили эти векторы для всех токенов.
01:00:55Так что здесь определенно имеет место большая трата вычислений.
01:01:02Если проанализировать временную сложность этого процесса, она окажется равной O от N в квадрате.
01:01:07Способ решения этой проблемы — классический компромисс в пользу памяти.
01:01:12Вы можете хранить историю этих векторов для токенов и обращаться к ней.
01:01:19Эта память получила название KV Cache.
01:01:24И сам процесс выглядит примерно так.
01:01:27Исходя из этого кэша KV, реально стали возможны четыре оптимизации.
01:01:35Первая касается постраничного внимания (PagedAttention).
01:01:42В чем же разница и в чем проблема сегодня?
01:01:45Итак, когда вы отправляете несколько запросов на вход в GPU, эти запросы объединяются в батч.
01:01:52Каждому запросу выделяется непрерывное хранилище памяти.
01:01:58Допустим, я просто привожу пример, скажем, 2 КБ.
01:02:05Однако вашему запросу требовалось, скажем, только 1 КБ.
01:02:11Таким образом, возникает примерно 50% фрагментации памяти.
01:02:19И эта фрагментация в основном приводит к пустой трате памяти.
01:02:24Это значит, что в памяти было пространство, где можно было бы обслужить больше запросов, но вы не могли этого сделать, потому что искали непрерывный блок памяти.
01:02:36Поэтому вдохновение было почерпнуто из того, как работает ОС.
01:02:41Например, вы поддерживаете логическую память и у вас есть физическая память.
01:02:47В логической памяти все равно будет казаться, что KV-вектор для каждого токена является непрерывным.
01:02:59Но он будет сопоставляться с другим физическим адресом.
01:03:06Так что это действительно помогло сэкономить много памяти.
01:03:11И это стало возможным только потому, что они рассматривают память как набор блоков.
01:03:18И вы будете динамически выделять эти блоки по мере необходимости для запросов.
01:03:22По мере того как поступают новые токены и им требуется такой объем памяти.
01:03:27Другой рычаг заключается в том, что когда вы отправляете несколько запросов в батче,
01:03:39GPU обрабатывает эти запросы.
01:03:42Но он не принимает новый батч, пока все запросы в этом батче не будут выполнены.
01:03:49Так что диаграмма больше похожа на постраничное внимание.
01:03:52Но здесь речь идет скорее о том, когда GPU доступен для приема следующего батча.
01:03:59Существует период времени, когда GPU простаивает.
01:04:04И вы хотите как-то решить эту проблему.
01:04:08Идея заключалась в том, чтобы использовать непрерывную батчизацию.
01:04:17Таким образом, непрерывная батчизация также очень помогла с пропускной способностью, потому что теперь можно отправлять больше запросов довольно быстро.
01:04:24Заботясь о том, чтобы GPU всегда был занят и не простаивал.
01:04:33Таким образом, вы экономите вычисления.
01:04:36Третье — это префиксное кэширование.
01:04:39Помните, KV-кэш помог вам сэкономить вычисления для одного запроса по всем токенам.
01:04:46Но что, если у вас одинаковые токены в разных запросах?
01:04:53Как с этим бороться?
01:04:55Префиксное кэширование, представленное в VLLM, борется именно с этим.
01:05:04И затем третье — вернее, мы уже говорили о четвертом.
01:05:10Мы говорили о квантовании модели, но вы также можете квантовать веса KV.
01:05:21Это значит, что теперь вам требуется меньше места для векторов ключей и значений.
01:05:28А значит, вы можете хранить больше ключей и векторов значений в памяти.
01:05:32И это значит, что вы можете обслуживать больше токенов.
01:05:34Это значит, что вы можете работать с большим лимитом контекста.
01:05:37И это значит, что вы можете поддерживать более высокое качество модели.
01:05:41И все это уже реализовано в VLLM.
01:05:51Вам не нужно заново изобретать велосипед.
01:05:56Вы можете развернуть VLLM в продакшене и увидеть этот рост.
01:06:03Далее у нас есть бенчмарк, который мы провели.
01:06:08Этот бенчмарк... сейчас посмотрю, есть ли он у меня.
01:06:14Вот.
01:06:17Демонстрации.
01:06:22Запуск этого бенчмарка занимает около часа, потому что приходится постоянно останавливать и перезапускать серверы VLLM, загружать модели и все такое.
01:06:35Тестирование занимает много времени, но я могу вкратце рассказать, что именно мы делаем.
01:06:41Мы оставили модель прежней, это Mistral 7B.
01:06:46Затем у нас есть набор входящих вопросов, которые мы отправляем.
01:06:53Считайте их промптами.
01:06:56Затем здесь есть вспомогательные функции, например, проверка того, запущен ли сервер.
01:07:01Этот сервер — сервер VLLM.
01:07:04Затем есть вспомогательные функции для получения метрик VLLM.
01:07:09И я расскажу о том, что это за метрики.
01:07:14Потом здесь есть множество бенчмарков и все такое.
01:07:17И еще нужно измерять использование KV и прочее.
01:07:22Так что это вспомогательные функции.
01:07:24Базовый вариант очень прост.
01:07:26У нас есть базовый вариант Hugging Face.
01:07:29Это простой способ отправки текста в LLM и получения ответа.
01:07:36Здесь мы видим некоторые результаты.
01:07:38Мы увидели, что пропускная способность Hugging Face составляет около 51 токена в секунду.
01:07:44Время до первого токена составило 54.
01:07:46А задержка между токенами — 19.
01:07:49Все это запускалось на H100.
01:07:56Затем мы запускаем сервер VLLM с настройками по умолчанию.
01:08:00По умолчанию VLLM предоставляет постраничное внимание, непрерывную батчизацию и KV-кэширование.
01:08:08Итак, три вещи присутствуют по умолчанию.
01:08:13И когда вы пытаетесь сравнить эти бенчмарки, вы видите, что пропускная способность возрастает почти в 15 раз.
01:08:21Вы можете обрабатывать больше токенов в секунду.
01:08:24Время до первого токена тоже увеличивается.
01:08:34А задержка между токенами снижается.
01:08:38Использование KV-кэша по отношению к пользователям и контексту, безусловно, возрастает.
01:08:43Теперь, когда вы применяете к этому префиксное кэширование.
01:08:51С префиксным кэшированием вы видите, что пропускная способность увеличивается еще сильнее.
01:08:57TTFT уменьшается.
01:08:59Задержка между токенами примерно такая же.
01:09:02Использование KV-кэша по отношению к пользователям начинает снижаться.
01:09:09По отношению к контексту оно не падает.
01:09:12Оно примерно такое же.
01:09:14Думаю, это тоже примерно то же самое.
01:09:16Это не так уж и важно.
01:09:19Когда вы применяете поверх этого квантование KV.
01:09:25Пропускная способность остается практически прежней.
01:09:33Время до первого токена не меняется.
01:09:36Задержка токенов остается прежней.
01:09:39Но использование KV действительно уменьшается.
01:09:42Это происходит потому, что вы квантовали пространство ключей и значений.
01:09:49Существует концепция спекулятивного декодирования, о которой расскажет Танмай.
01:09:54При тестировании этих методов также заметно некоторое снижение использования KV-памяти.
01:10:06Хотя результаты примерно одинаковые.
01:10:08В общем, это основные метрики.
01:10:21Наверное, мне стоит уменьшить масштаб.
01:10:25Ладно.
01:10:26Не получается.
01:10:27Уменьшить масштаб.
01:10:28Не работает.
01:10:29Отлично.
01:10:30В общем, это бенчмарки VLLM.
01:10:35Между прочим, это стандарт для продакшена.
01:10:38Мы также поделимся этим деревом решений, когда будем говорить о других движках.
01:10:48Давайте поговорим о том, какие еще оптимизации инференса мы можем сделать поверх этого.
01:10:58И какие еще решения появились.
01:11:02Я бы хотел снова пригласить Танмая.
01:11:07Он расскажет о некоторых из этих оптимизаций.
01:11:11Ой, простите.
01:11:12Большое извинение.
01:11:13Я не включил слайды.
01:11:26Какое было...
01:11:27Так.
01:11:28Отлично.
01:11:29Идеально.
01:11:30Какое именно?
01:11:31Спекулятивное декодирование.
01:11:32Да.
01:11:33Спасибо, Харшал.
01:11:34Да.
01:11:35Все это — спекулятивное декодирование.
01:11:40Все это, как бы сказать, разные вкусы одной и той же газировки.
01:11:46Эта техника относится к ускорителям декодирования.
01:11:51Первое — мы говорим только об этом спекулятивном декодировании, но есть и другие варианты, такие как self-speculative, Eagle, Medusa.
01:12:01Мне нравится, кажется, только этот, алгоритм Eagle.
01:12:05Итак, начнем со спекулятивного декодирования.
01:12:06Ладно.
01:12:07Хорошо.
01:12:08Давайте начнем с того, что такое спекулятивное декодирование.
01:12:09Главная проблема заключается в том, что в архитектуре трансформера все эти токены генерируются последовательно, один за другим.
01:12:26Что если использовать модель поменьше и позволить ей сгенерировать, скажем, четыре или пять токенов?
01:12:37И эта модель-учитель, или, как мы можем сказать, согласно нашему алгоритму Кубка мира — судья.
01:12:43Рефери решит, сколько токенов он принимает.
01:12:48И этот цикл продолжает повторяться.
01:12:51И мы предполагаем, что существуют определенные области, где такой подход будет работать.
01:12:59Например, в написании кода, где почти нет творчества.
01:13:05Каждый код или синтаксис почти одинаков.
01:13:08Так что, возможно, это поможет.
01:13:10Но, основываясь на личном опыте, я вообще не нашел спекулятивное декодирование полезным.
01:13:18Но другие методы, такие как самоспекулятивное декодирование, где у модели-учителя также есть одна вспомогательная голова, делают нечто похожее на то, что делает базовая или небольшая модель.
01:13:35Но затем появился EGLE — EGLE 1, 2, 3, не знаю, сколько там версий, но суть в том, что вместо генерации токенов давайте обучим небольшую модель и возьмем признаки из одного из слоев основных моделей, чтобы вместо генерации токенов она генерировала эти признаки.
01:14:02Так что EGLE лучше по сравнению с технологиями такого рода.
01:14:10И еще одна — MEDUSA, которая просто предлагает генерировать все эти токены параллельно.
01:14:17Хорошо, вот здесь, вот на этом слайде.
01:14:21Да.
01:14:22Следующий слайд.
01:14:24Ладно.
01:14:25Хорошо.
01:14:26Ладно, да.
01:14:27Хорошо.
01:14:28Теперь мы перейдем к кешированию префиксов.
01:14:34Не знаю, используют ли люди статическое кеширование префиксов.
01:14:39Но дело в том, что основная проблема кеширования префиксов заключается в том, что иногда мы делаем небольшую опечатку при вводе.
01:14:47И стандартное статическое кеширование префиксов берет промпт и выполняет хеширование.
01:14:53И в следующий раз, когда пользователь задает похожий вопрос, система пытается сопоставить хеш.
01:14:58Поэтому, если хеши совпадают, вместо повторного вычисления всех ключей и значений она просто берет их из хранилища.
01:15:09Но вы же знаете, что иногда мы ошибаемся или можем изменить слово или букву.
01:15:15Тогда мы получаем высокий процент промахов кеша.
01:15:21Именно поэтому дерево Радикса...
01:15:25Дерево Радикса становится очень популярным, в том числе из-за агентов.
01:15:30Думаю, почти все используют агентов, и большая часть вычислений происходит во время тестирования и инференса.
01:15:38Когда мы продолжаем задавать одни и те же вопросы и промпты.
01:15:42Например: «Ты эксперт в разработке ПО», повторенное 200 раз.
01:15:48Такие циклы постоянно происходят внутри агентских систем.
01:15:55Где необходимо сохранять или хранить подобные вещи в дереве Радикса.
01:16:03Так что дерево Радикса — это просто продвинутая версия префиксного дерева, где мы сворачиваем узел, если у него нет ответвлений.
01:16:17И для такой работы, где мы постоянно повторяем одно и то же,
01:16:24дерево Радикса очень помогает, и sglang использует алгоритм такого типа для кеширования префиксов.
01:16:35Ой, да, затем есть еще кое-что.
01:16:38Во-первых, TensorRT-LLM.
01:16:41Это очень запутанно.
01:16:42Когда я только начинал, я был просто сбит с толку.
01:16:46Что такое TensorRT-LLM?
01:16:49Ну да, TensorRT — это просто стандартный SDK.
01:16:55TensorRT-LLM — это просто движок инференса.
01:16:59Прямо как vLLM, sglang.
01:17:01Но проблема в том, что он связан с NVIDIA.
01:17:05Они оптимизировали каждый слой и каждую проблему.
01:17:10Как я упоминал в нашем алгоритме для Чемпионата мира, они просто переработали всё и оптимизировали на аппаратном уровне тоже.
01:17:18Так что да, ладно, дальше.
01:17:23Да, для этого воркшопа мы также провели бенчмаркинг, чтобы выяснить, что лучше.
01:17:33Наш сетап выглядел примерно так.
01:17:36Мы провели два вида тестирования.
01:17:39Первое — без агентского тестирования, где мы просто...
01:17:44Мы использовали набор данных ShareGPT и просто задавали эти вопросы с помощью vLLM и sglang.
01:17:57Хорошо.
01:18:05Да, хорошо.
01:18:07Позвольте мне приблизить.
01:18:12Отлично.
01:18:13Да, для этого воркшопа мы использовали H100, и наше первое тестирование заключалось в том, что мы просто...
01:18:23Мы брали вопросы из ShareGPT и передавали их в vLLM и sglang, и обнаружили, что статистической разницы в производительности нет.
01:18:34То есть у обоих примерно одинаковые...
01:18:37Оба обрабатывают схожее количество запросов в секунду, показывают одинаковое время до первого токена и задержку.
01:18:43Единственную разницу мы заметили при агентском ветвлении.
01:18:50Мы задали похожий вопрос: «Ты лучший инженер-программист в мире».
01:18:59«Реши проблему пробок на дорогах в городе».
01:19:04Затем мы передали это в LLM.
01:19:08LLM сгенерировала результат.
01:19:10После этого мы провели второй раунд.
01:19:13Когда LLM сгенерировала этот ответ, во втором раунде мы специально указали...
01:19:22проанализируй предложение и поставь оценку от одного до десяти.
01:19:28Это были два шага, которые мы сделали, и этот цикл постоянно повторялся.
01:19:35Мы выяснили, что для рабочего процесса такого типа, где все стандартно, в игру вступают промпты и контекстная инженерия.
01:19:47Если выполнять правильное агентское ветвление, то, на мой взгляд, SGLang работает в три-четыре раза лучше.
01:19:54Но опять же, это зависит от конкретного сетапа.
01:19:58Если вы запустите его, результаты могут отличаться.
01:20:02Понятно.
01:20:03Да.
01:20:04Думаю...
01:20:06Мы загрузили это на GitHub?
01:20:08Да.
01:20:09Хорошо.
01:20:10Да.
01:20:11PDF-файл также лежит на Диске.
01:20:15Там та же ссылка, что и на слайды.
01:20:18Итак, краткое резюме.
01:20:22Для стандартной рабочей нагрузки API пропускная способность vLLM и SGLang будет одинаковой.
01:20:31Поэтому, если у вас нет...
01:20:33Если у вас стандартная рабочая нагрузка, определенно выбирайте vLLM.
01:20:36Это в любом случае стандарт для продакшена.
01:20:38Но, как говорил Танмай, когда вы пытаетесь использовать агентские рабочие нагрузки, вот тут SGLang действительно раскрывает себя.
01:20:50И он приносит вам все эти преимущества.
01:20:55Так что да.
01:20:58Используйте vLLM по умолчанию.
01:21:00Но если у вас агентские нагрузки, попробуйте перейти на SGLang.
01:21:05Если вас не устраивает производительность vLLM.
01:21:09Ладно.
01:21:10Позвольте мне...
01:21:15Погодите.
01:21:18Хорошо.
01:21:21А затем здесь есть...
01:21:29Сравнение, выполненное для модели на 120 миллиардов параметров.
01:21:33Для GPT OSS 120B.
01:21:36Это бенчмарк, подготовленный PlayPy.
01:21:42Здесь есть ссылка на блог.
01:21:46О, отлично.
01:21:48Хорошо.
01:21:49Да.
01:21:50Они провели аналогичный бенчмарк и включили в него TensorRT-LLM.
01:21:57Вы всегда можете изучить эти бенчмарки и понять, что лучше всего подходит под ваши задачи.
01:22:05Как мы уже упоминали, TensorRT старается оптимизировать и аппаратную сторону для достижения пиковой производительности железа.
01:22:16И когда вы выбираете движки после сравнения vLLM, SGLang и TensorRT, появляются некоторые новые движки.
01:22:29NVIDIA Dynamo, безусловно.
01:22:43Они также предназначены для маршрутизации агентских сессий.
01:22:49Hugging Face тоже всегда здесь.
01:22:51Это простой инструмент.
01:22:53Затем есть движок MSTAR, недавно предложенный Стэнфордом.
01:23:00NVIDIA Dynamo для мультимодальных задач.
01:23:05Вы вполне можете их изучить.
01:23:08И подводя короткий итог: мы начинаем с базовой линии.
01:23:15Мы пытаемся найти модель, которая подойдет для наших задач.
01:23:22Вы можете выбрать DeepSeek.
01:23:27Только не выбирайте Mistral 7B.
01:23:30В общем, она не очень хороша.
01:23:32Но да.
01:23:35Итак, вы выбираете модель, хотите использовать меньше памяти и уместить большую модель в меньший объем памяти.
01:23:44Чтобы сэкономить на затратах на GPU.
01:23:47Для этого можно использовать квантование.
01:23:51Затем вы можете применить оптимизации сервиса, используя правильный движок под капотом.
01:23:58Это действительно обеспечит нужную вам пропускную способность.
01:24:07А теперь то, что вы можете сделать по возвращении домой — поскольку мы не можем охватить весь материал здесь, — это почитать об исходной информации: различных механизмах внимания и этих движках.
01:24:27Попробуйте ознакомиться с различными бенчмарками, доступными в интернете.
01:24:34Изучите множество глубоких руководств или следующих этапов, таких как стратегии вытеснения KV-кеша.
01:24:45Сейчас мир движется в сторону выделения отдельной области инженерии KV-кеша.
01:24:50Вам нужно понимать, что там происходит.
01:24:52Это вытеснение KV, сжатие кеша, гибридная память.
01:24:57Вокруг этого появляется множество решений.
01:25:01Поэтому всегда старайтесь опираться на эти основы и фундаментальные принципы.
01:25:08И оценивайте, какое решение какую проблему решает и нужно ли вообще решать эту проблему для вашего кейса.
01:25:17Затем есть распределенный инференс LLM, что представляет собой совершенно другую сложную задачу.
01:25:26Для этого, вероятно, понадобится двухчасовой воркшоп, чтобы разобрать всю «начинку» и попрактиковаться.
01:25:40Да, и это то, что мы пытаемся предложить для сессии AI Engineer в Нью-Йорке, то есть углубиться в продвинутые разделы инференса LLM.
01:25:51Этот же воркшоп больше подходил для начинающего и среднего уровней.
01:25:55Так что в этой форме у нас есть отзывы, а также интерес.
01:26:02Если вы считаете, что в определенных разделах нужны улучшения, обязательно оставьте свой отзыв.
01:26:09И если вы хотите увидеть этот семинар, например, на New York Fair, обязательно выразите свой интерес.
01:26:22А?
01:26:24О, как это возможно?
01:26:27Бум.
01:26:32Дайте-ка проверить.
01:26:37Ладно.
01:26:38А?
01:26:39Да.
01:26:40URL работает, верно?
01:26:41Да.
01:26:42Не QR-код?
01:26:43Ладно.
01:26:44Наверное, я забыл их связать.
01:26:45Ладно.
01:26:46Отлично.
01:26:46Да.
01:26:47Так что, если вы можете это предоставить.
01:26:49Ладно.
01:26:50Отлично.
01:26:51Да.
01:26:52Так что, если вы можете это предоставить.
01:26:53Ладно.
01:26:54Да.
01:26:55Ладно.
01:26:56Отлично.
01:26:57Да.
01:26:58Так что, если вы можете это предоставить.
01:26:59Позвольте мне просто.
01:27:00Ладно.
01:27:00Ладно.
01:27:01Отлично.
01:27:02Да.
01:27:02Так что, если вы можете это предоставить.
01:27:03Позвольте мне просто.
01:27:04Ладно.
01:27:05Так будет нормально.
01:27:06Эм, и да, думаю, на этом мы бы хотели завершить этот семинар.
01:27:13И я уверен, у многих из вас накопилось много вопросов.
01:27:14Так что мы можем обсудить их вне эфира.
01:27:15Эм, мы можем встретиться, эм, и мы сможем поговорить об этих вопросах.
01:27:16Да.
01:27:17Конечно.
01:27:18Конечно.
01:27:19Эм, спасибо всем.
01:27:20Спасибо, что присоединились.
01:27:21Эм, думаю, это было действительно.
01:27:22Эм, спасибо всем.
01:27:23Эм, спасибо всем.
01:27:24Спасибо, что присоединились.
01:27:25Эм, спасибо всем.
01:27:26Спасибо, что присоединились.
01:27:27Эм, думаю, это было действительно.
01:27:28О, ладно.
01:27:29Эм, ладно.
01:27:30Так будет нормально.
01:27:31Эм, и да, думаю, на этом мы бы хотели завершить этот семинар.
01:27:33Эм, и да, думаю, на этом мы бы хотели завершить этот семинар.
01:27:36И я уверен, у многих из вас накопилось много вопросов.
01:27:39Так что мы можем обсудить их вне эфира.
01:27:41Эм, мы можем встретиться, эм, и мы сможем, эм, поговорить об этих вопросах.
01:27:42Да, конечно.
01:27:43Эм, спасибо всем.
01:27:44Эм, думаю, это было очень содержательно, и все вы пришли сюда.
01:27:49Эм, большое спасибо.
01:27:50Да, спасибо.
커뮤니티 글
아직 글이 없습니다. 이 영상에 대한 첫 번째 글을 작성해 보세요!
이 영상에 대해 글쓰기