动手点关注
干货不迷路
本文旨在让无大模型开发背景的工程师或者技术爱好者无痛理解大语言模型应用开发的理论和主流工具,因此会先从与LLM应用开发相关的基础概念谈起,并不刻意追求极致的严谨和完备,而是从直觉和本质入手,结合笔者调研整理及消化理解,帮助大家能够更容易的理解LLM技术全貌,大家可以基于本文衍生展开,结合自己感兴趣的领域深入研究。若有不准确或者错误的地方也希望大家能够留言指正。
本文体系完整,内容丰富,由于内容比较多,分多次连载,大家在本公众号查看 。
第一部分 基础概念
1.机器学习场景类别
2.机器学习类型(LLM相关)
3.深度学习的兴起
4.基础模型
第二部分 应用挑战
1.问题定义与基本思路
2.基本流程与相关技术
1)Tokenization与Embbeding
2)向量数据库
3)finetune(微调)
- 背景挑战
- 方案理论
- 工具实践
4)模型部署与推理
5)prompt
6)编排与集成
7)预训练
第三部分 场景案例
常用参考
2.基本流程与相关技术
2) finetune(微调)-背景与挑战
缘起
我们前面提到过预训练大语言模型(PLM),虽然它通过无监督学习已经自学了大量的" 世界知识(universal knowledge)" ,具备了一定的任务技能,如Bert做“完形填空”,GPT做擅长”文字接龙“,在无监督学习时做的任务叫做上 游任务( upstream task )。
@Hung-yi Lee
虽然它们“博览群书,学富五车”,但显然它还无法直接完成具体的下游任务(downstream),如情感分析,主题分类,文本生成等。
那么,如何弥合上下游任务之间的gap,“对齐”大模型能力和用户实际的需求呢?
两条路线
为了解决这样的问题,但又由于大模型的特点,如训练成本高,以及利用到大模型学习到的“世界知识”的初衷,进而有一个比较直接的做法,就是设计不同目标的下游任务来和大模型组合起来一起完成具体的任务。这一过程叫做目标函数挖掘(Objective Engineering)。 基于此思路收集训练该领域任务需要的标注数据重新学习,从而使得模型具备该领域任务的能力。 当然我们不希望学习特定领域方面的知识时,忘掉自己之前在预训练学习的知识,我们会将大模型的参数作为初始参数来学习,从而使得他在保留历史知识和能力的情况下,又能适配下游任务具体的要求,这一过程就叫做finetune(微调)。 这样的思路相较于从零训练模型有了很大的改进。因此, “预训练(pretrain)+微调(finetune)”对齐模型能力与用户需要的范式也就流行起来。
在bert时代,参数还不算非常大,这样的模式似乎也没有什么问题。模型朝着专才如火如荼发展。
但这种每一种任务都做一个适配任务的模式显然并不能满足人们的对人工智能的期待,那有没有另外一种思路,改变大模型适配下游任务的路线,而是反过来让任务适配大模型,采用统一的模式处理不同任务呢?
@cw
有,以openAI为代表走了另一条路,通过构造合适的提示词(prompt)来适配大模型做不同的任务,做一个“全才”,以具有创造性的生成式模型(GPT)为例,可以把具体问题变成大模型的文字接龙的方式来激发模型完成任务。例如:一个情感分析问题:給大模型输入:I love this movie. It is [MASK],它很自然的基于学习到的知识补全为good,这样再将good这样的标签映射(Verbalizer)为“positive”,这样就完成情感分析,整个过程无需修改模型参数,大模型一直在做自己擅长的文字接龙。
两条路线比较起来,前者直接简单,效果还不错,缺点是需要设计不同的下游任务适配,且需要大量标注数据针对性训练,而后者却希望将下游任务统一为一种模式, 通过提示词学习(prompt learning,也可叫做in-context learning)仅需少量(几条到几十条)数据(few-shot)或者无需数据(zero-shot)的数据高效的做法(data-efficent)完成各种下游工作。
在T0模型 上训练了三类任 务,在执行第四类任务时,它仍然可以给出预期
更为疯狂的是,希望在微调阶段,通过给予任务指令样例进行监督学习(instruct tuning),便事大模型能以zero-shot的方式回答用户,甚至能够读懂样例中未出现的新指令类型(泛化性),并正确生成答案。早期大家一度对这一想法的实现可能性抱有怀疑,加之早期GPT模型因为参数量不足,表现也不尽如人意,故而,更多人研究前者,后者并不火热。
黄色为训练的任务类型,绿色是泛化后可执行的类型
而今年chatGPT的出现,之前认为疯狂的想法变成了现实,大家也认识到这一路线的潜力,跑步进入AI 2.0时代。 就微调本身,bert为代表的专才考虑的还是如何解决具体的任务时,而以GPT为代表的通才已经在考虑如何读懂指令和执行,以更符合人类需求,这种理念层次上的差距似乎如“枪炮”与“弓箭”之别 。
FineTune的挑战
1750亿参数的chatGPT的到来,还带来了一个一致的认知,就是发现把模型越做越大,是有可能让模型产生原来想象不到的智能涌现。于是,大模型的军备竞赛拉开帷幕,模型越来越大,原来的全量参数finetune的方式越来越行不通。
@huggingface
对于bert这类专才路线的大模型随着模型变大,也会出现下面的问题:
1)每一个特定的任务都需要全量更新所有参数,参数量越来越大,需要大量的算力和时间。
2)每一个特定的任务都有一个模型,模型越来越大,太占空间。
3)每一类任务都需要准备大量标注数据用来训练。
类GPT模型Finetune
那GPT这样走通才路线的模型,通过prompt learning对齐模型和用户,那finetune还有必要吗?或者finetune能够起什么作用?
如上面所讲,我们的最初目标就是对齐用户期望和模型能力。在finetune阶段,要教给模型的不简单是知识,还要教给他以什么样的模式回复用户,比如,我们常看到chatGPT这类产品在回答时有一定套路和模式。而这种模式就需要在finetune中完成。 因此, 微调在现阶段十分有必要。
尽管对于 经过微调甚至强化学习后的 GPT产品来讲,具备了很多能力,对话,翻译等等,也可以通过prompt tuning来完成大部分工作,但是,对于一些实际场景,大模型的通用能力是不够的。仍然需要它对某个领域的理解并扩展能力,比如对专业问题的回答能力(比如一些行业黑话和输入模式)。通过指令微调 不仅能够更好地识别输入的意图,达到更泛化的指令遵从性,提升zero-shot条件下的性能(即在不给示例的情况下,一样能够理解用户指令,返回符合预期的答案),还可以将这些领域积累的答案注入到模型,也能够获得更高质量的结果。
多说一句,一般指令数据集都是手工构造的,为了简化这一工作,斯坦福大学有一项新的研究,尝试让AI“自举”。
自举
在计算机科学中,自举是一种自生成编译器的技术——也就是,某个编程语言的编译器(或汇编器)是该语言编写的。最初的核心编译器(自举编译器)是由其他编程语言生成的(可以是使用汇编语言),之后的编译器版本则是使用该语言的最小子集编写而成。自生成编译器的编译问题被称为编译器设计的先有鸡还是先有蛋问题,而自举则是这个问题的解决方法。
https://arxiv.org/pdf/2212.10560
通过少量种子指令,然后通过openAI的text-davinci-003模型生成指令数据,利用这些机器生成的指令数据基于llama模型(未经指令微调)finetune出Alpaca模型,其效果在少量微调数据的情况下,就获得了很大的性能提升,媲美text-davinci-003模型,不仅体现finetune的价值,而且让人们看到了AI的巨大潜力。
另外,因为finetune时领域背景知识的注入,也使得不用每次都提交prompts中携带背景信息,从而解决现阶段token限制问题以及获得更快的模型响应。
finetune对GPT类模型是如何起作用的?个人的猜想是利用instruct tuning改变原本预训练模型中的既有的概率分布,强化了预期格式和内容的影响,从而更好的对齐用户。举一个例子,对于一个普通人“羊驼“对应的就是”草泥马“,而对于大模型开发者来讲脑子里闪现的便是一个”大模型“。当然,这种概率影响也可以通过预训练施加到模型中。但为什么在如此少的样本,这么大参数模型下也依然敏感,确实很神奇,欢迎理解其中原理的朋友留言探讨。
可以看到,不管是通才模型还是专才模型,都有微调模型的需要,在下一节中,我们将介绍在模型规模不断增大的今天,如何微调一个大模型的基本理论-参数高效微调(PEFT)。
未完待续...
合集目录:
