Dynamic Resolution Scaling
Масштабирование разрешения в реальном времени меняет разрешение обработки каждого кадра на лету, чтобы укладываться в бюджет времени кадра. Этот метод используют в играх и системах компьютерного зрения с ИИ реального времени.
Динамическое масштабирование разрешения (DRS) — это метод, который меняет разрешение обработки каждого кадра, чтобы время обработки кадра не превышало заданный бюджет. При высокой нагрузке рендерер или модель обрабатывает меньше пикселей; когда есть запас ресурсов, разрешение снова повышается, а результат обычно масштабируется до постоянного размера экрана. Метод получил широкое распространение в видеоиграх, помогая поддерживать стабильную частоту кадров на консолях и ПК. Тот же принцип применим к инференсу в реальном времени: модель компьютерного зрения может уменьшать входное изображение, чтобы укладываться в бюджет задержки при высокой нагрузке или троттлинге из-за перегрева оборудования.
Как работает масштабирование динамического разрешения#
DRS — это контур обратной связи. Для каждого кадра система измеряет, сколько времени заняла обработка предыдущих кадров на GPU, сравнивает результат с бюджетом и выбирает масштаб разрешения следующего кадра в заданных пределах:
Разница между «выше бюджета» и «значительно ниже бюджета» не дает разрешению мерцать, переключаясь между двумя уровнями. Например, в Unreal Engine бюджет по умолчанию составляет 33,3 мс на кадр, или 30 кадров в секунду, а масштаб изображения на экране меняется от 50% до 100% выходного разрешения по каждой оси. Таким образом, при минимальном качестве рендерится четверть пикселей.
От этапа масштабирования зависит, насколько сильно пострадает качество из-за снижения разрешения. Простое пространственное масштабирование размывает изображение, поэтому в современных играх DRS сочетают с обучаемыми или временными методами масштабирования, такими как NVIDIA DLSS, AMD FSR, Intel XeSS и PlayStation Spectral Super Resolution от Sony. Они объединяют предыдущие кадры и в большинстве современных версий используют глубокое обучение для восстановления деталей. Это восстановление — разновидность сверхразрешения, которая позволяет игре рендерить изображение со значительно более низким разрешением, почти не теряя заметного качества.
Динамическое разрешение в ИИ для компьютерного зрения#
Для сверточной нейронной сети объем вычислений и задержка инференса примерно пропорциональны количеству входных пикселей. Поэтому уменьшение стороны входного изображения до 320 пикселей сокращает количество FLOPs модели, рассчитанной на 640 пикселей, примерно до четверти. Контроллер может менять разрешение ради скорости, если устройство периферийного ИИ, например NVIDIA Jetson, перегревается и снижает частоту, серверу приходится обрабатывать больше потоков с камер или дрону нужны свободные вычислительные ресурсы для навигации. При низком разрешении страдает точность обнаружения мелких и удаленных объектов, поскольку на них приходится слишком мало пикселей. Поэтому системы обнаружения объектов задают минимальный размер входного изображения.
Ultralytics YOLO26 поддерживает эту возможность непосредственно в режиме predict: модель PyTorch принимает новое imgsz при каждом вызове без перезагрузки, меняя размер каждого кадра так, чтобы его большая сторона соответствовала imgsz, а меньшая дополнялась только до ближайшего числа, кратного шагу 32 пикселя. Модели, экспортированные в форматы со статической формой входных данных, сохраняют размер, с которым были экспортированы, если не задан параметр dynamic=True. Простой контроллер переключается между разрешенными размерами на основе измеренного времени инференса:
import cv2
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
cap = cv2.VideoCapture("https://github.com/ultralytics/assets/releases/download/v0.0.0/decelera_portrait_min.mov")
sizes = [320, 416, 512, 640] # допустимые размеры входных данных, кратные шагу 32 пикселя
level, budget_ms = len(sizes) - 1, 15.0 # начать с полного размера при бюджете инференса 15 мс
frames_at = dict.fromkeys(sizes, 0)
while True:
ok, frame = cap.read()
if not ok:
break
result = model(frame, imgsz=sizes[level], verbose=False)[0]
frames_at[sizes[level]] += 1
# Уменьшать размер при превышении бюджета и увеличивать его только при значительном запасе, чтобы избежать мерцания
if result.speed["inference"] > budget_ms and level > 0:
level -= 1
elif result.speed["inference"] < 0.6 * budget_ms and level < len(sizes) - 1:
level += 1
print("Frames processed at each input size:", frames_at)Вывод показывает, сколько кадров обработано при каждом размере; на более медленном оборудовании большая часть видео обрабатывается при меньших размерах.
Связанные понятия#
- Сверхразрешение: восстанавливает изображение с более высоким разрешением из изображения с более низким разрешением и часто служит второй частью конвейера DRS.
- Адаптивная потоковая передача с переменным битрейтом: меняет качество видео в соответствии с пропускной способностью сети, а не временем вычислений.
- Переменное затенение: снижает детализацию затенения в выбранных областях кадра вместо масштабирования всего кадра.
- Обучение на нескольких масштабах: обучает модель на изображениях разного размера, чтобы она сохраняла точность при изменении разрешения инференса.
- Нативное динамическое разрешение в визуально-языковых моделях: кодирует каждое изображение с исходным разрешением в переменное количество токенов, сохраняя детали. Такой подход используется, например, в Qwen2-VL от Alibaba, где эта реализация называется Naive Dynamic Resolution.










