基于C++的PyTorch模型部署

C++调用PyTorch模型教程 在人工智能的世界中,PyTorch已经成为了研究人员和工程师们广泛使用的深度学习框架之一。它以其灵活性和动态计算图而闻名,非常适合快速原型设计和实验。然而,当我们想要将训练好的模型部署到生产环境中时,我们可能会倾向于使用C++这样的更高性能语言,因为它提供了更好的速度和资源管理。幸运的是,PyTorch提供了LibTorch库,使得我们可以在C++环境中加载和使用PyTorch模型。本教程将详细介绍如何在C++中调用PyTorch模型,包括环境配置、模型的导出、C++中的加载和使用等步骤。 阅读详情

PyTorch

Author:louwill

Machine Learning Lab

   

引言

     PyTorch作为一款端到端的深度学习框架,在1.0版本之后已具备较好的生产环境部署条件。除了在web端撰写REST API进行部署之外(参考),软件端的部署也有广泛需求。尤其是最近发布的1.5版本,提供了更为稳定的C++前端API。

     工业界与学术界最大的区别在于工业界的模型需要落地部署,学界更多的是关心模型的精度要求,而不太在意模型的部署性能。一般来说,我们用深度学习框架训练出一个模型之后,使用Python就足以实现一个简单的推理演示了。但在生产环境下,Python的可移植性和速度性能远不如C++。所以对于深度学习算法工程师而言,Python通常用来做idea的快速实现以及模型训练,而用C++作为模型的生产工具。目前PyTorch能够完美的将二者结合在一起。实现PyTorch模型部署的核心技术组件就是TorchScript和libtorch。

     所以基于PyTorch的深度学习算法工程化流程大体如下图所示:

TorchScript

     TorchScript可以视为PyTorch模型的一种中间表示,TorchScript表示的PyTorch模型可以直接在C++中进行读取。PyTorch在1.0版本之后都可以使用TorchScript的方式来构建序列化的模型。TorchScript提供了Tracing和Script两种应用方式。

     Tracing应用示例如下:

class MyModel(torch.nn.Module):
    def __init__(self):
        super(MyModel, self).__init__()
        self.linear = torch.nn.Linear(4, 4)


    def forward(self, x, h):
        new_h = torch.tanh(self.linear(x) + h)
        return new_h, new_h


# 创建模型实例 
my_model = MyModel()
# 输入示例
x, h = torch.rand(3, 4), torch.rand(3, 4)
# torch.jit.trace方法对模型构建TorchScript
traced_model = torch.jit.trace(my_model, (x, h))
# 保存转换后的模型
traced_model.save('model.pt')

     在这段代码中,我们先是定义了一个简单模型并创建模型实例,然后给定输入示例,Tracing方法最关键的一步在于使用torch.jit.trace方法对模型进行TorchScript转化。我们可以获得转化后的traced_model对象获得其计算图属性和代码属性。计算图属性:

print(traced_model.graph)
graph(%self.1 : __torch__.torch.nn.modules.module.___torch_mangle_1.Module,
      %input : Float(3, 4),
      %h : Float(3, 4)):
  %19 : __torch__.torch.nn.modules.module.Module = prim::GetAttr[name="linear"](%self.1)
  %21 : Tensor = prim::CallMethod[name="forward"](%19, %input)
  %12 : int = prim::Constant[value=1]() # /var/lib/jenkins/workspace/beginner_source/Intro_to_TorchScript_tutorial.py:188:0
  %13 : Float(3, 4) = aten::add(%21, %h, %12) # /var/lib/jenkins/workspace/beginner_source/Intro_to_TorchScript_tutorial.py:188:0
  %14 : Float(3, 4) = aten::tanh(%13) # /var/lib/jenkins/workspace/beginner_source/Intro_to_TorchScript_tutorial.py:188:0
  %15 : (Float(3, 4), Float(3, 4)) = prim::TupleConstruct(%14, %14)
  return (%15)

代码属性:

print(traced_cell.code)


def forward(self,
    input: Tensor,
    h: Tensor) -> Tuple[Tensor, Tensor]:
  _0 = torch.add((self.linear).forward(input, ), h, alpha=1)
  _1 = torch.tanh(_0)
  return (_1, _1)

     这样我们就可以将整个模型都保存到硬盘上了,并且经过这种方式保存下来的模型可以加载到其他其他语言环境中。

     TorchScript的另一种实现方式是Script的方式,可以算是对Tracing方式的一种补充。当模型代码中含有if或者for-loop等控制流程序时,使用Tracing方式是无效的,这时候可以采用Script方式来进行实现TorchScript。实现方法跟Tracing差异不大,关键在于把jit.tracing换成jit.script方法,示例如下。

