Prompt工程还是SFT微调?剖析企业应用中优化大语言模型输出的两种方案

技术

Summer

picture.image

picture.image

点击上方

蓝字 关注我们

picture.image

本文约 6200 字 预计阅读时间 15 分钟

我们在使用大语言模型(LLM)的过程中应该都遇到过这样的困惑:模型很多时候并不总能输出你期望的结果。这里面有的是大模型的“知识盲区”导致的“幻觉”问题,有的是大模型不能很好的遵循你的“指令”。这些问题在企业应用中会尤其突出,这源自于企业应用对输出确定性的要求以及应用环境的复杂性。特别是在构建类似AI Agent(自主AI智能体)应用时,作为智能体“大脑”的LLM,很多时候我们需要更准确与稳定的输出,以降低智能体的出错概率。

picture.image

那么如何提高大语言模型针对特定行业与场景输出的适应性、准确性及时效性呢?常见的解决方案是提示工程(Prompt Engineering )与微调(SFT)。本文将 一起来了解这两种方案及选择策略,我们不会专注某些技术或算法细节,仅希望在产品与架构层面形成一定的指导与建议。

我们首先用一个简单的比喻来形成一个初步印象:

picture.image

如果LLM比作一个学习了很多知识的小孩,正在参考一个考试,那么

  • Prompt工程:在考试时向他提供足够的背景/相关信息,并要求他用自己的语言和推理,结合提供的信息,来得出答案。

  • SFT微调:在考试前一天对他进行了辅导,使他成为了某个领域的专家,然后来回答问题,但是付出的代价可能是降低他在其他方面的技能。

picture.image

picture.image

picture.image

提示工程Prompt Engineering

【Prompt是什么】 不要把Prompt简单与我们使用chatGPT的一个提问对等 。Prompt可以简单的理解成是给大模型(不仅是语言模型)的指令。它可以是一个问题、一段文字描述,可以携带参数,未来甚至可能含有多模态内容。大模型会基于 prompt 的信息输出响应内容。一个好的Prompt通常由指令、上下文、输入数据、输出格式等部分组成,越明确越好。

picture.image

【Prompt工程】不要简单地认为让AI模仿李白和你对话就是Prompt工程Prompt工程是针对于Prompt进行结构、内容等维度进行优化的AI技术,进而更好地引导与控制模型的输出。 通过提供清晰和具体的指令,引导模型输出生成高相关、高准确且高质量的响应内容。这是大模型应用领域的一个重要技术工程。

【为什么重要】 一些套壳的个人AI助手上 很多类似的“角色模拟”,“专家扮演”等功能,其实就是简单的预设提示词工程。但是在企业应用场景中,很多时候需要精确控制大模型的输出时,提示工程会比我们想象的要复杂。 一些常见的高阶Prompt提示技巧包括:

  • 少样本提示
  • 思维链提示
  • 自一致性提示
  • 头脑风暴提示
  • 知识增强提示
  • 知识反刍提示

我们介绍在企业应用或AI Agent中常见的两种Prompt工程模式。

01

思维链提示(Chain Of Thought)

简单的说, 思维链提示就是给 LLM 提供一些思考的中间过程,让大模型来学会思考并解决问题的步骤。思维链又可以分为零样本思维链与少样本思维链 ,区别仅在于是否提供一些参考的“样例”。 思维链的核心是为了提高模型解决复杂推理问题的能力,包括但不限于符号推理,数学问题,决策规划等等。COT让模型在得到结果前,模拟人类思考推理的过程生成中间的推理步骤。

思维链提示在一些AI智能体构建中的具体落地模式常见的有两个,一种叫ReAct(推理与行动),一种叫Self Ask(自我提问)。

【ReAct提示框架】 这个提示 框架要求LLM以一种固定的模式来“思考”后输出结果,配合相应的工具(Tool)使用后,可以实现自动完成的输入任务,比如实现一个AI销售助理,甚至在线订购一个披萨。

picture.image

