Real-ESRGAN → OpenVINO INT4

把 Real-ESRGAN 的 RealESRGAN_x4plus (RRDBNet,23 個 RRDB block,16.7 M 參數)轉成 OpenVINO IR,並用 NNCF 做成 INT4 / INT8 / FP16 多種精度版本。所有模型都是純 OpenVINO 推論, 執行時不需要 PyTorch,只要 openvino + opencv + numpy(首次使用會自動從本 repo 下載權重)。

模型 key 檔案 精度 大小 (xml+bin) 說明
int4 models/realesrgan_x4plus_int4_w4a16.* W4A16(權重 u4 per-channel asym,activation FP16) 11.0 MB 純 4-bit,351 個 conv 全部 4-bit,體積最小
int4-mixed models/realesrgan_x4plus_int4_mixed_w4a16.* W4/W8 混合 15.2 MB 約一半權重 4-bit、最敏感的一批保留 INT8,畫質明顯較好
int4-w4a8 models/realesrgan_x4plus_int4_w4a8.* W4A8(權重 4-bit、activation INT8) 11.8 MB 純 4-bit 權重 + INT8 計算路徑
int8 models/realesrgan_x4plus_int8_w8a8.* W8A8 19.5 MB CPU 上最快,畫質/速度最佳平衡點
fp16 models/realesrgan_x4plus_fp16.* FP16 35.1 MB 幾乎無損(對 FP32 約 48 dB),當作 reference 基準
fp32 用 export_openvino_int4.py 產生 FP32 66.8 MB 未壓縮,僅供對照/量測 PSNR 用

原始 PyTorch 權重檔:RealESRGAN_x4plus.pth(67 MB,來自 Real-ESRGAN v0.1.0 release), checkpoint 內的 key 是 params_ema。本 repo 的轉換管線已驗證 與 BasicSR RRDBNet 逐 bit 相同 (max|diff| = 0.0)。


1. 實測結果

測試機:Intel Xeon Platinum 8559C(Emerald Rapids,16 vCPU,含 AMX-INT8 / AVX512-VNNI / AVX512-FP16)、 OpenVINO 2026.4.1、tile=128、tile_pad=16。

畫質(3 張 inputs/ 測試圖,PSNR / SSIM 對 fp16 版本;fp16 與 PyTorch FP32 差異 < 0.3 dB):

模型 大小 PSNR ↑ SSIM ↑ PSNR vs. 原圖 ↑(bicubic LR 輸入)
fp16 35.1 MB 基準 1.0000 18.90 dB
int8 (W8A8) 19.5 MB 29.62 dB 0.927 19.25 dB
int4-mixed 15.2 MB 24.73 dB 0.897 17.77 dB
int4 (W4A16) 11.0 MB 18.41 dB 0.679 16.83 dB
int4-w4a8 11.8 MB 18.72 dB 0.618 16.95 dB

速度(合成 512×256 輸入、tile=128、取 3 次最佳):

模型 秒 / 張 輸入 MPix/s 備註
int8 (W8A8) 1.30 s 0.10 AMX/VNNI INT8 路徑,比 FP32 快約 1.9×
fp16 2.48 s 0.05
int4-mixed 2.28 s 0.06
int4 (W4A16) 2.32 s 0.06
int4-w4a8 2.49 s 0.05 INT8 quantize/dequantize 節點反而稍慢

為什麼 INT4 沒有比較快?

OpenVINO CPU plugin 執行 u4 權重時會在 runtime 解壓回 FP32/FP16 再做卷積, 所以 4-bit 的收益是 模型體積 / 記憶體(4×)而不是速度;要速度請用 int8(W8A8)。 4-bit 權重大多數時候適合「記憶體受限 / 想把模型塞進邊緣裝置 / 減少下載量」的場景。

為什麼 INT4 畫質掉得比較多?

Real-ESRGAN 是純卷積的深層殘差網路(23 個 RRDB,每層輸出 x*0.2 + conv(x)), 誤差會沿 351 層累積。4-bit 每層權重 SQNR 只有 ~17 dB,累積後 PSNR 掉到 ~18 dB。 因此本 repo 同時提供:

  • int4-mixed:由 NNCF 敏感度分析挑出「最不能壓」的層保留 INT8,其餘 4-bit → 幾乎無損的畫質(SSIM 0.90+),大小只多 38%。
  • int8:想要又快又準就用這個。

1.5 效果對比(同一張圖:原始 PyTorch vs 各個 OpenVINO 版本)

測試照片是 NASA 肯尼迪太空中心的公有領域白頭海雕照片 (KSC-20230425-PH-JBS02_0003), 裁切 1024×768 當 Ground Truth,bicubic 降 4 倍成 256×192 餵進模型, 所有模型都用 tile=128 推論成 768×1024。

細節並排比較(左上 bicubic、右上原始 PyTorch FP32、中上 FP16、左下 INT8、下中 INT4 混合、右下純 INT4):

detail montage

模型 大小 PSNR vs PyTorch FP32 ↑ SSIM ↑ PSNR vs 原圖 ↑ 推論時間
pytorch_fp32(原始 PyTorch,基準) 67.0 MB 基準 1.0000 20.12 dB 4.46 s
bicubic x4(對照) – 22.54 dB 0.7049 21.70 dB –
openvino_fp16.jpg 35.1 MB 48.38 dB 0.9981 20.14 dB 0.60 s
openvino_int8_w8a8.jpg 19.5 MB 27.76 dB 0.8675 20.39 dB 0.39 s
openvino_int4_mixed_w4a16.jpg 15.2 MB 22.84 dB 0.8160 18.68 dB 0.61 s
openvino_int4_w4a16.jpg 11.0 MB 18.02 dB 0.4879 17.19 dB 0.60 s
openvino_int4_w4a8.jpg 11.8 MB 17.89 dB 0.4624 17.09 dB 0.69 s

重現方式、完整檔案清單與說明見 **samples/eagle_4x/README.md**, 照片授權為 NASA 公有領域(Public Domain)。


1.6 影片對比(放大前 vs 各個量化版本,repo 內可直接播放)

除了靜態圖,repo 也放了一段公有領域的 NASA 影片(ISS 氣輝夜景,GSFC_20181022_ICON_m12902_Airglow), 用原始 PyTorch 模型與所有 OpenVINO 版本做 640×360 → 2560×1440 的 4 倍放大,逐影格記錄時間與畫質。

① 放大前(模型輸入,640×360,1.5 s / 45 影格)

② 並排比較影片(bicubic / PyTorch FP32 / FP16 / INT8 / INT4 mixed / INT4,含標籤)

若播放器不支援 HTML video,可直接看這支 GIF:

side by side gif

③ 各個模型的 4x 放大影片(2560×1440)

原始 PyTorch FP32(放大後)

OpenVINO FP16

OpenVINO INT8(W8A8)

OpenVINO INT4 混合精度(W4/W8)

OpenVINO 純 INT4(W4A16)

④ 城市燈光帶 1:1 放大比較(最能看出量化差別)

video zoom

⑤ 時間與畫質紀錄

模型 大小 45 影格總時間 ms/影格 張/秒 vs PyTorch PSNR ↑ SSIM ↑ 加速比 ↑
pytorch_fp32(原始) 67.0 MB 663.5 s 14745 0.07 基準 1.0000 1.0×
openvino_fp16 35.1 MB 211.5 s 4700 0.21 45.41 dB 0.9927 3.1×
openvino_int8_w8a8 19.5 MB 124.8 s 2773 0.36 36.90 dB 0.9284 5.3×
openvino_int4_mixed_w4a16 15.2 MB 214.6 s 4769 0.21 31.31 dB 0.9344 3.1×
openvino_int4_w4a16 11.0 MB 246.8 s 5485 0.18 25.40 dB 0.7894 2.7×

直接下載:samples/video_airglow/00_source_lr.mp4、10_pytorch_fp32_4x.mp4、11_openvino_fp16_4x.mp4、 12_openvino_int8_w8a8_4x.mp4、13_openvino_int4_mixed_4x.mp4、14_openvino_int4_4x.mp4、 20_side_by_side_1920x780.mp4(完整說明見 samples/video_airglow/README.md)

重點結論:INT8 (W8A8) 在 CPU 上比 PyTorch FP32 快 5.3× 且畫質僅 36.9 dB / SSIM 0.93; INT4 在 CPU 上不會更快(CPU plugin 執行時會把 4-bit 權重解壓回 FP32/FP16), 它的優勢是模型只有 11 MB;若要在 4-bit 尺寸下兼顧畫質,請用 int4-mixed。

Intel GPU(NPU / AUTO 同理)可以執行嗎?

可以。這些都是標準 OpenVINO IR(動態 shape),不綁定 plugin,-d GPU / -d NPU / -d AUTO / -d HETERO 都能跑:

python realesrgan_ov.py -i input.jpg -d GPU -m int8 -t 128     # Intel GPU 上推薦 INT8
python realesrgan_ov.py -i input.jpg -d AUTO -m fp16            # 自動挑最快裝置
模型 Intel GPU 支援 說明
fp16 ✅ Xe / Arc 上 FP16 有硬體加速;更舊的 UHD/Iris 會以 f32 執行
int8 (W8A8) ✅ GPU 上最快 GPU plugin 對 INT8 卷積有最佳路徑(Xe-LP+ / Arc / Alchemist)
int4-mixed / int4 / int4-w4a8 ⚠️ 可執行、通常不快 GPU plugin 支援 4-bit 權重,但卷積沒有 4-bit 加速路徑,會在 runtime 解壓成 FP16/FP32;收益只有 VRAM。純 4-bit 的模型還多了 dequantize 節點,GPU 上反而變慢
fp32 ✅ 相容但最慢,僅供對照

若要給 Intel GPU 專用的量化模型(INT8 的 activation 範圍與 SmoothQuant 會依 GPU 特性不同而調整):

python export_openvino_int4.py --weights RealESRGAN_x4plus.pth --target-device gpu \
    --a8-bits 8 --a8-name int8_w8a8_gpu --no-w4a16

備註:本 repo 的模型是在沒有 GPU 的機器上驗證的(available_devices = ['CPU']), 以上 Intel GPU 的說明是依 OpenVINO plugin 的能力整理,不是本機實測數據。


2. 安裝

pip install openvino opencv-python numpy huggingface_hub
# 只有要「自己重新轉換模型」才需要:
pip install torch onnx onnxscript nncf

realesrgan_ov.py 會在第一次執行時自動從本 repo 下載 *.xml / *.bin, 並快取到 ~/.cache/realesrgan_openvino(可用環境變數 REALESRGAN_OV_CACHE 改位置)。 也可以手動下載後用 --model-path / -m /path/to/model.xml 指定本機檔案。


3. 快速開始:單一 py 檔

下載兩個檔案即可(realesrgan_ov.py + benchmark_models.py),模型會自動下載。

# quick_start.py
import cv2
from realesrgan_ov import RealESRGAN

upscaler = RealESRGAN(model='int4')              # int4 | int4-mixed | int8 | fp16 | 自訂 .xml 路徑
img = cv2.imread('input.jpg')                     # BGR uint8
sr, scale = upscaler.enhance(img, tile=128)       # 4 倍超解析(記憶體吃太多時用 tile 分塊)
cv2.imwrite('output.png', sr)
print('output:', sr.shape, 'scale:', scale)

inputs/ 內附 3 張測試圖(來自 Real-ESRGAN 官方 inputs),samples/ 內附 1 張公有領域照片與 1 段公有領域影片(都已用所有模型跑過),可直接試跑:

python realesrgan_ov.py -i inputs/00003.png -o results/ -m int4-mixed -t 128
# 命令列
python realesrgan_ov.py -i input.jpg                     # 4x 超解析,輸出 results/
python realesrgan_ov.py -i ./photos -o out/ -m int8      # 整個資料夾
python realesrgan_ov.py -i clip.mp4 -o clip_4x.mp4      # 影片逐影格
python realesrgan_ov.py -i big.png -t 64 --tile-pad 16   # 大圖分塊(256→1024 這類)
python realesrgan_ov.py -i input.jpg --outscale 2        # 只放大 2 倍(先 4x 再 downscale)
python realesrgan_ov.py -d GPU -m int8 -i input.jpg      # 用 GPU / NPU / AUTO
python realesrgan_ov.py --benchmark --images input.jpg   # 只測效能
python benchmark_models.py --images a.png b.png          # 比較所有版本的畫質/速度

支援 PNG/BMP/JPG/WEBP(含 alpha 通道,alpha 會用 bicubic 放大)、資料夾遞迴、影片(mp4/avi/mov/mkv)。


4. Python API

from realesrgan_ov import RealESRGAN

up = RealESRGAN(
    model='int4',        # int4 / int4-mixed / int4-w4a8 / int8 / fp16 / '/path/model.xml'
    device='CPU',        # CPU / GPU / NPU / AUTO
    precision='auto',    # auto(預設)/ f32 / f16 / bf16
    num_threads=8,       # 0 = 使用全部核心
)

sr, scale = up.enhance(img, tile=128, tile_pad=16, pre_pad=0, outscale=4)
sr_bgra   = up.enhance_alpha(bgra_img, tile=128)     # 自動處理 alpha

