Предобработка видео для ML – Computer Vision проекты, применения и инженерный плейбук 2026

Автор: Николай СапуновОбновлено: август 202633 мин чтения
Содержание статьи +

Кратко

Любой проект computer vision, который не доходит до продакшна, проваливается по одной и той же причине: команда рассматривает видео как последовательность изображений и строит пайплайн предобработки, который никто из них не стал бы использовать для аудио или текста. Предобработка видео – это отдельная инженерная дисциплина: преобразование цветового пространства, выборка кадров, временная батчизация и согласование форматов пикселей между декодером, библиотекой аугментаций и моделью. Ошибка в любом из этих четырёх компонентов стоит от 5 до 25 процентных пунктов точности на той же модели, которая на ноутбуке показывала 95%. Мировой рынок computer vision в 2026 году оценивается в USD 24–35 млрд при темпах роста 15–33% в год – а значит, разница между успешным и провальным проектом теперь измеряется миллионами долларов в год на один продукт. В статье разобран полный пайплайн предобработки, которым пользуются продакшн-команды YOLO, SAM 2, Whisper, основных VLM и LiveKit Agents – от камеры до тензора, – и собраны восемь ключевых параметров, которые нужно согласовать раньше любого другого решения в CV-проекте.

Зачем это важно

Если вы – продакт-менеджер, основатель или техлид, готовящий запуск проекта на основе computer vision (видеонаблюдение, модерация OTT, телемедицинская сортировка, фитнес-трекинг позы, ритейл-аналитика, мониторинг внимания в e-learning), то именно на этапе предобработки теряются две трети бюджета точности. Большинство команд приходят к обсуждению с ноутбуком, где OpenCV декодирует один видеофайл, каждый кадр масштабируется до 224×224, нормализуется по средним значениям ImageNet и подаётся в предобученную модель. В чистом датасете такой подход работает; на реальных камерах всё рушится по неочевидным причинам, которые не описаны ни в одном вендорском туториале. Это инженерная задача, а не магия.

Статья предполагает, что вы уже ознакомились с уроком 1.2 про латентность и топологию деплоя и уроком 1.4 про реальную стоимость ИИ в видео-продуктах, потому что каждое решение на этапе предобработки в итоге выражается числом миллисекунд, числом долларов или числом процентных пунктов точности – чаще всего сразу по всем трём параметрам. К концу статьи вы сможете понять секцию pre-processing в любой научной публикации, провести аудит вендорского пайплайна и составить одностраничное ТЗ, которое выдержит проверку на реальных продакшн-камерах.

Что на самом деле означает «предобработка» в CV-проекте

Слово «предобработка» в большинстве вакансий по computer vision перегружено, и разговоры буксуют – потому что никто не договорился, о каком именно этапе пайплайна идёт речь. Приведённая ниже таксономия – та, которую мы в Фора Софт используем, когда начинаем работу с новым клиентом и анализируем, где проект может потерять качество. Пока такой таксономии нет, обсуждение моделей теряет смысл.

Шаг декодирования превращает сжатый битстрим, который выдаёт камера – H.264, H.265, AV1, иногда MJPEG или проприетарный формат на промышленных камерах – в массивы сырых пикселей. Битстрим находится внутри контейнера (MP4, MKV, фрагментированный MP4, RTSP- или RTP-пакеты внутри WebRTC-сессии), и декодеру нужно распаковать как контейнер, так и кодек. Именно на этом этапе CV-проект впервые теряет качество: декодер тихо выдаст восьмибитные кадры в формате YCbCr 4:2:0, даже если камера снимала в десятибитном BT.2020 – а модель будет обучаться на том, что вернул декодер, а не на том, что реально видела камера.

Шаг конверсии формата преобразует декодированный YCbCr 4:2:0 в формат пикселей, который ожидает модель. Почти всегда модель требует RGB с полной цветовой разрешённостью (RGB 4:4:4) – либо в формате uint8, либо float32. Конверсия не бесплатна: она затрагивает каждый пиксель. Матрица, применяемая при этом (BT.601, BT.709 или BT.2020), изменяет каждый цвет в кадре, и большинство команд ошибочно выбирают не ту матрицу. Подробности рассмотрим ниже.

Шаг пространственного преобразования изменяет размер, обрезает, дополняет или деформирует кадр до формата, требуемого моделью. Обычно модель ожидает квадратное изображение – 224×224, 384×384, 640×640, 768×768 или 1024×1024 пикселей, в зависимости от архитектуры. Преобразование должно сохранять соотношение сторон (иначе детекторы объектов перестают работать корректно), а выбор метода интерполяции (bilinear, bicubic, Lanczos, nearest) влияет на точность модели в пределах 2 процентных пунктов.

Шаг временной выборки определяет, какие кадры из видео подаются на вход модели. Для 3D-Convolutional Neural Networks (3D-ConvNet) это окно из 8, 16, 32 или 64 последовательных кадров. В случае видеомоделей с языковым моделированием (video-VLM) берутся 8, 16, 32 или 64 кадра из 30-секундного фрагмента, и способ их отбора – равномерный, сконцентрированный в центре, только ключевые кадры или по схеме «начало–середина–конец» – влияет на точность модели на 5–15 пунктов. Для пер-кадровых моделей используется принцип «каждый n-й кадр», и выбор значения n напрямую определяет, удастся ли зафиксировать событие или оно будет пропущено.

