Архитектура для более эффективного вывода ИИ

Источник: Everpure Blog•

Архитектура для более эффективного вывода ИИ

Архитектура для более эффективного вывода ИИ от Everpure Blog. Узнайте, как совместное кеширование KV, интеллектуальная маршрутизация запросов и развертывание гибридных моделей могут повысить эффективность локального (on-premises) вывода ИИ и снизить эффективную стоимость за токен. Статья…

За последний год экономика инференса заставила многие предприятия всерьез задуматься о локальных мощностях. Именно с этой задачей связана эталонная архитектура оптимизации токенов ИИ, которую мы анонсировали на конференции Everpure Accelerate London на прошлой неделе. Цены на генерацию передовых моделей выросли примерно в два-семь раз, графических процессоров не хватало, а спрос на инференс удваивался каждые несколько месяцев. Поэтому компании поступили разумно и начали переносить рабочие нагрузки на собственное железо. Логика была проста: купить графические процессоры, установить движок инференса, запустить собственные модели и перестать платить за каждый токен с наценкой.

Сюжет в том, что затраты на локальную инфраструктуру сложнее отследить. В облаке больший счет сигнализирует финансовому отделу об изменениях. В случае с локальным размещением счета нет. Первый сигнал обычно поступает от инженеров, когда ответы начинают казаться медленными или система требует больше железа, чем должна. Кто-то наконец открывает дашборд и видит загрузку GPU на уровне почти 100%, что выглядит именно так, как и предполагалось по плану емкости.

Но показатель загрузки говорит лишь о том, что чипы заняты. Он ничего не говорит о стоимости каждого ответа. Для этого требуется другой показатель: эффективная цена за токен, то есть все затраты на создание токенов (часы работы GPU, электроэнергия и прочее), деленные на полученное количество токенов. Все больше команд начинают производить такие расчеты и обнаруживают, что при неправильном стеке инференса «бесплатная» модель с открытыми весами может обходиться за один токен столько же, сколько API передовых моделей.

Высокая загрузка и низкая эффективность могут одновременно наблюдаться на одном и том же кластере. Именно в этом разрыве теряется суть большей части сценариев локального инференса, а его устранение требует внимания не столько к самой модели, сколько к окружающему ее стеку.

Высокая загрузка GPU не обязательно означает эффективную загрузку GPU

Представьте парк графических процессоров как ресторанную кухню в часы пик. Каждая конфорка зажжена, на каждой станции кипит работа. Из обеденного зала это выглядит как кухня на пике производительности. Зайдите внутрь — и вы обнаружите нечто странное: ничто на этой кухне не готовится заранее и не используется повторно. Каждый бульон варится из сырых костей, а каждый соус создается с нуля для каждого отдельного заказа, даже если в только что поданном блюде использовался точно такой же бульон. Кухня выглядит загруженной, но не продуктивной. Большая часть этой суеты сводится к переделке работы, которая уже была завершена пять минут назад на соседней станции.

Именно это обычно скрывает высокая загрузка GPU. Существует утешительное предположение, что работающий на пределе GPU отрабатывает свою стоимость. Это не обязательно так. GPU, генерирующий новые токены, выполняет ту работу, для которой вы его купили. GPU, заново выводящий бульон, который другой узел уже приготовил, готовит из сырых ингредиентов, хотя все необходимое уже было на плите.

Куда на самом деле уходит время GPU

Чтобы понять, почему эта повторная подготовка обходится так дорого, полезно узнать, на что модель тратит время на самом деле. Прежде чем выдать хотя бы один токен результата, она должна сначала обработать весь промпт — этот этап называется префилом (prefill). Префилл масштабируется квадратично относительно длины: удвойте промпт, и объем работы увеличится примерно в четыре раза. Промпт на 100 000 токенов для крупной модели, даже при запуске на современном железе вроде систем NVIDIA DGX B300™ или NVIDIA Vera Rubin NVL72, все равно может тратить от 8 до 10 секунд времени GPU до появления первого выходного токена.

