Ручной аудит на сети АЗС покрывал лишь несколько процентов смен — всё остальное оставалось вне контроля. Задача была закрыть эту зону с помощью уже установленных камер и микрофонов: автоматически выделять сессии обслуживания и проверять их по чек-листу. Никакого нового оборудования.

Первая очевидная идея — прогнать аудиопоток через ASR и искать ключевые фразы — ломается на практике. Система слышит «Здравствуйте», но не знает, кому это сказано: в зале может стоять несколько человек, кассир разговаривает с коллегой или курьером. Без привязки к визуальной сцене приветствие нельзя отнести к конкретной клиентской сессии. Обратный вариант — только видеоаналитика — тоже не закрывает задачу: камера видит, что клиент стоит у кассы 40 секунд, но не знает, предложил ли кассир кофе или приложение. Детекция жестов с существующих камер под типичным углом не работает надёжно.

ТриггерЧто ищемИсточник
Приветствие«Здравствуйте», «Добрый день» в начале сессииАудио + появление клиента в ROI
Прощание«Спасибо», «Всего доброго», «До свидания» в концеАудио + уход клиента из ROI
Предложение кофеУпоминание кофе или напитковASR + доменный лексикон
Нецензурная лексикаСписок стоп-словASR, независимо от роли

Архитектура получилась двухмодальной: видео даёт хронологию сцены и идентификацию ролей, аудио — содержание диалога. Сессия обслуживания собирается только после синхронизации обоих потоков.

Видеомодуль решает две задачи. Первая — разделить людей в кадре на четыре класса: клиент, кассир, стажёр, заправщик. Стандартные предобученные веса здесь не подходят: кассир и стажёр визуально похожи, заправщик выглядит как сотрудник, но работает в другой зоне. Детектор дообучали на реальных данных с АЗС. Стажёры при этом исключаются из оценки в первые 14 дней — маркер виден визуально (браслет или нагрудный знак). Вторая задача — удерживать ID клиента на протяжении всей сессии. Типичная проблема: клиент на секунду перекрывается стойкой, трекер открывает новый ID, и одна сессия распадается на две — система фиксирует «две сессии без приветствия» вместо одной корректной. Для решения использовали визуальные ReID-эмбеддинги с порогами, подобранными под конкретный ракурс камеры, и добавили зональное гейтинг-правило: случайное появление человека на периферии кадра не открывает сессию. ROI кассовой зоны задаётся вручную под планировку каждой станции и хранится отдельно от модели — это позволяет переносить систему на новую АЗС без переобучения.

Аудиочасть упирается в акустическую асимметрию. Кассир говорит близко к микрофону, длинными фразами, с высоким уровнем сигнала. Клиент отвечает односложно — «нет», «девятая», «наличными» — репликами короче секунды, на несколько децибел тише. В условиях АЗС с фоном компрессоров, кофе-машины и кассового оборудования тихая реплика акустически неотличима от шума. Стандартный VAD настроен не пропускать шум — и систематически выбрасывает именно клиентскую речь.

Для русского ASR рассматривали несколько вариантов. GigaAM v3 выбрали по трём причинам: модель заточена под русский язык, а не является мультиязычной; RNN-T вариант в тестах лучше держит короткие фрагменты; есть документированная процедура дообучения на доменных данных. Базовый WER на реальных записях составил около 49% — сдвиг домена: модель не встречала такой акустики при обучении. Собрали и вручную разметили около пяти часов диалогов. В обучающую выборку добавили короткие реплики клиента, числа с единицами («восемь литров», «колонка три»), доменную лексику АЗС и шумную среду без стерильной очистки — специально, чтобы модель не разваливалась на фоновом шуме. Обучали CTC и RNN-T версии параллельно: RNN-T добавляет авторегрессионный слой и использует уже распознанный контекст, что на коротких тихих репликах даёт около 2–3 процентных пунктов абсолютного WER лучше CTC.

Дообучение не помогает, если VAD уже выбросил нужный сегмент как тишину. Поэтому предобработка выделена отдельно: извлечение аудио, выбор лучшего канала, подавление низкочастотного гула, нормализация громкости. VAD запускается двумя проходами: первый — на исходном аудио со стандартными порогами, второй — на усиленном аудио с пониженными порогами. Окна второго прохода добавляются к первому без замены. Прирост покрытия речевых сегментов на тихих участках — 15–25% в тестах команды.

Whisper Large v3 не заменяет GigaAM, а работает резервным арбитром: включается только когда GigaAM выдала низкую уверенность, фрагмент слишком короткий или результат подозрительно пустой при явном наличии речи. Если Whisper уверенно фиксирует слово, которое GigaAM пропустила, создаётся кандидат на добавление. Если обе модели расходятся без явного перевеса — фрагмент отклоняется. Итоговая транскрипция остаётся за GigaAM.

После того как оба модуля отработали, система собирает бизнес-сессию и проверяет её по чек-листу: приветствие, прощание, предложение кофе, нецензурная лексика. Правила чек-листа хранятся в конфигурации отдельно от кода — заказчик менял их несколько раз в ходе пилота, и каждый раз достаточно было правки конфига без изменений в коде. Ряд случаев система не оценивает по условиям заказчика: дети, клиенты не говорящие по-русски, мотоциклисты в шлемах, стажёры первые две недели.