You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GFPGANv1.3的.pth转ONNX遇类型错误,求解决方法及流程讲解

运行环境
  • Windows 10
  • Python 3.10.0
  • torch 2.1.2
  • gfpgan 1.3.8
  • onnx 1.14.0
  • onnxruntime 1.15.0
转换代码
import torch
import torch.onnx

import onnx
import onnxruntime

from gfpgan.archs.gfpganv1_clean_arch import GFPGANv1Clean

device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')

onnx_path = "models/GFPGANv1.3.onnx"
gfpgan_path = "models/GFPGANv1.3.pth"

torch_model = GFPGANv1Clean(
                out_size=512,
                num_style_feat=512,
                channel_multiplier=2,
                decoder_load_path=None,
                fix_decoder=False,
                num_mlp=8,
                input_is_latent=True,
                different_w=True,
                narrow=1,
                sft_half=True)

# 加载预训练模型权重
loadnet = torch.load(gfpgan_path)

# 用预训练权重初始化模型
torch_model.load_state_dict(loadnet, strict=False)

torch_model.to(device)

# 设置模型为评估模式
torch_model.eval()

# 模型输入
inputs = torch.ones((1, 3, 512, 512)).to(device)

# 导出模型为ONNX格式
torch.onnx.export(torch_model,               # 要导出的模型
                  inputs,                    # 模型输入(多输入用元组)
                  onnx_path,                 # 模型保存路径
                  export_params=True,        # 将训练好的参数权重存入模型文件
                  verbose=False,
                  do_constant_folding=True,  # 是否执行常量折叠优化
                  input_names=['input'],     # 模型输入名称
                  output_names=['output'],   # 模型输出名称
                  opset_version=12           # 导出使用的ONNX版本
                  )

