久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

基于C 的PyTorch模型部署

 aideshizhe0 2023-04-30 發(fā)布于河南

PyTorch

Author:louwill

Machine Learning Lab

引言

     PyTorch作為一款端到端的深度學習框架,在1.0版本之后已具備較好的生產(chǎn)環(huán)境部署條件。除了在web端撰寫REST API進行部署之外(參考),軟件端的部署也有廣泛需求,。尤其是最近發(fā)布的1.5版本,提供了更為穩(wěn)定的C++前端API。

     工業(yè)界與學術界最大的區(qū)別在于工業(yè)界的模型需要落地部署,,學界更多的是關心模型的精度要求,而不太在意模型的部署性能,。一般來說,,我們用深度學習框架訓練出一個模型之后,使用Python就足以實現(xiàn)一個簡單的推理演示了,。但在生產(chǎn)環(huán)境下,,Python的可移植性和速度性能遠不如C++。所以對于深度學習算法工程師而言,,Python通常用來做idea的快速實現(xiàn)以及模型訓練,,而用C++作為模型的生產(chǎn)工具。目前PyTorch能夠完美的將二者結合在一起,。實現(xiàn)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
# 創(chuàng)建模型實例 my_model = MyModel()# 輸入示例x, h = torch.rand(34), torch.rand(34)# torch.jit.trace方法對模型構建TorchScripttraced_model = torch.jit.trace(my_model, (x, h))# 保存轉(zhuǎn)換后的模型traced_model.save('model.pt')

     在這段代碼中,,我們先是定義了一個簡單模型并創(chuàng)建模型實例,,然后給定輸入示例,,Tracing方法最關鍵的一步在于使用torch.jit.trace方法對模型進行TorchScript轉(zhuǎn)化。我們可以獲得轉(zhuǎn)化后的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)

     這樣我們就可以將整個模型都保存到硬盤上了,,并且經(jīng)過這種方式保存下來的模型可以加載到其他其他語言環(huán)境中。

     TorchScript的另一種實現(xiàn)方式是Script的方式,,可以算是對Tracing方式的一種補充,。當模型代碼中含有if或者for-loop等控制流程序時,使用Tracing方式是無效的,,這時候可以采用Script方式來進行實現(xiàn)TorchScript,。實現(xiàn)方法跟Tracing差異不大,關鍵在于把jit.tracing換成jit.script方法,,示例如下,。

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

     除了Tracing和Script之外,我們也可以混合使用這兩種方式,,這里不做詳述,。總之,TorchScript為我們提供了一種表示形式,,可以對代碼進行編譯器優(yōu)化以提供更有效的執(zhí)行,。

libtorch

     在Python環(huán)境下對訓練好的模型進行轉(zhuǎn)換之后,我們需要C++環(huán)境下的PyTorch來讀取模型并進行編譯部署,。這種C++環(huán)境下的PyTorch就是libtorch,。因為libtorch通常用來作為PyTorch模型的C++接口,libtorch也稱之為PyTorch的C++前端,。

     我們可以直接從PyTorch官網(wǎng)下載已經(jīng)編譯好的libtorch安裝包,,當然也可以下載源碼自行進行編譯。這里需要注意的是,,安裝的libtorch版本要與Python環(huán)境下的PyTorch版本一致,。

圖片

     安裝好libtorch后可簡單測試下是否正常。比如我們用TorchScript轉(zhuǎn)換一個預訓練模型,,示例如下:

import torchimport torchvision.models as modelsvgg16 = 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.609512.4716]], device='cuda:0',        grad_fn=<AddBackward0>)

     然后切換到C++環(huán)境,,編寫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)

     繼續(xù)編寫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轉(zhuǎn)化后的模型    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));
    // 執(zhí)行模型推理并輸出tensor    at::Tensor output = module->forward(inputs).toTensor(); std::cout << output.slice(/*dim=*/1, /*start=*/0, /*end=*/5) << '\n';}

     編譯test.cpp并執(zhí)行,,輸出如下,。對比Python環(huán)境下的的運行結果,可以發(fā)現(xiàn)基本是一致的,,這也說明當前環(huán)境下libtorch安裝沒有問題,。

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

完整部署流程

     通過前面對TorchScript和libtorch的描述,其實我們已經(jīng)基本將PyTorch的C++部署已經(jīng)基本講到了,,這里我們再來完整的理一下整個流程,。基于C++的PyTorch模型部署流程如下。

第一步:

     通過torch.jit.trace方法將PyTorch模型轉(zhuǎn)換為TorchScript,,示例如下:

import torchfrom torchvision.models import resnet18model =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模型,為此我們需要分別編寫包含調(diào)用程序的cpp文件,、配置和編譯用的CMakeLists.txt文件,。CMakeLists.txt文件示例內(nèi)容如下:

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)

     包含模型調(diào)用程序的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';}

     兩個文件編寫完成之后便可對其執(zhí)行編譯:

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

第四步:

給example-app.cpp添加模型推理代碼并執(zhí)行:

std::vector<torch::jit::IValue> inputs;inputs.push_back(torch::ones({13224224}));// 執(zhí)行推理并將模型轉(zhuǎn)化為Tensoroutput = module.forward(inputs).toTensor();std::cout << output.slice(/*dim=*/1, /*start=*/0, /*end=*/5) << '\n';

     以上便是C++中部署PyTorch模型的全過程,相關教程可參考PyTorch官方:

https://pytorch.org/tutorials/

參考資料:

https://pytorch.org/tutorials/

https://pytorch.org/features/

    本站是提供個人知識管理的網(wǎng)絡存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導購買等信息,,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多