Шаг нормализации масштабирует значения пикселей в диапазон, на котором обучалась модель. Большинство моделей, предобученных на ImageNet, требуют mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225) после деления на 255. Модели, обученные на данных, подобных CLIP, используют mean=(0.48145466, 0.4578275, 0.40821073), std=(0.26862954, 0.26130258, 0.27577711). Если перепутать константы – потеряете 2–8 пунктов; если не нормализовать вообще – до 10–25. Решение: брать параметры нормализации из документации модели и проверять их корректность на контрольной выборке.

Шаг батчизации собирает кадры в тензоры и отправляет их на ускоритель. Статическая батчизация (всегда batch=8) теряет ёмкость на старте и в конце клипа. Динамическая (собирает всё, что пришло за 50 мс) максимизирует пропускную способность, но увеличивает хвостовую задержку. Padded batching (дополнение до максимальной длины в батче) – единственный способ, который работает с клипами переменной длины. Ошибка в выборе режима батчизации – самая частая причина использования GPU ниже 30%.

Шаг аугментации находится поверх всего предыдущего на этапе обучения. Random crop, horizontal flip, colour jitter, random erasing, MixUp, CutMix, RandAugment, AutoAugment, а также временные аугментации (frame drop, frame jitter, temporal crop, temporal stretch) реализуются здесь. В 2026 году доминируют RandAugment для изображения и семейство TimeMix для видео; при правильной настройке они дают прирост точности на held-out данных на 1–4 п.п.

Самый большой инженерный выигрыш в CV-проекте – чётко обозначить эти семь шагов и присвоить каждому из них числовое значение (бюджет точности). Фраза «модель даёт 92%» – это не спецификация; а вот «модель теряет 0,5% из-за цветового дрейфа декодера, 1,2% – из-за неправильных констант нормализации, 0,8% – из-за использования bilinear-вместо bicubic ресайза, 2,1% – из-за временного алиасинга, итого 92%» – уже полноценная спецификация, которую можно отлаживать.

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

Рынок Computer Vision в 2026 – Почему эти цифры важны уже сегодня

Прежде чем углубляться в инженерные детали, важно понимать коммерческую картину – именно она определяет цену ошибки. Мировой рынок computer vision в 2026 году, по оценкам аналитиков, составит от 24 до 35 млрд долларов США в зависимости от выбранного подхода: Fortune Business Insights прогнозирует объём широкого рынка в 24,14 млрд долларов с ростом до 72,80 млрд к 2034 году, Grand View Research и Mordor Intelligence оценивают рынок на 2026 год в диапазоне 32–35 млрд долларов, а Coherent Market Insights прогнозирует более узкий сегмент «AI in computer vision» в размере 34,94 млрд долларов при CAGR 32,8% до 2033 года. В 2025 году Северная Америка контролировала около 34,3% рынка; Азиатско-Тихоокеанский регион остаётся самым быстрорастущим. По направлениям применения лидируют: контроль качества в производстве, ассистенты водителя и автономные технологии в автопроме, аналитика в ритейле, медицинская визуализация и видеонаблюдение – примерно в таком порядке по объёму выручки.

Для решений по предобработке важны параметры более низкого уровня. Типичный деплой IP-камер в 2026 году – 1080p, кодек H.265, 30 кадров в секунду, пропускная способность 4–8 Мбит/с на поток, 50–200 камер на объект. Типичный бэклог модерации OTT-сервисов – 100 000–10 млн минут UGC-видео в месяц в разрешениях от 480p до 4K. Типичное телемедицинское приложение – 720p через WebRTC, 15–30 кадров в секунду, при этом качество падает до SD, если у пациента прерывается Wi-Fi. Типичный фитнес-приложение получает видео с телефона в разрешении 1080p, 30–60 кадров в секунду, при этом пользователь держит устройство в руках и никогда не читал инструкцию к штативу. У каждой из этих нагрузок – свой оптимальный режим предобработки, а инженерный паттерн ниже – это пересечение того, что работает во всех четырёх случаях.

Цветовая ловушка – первая ошибка в каждом CV-проекте

Самый недооценённый шаг в пайплайне предобработки видео – преобразование цветового пространства, и эта недооценка стоит больше пунктов точности, чем что-либо другое на этой странице. Причина структурная: камеры снимают в YCbCr, кодеки кодируют YCbCr 4:2:0, модели обучены на RGB 4:4:4, а матрицы конверсии различаются для SDR-BT.601, SDR-BT.709 и HDR-BT.2020. Если использовать не ту матрицу, каждый цвет в кадре смещается на 2–8% – и модель, обученная распознавать зелёный жилет безопасности, начнёт его пропускать на камере, снимающей в BT.2020.

