Android高通平台上大模型部署和推理

18 篇文章 0 订阅

1 部署的过程

高通NPU(HTP)平台上对PyTorch/SAFETensor模型进行优化和部署的过程,具体包括格式转换、量化、编译等步骤。这个流程是为了确保模型能够在终端设备上高效地推理运行。以下是对每个步骤的详细解释和涉及的底层原理。

1.1 格式转换

  • 背景:PyTorch模型是开发人员常用的格式,但在移动终端设备上推理时,这些模型需要转换为特定的格式,才能与高通的NPU和工具链兼容。
  • aimet工具:aimet是一个用于神经网络优化的工具,它能在不影响模型性能的情况下,通过压缩和量化等技术优化模型。aimet工具会根据QNN(Qualcomm Neural Network)的后端要求,将PyTorch格式的模型转换为合适的结构。
  • 权重转换:为了在NPU上运行,模型的一些结构和权重会被调整。例如,多头注意力(MHA)模块会被转换为缩放注意力(SHA)模块,线性层(Linear)会被转换为卷积层(Conv),这些转换有助于利用NPU的高效计算单元。
  • 性能优化:在转换过程中,aimet还会对模型进行一些结构上的优化,如重新排列权重,减少内存访问延迟,提高推理速度。

1.2 PTQ线性层量化

  • 量化目标:量化的主要目标是降低模型在硬件上运行时的内存占用和计算复杂度。这里特别针对LLM(大语言模型)中的QKVO(查询、键、值、输出)和FFN(前馈神经网络)的线性层进行量化。
  • 线性层切割:为了提高量化的精度,大的线性层会被分割为多个小的线性层。通过将embedding维度切割为1024或1536个channel,减少每个channel的量化误差。
  • 量化参数的计算:对于每个channel的权重,量化需要计算scaleoffset。这些值的选择非常重要,因为它们会影响模型的精度。为了找到合适的scaleoffset,需要通过校准数据集对量化后的模型进行测试,并在多次的最小-最大缩放范围窗口中找到最优值。
  • 量化格式:常见的量化格式包括A16W4(激活量化为16位,权重量化为4位)或A16W8(激活16位,权重8位),可以根据精度和内存需求进行调整。权重和量化参数会被保存在encoding文件中。

1.3 PTQ激活层量化

  • 激活量化:除了线性层之外,激活函数和其他激活层(如LayerNorm)的量化也是必要的。激活层量化是通过将浮点数表示的激活值压缩为较低位数的定点数表示。通过量化激活函数,能够进一步减少计算和内存带宽消耗。
  • 校准数据:和线性层一样,激活层的量化也需要校准数据集,帮助找到最适合的量化参数,并将其加入到之前生成的encoding文件中。

1.4 ONNX导出

  • ONNX模型格式:ONNX(Open Neural Network Exchange)是一种标准化的神经网络模型格式,方便在不同平台和硬件之间的模型互操作。在高通NPU上进行推理时,模型通常会被转换为ONNX格式。
  • 模型拆分:为了优化推理速度,模型会根据不同的阶段进行拆分。预填充阶段(Prefill)和KVC(Key-Value Cache)阶段的输入不同,因此需要导出两个不同的ONNX模型。尽管权重和量化参数相同,但输入和输出形状不同,满足不同推理阶段的需求。

1.5 Split和权重共享

  • 模型分割:当模型的尺寸超过硬件处理能力时,需要将模型拆分为多个子模型。每个子模型处理一部分计算任务,避免超出硬件的内存和计算能力。
  • 权重共享:为了节省内存,多个子模型可以共享相同的权重。例如,Prefill和KVC阶段的模型使用相同的权重,因此可以将它们合并为一个共享权重的模型,推理时只需加载一套权重。这种方法有效减少了内存占用,尤其在内存有限的移动终端设备上非常重要。

2 部署过程底层原理分析

2.1 量化与硬件加速

  • 量化是指将浮点数模型的权重和激活值转换为低位数的整数表示。这在硬件上可以显著减少内存带宽和计算量,尤其对于NPU等专用加速硬件而言,量化后的整数计算远比浮点计算更快且能耗更低。

2.2 MHA转SHA和Linear转Conv

  • 多头注意力(MHA)转缩放注意力(SHA):这是为了提高NPU对注意力机制的处理效率。SHA通过缩放操作简化了注意力矩阵的计算,减少了矩阵乘法的复杂度。
  • Linear转Conv:线性层转换为卷积层是为了利用NPU上对卷积操作的硬件加速支持。卷积操作在并行计算中的效率更高,能够更好地利用硬件资源。

2.3 权重共享

  • 权重共享的机制在多模型推理时尤其重要,可以通过减少重复加载的权重,节省内存占用,并减少推理过程中的I/O操作。

3 术语的详细解释

3.1 PyTorch/SAFETensor

  • PyTorch:是一种深度学习框架,广泛用于训练和推理神经网络。它提供了动态计算图和丰富的API,使得开发者可以快速开发和实验各种模型。
  • SAFETensor:是一种序列化张量的格式,设计为更加安全和高效,适用于在不信任的环境中进行张量传输。相比于常规的模型文件格式,它能够避免潜在的安全问题。