precision 說明(很重要):新版 OpenVINO CPU 對 FP32 graph 的預設 INFERENCE_PRECISION_HINT 是 bf16,會讓這個網路的 PSNR 掉約 20 dB。 realesrgan_ov.py 的 auto 會對 FP32/FP16/INT4(FP16 activation) 的模型自動釘成 f32, INT8 graph 不受影響。若你自己用 ov.Core().compile_model(),請記得傳 {'INFERENCE_PRECISION_HINT': 'f32'}。


5. 從 PyTorch 權重重新轉換成 OpenVINO INT4

python export_openvino_int4.py \
    --weights RealESRGAN_x4plus.pth \
    --data-dir inputs \        # 校準用的低解析度圖
    --out-dir models \
    --calib-tile 128 --calib-samples 6 \
    --weight-ratio 1.0 \       # 1.0 = 全部 4-bit;0.5 = 一半 4-bit、其餘 INT8
    --a8-bits 8 --a8-name int8_w8a8

流程:RRDBNet(重建) → strict=True 載入 checkpoint → ONNX(opset17, 動態 H/W) → OpenVINO FP32/FP16 → NNCF 量化 → IR

這個管線裡有兩個必須處理的地方(否則 INT4 會被靜默降級成 INT8):

  1. nncf.compress_weights(mode='int4_*') 預設只把 MatMul 壓成 4-bit,卷積一律落到 INT8 backup → enable_int4_for_convolutions() 擴充 _get_ratio_defining_params,讓 Conv 也吃 4-bit。
  2. NNCF 的 CPU hardware config 只允許 8/16-bit 權重 → enable_int4_weights_in_cpu_hw_config() 把 q4_w 加進 Convolution 的 qspace,產生 u4 常數(OpenVINO CPU plugin 可執行)。
  3. openvino.convert_model() 預設會把權重壓成 FP16(本模型會掉到 ~27 dB)→ convert_onnx() 以 compress_to_fp16=False 轉換,得到真正的 FP32 graph。

驗證方式(本 repo 產出的模型都跑過):

python - <<'PY'
from openvino import Core
m = Core().read_model('models/realesrgan_x4plus_int4_w4a16.xml')
print(sorted({str(n.get_element_type()) for n in m.get_ops() if n.get_type_name() == 'Constant'}))
PY
# 應該看到 '<Type: 'uint4_t'>',代表權重真的是 4-bit

export_openvino_int4.py 也能轉換其他 Real-ESRGAN 權重,只要架構相同(--stem 改檔名):

  • RealESRGAN_x4plus.pth(本 repo 使用,num_feat=64 / num_block=23 / num_grow_ch=32)
  • RealESRNet_x4plus.pth、RealESRGAN_x4plus_anime_6B.pth、RealESRGAN_x2plus.pth(需在 rrdbnet_arch.py 對應調整 scale / num_block / num_feat)

6. 疑難排解

症狀 原因 / 解決
輸出整張有雜訊、幾乎是亂圖 用了 int4:Real-ESRGAN 對 4-bit 非常敏感,請改用 int4-mixed 或 int8
輸出整體偏色 / 邊緣有雜訊 沒有指定 INFERENCE_PRECISION_HINT='f32',CPU 預設跑 bf16。用 precision='f32' 或 -m int8
大圖 OOM 用 -t 128(或 64)分塊,--tile-pad 16;不要 -t 0
分塊後有接縫 --tile-pad 調大到 20~32
下載權重失敗 export HF_TOKEN=hf_xxx(私有 repo)或先手動下載 models/*.xml *.bin 後用 -m 指定
匯出時 KeyError: 'input' LWC 傳入 dataset 的已知問題,script 預設不傳(--lwc-dataset 可開啟 AWQ / scale-estimation)
想改輸出的放大倍率 --outscale 2(>4 會再 cubic 放大)

7. 出處與授權

  • 程式碼/權重出處:xinntao/Real-ESRGAN、XPixelGroup/BasicSR(Apache-2.0)
  • rrdbnet_arch.py 為 BasicSR RRDBNet 的獨立重寫(不需安裝 BasicSR),參數名稱與官方 checkpoint 完全一致
  • 量化:OpenVINO NNCF
  • 本 repo 的推論程式、轉換腳本與本說明文檔為本專案新增。
  • 樣品照片:NASA Kennedy Space Center(公有領域),見 samples/eagle_4x/README.md 的來源與授權說明
  • 樣品影片:NASA/Goddard ICON 任務 ISS 氣輝畫面(公有領域),見 samples/video_airglow/README.md
  • License:Apache-2.0(見 LICENSE)。
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support