跳到正文
原文
Hugging Face:Blog(RSS)·· 2024-01-24精选AI 评分70

Hugging Face 实测开源 LLM 作为 LangChain ReAct 智能体:Mixtral-8x7B 超过 GPT-3.5

Open-source LLMs as LangChain Agents

AI 导读

Hugging Face 发布教程,讲解 ReAct 智能体的内部工作原理,并演示如何用新集成的 ChatHuggingFace 类在 LangChain 中构建开源模型智能体。

推荐理由

原文给出 ReAct 智能体的运行机制、LangChain 实现代码和开源模型对比基准,Mixtral-8x7B 超过 GPT-3.5 的结果可作选型参考。

正文 · AI 翻译

TL;DR

开源 LLM 现在已经达到了一个性能水平,使其适合作为驱动 agent 工作流的推理引擎:Mixtral 在我们的基准测试中甚至超越了 GPT-3.5,而且它的性能可以通过微调轻松进一步提升。

我们发布了目前最简单的 agentic 库:smolagents! 去查看smolagents介绍博客这里。

Introduction

为因果语言建模训练的大型语言模型(LLM)可以处理广泛的任务,但它们往往在逻辑、计算和搜索等基本任务上表现不佳。最糟糕的情况是,它们在一个领域(如数学)表现不佳,却仍试图自己处理所有计算。

为了克服这一弱点,除其他方法外,可以将 LLM 集成到一个可以调用工具的系统里:这样的系统被称为 LLM agent。

在这篇文章中,我们解释 ReAct agent 的内部工作原理,然后展示如何使用最近集成到 LangChain 中的ChatHuggingFace类来构建它们。最后,我们针对 GPT-3.5 和 GPT-4 对几个开源 LLM 进行基准测试。

Table of Contents

What are agents?

LLM agent 的定义相当宽泛:LLM agent 是所有以 LLM 为引擎、并能根据观察在其环境中执行操作的系统。它们可以使用感知 ⇒ 反思 ⇒ 行动循环的多次迭代来完成任务,并且通常通过规划或知识管理系统来增强其性能。你可以在Xi et al., 2023中找到对 Agents 领域的良好综述。

今天,我们重点关注ReAct agent。ReAct是一种基于两个词拼接构建 agent 的方法,即“Reasoning”和“Acting”。在提示中,我们描述模型、它可以使用的工具,并要求它“逐步”思考(也称为Chain-of-Thought行为)来规划和执行其下一步行动,以达成最终答案。

drawing

Toy example of a ReAct agent's inner working

上图看起来非常高层,但在底层其实相当简单。

看看这个 notebook:我们用 Transformers 库实现了一个最简的工具调用示例。

LLM 在一个循环中被调用,提示本质上包含:

Here is a question: "{question}" 
You have access to these tools: {tools_descriptions}. 
You should first reflect with ‘Thought: {your_thoughts}’, then you either:
- call a tool with the proper JSON formatting,
- or your print your final answer starting with the prefix ‘Final Answer:’

然后你解析 LLM 的输出:

  • 如果它包含字符串‘Final Answer:’,循环结束,你打印答案,
  • 否则,LLM 应该输出了一次工具调用:你可以解析这个输出以获取工具名称和参数,然后用这些参数调用该工具。接着,这个工具调用的输出会被追加到提示中,你再用这个扩展后的信息再次调用 LLM,直到它有足够的信息最终为问题提供最终答案。

例如,在回答问题时,LLM 的输出可能看起来像这样:How many seconds are in 1:23:45?

Thought: I need to convert the time string into seconds.

Action:
{
    "action": "convert_time",
    "action_input": {
    "time": "1:23:45"
    }
}

由于这个输出不包含字符串‘Final Answer:’,它是在调用工具:所以我们解析这个输出并获取工具调用参数:调用工具convert_time,参数为{"time": "1:23:45"}。 运行这个工具调用返回{'seconds': '5025'}。

所以我们把这一整块内容追加到提示中。

新的提示现在是(一个稍微更精细的版本):

Here is a question: "How many seconds are in 1:23:45?"
You have access to these tools:
    - convert_time: converts a time given in hours:minutes:seconds into seconds.

You should first reflect with ‘Thought: {your_thoughts}’, then you either:
- call a tool with the proper JSON formatting,
- or your print your final answer starting with the prefix ‘Final Answer:’

