MNN推理框架将大模型放进移动端设备,并达到SOTA推理性能!

本文涉及的产品
模型在线服务 PAI-EAS,A10/V100等 500元 1个月
模型训练 PAI-DLC,100CU*H 3个月
交互式建模 PAI-DSW,每月250计算时 3个月
简介: 随着移动端(手机/平板等)算力、内存、磁盘空间的不断增长,在移动端部署大模型逐渐成为可能。在端侧运行大模型,可以有一系列好处:去除网络延迟,加快响应速度;降低算力成本,便于大规模应用;不需数据上传,保护用户稳私。

01.概述

随着移动端(手机/平板等)算力、内存、磁盘空间的不断增长,在移动端部署大模型逐渐成为可能。在端侧运行大模型,可以有一系列好处:去除网络延迟,加快响应速度;降低算力成本,便于大规模应用;不需数据上传,保护用户稳私。

为了在更广泛的设备上部署大模型,MNN团队开发了 MNN-LLM / MNN-Diffusion,合称MNN-Transformer ,支持大语言模型和文生图等AIGC模型,具有如下特性:

-支持各类LLM和Diffusion模型,支持加载同时加载多份Lora;不依赖厂商NPU能力,2020年后的手机基本都能跑得动 LLM 小模型。

-支持int4/int8等模型量化方案,并支持在内存不足时使用磁盘空间替换,避免内存溢出风险。

-充分利用CPU sdot / smmla 与GPU recordable / simdgroup / GMemory 等较新特性,在8Gen1芯片上,MNN-Transformer支持 1.8b 端侧模型 35 token/s 以上的解码速度,生成 512x512的图片约 40s (2s / iter),基本上能充分利用移动端上CPU与GPU算力。

MNN 及大模型推理相关代码均已开源:

https://github.com/alibaba/MNN/

MNN推理端侧模型均已在魔搭社区开源:

https://modelscope.cn/organization/MNN

效果体验视频(LLM):

https://developer.aliyun.com/live/254741?spm=a2c6h.26396819.creator-center.8.404f3e184lgDmA

效果体验视频(多模态大模型):

https://developer.aliyun.com/live/254740?spm=a2c6h.26396819.creator-center.10.404f3e18rb0Xb3

02.MNN系统架构

如上述架构图所示,MNN-Transformer由导出工具、量化工具、插件与引擎三个部分组成:导出工具负责将各类大模型转换为MNN格式,并构建必需的资源包;量化工具减少MNN模型大小,以降低运行时内存,加快执行速度;LLM/Diffusion运行时所需要的分词、KV缓存管理、LoRA等功能由插件与引擎模块提供。

模型导出

在将深度学习模型从研究原型转换为实际可部署的产品时,模型导出阶段的顺畅与否对于整个工作流程至关重要。通常,这个过程涉及将模型从训练框架中导出到一个中间表示,如 ONNX(开放神经网络交换格式),然后再转换为目标部署框架——在本例中为 MNN格式。为了简化并标准化这一过程,研究团队开发了一个名为 llm-export 的工具。

llm-export 工具的核心思想在于对大型语言模型(LLM)进行了高度抽象,建立了一个统一化的导出框架。这个项目的目标是消除将各种 LLM 模型导出到 ONNX 格式的障碍,确保无论是何种架构的 LLM 都能通过一个清晰定义的接口进行处理。在 llm-export 中,研究团队定义了一套公用的导出逻辑,这意味着对于任何特定的 LLM,开发者只需实现模型的加载逻辑。这极大地减少了从多样化的训练环境向 ONNX 模型迁移的复杂性,并显著提高了整个导出过程的易用性。模型一旦被成功导出至 ONNX,即可利用现有的mnnconver工具转换到 MNN 格式,从而使用MNN完成llm模型的推理。


llm-export中将llm模型抽象为4部分:tokenizer, embedding, blocks, lm;主要代码如下:

class LLM(torch.nn.Module):
    def __init__(self, args):
        super().__init__()
        # load tokenizer, embed, blocks, lm
        self.load_model(args.path)
    def forward(self, input_ids, attention_mask, position_ids, past_key_values):
        hidden_states = self.embed(input_ids)
        presents = []
        for i in range(self.block_nums):
            hidden_states, kv = self.blocks[i](hidden_states, attention_mask,
                                               position_ids, past_key_values[i])
            presents.append(kv)
        token_id = self.lm(hidden_states).view(1)
        presents = torch.stack(presents)
        return token_id, presents
    def export(self):
        # export llm to onnx and mnn
        ...