scripted_model = torch.jit.script(MyModel)
scripted_model.save('model.pt')

     除了Tracing和Script之外,我们也可以混合使用这两种方式,这里不做详述。总之,TorchScript为我们提供了一种表示形式,可以对代码进行编译器优化以提供更有效的执行。

libtorch

     在Python环境下对训练好的模型进行转换之后,我们需要C++环境下的PyTorch来读取模型并进行编译部署。这种C++环境下的PyTorch就是libtorch。因为libtorch通常用来作为PyTorch模型的C++接口,libtorch也称之为PyTorch的C++前端。

     我们可以直接从PyTorch官网下载已经编译好的libtorch安装包,当然也可以下载源码自行进行编译。这里需要注意的是,安装的libtorch版本要与Python环境下的PyTorch版本一致。

     安装好libtorch后可简单测试下是否正常。比如我们用TorchScript转换一个预训练模型,示例如下:

import torch
import torchvision.models as models
vgg16 = models.vgg16()
example = torch.rand(1, 3, 224, 224).cuda() 
model = model.eval()
traced_script_module = torch.jit.trace(model, example)
output = traced_script_module(torch.ones(1,3,224,224).cuda())
traced_script_module.save('vgg16-trace.pt')
print(output)

输出为:

tensor([[ -0.8301, -35.6095, 12.4716]], device='cuda:0',
        grad_fn=<AddBackward0>)

     然后切换到C++环境,编写CmakeLists文件如下:

cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
project(libtorch_test)
find_package(Torch REQUIRED)
message(STATUS "Pytorch status:")
message(STATUS "libraries: ${TORCH_LIBRARIES}")
add_executable(libtorch_test test.cpp)
target_link_libraries(libtorch_test "${TORCH_LIBRARIES}")
set_property(TARGET libtorch_test PROPERTY CXX_STANDARD 11)

     继续编写test.cpp代码如下:

#include "torch/script.h"
#include "torch/torch.h"
#include <iostream>
#include <memory>
using namespace std;


int main(int argc, const char* argv[]){
    if (argc != 2) {
        std::cerr << "usage: example-app <path-to-exported-script-module>\n";
        return -1;
    }


    // 读取TorchScript转化后的模型
    torch::jit::script::Module module;
    try {
        module = torch::jit::load(argv[1]);
    }


    catch (const c10::Error& e) {
        std::cerr << "error loading the model\n";
        return -1;
    }


    module->to(at::kCUDA);
    assert(module != nullptr);
    std::cout << "ok\n";


    // 构建示例输入
    std::vector<torch::jit::IValue> inputs;
    inputs.push_back(torch::ones({1, 3, 224, 224}).to(at::kCUDA));


    // 执行模型推理并输出tensor
    at::Tensor output = module->forward(inputs).toTensor();
    std::cout << output.slice(/*dim=*/1, /*start=*/0, /*end=*/5) << '\n';}

     编译test.cpp并执行,输出如下。对比Python环境下的的运行结果,可以发现基本是一致的,这也说明当前环境下libtorch安装没有问题。

ok
-0.8297, -35.6048, 12.4823
[Variable[CUDAFloatType]{1,3}]

完整部署流程

     通过前面对TorchScript和libtorch的描述,其实我们已经基本将PyTorch的C++部署已经基本讲到了,这里我们再来完整的理一下整个流程。基于C++的PyTorch模型部署流程如下。

第一步:

     通过torch.jit.trace方法将PyTorch模型转换为TorchScript,示例如下:

import torch
from torchvision.models import resnet18
model =resnet18()
example = torch.rand(1, 3, 224, 224)
tracing.traced_script_module = torch.jit.trace(model, example)

第二步:

     将TorchScript序列化为.pt模型文件。

traced_script_module.save("traced_resnet_model.pt")

第三步:

     在C++中导入序列化之后的TorchScript模型,为此我们需要分别编写包含调用程序的cpp文件、配置和编译用的CMakeLists.txt文件。CMakeLists.txt文件示例内容如下:

cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(custom_ops)
find_package(Torch REQUIRED)
add_executable(example-app example-app.cpp)
target_link_libraries(example-app "${TORCH_LIBRARIES}")
set_property(TARGET example-app PROPERTY CXX_STANDARD 14)

     包含模型调用程序的example-app.cpp示例编码如下:

#include <torch/script.h> // torch头文件.
#include <iostream>#include <memory>


