<p>TorchSharp 无法直接使用 PyTorch 的 torch.load(),仅支持加载 TorchScript 格式(.pt)模型,需通过 TorchJit.Load() 加载;state_dict 文件须在 C# 中手动重建网络结构并调用 LoadStateDict()。</p>

torch.Load() 在 TorchSharp 中根本不能直接用
PyTorch 的 torch.load() 是 Python 侧的函数,TorchSharp 没有等价的通用反序列化解析器。它不支持直接加载任意 .pt 或 .pth 文件——尤其是那些用 torch.save(model.state_dict(), ...) 或 torch.save(model, ...) 保存的、含 Python 闭包/类定义的文件。强行调用会抛出 System.NotImplementedException 或更隐蔽的 InvalidDataException。
真正能走通的路径只有一条:模型必须是 **TorchScript 格式**(即通过 torch.jit.trace 或 torch.jit.script 导出的 .pt),且导出时没依赖未注册的自定义算子或 Python 层逻辑。
- 检查你的原始 PyTorch 代码是否调用了
torch.jit.trace(model, example_input)或torch.jit.script(model) - 导出后用 Python 跑
torch.jit.load("model.pt")确认能加载成功,再交给 C# - 如果保存的是
state_dict(常见于训练中间存档),TorchSharp 无法重建模型结构,必须在 C# 里手动复现网络定义
TorchSharp 加载 TorchScript 模型的正确写法
核心是用 TorchSharp.TorchJit.Load(),不是 TorchSharp.Torch.Load()。路径必须是本地绝对路径或可被 .NET File API 访问的路径(不支持嵌入资源或 URL)。
using TorchSharp;
<p>var model = TorchJit.Load(@"C:\models\resnet18_traced.pt"); // 注意:必须是 .pt,且是 TorchScript
var input = torch.randn(new long[] { 1, 3, 224, 224 });
var output = model.Forward(input); // 不是 model.forward(),大小写敏感-
TorchJit.Load()返回ITorchScriptModule,只能调用Forward(),不能访问named_parameters()或修改结构 - 输入张量的 shape、dtype、device 必须和 traced 时一致;常见坑是 Python 侧用了
float32,C# 默认是float64,得显式写torch.randn(..., torch.float32) - Windows 上路径斜杠用
@""或双反斜杠,单反斜杠会触发转义错误
模型结构不匹配?你可能得手写 C# 版 Network 类
如果你只有 state_dict.pth(比如 Hugging Face 某些仓库只发权重),TorchSharp 不提供类似 PyTorch 的 load_state_dict() 绑定机制。你必须在 C# 里用 nn.Module 子类完整重写模型结构,再逐层加载参数。
例如加载一个简单 CNN:
public class MyCNN : nn.Module
{
public MyCNN() : base("MyCNN")
{
conv1 = nn.Conv2d(3, 32, 3);
fc1 = nn.Linear(32 * 224 * 224, 10);
RegisterComponents(); // 必须调用,否则 save/load 不生效
}
public override Tensor forward(Tensor input) => ...
}- 所有层必须用
nn.Xxx构造,不能用原生 C# 数组模拟 - 权重加载靠
model.LoadStateDict(stateDict),但stateDict得先用 Python 把.pth读成字典,再用 JSON 或 ONNX 中转——TorchSharp 不解析原始 PyTorch state_dict 二进制格式 - 层命名必须和 Python 侧完全一致(包括
features.0.weight这种),否则LoadStateDict()会静默跳过
CUDA 支持不稳定,CPU 是默认安全区
TorchSharp 的 CUDA 后端依赖 libtorch 的对应版本,且目前仅支持 Windows + CUDA 11.x(官方未明确支持 12.x)。即使配置正确,也常出现 CUDA error: initialization error 或 tensor 在 GPU 上计算结果为 NaN。
- 开发阶段一律用
torch.set_device(DeviceType.CPU)开头,确认逻辑正确后再切 GPU - 加载模型后立刻调用
model.ToDevice(DeviceType.CPU),别依赖自动 placement - libtorch.dll 必须和 TorchSharp NuGet 包版本严格匹配(如 TorchSharp 0.97 对应 libtorch-win-shared-with-deps-1.13.1);混用会导致
AccessViolationException
最麻烦的点其实是模型导出环节——Python 侧 trace 时若用了动态控制流(比如 if x.sum() > 0:),TorchScript 会静默失败或生成不兼容的图,而这个错误在 C# 加载时才暴露,且报错信息毫无指向性。