3.2 AIMET(AI Model Efficiency Toolkit)

  • AIMET是高通提供的一个工具包,专门用于优化神经网络模型。它包含了量化、剪枝(pruning)和稀疏化等技术,可以在模型推理性能和模型精度之间取得平衡,特别是用于移动和嵌入式设备。
  • AIMET工具的一个重要功能是帮助将PyTorch模型转换为适合硬件加速器的格式,尤其是在NPU、DSP等异构计算平台上运行。

3.3 QNN(Qualcomm Neural Network)

  • QNN是高通开发的一个神经网络加速框架,专门用于在高通芯片上的硬件加速器(如NPU、DSP)上高效地执行深度学习模型。它为开发者提供了编译、优化和部署神经网络模型的工具链。
  • QNN backend工具链负责处理模型编译、优化、转换等任务,使模型适应终端设备的计算环境。

3.4 MHA(Multi-Head Attention)和SHA(Scaled Head Attention)**

  • MHA(多头注意力):多头注意力机制是Transformer模型中的核心组件,用于让模型能够关注输入的不同部分。MHA通过多个“头”(即多个并行的注意力操作)计算不同的注意力分数,增加了模型的表示能力。
  • SHA(缩放头注意力):缩放头注意力是一种对MHA的优化,它通过缩放操作简化了注意力计算,从而在硬件上能更高效地实现。这种简化方法降低了计算复杂度,使得模型在硬件加速器(如NPU)上运行时更为高效。

3.5 Linear层(全连接层)和Conv层(卷积层)

  • Linear层:线性层,也称为全连接层,是神经网络中的基础组件。它将输入乘以权重矩阵并加上偏置,输出一个新的向量。线性层广泛用于Transformer等模型的QKV(Query、Key、Value)计算和FFN(前馈神经网络)中。
  • Conv层:卷积层通过在输入上应用卷积核来提取局部特征。卷积层通常用于计算效率更高的硬件平台,因为它可以利用硬件的并行处理能力。将线性层转换为卷积层能够提高NPU等加速器的执行效率。

3.6 量化(Quantization)

  • 量化:量化是将浮点数表示的神经网络参数(如权重、激活值)转换为较低位数的整数表示,以减少模型的计算和内存开销。量化分为权重量化和激活量化。
  • PTQ(Post-Training Quantization):这是量化技术的一种,通过对训练后模型进行量化。PTQ不需要重新训练模型,而是通过校准数据集来调整量化参数(如scaleoffset),降低量化对模型性能的影响。

3.7 QKVO(Query、Key、Value、Output)和FFN(Feedforward Neural Network)

  • QKVO:这些术语来自Transformer模型的注意力机制:
    • Query(查询):输入的一部分,用于计算注意力分数。
    • Key(键):和Query进行点积,决定Query应该“关注”输入的哪些部分。
    • Value(值):根据注意力分数加权,用于生成最终的输出。
    • Output(输出):通过多个注意力头生成的结果。
  • FFN(前馈神经网络):Transformer中的一个组成部分,通常跟在多头注意力层之后,进行进一步的非线性映射。FFN通常由两个线性层和一个激活函数组成。

3.8 ONNX(Open Neural Network Exchange)

  • ONNX:是一个开放的神经网络交换格式,旨在使神经网络模型能够在不同的深度学习框架和硬件平台之间互操作。通过ONNX,模型可以在不同的硬件加速平台上进行优化推理。
  • Prefill模型:Prefill模型用于神经网络推理的初始阶段,处理输入的预处理。
  • KVC(Key-Value Cache)模型:在连续的推理过程中,KVC模型用于缓存中间结果,避免重复计算,从而提高推理速度。

3.9 权重共享

  • 权重共享:当多个模型使用相### 总结

通过这一系列的转换、量化和优化步骤,原本在浮点数计算下运行的PyTorch模型得以适应高通NPU等硬件设备的要求,在保证推理精度的同时,显著降低了内存占用和计算复杂度。这些优化的核心在于利用专用硬件加速的特性,通过量化、权重共享等手段,最大化硬件资源的利用率。同的权重时,可以通过权重共享的方式,避免加载多个副本。这减少了内存占用,尤其在资源受限的嵌入式设备中非常有用。例如,Prefill模型和KVC模型共享相同的权重,但执行不同的任务。

3.10 DDR带宽

  • DDR(Double Data Rate):指的是设备中的内存类型。高带宽的DDR内存对于大模型的推理非常重要,尤其在处理大量数据时。对于高通NPU,模型推理过程中会消耗大量DDR带宽,特别是在HTP(Hardware Trust Platform)加速器运行时。

4 在高通平台上大语言模型(LLM)的推理引擎流程

涉及多个模型模块(如Tokenizer、Embedding、Attention、LM_head等)的工作机制和相互协作。以下是对整个过程和其底层原理的详细解释。

