文章大綱
- 引言
- 一、模型加載概述
- 二、核心數據結構
- 三、模型加載核心流程
引言
Mindspore 是一款華為開發開源的AI推理框架,而Mindspore Lite則是華為為了適配在移動終端設備上運行專門定制的版本,使得我們可以在OpenHarmony快速實現模型加載和推理等功能,模型加載則是利用 Mindspore Lite 進行推理任務的首要步驟,它猶如打開智能應用大門的鑰匙,精準且高效地將預訓練模型導入到運行環境中,為后續的推理計算奠定堅實基礎。無論是在移動端的智能應用開發,還是邊緣計算設備的智能任務處理,Mindspore Lite 加載模型的能力都直接影響著整個系統的運行效率與智能化表現,值得我們深入探究其原理、流程與優化策略,接下來就重點解讀核心API 及其流程。
本文非Mindspore入門科普文,需要具備一定的Mindspore 知識。
一、模型加載概述
加載的本質就是把模型從文件Buffer 轉為Mindspore 后續推理時所需要的模型的相關對象。
CPU 方式直接加載的話就是直接通過本地設備的CPU完成這些工作,這些作為推理的輸入直接使用;而通過NNRT 的話就是在CPU完成這第一步加載后,再把轉換完成后的輸出作為輸入通過Delegate 模式再次進行轉換,轉為NNRT 所需要的模型的相關對象,再把這些NNRT的對象通過NNRT傳遞到NNRT HOST 進而傳遞到NPU中進行運算。
二、核心數據結構
Model 由LiteGraph 呈現,LiteGraph 保存著所有的Tensor列表、Node列表、SubGrapha列表和輸出、輸入的索引,LiteGraph 包含著Node、和SubGrapha,相當于所有的子結構信息都保存到LiteGraph中,每個子結構只保存各自的索引數據,計算后再通過索引從LiteGraph中獲取得到對應的數據。圖由多個Node構成,每一個Node 承擔一個運算操作。比如一個計算圖有兩個節點NodeA(執行加法操作)和NodeB(執行乘法操作,輸入來自NodeA的輸出),NodeA 輸出張量生成的索引將被記錄在output_indices_ 表示這個節點的輸出Tensor,NodeB 就使用NodeA 的輸出索引作為輸入以便獲取計算所需的數據。
struct MS_API LiteGraph {struct Node {std::string name_;std::string op_type_;int node_type_;const void *primitive_ = nullptr;std::shared_ptr<void> base_operator_ = nullptr;std::vector<uint32_t> input_indices_;std::vector<uint32_t> output_indices_;int quant_type_;int device_type_ = -1;};struct SubGraph {std::string name_;std::vector<uint32_t> input_indices_;std::vector<uint32_t> output_indices_;std::vector<uint32_t> node_indices_;std::vector<uint32_t> tensor_indices_;};std::string name_;std::string version_;std::vector<uint32_t> input_indices_;std::vector<uint32_t> output_indices_;std::vector<mindspore::schema::Tensor *> all_tensors_;std::vector<Node *> all_nodes_;std::vector<SubGraph *> sub_graphs_;std::string ToString() const;
};struct MS_API Model {LiteGraph graph_;char *buf = nullptr;size_t buf_size_ = 0;LiteModelType model_type_ = mindspore::lite::ModelType_MSLite;void *deobf = nullptr;/// \brief Static method to create a Model pointer.static Model *Import(const char *model_buf, size_t size);/// \brief Static method to create a Model pointer.static Model *Import(const char *filename);/// \brief method to export model to file.static int Export(Model *model, const char *filename);/// \brief method to export model to buffer.static int Export(Model *model, char *buf, size_t *size);/// \brief Free meta graph temporary buffervirtual void Free() = 0;/// \brief Free all temporary buffer.EG: nodes in the model.virtual void Destroy() = 0;/// \brief Model destruct, free all memoryvirtual ~Model() = default;
};
Struct LiteGraph{struct Node {std::string name_;std::string op_type_;int node_type_;const void *primitive_ = nullptr;std::shared_ptr<void> base_operator_ = nullptr;std::vector<uint32_t> input_indices_;std::vector<uint32_t> output_indices_;int quant_type_;int device_type_ = -1;};struct SubGraph {std::string name_;std::vector<uint32_t> input_indices_;std::vector<uint32_t> output_indices_;std::vector<uint32_t> node_indices_;std::vector<uint32_t> tensor_indices_;};std::string name_;std::string version_;std::vector<uint32_t> input_indices_;std::vector<uint32_t> output_indices_;std::vector<mindspore::schema::Tensor *> all_tensors_;std::vector<Node *> all_nodes_;std::vector<SubGraph *> sub_graphs_;std::string ToString() const;
}
class MS_API LiteModel : public Model {...
}
三、模型加載核心流程
未完待續…