EDSR与MDSR超分辨率模型介绍
图像超分辨率重建的目标是将低分辨率图像提升为高分辨率图像,这是计算机视觉中备受关注的研究方向。本文将重点介绍在该领域表现优异的EDSR(Enhanced Deep Super-Resolution Network)和MDSR模型,并详细说明如何利用TPU-MLIR工具链,将ONNX格式的模型部署到BM1684X平台上运行。
先来认识一下今天的主角——EDSR模型,全称Enhanced Deep Super-Resolution Network(增强型深度超分辨率网络)。它的核心任务是对输入图像进行超分辨率处理,显著提升图像清晰度。而MDSR模型则是一款多尺度超分辨率模型,能够通过一次推理同时输出不同放大倍数的超分结果,以更少的参数实现相近的性能,极具实用价值。
EDSR的模型结构如下:

MDSR的结构则是这样的:

接下来,我们将详细讲解从EDSR到MDSR的完整模型转换流程。
模型导出与转换步骤
整个转换流程主要分为两个阶段:首先将原始模型导出为ONNX中间格式,然后利用TPU-MLIR工具链,将ONNX模型编译为可在BM1684X平台上高效运行的bmodel模型。
目录结构可以这样安排,看着清爽:
.
├── dataset
│ ├── x2
│ ├── x3
│ └── x4
├── image
└── model
├── EDSR_x2.onnx
├── EDSR_x3.onnx
├── EDSR_x4.onnx
├── MDSR_x2.onnx
├── MDSR_x3.onnx
└── MDSR_x4.onnx
dataset目录存放用于模型量化的DIV2K数据集,image目录包含测试图片,model目录则存放已经准备好的ONNX模型文件。
以下所有操作都在TPU-MLIR的Docker环境内进行。先进入EDSR-transform目录,然后设置好参数:
scale=4
size=100
echo scale=${scale} size=${size}
mkdir workspace_x${scale} && cd workspace_x${scale}
具体来说,需要经历这么几步:
第一步:模型转换与图优化。使用model_transform.py工具将ONNX模型转换为MLIR中间表示,同时完成算子转换和图结构优化:
model_transform.py \
--model_name EDSR_x${scale} \
--model_def ../model/EDSR_x${scale}.onnx \
--input_shapes [[1,3,${size},${size}]] \
--keep_aspect_ratio \
--pixel_format rgb \
--test_input ../image/0901x${scale}.png \
--test_result EDSR_x${scale}_outputs.npz \
--mlir EDSR_x${scale}.mlir
第二步:生成校准表。为后续INT8量化做好准备,需要运行校准工具生成校准表:
run_calibration.py EDSR_x${scale}.mlir \
--dataset ../dataset/X${scale} \
--input_num 50 \
-o EDSR_x${scale}_cali_table
第三步:多级优化与bmodel生成。可根据需求选择不同精度进行编译:
INT8模型:
model_deploy.py \
--mlir EDSR_x${scale}.mlir \
--quantize INT8 \
--calibration_table EDSR_x${scale}_cali_table \
--chip bm1684x \
--test_input EDSR_x${scale}_in_f32.npz \
--test_reference EDSR_x${scale}_outputs.npz \
--tolerance 0.85,0.45 \
--model EDSR_x${scale}_1684x_int8_sym.bmodel
FP16模型:
model_deploy.py \
--mlir EDSR_x${scale}.mlir \
--quantize F16 \
--chip bm1684x \
--test_input EDSR_x${scale}_in_f32.npz \
--test_reference EDSR_x${scale}_top_outputs.npz \
--model EDSR_x${scale}_1684x_f32_sym.bmodel
FP32模型:
model_deploy.py \
--mlir EDSR_x${scale}.mlir \
--quantize F32 \
--chip bm1684x \
--test_input EDSR_x${scale}_in_f32.npz \
--test_reference EDSR_x${scale}_top_outputs.npz \
--model EDSR_x${scale}_1684x_f32_sym.bmodel
若需转换MDSR模型,操作步骤完全相同,只需将命令中的“EDSR”替换为“MDSR”即可,此处不再赘述。
转换结果评估与精度分析
评估过程说明
模型的最终性能需要通过实际推理和指标计算来验证。具体操作流程如下:首先在BM1684X平台上配置环境,上传并解压项目包EDSR-BM1684x.zip。然后下载benchmark数据集,确保benchmark文件夹与EDSR文件夹处于同级目录。接着进入EDSR/python目录,执行推理脚本:
for model in {EDSR,MDSR}; do
for scale in {2,3,4}; do
echo ---------------------dataset=Set14-------------scale=${scale}---------------------
cmd="python run_opencv_crop.py --input ../../benchmark/Set14/LR_bicubic/X${scale} \
--output results/${model}_Set14_x${scale}_int8 \
--bmodel ../models/BM1684X/${model}_x${scale}/${model}_x${scale}_1684x_int8_sym.bmodel"
echo ">>> Running: ${cmd}"
$cmd
done
done
推理结果将保存在EDSR/python/results目录下。若需切换不同精度的bmodel,只需修改--bmodel参数对应的路径即可。评估阶段,首先安装lpips依赖库:
pip install lpips
评估的核心逻辑由eval.py实现,该脚本会遍历推理得到的超分图像列表,查找对应的原始高分辨率图像(HR),并计算PSNR、SSIM以及LPIPS等关键指标:
for i, sr in enumerate(sr_list):
hr = Path(args.hr_path) / (sr.stem.split('x')[0] + sr.suffix)
if not hr.exists():
logging.error(f'{sr}: {hr} does not exist')
hr_list.append(None)
continue
hr_list.append(hr)
sr_img = Image.open(sr).convert('RGB')
hr_img = Image.open(hr).convert('RGB')
if hr_img.size != sr_img.size:
logging.info(f' cropping hr_img from {hr_img.size} to {sr_img.size}')
hr_img = hr_img.crop((0, 0, sr_img.size[0], sr_img.size[1]))
sr_img = np.array(sr_img)
hr_img = np.array(hr_img)
lpi = calculate_lpips(sr_img, hr_img, border=args.scale)
sr_img_y = rgb2ycbcr(sr_img, only_y=True)
hr_img_y = rgb2ycbcr(hr_img, only_y=True)
psnr = calculate_psnr(sr_img_y, hr_img_y, border=args.scale)
ssim = calculate_ssim(sr_img_y, hr_img_y, border=args.scale)
...
执行评估的命令如下:
for model in {EDSR,MDSR}; do
for i in "${!scale[@]}"; do
echo -------------scale=${scale[$i]}-----------------
cmd="python eval.py --hr_path ../../benchmark/Set14/HR --sr_path results/${model}_Set14_x${scale[$i]}_int8 --scale ${scale[$i]}"
echo ">>> Running: ${cmd}"
$cmd
done
done
评估结果直接记录在results/*/result.log里,方便查阅。
若需测试自定义图片,只需将图片放入image目录,然后运行以下命令,结果将保存在results/image中。通过更换bmodel参数,可灵活切换模型与超分倍率:
python run_opencv_crop.py --input ../image \
--output results/image \
--bmodel ../models/BM1684X/EDSR_x2_1684x_int8_sym.bmodel
随后用eval.py进行评估:
python eval.py --sr_path results/image --hr_path ../image --scale {scale}
评估结果
精度测试方法
测试数据集采用经典的Set14,评估指标沿用原论文中的PSNR和SSIM。需要注意的是,由于模型输入尺寸固定,我们采用了“原图裁切、分别超分、最后拼合”的策略来支持大图动态输入,这导致部分精度指标在测试中不仅未下降,反而略有提升。同时,不同放大倍数的模型在输入尺寸和参数量上存在差异,因此推理时间比例也会相应变化。
fp32结果

FP32精度结果
fp16结果

FP16精度结果
int8结果

INT8精度结果
精度对比

精度对比数据
性能对比

性能对比数据
结论
本文成功完成了EDSR和MDSR两个超分辨率模型从ONNX到bmodel的转换,并覆盖了FP32、FP16、INT8三种精度模式。整个转换过程中,TPU-MLIR工具链对这两个模型提供了良好的支持,未遇到任何障碍。从评估结果看,超分模型对数值精度不敏感,即使经过INT8量化,指标损失极小,部分指标甚至有所提升。在BM1684X平台上,INT8模型的推理速度最快,因此在实际部署中,我们强烈推荐优先使用量化后的INT8模型,以在性能和精度之间取得最佳平衡。