Эта проблема значительно усугубляется с агентным ИИ. Пятьсот инженеров могут одновременно запустить кодинг-агентов для работы с одной и той же кодовой базой, используя те же системные промпты, определения инструментов и большие объемы общего контекста. Соответствующий контекст почти идентичен в каждом случае, но наивная конфигурация воссоздает его для каждого запроса, тратя от 4 000 до 5 000 GPU-секунд на повторное вычисление одного и того же KV-состояния. Балансировщик нагрузки с алгоритмом карусели (round-robin) делает ситуацию только хуже, поскольку следующий запрос из той же сессии попадает на другой узел с холодным кэшем и снова оплачивает полную стоимость подготовки.

Это та сторона экономики токенов, которую упускает главный показатель. API передовых моделей напрямую учитывают попадание в кэш: повторно используемый контекст стоит лишь малую часть от свежего входящего токена, поэтому активное использование кэша отражается в виде реальной скидки в счете. При локальном развертывании отдельной позиции для промаха кэша (cache miss) нет, поскольку нет и самого счета. Затраты выражаются в парении пропускной способности. Каждая секунда GPU, потраченная на повторный вывод контекста, который кто-то уже вычислил, — это секунда GPU, не потраченная на генерацию новых токенов. Это незаметно повышает стоимость каждого произведенного токена, а соотношение «токены на доллар» падает, даже если ничто на дашборде не сигнализирует о проблеме с кэшем.

Вычисляй один раз, обслуживай везде

Думайте об этом как об эквиваленте концепции mise en place в системной архитектуре: подготовьте компоненты один раз в начале и позвольте каждой станции брать их с одного подноса. В терминах инференса кэш ключей-значений (KV-кэш), сгенерированный при чтении промпта, не должен быть заперт на том единственном узле GPU, который его создал. Он должен быть вычислен один раз и стать доступным для всего кластера.

Благодаря переходу от локального кэша узла к общему кэшу уровня кластера, любой узел может использовать уже выполненную работу. NVIDIA Dynamo и Pure Key-Value Accelerator (KVA) — это те элементы инфраструктуры, которые делают такую передачу возможной, перемещая KV-состояние между узлами вместо того, чтобы привязывать его к тому GPU, который первым выполнил вычисление. Когда префикс уже вычислен где-то в кластере, система может повторно использовать этот KV-кэш из соответствующего уровня кэширования вместо повторного вычисления с нуля. При бенчмарк-тестировании Pure KVA повторное вычисление длительностью около 10 секунд превращается в инъекцию кэша примерно за 500 миллисекунд, одновременно высвобождая циклы GPU для генерации новых токенов.

Такая же архитектура решает и другую проблему непроизводительных затрат: простаивающие сессии. Агентные рабочие процессы тратят много времени на ожидание вызовов инструментов, процессов сборки или ответов внешних API. Удерживать дорогую память GPU для приостановленной сессии неэффективно. Вместо этого система может перенести простаивающий KV-кэш в общее хранилище и восстановить его без повторных вычислений на том узле, у которого есть свободные мощности при возобновлении работы. Все это происходит прозрачно за единым шлюзом и не требует никаких изменений в клиентском коде. Избежание повторных вычислений — это половина уравнения эффективности. Вторая половина заключается в том, чтобы каждый запрос изначально выполнялся на подходящих мощностях.

Локальная инфраструктура и передовые модели вместе, а не по отдельности

Повторное использование вычислений решает лишь часть экономических задач. Идеальная платформа также должна динамически определять, где должен выполняться каждый запрос. Хотя наивная локальная архитектура снижает затраты на массовые рабочие нагрузки, она привязывает эти нагрузки к фиксированному оборудованию, закрывая им доступ к возможностям передовых моделей, когда этого требует сложная задача.

Преодоление этого ограничения требует объединения двух сред.

Разместив единый шлюз перед локальными и внешними моделями, архитектура полностью абстрагируется от «железа». Прежде чем запрос куда-либо отправится, его размер оценивает легковесный определитель сложности: он анализирует суть промпта и направляет его на ту модель, которая с ним справится. Такой паттерн появляется по всей индустрии, и не только здесь. NeMo Switchyard от NVIDIA — уровень маршрутизации с открытым исходным кодом, построенный на той же идее, — уже прошел бенчмаркинг в LangChain, показав снижение затрат на 74% за счет перенаправления запросов между эффективной открытой моделью и передовой, причем на передовой уровень отправляется лишь небольшая доля вызовов.