int main(int argc, const char* argv[]) {
  if (argc != 2) {
    std::cerr << "usage: example-app <path-to-exported-script-module>\n";
    return -1;
  }


  torch::jit::script::Module module;
  try {
    // 反序列化:导入TorchScript模型
    module = torch::jit::load(argv[1]);
  }


  catch (const c10::Error& e) {
    std::cerr << "error loading the model\n";
    return -1;
  }
  std::cout << "ok\n";}

     两个文件编写完成之后便可对其执行编译:

mkdir example_test
cd example_test
cmake -DCMAKE_PREFIX_PATH=/path/to/libtorch ..
cmake --example_test . --config Release

第四步:

给example-app.cpp添加模型推理代码并执行:

std::vector<torch::jit::IValue> inputs;inputs.push_back(torch::ones({1, 3, 224, 224}));
// 执行推理并将模型转化为Tensor
output = module.forward(inputs).toTensor();std::cout << output.slice(/*dim=*/1, /*start=*/0, /*end=*/5) << '\n';

     以上便是C++中部署PyTorch模型的全过程,相关教程可参考PyTorch官方:

https://pytorch.org/tutorials/

欢迎扫码关注:

“深入浅出”系列之算法篇:(2)使用 C++ 部署 PyTorch 模型 通常,在此阶段,我们将创建一个 REST-API 来为模型提供服务(或使用 TorchServing),将该 API 部署在具有自动缩放功能的 Kubernetes/AKS/Fargate/EC2 集群上,并从应用程序中查询该 API。如果您正在运行 MacOS(您不太可能在生产中使用),您可能会遇到防火墙问题,请apple.quarantine通过运行允许 Libtorch 禁用。以下是一些内部代码,它们定义模型、加载训练后的权重并使用 保存模型torch.jit.script。 阅读详情

相关推荐

在C++平台部署pytorch模型的两种方法

1、准备工作 1、模型转换代码: import torch from model.FCN_Aux import FCN_AUX model = FCN_AUX(2) model_weight_path = './model/better.pth'#训练完模型位置 model.load_state_dict(torch.load(model_weight_path)) model.cuda() model.eval() example = torch.rand(1, 3, 224, 224).cuda() t

m0_46278347的博客 3374

C++部署pytorch模型

转自https://www.jianshu.com/p/02f16439892d,侵删 (一)————将pytorch模型转化为torchscript模型 Pytorch官方提供的C++API名为libtorch,在Pytorch1.0版本之后开始支持windows,以后就可以直接用libtorch来部署Pytorch模型了。 在Windows平台上用C++部署深度学习应用一直很麻烦,caffe使用自定义层还需要自己写backward(),而TensorFlow对Windows平台的支持也不是很好,在W

weixin_39450742的博客 2165

c++调用pytorch libtorch(基础篇)

c++调用pytorch libtorch1.将pytorch模型转换成Torch Script参考文献 以GitHub [见参考文献1]为例,学习了c++调用pytorch API libtorch的实现过程。 1.将pytorch模型转换成Torch Script 官方tutorial https://pytorch.org/tutorials/advanced/cpp_export.html中给出了当前将pytorch模型转成Torch Script的两种方式(官方源码如下): 1.Converti

驽马十驾,功在不舍;锲而不舍,金石可镂。 4490

部署Pytorch模型到C++环境

由于工作原因需要部署Pytorch模型到c++环境下,目前大概有三种方式。 1、pytorch转成onnx文件后,通过opencv读取。 2、pytroch转成onnx文件后,通过onnxruntime读取。 3、利用libtorch库,也就是pytorch的c++版。首先的将pytorch训练好的模型导出onnx文件。...............

likesomething1的博客 6803

别再只跑recon-all了!FreeSurfer实战:从T1图像到freeview可视化的完整避坑指南

本文详细解析FreeSurfer从T1图像处理到freeview可视化的全流程,包括环境配置、recon-all深度解析、高级可视化技巧及性能优化策略。特别针对常见错误提供解决方案,帮助用户高效完成MRI数据分析,避免常见陷阱。

weixin_33404102的博客 353

51单片机定时器的原理、应用与编程实现

本文系统介绍了51单片机定时器的基本原理与应用。首先阐述了定时器的工作原理,包括定时模式和计数模式的区别。然后详细讲解了定时器的四种工作模式(方式0-方式3)及其适用场景,并分析了相关寄存器(TMOD、TCON、THx/TLx)的功能设置。文章还给出了定时器编程的具体步骤,包括初始化、计数初值计算和示例代码。最后通过LED闪烁、PWM波形产生、脉冲计数等实际应用案例,展示了定时器的多样化应用。掌握这些知识对嵌入式系统开发具有重要意义。