# 验证ONNX模型
onnx_model = onnx.load("models/GFPGANv1.3.onnx")
onnx.checker.check_model(onnx_model)
导出阶段错误
D:\roop\.venv\lib\site-packages\torchvision\transforms\functional_tensor.py:5:
UserWarning: The torchvision.transforms.functional_tensor module is deprecated
in 0.15 and will be **removed in 0.17**. Please don't rely on it. You probably
just need to use APIs in torchvision.transforms.functional or in
torchvision.transforms.v2.functional. warnings.warn( 

D:\roop\.venv\lib\site-packages\gfpgan\archs\gfpganv1_clean_arch.py:314:
TracerWarning: 将张量转换为Python布尔值可能会导致追踪结果不正确。我们无法记录Python值的数据流,因此该值未来会被视为常量。这意味着追踪结果可能无法推广到其他输入! if return_rgb:

D:\roop\.venv\lib\site-packages\gfpgan\archs\gfpganv1_clean_arch.py:62:
TracerWarning: 将张量转换为Python布尔值可能会导致追踪结果不正确。我们无法记录Python值的数据流,因此该值未来会被视为常量。这意味着追踪结果可能无法推广到其他输入! if randomize_noise:

D:\roop\.venv\lib\site-packages\gfpgan\archs\gfpganv1_clean_arch.py:102:
TracerWarning: 将张量转换为Python整数可能会导致追踪结果不正确。我们无法记录Python值的数据流,因此该值未来会被视为常量。这意味着追踪结果可能无法推广到其他输入! out_same, out_sft = torch.split(out, int
(out.size(1) // 2), dim=1)

D:\roop\.venv\lib\site-packages\gfpgan\archs\gfpganv1_clean_arch.py:114:
TracerWarning: 将张量转换为Python布尔值可能会导致追踪结果不正确。我们无法记录Python值的数据流,因此该值未来会被视为常量。这意味着追踪结果可能无法推广到其他输入! if return_latents:

D:\roop\.venv\lib\site-packages\torch\onnx\utils.py:1686: UserWarning: 导出的ONNX模型未通过ONNX形状推理。该模型无法被ONNX Runtime执行。如果这并非预期且您认为存在bug,请在https://github.com/pytorch/pytorch/issues提交问题。
严格ONNX形状推理报告的错误:[ShapeInferenceError]
(op_type:Conv, node name: /stylegan_decoder/to_rgb1/modulated_conv/Conv): W has
inconsistent type tensor(float) (Triggered internally
at ..\torch\csrc\jit\serialization\export.cpp:1421.)
  _C._check_onnx_proto(proto)
问题描述

我成功生成了GFPGANv1.3.onnx模型,但不确定这些错误的影响。刚接触模型开发与训练,推测最初的数据类型警告是由于gfpgan 1.3.8(最后更新于2022年9月16日)与torch 2.1.2(2023年12月15日)之间存在版本不兼容问题。

当我尝试用以下代码创建ONNX Runtime会话时:

# 使用ONNX Runtime的Python API计算输出
ort_session = onnxruntime.InferenceSession("models/GFPGANv1.3.onnx", providers=["CPUExecutionProvider"])

再次遇到了导出阶段提示的错误:

Traceback (most recent call last):
  File "D:\roop\convert.py", line 56, in <module>
    ort_session = onnxruntime.InferenceSession("models/GFPGANv1.3.onnx", providers=["CPUExecutionProvider"])
  File "D:\roop\.venv\lib\site-packages\onnxruntime\capi\onnxruntime_inference_collection.py", line 383, in __init__
    self._create_inference_session(providers, provider_options, disabled_optimizers)
  File "D:\roop\.venv\lib\site-packages\onnxruntime\capi\onnxruntime_inference_collection.py", line 424, in _create_inference_session
    sess = C.InferenceSession(session_options, self._model_path, True, self._read_config_from_model)
onnxruntime.capi.onnxruntime_pybind11_state.Fail: [ONNXRuntimeError] : 1 : FAIL : Load model from models/GFPGANv1.3.onnx failed:Type Error: Type parameter (T) of Optype (Conv) bound to different types (tensor(double) and tensor(float) in node (/stylegan_decoder/to_rgb1/modulated_conv/Conv).

我希望有人能指出这些错误的解决方案,更重要的是讲解整个模型转换流程。之前我以为转换过程很简单,用外部脚本就能完成,但现在发现并非如此。


解决方案与流程讲解

错误原因分析

  1. 版本不兼容:GFPGAN 1.3.8是2022年的版本,而PyTorch 2.1.2是2023年底的版本,两者的API和追踪逻辑存在差异,导致导出时出现类型不匹配问题。
  2. 张量类型不统一:导出的ONNX模型中,Conv节点的权重(W)是float类型,但输入可能被解析为double类型,导致ONNX Runtime加载失败。
  3. TorchScript追踪警告:代码中存在将张量转为Python布尔/整数的操作,破坏了TorchScript的追踪流程,导致导出的模型无法适配动态输入。

具体解决方案

1. 统一数据类型

在导出模型前,确保模型和输入都使用float32类型,避免混合double和float:

# 修改输入张量的类型
inputs = torch.ones((1, 3, 512, 512)).to(device).float()
# 强制模型参数转为float32
torch_model = torch_model.float()

2. 调整PyTorch版本

降级PyTorch到与GFPGAN 1.3.8兼容的版本,比如PyTorch 1.12.x或1.13.x,这能减少版本差异带来的API不兼容问题。

3. 修复GFPGAN代码中的追踪问题

修改gfpganv1_clean_arch.py中的相关代码,避免将张量转为Python原生类型:

  • 对于if return_rgb:这类判断,确保return_rgb是模型初始化时的固定参数(而非张量),或者使用torch.where替代Python条件判断。
  • 对于int(out.size(1) // 2),改为使用张量操作:
split_size = out.size(1) // 2
out_same, out_sft = torch.split(out, split_size, dim=1)

(去掉int转换,让TorchScript能追踪到这个值的数据流)

4. 调整ONNX导出参数

导出时指定do_constant_folding=False,避免常量折叠导致的类型错误;同时提升opset版本到14或更高,更好地兼容新版PyTorch的算子:

torch.onnx.export(torch_model,
                  inputs,
                  onnx_path,
                  export_params=True,
                  verbose=False,
                  do_constant_folding=False,
                  input_names=['input'],
                  output_names=['output'],
                  opset_version=14,
                  dynamic_axes={'input': {0: 'batch_size'}, 'output': {0: 'batch_size'}})  # 如果需要动态批量

模型转换完整流程

1. 环境准备

  • 确认模型依赖的框架版本兼容性,优先选择官方推荐的版本组合(比如GFPGAN 1.3.8推荐PyTorch 1.10+)。
  • 安装必要库:torch、onnx、onnxruntime、gfpgan。

2. 模型加载与初始化

  • 从官方渠道下载预训练权重(.pth文件)。
  • 导入模型结构类,初始化模型并加载权重,设置为eval()模式(关闭dropout、batchnorm的训练行为)。

3. 输入准备

  • 创建与模型输入尺寸、类型匹配的张量,确保设备(CPU/GPU)与模型一致。
  • 如果需要动态输入,提前规划好动态维度(比如batch_size)。

4. ONNX导出

  • 使用torch.onnx.export()导出模型,指定输入输出名称、opset版本、是否保存参数等。
  • 导出后用onnx.checker.check_model()验证模型结构合法性。

5. 模型验证

  • 用ONNX Runtime加载模型,对比PyTorch模型和ONNX模型的输出结果,确保误差在可接受范围内。
  • 如果加载失败,检查错误日志中的类型、形状不匹配问题,针对性调整导出参数或模型代码。

内容的提问来源于stack exchange,提问作者Prashant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 04:58:12