Математика проста. Матрица преобразования YCbCr → RGB для стандарта BT.709 (основного стандарта HD) определена в документе Rec. ITU-R BT.709, раздел 3.2. При использовании аналоговых коэффициентов полного диапазона она выглядит так: R = Y + 1,5748 (Cr − 128), G = Y − 0,1873 (Cb − 128) − 0,4681 (Cr − 128), B = Y + 1,8556 (Cb − 128).

Однако реальное видео редко передаётся в полном диапазоне. Большинство камер записывают данные в студийном диапазоне (также известном как ограниченный или TV-диапазон): Y варьируется от 16 до 235, а Cb/Cr – от 16 до 240. Перед применением матрицы необходимо вычесть 16 из Y и выполнить масштабирование.

Ошибка в выборе диапазона приводит к тому, что каждый кадр оказывается примерно на 10 % темнее или светлее, чем должен быть. В результате ваша аугментация по яркости работает поверх этой базовой ошибки в 10 %, которую модель вынуждена «запоминать».

Лечение – читать метаданные цвета и диапазона с декодированного кадра. FFmpeg выставляет их как colorspace, color_range, color_primaries, color_trc на декодированном AVFrame; дефолтный cv2.VideoCapture в OpenCV их выбрасывает и молча предполагает BT.601 + studio range – худшая комбинация, потому что современное видео – почти всегда BT.709 + studio. Лучшая инженерная инвестиция в новый проект – отключить дефолтный декодер OpenCV, использовать PyAV, torchcodec или Decord с явной цветовой конверсией и проверять колорспейс на каждом кадре.

ИсточникДефолт в OpenCV (cv2.VideoCapture)Дефолт в PyAV / Decord / torchcodecЧто реально снимают современные камеры
HD-камера (1080p, 720p)BT.601, studio rangeЧитает метаданные, BT.709 если тегнутоBT.709, studio range
4K SDR-камераBT.601, studio rangeЧитает метаданные, BT.709 или BT.2020BT.709 или BT.2020, studio range
4K HDR-камера (HDR10 / PQ)BT.601, studio rangeЧитает метаданные, BT.2020 + PQBT.2020, PQ-перенос, studio range
Смартфонная камераBT.601, studio rangeЧитает метаданные, обычно BT.709 + sRGBBT.709, full или studio range

Рисунок 2. Цветовые дефолты наиболее распространённых декодеров по сравнению с тем, что реально выдают камеры. Дефолт OpenCV вызывает цветовой дрейф на 2–8% в каждом кадре современного источника; PyAV, Decord и torchcodec читают метаданные и корректно конвертируют данные.

Ловушка, в которую попадает каждая джуниорская команда, – двойная конверсия. Пайплайн сначала декодирует YCbCr → RGB по стандарту BT.709, а затем downstream-библиотека (Albumentations, torchvision, Pillow, даже Matplotlib) «исправляет» то, что считает неправильным цветовым пространством, применяя ещё одну матрицу преобразования. Кадр, начавший путь в BT.709, оказывается в BT.601-then-BT.709: цвета искажены дважды, а модель сбита с толку сильнее, чем если бы конверсия вообще не применялась. Решение – конвертировать цветовое пространство ровно один раз, зафиксировать матрицу преобразования и проверить, что никакие downstream-библиотеки больше не трогают цвет. Однострочный assert frame.color_range == "studio" and frame.colorspace == "bt709" на границе пайплайна ловит баг до попадания в продакшн.

Выборка кадров – число, которое решает всё остальное

Когда цветовое пространство настроено правильно, следующий вопрос – сколько кадров в секунду выделять модели на обработку одного клипа. Это число не выбирается произвольно: оно жёстко связывает латентность, стоимость и точность, и никакая архитектура модели не сможет это скрыть.

Пер-кадровые модели – YOLO, RT-DETR, Grounding DINO, SAM 2 в image-режиме, MediaPipe Selfie Segmentation – работают с отдельными кадрами. Выбор стратегии обработки сводится к интервалу между кадрами: обрабатывать каждый кадр (30 fps), через один (15 fps), каждый пятый (6 fps) или только ключевые кадры (1–2 fps). Оптимальная частота зависит исключительно от события, которое необходимо зафиксировать. Падение человека можно отследить при 6 fps, поскольку оно длится более секунды; номер автомобиля на трассе нужно распознавать при 30 fps, так как он виден менее секунды. Стоимость обработки растёт линейно с количеством кадров – следовательно, ключевая задача – определить самое медленное событие в требованиях заказчика.

Window-основные модели – 3D-CNN (I3D, SlowFast), видео-трансформеры (TimeSformer, VideoSwin, VideoMAE) и большинство классификаторов действий – работают с окном из 8, 16, 32 или 64 кадров. Временной шаг окна (насколько далеко друг от друга в исходном видео выбираются кадры) – это параметр, который чаще всего нарушают. Модель SlowFast, предобученная на Kinetics, ожидает для slow-пути шаг 16 (один кадр из шестнадцати, охват около 2 секунд при 30 кадрах в секунду) и для fast-пути – шаг 2 (один кадр из двух, около 1 секунды). Если подать ей 16 последовательных кадров при 30 fps, она увидит лишь одну двенадцатую часть временного контекста, на котором обучалась; точность при этом падает на 8–14 пунктов. Решение – всегда проверять шаг окна в спецификации модели и строго его соблюдать.