2501_91227323的博客 1524

PyTorch模型C++部署

在生产环境中 PyTorch 模型经常需要部署在 C++ 程序中,目前我找的方法有三种: LibTorch: PyTorch 官方 C++ 库 ONNX Runtime OpenCV: DNN 模块 示例网络 本文以 PyTorch 官方教程中的 SuperResolution 模型为例,介绍模型在 C++ 中如何部署。模型结构如下: # Super Resolution model definition in PyTorch import torch.nn as nn import torch.nn.

mightbxg的博客 7092

实战分享:如何利用svchost进程绕过360防护(附完整Shellcode注入教程)

本文深入解析系统进程安全防护机制,探讨svchost等关键进程的安全特性与防护策略。详细分析安全软件的行为检测和内存保护技术,提供系统加固与监控实践建议,助力企业构建多层次防御体系,有效应对潜在安全威胁。

weixin_30752699的博客 99

如何在c++平台上部署pytorch模型?

pytorch接口简单灵活,深受深度学习研究者的喜爱,不少论文及github上的开源代码是用pytorch写的,那么,训练完pytorch模型后,部署到c++平台上,着实让不少人头疼.好在,pytorch开放了libtorch c++接口,至此,caffe, mxnet, tensorflow, pytorch均完善了python以及c++接口,无论是在PC端,还是在移动端,均可满足大多数人的训练...

thankyvision 1万+

化学科学催化反应产率预测之Transformer建模SMILES(Datawhale AI 夏令营)

循环神经网络:由于所有的前文信息都蕴含在一个隐向量中,随着序列长度的增加,早期的上下文信息会逐渐被遗忘。卷积神经网络:受限的上下文窗口在建模长文本时存在天然不足。需要多层卷积操作才能处理长文本。在本篇文章中,我们学习了Transformer的基本架构及其在化学反应产率预测中的应用。通过利用Transformer的Encoder部分对SMILES进行建模,我们能够更有效地捕捉序列数据的特征,从而提高模型的预测性能。

不想宅的冷同学 1096

IGBT单管并联方案全解析:从均流设计到热管理实战技巧

本文深入解析了IGBT单管并联技术在新能源车电驱系统中的应用,重点探讨了均流设计与热管理实战技巧。通过优化寄生电感控制、动态均流和驱动电路设计,提升系统稳定性和效率,为工程师提供了一套完整的解决方案。

weixin_28720573的博客 441

C++部署pytorch模型(上)

文章目录C++部署pytorch模型(上)前言训练一个简单的pytorch网络 C++部署pytorch模型(上) 前言 项目需要将pytorch训练好的网络用c++调用,在正式开始项目之前,在网上查了各种资料,共有三种实现方法: 直接将网络从最基础的CNN模块用C++实现; 将网咯模型和参数保存,然后使用opencv的DNN模块加载,这个方法tensorflow、torch等其他网络架构也能用,具体包含哪些下文会给出; 使用pytorch官网提供的c++接口:LibTorch。其原理也是保存网络模型和参

cai1493105270的博客 1944

谷歌A2A协议入门指南:附简易Python代码示例

继"关税"之后,当下最热门的词汇当属AI智能体——这种基于人工智能的软件能够执行复杂任务、实现工作流自动化并提升生产效率。但迄今为止,大多数智能体都处于各自为政的状态,难以顺畅协作。就像团队执行重大项目时,成员之间却无法交流!对于技术人员而言,一个可能遇到的典型场景是:假设你需要协调四个不同的AI服务——处理用户查询的Gemini智能体、在向量数据库进行搜索的AI应用、基于Claude的摘要生成器,以及运行专业领域逻辑的Python智能体。

独立开发,substack顶级编辑 800

使用 C++ 部署 PyTorch 模型

默认情况下会根据上一次训练保留的参数继续训练,如果要从头训练,需要删除./mlruns文件夹,新训练的模型回报存在 ./models路径。在build文件夹有可执行文件torch-cpp-deployment,运行torch-cpp-deployment。把模型转换为TorchScript格式,把训练好的模型放在 ./models/路径下。(1) 训练PyTorch model并保存,把模型转换成TorchScript。先用python训练网络,在转换模型格式,最后用C++部署模型。

qq_35732321的博客 569

YOLOv11改进 - 卷积Conv | SPD-Conv空间深度转换卷积优化空间信息编码,攻克小目标检测难题

