通过实例,来展示如何最好地使用 GPT。
生成文字
假设你在写一篇文章,需要在结尾加上这样一句:「California’s population is 53 times that of Alaska.」(加州的人口是阿拉斯加州的 53 倍)。
但现在你不知道这两个州的人口数据,我们会怎样完成这个任务呢?大致推想,我们会经历一连串的思考过程。
如下图,
1、首先会想到为了得到结果,需要比较人口数量,那么就需要查询人口数据;
2、然后使用查询工具查一下——在维基百科上找到了加州和阿拉斯加的人口数据;
3、接下来显然需要做个除法运算,可能会需要计算器;然后得到倍数结果 53;
4、然后我们的大脑可能会用经验理智快速检验一下 ——53 倍感觉挺合理的,毕竟加州是美国人口最多的州。
5、信息有了之后,就进入了创造性写作的部分。你可能首先会写下:「California has 53x times greater」,然后你想一下感觉又不太合适,又删了重新想哪种表达更合适一点,最终得到你满意的句子表达。
简单来说,为了写这样一句话,你的内心会经历大量独白式的思考。
GPT 在生成这样一句话时又会经历什么呢?
GPT 处理的都是 token 序列。不管是阅读还是生成,它都是按部就班地一块块地进行,其中每一块都是针对一个 token,计算工作量也都一样。这些 Transformer 的层数不少,足有 80 个推理层,其实80 也不是非常多。Transformer 会通过这些来尽力模仿写作,但其思考过程和人类的大不相同。
如下图:
GPT 没有什么内心独白,它只会检视每一个 token 并在每个 token 上投入同等的计算量。
它们就像是 token 模拟器 —— 它们不知道自己知道什么或不知道什么,只是模仿地写出下一个 token;
它们也不会反思,内心不会思考结果是否合理;它们写错了也不会反过来修改。它们只是按序列采样 token。
但是,Karpathy 认为 GPT 依然具有某种形式的认知能力优势,比如它们具备非常广博的事实知识,涵盖许多不同领域,因为它们数以百亿计的参数,足以储存大量事实。
同时它们还有相对来说很大且完美的工作记忆。只要能填入 Transformer 的上下文窗口,它就能通过其内部自注意机制来加以利用。也就是说 GPT 能以无损的方式记住能嵌入其上下文窗口的任何内容。
Karpathy 表示:人类通过 prompt 使用 GPT 的过程本质上是大脑和 LLM 这两种不同的认知架构互相配合的过程。
用 GPT 执行推理
再来看 Transformer 在实践中表现相当好的一种用例:推理。
如果只有单个 token,当然不能指望 Transformer 推理出什么。推理的执行需要涉及更多 token。
比如,你不能向 Transformer 提一个非常复杂的问题,然后指望它通过单个 token 就找到答案。Transformer 需要通过 token 来「思考」。
如下图,输出结果中看到 Transformer 为了解答问题而进行的「思考」。如果你提供了一些示例(上方) ,那么 Transformer 就会模仿那个模板,结果看起来相当不错。
当然,你也可以通过说「Let’s think step by step」(请按步骤解答)引导 Transformer 给出类似的输出 —— 这在某种程度上展示了其工作过程。
而且由于它有点像是进入了工作过程展示模式,那么其在每个单独 token 上投入的计算量就会少一点。这样一来,它执行的就是一个速度更慢的推理过程,也就更可能成功得到正确答案。
再看下例。人类写作时会写不好,类似地,Transformer 在选择下一个 token 时可能会出错,但不同于人类可以及时停下进行修改,Transformer 会继续生成,一错到底,最终得到错误答案。
类似于人类写作时没写好可以重来一样,Transformer 也可以多次采样,然后我们可以使用某个过程找到其中较好的。这被称为自我一致性(self-consistency)。通过让模型反思(reflection),可以发现模型其实能知道自己出错了。
如下图,如果让 GPT-4 生成一首不押韵的诗然后它生成的诗却押韵了。然后你只需要问它「你完成任务了吗?」它就会知道自己没有完成任务,然后为你重新完成任务。
但如果你不给出那样的 prompt,它就不知道自己错了。它并不会自己去回顾,毕竟它只是一个 token 模拟器。你必须通过 prompt 让它回顾。
Karpathy 表示,可以按照目的将 AI 模型分为两种:一类系统(System 1)和二类系统(System 2)。
-
一类系统的处理过程速度快并且是自动化的,对应于只是采样 token 的大型语言模型。
-
二类系统的速度慢一些,会反复思考进行规划。
现在有很多人在通过设计 prompt 来让 LLM 表现出类似人类大脑的思维过程。
如下左图 (d) ,这是近期一篇论文提出的 Tree of Thought(思维树)。该论文提出为任意给定 prompt 维持多个完成结果,然后对这些结果进行评分,保留得分较好的结果。
要做到这一点,不只要用一个 prompt,而是需要用 Python Glue 代码将多个 prompt 组合到一起。这实质上是维持多个 prompt,还需要执行某个树搜索算法来找到可扩展的 prompt。可以说这是 Python Glue 代码与各个 prompt 组成的共生体。
Karpathy 在这里类比了 AlphaGo。AlphaGo 的每一步都是下接下来的一步棋,其策略的训练方式最初是模仿人类。但除了这个策略之外,它还会执行蒙特卡洛树搜索。
由此造成的结果是,AlphaGo 会在头脑里尝试大量不同的可能性然后对它们进行评估,最后仅保留其中效果好的。思维树就有点像是 AlphaGo 下围棋时的思维过程,只不过处理的是文本。
不只是思维树,现在也有更多人在实验让 LLM 完成比简单问答更加复杂的任务,但很多都像是 Python Glue 代码,将许多 prompt 连接起来。
下图给出了两个例子:
右图:论文提出了 ReAct,研究者是将 prompt 的答案构造成一个思维、动作、观察构成的序列,其中在动作部分,模型还能使用工具。这就像是某种回答查询的思维过程。
左图:是 AutoGPT。这个项目最近有些炒作,但也确实是很有趣的研究。AutoGPT 能够保存一个任务清单并递归式地分解这些任务。目前来说这种做法的效果并不很好,Karpathy 也不建议人们将其用于实际应用,但他表示从研究角度看,这种方法还是很有启发性。
以上就是创造二类系统思维方式的一些研究成果。
Karpathy说到LLM 的另一个有趣现象:「LLM 就好像有种心理怪癖。它们不想成功,只想模仿。」
你想要它给出正确答案,你就要明确要求它。这是因为 Transformer 的训练数据集中数据并不总是正确的,也存在低质量的数据。
举个例子,假如有某个物理问题,数据集中可能有某个学生给出的错误答案,同时也会有某个专家给出的正确答案。而 Transformer 不知道该模仿哪个或者说它都想模仿,毕竟它们的训练目标是语言建模,不是分辨对错。因此在使用和测试时,如果你想要正确答案,你就要明确提出要求。
如下图,论文中,研究者尝试了多种不同的 prompt,发现对于同一问题,不同 prompt 得到的输出结果准确度竟然不一样!
可以看到,如果在 prompt 中明确要求模型一步步推理并给出正确结果,其准确度会高一些,因为这样 Transformer 就不必再为低质量解答分配概率了。
因此,如果你想要正确答案,就大声说出来!
像是在 prompt 中添加「你是某领域的专家」或「假设你的 IQ 为 120」。但是也不要太过了,比如要求模型假设自己的 IQ 为 400,这样的话你的问题可能会超出数据的分布或者虽在分布中但结果却很科幻 —— 这样模型可能就会开始扮演什么科幻角色了。
让 LLM 使用工具 插件
针对具体问题,使用合适的工具往往能事半功倍。对 LLM 来说也是如此。根据具体任务的不同,我们可能希望 LLM 能使用计算器、代码解释器、搜索引擎等工具。
但首先我们需要记住一点:Transformer 默认情况下可能并不知道它们无法做到某些事情。
用户甚至可能需要在 prompt 中明确告知 Transformer:「你不擅长心算,如果要做大数运算,请使用这个计算器,这是使用这个计算器的方法。」你必须明确要求它使用某个工具,因为模型自身不知道自己擅长或不擅长什么。
检索是能极大提升 LLM 性能的重要工具。因为 LLM 是专精于记忆的(memory only),因此专精于检索的搜索引擎能为 LLM 提供极大补充。实践也证明,能使用检索工具的 LLM 的实用性会大大提升。
之前已经提到,Transformer 的上下文窗口就是其工作记忆范围。如果能在其工作记忆中载入与当前任务相关的信息,那么模型的表现就会更好,因为模型能够立即读取所有记忆。实际上用检索增强生成也是很多人感兴趣的课题。
下图,展示了 LlamaIndex,其中有一个连接大量不同类型数据的数据连接器。这个工具可以索引各种数据并将它们提供给 LLM 使用。
现在时兴的做法是:选取相关文档,然后将其分成文本块,再执行嵌入操作,得到表示那些数据的嵌入向量。这些嵌入向量会被保存起来。当使用模型时,我们可以向存储的向量发出查询,从中取用与当前任务相关的文本块。然后将这些文本块加入到 prompt,再让 LLM 生成。这种做法在实践中的效果很好。
这其实与人类完成任务的方法类似。人也可以仅靠自己的记忆做事,但如果能检索到与任务相关的资料,做起事来也自然会更容易。Transformer 虽然记忆广博,但也能从检索中受益。
在 prompt 中添加约束条件
在 prompt 中设定约束条件能迫使 LLM 按特定模板输出结果。
如下图:微软帮助用户更好使用 LLM 的 Guidance 工具,可访问https://github.com/microsoft/guidance 。
这个例子中,LLM 输出的结果会是 JSON 格式。这是可以得到保证的,因为 prompt 会调整 Transformer 输出不同 token 的概率,而这些 token 的输出位置受限了,即只能填补文本中的空缺位置。这样就实现了对文本留空处的严格限制。带约束条件的采样对某些任务来说非常有用。
微调
通过设计 prompt 能让 LLM 模型完成更多不同任务,但我们其实也能通过微调来做到这一点。
对模型进行微调是指改变模型的权重分布。这种事情做起来不难,因为现在已经有 LLaMA 等开源的大模型以及一些用于微调的软件库。
如:LoRA 等参数高效型微调技术让用户可以仅训练模型中少量稀疏的部分。使用该技术时,基础模型的大部分都保持不变,而某些部分可以变化。
实践中,这种技术用起来很不错,能让人以很低的成本对模型做少量调整。同时,因为模型大部分都是固定不变的,所以可以使用非常低精度的推理来计算那些部分,因为梯度下降不会更新它们。
由此,整体的微调效率就能非常高。
不过,微调需要专业技术,而且多半还需要相应的专业领域知识,毕竟不管是雇佣人类专家来编写数据集还是通过自动方法合成数据都非常复杂,而这也会拉长迭代周期。
另外,对用户来说,监督式微调(SFT)还是可以做到的,因为这其实就是继续执行语言建模任务;但 RLHF 是还需进一步研究的课题,实现难度就大多了,因此不建议初学者来做。
Karpathy 的 GPT 使用建议
为了帮助人们更好使用 GPT,Karpathy 给出了一些建议。
在使用 GPT 来完成任务时,可以将任务分成两个部分:一,取得最佳结果;二,依照指定顺序优化结果。
如图:
对第一部分,首先是选模型,目前最强的模型是 GPT-4。
有了模型后,当执行具体任务时,你需要把 prompt 设计得足够详细,其中要包含任务的背景、相关信息和说明。你要想一想人类会怎么完成这一任务,但你同时也要明白人类有内心独白、能够自省,LLM 却不行。了解 LLM 的工作方式对设计 prompt 大有裨益。
你可以检索一些相关背景和信息并将其添加到 prompt 中。网上已有不少人分享过相关经验和技术。
你不用急于让 LLM 一步到位完成你的任务。可以多做几次实验,测试一下各种可能性。你可以向 LLM 提供一些例子,让它真正理解你的意图。
对于原生 LLM 难以解决的问题,可以将其交给工具和插件处理。你要想想如何将工具整合进来,这当然无法通过单个 prompt 问答就可以解决。你需要多做几次实验,实践出真知。
最后,如果你成功搞出了适合自己的 prompt 设计方案,你可以再继续坚持一下,看看可以如何对模型进行微调以更好地服务你的应用;但要明白微调模型的速度会更慢,也需要投入更多。
对于想要使用 RLHF 的研究型专家来说,虽然如果真能用起来,RLHF 目前是会比 SFT 好一些,但成本也会更高。为了节省成本,探索性研究可以使用性能更低的模型或更短的 prompt。
Karpathy 强调:用 LLM 解决用例时可能会出现一些问题,比如结果可能有偏见、编造出幻觉信息、推理错误、无法理解应用类型(比如拼写相关任务)、知识隔断(GPT-4 的训练数据截止于 2021 年 9 月)、可能会被攻击(比如 prompt 注入攻击、越狱攻击、数据毒化攻击)……
建议用户目前仅在低风险程度的应用中使用 LLM 并且要搭配人工监督一起使用。LLM 可以作为灵感和建议来源,让它们辅助我们而不是完全自主地替代我们工作。
Karpathy 在总结时说:「GPT-4 是了不起的造物。我很感激它存在于世而且它很美丽。」它具有非凡的能力,能帮助用户解答疑问、编写代码等等。围绕它的生态系统也正在蓬勃发展。
Karpathy 问 GPT-4 的问题
Karpathy 向 GPT-4 提了一个问题:「如果要激励 Microsoft Build 2023 的观众,你会说点什么?」
GPT-4 给出了如下回答:
把ChatGPT 将这段话翻译成成中文,它是这么说的: