如何将语音预训练库的.pth文件转为C#可读的.pt文件?
预训练语音模型.pth转.pt时加载state_dict不匹配的解决方法
需要将预训练语音模型的.pth文件转为C#可读的.pt格式,但仅找到torchvision视觉模型的转换资料,PyTorch.audio相关文档较少。已知.pth和.pt本质相同,但Python加载.pth时存在兼容问题,参考torchvision示例写了代码,运行时出现RuntimeError。
代码示例
pth_file_path = 'FILE/PATH/model.pth' pt_file_path = 'FILE/PATH/model.pt' import torch import torchaudio from unet import UNet from zmq import device model = UNet(3, 2) model.load_state_dict(torch.load(pth_file_path, map_location=torch.device('cpu')))
错误信息
model.load_state_dict(torch.load(pth_file_path, map_location=torch.device('cpu'))) Traceback (most recent call last): File ".\IMPORT.py", line 11, in <module> model.load_state_dict(torch.load(pth_file_path, map_location=torch.device('cpu'))) File "C:\Users\user\AppData\Local\Programs\Python\Python38\lib\site-packages\torch\nn\modules\module.py", line 2215, in load_state_dict raise RuntimeError('Error(s) in loading state_dict for {}:\n\t{}'.format( RuntimeError: Error(s) in loading state_dict for UNet: Missing key(s) in state_dict: "encoder.encoding_blocks.0.conv1.conv_layer.weight", "encoder.encoding_blocks.0.conv1.conv_layer.bias", "encoder.encoding_blocks.0.conv1.block.0.weight", "encoder.encoding_blocks.0.conv1.block.0.bias", "encoder.encoding_blocks.0.conv2.conv_layer.weight", "encoder.encoding_blocks.0.conv2.conv_layer.bias", "encoder.encoding_blocks.0.conv2.block.0.weight", "encoder.encoding_blocks.0.conv2.block.0.bias", "encoder.encoding_blocks.1.conv1.conv_layer.weight", "encoder.encoding_blocks.1.conv1.conv_layer.bias", "encoder.encoding_blocks.1.conv1.block.0.weight", "encoder.encoding_blocks.1.conv1.block.0.bias", "encoder.encoding_blocks.1.conv2.conv_layer.weight", "encoder.encoding_blocks.1.conv2.conv_layer.bias", "encoder.encoding_blocks.1.conv2.block.0.weight", "encoder.encoding_blocks.1.conv2.block.0.bias", "encoder.encoding_blocks.2.conv1.conv_layer.weight", "encoder.encoding_blocks.2.conv1.conv_layer.bias", "encoder.encoding_blocks.2.conv1.block.0.weight", "encoder.encoding_blocks.2.conv1.block.0.bias", "encoder.encoding_blocks.2.conv2.conv_layer.weight", "encoder.encoding_blocks.2.conv2.conv_layer.bias", "encoder.encoding_blocks.2.conv2.block.0.weight", "encoder.encoding_blocks.2.conv2.block.0.bias", "encoder.encoding_blocks.3.conv1.conv_layer.weight", "encoder.encoding_blocks.3.conv1.conv_layer.bias", "encoder.encoding_blocks.3.conv1.block.0.weight", "encoder.encoding_blocks.3.conv1.block.0.bias", "encoder.encoding_blocks.3.conv2.conv_layer.weight", "encoder.encoding_blocks.3.conv2.conv_layer.bias", "encoder.encoding_blocks.3.conv2.block.0.weight", "encoder.encoding_blocks.3.conv2.block.0.bias", "bottom_block.conv1.conv_layer.weight", "bottom_block.conv1.conv_layer.bias", "bottom_block.conv1.block.0.weight", "bottom_block.conv1.block.0.bias", "bottom_block.conv2.conv_layer.weight", "bottom_block.conv2.conv_layer.bias", "bottom_block.conv2.block.0.weight", "bottom_block.conv2.block.0.bias", "decoder.decoding_blocks.0.upsample.weight", "decoder.decoding_blocks.0.upsample.bias", "decoder.decoding_blocks.0.conv1.conv_layer.weight", "decoder.decoding_blocks.0.conv1.conv_layer.bias", "decoder.decoding_blocks.0.conv1.block.0.weight", "decoder.decoding_blocks.0.conv1.block.0.bias", "decoder.decoding_blocks.0.conv2.conv_layer.weight", "decoder.decoding_blocks.0.conv2.conv_layer.bias", "decoder.decoding_blocks.0.conv2.block.0.weight", "decoder.decoding_blocks.0.conv2.block.0.bias", "decoder.decoding_blocks.1.upsample.weight", "decoder.decoding_blocks.1.upsample.bias", "decoder.decoding_blocks.1.conv1.conv_layer.weight", "decoder.decoding_blocks.1.conv1.conv_layer.bias", "decoder.decoding_blocks.1.conv1.block.0.weight", "decoder.decoding_blocks.1.conv1.block.0.bias", "decoder.decoding_blocks.1.conv2.conv_layer.weight", "decoder.decoding_blocks.1.conv2.conv_layer.bias", "decoder.decoding_blocks.1.conv2.block.0.weight", "decoder.decoding_blocks.1.conv2.block.0.bias", "decoder.decoding_blocks.2.upsample.weight", "decoder.decoding_blocks.2.upsample.bias", "decoder.decoding_blocks.2.conv1.conv_layer.weight", "decoder.decoding_blocks.2.conv1.conv_layer.bias", "decoder.decoding_blocks.2.conv1.block.0.weight", "decoder.decoding_blocks.2.conv1.block.0.bias", "decoder.decoding_blocks.2.conv2.conv_layer.weight", "decoder.decoding_blocks.2.conv2.conv_layer.bias", "decoder.decoding_blocks.2.conv2.block.0.weight", "decoder.decoding_blocks.2.conv2.block.0.bias", "decoder.decoding_blocks.3.upsample.weight", "decoder.decoding_blocks.3.upsample.bias", "decoder.decoding_blocks.3.conv1.conv_layer.weight", "decoder.decoding_blocks.3.conv1.conv_layer.bias", "decoder.decoding_blocks.3.conv1.block.0.weight", "decoder.decoding_blocks.3.conv1.block.0.bias", "decoder.decoding_blocks.3.conv2.conv_layer.weight", "decoder.decoding_blocks.3.conv2.conv_layer.bias", "decoder.decoding_blocks.3.conv2.block.0.weight", "decoder.decoding_blocks.3.conv2.block.0.bias", "classifier.conv_layer.weight", "classifier.conv_layer.bias", "classifier.block.0.weight", "classifier.block.0.bias". Unexpected key(s) in state_dict: "weight", "config", "info", "sr", "f0", "version".
问题分析
从错误信息能看出,你加载的.pth文件内容和定义的UNet模型结构完全不匹配:
- 意外键
weight、config、info等说明这个.pth不是标准的PyTorch模型state_dict,而是包含权重、配置信息的复合字典,甚至可能是语音库自定义的序列化格式。 - 缺少的键都是UNet模型的子模块参数,说明.pth里的权重结构和你的UNet完全对应不上。
解决步骤
1. 先排查.pth文件的结构
先不要急于加载到模型,先打印文件内容,确认里面的结构:
import torch pth_data = torch.load('FILE/PATH/model.pth', map_location='cpu') print(type(pth_data)) # 如果是字典,打印所有键 if isinstance(pth_data, dict): print(pth_data.keys()) # 查看'weight'键对应的张量形状(如果存在) if 'weight' in pth_data: print(pth_data['weight'].shape)
这一步能帮你明确.pth里存的是单个权重张量、完整模型还是复合配置数据。
2. 匹配模型结构或提取正确权重
- 如果.pth里的
weight是模型权重张量,需要确认该权重对应的模型结构和你的UNet是否一致。不一致的话,要么修改UNet结构匹配权重,要么找到该语音库的官方模型定义代码,用正确的模型类加载。 - 如果.pth是完整模型(用
torch.save(model, path)保存的),直接加载整个模型即可:model = torch.load('FILE/PATH/model.pth', map_location='cpu') - 如果是复合字典,比如权重存在
pth_data['model']这类键下,提取对应部分再加载:model.load_state_dict(pth_data['model'])
3. 转换为C#可读的.pt格式
成功加载模型后,直接保存为.pt格式即可(.pt和.pth本质都是PyTorch序列化格式,C#的TorchSharp等库均可读取):
# 保存模型state_dict torch.save(model.state_dict(), 'FILE/PATH/model.pt') # 或者保存完整模型 torch.save(model, 'FILE/PATH/model.pt')
注意事项
- 语音模型的.pth格式常带有自定义内容(如采样率、配置信息),不能直接套用视觉模型的加载逻辑。
- 优先参考该预训练语音库的官方文档或加载示例,确保模型结构和权重完全匹配。
内容的提问来源于stack exchange,提问作者Crombopul
相关产品推荐
相关产品推荐

