赞
踩
tritonserver学习之二:tritonserver编译
tritonserver学习之三:tritonserver运行流程
tritonserver学习之六:自定义c++、python custom backend实践
tritonserver学习之八:redis_caches实践
tritonserver学习之九:tritonserver grpc异步模式
backend是triton中的核心部件,它负责处理来自客户端的推理请求,并将请求转发给相应的模型进行推理。每个backend都对应一个特定的深度学习框架,例如TensorFlow、PyTorch、ONNX、paddle等。当客户端发送推理请求时,Triton Server会根据请求的模型和版本信息,将请求路由到相应的backend进行处理。
大家知道,triton serve的每个模型都有个配置文件:config.pbtxt,这个配置中,明确了模型的meta信息,当然也包含了对应backend信息,例如代码中的官方模型simple的配置如下:
- name: "simple"
- platform: "tensorflow_graphdef"
- max_batch_size: 8
- input [
- {
- name: "INPUT0"
- data_type: TYPE_INT32
- dims: [ 16 ]
- },
- {
- name: "INPUT1"
- data_type: TYPE_INT32
- dims: [ 16 ]
- }
- ]
- output [
- {
- name: "OUTPUT0"
- data_type: TYPE_INT32
- dims: [ 16 ]
- },
- {
- name: "OUTPUT1"
- data_type: TYPE_INT32
- dims: [ 16 ]
- }
- ]

看到这个配置可能会有疑惑,配置中没有设置banckend的信息,哪triton是如何找到对应的backend的呢,答案是通过【platform】这个字段找到的,为什么是通过这个字段找到的,先不细讲,大概说一下,先看如下代码,位于core代码库,位于core/src/constants.h:
- constexpr char kTensorFlowGraphDefPlatform[] = "tensorflow_graphdef";
- constexpr char kTensorFlowSavedModelPlatform[] = "tensorflow_savedmodel";
- constexpr char kTensorFlowGraphDefFilename[] = "model.graphdef";
- constexpr char kTensorFlowSavedModelFilename[] = "model.savedmodel";
- constexpr char kTensorFlowBackend[] = "tensorflow";
【platform】这个字段的设置是要求的,对于TensorFlow模型,云端推理上线主要有两种格式,分别为:
- GraphDef
- SavedModel(推荐)
对应的【platform】字段是固定的,分别为:tensorflow_graphdef和tensorflow_savedmodel,triton就是通过这两个字符串来找到对应的backend的。
triton所有backend的实现,包括pytorch_backend、paddle_backend等所有backend的实现,实现原理都是一样的,大家可以看一下源码,主要是实现7个api:
- TRITONBACKEND_Initialize:创建ModelState对象。
- TRITONBACKEND_ModelInitialize
- TRITONBACKEND_ModelInstanceInitialize:创建ModelInstanceState对象,可以通过这个对象调用LoadModel函数
- TRITONBACKEND_ModelInstanceExecute
- TRITONBACKEND_ModelInstanceFinalize
- TRITONBACKEND_ModelFinalize
- TRITONBACKEND_Finalize
架构如下:
linux系统提供一套api,实现了动态加载so,triton中,对各个backend库的加载使用的就是这种方式,api的原型如下:
- void *dlopen(const char *filename, int flag);
- char *dlerror(void);
- void *dlsym(void *handle, const char *symbol);
- int dlclose(void *handle);
使用上面函数之前,需要包含头文件:
#include <dlfcn.h>
dlopen:以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程。
dlsym:在打开的动态库中查找符号的值,其不仅能够获取函数地址,也能够获取全局变量地址,非常之方便。
dlclose:关闭动态库。
dlerror:返回一个描述最后一次调用dlopen、dlsym,或dlclose的错误信息的字符串。
tirton中,对banckend的管理,主要在core代码中,代码位于:core/src/backend_manager.cc中,主要是两个类:
- class TritonBackendManager {}
- class TritonBackend {}
这两个类,严格来说,只是banckend的一个proxy,这两个类最重要的就是获取到模型对应backend的7个api,获取api指针后,用于之后的推理。
TritonBackendManager类的定义如下:
- class TritonBackendManager {
- public:
- static Status Create(std::shared_ptr<TritonBackendManager>* manager);
-
- Status CreateBackend(
- const std::string& name, const std::string& dir,
- const std::string& libpath,
- const triton::common::BackendCmdlineConfig& backend_cmdline_config,
- bool is_python_based_backend, std::shared_ptr<TritonBackend>* backend);
-
- Status BackendState(
- std::unique_ptr<
- std::unordered_map<std::string, std::vector<std::string>>>*
- backend_state);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TritonBackendManager);
- TritonBackendManager() = default;
- std::unordered_map<std::string, std::shared_ptr<TritonBackend>> backend_map_;
- };

