庆云古诗词

庆云古诗词

chatgpt到来程序员如何转型 ChatGPT可以进行代码管理吗

互联资讯 0
程序员carl,程序员让我看看,进入程序员,从程序员到cto

随着『GPT4多模态/Microsoft?365?Copilot/Github?Copilot?X/ChatGPT插件』的推出,绝大部分公司的技术?产品?服务,以及绝大部分人的工作都将被革新一遍

  • 类似iPhone的诞生?大家面向iOS编程?有了App?Store
  • 现在有了ChatGPT插件/GPT应用商店,以后很多公司?很多人面向GPT编程(很快技术人员分两种,一种懂GPT,一种不懂GPT)

然ChatGPT/GPT4基本不可能开源了,而通过上篇文章《类ChatGPT项目的部署与微调(上):从LLaMA到Alpaca、【【微信】】、BELLE、ChatLLaMA和ColossalChat》可知,国内外各大公司、研究者推出了很多类ChatGPT开源项目,比如LLaMA、BLOOM

本文则侧重

  • ChatGLM
  • 垂直领域的ChatGPT等,比如ChatDoctor 毕竟,虽然LLaMA这些模型的通用能力很强,然应用在垂直领域的话,还得再加上各个垂直方向的预料加以训练,由此便诞生了以LLaMA为底层模型的比如ChatDoctor,且可以预见的是,垂直领域的ChatGPT,今年会诞生一大批

在2022年上半年,当时主流的预训练框架可以分为三种:

  • autoregressive,自回归模型的代表是单向的GPT,本质上是一个从左到右的语言模型,常用于无条件生成任务(unconditional generation),缺点是无法利用到下文的信息
  • autoencoding,自编码模型是通过某个降噪目标(如掩码语言模型,简单理解就是通过挖洞,训练模型做完形填空的能力)训练的语言编码器,如双向的BERT、ALBERT、RoBERTa、DeBERTa 自编码模型擅长自然语言理解任务(natural language understanding tasks),常被用来生成句子的上下文表示,缺点是不适合生成任务
  • encoder-decoder,则是一个完整的Transformer结构,包含一个编码器和一个解码器,以T5、BART为代表,常用于有条件的生成任务 (conditional generation) 细致来说,T5的编码器中的注意力是双向,解码器中的注意力是单向的,因此可同时应用于自然语言理解任务和生成任务。但T5为了达到和RoBERTa和DeBERTa相似的性能,往往需要更多的参数量

这三种预训练模型各自称霸一方,那么问题来了,可否结合三种预训练模型,以成天下之一统?这便是2022年5月发表的这篇论文《GLM: General Language Model Pretraining with Autoregressi【【微信】】》的出发点,它提出了GLM架构(这是张义策关于GLM论文的解读之一,下面三小节的内容主要参考自该篇解读)

首先,考虑到三类预训练模型的训练目标

  • GPT的训练目标是从左到右的文本生成
  • BERT的训练目标是对文本进行随机掩码,然后预测被掩码的词
  • T5则是接受一段文本,从左到右的生成另一段文本

为了大一统,我们必须在结构和训练目标上兼容这三种预训练模型。如何实现呢?文章给出的解决方法

  • 结构上,只需要GLM中同时存在单向注意力和双向注意力即可 在原本的Transformer模型中,这两种注意力机制是通过修改attention mask实现的 当attention_mask是全1矩阵的时候,这时注意力是双向的 当attention_mask是三角矩阵的时候(如下图),注意力就是单向 类似地,我们可以在只使用Transformer编码器的情况下,自定义attention mask来兼容三种模型结构
  • 训练目标上,这篇文章提出一个自回归空格填充的任务(Autoregressi【【微信】】),来兼容三种预训练目标 自回归填充有些类似掩码语言模型,首先采样输入文本中部分片段,将其替换为[MASK]标记,然后预测[MASK]所对应的文本片段,与掩码语言模型不同的是,预测的过程是采用自回归的方式 具体来说,? 当被掩码的片段长度为1的时候,空格填充任务等价于掩码语言建模,类似BERT? 当将文本1和文本2拼接在一起,然后将文本2整体掩码掉,空格填充任务就等价于条件语言生成任务,类似T5/BART? 当全部的文本都被掩码时,空格填充任务就等价于无条件语言生成任务,类似GPT

