☰
LaMa 大面积图像修复生产部署完整指南:ONNX 导出到 TensorRT FP16 加速的三道门槛
2026/9/29 13:36:14 网站建设 项目流程

LaMa 大面积图像修复生产部署完整指南:ONNX 导出到 TensorRT FP16 加速的三道门槛

【免费下载链接】lama🦙 LaMa Image Inpainting, Resolution-robust Large Mask Inpainting with Fourier Convolutions, WACV 2022项目地址: https://gitcode.com/GitHub_Trending/la/lama

big-lama 是本仓库的大面积掩码图像修复模型,原生 PyTorch 推理单张以秒计,而训练栈的 autograd 与 hook 在线上全是纯开销。这篇文章围绕 big-lama,走通「提速、验稳、上线」三道门槛:ONNX 导出、TensorRT 引擎构建、服务化封装。

先看选型表:三条推理路线的适用边界

结论先行:GPU 型号固定且直接扛流量,直接上 TensorRT;GPU 型号未定或要快速量出加速上限,ONNX Runtime 做过渡;PyTorch 原生只留作开发基准与数值对照。

路线优化发生在哪层部署约束相对 PyTorch 原生的保守预期
PyTorch 原生动态图解释执行,无融合无基准 1×
ONNX Runtime静态图算子融合,多后端需 onnxruntime + 匹配的执行提供器约 1~2×(CUDA EP)
TensorRT按具体 GPU 重编译,层融合 + 内核调优 + FP16引擎与 GPU 型号绑定FP32 约 1.5~2.5×,FP16 约 2~4×

一句话解读:三条路线输出应当数值一致,差异只在图优化深度与硬件适配程度,这也是后文「先对数再谈快」的由来。

先跑通 PyTorch 基准:用官方 predict 流程锁定参照结果

动手导出前,先把官方推理路径跑一遍,手里有随时可比对的参照输出。

git clone https://gitcode.com/GitHub_Trending/la/lama cd lama export TORCH_HOME=$(pwd) && export PYTHONPATH=$(pwd) python3 bin/predict.py model.path=$(pwd)/big-lama \ indir=$(pwd)/LaMa_test_images outdir=$(pwd)/output \ model.checkpoint=last.ckpt
  • model.checkpoint(默认best.ckpt):指定加载哪个 checkpoint。解压big-lama.zip得到big-lama/last.ckpt,所以必须显式传model.checkpoint=last.ckpt,传错文件名会整图修复失败或黑屏。
  • pad_out_to_modulo(值为 8,见 configs/prediction/default.yaml):官方流程把输入补到 8 的倍数再进模型。不补的话输出与输入尺寸对不齐,服务侧还得加裁剪逻辑。
  • refine: False:迭代细化器默认关闭。它在同一配置里是n_iters: 15、max_scales: 3,延迟远高于主模型;线上要开就单独测一版,别混进主链路。

GPU 路径可直接走 docker/2_predict_with_gpu.sh。基准跑通后,记录一张真实图像的修复输出张量与单张耗时,作为后续所有加速结果的对照基线。

怎么构建 big-lama 的 ONNX 导出脚本:输入通道与 opset

先确认模型类。configs/training/big-lama.yaml 里 generator 段是kind: ffc_resnet,由 saicinpainting/training/modules/init.py 的make_generator分发到FFCResNetGenerator(定义在 saicinpainting/training/modules/ffc.py)。别用GlobalGenerator,那是lama-regular的结构,类选错权重直接加载不上。

model = FFCResNetGenerator(**OmegaConf.to_container(cfg['generator'])) model.load_state_dict(torch.load('big-lama/last.ckpt', map_location='cpu')['state_dict']) model.eval() torch.onnx.export(model, torch.randn(1, 4, 512, 512), 'big-lama.onnx', opset_version=14, do_constant_folding=True, dynamic_axes={'input': {2: 'h', 3: 'w'}, 'output': {2: 'h', 3: 'w'}})
  • input_nc: 4:同配置文件里concat_mask: true,generator 输入是 3 通道图像 + 1 通道掩码拼接。传 3 通道导出不会报错,但 ONNX 推理时通道数直接对不上。
  • opset_version: 14:ffc.py 的FourierUnit前向依赖torch.fft.rfftn,低 opset 落不了地。导出失败先看torch.onnx报的具体算子名;环境锁在 PyTorch 1.8(本仓库 conda_env.yml 的版本)时,优先把导出侧 PyTorch 升到 1.12+ 再试。
  • dynamic_axes:把 H/W 声明为动态。不做的话每个分辨率导一个模型、每档尺寸建一次引擎,运维上收不住。