VLM-модели – Gemini 2.5, GPT-5, Claude Opus, открытые Qwen-VL и LLaVA-Video, семейство SmolVLM – используют фиксированный бюджет при выборке кадров. Например, Gemini 2.5 Flash по умолчанию обрабатывает медиа с частотой 1 кадр в секунду в режиме low-resolution и тратит около 66 токенов на кадр; 60-секундный клип превращается в 60 кадров и занимает примерно 4000 токенов медиа-контекста. GPT-5 Vision API работает с кадрами как с отдельными изображениями – каждый кадр считается за одну картинку; 60-кадровый клип обойдётся примерно в 60 раз дороже, чем одна картинка. Claude Opus 4 действует аналогично. Прямое следствие для стоимости: частота 1 кадр в секунду обходится в 3,3% от стоимости 30 кадров в секунду на той же модели. Выбирайте самую медленную каденцию, при которой всё ещё удаётся распознать нужный класс события.

Рабочий пример. В ритейл-магазине 80 камер снимают видео в разрешении 1080p со скоростью 30 кадров в секунду. Продакт хочет отслеживать момент, когда шоплифтер кладёт товар в сумку – событие длится 4–8 секунд. При 30 fps нагрузка составляет 80 × 30 × 86 400 = 207 млн кадров в день на один магазин. При 6 fps – 41,5 млн кадров в день, при 2 fps – 13,8 млн кадров в день. Модель YOLOv11s на 6 fps на NVIDIA L4 (стоимость $1,10 в час) легко справляется с 200 потоками, то есть с двумя магазинами на одной видеокарте. На 30 fps потребуется в пять раз больше вычислительной мощности GPU и в пять раз выше почасовая оплата. Класс события умещается в 6 fps – выбираем 6 fps, и те же $1,10 в час на два магазина становятся рентабельными с точки зрения unit economics.

Каденция выборкиЧто надёжно ловитЧто пропускаетСтоимость к 30 fps
30 fpsСубсекундные события, номера на трассе, быстрые жестыНичего по каденции; давит бюджет100%
15 fpsБольшую часть action recognition, шоплифтинг, poseТрассу, очень быстрые жесты руками50%
6 fpsПадения, формирующиеся очереди, поведенческие аномалии, dwellСубсекундные события, быстрые мелкие объекты20%
2 fpsНарушения расписания, presence, медленные сценыВсё короче 2 секунд6,7%
1 fps (дефолт VLM)Длинноформатную разметку action, summarisation сценВсё короче 2 секунд стабильно3,3%
Только key-frameEditorial / search кейсыReal-time оповещениеПеременно, обычно <1%

Рисунок 3. Каденция выборки кадров жёстко связывает латентность, точность и стоимость. Выбирайте самую медленную каденцию, при которой удаётся обнаруживать нужный класс событий, а не самую быструю, которую вы можете себе позволить.

Распространённая ошибка – пересэмплинг из-за мысли: «камера снимает 30 кадров в секунду, надо использовать всё». Зеркальная ошибка – недосэмплинг, потому что «модели хватает 8 кадров на клип». Обе подходы провальны. Правильная каденция – та, что позволяет модели увидеть временной размах класса события один раз, плюс запас прочности 2× на хвостовые события и шум.

Пространственные преобразования – Resize, Crop, Pad и почему соотношение сторон «кусает» детекторы

Входная форма модели почти всегда квадратная – 224×224, 384×384, 640×640, 768×768, 1024×1024, – а выход камеры редко бывает квадратным. Преобразование между ними – третье по значимости место, где теряется точность, причём особенно сильно это сказывается на детекторах объектов.

Три паттерна доминируют. Naive resize растягивает кадр под форму модели, игнорируя соотношение сторон. Это стандарт для большинства туториалов, но он снижает точность детекции – у каждого бокса теперь искажённый аспект-рейшио. Letterbox resize (pad-resize) масштабирует длинную сторону кадра под размер входа модели, а короткую дополняет нейтральным цветом – серым, средним по кадру или чёрным. Такой подход сохраняет соотношение сторон, что важно для YOLO, RT-DETR и большинства детекторов в продакшене. Crop-and-resize берёт квадратный фрагмент кадра и масштабирует его, отбрасывая остальное. Подходит для классификаторов, где объект уже центрирован, но не работает для детекторов, которым нужна полная картина сцены.

Ловушка, которую команда обычно ловит дорогой ценой, – это использование разных функций ресайза в библиотеке аугментации и инференс-путе. На тренировке Albumentations применяет один bilinear, а на инференсе OpenCV – другой, из-за чего кадры отличаются на 1–3% по пиксельным значениям. Этого достаточно, чтобы детекция с уверенностью 0,51 оказалась ниже порога 0,50 и бокс был пропущен. Решение – гарантировать побайтовое совпадение функции ресайза на тренировке и в инференсе, либо переобучить модель с использованием инференс-функции. Опубликованный разбор Roboflow по деплою YOLO показывает, что паттерн letterbox + bilinear доминирует в продакшене; любое отклонение от него – это почти гарантированный разрыв в 1–2 пп между результатами в статье и в продукте.

Ядро интерполяции для инференса имеет меньшее значение, чем кажется, а для обучения – большее. Bilinear быстрый и вполне достаточен для большинства соотношений сторон. Bicubic чуть точнее при уменьшении изображения и является стандартом для задач в области искусства. Lanczos обеспечивает наивысшее качество, но работает медленнее всех. При обучении разница действительно существенна, поскольку модель учится ожидать определённое распределение пикселей – поэтому важно выбрать одно ядро и использовать его на всех этапах. Дефолты image_processor в Hugging Face Transformers различаются в зависимости от модели: CLIP использует bicubic, ViT – bilinear, BEiT – bicubic; применение неправильного дефолта приводит к измеримому падению на 0,5–1 процентный пункт в каждом бенчмарке.

Нормализация – константы, которые стоят 10 пунктов, если их пропустить

Шаг нормализации механически прост: вычесть поканальное среднее и разделить на поканальное стандартное отклонение. Однако режим отказа заключается в том, что команда использует неправильные константы. Правильные – те, на которых модель обучалась; неправильные – всё остальное.

Три набора констант покрывают 90% продакшн-моделей 2026 года.

ImageNet-константы используют ResNet, EfficientNet, ConvNeXt, различные варианты ViT-Base/Large, предварительно обученные на ImageNet, а также большинство моделей из библиотеки TIMM. Mean = (0.485, 0.456, 0.406), std = (0.229, 0.224, 0.225), входные данные нормализуются в диапазон [0, 1] после деления на 255.

CLIP-константы используются в моделях CLIP, OpenCLIP, SigLIP, EVA-CLIP и большинстве VLM на их основе (LLaVA, Qwen-VL, InternVL, Pixtral). Mean = (0.48145466, 0.4578275, 0.40821073), std = (0.26862954, 0.26130258, 0.27577711), вход нормализован в диапазон [0, 1] после деления на 255.

Без нормализации (raw [0, 255] uint8) – это формат, используемый в некоторых вариантах YOLO (например, YOLOv8 в 0-255 режиме, а также все варианты Ultralytics по умолчанию), моделях MediaPipe и большинстве ONNX-экспортов компьютерных моделей для edge-инференса. Константы нормализации закодированы непосредственно в графе модели.

Промах с константами даёт потерю точности в 2–8 процентных пунктов на хорошо настроенной модели и до 10–25 пунктов – на менее настроенной. Лечение: копировать константы из карточки модели, запускать санити-чек на held-out батче (предсказать 100 изображений, сравнить с опубликованным бенчмарком и подавать тревогу, если разница превышает 0,5 пп), а также никогда не полагаться на значения по умолчанию из туториала.

Лекарство экосистемы 2026 – сама карточка модели. Карточки моделей Hugging Face указывают константы нормализации в preprocessor_config.json для каждого современного чекпойнта; правильный подход – загружать препроцессор вместе с моделью и применять его к каждому входу. AutoImageProcessor.from_pretrained(model_id) делает это корректно как для ImageNet, так и для CLIP; использование такого подхода устраняет целый класс ошибок. Соответствующий паттерн в TensorFlow – tf.keras.applications.<arch>.preprocess_input; в MediaPipe используется собственный фреймворковый препроцессор.

Временная батчизация и пропускная способность – почему GPU загружен на 23%

Последний инженерный шаг – батчизация, и именно здесь проявляется юнит-экономика CV-проекта. Математика проста, а режим отказа универсален: команда отгружает статический батч, GPU работает с утилизацией 20–30%, облачный счёт оказывается в 3–5 раз выше нормы, а в постмортеме вину сваливают на «модель», а не на батчизацию.

Статическая батчизация («всегда batch=8») – самый простой паттерн и правильный выбор, когда один продюсер обслуживает одного консьюмера. Как только продюсер становится «бёрстовым» – например, мультикамерный surveillance feed, где иногда 80 камер одновременно фиксируют движение, – система начинает тормозить. GPU ждёт, пока наберётся batch=8, потом обрабатывает его, а затем снова простаивает. Пропускная способность падает ниже 50% от номинальной мощности GPU.

Динамическая батчизация («собирать 20 мс, потом отправлять») – это паттерн, применяемый в продакшене. Triton Inference Server, TorchServe и vLLM предлагают динамическую батчизацию как полноценную функцию. Есть две настройки: максимальный размер батча (ограничен объёмом памяти GPU) и максимальное время ожидания (ограничено допустимым временем отклика). При бюджете на инференс в 50 мс типичная конфигурация – max wait = 10 мс, max batch = 16. Утилизация GPU при этом возрастает с 23% до 75–90% при той же нагрузке, а стоимость обработки одного кадра снижается в 3–5 раз.