假设原始的文本序列为,采样的两个文本片段为??和??,那么掩码后的文本序列为?(以下简称Part A),如上图所示,拆解图中的三块分别可得

  • 我们要根据第一个?解码出??,根据第二个依次解码出??,那怎么从??处解码出变长的序列吗?这就需要用到开始标记??和结束标记??了
  • 我们从开始标记?开始依次解码出被掩码的文本片段,直至结束标记??。通过本博客内的Transformer笔记可知,Transformer中的位置信息是通过位置向量来记录的 在GLM中,位置向量有两个,一个 用来记录Part A中的相对顺序,一个 用来记录被掩码的文本片段(简称为Part B)中的相对顺序
  • 此外,还需要通过自定义自注意掩码(attention mask)来达到以下目的:? 双向编码器Part A中的词彼此可见,即图(d)中蓝色框中的区域? 单向解码器Part B中的词单向可见,即图(d)黄色框的区域? Part B可见Part A? 其余不可见,即图(d)中灰色的区域

需要说明的是,Part B包含所有被掩码的文本片段,但是文本片段的相对顺序是随机打乱的

作者使用了两个预训练目标来优化GLM,两个目标交替进行:

  • 文档级别的预测/生成:从文档中随机采样一个文本片段进行掩码,片段的长度为文档长度的50%-100%
  • 句子级别的预测/生成:从文档中随机掩码若干文本片段,每个文本片段必须为完整的句子,被掩码的词数量为整个文档长度的15%

尽管GLM是BERT、GPT、T5三者的结合,但是在预训练时,为了适应预训练的目标,作者还是选择掩码较长的文本片段,以确保GLM的文本生成能力,并在微调的时候将自然语言理解任务也转化为生成任务,如情感分类任务转化为填充空白的任务

  • 输入:{Sentence},prompt:It?is?really??,对应的标签为good和bad

此外,模型架构层面,除了整体基于Transformer之外

  1. 重新排列了层归一化和残差连接的顺序
  2. 针对token的输出预测使用单一线性层
  3. 用GeLU替换ReLU激活函数

2022年8月,清华背景的智谱AI基于GLM框架,正式推出拥有1300亿参数的中英双语稠密模型 GLM-130B(论文地址、代码地址,论文解读之一,GLM-130B is trained on a cluster of 96 DGX-A100 GPU (8×40G) ser【【微信】】,可以较好的支持2048个token的上下文窗口)

其在一些任务上的表现优于GPT3-175B,是国内与2020年5月的GPT3在综合能力上差不多的模型之一(即便放到23年年初也并不多),这是它的一些重要特点

ChatGLM-6B(介绍页面、代码地址),是智谱 AI 开源、支持中英双语的对话语言模型,其

  • 基于General Language Model(GLM)架构,具有62亿参数,无量化下占用显存13G,INT8量化级别下支持在单张11G显存的 2080Ti 上进行推理使用(因为INT8下占用显存10G,而INT4量化级别下部署的话最低只需 6GB显存,另基于 P-Tuning v2 的高效参数微调方法的话,在INT4 下最低只需 7GB 显存即可启动微调)
    量化等级最低 GPU 显存(部署/推理)最低 GPU 显存(高效参数微调)
    FP16(无量化)13 GB14 GB
    INT88 GB9 GB
    INT46 GB7 GB
    这里需要解释下的是,INT8量化是一种将深度学习模型中的权重和激活值从32位浮点数(FP32)减少到8位整数(INT8)的技术。这种技术可以降低模型的内存占用和计算复杂度,从而减少计算资源需求,提高推理速度,同时降低能耗 量化的过程通常包括以下几个步骤: 1 量化范围选择:确定权重和激活值的最小值和最大值 2 量化映射:根据范围将32位浮点数映射到8位整数 3 反量化:将8位整数转换回浮点数,用于计算
  • ChatGLM-6B参考了 ChatGPT 的训练思路,在千亿基座模型GLM-130B中注入了代码预训练,通过监督微调(Super【【微信】】)、反馈自助(Feedback Bootstrap)、人类反馈强化学习(Reinforcement Learning from Human Feedback)等方式等技术实现人类意图对齐,并针对中文问答和对话进行优化
  • 最终经过约 1T 标识符的中英双语训练,生成符合人类偏好的回答

