Содержание статьи +
- Кратко
- Зачем Это Важно
- Что На Самом Деле Означает «Предобработка» В CV-Проекте
- Рынок Computer Vision В 2026 – Почему Цифры Ниже Значимы Сегодня
- Цветовая Ловушка – Первая Ошибка В Каждом CV-Проекте
- Выборка Кадров – Число, Которое Решает Всё Остальное
- Пространственные Преобразования – Resize, Crop, Pad И Почему Соотношение Сторон Кусает Детекторы
- Нормализация – Константы, Которые Стоят 10 Пунктов, Если Их Пропустить
- Временная Батчизация И Пропускная Способность – Почему GPU Загружен На 23%
- Выбор Декодера – OpenCV, PyAV, Decord, Torchcodec, NVIDIA DALI
- Аугментация – Паттерны, Которые Дают Реальные Пункты
- Типичные CV-Проекты 2026 И Их Спецификация Предобработки
- Где Тут Фора Софт
- Ключевые Выводы
- Что Читать Дальше
Кратко
Любой 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 при полной chroma-разрешённости (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-CNN это окно из 8, 16, 32 или 64 кадров. Для видео-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. Решение: брать константы из карточки модели и проверять их санити-чеком на held-out батче.
Шаг батчизации собирает кадры в тензоры и отправляет на ускоритель. Статическая батчизация (всегда 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 для image-уровня и семейство TimeMix для видео; при правильной настройке они дают 1–4 пп точности на held-out.
Самый большой инженерный выигрыш в CV-проекте – назвать эти семь шагов явно и приписать к каждому число (бюджет точности). «Модель даёт 92%» – это не спецификация; «модель теряет 0,5% на цветовом дрейфе декодера, 1,2% на неправильных константах нормализации, 0,8% на bilinear-вместо-bicubic ресайзе, 2,1% на временном алиасинге, итого 92%» – это уже спецификация, которую можно отладить.
Рынок Computer Vision В 2026 – Почему Цифры Ниже Значимы Сегодня
До того, как пойти глубже в инженерию, важна коммерческая картина – она задаёт цену неправильного решения. Мировой рынок computer vision в 2026 оценивается аналитиками в USD 24–35 млрд в зависимости от того, какой срез считают: Fortune Business Insights оценивает широкий рынок в USD 24,14 млрд с ростом до USD 72,80 млрд к 2034, Grand View Research и Mordor Intelligence ставят 2026 год около USD 32–35 млрд, Coherent Market Insights прогнозирует более узкий сегмент «AI in computer vision» в USD 34,94 млрд при CAGR 32,8% до 2033. Северная Америка держала около 34,3% рынка в 2025; Азиатско-Тихоокеанский регион – самый быстрорастущий. По применениям лидируют: контроль качества в производстве, ассистенты водителя и автономия в автопроме, ритейл-аналитика, медицинская визуализация и видеонаблюдение – примерно в этом порядке по выручке.
Для решений по предобработке важны цифры ниже по уровню. Типичный 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. С аналоговыми full-range коэффициентами она сводится к: R = Y + 1,5748 (Cr − 128), G = Y − 0,1873 (Cb − 128) − 0,4681 (Cr − 128), B = Y + 1,8556 (Cb − 128). Но реальное видео редко идёт в full range. Большинство камер пишет в studio range (он же limited range, он же TV range): 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.2020 | BT.709 или BT.2020, studio range |
| 4K HDR-камера (HDR10 / PQ) | BT.601, studio range | Читает метаданные, BT.2020 + PQ | BT.2020, PQ-перенос, studio range |
| Смартфонная камера | BT.601, studio range | Читает метаданные, обычно BT.709 + sRGB | BT.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) или только key-frame (1–2 fps). Правильное число зависит исключительно от события, которое нужно поймать. Падение человека ловится при 6 fps, потому что падение длится больше секунды; номер машины на трассе нужно ловить при 30 fps, потому что номер виден меньше секунды. Стоимость линейна по числу обрабатываемых кадров – то есть вопрос сводится к самому медленному событию в спецификации заказчика.
Window-based модели – 3D-CNN (I3D, SlowFast), видео-трансформеры (TimeSformer, VideoSwin, VideoMAE) и большинство action recognisers – работают на окне из 8, 16, 32 или 64 кадров. Временной stride окна (как далеко друг от друга в источнике стоят выбранные кадры) – параметр, который чаще всего ломают. Kinetics-претренированный SlowFast ждёт slow-pathway при stride 16 (один кадр из шестнадцати, охват ~2 с при 30 fps) и fast-pathway при stride 2 (один из двух, ~1 с). Подайте ему 16 подряд идущих кадров при 30 fps – он увидит одну двенадцатую того временного контекста, на котором обучался; точность падает на 8–14 пунктов. Лечение – читать stride с карточки модели и его соблюдать.
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-fps cadence стоит 3,3% от 30-fps cadence на той же модели. Выбирайте самую медленную каденцию, на которой всё ещё ловится класс события.
Рабочий пример. В ритейл-магазине 80 камер снимают 1080p при 30 fps. Продакт хочет ловить шоплифтера, кладущего товар в сумку, – событие длится 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 потоков, то есть два магазина на одну L4. На 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-frame | Editorial / search кейсы | Real-time оповещение | Переменно, обычно <1% |
Рисунок 3. Каденция выборки кадров жёстко связывает латентность, точность и стоимость. Выбирайте самую медленную каденцию, на которой ловится класс события, а не самую быструю, которую можете оплатить.
Распространённая ошибка – пересэмплить, потому что «камера снимает 30 fps, надо использовать всё». Зеркальная ошибка – недосэмплить, потому что «модели хватает 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 быстрый и адекватный для большинства ratio. Bicubic чуть точнее на downsampling и стандарт для арт-задач. 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-экспортов CV-моделей под edge-инференс. Константы зашиты в граф модели.
Промах с константами – это 2–8 пп точности на хорошо настроенной модели и 10–25 пунктов на менее настроенной. Лечение – копировать константы из карточки модели, прогонять санити-чек на held-out батче (предсказать 100 картинок, сравнить с опубликованным бенчмарком, бить тревогу, если разрыв больше 0,5 пп), и никогда не доверять дефолту из туториала.
Лекарство экосистемы 2026 – сама карточка модели. Hugging Face Model Cards выставляют константы нормализации в 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 раз больше, чем должен быть, и post-mortem обвиняет «модель» вместо батчизации.
Статическая батчизация («всегда batch=8») – самый простой паттерн и правильный для одного продюсера, кормящего одного консьюмера. Падает, как только продюсер становится «бёрсти», – мульти-камерный surveillance feed, где иногда 80 камер одновременно видят движение. GPU ждёт, пока batch=8 наберётся, потом стреляет, потом снова простаивает. Пропускная способность ниже 50% от номинала GPU.
Динамическая батчизация («собирать 20 мс, потом отправлять») – продакшн-паттерн. Triton Inference Server, TorchServe и vLLM выставляют динамическую батчизацию как first-class feature. Две ручки: максимальный размер батча (ограничен памятью 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 секунд). При static batch = 1 пропускная способность – 50 клипов за 5 с = 10 клипов/с; L4 на 8% загружен. При static batch = 8 пропускная способность поднимается до 28 клипов/с, но время сбора батча – 1,6 с, бюджет провален. При динамической батчизации с max wait = 20 мс и max batch = 16 пропускная способность – 80 клипов/с, латентность 50–60 мс, GPU сидит на 84%, облачный счёт падает в 4,5 раза. Та же модель, то же железо, та же нагрузка; разницу делает батчизация.
Co-design железо-софт – вторая часть. NVIDIA Triton Inference Server (всё ещё продакшн-дефолт в 2026) поддерживает динамическую батчизацию из коробки и работает с TensorRT-LLM, vLLM и любой PyTorch- или TensorFlow-моделью. Проект vLLM стал доминирующим инференс-движком для VLM и поддерживает continuous batching, который ещё эффективнее фиксированной динамической батчизации для LLM-стилевого decode-цикла. Для не-VLM image-моделей ONNX Runtime + Triton или PyTorch + Triton остаются безопасным выбором.
Выбор Декодера – OpenCV, PyAV, Decord, Torchcodec, NVIDIA DALI
Декодер – первое звено цепи, и выбор декодера значит для пропускной способности больше, чем команды осознают. Пять библиотек доминируют в экосистеме 2026.
OpenCV (cv2.VideoCapture) – самый простой. Оборачивает FFmpeg, держит большинство контейнеров, отдаёт пайтоновский кадр-за-кадром API. Два режима отказа: тихо предполагает BT.601 (см. выше) и копирует каждый декодированный кадр из буфера FFmpeg в буфер OpenCV, удваивая нагрузку на память. Для прототипа годится; для продакшна в масштабе – неправильный дефолт.
PyAV – обёртка FFmpeg, на которой оседает большинство продакшн-команд. Выставляет каждую ручку FFmpeg – цветовое пространство, диапазон, аппаратное декодирование через NVDEC / VAAPI / VideoToolbox, формат контейнера – и отдаёт декодированный кадр как numpy-массив с метаданными. Кривая обучения круче, чем у OpenCV; пропускная способность на одном CPU-потоке примерно 2× от OpenCV – потому что нет двойного копирования.
Decord (dmlc/decord) – DL-специализированный ридер. Поддерживает случайный доступ в файле («дай кадры 100, 250, 400»), GPU-декодирование через NVDEC и встроенный батч-API, возвращающий numpy-тензор из N кадров. Пропускная способность на одном GPU – 10–30× от CPU PyAV-пайплайна. Цена – меньше фич, чем у PyAV: меньше контейнеров, меньше энкодер-ручек. Для инференс-нагрузок с известным фиксированным кодеком Decord – правильный дефолт.
TorchCodec – новый (со середины 2024) PyTorch-нативный видео-ридер. Возвращает декодированные кадры прямо как torch.Tensor на GPU, поддерживает любой кодек, который держит установленный FFmpeg, и интегрируется с PyTorch DataLoader без копии numpy → tensor. Команда PyTorch инвестирует в TorchCodec как в долгосрочную замену ad-hoc API read_video; правильный выбор для новых PyTorch-проектов.
NVIDIA DALI (nvidia.dali) – самый тяжёлый и самый перформантный вариант. Полный data-processing-пайплайн (decode + augment + batch), работающий end-to-end на GPU, – снимает CPU-боттлнек полностью. Пропускная способность на A100 – 5–15× от Decord-пайплайна. Цена – операционная сложность: у DALI свой DSL, свой дебаггер и кривая обучения, на которую сеньёр-инженеру нужна неделя. Для high-volume тренировки на NVIDIA-железе (выше 1 млн клипов на тренинг-ран) – правильный дефолт; ниже – простые библиотеки лучше.
| Библиотека | Лучшее применение | Пропускная способность на 1080p клипе (1 поток) | Production-grade | Заметки |
|---|---|---|---|---|
| OpenCV | Прототипы, single-camera демо | ~30 fps | Нет в масштабе | Неправильный цветовой дефолт |
| PyAV | Продакшн CPU-пайплайны | ~60 fps | Да | Безопасный дефолт |
| Decord | Random-access dataloading | ~200 fps (GPU NVDEC) | Да | Создан под ML-батчи |
| TorchCodec | Новые PyTorch-проекты | ~150 fps (GPU NVDEC) | Да | Тензоры PyTorch-нативно |
| NVIDIA DALI | High-throughput тренировка | ~600 fps (GPU, с аугментацией) | Да | Сложный, только GPU |
Рисунок 5. Пять доминирующих видео-декодеров для ML-пайплайнов в 2026 с пропускной способностью на 1080p клипе и best-fit применением.
Аугментация – Паттерны, Которые Дают Реальные Пункты
Шаг аугментации – последнее инженерное решение в цепочке предобработки, и здесь у хорошо настроенного проекта ещё лежат 1–4 пп точности. Доминирующие image-level паттерны 2026 известны; видео-специфичные временные – известны хуже.
Image-level аугментация – зрелая. Random crop, horizontal flip, colour jitter, random erasing и семейство policy-based методов (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 поверх no-augmentation baseline.
Mixup, CutMix и варианты MixUp садятся сверху. Image-level Mixup микширует две картинки и их лейблы в фиксированной пропорции; CutMix вставляет квадрат одной картинки в другую. Для видео есть VideoMix (3D-версия CutMix) и более новый TubeMix, который микширует под-объёмы одного клипа в другой. Лифт точности стабильный (1–2 пп на action recognition бенчмарках), стоимость в тренировке по сути нулевая.
Ловушка, в которую часто падает команда, – переаугментация. Четырёхступенчатый пайплайн (random crop + flip + colour jitter + RandAugment + Mixup) на маленьком датасете даёт модель, выучившую политику аугментации не меньше, чем саму задачу. Лечение – провести небольшую ablation: обучать без каждой аугментации, измерять просадку – и оставить только те, которые дают минимум 0,3 пп.
Типичные CV-Проекты 2026 И Их Спецификация Предобработки
Всё до этого было общим. Спецификация предобработки меняется по use case. Шесть паттернов ниже покрывают примерно 80% продакшн-проектов CV, которые мы видим в 2026.
Real-time детекция объектов на surveillance-видео (доминирующий CV-проект по числу). Вход камеры: 1080p H.265 при 30 fps. Декодер: PyAV с явным BT.709 + studio range. Выборка: 6–10 fps. Letterbox-resize в 640×640. Без нормализации (Ultralytics YOLOv11 берёт 0–255 uint8). Static batch = 1 на камеру, dynamic batch = 16 на инференс-сервере. Аугментация в тренировке: random crop + flip + mosaic + Mixup. Ожидаемая точность: 88–92% mAP@50 на доменно-адаптированной модели; 80–85% на Roboflow / Ultralytics претрене без адаптации.
Action recognition на архивном видео (OTT, security, e-learning). Вход: 480p–1080p H.264 при 24–30 fps. Декодер: Decord с GPU NVDEC. Выборка: окно 32 кадра с временным stride, соответствующим Kinetics-претренированной модели (обычно stride 2 для fast pathway, stride 16 для slow pathway в SlowFast). Centre-crop в 224×224 после resize-shortest-side=256. ImageNet-нормализация. Padded batch = 8 в тренировке, dynamic – в инференсе. Аугментация: temporal crop + RandAugment + Mixup. Ожидаемая точность: 85–90% на Kinetics-400 на дообученном SlowFast или VideoSwin.
Pose-трекинг для фитнеса или телехелса. Вход: 1080p с телефонной камеры, 30 fps по WebRTC. Декодер: клиент через MediaStreamTrack и OffscreenCanvas; на сервере – PyAV или Decord. Выборка: каждый кадр для трекинга, каждый 5-й для оценки. Resize в 256×256. Без нормализации (MediaPipe Pose v2 берёт uint8). Static batch = 1 на поток (латентность-bound). Аугментация: scale + flip + малое вращение; переаугментация вредит, потому что ground-truth лейблы позы точные. Ожидаемая MPJPE: 30–50 мм на indoor-сессиях, 50–80 мм на шумных outdoor или low-light.
Детекция лиц для модерации или посещаемости. Вход: разрешение разное (480p–4K). Декодер: PyAV. Выборка: один кадр на face-encounter (быстрый детектор + трекер решает, какой кадр оставить). Resize под вход детектора – 416×416 для legacy MTCNN, 640×640 для YOLOv8-Face, 320×320 для SCRFD. ImageNet или detector-specific нормализация. Dynamic batch на инференс-сервере. Аугментация в тренировке: фотометрическая + малый scale jitter; без horizontal flip, если модель ещё предсказывает атрибут «лево / право». Ожидаемая точность: 95%+ AP при 0,5 IOU на 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.
Детекция аномалий на surveillance-видео. Покрыто end-to-end в уроке 2.15; спецификация предобработки там: PyAV с BT.709, 10-секундные клипы при 6 fps, 16-кадровая равномерная выборка на клип, 224×224 centre crop, ImageNet-нормализация, dynamic batch = 8 на edge-инференс-сервере.
Где Тут Фора Софт
Фора Софт отгружает видео-продукты с 2005 года и computer vision проекты – с 2018: видеонаблюдение и intelligent video analytics, OTT-модерация, телемедицинская сортировка, e-learning attention analytics, AR-фитнес-коучинг, плюс несколько закрытых индустриальных систем визуального контроля. Пайплайн предобработки выше – объединение того, что мы отгрузили, того, что у нас ломалось в продакшне, и того, что мы пересобирали. Мы не продаём CV-продукт; мы встраиваем CV-пайплайн в ваш. Разговор, на котором подключается наша команда, обычно начинается с одностраничного worksheet – того самого, который мы упаковали как компаньон-загрузку к статье, – где идут восемь чисел, на которые новый проект обязан ответить раньше выбора модели.
Ключевые Выводы
- Предобработка видео – семиступенчатый пайплайн; у каждого шага свой бюджет точности. Перед тюнингом модели аудитируйте все семь.
- Дефолтный декодер OpenCV молча предполагает BT.601 + studio range – неверно для большинства современных 1080p+ камер. В продакшне используйте PyAV, Decord, TorchCodec или DALI.
- Выбирайте самую медленную каденцию кадров, которая всё ещё ловит класс события. 6 fps заменяют 30 fps в большинстве surveillance-задач и режут стоимость в пять раз.
- Константы нормализации – model-specific. Копируйте с карточки модели, не из туториала; цена ошибки – 10–25 пунктов точности.
- Динамическая батчизация на Triton или vLLM поднимает утилизацию GPU с 23% до 75–90% на той же нагрузке. Static batching – неправильный дефолт в масштабе.
- Шесть продакшн use case покрывают ~80% проектов: детекция объектов, action recognition, поза, лицо, VLM-модерация, детекция аномалий.
Что Читать Дальше
- Урок 2.2 – YOLO Production Lineage: v8, v9, v10, v11, v12 – самое отгружаемое семейство real-time детекторов.
- Урок 2.15 – Детекция аномалий в видео – инженерный плейбук 2026 – слоистый стек, который отгружает реальный продукт.
- Урок 1.4 – Реальная стоимость ИИ в видео-продуктах – модель стоимости за каждым решением по выборке и батчизации.