Padded batching нужен для клипов переменной длины – например, в видео-VLM, где в одном батче могут быть клипы по 10 и по 60 секунд. Паддингите каждый клип до длины самого длинного в батче, используйте attention mask, чтобы модель игнорировала паддинг, и смиритесь с тем, что на коротких клипах вычисления займут в 1,1–1,4 раза больше времени. Сделка выгодная – альтернатива (обработка каждого клипа отдельным батчем) полностью убивает утилизацию GPU.

Рабочий пример. Surveillance-продукт, 50 камер, бюджет латентности инференса – 100 мс. Каждая камера отправляет 30-кадровый клип раз в 5 секунд (окно 1 секунда каждые 5 секунд). При статическом батче = 1 пропускная способность – 50 клипов за 5 с, то есть 10 клипов в секунду; L4 загружен на 8%. При статическом батче = 8 пропускная способность растёт до 28 клипов в секунду, но время ожидания батча – 1,6 с, что превышает бюджет. При динамической батчизации с max wait = 20 мс и max batch = 16 пропускная способность достигает 80 клипов в секунду, латентность – 50–60 мс, GPU загружен на 84%, а облачный счёт снижается в 4,5 раза. Та же модель, то же железо, та же нагрузка – разницу делает батчизация.

Co-дизайн железа и софта – вторая часть. NVIDIA Triton Inference Server (всё ещё стандарт в продакшене в 2026 году) поддерживает динамическую батчизацию «из коробки» и работает с TensorRT-LLM, vLLM и любыми моделями на PyTorch или TensorFlow. Проект vLLM стал доминирующим инференс-движком для VLM и поддерживает continuous batching, который ещё эффективнее фиксированной динамической батчизации в decode-цикле, характерном для LLM. Для не-VLM моделей обработки изображений ONNX Runtime + Triton или PyTorch + Triton остаются надёжным выбором.

Рисунок 4. Статическая, динамическая и continuous батчизация с уровнем использования GPU, который они обеспечивают при одинаковой нагрузке.

Выбор декодера – OpenCV, PyAV, Decord, Torchcodec, NVIDIA DALI

Декодер – первое звено в цепи, и выбор декодера влияет на пропускную способность сильнее, чем осознают команды. Пять библиотек доминируют в экосистеме 2026 года.

OpenCV (cv2.VideoCapture) – самый простой вариант. Оборачивает FFmpeg, поддерживает большинство контейнеров и предоставляет удобный Python-интерфейс для работы с кадрами по одному. Два существенных недостатка: тихо использует цветовое пространство BT.601 (см. выше) и копирует каждый декодированный кадр из буфера FFmpeg в буфер OpenCV, удваивая потребление памяти. Для прототипа подойдёт; для масштабируемого продакшена – неподходящий выбор по умолчанию.

PyAV – обёртка FFmpeg, которую выбирают большинство команд в продакшене. Она предоставляет полный доступ ко всем настройкам FFmpeg: цветовое пространство, диапазон, аппаратное декодирование через NVDEC, VAAPI или VideoToolbox, формат контейнера – и возвращает декодированный кадр в виде numpy-массива с метаданными. Кривая обучения здесь круче, чем у OpenCV, но пропускная способность на одном CPU-потоке примерно в 2 раза выше – благодаря отсутствию двойного копирования данных.

Decord (dmlc/decord) – ридер, специализированный на задачах глубокого обучения. Поддерживает случайный доступ к кадрам в файле (например, «дай кадры 100, 250, 400»), GPU-декодирование через NVDEC и встроенный батч-API, возвращающий numpy-тензор из N кадров. Пропускная способность на одном GPU в 10–30 раз выше, чем у CPU-пайплайна на PyAV. В обмен на производительность Decord предлагает меньше возможностей: поддерживается меньше контейнеров и меньше параметров кодеков. Для задач инференса с известным и фиксированным кодеком Decord – оптимальный выбор по умолчанию.

TorchCodec – новый (с середины 2024 года) нативный для PyTorch видео-ридер. Возвращает декодированные кадры прямо на GPU в виде torch.Tensor, поддерживает любой кодек, доступный в установленном FFmpeg, и интегрируется с PyTorch DataLoader без копирования данных из numpy в tensor. Команда PyTorch активно развивает TorchCodec как долгосрочную замену ad-hoc API read_video – это оптимальный выбор для новых проектов на PyTorch.

NVIDIA DALI (nvidia.dali) – самый тяжёлый, но и самый производительный вариант. Полный пайплайн обработки данных (декодирование, аугментация, формирование батчей), работающий end-to-end на GPU, полностью устраняет узкое место на CPU. Пропускная способность на A100 – в 5–15 раз выше, чем у пайплайна на основе Decord. Платой за это становится операционная сложность: у DALI свой DSL, собственный дебаггер и кривая обучения, на освоение которой даже опытному инженеру может уйти неделя. Для высоконагруженных тренировок на железе NVIDIA (свыше 1 млн клипов за один прогон обучения) – это оптимальный выбор по умолчанию; при меньших объёмах проще использовать более лёгкие библиотеки.