4.1 Tokenizer阶段

  • 原理:Tokenizer是语言模型中将自然语言文本转换为模型可以理解的tokens的组件。每个token代表一个字符、词或子词,模型通过这些tokens进行处理。
  • 流程:用户输入的prompt是以字符串的形式存在的,Tokenizer将其编码为n个tokens。为了让输入符合模型的输入层尺寸要求(例如输入的shape为1 x N,其中N是固定的最大序列长度),如果n个tokens少于N,会进行填充(padding)操作,将未使用的部分用特殊的填充token补充到N个tokens。
  • 目的:通过这种方式,所有输入都能符合模型的输入shape要求,便于后续的计算处理。

4.2 BERT Prefill阶段:首token生成

  • 原理:BERT prefill模型负责对输入的多个tokens进行语义理解。它采用Attention机制处理整个序列,并生成相应的KVC(Key-Value-Cache)数组和logits。
  • 流程:N个tokens(经过填充后的)与mask一起输入到BERT prefill模型中。mask用于忽略填充token的影响,只处理有效的tokens。模型经过计算后生成:
    • KVCaches数组:存储了模型处理输入序列的中间结果(Key-Value对),供后续推理使用。
    • Logits数组:输出的概率分布,用于生成下一个token。
  • 采样:通过对logits进行采样(如使用随机采样、贪心算法或Beam Search),从概率分布中选出一个新的token(new token),为下一步推理做准备。

4.3 第一次KV Decoder阶段

  • 原理:KV Decoder模型的任务是基于新的token和先前的KVCaches数组进行推理,进一步生成新的KVCaches和logits。
  • 流程:将1个新生成的token、N长度的KVCaches数组以及mask输入到KV Decoder模型中。模型根据输入进行计算,输出:
    • New KVCache:更新后的KVCaches,存储了当前推理步骤的中间状态,供下一步使用。
    • New Logits:用于生成新的token。
  • 后处理:与BERT Prefill阶段相似,通过采样算法对logits进行后处理,生成新的token。

4.4 判停逻辑

  • 原理:在每次生成新token后,系统需要判断是否满足停止条件。常见的停止条件包括生成了指定的停止token(stop token),或者满足了其他逻辑,如达到最大生成长度。
  • 流程generate调度模块会分析当前生成的token,检查它是否是停止token,或是否有其他条件满足,如果满足则停止生成。如果没有满足停止条件,则进入下一轮推理。

4.5 Generate调度:自回归阶段

  • 自回归模型:语言模型的自回归生成是一个循环过程,即每次生成一个token后,将该token和之前的中间状态输入模型,再生成下一个token。
  • 流程
    1. 使用之前生成的N个KVCaches和1个新生成的KVCache,通过kvmanager模块管理KVCaches。因为KVCaches的长度是固定的(为N),需要保持这个固定长度,因此将最前面的一个pad token移出,并将新生成的KVCache添加到末尾,以确保KVCaches数组的长度维持不变。
    2. 将新的KVCaches和新token再次输入KV Decoder模型,进行下一次推理。KV Decoder模型的shape与上一次相同,每次输出1个新的KVCache和新的logits。
    3. 这个过程会反复进行,直到判停逻辑触发停止条件。

4.6 循环过程中的Token解码与流式输出

  • Token解码:每次生成的新token可以通过Tokenizer解码为可读的文本字符串。这些字符串可以在生成过程中实时反馈给用户。
    • 流式输出:如果开启了流式输出模式,每次生成的token会立即解码并反馈给用户,类似于实时的对话输出。
    • 非流式输出:如果没有开启流式输出,解码后的字符串会被缓存,直到生成结束,所有token拼接在一起作为最终输出返回。

5 推理过程的底层原理

5.1 Attention机制与KVCaches

  • Attention机制:模型中的Attention机制是通过对输入序列中的各个位置的tokens之间的关系进行计算,生成每个token对其他token的权重分布。这些权重帮助模型捕捉输入序列中的全局上下文关系。
  • KVCaches的作用:KVCaches存储了模型在推理过程中的中间结果(Key-Value对)。这些缓存使得后续的推理过程可以利用之前的计算结果,避免重复计算。这种机制提高了自回归推理的效率,特别是在长序列的生成中。

5.2 采样算法与Logits

  • 采样算法:Logits表示每个可能token的概率分布。采样算法决定从该分布中如何选择下一个token。常见的采样方法有:
    • 随机采样:从概率分布中随机选取一个token,适用于生成多样化的文本。
    • 贪心算法:选择概率最大的token,生成确定性输出,但多样性较差。
    • Beam Search:通过并行探索多个可能的输出路径,适用于生成较高质量的文本。

5.3 自回归生成

  • 自回归模型的核心是通过循环生成每个token,前一步生成的token会影响后续的生成。这种方式虽然计算量较大,但能够捕捉到上下文信息,使得生成的文本语义连贯。

5.4 流式输出与非流式输出

  • 流式输出:每次生成一个token后就立即解码并返回给用户,类似于实时反馈。这种模式能够提升用户体验,尤其在对话生成场景中显得尤为重要。
  • 非流式输出:解码后的token被暂时存储,直到整个序列生成完成后再一次性返回。这种模式适用于对流畅性和整体语义一致性要求较高的任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值