Dynamic Resolution Scaling
동적 해상도 스케일링은 프레임 시간 예산을 유지하도록 각 프레임의 처리 해상도를 실시간으로 변경하며, 게임과 실시간 비전 AI에 사용됩니다.
동적 해상도 조정(DRS)은 각 프레임을 처리하는 해상도를 프레임마다 조정하여 프레임당 시간을 고정된 예산 안에 유지하는 기법입니다. 장면 처리 비용이 커지면 렌더러나 모델은 더 적은 픽셀을 사용하고, 여유가 생기면 해상도를 다시 높입니다. 일반적으로 출력은 일정한 디스플레이 크기로 업스케일링됩니다. 비디오 게임은 콘솔과 PC에서 안정적인 프레임 레이트를 유지하기 위해 이 기법을 널리 사용했으며, 같은 원리는 실시간 추론에도 적용됩니다. 이때 컴퓨터 비전 모델은 부하가 높거나 열 스로틀링이 발생하는 하드웨어에서 지연 시간 예산을 지키기 위해 입력 크기를 줄일 수 있습니다.
동적 해상도 스케일링의 작동 방식#
DRS는 피드백 루프입니다. 시스템은 매 프레임마다 GPU에서 이전 프레임들을 처리하는 데 걸린 시간을 측정하고 예산과 비교한 다음, 고정된 범위 안에서 다음 프레임의 해상도 배율을 선택합니다.
"초과"와 "충분히 미만" 사이에 간격을 두면 해상도가 두 단계 사이에서 깜박이는 현상을 막을 수 있습니다. 예를 들어 Unreal Engine의 기본 예산은 프레임당 33.3 ms, 즉 초당 30프레임이며, 화면 비율은 각 축에서 출력 해상도의 50%에서 100% 사이로 움직입니다. 따라서 가장 낮은 설정에서는 픽셀의 4분의 1만 렌더링됩니다.
업스케일링 단계는 낮은 해상도가 화질에 미치는 영향을 결정합니다. 단순한 공간 스케일링은 이미지를 흐리게 만들기 때문에, 최신 게임은 DRS와 함께 NVIDIA DLSS, AMD FSR, Intel XeSS, Sony의 PlayStation Spectral Super Resolution과 같은 학습 기반 또는 시간적 업스케일러를 사용합니다. 이러한 기술은 이전 프레임을 활용하고, 대부분의 최신 버전에서는 딥러닝을 적용해 디테일을 복원합니다. 이러한 복원은 초해상도의 한 형태이며, 눈에 띄는 손실을 거의 일으키지 않으면서 게임을 출력 해상도보다 훨씬 낮은 해상도로 렌더링할 수 있게 합니다.
비전 AI의 동적 해상도#
합성곱 신경망의 연산량과 추론 지연 시간은 입력 픽셀 수에 대략 비례해 증가하므로, 입력의 한 변을 320픽셀로 절반 줄이면 640픽셀 모델의 FLOPs는 약 4분의 1로 감소합니다. 따라서 NVIDIA Jetson과 같은 엣지 AI 장치가 뜨거워져 클록 속도를 낮추거나, 서버가 더 많은 카메라 스트림을 처리하거나, 드론이 내비게이션에 사용할 연산 여유가 필요할 때 컨트롤러는 해상도와 속도를 맞바꿀 수 있습니다. 그 대가로 작은 물체와 멀리 있는 물체의 정확도가 낮아집니다. 저해상도에서는 이러한 물체가 너무 적은 픽셀을 차지하기 때문에 객체 검출 시스템은 입력 크기에 하한을 둡니다.
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 ms 추론 예산으로 전체 크기에서 시작
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 파이프라인의 후반부를 담당하는 경우가 많습니다.
- 적응형 비트레이트 스트리밍: 연산 시간이 아니라 네트워크 대역폭에 맞춰 동영상 품질을 전환합니다.
- 가변 레이트 셰이딩: 프레임 전체의 크기를 조정하는 대신 선택된 영역의 셰이딩 디테일을 낮춥니다.
- 멀티스케일 학습: 추론 해상도가 바뀌어도 정확도를 유지하도록 다양한 입력 크기로 모델을 학습시킵니다.
- 비전-언어 모델의 네이티브 동적 해상도: 각 이미지를 고유한 해상도로 인코딩하여 세부 정보를 보존하는 가변 개수의 토큰을 생성합니다. Alibaba의 Qwen2-VL은 이 기능을 Naive Dynamic Resolution이라고 부릅니다.