БиблиотекаЛучшее применениеПропускная способность на 1080p клипе (1 поток)Production-gradeЗаметки
OpenCVПрототипы, single-camera демо~30 fpsНет в масштабеНеправильный цветовой дефолт
PyAVПродакшн CPU-пайплайны~60 fpsДаБезопасный дефолт
DecordRandom-access dataloading~200 fps (GPU NVDEC)ДаСоздан под ML-батчи
TorchCodecНовые PyTorch-проекты~150 fps (GPU NVDEC)ДаТензоры PyTorch-нативно
NVIDIA DALIHigh-throughput тренировка~600 fps (GPU, с аугментацией)ДаСложный, только GPU

Рисунок 5. Пять доминирующих видео-декодеров для ML-пайплайнов в 2026 году: пропускная способность на 1080p-клипе и оптимальное применение.

Аугментация – паттерны, приносящие реальные очки

Шаг аугментации – последнее инженерное решение в цепочке предобработки, и здесь у хорошо настроенного проекта ещё остаётся 1–4 п.п. точности. Доминирующие паттерны на уровне изображений в 2026 году известны; видео-специфичные временные паттерны – хуже.

Image-level аугментация – зрелая технология. Random crop, horizontal flip, colour jitter, random erasing и семейство policy-основанных методов (RandAugment, AutoAugment, TrivialAugment) – стандартный набор. Albumentations остаётся доминирующей Python-реализацией; torchvision v2 догнал в 2024 году и теперь – достойная альтернатива. Самое важное правило – применять одну и ту же аугментацию к одному и тому же кадру во время обучения и отключать её во время инференса; фреймворк-специфичные хелперы (model.train() против model.eval()) обычно делают это автоматически, но проверяйте на каждом новом пайплайне.

Временная аугментация – специфична для видео и хуже документирована. Эффективные паттерны, дающие измеримый прирост: temporal cropping (выбор случайного окна из K кадров в длинном клипе), temporal stretching (ресэмплирование клипа до немного другой частоты кадров), frame dropping (обнуление или интерполяция 10–30% кадров) и семейство TimeMix (смешивание двух клипов по временной оси). Статья Cerberus 2024 показала, что комбинация RandAugment для пространственной аугментации с 20% temporal dropout даёт прирост в 3,1 пп на UCF-Crime по сравнению с базовым вариантом без аугментации.

Mixup, CutMix и варианты MixUp работают сверху. Image-level Mixup комбинирует две картинки и их метки в фиксированной пропорции; CutMix вставляет прямоугольный фрагмент одной картинки в другую. Для видео существуют VideoMix (3D-версия CutMix) и более новый TubeMix, который комбинирует подобъёмы одного клипа с другим. Прирост точности стабилен (1–2 п.п. на бенчмарках по распознаванию действий), стоимость обучения практически нулевая.

Ловушка, в которую часто попадает команда, – переаугментация. Четырёхступенчатый пайплайн (random crop + flip + colour jitter + RandAugment + Mixup) на маленьком датасете приводит к тому, что модель учится политике аугментации не меньше, чем самой задаче. Лечение – провести небольшую ablation: обучить модель без каждой из аугментаций, измерить просадку и оставить только те, что дают прирост не менее 0,3 пп.

Типичные CV-проекты 2026 и их спецификация предобработки

Всё вышеизложенное было общим. Спецификация предобработки зависит от конкретного use case. Шесть паттернов, приведённых ниже, покрывают примерно 80% продакшн-проектов компьютерного зрения, с которыми мы сталкиваемся в 2026 году.

Реальное время детекции объектов на видео с камер наблюдения (наиболее распространённый проект в области компьютерного зрения по количеству). Входной сигнал камеры: 1080p, кодек H.265, 30 кадров в секунду. Декодирование: PyAV с явным указанием цветового пространства BT.709 и диапазона студийного уровня. Частота выборки: 6–10 кадров в секунду. Изменение размера с сохранением пропорций (letterbox) до 640×640 пикселей. Без нормализации (YOLOv11 от Ultralytics принимает данные в формате 0–255, uint8). Статическая батч-обработка: 1 кадр на камеру, динамическая батч-обработка: 16 кадров на инференс-сервере. Аугментации при обучении: случайный обрез, горизонтальное отражение, мозаика, Mixup. Ожидаемая точность: 88–92% mAP@50 на модели, адаптированной к домену; 80–85% на модели, предобученной на Roboflow / Ultralytics без адаптации.

Распознавание действий на архивном видео (OTT, безопасность, электронное обучение). Вход: H.264, разрешение 480p–1080p, частота кадров 24–30 fps. Декодирование: Decord с использованием GPU NVDEC. Выборка: окно из 32 кадров с временным шагом, соответствующим модели, предобученной на Kinetics (обычно шаг 2 для быстрого пути и шаг 16 для медленного пути в SlowFast). Центрированная обрезка до 224×224 после масштабирования по короткой стороне до 256. Нормализация по ImageNet. Размер батча: 8 с паддингом при обучении, динамический – при инференсе. Аугментации: временной кроп + RandAugment + Mixup. Ожидаемая точность: 85–90% на Kinetics-400 при дообучении SlowFast или VideoSwin.