虽尚有很多不足(比如因为6B的大小限制,导致模型的记忆能力、编码、推理能力皆有限),但在6B这个参数量级下不错了,部署也非常简单,我七月在线的同事朝阳花了一两个小时即部署好了(主要时间花在模型下载上,实际的部署操作很快)

以下是具体的部署过程

  1. 硬件配置 本次实验用的七月的GPU服务器(专门为七月集/高/论文/VIP学员配置的),显存大小为16G的P100,具体配置如下: CPU&内存:28核(vCPU)112 GB 操作系统:Ubuntu_64 GPU:N【【微信】】 显存:16G
  2. 配置环境 建议最好自己新建一个conda环境 pip install -r re【【微信】】.txt 特别注意torch版本不低于1.10(这里安装的1.10),transformers为4.27.1 torch的安装命令可以参考pytorch官网:https://pytorch.org/ 这里使用的pip命令安装的,命令如下 pip install torch==1.10.0+cu102 torchvision==0.11.0+cu102 torchaudio==0
  3. 下载项目仓库 git?clone?https://github.com/THUDM/ChatGLM-6B cd?ChatGLM-6B
  4. 下载ChatGLM-6B模型文件 具体而言,较大的8个模型文件可以从这里下载(下载速度快):清华大学云盘 其他的小文件可以从这里下载(点击红框的下载按钮即可):THUDM/chatglm-6b ・ Hugging Face 注意这里都下载在了/data/chatglm-6b下,在后面执行代码的时候需要将文件中的模型文件路径改为自己的
  5. 推理与部署 可运行的方式有多种? 如果在本地运行,可以直接执行代码,或者使用命令行方式运行? 如果想让别人公网访问,可以用下面两种方式:一种是基于Gradio,一种是基于streamlit 特别注意:运行代码前请检查模型文件路径是否正确,这里均改为了/data/chatglm-6b代码运行demo 运行之后 如下截图所示命令行 Demo 运行仓库中 cli_demo.py: python cli_demo.py 程序会在命令行中进行交互式的对话,在命令行中输入指示并回车即可生成回复,输入 clear 可以清空对话历史,输入 stop 终止程序基于Gradio的网页版demo 运行web_demo.py即可(注意可以设置share=True,便于公网访问):python?web_demo.py(注意运行前确认下模型文件路径)基于streamlit网页版 Demo pip?install?streamlit pip?install?streamlit-chat streamlit?run?web_demo2.py?--server.port?6006(可以将6006端口放出,便于公网访问) 默认情况下,模型以 FP16 精度加载,运行上述代码需要大概 13GB 显存。如果显存有限,还可以考虑模型量化,目前支持4/8 bit 量化

此外,据介绍,GLM团队正在内测130B参数的ChatGLM,相信从6B到130B,效果应该能提升很多

从上文可知,Stanford Alpaca的52K数据集是通过Self Instruct方式提示GPT3对应的API产生的指令数据,然后通过这批指令数据微调Meta的LLaMA 7B

而GitHub上的这个微调ChatGLM-6B项目(作者:mymusise),则基于Stanford Alpaca的52K数据集通过LoRA(low-rank adaptation)的方式微调ChatGLM-6B

