Dynamic Resolution Scaling
動的解像度スケーリングは、フレーム時間の予算を守るため、各フレームの処理解像度を実行時に変更します。ゲームやリアルタイムのビジョンAIで使われます。
動的解像度スケーリング (DRS) は、フレームごとにシステムが処理する解像度を調整し、1フレームあたりの処理時間を一定の予算内に保つ技術です。シーンの処理負荷が高くなると、レンダラーまたはモデルはより少ないピクセルで処理します。余裕ができると、解像度を再び上げます。通常、出力は一定のディスプレイサイズに拡大されます。ビデオゲームでは、コンソールやPCで安定したフレームレートを維持するためにこの技術が広まりました。同じ考え方はリアルタイム推論にも応用でき、コンピュータービジョンモデルは、負荷の高いハードウェアや熱によるスロットリングが発生したハードウェアで、レイテンシ予算内に収まるよう入力サイズを縮小できます。
動的解像度スケーリングの仕組み#
DRSはフィードバックループです。各フレームで、システムはGPU上で直前のフレームの処理にかかった時間を測定し、予算と比較して、固定範囲内で次のフレームの解像度スケールを選択します。
「超過」と「十分に余裕がある」の間に幅を設けることで、解像度が2つのレベル間でちらつくのを防ぎます。たとえばUnreal Engineでは、デフォルトの予算は1フレームあたり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と呼んでいます。










