LeRobot documentation
Руководство по потоковому кодированию видео
Руководство по потоковому кодированию видео
1. Обзор
Потоковое кодирование видео устраняет традиционный цикл обработки PNG при записи набора данных видео. Вместо:
- Захват кадра -> запись PNG на диск -> (в конце эпизода) чтение PNG -> кодирование в MP4 -> удаление PNG
Кадров можно кодировать в реальном времени во время захвата:
- Захват кадра -> очередь в поток кодировщика -> кодирование непосредственно в MP4
Благодаря этому save_episode() выполняется практически мгновенно (видео уже закодировано к моменту завершения эпизода), а блокирующая пауза, которая ранее возникала между эпизодами, особенно при использовании нескольких камер в длинных эпизодах, устраняется.
2. Параметры настройки
| Параметр | Флаг CLI | Тип | По умолчанию | Описание |
|---|---|---|---|---|
streaming_encoding | --dataset.streaming_encoding | bool | False | Включить кодирование в реальном времени во время захвата |
vcodec | --dataset.rgb_encoder.vcodec | str | "libsvtav1" | Видеокодек. "auto" определяет лучший аппаратный энкодер |
encoder_threads | --dataset.encoder_threads | int \| None | None (авто) | Потоков на экземпляр энкодера. None оставит решение за vcoded |
encoder_queue_maxsize | --dataset.encoder_queue_maxsize | int | 30 | Максимальное количество буферизованных кадров на камеру (~1 с при 30 кадрах/с). Потребляет оперативную память |
3. Вопросы производительности
Потоковое кодирование означает, что CPU кодирует видео во время цикла захвата, а не после него. Это создаёт бюджет CPU, который необходимо распределять между:
- Цикл управления (чтение данных с камер, управление роботом, запись данных, не являющихся видео)
- Потоки кодирования (один пул на камеру)
- Повторить визуализацию (если включено)
- ОС и другие процессы
Влияние разрешения и количества камер
| Настройка | Пропускная способность (px/сек) | Загрузка кодирования на CPU | Примечания |
|---|---|---|---|
| 2camsx 640x480x3 @30fps | 55M | Низкий | Работает на большинстве систем |
| 2camsx 1280x720x3 @30fps | 165M | Умеренный | Комфортно на современных системах |
| 2camsx 1920x1080x3 @30fps | 373M | Высокий | Требуется мощный высокопроизводительный процессор |
encoder_threads Настройка
Этот параметр определяет, сколько потоков использует каждый экземпляр кодировщика внутри:
- Более высокие значения (например, 4–5): более быстрое кодирование, но используется больше ядер CPU на камеру. Подходит для мощных систем с большим количеством ядер.
- Меньшие значения (например, 1–2): меньше CPU на камеру, что освобождает ядра для захвата и визуализации. Подходит для изображений с низким разрешением и производительных CPU.
None(по умолчанию): позволяет кодексу принимать решение. Информация доступна в журналах кодека.
Backpressure и отбрасывание кадров
Каждая камера имеет ограниченную очередь (encoder_queue_maxsize, по умолчанию 30 кадров). Если кодировщик не успевает обрабатывать данные:
- Очередь заполняется (расходует оперативную память)
- Новые кадры отбрасываются (не блокируются) — цикл захвата продолжается без прерываний
- В журнал выводится предупреждение:
"Encoder queue full for {camera}, dropped N frame(s)" - По завершении эпизода отчитывается общее количество потерянных кадров для каждой камеры
Симптомы отставания кодировщика
- Система работает с задержками и зависает: все процессоры загружены на 100%
- Предупреждения о пропущенных кадрах в журнале или более низкое значение кадров/ФПС, чем ожидалось, в записанном наборе данных
- Рывки в движении робота: при сильной перегрузке ЦП может пострадать даже цикл захвата
- Накопленная задержка повторного запуска: визуализация отстаёт от реального времени
4. Аппаратно-ускоренное кодирование
Когда использовать
Используйте аппаратное кодирование, когда:
- CPU является узким местом (потеря кадров, рывки робота, задержка в Rerun)
- У вас есть совместимое оборудование (GPU или выделенный энкодер)
- Вы записываете данные с высокой пропускной способностью (высокое разрешение или большое количество камер)
Выбор кодека
| Кодировщик | Использование CPU | Размер файла | Качество | Примечания |
|---|---|---|---|---|
libsvtav1 (по умолчанию) | Высокий | Минимальный | Лучший | По умолчанию. Лучшее сжатие, но максимальная нагрузка на CPU |
h264 | Средний | на ~30-50% больше | Хорошо | Программный H.264. Меньшая нагрузка на CPU |
| Аппаратные кодировщики | Очень низкий | Самые большие | Хорошо | Переносит данные на выделенное оборудование. Лучше всего подходит для систем с ограниченными ресурсами CPU |
Доступные аппаратные кодировщики
| Кодер | Платформа | Аппаратное обеспечение | Значение CLI |
|---|---|---|---|
h264_videotoolbox | macOS | Apple Silicon / Intel | --dataset.rgb_encoder.vcodec=h264_videotoolbox |
hevc_videotoolbox | macOS | Apple Silicon / Intel | --dataset.rgb_encoder.vcodec=hevc_videotoolbox |
h264_nvenc | Linux/Windows | NVIDIA GPU | --dataset.rgb_encoder.vcodec=h264_nvenc |
hevc_nvenc | Linux/Windows | NVIDIA GPU | --dataset.rgb_encoder.vcodec=hevc_nvenc |
h264_vaapi | Linux | GPU Intel/AMD | --dataset.rgb_encoder.vcodec=h264_vaapi |
h264_qsv | Linux/Windows | Intel Quick Sync | --dataset.rgb_encoder.vcodec=h264_qsv |
auto | Любой | Определяет доступные аппаратные энкодеры в системе. Если аппаратный энкодер не найден, используется libsvtav1 | --dataset.rgb_encoder.vcodec=auto |
Для использования аппаратно-ускоренных кодировщиков может потребоваться обновление драйверов GPU.
libsvtav1используется по умолчанию, так как обеспечивает наилучшую производительность обучения; другие vcodecs могут снижать нагрузку на CPU и работать быстрее, но обычно создают файлы большего размера и могут влиять на время обучения.
5. Устранение неполадок
| Симптом | Возможная причина | Исправление |
|---|---|---|
| Система зависает, движение робота рывками или задержки в визуализации Rerun | CPU голод (100% загрузка) | Закройте другие приложения, снизьте пропускную способность кодирования, уменьшите значение encoder_threads, используйте h264, установите display_data=False. Если загрузка CPU по-прежнему составляет 100%, возможно, его мощности недостаточно для вашей конфигурации. Рассмотрите вариант с --dataset.streaming_encoding=false или аппаратным кодированием (--dataset.rgb_encoder.vcodec=auto). |
| Предупреждения «Encoder queue full» или потеря кадров в наборе данных | Кодировщик не успевает (переполнение очереди) | Если загрузка CPU не составляет 100%: увеличьте encoder_threads, увеличьте encoder_queue_maxsize или используйте аппаратное кодирование (--dataset.rgb_encoder.vcodec=auto). |
| Высокое потребление ОЗУ | Очередь заполняется быстрее, чем идёт кодирование | Слишком низкое значение encoder_threads или недостаточная мощность CPU. Уменьшите encoder_queue_maxsize или используйте аппаратное кодирование |
| Большие видеофайлы | Использование аппаратного кодировщика или H.264 | Ожидаемый компромисс. Переключитесь на libsvtav1, если CPU позволяет |
save_episode() всё ещё медленный | streaming_encoding равно False | Установите --dataset.streaming_encoding=true |
| Сбой потока кодировщика | Кодировщик недоступен или параметры недействительны | Проверьте, что vcodec установлен, попробуйте --dataset.rgb_encoder.vcodec=auto |
| В записанном наборе данных отсутствуют кадры | Голодание CPU/GPU или периодические всплески нагрузки | Если пропущено ~5% кадров, система, вероятно, перегружена — следуйте рекомендациям выше. Если пропущено меньше кадров (~2%), они, скорее всего, вызваны периодическими кратковременными пиками нагрузки (часто при запуске) и могут считаться ожидаемыми. |
6. Рекомендуемые конфигурации
Эти оценки являются консервативными; мы рекомендуем протестировать их на вашей конфигурации — начните с низкой нагрузки и постепенно увеличивайте её.
Высокопроизводительные системы: современные 12+ ядер (24+ потоков)
Пропускная способность в диапазоне ~250–500 млн пикс/сек должна быть комфортной для CPU. Для еще лучших результатов попробуйте аппаратное кодирование, если оно доступно.
# 3camsx 1280x720x3 @30fps: Defaults work well. Optionally increase encoder parallelism.
# 2camsx 1920x1080x3 @30fps: Defaults work well. Optionally increase encoder parallelism.
lerobot-record --dataset.encoder_threads=5 ...
# 3camsx 1920x1080x3 @30fps: Might require some tuning.Системы среднего уровня: современные 8+ ядер (16+ потоков) или Apple Silicon
Пропускная способность в диапазоне ~80–300 млн пикс/сек должна быть достижима на CPU.
# 3camsx 640x480x3 @30fps: Defaults work well. Optionally decrease encoder parallelism.
# 2camsx 1280x720x3 @30fps: Defaults work well. Optionally decrease encoder parallelism.
lerobot-record --dataset.encoder_threads=2 ...
# 2camsx 1920x1080x3 @30fps: Might require some tuning.Системы с ограниченными ресурсами: современные 4+ ядра (8+ потоков) или Raspberry Pi 5
На системах с очень ограниченными ресурсами потоковое кодирование может чрезмерно конкурировать с циклом захвата. Отключение этой функции возвращает систему к основанному на PNG подходу, при котором кодирование выполняется между эпизодами (блокирующее, но не мешает захвату). Альтернативный вариант — записывать с меньшей пропускной способностью, чтобы снизить нагрузку как на захват, так и на кодирование. Также стоит рассмотреть смену кодека на h264 и использование пакетного кодирования.
# 2camsx 640x480x3 @30fps: Requires some tuning.
# Use H.264, disable streaming, consider batching encoding
lerobot-record --dataset.rgb_encoder.vcodec=h264 --dataset.streaming_encoding=false ...7. Заключительное замечание
Производительность в конечном счёте зависит от вашей конкретной конфигурации — кадров в секунду, разрешения, количества ядер и загрузки CPU, доступной памяти, длительности эпизода и выбранного вами кодировщика. Всегда тестируйте систему с целевой нагрузкой, учитывайте возможности вашего CPU & системы и разумно настраивайте параметры encoder_threads, encoder_queue_maxsize и vcodec. Тем не менее, распространённая практическая конфигурация (для многих приложений) — это три камеры с разрешением 640×480x3 @30fps; как правило, она стабильно работает с настройками потокового видеокодирования по умолчанию на современных системах. Всегда проверяйте целостность записанного набора данных, сравнивая длительность видео с длительностью эпизода в CLI и убеждаясь, что количество строк равно FPS × длительности в CLI.