如上一篇文章所说,Huggingface公司推出的PEFT(Parameter-Efficient Fine-Tuning)库便封装了LoRA这个方法,具体而言,通过PEFT-LoRA微调ChatGLM-6B的具体步骤如下

  • 第一步,配置环境与准备 先下载项目仓库 git clone https://github.com/mymusise/ChatGLM-Tuning.git 创建一个python3.8的环境 conda create -n torch1.13 python==3.8 conda acti【【微信】】3 根据re【【微信】】.txt配置环境 pip install bitsandbytes==0.37.1 安装1.13,cuda11.6(torch官网命令) pip install torch==1.13.1+cu116 torchvision==0.14.1+cu116 torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cu116 安装其他的包 遇到冲突问题:icetk 0.0.5 has re【【微信】】<3.19, but you ha【【微信】】.19.5. 最后装了3.18.3的protobuf,发现没有问题 模型文件准备 模型文件在前面基于ChatGLM-6B的部署中已经准备好了,注意路径修改正确即可
  • 第二步,数据准备 项目中提供了数据,数据来源为 Stanford Alpaca 项目的用于微调模型的52K数据,数据生成过程可详见:https://github.com/tatsu-lab/stanford_alpaca#data-release alpaca_data.json,包含用于微调羊驼模型的 52K 指令数据,这个 JSON 文件是一个字典列表,每个字典包含以下字段: instruction: str,描述了模型应该执行的任务,52K 条指令中的每一条都是唯一的 input: str,任务的可选上下文或输入。例如,当指令是“总结以下文章”时,输入就是文章,大约 40% 的示例有输入 output: str,由?text-da【【微信】】?生成的指令的答案 示例如下:
  • 第三步,数据处理 运行 co【【微信】】.py 文件 python co【【微信】】.py \ --data_path data/alpaca_data.json \ --sa【【微信】】lpaca_data.jsonl \ 处理后的文件示例如下: 运行 tokenize_dataset_rows.py 文件,注意:修改tokenize_dataset_rows中的model_name为自己的文件路径 :/data/chatglm-6b
  • 第四步,微调过程 注意:运行前修改下finetune.py 文件中模型路径:/data/chatglm-6b Nvidia驱动报错(如没有可忽略) 遇到问题,说明Nvidia驱动太老,需要更新驱动 UserWarning: CUDA initialization: The N【【微信】】tem is too old (found 【【微信】】). Please update your GPU driver by downloading and installing a new 【【微信】】: http://www.nvidia.com/【【微信】】/index.aspx Alternatively, go to: https://pytorch.org to install a PyTorch 【【微信】】mpiled with your version of the CUDA driver. (【【微信】】t http://www.taodudu.cc/c10/cuda/CUDAFunctions.cpp:109.) 解决:更新驱动即可,参考:Ubuntu 18.04 安装 NVIDIA 显卡驱动 - 知乎 BUG REPORT报错 参考:因为peft原因,cuda10.2报错 ・ Issue #108 ・ mymusise/ChatGLM-Tuning ・ GitHub CUDA SETUP: CUDA 【【微信】】e currently not supported for LLM.int8() 考虑安装11以上的cudatooklit,参考下面链接,安装【【淘密令】】.3(因为Ubuntu系统版本的原因,不能装11.6的)Ubuntu16.04 安装cuda11.3+cudnn8.2.1 - 知乎 cudatooklit下载地址:CUDA Toolkit 11.3 【【微信】】s | NVIDIA 开发者 运行代码前先执行下面命令: 内存不够,考虑将per_de【【微信】】e设为1 报错:RuntimeError: expected scalar type Half but found Float https://github.com/mymusise/ChatGLM-Tuning/issues?q=is%3【【微信】】+is%3Aopen+RuntimeError%3A+expected+scalar+type+Half+but+found+Float 解决方法: 一种是,不启用fp16, load_in_8bit设为True,可以运行,但loss为0; 一种是,启用fp16, load_in_8bit设为False,不行,应该还是显存不够的问题,至少需要24G左右的显存

此外,ChatGLM团队自身也出了一个基于P-Tuning v2的方式微调ChatGLM-6B的项目:ChatGLM-6B 模型基于 P-Tuning v2 的微调

P-Tuning v2(代码地址,论文地址)意义在于:将需要微调的参数量减少到原来的 0.1%,再通过模型量化、Gradient Checkpoin

chatgpt内部环境分析 chatgpt怎样增加我们的数据集