Thought: I need to convert the time string into seconds.

Action:
{
    "action": "convert_time",
    "action_input": {
    "time": "1:23:45"
    }
}
Observation: {'seconds': '5025'}

➡️ 我们再次调用 LLM,使用这个新提示。鉴于它能够访问 Observation 中工具调用的结果,LLM 现在最有可能输出:

Thought: I now have the information needed to answer the question.
Final Answer: There are 5025 seconds in 1:23:45.

任务解决了!

代理系统的挑战

一般来说,为 LLM 引擎运行代理系统的困难部分包括:

  1. 从提供的工具中,选择有助于推进到期望目标的工具:例如,当被要求 "What is the smallest prime number greater than 30,000?" 时,代理可以调用 Search 工具并使用 "What is the height of K2",但这不会有帮助。
  2. Call tools with a rigorous argument formatting: for instance when trying to calculate the speed of a car that went 3 km in 10 minutes, you have to call tool Calculator to divide distance by time : even if your Calculator tool accepts calls in the JSON format: {”tool”: “Calculator”, “args”: “3km/10min”} , there are many pitfalls, for instance:
    • 拼错工具名称:“calculator” 或 “Compute” 都不会起作用
    • 给出参数名称而不是它们的值:“args”: “distance/time”
    • 非标准化格式:“args": "3km in 10minutes”
  3. 高效地摄取和使用过去观察中收集的信息,无论是初始上下文还是使用工具后返回的观察结果。

那么,一个完整的代理设置会是什么样子?

使用 LangChain 运行代理

我们刚刚集成了一个 ChatHuggingFace 包装器,让你能够在 🦜🔗LangChain 中基于开源模型创建代理。

创建 ChatModel 并为其提供工具的代码非常简单,你可以在 Langchain 文档中查看全部内容。

from langchain_community.llms import HuggingFaceEndpoint
from langchain_community.chat_models.huggingface import ChatHuggingFace

llm = HuggingFaceEndpoint(repo_id="HuggingFaceH4/zephyr-7b-beta")

chat_model = ChatHuggingFace(llm=llm)

你可以通过给它一个 ReAct 风格的提示和工具,将 chat_model 变成一个代理:

from langchain import hub
from langchain.agents import AgentExecutor, load_tools
from langchain.agents.format_scratchpad import format_log_to_str
from langchain.agents.output_parsers import (
    ReActJsonSingleInputOutputParser,
)
from langchain.tools.render import render_text_description
from langchain_community.utilities import SerpAPIWrapper

# setup tools
tools = load_tools(["serpapi", "llm-math"], llm=llm)

# setup ReAct style prompt
prompt = hub.pull("hwchase17/react-json")
prompt = prompt.partial(
    tools=render_text_description(tools),
    tool_names=", ".join([t.name for t in tools]),
)

# define the agent
chat_model_with_stop = chat_model.bind(stop=["\nObservation"])
agent = (
    {
        "input": lambda x: x["input"],
        "agent_scratchpad": lambda x: format_log_to_str(x["intermediate_steps"]),
    }
    | prompt
    | chat_model_with_stop
    | ReActJsonSingleInputOutputParser()
)

# instantiate AgentExecutor
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

agent_executor.invoke(
    {
        "input": "Who is the current holder of the speed skating world record on 500 meters? What is her current age raised to the 0.43 power?"
    }
)

然后代理将处理输入:

Thought: To answer this question, I need to find age of the current speedskating world record holder.  I will use the search tool to find this information.
Action:
{
    "action": "search",
    "action_input": "speed skating world record holder 500m age"
}
Observation: ...

代理对决:开源 LLM 作为通用推理代理的表现如何?

你可以在这里找到这个基准测试的代码。

评估

我们想要衡量开源 LLM 作为通用推理代理的表现。因此,我们选择了需要使用逻辑和使用基本工具的问题:计算器和访问互联网搜索。 最终数据集是来自其他 3 个数据集的样本组合:

  • 为了测试互联网搜索能力:我们从 HotpotQA 中选择了问题:这原本是一个检索数据集,但可以用于通用问答,并访问互联网。有些问题原本需要结合来自各种来源的信息:在我们的设置中,这意味着执行多个步骤的互联网搜索来组合结果。
  • 为了测试计算器使用,我们添加了来自 GSM8K 的问题:这个数据集测试小学水平的数学能力,并且完全可以通过正确利用 4 个运算符(加、减、乘、除)来解决。
  • 我们还从 GAIA 中挑选了问题,这是一个非常困难的通用 AI 助手基准测试。原始数据集中的问题可能需要许多其他不同的工具,例如代码解释器或 pdf 阅读器:我们手工挑选了不需要除搜索和计算器之外其他工具的问题。

