Skip to main content

2 posts tagged with "GPT"

View All Tags

· 12 min read
Yiran Wu

MathChat 工作流程 简要总结:

  • 我们介绍了MathChat,一个利用大型语言模型(LLMs),特别是GPT-4,来解决高级数学问题的对话框架。
  • MathChat提高了LLM在挑战性数学问题解决方面的性能,比基本提示和其他策略高出约6%。在代数类别中,准确性特别提高了15%。
  • 尽管有所进步,GPT-4在解决非常具有挑战性的数学问题上仍然存在困难,即使采用有效的提示策略。还需要进一步改进,例如开发更具体的助手模型或集成新工具和提示。

最近的大型语言模型(LLMs),如GTP-3.5和GPT-4,在各种任务上展示了惊人的能力,例如文本生成、问题回答和代码生成。此外,这些模型可以通过对话与人类交流并记住之前的上下文,使人类更容易与它们互动。这些模型在我们日常生活中扮演着越来越重要的角色,帮助人们完成不同的任务,如写电子邮件、总结文件和编写代码。

在这篇博客文章中,我们探讨了LLMs的问题解决能力。具体来说,我们对它们解决高级数学问题的能力感兴趣,这可能代表了一类需要精确推理并且有确定性解决方案的更广泛问题。

我们介绍了MathChat,一个为了与LLMs一起解决挑战性数学问题而设计的对话框架。这个框架利用了最先进LLMs的聊天优化特性,其中用户代理和LLM助手共同努力解决数学问题。我们还测试了之前的提示技术进行比较。

MathChat框架

MathChat模拟了LLM助手和用户代理之间的对话。顾名思义,用户代理充当用户的代理,负责与LLM助手通信并以期望的方式继续对话。

代理首先向LLM助手提出一个数学问题,由一个初始提示框架出来,指导助手如何协作解决问题。我们在初始提示中融入了现有的提示方法,如CoT(思维链)和使用工具的提示。提示的关键组成部分包括:

  • 使用工具的提示: 这指导LLM助手使用正确格式的Python代码来解决问题,允许用户代理解析代码并提供适当的结果。

  • 问题解决策略选择提示: 助手被指示选择三种潜在问题解决策略之一,包括:

    1. 编写Python程序直接解决问题。
    2. 不使用Python直接解决问题,这锻炼了LLMs的内在推理能力。
    3. 使用Python逐步解决问题。当前两种策略不适用时应使用此策略。
  • 最终答案封装提示: 这部分指导助手将最终答案放在 \boxed{} 中。

MathChat的提示设计灵活,可以轻松地细化以包括其他工具,如Wolfram Alpha。

让我们看一个例子,介绍用户代理LLM助手(GPT-4)之间的对话。对话集中在如何使用Python解决不等式。 (对话已修改以便阅读。)

参与者对话
用户代理(初始提示: 让我们用Python解决一个数学问题...) 问题:找到所有满足不等式 (2x+10)(x+3) < (3x+9)(x+8) 的x。用区间表示法表达你的答案。
LLM助手解决这个问题的关键思路是找到临界点,这些是不等式相等的点。然后测试临界点之间的区间,找出不等式成立的区间。
LLM助手(继续)这是找到临界点的Python代码:from sympy import symbols, Eq, solve; x = symbols("x"); lhs = (2*x + 10)*(x + 3); rhs = (3*x + 9)*(x + 8); equation = Eq(lhs, rhs); critical_points = solve(equation, x); critical_points
用户代理临界点是:[-14, -3]
LLM助手我们发现临界点是x = -14和x = -3。现在我们将测试这些临界点之间的区间,以及临界点之前和之后的点。区间是:x < -14, -14 < x < -3, x > -3。
LLM助手(继续)这是测试每个区间不等式的Python代码:from sympy import symbols; x = symbols("x"); inequality = (2*x + 10)*(x + 3) < (3*x + 9)*(x + 8); test_points = [-15, -5, 0]; intervals = []; for point in test_points: if inequality.subs(x, point): intervals.append(point); intervals
用户代理不等式成立的区间是测试点:[-15, 0]

| LLM

助手 | 我们已经测试了区间并发现不等式对于:1. x < -14 (测试点:-15) 2. x > -3 (测试点:0) 是成立的。因此,不等式 (2x+10)(x+3) < (3x+9)(x+8) 的解是 x ∈ (-∞, -14) ∪ (-3, ∞) |

实验设置

我们评估了MathChat带来的改进。

对于实验,我们专注于MATH数据集中的5级问题,这些问题由高中竞赛问题组成。这些问题包括定理的应用和复杂方程的推导,即使对于本科生来说也是具有挑战性的。我们评估了数据集中的6个类别中的7个(几何除外):初等代数、代数、数论、计数与概率、中级代数和预备微积分。

我们评估了GPT-4并使用了OpenAI API的默认配置。为了访问最终性能,我们手动将最终答案与正确答案进行比较。对于普通提示、程序合成和MathChat,我们让GPT-4将最终答案放在 \boxed{} 中,并将PoT函数的返回作为最终答案。

我们还评估了以下方法进行比较:

  1. 普通提示: 评估GPT-4的直接问题解决能力。使用的提示是:"仔细解决问题。将最终答案放在 \boxed{} 中"

  2. 思维程序(PoT): 使用零次射击PoT提示,要求模型创建一个Solver函数来解决问题并返回最终答案。

  3. 程序合成(PS)提示: 像PoT一样,它提示模型编写一个程序来解决问题。使用的提示是:"编写一个程序来回答以下问题:{问题}"

实验结果

下面显示了使用不同方法从MATH数据集的不同类别中难度为5级的所有问题的准确性:

结果

我们发现,与展示GPT-4内在能力的基本提示相比,将Python用于PoT或PS策略的上下文中提高了大约10%的总体准确性。这种增加主要出现在涉及更多数字操作的类别,如计数与概率和数论,以及更复杂的类别,如中级代数和预备微积分。

对于代数和初等代数等类别,PoT和PS显示出的改进很小,在某些情况下,甚至导致准确性下降。然而,MathChat能够相比PoT和PS提高总体准确性约6%,在所有类别中显示出竞争性能。值得注意的是,MathChat在代数类别中的准确性提高了约15%,超过了其他方法。注意,像中级代数和预备微积分这样的类别对所有方法来说仍然是挑战,只有大约20%的问题被准确解决。

实验的代码可以在这个仓库找到。 我们现在提供了使用AutoGen中的交互式代理的MathChat实现。参见这个笔记本以了解示例用法。

未来方向

尽管MathChat在先前方法上有所改进,但结果显示,即使在外部工具的帮助下,复杂的数学问题对于最近强大的LLMs,如GPT-4,仍然是一个挑战。

可以进行进一步的工作来增强这个框架或一般的数学问题解决:

  • 虽然使模型能够使用像Python这样的工具可以减少计算错误,但LLMs仍然容易出现逻辑错误。像自我一致性(采样多个解决方案并对最终答案进行多数投票)或自我验证(使用另一个LLM实例检查答案是否正确)的方法可能会提高性能。
  • 有时,LLM能否解决问题取决于它使用的计划。一些计划需要较少的计算和逻辑推理,从而减少了错误的空间。
  • MathChat有潜力被改编成一个副驾驶系统,这可以帮助用户解决数学问题。这个系统可以允许用户更多地参与解决问题的过程,可能增强学习。

进一步阅读

您是否正在从事涉及数学问题解决的应用?您是否需要在LLM-based代理用于数学问题解决的应用上额外的研究或支持?请加入我们的Discord服务器进行讨论。

· 12 min read
Chi Wang

在编码成功率和推理成本上,使用GPT-3.5和GPT-4的自适应方式优于单独使用GPT-4

简而言之:

  • 使用HumanEval基准测试案例研究表明,通过自适应使用多个GPT模型,可以在编码方面实现更高的准确性(从68%提高到90%)和更低的推理成本(降低18%),而不是单独使用GPT-4。

GPT-4是基础模型能力的一个重大升级,例如在代码和数学方面,伴随着使用代价的大幅提升(超过10倍)相比于GPT-3.5-Turbo。在OpenAI开发的代码完成基准测试HumanEval上,GPT-4可以成功解决68%的任务,而GPT-3.5-Turbo则为46%。通过生成多个响应或进行多次调用,可以进一步提高GPT-4的成功率。然而,这将进一步增加成本,而且API调用率限制更为严格,成本已经近乎使用GPT-3.5-Turbo的20倍。我们能否用更少的资源做到更多?