一个典型的ReAct提示模板如下:


      
 【.........前置提示,扮演角色/可用工具/输出格式要求等........】
 
      
   

 
      
 
  `请遵循以下的格式进行一步一步的推理并回答问题:===========`
 
 
  `Question: 我需要回答的问题Thought: 回答该问题我是否需要使用工具Action: 【可用的一个工具名字】Action Input: 【该工具的输入内容】Observation: 【该工具上次的调用结果】...(以上的思考/行动/输入/观察可以重复迭代N次)Final Answer: 最终输出答案`
 
 
      
 
  `============`
 
 
      
 
  `开始吧!`
 
 
      
 
  `输入问题:{question}`
 
 
 
 
 
    

【Self-Ask提示框架】 另外一种提示框架叫Self- Ask, Self Ask提出了一种把问题拆解成子问题的Prompt范式,简单的说,就是提示AI在每一步通过自我提问生成子问 题,并进行回答或者使用工具获得结果,然后根据这一步的结果进一步自我提问, 直到获得答案。比如 问题: 美国公开赛卫冕男子冠军的家乡是哪里? LLM的推理过程可能是这样的(中途需要调用搜索工具并获得反馈)

picture.image

一个典型的Self-Ask提示** 模板如下:**

【.........前置提示,扮演角色/可用工具/输出格式要求等........】

请参考如下的推理格式并回答问题:

==============

问题: Who lived longer, Muhammad Ali or Alan Turing?

是否需要提出子问题: Yes.

子问题: How old was Muhammad Ali when he died?

子问题答案:Muhammad Ali was 74 years old when he died.【此处调用工具获得答案】

下一个子问题:How old was Alan Turing when he died?

子问题答案: Alan Turing was 41 years old when he died.

得出最终答案: Muhammad Ali

==========

输入问题: {input}

02

知识增强(检索)提示

增强检索提示就是在提示的时候带入更多的知识信息,从而更好的引导大模型给出答案(帮助大模型补充或者回忆)。

我们听的比较多的私有知识库+LLM的方案,本质上就是这种知识增强提示的一种。 即利用私有知识库来提高prompt的信息量,这里的私有知识库需要embedding模型进行向量化存储与检索,用来降低输入的知识块大小。具体的方案我们在之前的文章做过介绍,此处不过多展开。

picture.image

另外还有一种提示方式,就是在构建Prompt的时候,让LLM先自行产生一些相关的知识和事实 ,再把这些知识和原生问题一起输入给大模型。形象的说,就是“帮助大模型先回忆出一些相关的知识“,毕竟大模型有时候会由于掌握了太多知识容易“健忘“。

以上就是我们对在企业应用/AI Agent中常用的提示工程模式及其实现的介绍。了解他们背后的思想,有助于我们优化LLM的输出。

对于高阶提示工程的研究,除了阅读相关的论文外(文末列表),也可以阅读知名LLM开发框架LangChain的部分源代码,可以更好的理解其应用。其中包含了众多实现了各种提示工程的组件,如Zero-shot Agent,ReAct Agent,Sef-ask-chain等。

picture.image

picture.image

微调(Supervised Finetuning)

【微调(Fine Tuning)基础】 下图是OpenAI公司在Microsoft Build大会上介绍GPT架构的大语言模型的训练路线图,我们可以通过这张图了解到一个发布使用的大语言模型的训练通常会有几个阶段:

picture.image

预训练阶段: 整个过程中最复杂的阶段,像chatGPT这样的模型在预训练阶段通常需要数千个GPU,在海量的无标记的数据上训练数月来完成,这一阶段其实占用了全部阶段的99%的时间成本。预训练输出的模型一般叫基座模型,基座模型有的会发布(比如开源的LLaMa),有的不会发布(比如GPT-4)。

picture.image

picture.image

基座模型本身也是可以直接使用的,但基座模型通常不是一个“回答问题”的模型,而是一个“补全文档”的模型。如果你想让基座模型来回答问题,你必须假装在输出一个文档,然后让他来“补全”。比如你必须提示“下面是一首赞美祖国的诗歌:”,然后让模型来补全;而不能直接要求“写一首赞美祖国的诗歌”。那么如何让基座模型变成一个交互式的AI助手呢?那就需要进入后面的阶段:微调。

picture.image