class Chatglm2_6b(LLM):
    def load_model(self, model_path: str):
        # chatglm2 load impl
        ...
class Qwen_7b(LLM):
    def load_model(self, model_path: str):
        # qwen load impl
        ...

模型部署

在部署大型语言模型(LLM)时,兼容性和易用性是关键因素。为了解决这一挑战,MNN团队开发了一个名为 mnn-llm 的项目。考虑到MNN在跨平台上支持上的优秀表现,该项目基于 MNN 构建,旨在为各种平台提供一个统一的 LLM 模型部署解决方案。mnn-llm 项目使得从 llm-export 导出的模型能够无缝进行端到端的推理,并为开发者提供了一个简易的文本到文本(txt2txt)调用接口。

在mnn-llm中移植实现了目前主流的tokenizer工具:Sentencepiece 和 Tiktoken。这些 tokenizer 组件是处理自然语言输入的关键部分,它们能够将原始文本转换为模型能理解的格式。同时为了轻量化,两种模型都使用文本的方式存储,移除了Sentencepiece中迪对protobuf的依赖。

此外,考虑到内存占用在移动设备上尤为宝贵,同时还在 mnn-llm 中引入了 disk embedding 功能。这意味着用户可以根据需要选择:在模型推理过程中使用 embedding 模型在内存计算,或者直接从磁盘加载 embedding 值。这种灵活性不仅降低了运行时的内存需求,也为用户提供了更多的选择来平衡推理性能和资源使用。为了确保 mnn-llm 的通用性和扩展性,研究团队设计了一种易于扩展的架构。开发者可以通过继承基类并实现特定的配置来支持不同的 LLM 模型。这种架构设计使得整合新的 LLM 模型变得简单快捷,大大降低了将最新的研究成果应用到实际产品中的门槛。

性能优化

内存优化

DRAM-Flash混合存储



在移动设备上部署大型语言模型的主要瓶颈在于DRAM的限制。MNN-LLM采用混合存储策略,以缓解内存使用情况,并确保在受限内存条件下保持大型语言模型推理的可用性。尽管闪存存储容量比DRAM大得多,但其读取速度要慢得多;MNN-LLM的混合存储策略针对模型的操作特性进行了定制:对于参数存储,它评估利用率并将低利用率参数分配给闪存以最小化速度影响。对于KV数据,预取技术被用于降低闪存读取延迟,从而减轻对性能的影响。

大型语言模型 (LLM) 模型的大量参数是其高内存消耗的主要原因。结构上,这些参数可以分为三个类别:embedding、layers和Lm head。embedding和Lm head参数的大小通常计算为词汇表大小×隐藏单元大小,由于词汇表大小通常很大,因此嵌入参数不会像其他参数一样参与计算。层是指每个解码器层中的参数,包括注意力和MLP线性层,通常大小为隐藏单元大小×隐藏单元大小或中间大小×隐藏单元大小,在各层中具有相同的参数规模。在Qwen2 7B 模型中,不参与计算的嵌入参数约占总参数量的15%。

利用Flash来存储Embedding层允许在不显著影响推理性能的情况下减少DRAM的使用。例如,Qwen-7B通过使用bfloat16存储可以减少大约2.18GB的DRAM使用,大大提高了对内存受限的移动设备模型推理的可行性。

在输入文本较长或生成长度较广的场景中,连续增长的KV缓存可能导致显著内存使用。MNN-LLM通过采用混合存储策略来解决这一挑战,利用闪存来保存部分KV缓存,从而确保在长上下文条件下仍能进行LLM推理。最初,所有KV缓存值都存储在DRAM中,但随着上下文的扩展和KV缓存大小的增长,任何超过一定阈值的部分都会转移到Flash上。由于每个计算仅产生一组新的KV值,Qwen2 7B模型的总KV值约为1KB,最大限度地减少了存储开销。

随着存储在闪存中的KV缓存值数量的增加,从闪存中加载它们所需的时间将逐渐增加,并且可以减慢推理速度,如图所示。为了减轻从闪存中加载KV缓存对推理时间的影响,MNN实现了预取:在当前层的MLP阶段和下一层的qkv投影阶段,在内存中预取闪存中的KV缓存值。当预取时间小于或等于计算时间时,LLM推理速度不受影响。

