Когда-то, когда мы начинали разработку систем компьютерного зрения, мы полагались на известные решения для отслеживания с открытым исходным кодом, такие как те, которые вы можете найти для трекеров SORT и DeepSORT в Интернете.

Основная причина их популярности в том, что они представлены авторами алгоритмов и собрали тысячи звезд GitHub. Однако обычно они реализованы на Python и NumPy, которые (к сожалению) не могут обеспечить максимальную скорость.

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

Неэффективность или узкие места вычислений. Первая причина, по которой я хотел бы рассмотреть, заключается в том, как медленные трекеры ухудшают возможности конвейеров машинного обучения. Рассмотрим два трекера, работающих на сцене: первый трекер предсказывает треки за 1 мс, а второй трекер делает то же самое за 10 мс. Чтобы оценить проблему, предположим, что другие части конвейера (детектор, классификатор) тратят 3 мс на кадр. Чтобы лучше представить, посмотрите на картинку ниже:

Картинка является идеализированным представлением конвейера, потому что в реальной жизни программное обеспечение всегда испытывает различные потери, но для простоты не будем ими пренебрегать.

Рассмотрим первый (зеленый) конвейер. Он использует только один ресурс GPU, поэтому узким местом является сам GPU. В этом сценарии конвейеру требуется 3 мс для обработки кадра: за 1 секунду он может оценить 333 кадра в секунду.

Теперь мы готовы взглянуть на второй (красный) конвейер, который использует ресурсы GPU и CPU для выполнения вычислений.

Ну, в некоторых случаях трекер может использовать и GPU для вычислений, но в этом случае картина будет еще менее оптимистичной, потому что нет возможности запускать вычисления в очереди, а ресурсы GPU также тратятся на отслеживание объектов.

Мы можем видеть, что блок отслеживания ЦП является узким местом, поскольку он не может обрабатывать более 100 кадров в секунду; с другой стороны, блок графического процессора может работать со скоростью 333 кадра в секунду. Замятие на ЦП приводит к тому, что вычисления в графическом процессоре ограничиваются 100 кадрами в секунду, что заканчивается 700 мс бездействия графического процессора. Это плохой случай, потому что мы не можем полностью использовать GPU.

Третий конвейер (синий) равен первому с точки зрения узких мест. Он может полностью использовать GPU, в то время как CPU простаивает в течение 667 мс, что обычно выгодно, поскольку CPU выполняет другие координирующие и коммуникационные задачи.

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

Ограниченная масштабируемость вычислений. Трекеры MOT, как правило, масштабируются нелинейным образом. Следующие списки демонстрируют, как производительность обычной реализации SORT сравнивается с высокоэффективным трекером SORT Similari:

Обычный Python SORT:

 29 objects/frame - 183.35 FPS
 32 objects/frame - 166.13 FPS
 73 objects/frame -  58.34 FPS
115 objects/frame -  39.14 FPS

СОРТИРОВКА Similari (API Python):

 29 objects/frame — 1179.10 FPS
 32 objects/frame — 1087.52 FPS
 73 objects/frame —  303.49 FPS
115 objects/frame —  188.58 FPS

Вы можете заметить, что FPS падает быстрее, чем растет количество объектов. Это связано с характером отслеживания: теоретически существует квадратичная сложность.

Заключение. Нелинейная масштабируемость средства отслеживания приводит к еще одному важному последствию того, как средство отслеживания влияет на вычисления: чем больше объектов отслеживается, тем менее эффективным становится конвейер (см. раздел «Неэффективность или узкие места вычислений»). Плохая производительность трекеров приводит к более высокому простою графического процессора:чтобы преодолеть это, вы должны зарезервировать дополнительную мощность ЦП, что означает более дорогой и менее энергоэффективный ЦП.

Несовместимость вычислений Edge (ARM). Медленные трекеры делают невозможным запуск сложных конвейеров на периферийных устройствах. Удивительно, как последние несколько лет развиваются периферийные устройства. Однако наиболее значительное улучшение произошло в ускорении ИИ, а не в производительности процессора. Процессоры ARM, развернутые на периферии, по-прежнему не очень эффективны с точки зрения вычислений. Не похоже, что это изменится в будущем: периферийные вендоры больше заботятся о специализированных ASIC для решения конкретных аппаратных задач (таких как декодирование видео, кодирование и вывод ИИ), а не об улучшении архитектуры ЦП или развертывании монструозных универсальных x86-подобных Процессоры на пределе.

Процессоры в Nvidia Jetson не сильно эволюционировали, по сравнению с соответствующей эволюцией GPU: от прежнего Jetson Nano до нынешнего Jetson Orin Nano процессор стал быстрее примерно в два раза, и в то же время производительность GPU резко возросла. И, конечно же, разница в производительности ИИ еще более значительна между Jetson Nano и Jetson AGX Orin, в то время как процессоры существенно не изменились.

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

Заключение. Пограничные устройства имеют на борту энергоэффективные, но слабые процессоры, заменить которые невозможно. Традиционный x86-подход, когда разработчик может развернуть большую нагрузку на ЦП, не работает, поэтому нужно запускать оптимизированный код на ЦП, чтобы не допустить простоя ГП и иметь возможность сбалансировать бюджет устройства. Это делает практически невозможным запуск трекеров на чистом Python на периферийных устройствах. Кроме того, важно учитывать вывод раздела «Ограниченная масштабируемость вычислений»: если количество объектов резко возрастет, ЦП ARM может стать перегруженным, и весь конвейер может стать работоспособным.

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

Почему я зациклен на трекерах? Вообще говоря, каждая часть конвейера компьютерного зрения требует оптимизации, но, по нашему опыту, трекеры менее оптимизированы и являются наиболее ресурсоемкими компонентами. . Большинство других компонентов выполняются на графическом процессоре; даже когда логика «перемещения ящиков» разработана на Python, они не создают узких мест.

В чем смысл включения трекера в конвейер машинного обучения? Вы можете задаться вопросом, зачем заботиться о трекерах, если у вас есть простой конвейер обнаружения/классификации. Наш опыт показывает, что трекеры часто желательны или необходимы, даже в тех случаях, когда отслеживание кажется чрезмерным. Вспомним картинку из начала статьи:

Как видите, я разместил блок трекера прямо между блоками детектора и классификатора. На то есть причина: трекеры помогают пропустить определенное количество вычислений, если трек не изменился. Эффективный трекер помогает справляться с большей рабочей нагрузкой при меньшем количестве оборудования.

Также трекеры помогают справиться с ситуацией, когда модель детектора иногда не может обнаружить объекты: они интерполируют результаты между кадрами и уменьшают мерцание.

Доступно несколько реализаций трекеров с открытым исходным кодом, которые являются эффективными, настраиваемыми и масштабируемыми. Одной из альтернатив является платформа отслеживания Similari, которая реализована на Rust, но предоставляет Python API для часто используемых функций. Он может обрабатывать ресурсоемкие сцены с высоким FPS на серверах центров обработки данных на базе x86 и периферийных устройствах на базе ARM, таких как Nvidia Jetson.

Чтобы попробовать Similari в своем проекте, ознакомьтесь со статьями:

  • Высокопроизводительный Python SORT Трекер;
  • Отслеживание повернутых объектов с помощью Angle-Aware Detection Model и SORT Tracker.