Create:这个函数比较好理解,静态函数,创建 TritonBackendManager类对象。
CreateBackend:根据backend名称、so路径、配置,创建对应的backend,如果TRITONBACKEND_Initialize函数指针不为空,则运行该函数。
BackendState获取backend配置信息,例如:
这个类直接和各个backend进行交互,加载backend动态库,同时获取对应的7个api函数指针。
- class TritonBackend {
- public:
- struct Attribute {
- Attribute()
- : exec_policy_(TRITONBACKEND_EXECUTION_BLOCKING),
- parallel_instance_loading_(false)
- {
- }
- TRITONBACKEND_ExecutionPolicy exec_policy_;
- std::vector<inference::ModelInstanceGroup> preferred_groups_;
- // Whether the backend supports loading model instances in parallel
- bool parallel_instance_loading_;
- };
- typedef TRITONSERVER_Error* (*TritonModelInitFn_t)(
- TRITONBACKEND_Model* model);
- typedef TRITONSERVER_Error* (*TritonModelFiniFn_t)(
- TRITONBACKEND_Model* model);
- typedef TRITONSERVER_Error* (*TritonModelInstanceInitFn_t)(
- TRITONBACKEND_ModelInstance* instance);
- typedef TRITONSERVER_Error* (*TritonModelInstanceFiniFn_t)(
- TRITONBACKEND_ModelInstance* instance);
- typedef TRITONSERVER_Error* (*TritonModelInstanceExecFn_t)(
- TRITONBACKEND_ModelInstance* instance, TRITONBACKEND_Request** requests,
- const uint32_t request_cnt);
-
- static Status Create(
- const std::string& name, const std::string& dir,
- const std::string& libpath,
- const triton::common::BackendCmdlineConfig& backend_cmdline_config,
- std::shared_ptr<TritonBackend>* backend);
- ~TritonBackend();
-
- const std::string& Name() const { return name_; }
- const std::string& Directory() const { return dir_; }
- const std::string& LibPath() const { return libpath_; }
- const TritonServerMessage& BackendConfig() const { return backend_config_; }
- const Attribute& BackendAttributes() const { return attributes_; }
-
- TRITONBACKEND_ExecutionPolicy ExecutionPolicy() const
- {
- return attributes_.exec_policy_;
- }
- void SetExecutionPolicy(const TRITONBACKEND_ExecutionPolicy policy)
- {
- attributes_.exec_policy_ = policy;
- }
-
- void* State() { return state_; }
- void SetState(void* state) { state_ = state; }
- bool IsPythonBackendBased() { return is_python_based_backend_; }
- void SetPythonBasedBackendFlag(bool is_python_based_backend)
- {
- is_python_based_backend_ = is_python_based_backend;
- }
-
- TritonModelInitFn_t ModelInitFn() const { return model_init_fn_; }
- TritonModelFiniFn_t ModelFiniFn() const { return model_fini_fn_; }
- TritonModelInstanceInitFn_t ModelInstanceInitFn() const
- {
- return inst_init_fn_;
- }
- TritonModelInstanceFiniFn_t ModelInstanceFiniFn() const
- {
- return inst_fini_fn_;
- }
- TritonModelInstanceExecFn_t ModelInstanceExecFn() const
- {
- return inst_exec_fn_;
- }
-
- private:
- typedef TRITONSERVER_Error* (*TritonBackendInitFn_t)(
- TRITONBACKEND_Backend* backend);
- typedef TRITONSERVER_Error* (*TritonBackendFiniFn_t)(
- TRITONBACKEND_Backend* backend);
- typedef TRITONSERVER_Error* (*TritonBackendAttriFn_t)(
- TRITONBACKEND_Backend* backend,
- TRITONBACKEND_BackendAttribute* backend_attributes);
-
- TritonBackend(
- const std::string& name, const std::string& dir,
- const std::string& libpath, const TritonServerMessage& backend_config);
-
- void ClearHandles();
- Status LoadBackendLibrary();
-
- Status UpdateAttributes();
-
- // The name of the backend.
- const std::string name_;
-
- // Full path to the directory holding backend shared library and
- // other artifacts.
- const std::string dir_;
-
- // Full path to the backend shared library.
- const std::string libpath_;
-
- bool is_python_based_backend_;
-
- // Backend configuration as JSON
- TritonServerMessage backend_config_;
-
- // backend attributes
- Attribute attributes_;
-
- // dlopen / dlsym handles
- void* dlhandle_;
- TritonBackendInitFn_t backend_init_fn_;
- TritonBackendFiniFn_t backend_fini_fn_;
- TritonBackendAttriFn_t backend_attri_fn_;
- TritonModelInitFn_t model_init_fn_;
- TritonModelFiniFn_t model_fini_fn_;
- TritonModelInstanceInitFn_t inst_init_fn_;
- TritonModelInstanceFiniFn_t inst_fini_fn_;
- TritonModelInstanceExecFn_t inst_exec_fn_;
-
- // Opaque state associated with the backend.
- void* state_;
- }

create函数:静态函数,创建该类的对象。
其他函数基本都是围绕加载so,获取api函数指针相关。
以上就是backend相关的知识。
triton支持了目前市场上所有主流的深度学习框架,对于paddle,官方镜像只有21.10版本支持,其他版本都不支持,如果需要在新版本支持,则需要自己进行编译,可以参考前面编写的博客,编译部分:tritonserver学习之二:tritonserver编译-CSDN博客,博客中介绍的backend的类,主要还是一个proxy的作用,直接调用深度学习api的还是对应的backend,大家可以自己学习理解下,不清楚的,欢迎评论交流。欢迎各位同行关注一下公众号:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。