Руководство NVIDIA пришло к аналогичному выводу. Дженсен Хуанг откровенно заявлял, что самостоятельный хостинг несет в себе реальные издержки: это экспертиза, защитные механизмы и обслуживание, которых требует закрытый API. Он также советует своим сотрудникам арендовать облачный интеллект везде, где это ведет к цели быстрее. Описанный выше шлюз позволяет компании действовать именно так: направлять основной объем трафика на собственную инфраструктуру и в то же время обращаться к передовой модели ровно тогда, когда этого требуют задача или момент.

Подобная маршрутизация учитывает не только сложность, но и тайминг. Когда объем трафика превышает тот, что собственный парк может обработать без замедления работы для всех остальных, шлюз может перенаправить избыточный трафик на передовую модель, вместо того чтобы наращивать глубину очереди на и так загруженном «железе». Имеющиеся у вас мощности остаются рассчитанными на стабильную нагрузку. Арендованные мощности покрывают пики. Пользователи по-прежнему видят единую систему, в то время как платформа резервирует платные передовые мощности ровно под ту нагрузку и ту сложность, которые этого требуют.

Но разве более дешевые модели не сделают это бессмысленным?

Логично возразить, что цены на токены будут продолжать падать, а контекстные окна — расти. Разве из-за этого потери от ревычислений не становятся со временем менее значительными?

На практике массовое внедрение делает проблему масштабнее, а не меньше. «Дешевле» и «быстрее» — не одно и то же, хотя в возражении они приравниваются. То, что модель становится дешевле в расчете на токен или получает контекстное окно, способное вместить всю кодовую базу, ничего не говорит о том, с какой скоростью эта модель выдает те самые токены, за которые вы платите. Префилл по-прежнему масштабируется квадратично относительно длины промпта, поэтому большее контекстное окно делает эту стену выше, а не ниже каждый раз, когда запрос считывается сначала. То, что действительно дает вам скорость (то есть большее число токенов, генерируемых в секунду на том же графическом процессоре), — это повторное использование уже существующего где-то в парке KV-кеша вместо его повторного вычисления. И именно эта скорость превращается в лучший показатель «токенов на доллар» (ту самую метрику из начала этого поста), независимо от того, что произойдет с прайс-листом модели в следующем году. Большая пропускная способность на каждый GPU также означает обслуживание большего числа пользователей на уже имеющемся у вас парке оборудования — а ведь именно этот показатель должен был улучшиться, когда вы изначально переходили на локальную инфраструктуру.

Наращивайте мощности в последнюю очередь

Когда затраты на инференс остаются высокими, инстинктивно хочется добавить мощностей: более быстрые GPU, больше узлов, кластер побольше. Такой подход пропускает один шаг. Эффективный инференс — это не какой-то один трюк, это целый стек. Он начинается с понимания того, какой объем интеллекта на самом деле нужен конкретному промпту, и его маршрутизации на модель соответствующего размера. Он продолжается использованием KV-кеша, доступного всему парку. И он заканчивается предохранительным клапаном: запросы, которым действительно требуются возможности передового уровня или которые поступают во время всплеска нагрузки, с которым ваш парк не справляется, отправляются на передовую модель по требованию. Сложите эти три составляющие вместе — и вы получите систему, которая действительно заслуживает звания эффективной. Высокая загрузка сама по себе не говорит о том, что перед вами именно она, а не просто парк оборудования, который работает на пределе без всякой необходимости.

Сначала разберитесь со всеми тремя пунктами, и вопрос с мощностями станет гораздо менее масштабным и гораздо более точечным. Тот самый шлюз, который направляет сложные задачи на передовую модель по требованию, также означает, что пиковую нагрузку не обязательно обслуживать за счет простаивающего в остальное время недели собственного «железа». Благодаря этому расширение парка GPU превращается в осознанный шаг — к нему приступают только после того, как маршрутизация и кэширование уже показали, где находится реальное узкое место. Покупайте дополнительные GPU после того, как стек согласован, и каждый из них действительно добавит реальных мощностей, а не станет молча покрывать лишние отходы.

,

,

Ссылки: AI Token Optimization for On-Prem Inference reference architecture

О чём эта статья

Ещё в разделе «Hardware и электроника»

Все →

Ещё от Pure Storage