组合量化

大型语言模型(LLM)的参数量大是其高内存消耗的主要原因,量化可以显著减少参数量,从而降低内存使用。然而,量化会影响模型的推理精度;一般来说,较低位数会导致信息损失更大,并对准确性产生更大的影响。有各种方法、数据类型和位数可用于量化,因此选择适当的量化方法以平衡内存使用、运行时性能和模型精度至关重要。

对于Embedding、layer和Lm head的参数,MNN-LLM采用组合量化策略来平衡精度和计算开销。embedding的权重约占总模型重量的15%。由于这些权重在每个解码步骤中只使用一小部分,在闪存中存储它们不会占用DRAM空间。这允许使用bfloat16存储,确保计算准确性。非嵌入参数包括layer和LM head的权重,必须完全在每个计算中加载,使得它们的大小对推理性能产生显著影响。特别是,在解码阶段,由于内存受限,推断时间直接与这些参数的大小成正比。因此,对于这些权重使用低比特量化至关重要。考虑到精度和硬件计算指令——边缘CPU特别适合int8运算——这些参数被量化为int4或int8。非对称量化如下:

在处理长上下文时,KV缓存的内存使用量会继续增长,并且量化策略可以有效地减少这种内存消耗。MNN-LLM根据其计算角色为键和值提供不同的量化方法。在注意力计算中,查询、键和值的形状是 [头数,序列长度,头维度] 。当对键和查询进行矩阵乘法运算时,被缩减的维度是头维度,这是一个固定值。

因此,可以将int4/int8量化应用于键上,允许新键值直接量化并存储。相反,在与值进行注意力得分矩阵乘法运算时,被缩减的维度是序列长度。对于值采用int4/int8量化会影响现有值的数据分布,需要更新它们的量化值并且产生额外开销。为此,MNN-LLM采用了fp8量化用于值,允许新值直接量化而不会影响现有的值。

计算优化

硬件驱动的数据重排序

对大型语言模型(LLMs)的推理过程进行分析,发现主要耗时的操作是线性运算和注意力机制,这两种操作本质上都依赖于矩阵乘法。因此,优化这些操作中的矩阵乘法对于提高LLM性能至关重要。循环块化是一种常见的优化技术,它增强了内存访问的局部性,显著影响了性能。循环块化的最佳块大小极大地影响最终的矩阵乘法性能,并受到设备内存、缓存和计算硬件的影响。因此,在硬件和数据规模的基础上选择最合适的数据重组织和计算方法以实现峰值性能非常重要。MNN-LLM采用一种针对这两种操作类型的计算特征而定制的硬件驱动的数据重新排序策略来确定块化方法和大小,从而优化LLM推理性能。

对于Attention操作,使用与Linear相同的重新排列策略。键和值直接存储在重新排列的数据布局中,确保无需在每次计算期间重新排列历史KV。

多核工作负载平衡

现代CPU通常具有多个内核,因此有效地利用多核心计算能力对于优化性能至关重要。MNN-LLM利用CPU的多线程并行性将操作平行化沿seqlen和-dimensions方向。MNN-LLM在启动时根据其实际计算能力为不同内核指定计算负载。在并行计算期间,MNN-LLM根据内核的负载率分配计算工作量。这种平衡的工作负载分布策略与均匀工作负载策略相比可以提高多线程计算性能。

主流移动SoC通常具有一个主核心和三个性能核心,例如Snapdragon 8 Gen 3。高负载计算一般使用主核心和性能核心。当线程数超过一个时,在主核心与性能核心之间发生并行计算,如图4所示。在这种情况下,工作量平衡显著提高了多线程加速比,相比于均匀的工作负载分布。

混合浮点精度

在之前的矩阵操作讨论中,使用了低精度量化方法来加速计算。对于非矩阵乘法运算,MNN-LLM也支持混合精度结果,确保准确性的同时提升推理性能。ARMv8.2和更新的CPU支持float16计算,相比float32可以节省一半内存,并且float16 NOEN指令的吞吐量是float32的两倍。然而,float16有一些精度限制;对于需要更宽精度范围的计算,可能会出现显著误差,尤其是在值超过65,504时尤其明显。为了应对这一问题,MNN-LLM采用混合精度策略以保持推理准确度。在LLM推理过程中,注意力中的Softmax计算对数据精度非常敏感,因此MNN-LLM保证Softmax使用float32。在查询与键的矩阵相乘中,查询值可能很大,在累积后可能导致溢出。为了解决这个问题,可以直接将查询除以dk从而缩小其值范围并防止最终结果发生溢出。这种方法优化了整体内存使用和推理性能,同时保持了准确性。