评估使用 GPT-4 作为评判者,基于 Prometheus 提示格式的提示进行,结果以 5 点李克特量表给出:在这里查看确切的提示。

模型

我们评估了几个强大的开源模型:

这些模型在 LangChain 的 ReAct 实现中进行评估 这意味着我们提示它们以这种格式输出函数调用:

{
  "action": $TOOL_NAME,
  "action_input": $INPUT
}

为了进行比较,我们还使用 LangChain 的 OpenAI 专用代理 在相同的示例上评估了 GPT-3.5 和 GPT-4。 由于这使用了它们自己的函数调用模板,而它们正是在此基础上进行了微调,这意味着 OpenAI 模型应处于其最佳性能状态。

结果

由于开源模型并未针对给定输出格式中的函数调用进行专门微调,与 OpenAI 代理相比,它们处于轻微劣势。

尽管如此,一些模型表现非常出色!💪

以下是 Mixtral-8x7B 回答问题的示例:“Which city has a larger population, Guiyang or Tacheng?”

Thought: To answer this question, I need to find the current populations of both Guiyang and Tacheng. I will use the search tool to find this information.
Action:
{
    "action": "search",
    "action_input": "current population of Guiyang"
}
4.697 million (2016)

Thought: I have obtained the population of Guiyang, which is 4.697 million (as of 2016). Now, I will use the search tool again to find the population of Tacheng.
Action:
{
    "action": "search",
    "action_input": "current population of Tacheng"
}
Population: Xinjiang: Tacheng data was reported at 1,110.000 Persons in 2021. This records a decrease from the previous number of 1,138.638 Persons for 2020.
Population: Xinjiang: Tacheng data is updated yearly, averaging 1,023.000 Persons from Dec 2005 to 2021, with 17 observations.

I have obtained the population of Tacheng, which is approximately 1.11 million (as of 2021). Comparing the two populations, Guiyang has a larger population than Tacheng.

Thought: I now know the final answer
Final Answer: Guiyang has a larger population, which is approximately 4.697 million (as of 2016), compared to Tacheng's population of approximately 1.11 million (as of 2021).

以下是我们评估数据集上模型的基准测试结果(原本 1-5 分的平均分已转换为 0-100% 的尺度以便阅读):

benchmark of agents performance

如您所见,一些开源模型在驱动代理工作流方面表现不佳:虽然这对于小型 Zephyr-7b 是意料之中的,但 Llama2-70b 的表现却出奇地差。

👉 但 Mixtral-8x7B 表现非常出色:它甚至击败了 GPT-3.5! 🏆

而且这是开箱即用的性能:与 GPT-3.5 不同,Mixtral 并未针对代理工作流进行微调(据我们所知),这在一定程度上影响了其性能。例如,在 GAIA 上,10% 的问题失败是因为 Mixtral 尝试调用工具时参数格式不正确。如果针对函数调用和任务规划技能进行适当的微调,Mixtral 的得分可能会更高。

➡️ 我们强烈建议开源开发者开始为代理微调 Mixtral,以超越下一个挑战者:GPT-4!🚀

结语:

  • GAIA 基准测试,尽管此处仅在一小部分问题和少数工具上进行了尝试,但似乎是一个非常稳健的指标,用于衡量代理工作流的整体模型性能,因为它通常涉及多个推理步骤和严谨的逻辑。
  • 代理工作流允许 LLM 提高性能:例如,在 GSM8K 上,GPT-4 的技术报告 报告了 5-shot CoT 提示的 92%:给它一个计算器使我们在零样本下达到 95%。对于 Mixtral-8x7B,LLM 排行榜 报告了 5-shot 的 57.6%,我们在零样本下得到 73%。(请记住,我们仅测试了 GSM8K 的 20 个问题)

来源:Hugging Face:Blog(RSS) · huggingface.co