本文介绍了一种名为SPD-Conv的新型CNN构建块及其在YOLOv11中的结合。传统CNN在处理低分辨率图像或小物体时,因使用步长卷积和池化层导致细粒度信息丢失、性能下降。SPD-Conv由空间到深度(SPD)层和非步长卷积(Conv)层组成,完全消除卷积步长和池化层,避免信息损失。SPD层重排特征图元素将空间信息转换到深度维度,非步长卷积层进一步处理特征图。我们将SPD-Conv集成进YOLOv11,实验证明其在低分辨率图像和小物体检测任务上显著优于现有模型。

魔改工程师的博客 1144

手把手教你安装 OpenClaw 小龙虾(MAC安装教程),一次成功不踩坑

本文详细介绍了在Mac上安装OpenClaw的完整流程。主要内容包括:1)准备工作(磁盘空间、网络环境、终端工具);2)安装Homebrew包管理器及常见问题解决;3)安装Node.js 22+版本(环境核心);4)Git安装与验证;5)OpenClaw项目克隆、依赖安装及运行配置;6)大模型配置方法(以MiniMax为例)。文章提供了详细的命令行操作步骤和常见错误解决方案,特别强调了网络环境要求和Apple Silicon芯片的原生支持注意事项。最后展示了验证配置成功的方法和资源获取渠道。

Chengbei11的博客 6344

[PyTorch]PyTorch的C++前端和模型部署

一.前言 差不多一年前的这个时候,在狗厂实习的时候,主要用PyTorch做一些事情。那个时候针对PyTorch的模型部署问题,主要讨论ONNX。想像一下今天的DL框架格局,PyTorch,Tensorflow,Keras,Caffe,Caffe2等,持久化模型之间不兼容。常见的一种情况是,一篇论文基于不同框架写不同版本的代码。那么,很显然的一个需求是: 一个框架下的模型如何可以转化为另一个框架下的模型? 相关工作有一些,ONNX是其中一个,微软也做过类似工作。但是问题是总会遇到一些无法直接转换的组件。

sunlin972913894的博客 985

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

使用C++调用并部署pytorch模型

1.背景(Background) 上图显示了目前深度学习模型在生产环境中的方法,本文仅探讨如何部署pytorch模型! 至于为什么要用C++调用pytorch模型,其目的在于:使用C++及多线程可以加快模型预测速度 关于模型训练有两种方法,一种是直接使用C++编写训练代码,可以做到搭建完整的网络模型,但是无法使用迁移学习,而迁移学习是目前训练样本几乎都会用到的方法,另一种是使...

weixin_30401605的博客 2336

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

C++部署pytorch模型(中)

在C++部署pytorch模型(上)中我们已经将所有准备工作做好,今天开始利用opencv部署网络。 利用opencv加载训练好的模型和网络 参考链接: OpenCV4.0 运行快速风格迁移(Torch) opencv官方文档 OpenCV加载Pytorch模型出现Unsupported Lua type 解决方法 将模型从PYTORCH导出到ONNX并使用ONNX RUNTIME运行(官网链接) 这个方法算是一个比较常用的方法,而且可以用到许多深度学习框架上面: 根据opencv官方文档中的说明,可以支持

cai1493105270的博客 1914

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

在c++平台上部署pytorch模型

如何在c++平台上部署pytorch模型? pytorch接口简单灵活,深受深度学习研究者的喜爱,不少论文及github上的开源代码是用pytorch写的,那么,训练完pytorch模型后,部署到c++平台上,着实让不少人头疼.好在,pytorch开放了libtorch c++接口,至此,caffe, mxnet, tensorflow, pytorch均完善了python以及c++接口,无论是在PC端,还是在移动端,均可满足大多数人的训练和模型部署需求. 深度学习框架趋于大同的情况下,需要耐心对各框架熟悉

Boys_Wu的博客 791

使用pytorch的C++API部署图像分类模型

在部署pytorch模型时候,使用C++ API能有更高的效率,本文记录使用C++ API部署一个图像分类模型的过程。 1.模型转换 首先需要将pytorch模型转化为Torch Script,Torch Script是PyTorch模型的一种表示,可以被Torch Script编译器理解,编译和序列化。用torch script把torch模型转成c++接口可读的模型有两种方式:Tracing && Annotation. tracing比Annotation简单,但只适合结构固定的网络模

qq_37546267的博客 1544

机器视觉系列5:C++部署pytorch模型onnxruntime

环境:visual studio 2019;pytorch1.8;

axe的博客 1万+
上一篇: 新手必会的 9 个 Python 技巧!
下一篇: 一个小改动,CNN输入固定尺寸图像改为任意尺寸图像
机器学习算法那些事
博客等级 码龄9年 1633粉丝 62原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值