几何计算

LLMs的计算图还包括诸如转置、聚集和连接等长尾操作。尽管这些操作可能不会显著影响整体执行时间,但在数据规模较大时它们会导致大量内存访问。为了应对这些长尾操作,MNN-LLM采用了几何计算方法, 抽象所有数据重新排列操作为地址线性映射。

对于计算图中的连续数据重新排序操作,此抽象产生大量连续的区域。MNN-LLM 实现了一个基于循环展开、循环交换、循环分区和循环融合规则的自动区域融合算法。该算法可以自动合并兼容的区域,从而减少数据重新排序操作的数据读写操作次数,并提高性能。通过利用几何运算对 LLM 模型进行推理,可以降低长尾操作的开销,提升约 3% 的性能。

LoRA优化

在移动设备上,不同的任务可能需要不同类型的LLM模型。由于模型参数数量庞大,直接使用多个模型会导致带宽和存储资源的过度消耗。因此,在多任务处理中,结合基线模型与多个LoRA模型是一种更高效的解决方案。

MNN-LLM支持合并的LoRA模型部署和多个LoRA模型的在线加载。在使用多个LoRA模型时,首先加载基模型,然后加载LoRA模型的计算图和权重,并且LoRA模型共享基模型的权重。由于LoRA权重通常较小,因此内存开销很小。与预合并方法相比,在线加载LoRA模型更加灵活,适用于多任务场景,虽然会增加额外的计算成本。

评估

实验设计基于量化模型,即Qwen2 1.5B、Qwen2 7B和Llama3 8B。使用小米14作为测试设备,并在CPU(利用4个线程)和GPU(通过OpenCL)上进行推理效果的比较评估。

使用诸如 llama.cpp、MLC-LLM 和 fastllm 等推理引擎的架构。由于 MLC-LLM 不支持基于 CPU 的推理,而 fastllm 缺乏对 GPU 的兼容性,因此这些引擎的相关实验被排除在外。在长度不同的提示(64、256 和 1024 个令牌)下进行了广泛的试验,并且在解码阶段施加了最多 16 个令牌的限制。

由于MLC-LLM在处理非对称量化模型时表现不佳,因此报告的MLC-LLM结果基于对称量化模型,但竞争引擎明确参与了使用非对称模型进行推理的任务。性能结果以预填充和解码速度的形式反映,并图形化地表示在下图中。

在CPU基准测试中,MNN-LLM表现出色,在预填充速度方面比llama.cpp快了8.6倍,并且比fastllm快了20.5倍。同时,解码速度也分别提高了2.3倍和8.9倍。而在基于GPU的评估中,与MLC-LLM相比,MNN-LLM的表现略有下降,特别是在使用Qwen2-7B时,由于MLC-LLM采用了优势对称量化技术,导致性能有所降低。然而,MNN-LLM仍然表现卓越,在预填充速度上比llama.cpp快了最多25.3倍,并且在解码速度上比llama.cpp快了7.1倍;此外,相对于MLC-LLM,其分别实现了2.8倍和1.7倍的改进。

02.总结与展望

在大模型端侧部署上,基于 MNN 实现的 mnn-llm 项目已经展现出业界领先的性能,特别是在 ARM 架构的 CPU 上。目前利用 mnn-llm 的推理能力,qwen-1.8b在mnn-llm的驱动下能够在移动端达到端侧实时会话的能力,能够在较低内存(<2G)的情况下,做到快速响应,可以下载 qwen-1.8b-apk来体验。然而,端侧部署 LLM 仍然面临着一系列挑战。尽管 qwen-1.8b 模型能在端侧设备上达到实用性能,但更大规模的模型如 6b 或 7b 仍然存在较高的部署门槛。这些模型往往要求更多的内存(~3GB)并且在处理较长文本(~ 100 token)时,很难在 1 秒内给出响应,这限制了其在实时应用场景下的可用性。