内部环境分析工具是什么,内部环境分析的常用工具,外部环境和内部环境分析工具,内部环境分析的特点

近期,除了研究ChatGPT背后的各种技术细节 不断看论文(至少100篇,100篇目录见此:ChatGPT相关技术必读论文100篇),还开始研究一系列开源模型(包括各自对应的模型架构、训练方法、训练数据、本地私有化部署、硬件配置要求、微调等细节)?

本文一开始是作为此文《ChatGPT技术原理解析:从RL之PPO算法、RLHF到GPT4、instructGPT》的第4部分,但随着研究深入 为避免该文篇幅又过长,将把『第4部分 开源项目』抽取出来 独立成本文,然后不断续写本文直至成了一个系列

毕竟我上半年的目标之一,便是把ChatGPT涉及的所有一切关键技术细节,以及相关的开源项目都研究的透透的,故过程中会不断产出一篇篇新文章出来

?虽说GPT3在2020年就出来了,但OpenAI并未开源,所以直到一年半后以后才有国内外各个团队比如DeepMind等陆续复现出来,这些大厂的复现代码我们自然无法窥知一二,毕竟人家也未开源出来

再到后来基于GPT3的InstructGPT、基于GPT3.5ChatGPT初版(GPT3.5的参数规模也尚无准确定论)、GPT4均未开源,OpenAI不再open,好在Meta等公司或研究者开源出了一系列类ChatGPT项目,本部分针对其中部分做下简要推荐(根据发布顺序排序)

2.15,很多朋友在GitHub上发现了一个基于【【微信】】低成本实现类ChatGPT迷你版训练过程的开源项目(基于OPT + RLHF + PPO),虽是类似GPT3的开源项目OPT与RLHF的结合,但可以增进我们对ChatGPT的理解,该项目有几个不错的特点

  1. 很多同学一看到DL,便会想到大数据,而数据量一大,还用CPU处理的话很可能训练一个小任务都得半天,而如果用GPU跑,可能一两分钟就出来了。于此,在深度学习大火的那几年,特别是AlphaGo出来的16年起,我司七月在线便分别为VIP、AI系统大课、在职提升大课、求职/论文/申博/留学1V1辅导提供GPU云平台进行实战训练 但如果想训练那种千亿参数规模的开源模型,就不只是有GPU就完事了,比如1750亿参数规模这种得用64张AI 100(即便经过一系列内存开销上的优化,也得至少32张AI 100,单张AI 100售价10万以上,且现在还经常没货),这样的硬件要求是大部分个人是无法具备的,所以该开源项目提供了单GPU、独立4/8-GPUs 的版本
  2. 如下代码所示,启动简单
  3. 训练过程明确清晰,如下图(由于此文已经详细介绍过ChatGPT的训练步骤,故不再赘述)

    ?此外,据钟博士在我所维护的『Machine Learning读书会群』里所说,【【微信】】的并行效率确实不错,是新加坡的一个初创团队推出的,但目前尚没有团队采用【【微信】】框架来做主训练框架训练175b级别的超大模型,可以再了解下Meta家训练OPT用的Metaseq

通过《ChatGPT技术原理解析》一文,我们已经知道了ChatGPT的三阶段训练过程,其中,阶段三的本质其实就是通过PPO的方式去微调LM

GitHub上有个TRL(Transformer Reinforcement Learning,基于『Hugging Face开发的Transformer库』),便是通过PPO的方式去微调LM,需要的数据便是三元组「query, response, reward」,具体如下图所示

  1. Rollout:语言模型根据query生成response
  2. 评估:怎么评估模型针对特定query生成response的质量呢,我们可以使用a function、model、human feedback或它们的某种组合进行评估,然后为每个que【【微信】】对产生一个标量值,说白了 就是奖励模型有了,那就直接打分
  3. 优化:在优化步骤中,「que【【微信】】 pairs」用于计算序列中标记的对数概率,且比较下面这两个模型输出之间的 KL 散度用作额外的奖励信号? 经过训练的模型(即上图中的Acti【【微信】】)? 基线模型(即上图中的Reference model),通常是PPO微调之前的模型(比如这里的GPT2,或者instructGPT里的SFT) 最终,使得Acti【【微信】】生成的响应不会偏离基线模型Reference model太远