微调&RLHF: 宏观上可以把后面的阶段都归到微调的范畴,即包括受监督微调、奖励模型+RLHF人类反馈强化学习的阶段。简单的说,这阶段就是对基座模型在少量(相对预训练的数据量来说)的、已标注的数据上进行再次训练与强化学习,以使得模型更好的适应特定的场景与下游任务。比如:

  • 强化某个方面的应用能力(比如利用大语言模型进行情感检测)
  • 适应特定的使用场景(比如针对人类对话,输出无害安全的内容)
  • 适应特定的知识领域(比医疗或法律行业,特定术语/语义)
  • 针对某些可标注数据相对稀缺的任务进行适应
  • 适应特定的语言输出要求(比如适应某个场景的语言风格)

相对于预训练阶段,微调对算力的要求与成本都大大降低,这也使得微调对于大部分企业在成本与技术上是可行的。

微调的类型与工具: 大模型微调是一个十分专业的技术课题,涉及到较多底层的深度学习架构、参数以及算法知识,本文无意对此展开。我们只需要知道目前大模型的微调的主要类型有全量微调、Prompt Tuning,Prefix Tuning,P-tuning V2,Lora等不同的方法,不同的方法对资源与成本、指令数据等有不同的要求,当然达到的效果也不一样。另外,也有一系列实现了这些微调算法的工具与框架可以使用:

  • OpenAI针对chatGPT提供的在线微调API
  • 重量级的大模型并行训练框架Deepspeed、colossal AI
  • 百度的文心千帆云大模型训练平台
  • 阿里的魔搭平台的SFT工具
  • FireFly开源微调项目等。

【微调的挑战】 在实际应用中我们发现, 相对算力与算法有成熟的平台与工具,而 最无可替代的任务反而是一定规模的高质量数据集的生成与标注,特别是垂直行业。 这通常 由大量的指令/输出的样本来组成,即Prompt+Response,通过这样类似QA问答的数据让大语言模型来学习其中的模式与知识,从而胜任特定领域的任务。

picture.image

对于一些行业特征特别突出的垂直领域,数据集的准备是最大的挑战。这些挑战主要来自于:

  • 数据从哪里采集,又如何确保专业性与有效性
  • 多形态的数据如何清洗与归一
  • 数据的提示、输入、输出等怎么标注
  • 数据过期处理,即变化后又如何反馈到大模型

这里面一部分需要使用大规模人工,一部分也建议借助技术手段:

  • 使用已有的AI大模型帮助进行数据清洗
  • 利用Self-Instruct帮助生成微调指令集

picture.image

picture.image

用微调替代或增强提示工程

大模型微调(SFT)的一个事实是:你在 Pormpt Engineering做的很多工作是可以通过微调给大模型注入知识以增强其响应能力来实现的 。毕竟大模型本身就是在大量的Prompt与响应基础上训练与学习而来,你的Prompt工程的指令数据完全可以拿过来进行SFT训练。

比如你在提示中给予大模型的样本,可以作为大模型SFT的输入一部分。

picture.image

图片来自OpenAI公司Microsoft Build大会演讲

我们对上面的几种提示工程做简单分析,看看微调在哪些方面对提示工程具有替代性或者进行辅助增强:

【知识增强提示】 很显然,你 完全可以对这些本地增强的知识做数据清洗与标注,然后通过SFT微调来让大模型学习 ,提高其对您私域知识的指令泛化能力,一劳永逸的达到目的。

picture.image

【思维链模式提示】 思维链模式的提示工程更多体现在AI Agent运行过程中的任务规划与自我执行。其中很重要的一个能力是对工具Tool调用的输出,也就是要让LLM来根据自然语言来决策何时调用工具、调用哪个工具、以及这个工具的输入信息。在实际使用中测试,我们会发现,通过提示工程(ReAct或者Self Ask)的实现,存在以下局限:

  • 对于简单的需求理解比如搜索,工具转换准确率较高;但对于一些复杂的工具输入,产生工具调用错误的概率较高
  • 工具的数量受限制,如果太多的工具及说明书临时交给LLM来决定,一方面会干扰大语言模型的判断,特别是在工具的“说明书”比较模糊的情况下;此外,过多的工具也会受到上下文窗口大小的限制。

