Download benchmark_models.py from HelloSun/Real-ESRGAN-OpenVINO: direct link, hf CLI and curl.
- Browser
- Download file 4.02 kB
-
https://huggingface.co/HelloSun/Real-ESRGAN-OpenVINO/resolve/main/benchmark_models.py
- Command line
-
hf download hf://HelloSun/Real-ESRGAN-OpenVINO/benchmark_models.py
-
curl -L -o benchmark_models.py https://huggingface.co/HelloSun/Real-ESRGAN-OpenVINO/resolve/main/benchmark_models.py
4.02 kB
| #!/usr/bin/env python3 | |
| """Benchmark the OpenVINO Real-ESRGAN variants (quality + speed), no PyTorch needed. | |
| Every model is compared against the FP16 model, which reproduces the original | |
| PyTorch `RealESRGAN_x4plus` result to ~48 dB. | |
| python benchmark_models.py # default set, synthetic input | |
| python benchmark_models.py --images a.png b.png # real images | |
| python benchmark_models.py --models int4 --models int8 | |
| """ | |
| import argparse | |
| import os | |
| import pathlib | |
| import time | |
| import cv2 | |
| import numpy as np | |
| from realesrgan_ov import MODELS, RealESRGAN, _download_model | |
| HERE = pathlib.Path(__file__).resolve().parent | |
| def psnr(a, b, peak=255.0): | |
| mse = np.mean((a.astype(np.float64) - b.astype(np.float64)) ** 2) | |
| return 99.0 if mse == 0 else 10 * np.log10(peak ** 2 / mse) | |
| def ssim(a, b): | |
| c1, c2 = 0.01 ** 2, 0.03 ** 2 | |
| a = cv2.cvtColor(a, cv2.COLOR_BGR2GRAY).astype(np.float64) / 255. | |
| b = cv2.cvtColor(b, cv2.COLOR_BGR2GRAY).astype(np.float64) / 255. | |
| mu_a, mu_b = cv2.GaussianBlur(a, (11, 11), 1.5), cv2.GaussianBlur(b, (11, 11), 1.5) | |
| sa = cv2.GaussianBlur(a * a, (11, 11), 1.5) - mu_a ** 2 | |
| sb = cv2.GaussianBlur(b * b, (11, 11), 1.5) - mu_b ** 2 | |
| sab = cv2.GaussianBlur(a * b, (11, 11), 1.5) - mu_a * mu_b | |
| return (((2 * mu_a * mu_b + c1) * (2 * sab + c2)) / ((mu_a ** 2 + mu_b ** 2 + c1) * (sa + sb + c2))).mean() | |
| def main(): | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument('--models', nargs='+', default=['fp16', 'int8', 'int4', 'int4-mixed', 'int4-w4a8']) | |
| parser.add_argument('--reference', default='fp16') | |
| parser.add_argument('--images', nargs='*', default=[]) | |
| parser.add_argument('--tile', type=int, default=128) | |
| parser.add_argument('--tile-pad', type=int, default=16) | |
| parser.add_argument('--runs', type=int, default=2) | |
| parser.add_argument('--device', default='CPU') | |
| parser.add_argument('--size', type=int, nargs=2, default=[512, 256], help='synthetic input WxH') | |
| parser.add_argument('--token', default=os.environ.get('HF_TOKEN'), help='Hugging Face token') | |
| args = parser.parse_args() | |
| if args.images: | |
| inputs = [cv2.imread(p) for p in args.images] | |
| inputs = [im for im in inputs if im is not None] | |
| else: | |
| rng = np.random.default_rng(0) | |
| yy, xx = np.mgrid[0:args.size[1], 0:args.size[0]] | |
| base = (127 + 100 * np.sin(xx / 7.0) * np.cos(yy / 11.0))[..., None] | |
| inputs = [np.clip(base + rng.normal(0, 25, base.shape), 0, 255).astype(np.uint8).repeat(3, axis=2)] | |
| def load(key): | |
| path = HERE / 'models' / f'{MODELS[key][0]}.xml' | |
| if not path.exists(): # not downloaded yet -> fetch it from the Hub | |
| path = pathlib.Path(_download_model(key, args.token)) | |
| return RealESRGAN(model=str(path), device=args.device) | |
| ref_up = load(args.reference) if args.reference in args.models else load(args.reference) | |
| refs = [ref_up.enhance(im, tile=args.tile, tile_pad=args.tile_pad)[0] for im in inputs] | |
| size_mb = {} | |
| for key in args.models: | |
| up = load(key) | |
| xml = pathlib.Path(up.model_path) | |
| size_mb[key] = (xml.stat().st_size + xml.with_suffix('.bin').stat().st_size) / 1e6 | |
| ps, ss, ts, mp = [], [], [], [] | |
| for im, ref in zip(inputs, refs): | |
| up.enhance(im, tile=args.tile, tile_pad=args.tile_pad) | |
| best = min([_time(up, im, args) for _ in range(args.runs)]) | |
| out = up.enhance(im, tile=args.tile, tile_pad=args.tile_pad)[0] | |
| ts.append(best) | |
| mp.append(im.shape[0] * im.shape[1] / best / 1e6) | |
| ps.append(psnr(ref, out)) | |
| ss.append(ssim(ref, out)) | |
| print(f'{key:12s} {size_mb[key]:6.1f} MB PSNR {np.mean(ps):6.2f} dB SSIM {np.mean(ss):.4f} ' | |
| f'{np.mean(ts):6.3f} s/img {np.mean(mp):5.2f} MPix/s') | |
| def _time(up, im, args): | |
| t0 = time.time() | |
| up.enhance(im, tile=args.tile, tile_pad=args.tile_pad) | |
| return time.time() - t0 | |
| if __name__ == '__main__': | |
| main() |