В эпоху развития физической искусственного интеллекта (Physical AI) и автономных систем точность цифровых двойников становится критическим фактором. Инженерам необходимо не просто создавать 3D-модели, но и делать это с высокой скоростью, чтобы быстро итерировать алгоритмы восприятия и планирования. Однако процесс нейросетевой реконструкции динамических сцен из мультисенсорных данных — камер и лидаров — требует колоссальных вычислительных ресурсов. Как превратить часы ожидания в минуты, а минуты в секунды? В этой статье мы подробно разберем реальный кейс оптимизации пайплайна NVIDIA NuRec, используя инструменты NVIDIA Nsight Developer Tools. Мы покажем, как глубокий анализ профилей, слияние ядер и тонкая настройка использования памяти позволили значительно ускорить работу системы.
Нейросетевая реконструкция, такая как реализованная в Omniverse NuRec, объединяет передовые техники нейрорендеринга, включая Gaussian Splatting, с ускоренными на GPU симуляциями. Это позволяет создавать фотореалистичные цифровые копии реальных сред, захваченных автономными транспортными средствами (AV) или робототехническими платформами. Эти реконструкции затем используются для проверки моделей, генерации синтетических данных и обучения систем машинного зрения. Но высокая детализация имеет свою цену: большие объемы сенсорных данных, сложные циклы обучения на PyTorch и специализированные CUDA-ядра создают серьезную нагрузку на графический процессор.
Цель команды NVIDIA была амбициозной: достичь производительности, близкой к реальному времени, где запись сцены реконструируется за время, сопоставимое с длительностью самой записи. На начальном этапе даже короткие захваты могли занимать от часа до нескольких часов. В этом материале мы подробно рассмотрим каждый шаг оптимизации, от выявления узких мест в профайлере до конкретных изменений в коде CUDA, и объясним, почему каждый миллисекунда имеет значение в масштабах индустрии.
01Контекст задачи: Почему скорость реконструкции критична?
В разработке автономных систем и робототехники время отклика инженера напрямую влияет на скорость разработки. Типичный рабочий процесс выглядит следующим образом: система обнаруживает аномалию в поведении стека восприятия или планирования во время тестового заезда. Инженер идентифицирует этот проблемный сценарий и запускает процесс реконструкции, чтобы детально изучить, что именно пошло не так. Если на реконструкцию уходит несколько часов, цикл отладки замедляется до неприемлемых значений. Это не только frustrates разработчиков, но и увеличивает стоимость инфраструктуры, так как GPU-кластеры простаивают или работают неэффективно.
Кроме того, оптимизация важна не только для этапа реконструкции, но и для последующих этапов симуляции. После создания 3D-модели среды часто требуется сгенерировать огромное количество кадров для обучения с подкреплением (Reinforcement Learning) или создания синтетических данных. В таких масштабах даже незначительное улучшение производительности рендеринга приводит к существенной экономии времени вычислений и затрат на облачные ресурсы. Поэтому задача оптимизации пайплайна NuRec стояла не как академическое упражнение, а как насущная инженерная необходимость.
02Первый шаг: Базовый анализ с Nsight Systems
Для решения этой задачи команда использовала NVIDIA Nsight Systems — инструмент системного профилирования, который позволяет визуализировать поведение workload'а на уровне всей системы, включая CPU, GPU, память и сеть. Первым делом необходимо было установить базовый уровень производительности и найти очевидные узкие места. Команда сфокусировалась на одной итерации прямого прохода (forward pass) цикла обучения, используя встроенную поддержку функций Nsight Systems и расширения NVTX (NVIDIA Tools Extension SDK), интегрированные в PyTorch.
Изначальное предположение было стандартным: наиболее тяжелым компонентом является ядро рендеринга, и именно с него стоит начинать оптимизацию. Однако анализ временной шкалы (timeline) в Nsight Systems выявил неожиданную картину. На временной шкале аппаратного обеспечения CUDA (верхний ряд) оказалось, что большая часть времени GPU простаивал или был загружен минимально. Отсутствие синего цвета на графике свидетельствовало о низкой утилизации ресурсов. Кроме того, приложение использовало гораздо больше мелких ядер (kernels), чем ожидалось. Это указывало на то, что проблема кроется не в сложности самих вычислений, а в организации их выполнения и накладных расходах на запуск ядер.

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

Проблема мелких ядер: Функция interpolate
Дальнейшее погружение в код функции collect_gaussian_parameters выявило корень проблемы: функцию interpolate. Именно она занимала большую часть времени и состояла из множества мелких ядер и операций с памятью. На временной шкале API CUDA (нижний ряд) это выглядело как непрерывный поток мелких задач, которые «забивали» очередь и не позволяли GPU эффективно работать. Мелкие ядра создают высокие накладные расходы на запуск (launch overhead), что приводит к тому, что GPU тратит больше времени на ожидание команд от CPU, чем на их выполнение.

Источник: NVIDIA Developer ↗