因此,对于LLM的工具调用的输出能力,也可以使用大量的样本进行指令微调: 使用大量的自然语言输入与API调用规格作为指令与输出的样本进行训练 ,使的大模型在工具调用的准确率上有较大的增强。

我们看一个最近的样例:微软推出的 Gorilla模型 ,是一个针对API调用的大模型,通过自然语言输入,输出API调用建议,目前支持约1600多个不同平台的API。通过这个模型,可以用来大大降低AI Agent在工具使用方面的错误率。

picture.image

picture.image

picture.image

如何选择提示工程或者微调?

提示工程(Prompt Engineering)与微调(SFT)是调整大语言模型输出的两种技术手段。 在实际应用中, 需要根据自身的场景、条件(数据、技术能力、算力等)、测试结果(指令理解性、输出稳定性等)等来选择使用不同的方案。

picture.image

同大部分的IT技术选择一样,无论是微调模型,还是基础LLM+Prompt,都必然有着自身的优点,也对应会有一定的代价,我们做一个简单的对比:

提示工程

优点:

  1. 使用更灵活,可随时根据需要调整Prompt以获得期望输出

  2. 技术上更简单

  3. 可以通过知识增强的Prompt让大模型立即适应领域知识

  4. 无额外的训练成本

挑战:

  1. 容易受限于上下文窗口的长度(token限制)

  2. 本地知识增强Prompt在实现上下文连续对话时较为困难

  3. 大模型输出的不确定性在高准确性的场景下会带来失败概率

  4. 较长的Prompt带来较高的推理成本(token量大)

  5. 随着模型的迭代,可能需要重新调整Prompt

VS

微调

优点:

  1. 模型自身即拥有特定知识输出能力,或适应特定的输出格式

  2. 对下游应用更友好,特定的任务上使用更简单

  3. 可以节约推理使用的token,推理成本更低

挑战:

  1. 非开箱即用

  2. 需要额外的数据准备、标注、清洗成本;以及必要的算力与训练成本

  3. 需要足够的技术专家,特别是ML专家、数据专家

  4. 微调无法阻止幻觉,过度微调甚至可能导致某些能力下降

  5. 模型迭代周期长,对实时性高的数据不适用

无法确切的说,在什么场景下必须使用Prompt Engineering,什么场景下必然要微调。结合一些技术专家的研究及普遍的测试结果,我们建议在以下的场景上更适合考虑微调(SFT)的方案(不考虑人力资源与成本):

  • 需要较大数据量且相对稳定、迭代周期较长的领域应用知识注入;需要形成一个相对通用的大模型用于对外服务或者运营
  • 具备极高的准确率要求的部分关键任务,且其他手段无法满足要求,此时需要通过高效微调甚至全量微调来提高对这些任务的输出精度,比如医疗诊断
  • 在尝试Prompt提示优化、LLM+私有知识增强提示的技术手段下,无法达到需要的指令理解准确、输出稳定、或其他业务目标

此外的很多场景,建议优先考虑使用基础LLM配合辅助的Promp工程来实现AI能力,当然,在实际应用中且条件允许的前提下, 两者的融合应用,各尽其职或许会是更佳的选择。

【参考文章】

  • Why You (Probably) Don’t Need to Fine-tune an LLM

  • Prompt Engineering Guide

  • Chain-of-Thought Prompting Elicits Reasoning in Large Language Models

  • Multimodal Chain-of-Thought Reasoning in Language Models

  • Automatic Chain of Thought Prompting in Large Language Models

  • Self-Consistency Improves Chain of Thought Reasoning in Language Models

  • Chain-of-thought prompting for responding to in-depth dialogue questions with LLM

  • Think Outside the Code: Brainstorming Boosts Large Language Models in Code Generation

  • Tree of Thoughts: Deliberate Problem Solving with Large Language Models

  • Teaching llms to think and act react prompt engineering

  • Self ask prompting

picture.image

END

点击下方关注我,不迷路

点击下方体验AI助手

picture.image

0
0
0
0
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论