MNN后续会在如下方面进一步研发:

● 进一步优化高通设备上低精度计算的GPU运行性能

● 研究更有效的量化方案,并支持更低 Bit 的模型运行及中低端机型性能优化

● 提供输出限制条件情况下的优化方案

● 支持更多大语言模型和扩散模型

● 支持CPU/GPU/NPU混用计算

点击链接阅读全文:ModelScope 魔搭社区


相关文章
|
7天前
|
调度 云计算 芯片
云超算技术跃进,阿里云牵头制定我国首个云超算国家标准
近日,由阿里云联合中国电子技术标准化研究院主导制定的首个云超算国家标准已完成报批,不久后将正式批准发布。标准规定了云超算服务涉及的云计算基础资源、资源管理、运行和调度等方面的技术要求,为云超算服务产品的设计、实现、应用和选型提供指导,为云超算在HPC应用和用户的大范围采用奠定了基础。
179585 20
|
14天前
|
存储 运维 安全
云上金融量化策略回测方案与最佳实践
2024年11月29日,阿里云在上海举办金融量化策略回测Workshop,汇聚多位行业专家,围绕量化投资的最佳实践、数据隐私安全、量化策略回测方案等议题进行深入探讨。活动特别设计了动手实践环节,帮助参会者亲身体验阿里云产品功能,涵盖EHPC量化回测和Argo Workflows量化回测两大主题,旨在提升量化投研效率与安全性。
云上金融量化策略回测方案与最佳实践
|
16天前
|
人工智能 自然语言处理 前端开发
从0开始打造一款APP:前端+搭建本机服务,定制暖冬卫衣先到先得
通义灵码携手科技博主@玺哥超carry 打造全网第一个完整的、面向普通人的自然语言编程教程。完全使用 AI,再配合简单易懂的方法,只要你会打字,就能真正做出一个完整的应用。
9378 23
|
20天前
|
Cloud Native Apache 流计算
资料合集|Flink Forward Asia 2024 上海站
Apache Flink 年度技术盛会聚焦“回顾过去,展望未来”,涵盖流式湖仓、流批一体、Data+AI 等八大核心议题,近百家厂商参与,深入探讨前沿技术发展。小松鼠为大家整理了 FFA 2024 演讲 PPT ,可在线阅读和下载。
5051 15
资料合集|Flink Forward Asia 2024 上海站
|
20天前
|
自然语言处理 数据可视化 API
Qwen系列模型+GraphRAG/LightRAG/Kotaemon从0开始构建中医方剂大模型知识图谱问答
本文详细记录了作者在短时间内尝试构建中医药知识图谱的过程,涵盖了GraphRAG、LightRAG和Kotaemon三种图RAG架构的对比与应用。通过实际操作,作者不仅展示了如何利用这些工具构建知识图谱,还指出了每种工具的优势和局限性。尽管初步构建的知识图谱在数据处理、实体识别和关系抽取等方面存在不足,但为后续的优化和改进提供了宝贵的经验和方向。此外,文章强调了知识图谱构建不仅仅是技术问题,还需要深入整合领域知识和满足用户需求,体现了跨学科合作的重要性。
|
28天前
|
人工智能 自动驾驶 大数据
预告 | 阿里云邀您参加2024中国生成式AI大会上海站,马上报名
大会以“智能跃进 创造无限”为主题,设置主会场峰会、分会场研讨会及展览区,聚焦大模型、AI Infra等热点议题。阿里云智算集群产品解决方案负责人丛培岩将出席并发表《高性能智算集群设计思考与实践》主题演讲。观众报名现已开放。
|
16天前
|
人工智能 容器
三句话开发一个刮刮乐小游戏!暖ta一整个冬天!
本文介绍了如何利用千问开发一款情侣刮刮乐小游戏,通过三步简单指令实现从单个功能到整体框架,再到多端优化的过程,旨在为生活增添乐趣,促进情感交流。在线体验地址已提供,鼓励读者动手尝试,探索编程与AI结合的无限可能。
三句话开发一个刮刮乐小游戏!暖ta一整个冬天!
|
15天前
|
消息中间件 人工智能 运维
12月更文特别场——寻找用云高手,分享云&AI实践
我们寻找你,用云高手,欢迎分享你的真知灼见!
1190 72

热门文章

最新文章