0x01 前言 XNNPACK是一个由Google维护的算子库,在TensorFlowLite,ExecuTorch,ONNX RT等众多知名框架中使用。笔者最近在做mllm的xnnpack后端适配工作,因xnnpack缺少文档,在此记录。
xnnpack的test中展示了大部分xnnpack的API和使用方式,读者在碰到API使用问题的时候不妨去test文件夹下面找找答案;xnnpack遵循标准的doxygen注释,也较好的说明了函数和class的使用方法。
在xnn中使用的是静态图构建的方法,在开始构建静态图之前,需要初始化xnn:
xnn_initialize(nullptr /* allocator */) 使用如下API可以构建出一张subgraph,接下来的所有操作都在更改这张子图,
xnn_subgraph_t subgraph_ = nullptr; auto status = xnn_create_subgraph(external_nums, 0, &subgraph_); 0x02 定义 Tensor 定义未经过量化的Tensor使用的API是:
uint32_t uuid; status = xnn_define_tensor_value( /*subgraph*/..., /*dtype*/..., dims.size(), dims.data(), /*data=*/..., /*external id*/XNN_INVALID_VALUE_ID, /*flag*/0, /*id*/&uuid); 这里需要特殊解释的是external_id、flag和uuid三个值:
external_id 是对于EXternal Inputs和Outputs才需要设置的,对于xnnpack内部管理的Tensor,不需要设置这个值,给出默认的XNN_INVALID_VALUE_ID就行。external_id的作用是让xnnpack可以从runtime中传入的external_values中索引到需要的Tensor值。详细解释如下: 在xnnpack中,每个Tensor都会有一个uuid,对于xnnpack自己管理的Tensor,uuid在定义的时候会由xnnpack自己生成。还记得在xnn_create_subgraph创建的时候需要传入external_nums吗?这里的external_nums就是用户侧预留的uuid。比如external_nums是3的时候,xnn_define_tensor_value就会从4开始计数给新创建的Tensor。而前3个Tensor,即external Tensor的uuid(external_id)就是1,2,3。
flag flag是用来标识这个Tensor是不是External Inputs,Outputs或者是其他类型的Tensor。比如inputs tensor的flag是flags = XNN_VALUE_FLAG_EXTERNAL_INPUT;, outputs 是 flags = XNN_VALUE_FLAG_EXTERNAL_OUTPUT;
uuid 是每个Tensor的全局索引标识
题外话:
在mllm中,Tensor的define过程如下:
void defineXpTensor(XnnpackBackend *xpb, Tensor *t, XpTensorType ttype) { if (t->uuid() !...