大语言模型的优化及基于Intel® Extension for Transformers 的部署实践
内容分析
1. Intel® Extension for Transformers Overview
2. Optimizations
3. Neural Chat
4. Demo
大家好,我是来自 Intel 的 AI 工程师曹慧燕。我今天给大家介绍一下Intel Extension For Transformers。首先我会简单介绍一下Int Extension For Transformers的 Overview 。然后我们一起看一下它其中针对大语言模型的一些优化,主要包括 Wait Only Composition 和 Streaming Lm 。接下来我会给大家介绍一下它里面一个叫 New Chat 的组件。如何使用 New Chat 去 Find Tun 模型以及搭建 Rack Pipeline 。最后是一个在魔搭平台上使用 Intel Extension For Transformers 的 Demo 。
01. Overview
我们先来了解一下 Inter Extension For Transformers 。
Intel Extension For Transformers 是 Intel 对于 Hiking Face 的Transformers 库在 Intel 不同的硬件平台上进行优化的一个 Toolkit ,提供 Transformers 风格的 API 。针对 GenAI 和 LLM 在训练和推理方面都做了各种各样的优化。目前支持的模型列表也在不断的增加当中。
它主要的 Features 包括对模型的优化,比如向量化蒸馏剪枝等等。还有专门针对大源模型以及一些通用的优化技术。比如融合、混合精度等。集成了 Neural Speed 库, Neural Speed 原先是 Intel Extension For Transformers 内部的一个模块,从1.3.1版本开始它成为一个独立的优化库。这个库受 Llama.Cpp 的启发,使用C/C++实现大语言模型的推理,同时提供 Streaming Llm 以及 Tensor 并行之类的优化。另外, Inter Extension For Transformers 还提供了 Neural Chat 这样一个框架,它可以帮助你快速的搭建一个 Chat Bot 。提供 Open Ai Restful Api 的支持,以及对 Langchain Extension Api 做了一些扩展。
02. Optimizations
接下来我们来看一下在 Intel Extension For Transformers 中针对大宇模型的一些优化。
大家知道大语言模型动辄几十亿几百亿甚至几千亿的参数,这是极其消耗内存和算力的。模型量化可以解决一部分的挑战。其中仅量化权重被证明是一个行之有效的方法。尽量话权重主要是针对性形成权重的量化,我们把这部分全中量化成四比特数据类型并且可以保存下来,然后在运算过程中再恢复成FP32、FP16或者是BF16数据类型进行 Jmm 运算。目前 Intel Extension For Transformers 支持表格中列出来的这几种 Wait Only Quotation 算法。 CPU 已经全部支持了, GPU 还在完善过程中。通过 Int4 Weight Only Composition 我们可以把一个7B的模型从16GB降到4-5GB。接下来我会给大家简单介绍一下这些量化算法以及如何在 Intel Extension For Transformers 中使用。
对模型进行低比特量化,相信大家一定不陌生。思路就是在保证模型精度的前提下,使用低精度的数据类型去替换模型中的参数,从而减小内存占用,提高运算速度。目前比较常见的是 Int 8、 Int 4这些数据类型。在这个过程中就需要做数据映射。因为权重的分布基本都是比较对称的,所以 Waiter Only Quotation 使用的是对称量化。大家看下面这个公式。首先根据数据范围计算一个缩放因子 Scale 。在对称量化中 Zero Point 等于零,然后用原始的值除以 Scale ,四舍五入就可以得到量化后的值。这里的 Round 就是指 RTN running to nearest 。这种方式最简单,但是精度也相对比较差。
PPTQ 是一个比较流行的大语言模型量化算法。他是从 OBD 、 OBS 、 OPQ 算法一路引进过来的。最一开始是一个剪枝算法,思路就是我们在做剪枝的时候,希望剪掉的是对目标函数影响比较小的参数,从而保证模型的精确度。于是我们对目标函数做泰勒展开,计算参数的海森矩阵,从小到大给参数排个序,就可以确定剪枝的次序。剪枝可以被看作是一种特殊的量化,被剪枝的参数等价于量化到零,所以这个算法在 OPQ 中被扩展成了一个量化算法。 Gpt Q对 OPQ 的算法做了以下几点优化。首先 OPQ 算法它采用的是贪心策略,先量化对目标影响最小的参数。但是 GPT算法发现直接按顺序做参数量化对精度的影响并不大。这个发现就使得对参数矩阵每一行的量化可以做并行的矩阵计算,从而使量化速度快了一个数量级。另外,在更新权重的时候,它引入了 Lazy Batch Update 的机制。具体的做法就是将参数矩阵的列划分 Group 。量化某一列的时候, Group 内的参数立即更新。而 Group 后面的列只记录更新量延迟更新。当一个 Group 的参数全部量化完成再统一对后面的所有的参数做一次更新。通过这样的方式减少 Io 的读写次数。
AWQ 算法认为对模型精度有影响的权重只占1%左右。这1%左右的权重被认为是显著权重。这些显著权重跟激活值也就是输入有关。于是他首先将激活值对每一列求绝对值的平均值,然后把平均值较大的一列对应的那一行的群众作为显著群众保留 AP 16精度,对其他的通道进行低比特量化。但是这样的话大家可以看到在权重矩阵中,有的用 AP 16格式存储,有的用 Int 4格式存储,不仅存储的时候很麻烦,计算的时候取数也很麻烦, Kernel 函数也不好写。那怎么办呢?这时候作者通过公式推导发现了一个现象,他发现量化的时候对权重进行放大可以降低量化误差。于是他就改变了思路,为了更加对硬件友好,他对所有的群众都进行低比特量化。但是在量化的时候,对于显著权重,它乘以一个较大的缩放因子,相当于降低量化误差。同时对于非显著权重乘以一个较小的缩放因子,相当于给予更少的关注。最终我们可以看到,通过这样 Scaling 的方式,可以达到将显著权重保留 AP 16同样的精度。
最后要介绍的 Auto Round 算法是 Intel 发明的一个量化算法.在这个算法中,量化后的权重经过反量化,采用符号梯度下降法在一个小的数据集上微调一些超参数,比如这里的阿尔法和贝塔,使用它们去对 Min Max 范围进行调整。另外 Gradient 的正负也可以决定 Rounding 是往上还是往下,通过这两个优化区域提升量化的精度。微调也是一个比较轻量级的微调,通常只要经过两百步左右就可以得到一个很不错的效果。
前面介绍了 Intel Extension For Transformers 支持的一些 Weight Only 的算法。这里我们给出了如何在 Intel Extension For Transformers 中使用这些算法的例子。这个是在 CPU 上的使用方式。我们为每一个算法都定义了一个 Config 对象,设置好相应的参数。比如在这个例子中,我们定义了一个 Configure 。设置权重的存储类型是四比特,计算类型是 Int 8。然后把这个 Config 对象传给 From Pretrain 的方法就可以了。
对于 Intel GPU 的支持,目前我们结合了 Intel Extension For Transformers 的低比特 Kernel 和 Intel Extension For Pytorch 的优化。在这个例子中大家可以看到在 From Pretrain 的方法中,我们设置 Device 是 XP You Load Info Bi t等于 True ,那这一步就会完成这个模型的 Int 四量化,量化完成以后我们再调用 Apex 的 Optimus Transformers 方法,对这个量化后的模型再做一些相应的优化。
这里我们跟开源的 Lamar CPP 做了一个性能对比。左边是在第四代至强可扩展服务器上的一个性能数据,我截了一些模型的数据,大家可以看到 First Token 和 Next Token 的 Latency 都有明显的提升。右边是在酷睿 I 9上对 Lamar To 7B 模型做的一个性能对比。
另外,我们在 Hugging Face 上面创建了一个针对大源模型的低比特量化的一个 Leaderboard 。在这个名字当中含有 INC 的都是我们使用 Auto Run 的算法进行低比特量化的一些模型。大家有兴趣可以去看一下。对于大多数的模型来说, Auto Round 算法的精度会稍微好一些。
前面介绍了 Waiter Only Quotation 的一些优化算法,这里再给大家介绍一下针对 Streaming LLM 的优化。大原模型在训练的时候都有一个固定的输入长度,在推理的时候,当 Input 超过这个长度的时候,它就会卡住。另外不停增长的 KV catch 也会受到内存的限制。为了能够让 LLM 源源不断地输出,研究人员提出了 Streaming LLM 这样的技术。通过滑动注意力窗口保留最近长度的 Token 。当 Input 超过这个固定窗口大小的时候,就把前面的 Token 丢弃掉。比如左边的 B 图中我们看到的一直滑动的蓝色区域,左下角灰色的格子就是不断被丢弃的 Token 。但是当初始的这些 Token 被丢弃以后,我们发现模型的精确度急速的下降,原因是一开始的那些 Token 对模型的准确度影响很大,所以地图中的黄色部分保留了一开始的那些 Token ,从而解决了准确度的问题。
Intel 在图 D 的基础上又做了一些优化。第一个优化是当 Attention Window 满了的时候我们会丢弃前面一半的 Token 而不是一个。然后重新申请后面一半的 Token 。这样就可以减少内存申请和释放的次数。在程序中我们可以通过设置 Andy Scott 等于-1来开启这个优化。另外在New Speed 中还有一个优化,这个优化是针对使用 Rope 作为位置编码函数的 Llm 。我们把这个 Attention Windows 设计成一个Ring Buffer 这样当 Attention Window 满了的时候,就直接覆盖前面最老的 Token ,避免重新申请和释放内存从而提升性能。
03. Neural Chat
接下来我们来看一下 Neural Chat 的框架。
左边这张图是 Neural Chat的纵向架构图,它底层支持 Intel 不同的硬件平台,包括高地加速卡、 Intel 的 CPU 和 GPU ,同时也支持 NVIDIA GPU ,软件支持 Pytorch Tensorflow Onyx Runtime 这样的 AI 框架以及 Hugging Face Long Can Fast Track 这些不同领域的开源库。在这个基础之上, Neural Chat 提供 Papeete Quantum Session Started 这些功能,提供不同的 Plugin 来定制化 Check Out ,支持 Service 和 Client 端的 API 。基于 Neural Chat 的这些功能,我们可以开发各种基于大语言模型的应用,比如 Intel 基于 New Chat 开发的 Neural Pilot 组件目前已经发布在 VS Code 的 Marketplace 上,欢迎感兴趣的同学下载体验。右边这张图展示了我们如何使用 Neural Chat ,我们可以使用 Neural Chat 对 Pretrained Lm 进行微调或者优化,然后把它部署到 Chatbot 中去。右下角展示了一个非常简单的例子,仅仅使用三行代码就可以搭建一个简单的 Chatbot 。当然这个里面我们使用了很多 Default 的参数。
我们可以尝试用自己的数据集去 Fine-Tuning 一个大模型。先来看 Full Fine-Tuning ,所谓 Full Fine-Tuning 就是使用自己的数据集去更新这个模型所有的群众通常只需要很小的数据集就可以达到一个不错的效果。但是大语言模型一般参数量都非常大,都是 Billion 级别的。更新所有的群众意味着需要大量的计算资源和 Memory 资源,要耗费很长的时间,并且通常这些大语言模型的训练都涉及到分布式训练,还需要掌握一定的专业知识。
因此就有了 Parameter-Efficient Fine-Tuning ,简称 PEFT 。针对我们自己的数据集,可以只去更新这个网络中的某一些群众,或者是保持原来的权重不动额外的加一些 Adapter 。针对新的数据,只需要训练这些 Adapter 层的参数即可。
LoRA 就是 Paper 的一种。左边这张图是 Paper 当中的图,我们看一下它的思路。首先左边这一部分保持权重不变,我们在右边加入两个小的矩阵,这两个小的矩阵相乘以后跟左边这个矩阵的大小相同,这样它们的结果就可以直接相加。针对我们自己的数据集,只需要训练右边这两个小的矩阵即可。这样做有什么好处呢?
举个例子,假设他原来的矩阵大小是512*64,如果右边再加一个新的同样大小的矩阵,需要训练32000多个参数。如果我们用一个512*8和一个8*64的两个小的矩阵来代替这个大矩阵,那大家可以看到这个时候我们只需要训练4500多个参数就可以了,减少了86%的参数量。
接下来我们来看一下怎么使用 Neural Chat 的这些功能。 Fine Tuning 类似 Hugging Face The Past 库,首先创建一个 Configuration ,然后调用 Fine Tuning Model 方法即可。 Automates The Position 同样创建一个 Mixed Position Configure ,然后指定它的数据类型。 Intel 从第四代至强可扩展处理器开始加入了矩阵加速引擎。 Air Max 支持 BF 16和 int 8的矩阵运算,大家如果有第四代及以上的至强可扩展处理器,可以试一下这个 MP 优化,通常运算速度都会有很大的提升。 Weight Only Quantization 目前我们支持表格中的这几种。右边是一个 RTN 的例子,创建一个 RTN config ,权重可以保存成 Int 4。因为目前硬件还不支持直接用 Int 4进行运算,我们可以指定用 Int 8作为计算类型。
除了 Fine-Tuning 模型以外,还有像 Rag 这种机制。尤其是在一些企业里面,他们有自己的数据,但是又不想去 Fine-Tuning 模型,这个时候就可以使用 Rag 。在 Rag 机制中用户来一个 Querying 的时候,首先会经过自己的知识数据库去找到一些相关的信息,然后把这些检索出来的信息加到原始的这个 Querying 上面,再送到大语言模型中去。我们来看一下右边它的实现机制。首先,公司内部的文档经过一个 Embedding Model 把它向量化,保存到本地的一个向量数据库中。用户来了一个 Querying ,同样把这个 Querying 经过这个 Embedded Model 生成向量数据。接下来去向量数据库中检索相关信息,最后一起送到大语言模型中。
Neural Chat支持 Tts Sr Register Plugin 使用的时候设置Enabled 为 True 指定相关的参数即可,比如 Rag 设置 Input Path 为内部的知识文档路径。当然我们还可以设置使用不同的模型进行推理,就像下面这个例子中一样。
另外,我们针对 Langchain 的 API 也做了一些扩展。 RAG 中使用的矢量数据库就是 Langchain 中的对象。
此外 Neural Chat 支持 Serving 配置好这个 Yammer File 创建一个 Neural Chat Server Executor 对象,这个服务就自动起来了。
前面我们讲的不管是 Full-Tuning 还是 Primitive Patient Fine Tuning 都是 Supervised Fine-Tuning 。我们发现虽然通过 Supervised Fine-Tuning 模型学到了很多的知识,但是它们的输出有时候并不是我们期望的。比如说他会输出一些没有任何帮助的结果,或者是一些虚假的不真实的结果,甚至是有害的信息,这个时候我们就希望去对齐这个模型,让它的输出符合我们人类的预期。
于是就有了使用 Reinforcement Learning 这种机制,然后加入人类的 Feedback 来对齐这个模型。左上角的这个是一个典型 Reinforcement Learning 的工作机制。我们使用这个机制来对齐大语言模型的时候,这里的 Agent 就是我们要对齐的模型。在这个 Reward 部分,我们可以加入人类的 Feedback 或者是我们可以训练一个 Reward Model ,让他来给这个模型的输出打分,从而让这个模型学习去输出符合我们期望的结果。
接下来我们来看一下 RL HF是怎么工作的。 首先需要准备一个人类偏好数据集。我们送一个 Prompt 给这个模型,它会生成各种各样不同的 Completion ,然后人类来给这些 Completion 打分。打完分以后,我们把这些 Completion 两两配对,并且把这个分数高的排在前面。数据集准备好以后,我们就要来训练 Reward Model。
Reward Model 的组成结构跟我们要对齐的 Model 的结构是一样的。但是它的最上面一层改成了一个 Regression Layer 。输出一个分数。我们看右边这个图。 Reward Model 会对模型不同的输出打不同的分数,然后根据偏好数据集中的 Label 去优化这个 Loss 函数,从而去调整这个 Reward Model 的沉重。 Reward Model 训练好以后,我们看如何使用它去对齐模型。
首先从 Time Step 开始输入 Prompt 。然后它生成 Completion ,直到这个句子结束。然后我们把整个 Output 送给 Reward Model 。它会给这个 Output 打个分数,再通过 DPO 策略去调整这个模型的权重,从而让这个模型学习输出符合我们预期的结果。 RLHF 虽然可以有效的对其模型,但是在这个过程中,我们需要去训练一个 Reward Model ,然后再使用像 PPU 这样的策略去调整权重。
这个过程还是比较复杂的。而 DPU 这种直接偏好优化策略,它把整个对齐的部分直接设计成了一个损失函数。这个损失函数可以通过一个偏好数据集进行优化,这样就简单很多。
接下来给大家展示一个我们自己使用 Inter Extension For Transformers Fine Tuning 一个大语言模型的 Case 。我们在 Intel 高低 To 的加速器上使用 Lora Tuning 然后使用 GPU 对齐。这个 Fine Tuning 出来的模型在2023年11月13号在 Hugging Face Leader Board 7B 模型当中排名第1。
Fine Tuning 出来的模型叫Neural Chart TB V3。 Fine Tuning 使用的数据集是 Slim Local 数据集。另外我们生成了一个偏好数据集用来对齐模型。代码我们也放在 Intel Extension For Transformers 的源代码中。最右边是 Fine Tuning 的代码,我们使用了 Msture 7B V0.1这个 Pretrained Model 。设置了 Training 的相关参数,以及使用 Lora 进行 Fine Tuning 的参数。创建 Fine Tuning Config 对象,然后调用 Fine To Model 方法。中间这张图是 Fine Tuning 的过程当中 Last 下降曲线。左边这段代码是调用 GPU 对齐模型。在对齐的过程中,我们同时还使用 Lower 在这个偏好数据集上进行了 Fine Tuning 。大家有兴趣可以看一下这个 Python 脚本。
04. Build your own chatbot using Intel® Extension for Transformers
接下来我的同事会给大家展示一个在魔搭上使用 Inter Extension For Transformers 快速搭建一个聊天系统的 Demo 。
大家好,我是来自 Intel 的 AI 工程师万一天,今天我就带大家一起在万搭平台上快速搭建一个属于你自己的 Chat Bot 聊天机器人。大家下载实验手册并打开,然后我带大家进入魔蛋 Models Girls 平台,并跟随手册的指导完成这个搭建任务的全流程。
首先请用浏览器打开魔蛋 Models Girls 的官网,根据手册中的步骤注册并登录魔蛋。对于新用户,可以绑定新注册或现有的阿里云账号后,领取免费的计算资源礼包。
在完成上述步骤后,在浏览器中点击这里,我们就可以启动免费的CPU 服务器资源。
接下来我们进行环境安装环节,如果大家需要从零开始构建自己的运行环境,可以参考一步一步搭建运行环境的官方参考文档。另一种方式是我们这里展示的对以构建并配置完成的现有环境进行环境恢复的方式。这种方式简单快捷,适合初学者快速上手。环境恢复的具体操作如下。
打开这里的终端 Terminal 使用命令切换当前目录为环境目录。 接着在环境目录下新建文件夹 IX 。选择实验手册中两个下载云中的任何一个下载环境恢复文件至当前目录。
接着解压文件志 IX 目录。 Zi 完成后,通过命令激活环境。最后为 Notebook 安装对应的 Kernel 。
接下来我们切换当前目录至工作目录。下载所需的大语言模型至本地,这里我们将展示质朴的 Change M36B 模型和阿里的千万7B模型的下载和使用。可以看到模型已下载完。
下载完成后新建以 Ix 为和的 Test 点 IPYNB 文件。为了方便更高效地运行,我们首先利用 Intel Extension For Transformers 对模型进行量化。
在 Shell 中输入以下代码块。其中可以指定运算类型为 Int 8,承重类型为 Int 4。然后使用 Pipeline Config 设置构建 Chat Bot 。点击左侧运行的按钮,我们可以看到模型正在量化,在量化完成后可以为后面的推理进行准备和加载。
上述步骤完成后,新建 Excel 输入以下代码块。点击左侧按钮运行。可以看到模型的输出结果。下面我们来展示一下当前这个模型对于其他问题的输出结果。新建 Excel ,输入以下代码,将查询 Query 改为如何做麻婆豆腐后点击左侧运行按钮,就可以看到大语言模型的输出结果。接着我们来展示一下如何利用其他模型来构建 Chat Bot 。我们将第一个 Excel 中的模型参数 Model Name Or Path 改为千万模型的地址后,点击左侧按钮运行即完成构建新的 Chat Bot 。完成后,将第二个 Excel 中的 Query 改为上海有哪些美食进行第二次 Sale 。可以看到基于不同大语言模型的 Chat Bot 给出的回答。
到这里我已经带领大家完成了去语音 Text Station For Transformers 软件部署方案,分别使用两个主流的大语言模型完成聊天机器人的部署和实验。大概有兴趣还可以尝试其他部署解决方案知识的模型,如百乘二等。
谢谢大家。