Такая глубина анализа стоит за каждым нашим проектом. Мы публикуем её как подтверждение того, как мы на самом деле работаем — реальные варианты, которые мы взвешивали, цифры, которые их отсеяли, архитектура, пережившая столкновение со 150+ реальными магазинами на реальных интернет-соединениях — чтобы процесс был для клиентов таким же прозрачным, как и результат. В этом проекте «высекание из камня» было не про выбор самой точной модели в лабораторном бенчмарке — это было про признание того, что полка магазина, камера и интернет-соединение грязнее любого бенчмарк-датасета, и про то, чтобы строить архитектуру под эту грязь с самого начала.
У клиента была сеть розничных магазинов, где товарную доступность проверял персонал, физически обходя торговый зал с планшетом — ручной аудит, происходящий по расписанию, а не непрерывно, так что отсутствие товара, возникшее сразу после аудита, могло оставаться незамеченным часы или дни до следующей проверки. Каждый час, когда популярный товар отсутствовал на полке, — это упущенная продажа, которую с радостью подхватывал конкурент через дорогу.
Запрос звучал не как «поставьте камеру в каждый магазин». Он звучал так: ловить отсутствие товара и ошибки выкладки близко к моменту, когда они происходят, по всей сети магазинов, без необходимости в оборудовании и пропускной способности уровня дата-центра в каждой точке. Именно это последнее ограничение — у реальных магазинов реальные, непостоянные интернет-соединения и нет серверной — отсекло больше очевидных архитектур, чем любая цифра точности.
Второе ограничение, повлиявшее не меньше первого: у персонала операций в магазине уже полная загрузка. Система оповещений, которой персонал перестаёт доверять — потому что она часто ошибается, — игнорируется в течение недель, а значит система должна быть достаточно правой достаточно часто и честной насчёт своей неуверенности в остальное время, чтобы на неё реально реагировали.
Почему двухстадийные детекторы отсеялись первыми: независимое сравнительное исследование пропускной способности детекторов обнаружило, что YOLOv3 работает на 73 FPS против 12 FPS у Faster R-CNN — разрыв больше чем в 6 раз, обусловленный фундаментальным архитектурным различием между одним прямым проходом и двухстадийным пайплайном «предложить-затем-классифицировать». Более свежий вторичный бенчмарк, сравнивающий GPU-задержку YOLOv8 (1.3мс) с Faster R-CNN (54мс), обнаружил разрыв примерно в 40 раз — мы цитируем эту вторую цифру из нерецензируемого инженерного сравнения, не ставя на её точный множитель всё решение, но она направленно согласуется с той же архитектурной причиной. Для 150+ магазинов, генерирующих непрерывный поток фото полок, детектору нужно поспевать за объёмом, а не быть точным изолированно.
Почему трансформер-based детектор не подошёл, несмотря на то что это более новое направление исследований: оригинальная статья DETR (Carion et al., ECCV 2020) сообщает точность и скорость работы «на уровне» Faster R-CNN — то есть DETR изначально не конкурировал в категории скорости YOLO, он сравнивался с уже отсеянным выше двухстадийным детектором. Сходимость обучения DETR тоже реальная практическая стоимость: последующая работа (Deformable DETR) цитирует примерно 500 эпох обучения против 12-36 у Faster R-CNN. Более новые трансформер-детекторы вроде RT-DETR (2023-2024) заявляют конкурентную с YOLO скорость, но на серверных GPU — другая цель развёртывания, чем edge-оборудование уровня магазина. Наше собственное прочтение здесь, не заявление из какого-либо опубликованного источника, в том, что операции attention в трансформерах ещё не имеют такой же зрелой, оптимизированной поддержки на edge-ускорителях, как свёрточные архитектуры — что напрямую важно, как только решится §3 ниже.
Почему именно YOLOv8, а не более раннее поколение YOLO: собственные опубликованные бенчмарки Ultralytics (COCO val, 640px) показывают YOLOv8s на 44.9 mAP против YOLOv5s на 37.4 mAP при сопоставимом размере модели — реальный прирост точности в том же классе скорости, из документации самого вендора. Нам не нужен был самый крупный вариант (YOLOv8x, 53.9 mAP, рассчитанный на серверные GPU) — вариант среднего размера дал точность, нужную для детекции товара и пропусков на уровне полки, оставаясь внутри бюджета инференса, который реально мог выдержать edge-хардвер, выбранный в §3.
YOLOv8, вариант среднего размера, выбранный как single-shot детектор ради edge-жизнеспособной скорости инференса при точности, достаточной для анализа фото полок — не самый крупный или самый исследовательски-продвинутый вариант, а тот, что подошёл под цель развёртывания.
Почему нативный сервинг фреймворка не подошёл для роллаута на 150+ магазинов: поставка собственного рантайма PyTorch на каждое edge-устройство магазина означает поставку полного набора зависимостей фреймворка обучения на оборудование, которое никогда не выбиралось с учётом профиля производительности именно этого фреймворка, и неявно привязывает развёртывание к тому оборудованию, на котором этот рантайм работает быстрее всего.
Почему не только TensorRT: это реально быстрый вариант конкретно на оборудовании NVIDIA — собственные цифры Ultralytics показывают YOLOv8x, работающий за единицы миллисекунд на A100 с TensorRT. Но реальный мультимагазинный роллаут не гарантирует, что в каждой точке окажется идентичное edge-оборудование на базе NVIDIA, а привязка всего пайплайна к ускорителю одного вендора закрывает опцию, выбранную в §3 (Edge TPU от Google), если только не поддерживать два отдельных пути инференса параллельно — реальные постоянные инженерные расходы для растущей сети магазинов.
Почему именно ONNX Runtime: он построен ровно под эту проблему: единый экспортированный формат модели с несколькими execution provider’ами под ним — CPU, CUDA, TensorRT, CoreML и Edge-TPU-совместимые пути официально задокументированы — позволяя одной и той же экспортированной модели работать на разнородном оборудовании магазинов без отдельного пайплайна оптимизации под каждый тип устройства. По сырому ускорению собственное заявление Microsoft про «в среднем 2x прирост производительности на CPU» для их продакшен-сервисов (Bing, Office, Azure AI) — реальная цифра вендора, но это среднее по их конкретным нагрузкам, не гарантия для нашей. Более детальный сторонний бенчмарк, который мы нашли, дал конкретное сравнение PyTorch vs. ONNX Runtime на уровне примерно 1.58x, а собственный блог ONNX Runtime цитирует до 2.88x с fp16-квантизацией на другой (NLP) нагрузке. Честное резюме: ускорение реально и стабильно сообщается в диапазоне 1.5x-3x в зависимости от модели, оборудования и точности — не единая цифра, которую мы бы пообещали клиенту без бенчмарка на его конкретной модели.
ONNX Runtime как общий слой инференса для оборудования магазинов — экспортировать обученную модель YOLOv8 один раз, а не поддерживать отдельную оптимизированную сборку под каждый тип устройства по мере роста сети магазинов.
Почему только облачный инференс не подошёл под реальность связи в магазинах: интернет-соединения розничных магазинов часто представляют собой бизнес-широкополосный доступ или резервный 4G/LTE, а не аплинки уровня дата-центра. Типичная скорость загрузки 4G/LTE составляет примерно 10-15 Мбит/с по недавним отчётам мобильных сетей (Opensignal, RootMetrics), а одно фото полки в разрешении, реально способном разобрать отдельные этикетки SKU, — реалистично несколько мегабайт — занимает несколько секунд только на передачу на такой скорости, ещё до учёта TLS-хендшейка, очереди на сервере и обратного пути. Мы отмечаем это как собственную грубую оценку на основе публичных данных о скорости сети, а не опубликованный бенчмарк именно этого сценария, потому что не нашли такого. Умножьте это на сколько угодно фото, которые захватывает один аудит магазина, по 150+ магазинам — и время передачи по сети само по себе становится доминирующей задержкой в пайплайне, противоположность тому, что нужно своевременному оповещению об отсутствии товара.
Почему инференс на устройстве на Edge TPU оказался подходящим: собственные опубликованные бенчмарки Google Edge TPU показывают ускорение примерно в 20 раз по сравнению с инференсом на десктопном CPU для сопоставимых моделей (MobileNet v1: 53мс на десктопном CPU vs. 2.4мс на Edge TPU), а само оборудование потребляет по-настоящему небольшой энергетический бюджет — примерно 2 Вт при заявленных 4 TOPS, согласно собственному даташиту Coral — достаточно дёшево, чтобы развернуть в каждом магазине без значимого следа по питанию или охлаждению. Мы отмечаем честный пробел здесь: официальные бенчмарки Coral от Google опубликованы конкретно для семейства моделей MobileNet, SSD и EfficientNet-EdgeTPU, не для YOLOv8 — не существует публичной, подтверждённой вендором цифры YOLOv8-на-Coral, которую можно процитировать, и задержку инференса нашей собственной модели на устройстве нужно было бенчмаркать напрямую в ходе разработки, а не предполагать по опубликованным цифрам смежного семейства моделей.
Почему это не было чисто аргументом про задержку: инференс на устройстве также означает, что по сети из магазина нужно отправлять только результат детекции — небольшой структурированный пейлоад SKU, уверенности и позиции на полке, — а не сырое фото. Именно эта деталь сделала слой оповещений из §4 жизнеспособным по тем же ограниченным соединениям магазинов, которые изначально исключили чисто облачный инференс.
Инференс на устройстве на оборудовании Google Coral Edge TPU в каждом магазине, отправляя по сети только структурированные результаты детекции, никогда не сырое изображение.
Почему HTTP/REST не был естественным решением именно для этой формы трафика: MQTT — стандартизированный OASIS протокол (MQTT v5.0, OASIS Standard, март 2019), собственная заявленная цель проектирования которого — быть «лёгким... подходящим для использования в ограниченных сетях и мультиплатформенных средах» — описание, достаточно близко совпадающее с edge-оборудованием магазинов на непостоянной связи, чтобы воспринимать это всерьёз, а не как модное словцо. Конкретная разница: фиксированный заголовок MQTT — 2 байта, против типичного обмена HTTP request/response, занимающего 800-1000+ байт заголовков ради пейлоада, который сам может быть всего несколькими байтами — цифры, которые мы цитируем из инженерных материалов индустрии IoT, а не из единого рецензируемого источника, хотя несколько независимых источников сходятся в том же порядке величины. Для 150+ магазинов, каждый из которых публикует небольшие, частые события детекции, эти накладные расходы на сообщение накапливаются так, как не накапливались бы для горстки крупных, редких загрузок.
Почему паттерн «многие-к-одному» был важен конкретно здесь: модель публикации-подписки MQTT позволяет каждому магазину публиковать независимо в топики, не зная о центральном дашборде и не подключаясь к нему напрямую, а дашборд подписывается один раз, чтобы получать от них всех — задокументированный, стандартный архитектурный паттерн MQTT, не кастомная интеграция под каждый магазин. Альтернатива (каждое edge-устройство магазина вызывает центральный HTTP-эндпоинт) тоже работает, но заново реализует часть того, что pub/sub-брокер уже обрабатывает по умолчанию: удерживаемые сообщения, гарантии доставки для магазина на нестабильном соединении и одну точку подключения для масштабирования вместо 150+ отдельных входящих эндпоинтов, которые нужно защищать и мониторить.
MQTT, где edge-устройство каждого магазина публикует структурированные события детекции в центральный брокер, а дашборд операций магазина подписывается, чтобы получать оповещения по всей сети магазинов.
Почему одного фиксированного порога было недостаточно: фотографирование полок в реальном магазине — грязный процесс: частичное перекрытие, блики, необычные углы, сезонная или промо-упаковка, на которой модель не обучалась. Детектор, достаточно уверенный, чтобы быть полезным на чётких случаях, неизбежно будет и уверенно неправ достаточно часто на грязных случаях, так что единый порог либо пропускает достаточно ложных оповещений, чтобы подорвать доверие операций магазина к системе, либо устанавливается достаточно консервативно, чтобы этого избежать, и вместо этого пропускает реальные случаи отсутствия товара. Решение не в лучшем пороге — оно в том, чтобы дать неуверенности куда деться, кроме бинарного вызова оповещение/не оповещение.
Почему полное человеческое ревью каждой детекции подрывает сам смысл: весь бизнес-кейс — в замене отстающих на часы-дни ручных аудитов более быстрой детекцией. Направление каждой отдельной детекции через человека-ревьюера перед любым действием заново вводит ручное узкое место, размером с полный объём детекций по 150+ магазинам, а не только с реально неоднозначную его часть.
Почему именно маршрутизация по уверенности: отправка в лёгкую очередь ревью только детекций в неоднозначной полосе уверенности оставляет быстрый, автоматизированный путь обрабатывающим подавляющее большинство явно уверенных детекций на полной скорости, в то время как случаи, наиболее вероятно неправильные — и потому наиболее вероятно вредящие доверию операций магазина к оповещениям, если они неправильны, — получают быструю человеческую проверку, прежде чем стать пунктом действия в списке сотрудника магазина. Усталость от оповещений — хорошо задокументированный сценарий отказа в системах мониторинга в целом: как только персонал узнаёт, что оповещения часто ошибочны, он начинает игнорировать все их, включая правильные, и в этот момент система отказывает независимо от точности лежащей в основе детекции. Мы не цитируем здесь исследование, специфичное для усталости от оповещений именно в мониторинге полок ритейла — мы такого не нашли — это наше собственное операционное рассуждение, та же логика, что применима к любой системе оповещений, на которую человеку приходится реагировать многократно.
Маршрутизация по уверенности — авто-оповещение выше высокого порога уверенности, направление неоднозначной средней полосы в лёгкую очередь человеческого ревью, прежде чем она станет пунктом действия для операций магазина.
Ни одна из трёх опубликованных цифр не случайна — каждая является следствием конкретной комбинации решений выше:
Мы публикуем эти сравнения одинаково для каждой цифры в этом документе: как проверку правдоподобности относительно того, что сообщает индустрия, а не как утверждение, что результаты нашего клиента были сверены с конкретным конкурентом.
Стоит сказать прямо, потому что ни одна архитектура не вечна:
Ни один из этих пунктов не является провалом исходного решения — это условия, при которых тот же самый процесс рассуждения, запущенный заново, дал бы другой ответ.
Мы публикуем эту таблицу доверия намеренно. Клиенту полезнее знать, какие цифры пришли прямо из первоисточника — а какие, как оценка сетевой задержки загрузки фото полки, являются нашим собственным рассуждением на основе публичных данных, а не цитируемым бенчмарком, — чем получить документ, который выглядит чисто только потому, что неопределённость из него тихо вычистили.