你或许也想拥有专属于自己的AI模型文件格式-(1)

发布时间:2022-09-10 20:00

        2021年前后,大量的推理框架和训练框架层出不穷;训练框架有较新的Pytorch、TensorFlow,和老的Caffe、Darknet等;推理框架中有各种国产的、开源的,特别是边缘设备上的框架Ncnn、Tengine等;另外,国产的CANN更是兼顾了训练和推理两方面。

        但是,以上所有的框架基本是拥有一种专属于自己的模型文件。比如caffe由.prototxt和.caffemodel文件组成,darknet由.cfg和.weight文件组成,pytorch由.pt组成,tensorflow lite由.tflite组成。它们按照一定的规则组成了整个模型描述,包括了有向图信息、权重数据、连接关系等一切的一切。

        也许你会问:既然已经存在了这么多种类的模型格式,那我们何必要自定义一种自己的格式呢?如果一定要我胡说八道的话,那就是“有助于构建自己的AI框架;你的代码量将会得到提升....."。hhhhh,其实只是好玩,更是因为有成就感罢了,特别是如果你也拥有专属于自己的AI模型文件格式的话。

        因此,你或许也想拥有专属于自己的AI模型文件格式,你现在就可以想好它的格式名称了,可以是.holly、.love等,随君所爱哈。

一、总体流程

        万事开头难,自定义一个专属的AI模型文件格式(后续为了简化,我将简称“专属于自己的AI模型文件格式”为“专ai模”),需要我们拥有一个整体的规划,好事多磨嘛。以下是本人的本次制作专爱模的整体规划。

总体规划
序号       制作流程
1 了解现有的模型文件格式的信息组成以及自己的需求
2 制作环境准备、工具安装等事宜
3 专ai模的信息组成描述编写
4 为专爱模提供对应的操作的API,特别是生成模型、读模型等方面的功能需要编写
5 测试,或者是更多的特性开发

        那么我话不多说,直接开干吧。

二、了解一个模型文件应该包含的信息组成

        这里企图得到一份自定义的模型描述文件,在此主要探讨一份关于模型的描述文件应该定义哪些信息呢。如果从通用性来讲,应该怎么定义一个描述文件;从最小描述量来讲,又该如何描述这份文件;等等问题,以待探讨。

        从工作流程上来说,我们想要得到一份自己的模型描述文件,这需要从自身的需求入手。即我们希望自定义的模型应该包含哪些信息。不管是什么模型文件,基本是具备如下所示的信息,如下表所示:

序号

信息

说明

1

模型注解

主要是作为附属信息嵌入到了文件内,对模型推理和训练可有可无。最常见的就是类似于作者信息、模型生成时间、版本号、模型描述版本号等

2

数据类型

这个数据类型不是单纯的像是编程语言中的基本数据类,而是包含了多层次、多属性的数据类型。其包含了最基本的数据类型,比如bool、int4、uint4、uint8、int8、fp16、fp32、量化类型(qint*)等;又包括了描述某层的输入是常量还是运行时Tensor等这类的描述;除上述所述外,还有其他的方面。

3

层描述

主要是用于描述模型中的网络层信息,一般而言:一个网络层在模型文件中拥有输入输出描述、附属描述(用于推理时或者是训练的必不可少的信息,比如卷积层的步长、是否补齐等信息)。特别地,层描述的输入输出决定了模型的有向图描述,当然,也可能是编写Table来描述模型的有向图。

4

张量描述

张量描述,即是构成有向图的边,也包括了比如权重张量等的描述在内。

        从上面这张表格,我们可以看出如果专ai模拥有模型注解、数据类型、层描述以及张量描述,那么使用专ai模可以近乎完美地构建任何一个模型,管他什么语音识别还是目标检测等模型,统统可以变成专ai模的格式。

三、环境和工具搭建

        在进行环境和工具的搭建之前,需要说明一下这一步骤的重要性和必要性。

        如果不了解现有的AI框架的模型文件格式,也许你会选择直接操控二进制来作为自己的专ai模,又或者是直接编写txt文本来描述自己的专ai模。但是我们可以预见:自己完全操控二进制文件将会使得我们难以解析和改变模型,加大了后续的开发难度,同时也难以维护;而编写txt文本确实拥有容易修改和解析的好处,但是要知道模型文件里面可是拥有海量的权重信息的,试想一下在电脑上打开一个拥有10m甚至100m float数据的文本将是什么体验——我只能说毫无体验。

        因此,我在这里推荐两个数据协议编写工具,分别是ProtoBuffers和FlatBuffers。你可任选其中一个作为自己后续的开发工具,你所选择的开发工具将会成为描述你的专ai模的利器。

3.1、ProtoBuffers

3.1.1、说明和介绍

        如果你接触过caffe训练框架或者是接触过服务器-客户端的网络协议的话,或许对这个工具会有所了解甚至已经非常熟悉。不管怎样,我还是说明以下这个ProtoBuffers,我以caffe训练框架作为举例来说明该具体的作用和体现的地方:

        caffe训练框架是如何解析一个caffe模型的呢,.caffemodel和.prototxt组成了一个caffe模型,其中.prototxt是一个文本文件,是可以随意编辑的;而caffemodel是一个权重文件,这个权重文件包含的不仅仅是权重,准确来说是存放了带参的blob信息,这个结论我们可以从caffe.proto的描述看出:

message LayerParameter {
  optional string name = 1; // the layer name
  optional string type = 2; // the layer type
  repeated string bottom = 3; // the name of each bottom blob
  repeated string top = 4; // the name of each top blob

  // The train / test phase for computation.
  optional Phase phase = 10;

  // The amount of weight to assign each top blob in the objective.
  // Each layer assigns a default value, usually of either 0 or 1,
  // to each top blob.
  repeated float loss_weight = 5;

  // Specifies training parameters (multipliers on global learning constants,
  // and the name and other settings used for weight sharing).
  repeated ParamSpec param = 6;

  // The blobs containing the numeric parameters of the layer.
  repeated BlobProto blobs = 7;
//后续的是layer_param信息......

}

        上述的BlobProto就是所有带参的blob,而参数保存在了.caffemodel内,准确来说,caffe中组成一个层需要得到prototxt的一个层的json描述和.caffemodel内对应的带权重的blob信息,举例来说就是如下所示:

# 这是一层卷积层的prototxt内的描述
layer {
  name: "conv_conv1"
  type: "Convolution"
  # bottom表示该层的输入blob的名称
  bottom: "data"
  # 带有权重的blob是保存在了.caffemodel内,
  # 这里无法看出来,保存的时候采用了ProtoBuffers工具保存
  # top表示该层的输出blob的名称
  top: "conv_conv1"
  # *_param表示卷积的其他参数描述
  convolution_param { 
     num_output: 96
     kernel_size: 7
     stride: 2
     pad: 3
  }
}

        caffe就是靠着caffe.proto描述了一个模型格式,接着用ProtoBuffers来解析模型和加载权重的,如果你有兴趣,可以去以下的链接观看caffe.proto的全貌:

Caffe.proto的官方链接icon-default.png?t=LA92https://github.com/BVLC/caffe/blob/master/src/caffe/proto/caffe.proto        同Caffe类似的,我们只需要实现一份专ai模的.proto文件就可以定义自己的模型格式了,后续我们可以使用ProtoBuffers工具来解析和生成专ai模的模型文件了。

3.1.2、安装教程

        该工具因为官网的安装文档比较齐全,所以直接在这里放置官网的安装教程的链接,请点击此处进入ProtoBuffer安装教程界面icon-default.png?t=LA92https://github.com/protocolbuffers/protobuf/blob/master/src/README.md        如果实在有困难安装该工具的,可以在下方评论或者私信我。

3.2、FlatBuffers

3.2.1、说明和介绍

        FlatBuffers和ProtoBuffers的目的是一致的,就是实现数据协议的制定。在FlatBuffers的使用场景中,我们只需要实现一份自己的.fbs,后续就可以用FlatBuffers来解析和生成专ai模的模型文件了。

        目前我了解到的使用了FlatBuffers来作为模型描述工具的有armnn、tensorflow lite、onnx等。后续我选用的是FlatBuffers工具进行过开发,所以建议读者也选用这个工具继续开发,可以减少读者的麻烦。

3.2.2、安装

        因为FlatBuffers官网的安装教程比较少,因此我在这里写下安装教程。

        首先下载好FlatBuffers的源码:

wget -O flatbuffer.zip https://codeload.github.com/google/flatbuffers/zip/refs/heads/master

        然后解压压缩包然后进入对应目录:

unzip flatbuffer.zip
cd flatbuffers-master/

        开始编译:

# 使用cmake 构建工程
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
# 开始编译
make -j16
# 安装
make install

        测试是否安装成功:

# 如果安装成功,将会显示flatc版本号
flatc --version

介于篇幅太多,我将会拆分出多个文章进行说明,尽请期待。

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号