示例代码如下

一直致力于LLM模型研究的国外TOP 3大厂除了OpenAI、Google,便是Meta(原来的Facebook)

Meta曾第一个发布了基于LLM的聊天机器人――BlenderBot 3,但输出不够安全,很快下线;再后来,Meta发布一个专门为科学研究设计的模型Galactica,但用户期望过高,发布三天后又下线

23年2.24日,Meta通过论文《LLaMA: Open and Efficient Foundation Language Models》发布了自家的大型语言模型LLaMA(这是解读之一),有多个参数规模的版本(7B 13B 33B 65B)

LLaMA只使用公开的数据(总计1.4T即1,400GB的token,其中CommonCrawl的数据占比67%,C4数据占比15%,Github Wikipedia Books这三项数据均各自占比4.5%,ArXiv占比2.5%,【【微信】】占比2%),论文中提到

When training a 65B-parameter model, our code processes around 380 tokens/sec/GPU on 2048 A100 GPU with 80GB of RAM.

This means that training o【【微信】】g 1.4T tokens takes approximately 21 days

且试图证明小模型在足够多的的数据上训练后,也能达到甚至超过大模型的效果

  • 比如13B参数的版本在多项基准上测试的效果好于2020年的参数规模达175B的GPT-3
  • 而对于65B参数的LLaMA,则可与DeepMind的Chinchilla(70B参数)和谷歌的PaLM(540B参数)旗鼓相当
  • 且Meta还尝试使用了论文「Scaling Instruction-Finetuned Language Models」中介绍的指令微调方法,由此产生的模型LLaMA-I,在MMLU(Massi【【微信】】nderstanding,大型多任务语言理解)上要优于Google的指令微调模型Flan-PaLM-cont(62B)

此项目给出的环境依赖有4个:

  1. torch
  2. fairscale,fairscale是用来做GPU分布的,一般是当使用DDP仍然遇到超显存的问题时使用fairscale
  3. fire,fire是一个命令行工具,用或者不用他都可以
  4. sentencepiece,sentencepiece是用于tokenizer的工具包

为了提高训练的稳定性,对每个transformer子层的输入进行归一化,而不是对输出进行归一化,且使用由Zhang和Sennrich(2019)提出的RMSNorm(Root Mean S【【微信】】ion) RMS Norm是一般LayerNorm的一种变体,可以在梯度下降时令损失更加平滑 与【【微信】】相比,RMS Norm的主要区别在于去掉了减去均值的部分(re-centering),只保留方差部分(re-scaling)

为一目了然,我们看下它们各自的归一化的表达式

  • 一般的LN: 其中
  • RMS Norm: 其中

至于RMS Norm为什么有用,需要求梯度进行分析,感兴趣的同学可以阅读RMS Norm的论文

用Shazeer(2020)提出的SwiGLU替代ReLU,在维度上使用的维度是2/3*4d,而不是PaLM中的4d

LLaMA采用SwiGLU替换了原有的ReLU,具体是采用SwiGLU的FNN,在论文中以如下公式进行表述:

其中

对应论文见:Ramachandran et al., 2017 代码实现上:可以通过调用torch内置方法F.silu()实现,会在下文的FFN部分介绍

