Введение
К нашему голосовому продукту поступило две жалобы, которые мы не смогли устранить внутри компании. Англоязычным корпоративным клиентам ИИ показался быстрым. У клиентов, говорящих на китайском языке, а также у клиентов, говорящих на вьетнамском, тагальском и хинди, ИИ чувствовал себя вялым. Разрыв, измеряемый от начала молчания звонящего до первого слога ИИ, составил 260 мс на английском языке и 540 мс на китайском языке. Оба числа уложились в опубликованный бюджет задержки.
Только один из них чувствовал себя приемлемым во время телефонного звонка.
Инстинкт любой команды инженеров, которая видит пробел в задержках, заключается в том, чтобы доработать модель. Более быстрый вывод. Меньшая модель. Лучшее квантование. Мы все это сделали. Это дало нам 60 мс по всем направлениям, что ничего не закрыло — относительный разрыв все еще был, а английский остался вдвое быстрее.
Реальное решение пришло из другого наблюдения: мы рассматривали задержку как проблему модели, тогда как на самом деле это была проблема маршрутизации.
Куда на самом деле уходят миллисекунды
Разбиение ответа на китайском языке длительностью 540 мс на сегменты было первым, что прояснило проблему. Бухгалтерия выглядела примерно так:
- Захват звука и конечная точка — 80 мс
- Первый токен преобразования речи в текст — 140 мс
- Намерение + конвейер поиска — 90 мс
- Первый токен большой модели (поколение) — 180 мс
- Преобразование текста в речь в первую очередь — 50 мс
На английском пути одни и те же сегменты появились в 80/60/90/80/40. Двумя сегментами, которые резко разошлись, были преобразование речи в текст и генерация больших моделей. STT работал медленнее на китайском языке, потому что акустическая модель была обучена с использованием более длинного контекстного окна, необходимого для устранения тональной неоднозначности, которое сдвигало первый токен на 80 мс.
Генерация модели была медленнее, потому что токенизатор создавал больше токенов на символ эквивалентного значения в китайском языке, чем в английском.
И это не было дефектом модели. Оба были компромиссами, которые были незаметно накоплены независимыми командами, оптимизирующими собственные показатели: STT для точности, LLM для качества генерации. Цена задержки была реальной, но это не было ничьей прибылью и убытком.
Исправление маршрутизации, которое купило 200 мс
Мы перестали направлять все языки через один LLM. Вместо этого мы создали тонкий слой классификации перед генерацией, который менее чем за 8 мс определяет три вещи: язык входящего высказывания, класс разговорных намерений и является ли запрос одним из примерно 40 высокочастотных шаблонов, которые мы определили путем кластеризации 2 миллионов сегментов вызова.
Когда классификатор идентифицирует высокочастотный шаблон на языке, отличном от английского, мы направляем генерацию на меньшую, специализированную на языке модель, которая напрямую обрабатывает этот шаблон. Меньшая модель была очищена на миллионах завершений одного и того же шаблона, поэтому ее качество на этих конкретных путях находится в пределах шума большой модели, но ее задержка первого токена составляет примерно треть.
Когда классификатор видит хвостовое намерение — что-то, что не входит в 40 шаблонов, — запрос попадает в большую модель, как и раньше. Большая часть снижения задержки происходит из-за того, что высокочастотные шаблоны также шаблоны, на которые приходится ~78% объема звонков. Хвостовые случаи оплачивают первоначальную задержку, но они встречаются редко.
Классификатор, которого никто не ожидал
Тонкий классификатор был частью проекта, на который никто не заложил бюджет. Ее создание заняло больше времени, чем создание самой системы маршрутизации, поскольку виды сбоев были незаметными. Классификатор, который неправильно направляет 1% запросов на небольшую модель, которая их не обрабатывает, вызывает галлюцинации, а не просто ухудшенные ответы.
Три вещи заставили классификатор работать. Во-первых, он обучался на реальном производственном трафике, а не на синтетических данных. Во-вторых, он возвращал показатель достоверности, который мог установить маршрутизатор — все, что ниже 0,91, автоматически попадает в большую модель.
В-третьих, мы в течение шести недель развертывали его в теневом режиме на существующем конвейере, при этом большая модель предоставляла достоверную информацию, прежде чем какой-либо трафик был фактически перенаправлен на маленькие модели.
Теневое развертывание выявило четыре класса ошибок, которые пропустил набор автономных тестов. Два из них было легко исправить в обучающих данных. Два обязательных правила продуманной маршрутизации — все, что касается проверки личности, платежей или отмены встреч, всегда передается большой модели независимо от уверенности классификатора, потому что цена галлюцинации на этих путях выше, чем выигрыш в задержке.
TTS-сторона проблемы
Пока изменения LLM и STT проходили проверку, параллельная группа работала над речевым выводом. Первый звук TTS на английском языке длительностью 50 мс был фактически непобедимым; Разрыв в 70–90 мс для большинства языков, отличных от английского, обусловлен меньшими размерами голосовых моделей, менее агрессивным кэшированием и единым общим пулом графических процессоров, в котором приоритет отдается английскому языку под нагрузкой.
Мы разделили инфраструктуру TTS на пулы, привязанные к языку. Mandarin TTS теперь работает в собственном пуле со своими собственными правилами масштабирования на оборудовании, расположенном рядом с регионами, откуда исходит большая часть нашего трафика Mandarin. Задержка снизилась с 70-90 мс до 45 мс в течение двух недель после переключения.
Ничего из этого не было умным; это была инфраструктурная работа, которую никто не удосужился выполнить, потому что незначительное улучшение какого-либо отдельного языка само по себе не оправдало ее.
Урок — и сейчас мы записываем его внутри компании — заключается в том, что «мы не инвестировали в это, потому что ни один показатель, ориентированный на пользователя, не оправдывал этого» — это именно то решение, которое приводит к разрыву в 280 мс между двумя языками за четыре года.
Измерение паритета, а не средних значений
Одно небольшое, но существенное изменение, которое мы внесли внутри компании, касалось способа отчетов на информационной панели команды по задержке. Раньше мы отслеживали сквозную задержку p50 и p95, усредненную по всем языкам, по одному SLO. Приборная панель большую часть времени выглядела зеленой.
Новая панель мониторинга сообщает p50 и p95. за язык против паритет SLO — разрыв между самым медленным и самым быстрым поддерживаемым языком имеет свой собственный бюджет, который контролируется отдельно. Мы установили бюджет четности на уровне 60 мс. Когда разрыв превышает бюджет, дежурный вызывается.
Панель мониторинга четности делает то, чего не могла сделать система, основанная на средних значениях: она делает регрессии на самом медленном языке видимыми с той же срочностью, что и регрессии на самом быстром. При усреднении по 32 языкам регрессия на вьетнамском языке за 200 мс сдвигает среднее значение на 6 мс. Когда вы измеряете четность, приборная панель перемещается на 200 мс.
Что еще медленно
После работы по маршрутизации, пулов TTS и панели контроля четности наш худший язык (кантонский, в первую очередь потому, что корпус поддерживающих акустических моделей меньше) составляет 320 мс. Английский — 220 мс. Оставшийся разрыв в 100 мс реален, и мы примерно знаем, где он находится — кантонская акустическая модель STT старая и еще не на новой архитектуре, и мы переобучим ее в третьем квартале.
Но фраза «самый медленный язык отстает от самого быстрого на 100 мс» отличается от фразы «самый медленный язык отстает от самого быстрого на 280 мс». Первое — это известная регрессия, исправление которой запланировано ежеквартально. Последнее было чрезвычайной ситуацией, связанной с качеством обслуживания клиентов, о которой мы даже не подозревали.
Что мы сделаем по-другому в следующий раз
Три вещи в порядке приоритета, если бы мы перестраивали стек задержек с нуля, используя то, что мы знаем сейчас.
- Сначала постройте классификатор-маршрутизатор, затем модель. Уровень маршрутизации в конечном итоге оказался частью с самым высоким рычагом воздействия. Отношение к этому как к «мы добавим это позже, если оно нам понадобится» означало, что мы жили с задержкой одной модели на 18 месяцев дольше, чем нам было нужно.
- Устанавливайте SLO четности перед языковыми SLO. Соблазн состоит в том, чтобы установить целевые показатели для каждого языка и позволить достичь паритета. Паритет не возникает; он медленно расходится в направлении основного языка команды.
- Ресурсируйте языковую инфраструктуру так, как если бы каждый язык был отдельным продуктом. Mandarin TTS заслужил собственный пул графических процессоров с самого первого дня, а не с того дня, когда мы измерили разницу в задержке.
Ничто из этого не является новым исследованием. Ничто из этого не требовало бумаги. Требовалось рассматривать паритет задержек как обязательство по продукту, а затем финансировать непривлекательную инфраструктуру для поддержки этого обязательства. У нас есть тот паритет, который нам нужен сейчас. У нас его не было четыре года.