前言
ChatGPT的迅速出圈,加速了大模型时代的变革,本小白也被卷入了这场变革之中,下面是记录我从0入门大语言模型的一些笔记与实践。
基础知识
Why hasn't the public seen programs like ChatGPT from Meta or from Google?
"Because Google and Meta both have a lot to lose by putting out systems that make stuff up" says Meta's chief AI scientist, Yann LeCun.
LeCun在推特简短的一句话里包含了两个重要信息:
(1)chatGPT是一个组装模型(不够innovative,在LeCun看来是make stuff up)。它的零件来自于近5、6年内在LLM(大语言模型)领域上的里程碑。从技术上来说,它不是创新的。
(2)比起技术,更低的公众容忍度,商业化的形象和复杂的决策流程,是阻碍大厂在这个节点前进的原因之一。
根据ChatGPT官网介绍,ChatGPT沿用了openAI 2022年3月提出的instructGPT的训练框架,只是将原本的GPT3替换成了GPT3.5,同时在训练数据上做了一些调整。所以我们需要先简单看一下instructGPT
论文地址:
https://arxiv.org/pdf/2203.02155.pdf
首先我们可以看出论文的目标是希望gpt能够按照人们的指令做事(听话),能够按照人们想要的方式进行回答(会说话)。
GPT3(Generative Pre-trained Transformer)是openAI在2020年推出的Transformer类模型,它的模型参数已经高达175B,为什么chatgpt 3.5能够比gpt3强这么多?通过论文我们能看到原因在于增加了一个驯服模型的过程。首先假设我们拥有了一个模型,我们应该如何教模型怎么说话。
首先我们需要网上找了大量任意资料给模型看,它在海量的资料中学习。
比如你给它上半句“今天天气真不错”,它能根据自己的学习成果,接出下半句,且每次询问它,都可能得到不同的结果。
我们如何让模型能够按照我们想要的方式进行回答呢?
模型通过对海量的资料进行学习后学会了说话。但它的回答可能并不令你满意,没有对齐你的意图(aligin to your intention)。
例如,从你的意图来说,你希望是“今天天气真不错,我在家里睡懒觉。”从你老板的意图来说,他希望是“今天天气真不错,大家一起来加班。”从你老妈的意图来说,她希望是“今天天气真不错,我娃必须去擦地。”
为了让模型对齐人类意图,人类将模型这三句话重新送入模型,做有监督的微调。
对于同一个问题,不同人类的回答是不一样的。为了让模型得到一个让大部分人都满意的答案,我们再邀请一批人类,来对不同的回答进行排序/打分。然后,我们再训练一个“打分模型”,来学习人类的打分标准。
到这里,我们的模型已经明白了人类希望的回答,以及不同回答在人类那里的得分,此时,我们只需要把得分反馈给模型,让它在这样循环中更新迭代自己就行。于是,chatGPT的整体架构就出来了:
其中
action:(prompt, completion)对,prompt表示问题,completion表示模型的回答。
reward:(prompt completion)对的得分。
state:根据得分结果,优化迭代GPT3/GPT3.5,改变状态,得到最终的chatGPT
这张架构图,即为chatGPT官网给出的训练步骤的总结。
GPT3.5与GPT3原理基本一致,在训练数据上,引入codex数据集在GPT3上做微调,所以在chatGPT中,也能发现其具备对代码的解析能力。
STF
GPT-SFT(Supervised Fine-Tuning on GPT),基于GPT的有监督微调。通过前面我们知道,GPT已经是一个文字接龙好手了,并且由于看过足够多的资料,它能保证基本的回答质量。但它仍不够惊艳,因为它只是按照所学回答问题,而在贴合人类意图上还有所欠缺,也就是,还不够“类人”。
解决这个问题的想法,暴力又简单,那就是“标数据”,让self-supervised模式训练出来的GPT,也经过supervised的微调,直接了当的告诉它,人类想要什么回答。openAI雇佣了40名标注人员,在SFT阶段共标注13k的(prompt, completion)对问答数据,其中prompt包含如下类型:
Plain:让标注人员不受约束,随意写一些问题
Few-shot: 让标注人员按照Instruction: (prompt, completion)的方式进行标注。例如:请做翻译: (苹果->Apple)
User-based:让标注人员从openAI API的请求列表用例中,找一些问题进行标注。例如Generation类-请对下文做总结,Branstorming类-请列出保持职业热情的5种方法等。
有了标注数据,我们就可以对GPT进行微调,在论文中,一组(prompt, completion)也被称为demonstration。
奖励模型(RM, Reward Model)
当GPT大概能朝着人类意图的方向走时,我们需要给他更量化的指标,让它知道同一个prompt下,不同回答在人类那里的排序。所以,我们要训练一个奖励模型(RM,Reward Model)。
奖励模型也不是chatGPT的首创,它借鉴于Stiennon et.al (2020)的研究结果。在这一阶段,标注人员需要对同一prompt的不同回答进行排序,一共有33k的标注数据被用于训练。
在标注阶段,标注人员被要求对每一个prompt下的不同回答进行偏号排序。如图,某个prompt下有ABC三个回答,标注人员认为A>B>C。
在训练阶段,假设一个prompt下有K个回答,则两两回答一组,组成一条训练数据,例如(prompt, A, B),则一共有 CK2条训练数据。这群训练数据将组成一个batch,通过构造并最小化Pairwise Ranking Loss的方法,来训练奖励模型。作为机器学习小白对其原理不继续深入,只需要了解即可。
基于人类反馈的强化学习(RLHF)
模型学会了怎么说话,同时我们又训练出了一个独立的奖励模型,这时候,我们就要把两者结合起来,让模型能够更好的对齐人类意图了。在这里,chatGPT使用改良版本的PPO(Schulman et al, 2017)对GPT进行再次训练,改良后的训练算法被称为PPO-ptx。
目前业界可以下载到的大语言模型
ChatGLM-6B / ChatGLM2-6B :清华开源的中英双语的对话语言模型。目前,第二代ChatGLM在官网允许的情况下可以进行商用。
GLM-10B/130B :双语(中文和英文)双向稠密模型。
LLaMA-7B/13B/30B/65B :Meta开源的基础大语言模型。
Alpaca(LLaMA-7B):斯坦福提出的一个强大的可复现的指令跟随模型,种子任务都是英语,收集的数据也都是英文,因此训练出来的模型未对中文优化。
BELLE(BLOOMZ-7B/LLaMA-7B/LLaMA-13B):本项目基于 Stanford Alpaca,针对中文做了优化,模型调优仅使用由ChatGPT生产的数据(不包含任何其他数据)。
Bloom-7B/13B/176B:可以处理46 种语言,包括法语、汉语、越南语、印度尼西亚语、加泰罗尼亚语、13 种印度语言(如印地语)和 20 种非洲语言。其中,Bloomz系列模型是基于 xP3 数据集微调。推荐用于英语的提示(prompting);Bloomz-mt系列模型是基于 xP3mt 数据集微调。推荐用于非英语的提示(prompting)。
Vicuna(7B/13B):由UC Berkeley、CMU、Stanford和 UC San Diego的研究人员创建的 Vicuna-13B,通过在 ShareGPT 收集的用户共享对话数据中微调 LLaMA 获得。其中,使用 GPT-4 进行评估,发现 Vicuna-13B 的性能在超过90%的情况下实现了与ChatGPT和Bard相匹敌的能力;同时,在 90% 情况下都优于 LLaMA 和 Alpaca 等其他模型。而训练 Vicuna-13B 的费用约为 300 美元。不仅如此,它还提供了一个用于训练、服务和评估基于大语言模型的聊天机器人的开放平台:FastChat。
Baize:白泽是在LLaMA上训练的。目前包括四种英语模型:白泽-7B、13B 、 30B(通用对话模型)以及一个垂直领域的白泽-医疗模型,供研究 / 非商业用途使用,并计划在未来发布中文的白泽模型。白泽的数据处理、训练模型、Demo 等全部代码已经开源。
LLMZoo:来自香港中文大学和深圳市大数据研究院团队推出的一系列大模型,如:Phoenix(凤凰) 和 Chimera等。
MOSS:由复旦 NLP 团队推出的 MOSS 大语言模型。
baichuan-7B:由百川智能推出的大模型,可进行商用。
CPM-Bee:百亿参数的开源中英文双语基座大模型,可进行商用。
...
中小模型微调复盘
GLM是一个清华大学开发的预训练的语言模型,有6B和130B等等版本。GLM6B遵循prompt的能力比较弱。上限比较低。
LlaMA,vicuña,alpaca(羊驼家族),BLOOM(法国)等最近纷纷有了中文微调后的版本
微调(Fine-tuning)是指在预训练的模型基础上,使用特定的任务数据进行额外的训练,以使模型适应特定的任务或领域。这种方法通常用于迁移学习,通过使用预训练的模型来解决特定任务,而不是从头开始训练一个全新的模型。
目前的模型问题有:Hallucination(幻觉),Misalligment(有害性或着无时效)等。在专家领域遇到的问题有:知识泄露。
微调的步骤
有监督微调(SFT)。数据集:QA问答对的形式,在GPT的原始训练方式中,问答对质量极高。
目前的问题:A.有监督预训练数据集不够均匀,需要较长的数据整理清洗时间。B.缺少无监督预训练预料
无监督二次预训练。数据集:文件夹以及文章内容(非问答对)
二次预训练的代码目前仍旧在调试中。GLM目前没有二次预训练的代码,并且缺少数据,效果有可能不好。
强化奖励训练。
目前的微调结果,比较好的基本做了RW,PPO
微调的结果:
简单问答上有70~80%的准确度,有一定的涌现程度。P_tuning方法难以拟合,lora方法可以用,加速版本依旧在陆续开源调试。
工程经验(结论):
GLM的微调基本放弃。
A. GLM官方并未开源通用知识数据集,以及6B模型的能力有限并未充分利用一台服务器算力资源。
B. LLaMA系列生命力强,有中等模型。ziya,中文词表扩充后,逐渐可以使用。
强化学习尝试。数据集:数据以及优化过的数据(非问答对)
微调实践
因为glm的微调效果不佳,我这里使用Vicuna进行微调。
Vicuna具体的工作流程如下图所示,首先,研究人员从 http://ShareGPT.com(一个供用户分享 ChatGPT 对话内容的网站)收集了约 7 万个对话,并增强了 Alpaca 提供的训练脚本,以更好地处理多轮对话和长序列。训练是在一天内通过 8 卡 A100 GPU 配合 PyTOrch FSDP 进行的full fine-tune。为了提供演示服务,Vicuna研究人员建立了一个轻量级的分布式服务系统,创建了八个问题类别(如:角色扮演、编码/数学任务等)的 80 个不同问题,利用 GPT-4 来判断模型输出,借此对模型质量做初步评估。为了比较两个不同的模型,Vicuna研究人员将每个模型的输出组合成每个问题的单个提示。然后将提示发送到 GPT-4,GPT-4 评估哪个模型提供更好的响应。
环境搭建
这里我直接用了腾讯云的GPU机器,大致环境如下:
操作系统: Ubuntu 18.04
GPU:P40 24G(预装460驱动)
Python: 3.10
CUDA工具包: 11.7
Pytorch:1.9.1
通过pyllama下载llama模型文件
24G显存目前只能微调7B模型,通过qlora技术可以微调13B(后面有机会再写)
pip install pyllama -U
python -m llama.download --model_size 7B
Vicuna模型权重合并
Vicuna 仅发布了 delta 权重,以符合 LLaMA 模型license授权。因此,我们需要增量将其添加到原始 LLaMA 权重以获得整个 Vicuna 的权重。
下载Vicuna的 delta 权重:
git lfs clone https://huggingface.co/lmsys/vicuna-7b-delta-v1.1
下载fastchat
git clone https://github.com/lm-sys/FastChat.git
cd FastChat
pip3 install --upgrade pip # enable PEP 660 support
pip3 install -e .
Vicuna模型权重合并:
python3 -m fastchat.model.apply_delta
--base /model/llama-7b-hf
--delta /model/vicuna-7b-delta-v1.1
--target /model/vicuna-7b-all-v1.1
lora微调
git clone https://github.com/hiyouga/LLaMA-Efficient-Tuning.git
conda create -n llama_etuning python=3.10
conda activate llama_etuning
cd LLaMA-Efficient-Tuning
pip install -r requirements.txt
预训练
CUDA_VISIBLE_DEVICES=0 python src/train_pt.py
--model_name_or_path path_to_your_model
--do_train
--dataset wiki_demo
--finetuning_type lora
--output_dir path_to_pt_checkpoint
--overwrite_cache
--per_device_train_batch_size 4
--gradient_accumulation_steps 4
--lr_scheduler_type cosine
--logging_steps 10
--save_steps 1000
--learning_rate 5e-5
--num_train_epochs 3.0
--plot_loss
--fp16
SFT
CUDA_VISIBLE_DEVICES=0 python src/train_sft.py
--model_name_or_path path_to_your_model
--do_train
--dataset alpaca_gpt4_en
--finetuning_type lora
--output_dir path_to_sft_checkpoint
--overwrite_cache
--per_device_train_batch_size 4
--gradient_accumulation_steps 4
--lr_scheduler_type cosine
--logging_steps 10
--save_steps 1000
--learning_rate 5e-5
--num_train_epochs 3.0
--plot_loss
--fp16
数据集
预训练的数据集可以是纯文本,我爬取了维基百科的安全类数据以及一写优质的文章和博客。
SFT数据主要是问答对,我通过给GPT关键词让GPT帮我生成提示词并给出答案,最后转换成问答对格式。
项目自带了许多数据集,大家可以参考下
案例:
{
"instruction": "你现在是一名程序员,请你回答以下问题。",
"input": "用Java如何读取文件?",
"output": "```javanimport java.io.*;nnclass ReadFile {n public static void main(String[] args) {n try {n File file = new File("filename.txt");n BufferedReader br = new BufferedReader(new FileReader(file));n String st;n while ((st = br.readLine()) != null)n System.out.println(st);n }n catch (Exception e) {n System.err.println("Error: " + e.getMessage());n }n }n}n```"
}
我这里跑了安全相关的数据
数据量比较小,看效果
学习参考:
https://zhuanlan.zhihu.com/p/605516116
https://mp.weixin.qq.com/s/6n8KiOBbro6csGET_mMaYw
https://github.com/hiyouga/LLaMA-Efficient-Tuning
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……
还没有评论,来说两句吧...