Pose-трекинг для фитнеса или телехелса. Вход: видео 1080p с камеры телефона, 30 кадров в секунду по WebRTC. Декодирование: на клиенте – через MediaStreamTrack и OffscreenCanvas, на сервере – PyAV или Decord. Выборка кадров: каждый кадр используется для трекинга, каждый пятый – для оценки. Изменение размера – до 256×256 пикселей. Нормализация не применяется (MediaPipe Pose v2 работает с uint8). Размер статической батчи – 1 на поток (ограничение по латентности). Аугментация: масштабирование, отражение и небольшое вращение; повторная аугментация вредна, так как ground-truth метки позы точны. Ожидаемая MPJPE: 30–50 мм на indoor-сессиях, 50–80 мм на шумных outdoor-сессиях или при слабом освещении.

Детекция лиц для модерации или учёта посещаемости. Входное разрешение – от 480p до 4K. Декодирование – через PyAV. Выбор кадров: один кадр на событие обнаружения лица (быстрый детектор и трекер определяют, какой кадр использовать). Изменение размера под вход детектора: 416×416 для legacy MTCNN, 640×640 для YOLOv8-Face, 320×320 для SCRFD. Нормализация – ImageNet или специфичная для детектора. Динамическая батчировка на сервере инференса. Аугментация при обучении: фотометрическая + небольшой scale jitter; без горизонтального отражения, если модель предсказывает атрибут «лево / право». Ожидаемая точность: 95%+ AP при IOU = 0,5 на WIDER FACE Easy; 80–87% на Hard.

Видео-VLM модерация / captioning (новейший доминирующий CV-проект). Вход: любой клип, который загрузил пользователь. Декодер: PyAV для метаданных + ffmpeg для извлечения кадров на диск. Выборка: 8, 16 или 32 кадра равномерно по клипу плюс key-frame. Resize под вход VLM – 384×384 для SigLIP-моделей, 448×448 для Qwen-VL, 224×224 для старых CLIP-VLM. CLIP-style нормализация (большинство VLM используют её). Без батчизации (каждый клип – один VLM-вызов); для контроля стоимости – роутить в маленький VLM (Qwen-VL 7B, SmolVLM 2B, LLaVA 1.6 7B) на edge, а в frontier VLM (Gemini 2.5, GPT-5) – только пограничные случаи. Аугментация неприменима в инференсе; для fine-tuning – рецепт LoRA из урока главы 4 по дообучению VLM.

Детекция аномалий на видео с наблюдения. Полный end-to-end процесс описан в уроке 2.15; спецификация предобработки указана там же: PyAV с цветовым пространством BT.709, 10-секундные клипы со скоростью 6 кадров в секунду, равномерная выборка по 16 кадров на клип, центрированный кадр размером 224×224, нормализация по ImageNet, динамический батч размером 8 на сервере инференса на границе сети.

Где Тут Фора Софт

Фора Софт поставляет видео-решения с 2005 года, а проекты на основе computer vision – с 2018: системы видеонаблюдения и интеллектуального анализа видео, модерация OTT-контента, сортировка обращений в телемедицине, аналитика внимания в e-learning, AR-коучинг в фитнесе, а также несколько закрытых промышленных систем визуального контроля. Описанный выше пайплайн предобработки – это результат объединения того, что мы уже внедрили, что ломалось в продакшене, и что пришлось перепроектировать. Мы не продаём готовые CV-решения – мы интегрируем наш CV-пайплайн в вашу систему. Обычно разговор с нашей командой начинается с одностраничного worksheet – именно его мы приложили к статье в качестве компаньон-материала, – где перечислены восемь ключевых показателей, на которые новый проект должен дать ответ до выбора модели.

Ключевые выводы

  • Предобработка видео – семиступенчатый пайплайн, у каждого этапа свой бюджет точности. Перед дообучением модели обязательно проверьте все семь шагов.
  • Стандартный декодер OpenCV по умолчанию использует BT.601 + студийный диапазон, что неверно для большинства современных камер 1080p и выше. В продакшене используйте PyAV, Decord, TorchCodec или DALI.
  • Выбирайте самую низкую частоту кадров, которая всё ещё позволяет корректно детектировать нужный класс события. В большинстве задач видеонаблюдения 6 кадров в секунду заменяют 30, снижая затраты в пять раз.
  • Константы нормализации зависят от модели. Берите их с официальной карточки модели, а не из туториала – ошибка в этом может стоить 10–25 пунктов точности.
  • Динамическая батчизация в Triton или vLLM повышает загрузку GPU с 23% до 75–90% при той же нагрузке. Статическая батчизация – неправильный выбор по умолчанию при масштабировании.
  • Шесть основных сценариев использования покрывают около 80% проектов: детекция объектов, распознавание действий, оценка позы, распознавание лиц, модерация с VLM и детекция аномалий.

Что читать дальше

Строите такую систему?

Подберём параметры кодирования под ваш контент и посчитаем стоимость доставки до старта разработки.