在这篇博客文章中,我们将探索一种创造性的自适应使用GPT模型的方法,这将带来一个巨大的飞跃。

观察

  • GPT-3.5-Turbo已经可以解决40%-50%的任务。对于这些任务,如果我们从不使用GPT-4,我们可以节省近40-50%的成本。
  • 如果我们使用节省下来的成本在剩余未解决的任务上用GPT-4生成更多响应,有可能在保持平均成本降低的同时解决更多任务。

利用这些观察的障碍是,我们事先不知道哪些任务可以由更便宜的模型解决,哪些任务需要更昂贵的模型解决,以及哪些任务需要支付更多给昂贵的模型。

为了克服这个障碍,人们可能想要预测哪个任务需要哪个模型来解决,以及每个任务需要多少响应。让我们看一个代码完成任务的例子:

def vowels_count(s):
"""Write a function vowels_count which takes a string representing
a word as input and returns the number of vowels in the string.
Vowels in this case are 'a', 'e', 'i', 'o', 'u'. Here, 'y' is also a
vowel, but only when it is at the end of the given word.

Example:
>>> vowels_count("abcde")
2
>>> vowels_count("ACEDY")
3
"""

我们能预测GPT-3.5-Turbo是否能解决这个任务,还是我们需要使用GPT-4吗?我的第一反应是GPT-3.5-Turbo可以做对,因为指令相当直接。然而,事实证明,如果我们只给它一次机会,GPT-3.5-Turbo并不总是能做对。如何在不实际尝试的情况下预测性能是一个有趣的研究问题。

我们还能做什么?我们注意到: 验证给定解决方案比从头开始找到正确解决方案“更容易”。

文档字符串中提供了一些简单的示例测试用例。如果我们已经有了一个模型生成的响应,我们可以使用这些测试用例来过滤错误的实现,并使用更强大的模型或生成更多响应,直到结果通过示例测试用例。此外,这一步骤可以通过要求GPT-3.5-Turbo从文档字符串中给出的示例生成断言语句(一个我们可以下注的更简单的任务)并执行代码来自动化。

解决方案

结合这些观察,我们可以设计一个包含两个直观想法的解决方案:

  • 利用自动生成的反馈,即代码执行结果,来过滤响应。
  • 逐一尝试推理配置,直到一个响应能通过过滤。

设计

这个解决方案在不知道或预测哪个任务适合哪种配置的情况下自适应工作。它简单地逐一尝试多种配置,从最便宜的配置开始。注意,一个配置可以生成多个响应(通过将推理参数n设置得大于1)。不同的配置可以使用相同的模型和不同的推理参数,例如n和温度。每个任务返回并评估一个响应。

  1. GPT-3.5-Turbo, n=1, temperature=0
  2. GPT-3.5-Turbo, n=7, temperature=1, stop=["\nclass", "\ndef", "\nif", "\nprint"]
  3. GPT-4, n=1, temperature=0
  4. GPT-4, n=2, temperature=1, stop=["\nclass", "\ndef", "\nif", "\nprint"]
  5. GPT-4, n=1, temperature=1, stop=["\nclass", "\ndef", "\nif", "\nprint"]

实验结果

本博客文章的第一张图显示了与默认GPT-4相比,自适应解决方案的成功率和平均推理成本。推理成本包括在我们解决方案中生成断言的成本。生成的断言并不总是正确的,通过/未通过生成断言的程序并不总是正确/错误的。尽管如此,自适应解决方案可以将成功率(文献中称为pass@1)从68%提高到90%,同时降低成本18%。

以下是一些由不同配置在投资组合中解决的函数定义示例。

  1. 由GPT-3.5-Turbo, n=1, temperature=0解决的:
def compare(game,guess):
"""I think we all remember that feeling when the result of some long-awaited
event is finally known. The feelings and thoughts you have at that moment are
definitely worth noting down and comparing.
Your task is to determine if a person correctly guessed the results of a number of matches.
You are given two arrays of scores and guesses of equal length, where each index shows a match.
Return an array of the same length denoting how far off each guess was. If they have guessed correctly,
the value is 0, and if not, the value is the absolute difference between the guess and the score.


example:

compare([1,2,3,4,5,1],[1,2,3,4,2,-2]) -> [0,0,0,0,3,3]
compare([0,5,0,0,0,4],[4,1,1,0,0,-2]) -> [4,4,1,0,0,6]
"""
  1. 由GPT-3.5-Turbo, n=7, temperature=1, stop=["\nclass", "\ndef", "\nif", "\nprint"]解决的:前面提到的vowels_count函数。
  2. 由GPT-4, n=1, temperature=0解决的:
def string_xor(a: str, b: str) -> str:
""" Input are two strings a and b consisting only of 1s and 0s.
Perform binary XOR on these inputs and return result also as a string.
>>> string_xor('010', '110')
'100'
"""
  1. 由GPT-4, n=2, temperature=1, stop=["\nclass", "\ndef", "\nif", "\nprint"]解决的:
def is_palindrome(string: str) -> bool:
""" Test if given string is a palindrome """
return string == string[::-1]


def make_palindrome(string: str) -> str:
""" Find the shortest palindrome that begins with a supplied string.
Algorithm idea is simple:
- Find the longest postfix of supplied string that is a palindrome.
- Append to the end of the string reverse of a string prefix that comes before the palindromic suffix.
>>> make_palindrome('')
''
>>> make_palindrome('cat')
'catac'
>>> make_palindrome('cata')
'catac'
"""
  1. 由GPT-4, n=1, temperature=1, stop=["\nclass", "\ndef", "\nif", "\nprint"]解决的:
def sort_array(arr):
"""
In this Kata, you have to sort an array of non-negative integers according to
number of ones in their binary representation in ascending order.
For similar number of ones, sort based on decimal value.

It must be implemented like this:
>>> sort_array([1, 5, 2, 3, 4]) == [1, 2, 3, 4, 5]
>>> sort_array([-2, -3, -4, -5, -6]) == [-6, -5, -4, -3, -2]
>>> sort_array([1, 0, 2, 3, 4]) [0, 1, 2, 3, 4]
"""

最后一个问题是原始定义中有错误示例测试用例的一个例子。它误导了自适应解决方案,因为一个正确的实现被认为是错误的,并且进行了更多尝试。最后一个配置返回了正确的实现,即使它没有通过自动生成的断言。这个例子表明:

  • 我们的自适应解决方案具有一定程度的容错能力。
  • 如果使用正确的示例测试用例,自适应解决方案的成功率和推理成本可以进一步提高。

值得注意的是,降低的推理成本是在所有任务上的摊销成本。对于每个单独的任务,成本可能比直接使用GPT-4要大或小。这是自适应解决方案的本质:对于困难任务的成本通常比简单任务的成本要高。

一个运行此实验的示例笔记本可以在以下地址找到:https://github.com/microsoft/FLAML/blob/v1.2.1/notebook/research/autogen_code.ipynb。实验是在AutoGen作为FLAML子包时进行的。

讨论

我们的解决方案使用autogen中提供的通用接口实现起来非常简单,但结果却非常鼓舞人心。

虽然生成断言的具体方法是特定于应用的,但主要思想在LLM操作中是通用的:

  • 生成多个响应以供选择 - 特别是当选择一个好的响应比一次性生成一个好的响应更容易时。
  • 考虑多种配置来生成响应 - 特别是当:
    • 模型和其他推理参数的选择影响效用成本权衡;或者
    • 不同配置有互补效应。

之前的博客文章提供了这些想法在解决数学问题中也是相关的证据。 autogen使用一种技术EcoOptiGen来支持推理参数调整和模型选择。

在研究和开发中有许多扩展方向:

  • 概括提供反馈的方式。
  • 自动化优化配置的过程。
  • 为不同的应用构建自适应代理。

您觉得这种方法适用于您的用例吗?您是否有其他关于LLM应用的挑战要分享?您是否希望看到更多关于LLM优化或自动化的支持或研究?请加入我们的Discord服务器进行讨论。

进一步阅读