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

如何将PyTorch模型保存为无需PyTorch依赖的形式或编译为库?

有多种方法可以实现PyTorch模型脱离PyTorch依赖进行推理,以下是几种实用方案:

方案1:导出为ONNX格式,基于ONNX Runtime构建推理库

ONNX是跨框架的模型标准格式,ONNX Runtime是轻量独立的推理引擎,完全不依赖PyTorch,适合低依赖场景。

训练阶段导出ONNX模型

修改训练代码,将训练完成的PyTorch模型转换为ONNX格式:

import torch
import torch.nn as nn

# 假设model是训练好的模型实例
model = ... # 替换为你的模型对象
model.eval()

# 构造与模型输入维度匹配的示例张量(用于确定导出时的输入形状)
dummy_input = torch.randn(1, 3, 224, 224) # 根据你的模型输入维度调整

# 导出ONNX模型
torch.onnx.export(
    model,
    dummy_input,
    "MLmodel.onnx",
    opset_version=17, # 根据模型算子选择兼容的opset版本
    input_names=["input"],
    output_names=["output"],
    dynamic_axes={"input": {0: "batch_size"}, "output": {0: "batch_size"}} # 支持动态batch时添加
)

推理阶段:用ONNX Runtime + PyBind11构建动态库

编写C++代码实现推理逻辑,通过PyBind11暴露predict接口供Python调用:

#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <onnxruntime/core/session/onnxruntime_cxx_api.h>

namespace py = pybind11;

class MLModel {
private:
    Ort::Env env;
    Ort::Session session;
    Ort::AllocatorWithDefaultOptions allocator;
    const char* input_names[1] = {"input"};
    const char* output_names[1] = {"output"};

public:
    MLModel(const std::string& model_path) 
        : env(ORT_LOGGING_LEVEL_WARNING, "MLModel"),
          session(env, model_path.c_str(), Ort::SessionOptions{nullptr}) {}

    py::array_t<float> predict(py::array_t<float>& input_array) {
        // 解析输入numpy数组
        auto input_info = input_array.request();
        float* input_data = static_cast<float*>(input_info.ptr);
        std::vector<int64_t> input_shape(input_info.shape, input_info.shape + input_info.ndim);

        // 创建ONNX Runtime输入张量
        auto input_tensor = Ort::Value::CreateTensor<float>(
            allocator, input_data, input_array.size(), input_shape.data(), input_shape.size()
        );

        // 执行推理
        auto output_tensors = session.Run(
            Ort::RunOptions{nullptr}, input_names, &input_tensor, 1, output_names, 1
        );

        // 解析输出张量并转换为numpy数组返回
        float* output_data = output_tensors[0].GetTensorMutableData<float>();
        auto output_shape = output_tensors[0].GetTensorTypeAndShapeInfo().GetShape();
        return py::array_t<float>(output_shape, output_data);
    }
};

PYBIND11_MODULE(MLmodel, m) {
    py::class_<MLModel>(m, "MLModel")
        .def(py::init<const std::string&>())
        .def("predict", &MLModel::predict);
}

编译命令(示例,需根据环境调整路径)

g++ -O3 -shared -std=c++17 -fPIC `python3 -m pybind11 --includes` mlmodel.cpp -o MLmodel`python3-config --extension-suffix` -I/你的onnxruntime/include路径 -L/你的onnxruntime/lib路径 -lonnxruntime
方案2:导出TorchScript模型,编译为依赖LibTorch轻量版的动态库

LibTorch是PyTorch的C++运行时,支持静态链接,可将依赖打包进库中,无需用户单独安装PyTorch,适合对模型兼容性要求高的场景。

训练阶段导出TorchScript模型

import torch
import torch.nn as nn

model = ... # 训练好的模型实例
model.eval()

# 方式1:Trace导出(适合无动态控制流的模型)
dummy_input = torch.randn(1, 3, 224, 224)
traced_model = torch.jit.trace(model, dummy_input)
traced_model.save("MLmodel.pt")

# 方式2:Script导出(适合含if/for等动态控制流的模型)
# scripted_model = torch.jit.script(model)
# scripted_model.save("MLmodel.pt")

推理阶段:用LibTorch + PyBind11构建动态库

#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <torch/script.h>

namespace py = pybind11;

class MLModel {
private:
    torch::jit::script::Module module;

public:
    MLModel(const std::string& model_path) {
        module = torch::jit::load(model_path);
        module.to(torch::kCPU); // 根据需求选择设备,如torch::kCUDA
        module.eval();
    }

    py::array_t<float> predict(py::array_t<float>& input_array) {
        // 将numpy数组转换为torch张量
        auto input_info = input_array.request();
        torch::Tensor input_tensor = torch::from_blob(
            input_info.ptr,
            std::vector<int64_t>(input_info.shape, input_info.shape + input_info.ndim),
            torch::kFloat32
        ).to(torch::kCPU);

        // 执行推理(禁用梯度计算)
        torch::NoGradGuard no_grad;
        auto output_tensor = module.forward({input_tensor}).toTensor();

        // 转换为numpy数组返回
        return py::array_t<float>(
            output_tensor.sizes().vec(),
            output_tensor.strides().vec(),
            output_tensor.data_ptr<float>()
        );
    }
};

PYBIND11_MODULE(MLmodel, m) {
    py::class_<MLModel>(m, "MLModel")
        .def(py::init<const std::string&>())
        .def("predict", &MLModel::predict);
}

编译命令(静态链接LibTorch示例)

下载LibTorch轻量静态版后执行:

g++ -O3 -shared -std=c++17 -fPIC `python3 -m pybind11 --includes` mlmodel.cpp -o MLmodel`python3-config --extension-suffix` -I/你的libtorch/include路径 -I/你的libtorch/include/torch/csrc/api/include -L/你的libtorch/lib路径 -ltorch -ltorch_cpu -lc10 -pthread
方案3:编译为纯C静态库(完全脱离框架依赖)

通过onnx2c工具将ONNX模型转换为纯C代码,再编译为静态库,完全不依赖任何ML框架,适合极端轻量的嵌入式或小型软件场景(部分复杂算子可能不支持)。

  1. 先按方案1将PyTorch模型导出为ONNX格式
  2. 用onnx2c转换为C代码:
onnx2c MLmodel.onnx > mlmodel.c
  1. 编写PyBind11封装代码调用生成的C推理函数,编译为动态库即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 19:44:53