模型推理模板(代码片段)

洪流之源 洪流之源     2022-12-07     726

关键词:

infer.h

#pragma once

#include <string>
#include <future>
#include <memory>

// 封装接口类
class Infer 

public:
    virtual std::shared_future<std::string> commit(const std::string& input) = 0;
;

std::shared_ptr<Infer> create_infer(const std::string& file);

infer.cpp

#include "infer.h"
#include <thread>
#include <vector>
#include <condition_variable>
#include <mutex>
#include <string>
#include <future>
#include <queue>
#include <functional>

// 封装接口类

struct Job

    std::shared_ptr<std::promise<std::string>> pro;
    std::string input;
;

class InferImpl : public Infer 

public:
    virtual ~InferImpl() 
    
        stop();
    

    void stop() 
    
        if (running_) 
        
            running_ = false;
            cv_.notify_one();
        

        if (worker_thread_.joinable())
            worker_thread_.join();
    

    bool startup(const std::string& file) 
    

        file_ = file;
        running_ = true; // 启动后,运行状态设置为true

        // 线程传递promise的目的,是获得线程是否初始化成功的状态
        // 而在线程内做初始化,好处是,初始化跟释放在同一个线程内
        // 代码可读性好,资源管理方便
        std::promise<bool> pro;
        worker_thread_ = std::thread(&InferImpl::worker, this, std::ref(pro));
        /*
            注意:这里thread 一构建好后,worker函数就开始执行了
            第一个参数是该线程要执行的worker函数,第二个参数是this指的是class InferImpl,第三个参数指的是传引用,因为我们在worker函数里要修改pro。
         */
        return pro.get_future().get();
    

    virtual std::shared_future<std::string> commit(const std::string& input) override 
    
        Job job;
        job.input = input;
        job.pro.reset(new std::promise<std::string>());
        std::shared_future<std::string> fut = job.pro->get_future();
        
            std::lock_guard<std::mutex> l(lock_);
            jobs_.emplace(std::move(job));
        
        cv_.notify_one();
        return fut;
    

    void worker(std::promise<bool>& pro) 
    
        // load model
        if (file_ != "trtfile") 
        
            // failed
            pro.set_value(false);
            printf("Load model failed: %s\\n", file_.c_str());
            return;
        

        // load success
        pro.set_value(true); // 这里的promise用来负责确认infer初始化成功了

        std::vector<Job> fetched_jobs;
        while (running_) 
        
            
                std::unique_lock<std::mutex> l(lock_);
                // 一直等着,cv_.wait(lock, predicate) 
                // 如果 running不在运行状态 或者说 jobs_有东西 而且接收到了notify one的信号
                cv_.wait(l, [&]() return not running_ || not jobs_.empty(); ); 

                // 如果停止运行,则直接结束循环
                if (not running_) break;

                int batch_size = 5;
                for (int i = 0; i < batch_size && not jobs_.empty(); ++i) 
                   // jobs_不为空的时候
                    fetched_jobs.emplace_back(std::move(jobs_.front())); // 就往里面fetched_jobs里塞东西
                    jobs_.pop();                                         // fetched_jobs塞进来一个,jobs_那边就要pop掉一个。(因为move)
                
            

            // 一次加载一批,并进行批处理
            // forward(fetched_jobs)
            for (auto& job : fetched_jobs) 
            
                job.pro->set_value(job.input + "---processed");
            
            fetched_jobs.clear();
        
        printf("Infer worker done.\\n");
    

private:
    std::atomic<bool> running_ false ;
    std::string file_;
    std::thread worker_thread_;
    std::queue<Job> jobs_;
    std::mutex lock_;
    std::condition_variable cv_;
;

std::shared_ptr<Infer> create_infer(const std::string& file)

    // 实例化一个推理器的实现类(inferImpl),以指针形式返回 
    std::shared_ptr<InferImpl> instance = std::make_shared<InferImpl>();

    // 推理器实现类实例(instance)启动。这里的file是engine file
    if (not instance->startup(file)) 
                        
        instance.reset(); // 如果启动不成功就reset
    

    return instance;

main.cpp

#include "infer.h"

int main()

    auto infer = create_infer("trtfile"); // 创建及初始化
    if (infer == nullptr) 
    
        printf("Infer is nullptr.\\n");
        return -1;
    

    // 将任务提交给推理器(推理器执行commit),同时推理器(infer)也等着获取(get)结果
    printf("commit msg = %s\\n", infer->commit("msg").get().c_str()); 

    return 0;

模型推理openvino性能测试(代码片段)

...openvino性能测试的姿势。文章目录1、安装openvino2、openvino模型下载与推理实践3、openvino性能测试姿势3.1下载alexnet模型3.2模型转换3.3性能测试1、安装openvino 可以参考《【模型推理】ubuntu配置和使用openvino》。2、openvino模型下载与... 查看详情

模型推理谈谈为什么量化能加速推理(代码片段)

... o_O O_o ~_~ o_O 本文主要讨论一下为什么量化能加速模型推理。 前面已经写过几篇关于模型量化相关的文章:《【模型推理】谈谈几种量化策略:MinMax、KLD、ADMM、EQ》、《【模型推理】谈谈模型量化组织方式》、... 查看详情