在位置编码上,删除了绝对位置嵌入,而在网络的每一层增加了苏剑林等人(2021)提出的旋转位置嵌入(RoPE),其思想是采用绝对位置编码的形式,实现相对位置编码

  • RoPE主要借助了复数的思想,为了引入复数,首先假设了在加入位置信息之前,原有的编码向量是二维行向量,其中是绝对位置,现在需要构造一个变换,将引入到中,即寻找变换:? 考虑到Attention的核心计算是内积: 所以,寻求的这个变换,应该具有特性:
  • 这里直接说结论,寻求的变换就是,也就是给乘以,相应地,乘以 做了这样一个变换之后,根据复数的特性,有: 也就是,如果把二维向量看做复数,那么它们的内积,等于一个复数乘以另一个复数的共轭,得到的结果再取实部,代入上面的变换,也就有: 这样一来,内积的结果就只依赖于,也就是相对位置了 换言之,经过这样一番操作,通过给Embedding添加绝对位置信息,可以使得两个token的编码,经过内积变换(self-attn)之后,得到结果是受它们位置的差值,即相对位置影响的
  • 于是对于任意的位置为的二维向量,把它看做复数,乘以,而根据欧拉公式,有: 于是上述的相乘变换也就变成了: 把上述式子写成矩阵形式: 而这个变换的几何意义,就是在二维坐标系下,对向量进行了旋转,因而这种位置编码方法,被称为旋转位置编码
  • 根据刚才的结论,结合内积的线性叠加性,可以将结论推广到高维的情形。可以理解为,每两个维度一组,进行了上述的“旋转”操作,然后再拼接在一起: 由于矩阵的稀疏性,会造成计算上的浪费,所以在计算时采用逐位相乘再相加的方式进行: 其中为矩阵逐位相乘操作

原理理解了,接下来可以代码实现旋转位置编码

引用此文的介绍,再着重解释下precompute_fre【【微信】】的作用

  • 假设 batch_size为2 seq_len固定为512 【【微信】】的数量为12 每个【【微信】】的维度为64,那么,对于输入到multi-head attn中的输入的尺寸就是 (2, 512, 12, 64)
  • 而fre【【微信】】其实就是需要计算出来的也就是跟绝对位置相关的旋转的角度,在极坐标下对应的复数tensor

而precompute_fre【【微信】】就是提前将这些旋转角度对应的tensor给创建出来,并可以重复利用。因为确定了序列的最大长度,所以这个tensor是固定死的。根据后续的数据流我们可以发现,在调用该函数时,传入的两个参数分别是【【微信】】的维度,以及最大长度的两倍,具象地,也就是64和1024

LLaMA和GPT一样,都是基于Transformer这个架构,通常,我们在构建transformer时,是按Block构建的,每个transformer Block包含SA和FFN两部分,然后再通过堆叠block的形式,构建起整个transformer网络,LLaMA也是这样做的 回顾一下Attention计算的总体过程是:

  1. 输入,分别经过三个Linear得到
  2. 在??和中加入旋转位置编码
  3. 缓存??和??
  4. 计算

其中有一个细节就是缓存机制,它设计的目的是在generate时减少token的重复计算。简单解释一下,就是在计算第n个token特征的时候,需要用到第个token,即每次生成时,需要知道前面所有的过往信息,如果每次都从头算的话,那就会造成极大的浪费,所以就没算一个位置的信息,就把它缓存下来 接下来,我们来看下代码实现,首先是SA部分:

然后是FFN部分,需要注意的点就是采用的激活函数,以及激活函数的位置

这里与常见模型中的FFN做一下简单的对比

  • BART中的FFN,用的是fc->act->fc,用了两层全连接
  • GPT中的FFN,用的是【【微信】】->act->【【微信】】,也是只用了两层
  • 而LLaMA中的FFN采用了三个全连接层以实现FFNSwiGLU,即

然后将SA和FFN这两部分拼在一起就是一个transformer block

最后利用torch的module list将transformer block进行堆叠,拼上最前头的embedding部分,就是一个完整的transformer decoder结构了

接着看下生成过程,如下:

  1. 对prompts进行tokenize,得到token ids;
  2. 计算当前batch的最大长度total_len,用来创建输入的token tensor,最大长度不能超过前文所述缓存的大小;
  3. 从当前batch中,最短的一个prompt的位置,作为生成的开始位置,开始生成;
  4. 输入的token tensor传入transformer模型,计算logits,得到形状为(batch_size, hidden_size)的logits(transformer最后一层的输出);
  5. softmax+top_p采样,得到当前预测的token,并更新当前位置,准备预测下一个token;
  6. 解码得到生成的文本

代码如下

