把 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):
| 模型 |
大小 |
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:
③ 各個模型的 4x 放大影片(2560×1440)
原始 PyTorch FP32(放大後)
OpenVINO FP16
OpenVINO INT8(W8A8)
OpenVINO INT4 混合精度(W4/W8)
OpenVINO 純 INT4(W4A16)
④ 城市燈光帶 1:1 放大比較(最能看出量化差別)
⑤ 時間與畫質紀錄
| 模型 |
大小 |
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。
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):
nncf.compress_weights(mode='int4_*') 預設只把 MatMul 壓成 4-bit,卷積一律落到 INT8 backup
→ enable_int4_for_convolutions() 擴充 _get_ratio_defining_params,讓 Conv 也吃 4-bit。
- NNCF 的 CPU hardware config 只允許 8/16-bit 權重 →
enable_int4_weights_in_cpu_hw_config()
把 q4_w 加進 Convolution 的 qspace,產生 u4 常數(OpenVINO CPU plugin 可執行)。
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)。