推理引擎领域,经过近几年的打磨和优化,阿里推出的MNN(MobileNeuralNetwork)[1][2][3]也成为领先的推理引擎行业。当我们想要进一步提升性能时,结合深度学习模型设计是一个潜在的方向。结合科学计算和高性能计算方面的知识是一种更具体的方法。基于这种思维路径,业界逐渐开始从稀疏计算入手。提高推理机性能的观点。稀疏意味着某些数据矩阵具有0个元素。一般来说,矩阵稀疏化后,非零元素数据在内存中不连续,无法直接复用GEMM(generalmatrixmultiply)[9]算法。同时,缓存命中问题或者判断开销都会降低稀疏计算的性能,需要一种新的方法来加速稀疏相对于密集计算。结合业界现有的稀疏计算方法,结合MNN的推理框架、内存布局、算子关系,在MNN框架中设计了支持多种后端的稀疏整体方案,打磨稀疏计算核心组件,实现高表现;重要性能指标数据如下:以AI(人工智能)领域的经典分类模型MobileNetV1[12]MobileNetV2[13]为例,选用同款高通SD835CPU(MSM8998),对比XNNPack[6],XNNPack在MobileNetV1稀疏90%时加速比为2.35x,MNN加速比为2.57x-3.96x。当MobileNetV2有85%的稀疏度时,XNNPackMobileNetV2(onlyblock=2),加速比为1.62x,MNN加速比为3.71x(block=4),block的含义和其他模型信息在1.1和3.1节解释,其他信息在跟进中。1.稀疏布局与加速原理1.1可调块稀疏权重深度神经网络模型的稀疏计算包括输入稀疏性[11]、输出稀疏性、权值稀疏性。0元素占所有元素的比例就是稀疏程度。一般来说,输入和输出的稀疏性会对具有特定属性的模型产生影响。比如激活函数是ReLU,负值计算归零,所以这些结果可以计算不准确,只计算符号来实现加速。但是,CPU对一般DNN模型的加速作用是权重稀疏。在MNN中,我们关注的是权重稀疏的一般场景。另一个重要特征是深度学习的权重稀疏比例一般为30%-90%,不同于科学计算极度稀疏到99%的场景。也就是说有以下三点:MNN稀疏计算的基本选择:左右矩阵:选择一般权重稀疏;稀疏性:30%-90%左右需要产生加速效果,非科学计算极稀疏场景;structure:no采用了对权重矩阵通道维度进行裁剪的全结构化剪枝方式,而是随机稀疏+块稀疏。在常规结构化剪枝[4][5]中,直接删除权重矩阵的IC或OC维度的整个维度切片。剪枝后,模型还是稠密的,直接缩小了矩阵乘法的规模。由于宏观结构的巨大变化,这导致模型精度的显着损失。MNN中的稀疏计算选择在OC维度动态分块和稀疏权重。下图1为随机稀疏块下矩阵乘法的左右矩阵数据布局。彩色方块表示数据不为0,白色方块表示稀疏处理。后者为0,表示既不存储也不计算。下图2显示了块稀疏矩阵乘法的左右矩阵数据布局。左矩阵与随机稀疏情况相同,右矩阵为权重矩阵,以每个OCBlock为单位连续为0或非0分布在内存中。为了灵活性,我们将OCBlock设计并支持为可调整的值。1.2权重矩阵数据压缩格式经过比较和选择,MNN中的权重矩阵采用了多种布局形式。原始权重如图3所示,为了保证性能的同时压缩内存占用。当表现随机、稀疏时,选择图4所示的布局样式;当块稀疏时,选择图5所示的布局。原始矩阵被压缩为非零数据和索引部分。下面图4和图5中,权重矩阵A的0元素被压缩不再存储,数据为非零数据,RowstartIndex和ColumnIndex分别为行索引和列索引。图5中的布局可以节省更多的索引空间并压缩内存使用。2.MNN稀疏计算方案设计2.1推理框架层设计基于MNN现有架构设计稀疏计算,设计和实现需要考虑更多的现状约束,结合基础软件的定位,设计目标主要包括以下五个方面。解释:由于中文时间序列中“beforeandafter”的语义与英文中“forward/backward”的语义相反,因此使用向后兼容代替通常模棱两可的“向前兼容”。2.2MNN稀疏计算架构分析经过不断的设计和改进,MNN稀疏计算目前包括稀疏训练、转换参数、算子框架、后端内核四个阶段。设计的四个部分是松耦合的;方便层内扩展和模块化集成和被集成,如下图的包UML。为了便于理解,参考C4Model建模方法的分层。图6显示了容器层架构,图7显示了特定层的组件层架构。首先,属于算法模型阶段。算法工程师结合数据构建模型,根据自己的喜好在各种框架下训练AI模型;二、稀疏训练阶段,参考图6,从floatdenseweight模型开始,导入MNNPythonCompression工具包(mnncompress),设置mnncompress需要的参数,运行将原模型的weight部分稀疏化为0。我们建议用户使用MNNCompress工具中的训练插件,最大限度地提高加速性能;三、转换模型阶段,MNN转换器主要包括三类模块,MNN内部缓冲格式转换、图优化、后处理、算子选择、权重矩阵统计处理,如果满足稀疏度阈值,则加入参数需要进行稀疏后端识别和运算,最后写入文件得到稀疏MNN模型;四、MNN引擎推理计算阶段,将新模型部署到MNN运行环境,与普通模型运行相同,MNN运行时会自行处理算子映射、后端微内核选择、推理等。请参阅通用模型部署运行文档。(https://www.yuque.com/mnn/cn/create_session)在MNNEngine中,参考图7,算子和后端的设计和考虑如下。从外面看,算子注册没有增加一个“稀疏卷积”算子,仍然是一个普通的卷积算子,可以为用户降低选择成本,减少算子扩容,在MNN内部更灵活可选选择稀疏计算加速,或者原始的密集卷积。在算子层面,将原来的稠密卷积重组为两层,合理分配可重用和扩展的部分,实现稀疏计算,压缩各种运算。量化稀疏算子是在扩展量化卷积算子ConvInt8Tiled的基础上实现的,基本方法与2类似。对于算子中平台相关的核心功能,我们实现了六个后端的汇编代码,包括ARM32fp32,ARM32int8、ARM64fp32、ARM64int8、x86avx2fp32和x86avx512fp32。测试类方面,稀疏用例完全包含稠密卷积用例,增加稀疏块维度,遍历不同块、不同稀疏度、不同后端的正确性。3.稀疏计算性能评估3.1典型模型稀疏加速评估为了综合评估fp32稀疏加速效果,我们从“稀疏性、块大小、cpu模型、模型类型”四个维度进行评估。结果总结在图8中。Single第一张图显示了当一个设备和一个模型固定时,推理时间消耗随稀疏性的变化曲线。把大图的第一行和第二列拿出来放在单列中,这样更容易解读数据。单图包含4条曲线,“dense”是MNN目前的benchmark,“dense-im2col”是固定推理算法块im2col进行加速的数据,不使用winograd等加速算法,“sparse-block1x1”表示权重矩阵的稀疏度为1x1block,完全随机稀疏。“sparse-block1x4”为半结构化稀疏,表示权重矩阵的稀疏块为1x4块,沿ic维度的块为1,沿oc维度的块为4。可以看出从图中可以看出,在mobilenetV1、Mi6模型和1x4块中,对应绿色左三角?曲线,稀疏加速比在0.9稀疏度时达到3.71x。XNNPack模型推理性能参考与对比:XNNPack[6]数据评测采用高通SD835CPU(MSM8998),mobilenetV1为90%稀疏度,mobilenetV2为85%稀疏度,对应SD835CPU,我们以小米6为例,下面以图中Row1和column2为例,对比数据:XNNPackmobilenetV1(sparsity=0.9,block=1),加速比为2.35x,MNN的加速比为2.57x,加速比块为1x4时为3.96x。XNNPackmobilenetV2(sparsity=0.85,block=2),加速比为1.62x,MNN加速比为3.71x(block=4)。对于卷积核不是1x1的层,我们仍然可以实现稀疏加速,如XNNPack论文中所示他们没有实现稀疏加速。通过数据大图8,我们可以得到一些分析和结论:在参考设备小米6上,稀疏块为1x4时,稀疏加速阈值优化为0.3,低端机型阈值有所提高,和其他中高端机型一样,block为1x4时,稀疏度为0.1时达到加速临界值,稀疏度为0.9时加速比可达4.13x。MNN推理耗时随着稀疏度的增加而增加,基本呈线性下降,跨模型和CPU一致性都比较好。内存占用:经过推导,稀疏和密集节省内存的比例如下。另一方面,我们评估了典型模型的分类精度。MobileNetV2在0.5稀疏度和1x4稀疏块配置下有0.6%的精度损失,对应上图speedup为1.3x。4.商业模式实践4.1某图片超清业务在某业务的移动端链路上,时延和流量是其痛点。业务端对接智能MNN和workbench,开发超分辨率任务模型,同时使用MNN稀疏计算加速方案,主要包括四个步骤。第一步是训练超分辨率模型算法;第二步,参考稀疏训练文档,设置压缩工具mnncompress所需的稀疏参数,得到权重partnumber稀疏为0的模型;第二步三步,使用MNN转换器对模型进行转换;使用MNN工作台(https://www.mnn.zone/m/0.3/)将模型部署到mnn运行环境。整个过程集成到MNNworkbench中,大大提高了AI开发过程的效率。有兴趣的同学可以尝试一下,联系工作台负责人“明仪”。如下图所示,在稀疏度为0.45的情况下,稀疏自方案对inference的加速比约为1.2x,业务指标为图像信噪比,从34.728下降dB到34.502dB少量。对业务准确性的影响在可接受范围内。4.2语音模型另一种商业模型是语音模型。下图是构建稀疏后avx512下测得的加速比。不同的稀疏方法会影响加速比。当稀疏度为0.75时,输入序列为20(典型场景1),如下图所示,稀疏和密集模型对比,encoder1的加速比为2.82x,encoder2的加速比为3.02x.该方案实现了预期的加速。5.总结与展望我们在现有的MNN框架中设计了一种通用的稀疏卷积计算方案,使其数据布局和算子结构能够匹配现有的MNN结构并获得更高的性能,而XNNPack的稀疏矩阵乘法仅针对网络逐点卷积加速。首先,我们设计并实现了推理性能优于XNNPack的MNN稀疏加速方案;当稀疏度为0.9时,CV模型在ARM端获得了3.16x-4.13x的加速,跨模型和跨模型加速效果更加显着。第二点,业务准确度指标在实际业务模型中验证,损失有限,可以接受。第三点是推理时间随着稀疏度的增加线性下降,跨模型和跨CPU是一致的;在小米6上,稀疏块1x4的加速阈值优化为0.3,即使在中高端模型的稀疏度为0.1时也能达到临界值。第四点,减少内存占用与稀疏程度成正比,具体数值见性能分析部分。在引擎实现、稀疏计算内核、汇编代码开发中,往往从期望值出发,在每次调试中不断加深对MNN现有逻辑的理解,优化稀疏算子代码、SIMD代码,优化数据布局,最终将综合指数提升到一个较高的水平。稀疏计算的研发已经完成,非常感谢团队中的同学们的配合!在移动端或者服务端,量化加速在不同领域都比较普遍,指令集支持由来已久。深度模型在CPU上的稀疏计算加速不断发展。单独使用时,两者各有优势。稀疏计算加速可以理解为一种“可扩展”的等效位宽技术,可以探索更多独特的应用场景。