官方 bin/to_jit.py 是另一条路:用JITWrapper把 image、mask 分开喂给训练模型再 trace,拼接在内部完成。你直接导出FFCResNetGenerator的话,拼接得放在服务侧预处理好。

怎么建 big-lama 的 FP16 TensorRT 引擎:workspace 与动态 profile 的 3 个参数

import tensorrt as trt logger = trt.Logger(trt.Logger.WARNING) builder = trt.Builder(logger) net = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)) trt.OnnxParser(net, logger).parse(open('big-lama.onnx', 'rb').read()) cfg = builder.create_builder_config() cfg.max_workspace_size = 1 << 30 prof = builder.create_optimization_profile() prof.set_shape('input', (1,4,128,128), (1,4,512,512), (1,4,1024,1024)) cfg.add_optimization_profile(prof) cfg.set_flag(trt.BuilderFlag.FP16) open('big-lama.engine', 'wb').write(builder.build_serialized_network(net, cfg))
  • max_workspace_size: 1GB(1 << 30):FFT 与 18 个残差块的中间结果吃显存。给小了构建失败或放弃融合选择;显存不够先翻倍再排查别的。
  • FP16 标志:先用 FP32 建对照版验证一致,再开 FP16。只有一版引擎时,FP16 出 NaN 你分不清是精度问题还是图错误;确认是精度问题后,可对个别层用 layer precision override 单独锁回 FP32。
  • min/opt/max profile:TensorRT 不认识「动态」,只认区间。空间维给 128/512/1024 三档,opt设为业务最高频尺寸,内核选择会明显更优;不传要么构建报错,要么只能跑死尺寸。FFC 基于 FFT,空间维尽量保持 2 的幂对齐。

怎么验证引擎与 PyTorch 的数值一致性:容差、预热与抽查

顺序不能反:先确认输出一致,再谈速度。

out_pt = model(x).detach() out_trt = run_trt(engine, x) assert torch.allclose(out_pt.float(), out_trt, atol=1e-4) # FP32 引擎 for _ in range(10): # 预热 run_trt(engine, x) ts = [] for _ in range(50): t0 = time.perf_counter() run_trt(engine, x) ts.append(time.perf_counter() - t0) print(np.mean(ts), 's')
  • atol:FP32 引擎 1e-4 / FP16 引擎 1e-2:一致性的量级门槛。FP32 引擎到不了 1e-4,先怀疑图错误(opset、动态轴),别急着归咎精度;FP16 落在 1e-2 内还要看肉眼抽查。
  • 预热 10 次、取 50 次以上均值:首次调用含内核加载与显存分配,单次结果没有统计意义。
  • 抽查样本 2~3 张:测试输入用仓库评估流程的真实图像构造 4 通道张量,而不是随机噪声——只有真实图像能暴露数值边界问题,再目检修复区没有新伪影。

怎么把推理封装成服务:预对齐、batch 与性能区间

🔧 服务侧预处理与官方流程对齐:补 8 的倍数、拼接 4 通道。

ph, pw = (8 - h % 8) % 8, (8 - w % 8) % 8 x = torch.cat([F.pad(img, (0, pw, 0, ph)), F.pad(mask, (0, pw, 0, ph))], dim=0)

掩码命名与仓库测试集约定一致([image]_maskXXX.png同目录),回归测试可直接拿 saicinpainting/evaluation/masks/countless/images/segmentation.png 这类真实样例当固定输入。

  • batch:从 1 起步:batch=1 先固化全链路,再验 batch=2 的一致性与延迟,通过才扩。直接上大 batch,FFT 类算子的显存占用非线性上涨,爆了也不好归因。
  • 并发:单引擎实例不并发:每个 worker 一个引擎实例,或用请求队列串行化执行。共享引擎会偶发挂起。

⚡ 性能预期(512×512 单张、A10 级 GPU,保守区间):PyTorch 原生秒级;ONNX Runtime(CUDA EP)约其 0.5~0.8 倍;TensorRT FP32 约 0.4~0.6 倍;FP16 约 0.2~0.5 倍。分辨率提到 1024 后绝对耗时上升,但 TensorRT 的相对优势通常更明显,大 kernel 更吃融合优化。

这套「导出 → 建引擎 → 一致性验证」流水线对 configs/training/ 下lama-regular、big-lama-celeba等其他配置同样适用,换个 kind 重新导出即可。下一步可构建 INT8 校准集榨取最后的吞吐,或用 configs/training/trainer/ 里的 benchmark 配置做训练侧交叉对照。

【免费下载链接】lama🦙 LaMa Image Inpainting, Resolution-robust Large Mask Inpainting with Fourier Convolutions, WACV 2022项目地址: https://gitcode.com/GitHub_Trending/la/lama

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询