在Optimizer设计上

  • 该模型使用AdamW优化器(Loshchilov和【【微信】】,2017)进行训练,超参数设置为β1=0.9,β2=0.95 此外,使用余弦学习率方式,使最终学习率等于最大学习率的10%,以及使用0.1的权重衰减和1.0的梯度剪裁,和2000个warm up策略,使得可以根据模型的大小改变学习率和批次大小

在模型的加速优化方面

  1. 首先,使用一个高效的因果多头注意力方式的实现,灵感来自Rabe和Staats(2021)以及Dao等人(2022),这个实现可在xformers库中找到,可以有效减少内存的使用和计算 具体原理为通过不存储注意力权重和不计算由于语言建模任务的因果性质而被掩盖的键/查询分数来实现的
  2. 其次,为了进一步提高训练效率,减少了在check point的后向传递中重新计算的激活量,在实现上,通过手动实现trasnformer层的后向函数来进行操作 为了充分受益于这种优化,还通过如Korthikanti等人(2022)中采用的方法,进行使用模型和序列并行来减少模型的内存使用
  3. 最后,该工作还尽可能地重叠激活的计算和GPU之间在网络上的通信 最终的优化性能效果为:当训练一个65B参数的模型时,代码在2048A100的GPU上处理大约380个token/秒/GPU,并耗费80GB的内存,这意味着对包含1.4Ttoken的数据集进行训练大约花费了21天

LLaMA发布不久后,一些研究者基于它做了不少工作

  • 一开始最小参数7B的模型也需要近30GB的GPU才能运行,但通过比特和字节库进行浮点优化,能够让模型在单个N【【微信】】(显存一般12G)上运行
  • 之后,GitHub 上的一名研究人员甚至能够在Ryzen 7900X CPU上运行LLM的7B 版本,每秒能推断出几个单词
  • 再之后,有研究者推出了llama.cpp,无需 GPU,就能运行 LLaMA llama.cpp 项目实现了在MacBook上运行 LLaMA,还有开发者成功的在 4GB RAM 的树莓派上运行了 LLaMA 7B

3月中旬,斯坦福发布Alpaca(中文名:羊驼):号称只花100美元,人人都可微调Meta家70亿参数的LLaMA大模型(即LLaMA 7B),具体做法是通过52k指令数据,然后在8个80GB A100上训练3个小时,使得Alpaca版的LLaMA 7B在单纯对话上的性能比肩GPT-3.5(text-davinci-003),这便是指令调优LLaMA的意义所在

  • 论文《Alpaca: A Strong Open-Source Instruction-Following Model》
  • 代码地址:https://github.com/tatsu-lab/stanford_alpaca

可能有读者有疑问,即52k数据都长啥样呢?这52K数据存在Alpaca项目的alpaca_data.json文件中,这个JSON文件是一个字典列表,每个字典包含以下字段:

  • instruction: str,描述了模型应该执行的任务,52K 条指令中的每一条都是唯一的
  • input: str,要么是上下文,要么直接输入(【【微信】】ut for the task),例如,当指令是“总结以下文章”时,输入就是文章,大约 40% 的示例有输入
  • output: str,由GPT3.5对应的API即 text-davinci-003生成的指令的答案

而斯坦福团队微调LLaMA 7B所用的52K指令数据,便是通过Self-Instruct『Self-Instruct是来自华盛顿大学Yizhong Wang等22年12月通过这篇论文《SELF-INSTRUCT: Aligning Language Model with Self Generated Instructions》提出的』提示GPT3的API拿到的

?具体而言,论文中提出

  1. 人工设计175个任务,每个任务都有对应的{指令 输入 输出/实例}或{指令 输出/实例},将这175个任务数据作为种子集
  2. 然后提示模型比如GPT3对应的API即 text-da【【微信】】 (原论文中没用text-davinci-003,because their newer engines are trained with the latest user data and are likely to already see the SUPERNI e【【微信】】,但实际应用时比如斯坦福Alpaca指定的GPT3.5的API即 text-davinci-003生成指令,包括很快你将看到,23年4月还有微软的研究者指定GPT4的API生成指令),使用种子集作为上下文示