你或许也想拥有专属于自己的ai模型文件格式(推理部署篇)-(代码片段)

OCL-ENGINE的CPUDebug调试接口适配1、前言2、介绍余弦相似度计算函数的实现细节2.1、模板函数实现3、InferenceDebugByCpu调试推理接口3.1、调用流程3.2、实现细节4、cpu_run调试推理部分如何从cl核函数转换4.1、关于opencl的cl核函数说明4.2... 查看详情

模型推理谈谈模型量化组织方式(代码片段)

...O_o >_< o_O O_o ~_~ o_O 本文主要聊一下深度学习模型量化组织方式。 在我的这篇《【模型推理】谈谈推理引擎的推理组织流程》文章里对模型量化策略进行了一些介绍,有兴趣的同学可以翻看一下。今天这里主要... 查看详情

tensorrt系列模型推理(代码片段)

 推理代码://tensorRTinclude#include<NvInfer.h>#include<NvInferRuntime.h>//cudainclude#include<cuda_runtime.h>//systeminclude#include<stdio.h>#include<math.h>#include&l 查看详情

模型推理一文看懂winograd卷积加速算法(代码片段)

...篇卷积加速相关的文章,感兴趣的同学可以查阅《【模型推理】一文看懂Img2Col卷积加速算法》、《【模型推理】一文看懂GoogleTPU脉动阵列加速卷积计算原理》、《【模型推理】谈谈为什么 查看详情

模型推理寒武纪mluresnet50量化及离线推理流程(代码片段)

...搭建、resnet50量化、resnet50离线推理,resnet系列是标准模型,其他模型也可参考该流程执行。文章目录1、 查看详情

markdownatlas300实验:模型验证caffe_npu推理误差(代码片段)

查看详情

markdown使用mxnet实现生产级神经网络模型量化推理(代码片段)

查看详情

模型推理谈谈非线性激活函数的量化方式(代码片段)

...O_o >_< o_O O_o ~_~ o_O 本文主要聊一聊深度学习模型量化中对激活函数的处理方式。 之前已经写过几篇关于模型量化的文章:《【模型推理】谈谈几种量化策略:MinMax、KLD、ADMM、EQ》、《【模型推理】谈谈模... 查看详情

极智ai|tensorrtparser构建模型推理方法(代码片段)

...好,我是极智视界,本文介绍一下TensorRTParser构建模型推理方法。 TensorRT构建模型推理一般有三种方式:(1)使用框架自带的TensorRT接口,如TF-TRT、Torch-TRT;(2)使用Parser前端解释器,如TF/ 查看详情

模型推理加速系列bert加速方案对比torchscriptvs.onnx(代码片段)

文章目录简介基于ONNX导出ONNX模型示例代码基于TorchScriptJITTorchScript示例代码推理速度评测CPUGPU附录简介本文以BERT-base的为例,介绍2种常用的推理加速方案:ONNX和TorchScript,并实测对比这两种加速方案与原始Pytorch模型... 查看详情

模型推理ncnn模型转换及量化流程(代码片段)

...规范 O_o >_< o_O O_o ~_~ o_O 本文介绍一下ncnn模型转换及量化流程,以from_darknetyolov4为例。 关于ncnn的ubuntu和windows安装方法可以参考我之前写的:《【嵌入式AI】ubuntu安装ncnn》、《【经验分享】win10qm 查看详情

模型推理教你简化onnxupsample算子(代码片段)

... 实际部署中经常会涉及到pytorch/tensorflow/darknet->onnx的模型转换过程。本身模型转换过程就比较麻烦(当然pytorchexportonnx十分方便)&#x 查看详情

模型推理ubuntu配置和使用openvino(代码片段)

 本教程详细记录了在ubuntu上安装openvino的方法。文章目录1、cloneopenvino2、编译3、安装python接口4、cloneopen_model_zoo5、测试1、cloneopenvinogitclone--recursivehttps://gitee.com/openvinotoolkit-prc/openvino.git 若在clone一些三方依赖外链时超时࿰ 查看详情

极智ai|libtorch调用模型推理方法(代码片段)

...大家好,我是极智视界,本文介绍一下libtorch调用模型推理方法。 之前写了一篇《ubuntu安装libtorch》,所以关于ubuntu上安装libtorch的方法,有兴趣的同学可以自行查看。libtorch是pytorch的C++版本,支 查看详情

a.特定领域知识图谱知识推理方案:知识图谱推理算法综述[一](基于距离的翻译模型:transetranshtransrtranshtransarotate)(代码片段)

...推理方案:知识图谱推理算法综述[一](基于距离的翻译模型:TransE、TransH、TransR、TransH、TransA、RotatE)A.特定领域知识图谱知识推理方案:知识图谱推理算法综述[二](DTransE/PairRE:基于表示学习的知识图谱链接预测算法)A.特定... 查看详情

pytorch模型转换为rknn模型,使用npu推理(代码片段)

一、转换为onnx模型在yolov5代码中运行export.py,转换为onnx模型,参数根据自己需要修改。二、创建转换目录然后在rknn文件夹下,找到onnx2rknn.py、dataset.txt和coco2017数据集,将它们复制到新的文件夹中,作为rknn模... 查看详情