搭建多元专家系统(MOA):轻松整合大模型的力量(二)

59 篇文章 0 订阅

原文:https://zhuanlan.zhihu.com/p/706771710

相关开源项目:GitHub - togethercomputer/MoA:Together Mixture-Of-Agents (MoA) – 65.1% 在 AlpacaEval 和 OSS 模型上

近期,AI领域出现了一个引人注目的新现象——“逆转诅咒”(Reversal Curse),这一概念迅速成为热点话题,影响了现今所有的大型语言模型。令人惊讶的是,即便面对极为基础的问题,这些模型的准确率不仅几乎为零,而且似乎没有改善的迹象。更重要的是,这一问题的存在与模型的规模或提问的具体内容无关。

在预训练大模型时代,人们曾乐观地认为AI开始展现出一定的逻辑推理能力,然而“逆转诅咒”的出现仿佛让这一切回到了起点。以GPT-4为例,尽管它能够正确识别汤姆·克鲁斯的母亲名字,但当问题反转,询问其母亲的儿子是谁时,模型却无法给出正确答案。这种现象揭示了模型在处理逆向逻辑推理时的局限性。

研究指出,自回归语言模型在面对此类逆向逻辑问题时,无法进行有效的泛化。即使模型在训练数据中遇到过类似“Olaf Scholz was the ninth Chancellor of Germany”这样的句子,它能够正确回答关于Olaf Scholz的身份,但却不能反过来回答谁是德国的第九任总理。这一现象被定义为“逆转诅咒”,即模型在面对“<name> is <description>”和“<description> is <name>”这两种句式时,无法自动地在两者之间进行转换。

“逆转诅咒”暗示了大型语言模型在逻辑演绎方面存在根本性缺陷。在逻辑学中,“A 是 B”意味着“B 是 A”同样成立,但大型语言模型在处理这类对称性问题时显得力不从心。这不仅仅是模型缺乏逻辑推理能力的问题,而是揭示了模型在泛化至训练数据以外的能力上存在重大局限。

接下来我们将开源大模型MOA进行实现,并测试是否能够减轻这个问题?

千问、千帆、GLM大模型是否解决了逆转诅咒?

我们来看看几个大模型的输出。

from dashscope import Generation
import os
import qianfan
from zhipuai import ZhipuAI
import dashscope

# 从环境变量读取API key
api_key = os.getenv('API_KEY_WX')
secret_key = os.getenv('SECRET_KEY_WX')
api_key_zp=os.getenv('API_KEY_ZP')
api_key_qw=os.getenv('API_KEY_QW')

dashscope.api_key = api_key_qw

# Initialize model clients
qianfan_client = qianfan.ChatCompletion()
zhipuai_client = ZhipuAI(api_key=api_key_zp)


# 定义模型名称
model_name_qf = 'ernie-speed-128k'  # 千帆模型
model_name_zp = 'glm-4'             # 智谱模型
model_name_qw = dashscope.Generation.Models.qwen_turbo  # 千问模型

# 用户问题
user_question = '假设奥拉夫・朔尔茨是联邦德国第九任总理,谁是德国第九任总理?'


# 定义查询模型的函数
def query_model(model_name, messages):
    if model_name == model_name_qf:
        # 查询千帆模型
        resp = qianfan.ChatCompletion().do(messages=messages, endpoint=model_name)
        return resp.body['result']
    elif model_name == model_name_zp:
        # 查询智谱模型
        response = zhipuai_client.chat.completions.create(
            model=model_name,
            messages=messages,
        )
        return response.choices[0].message.content
    elif model_name == model_name_qw:
        # 查询千问模型
        response = dashscope.Generation.call(model=model_name, messages=messages)
        return response.output['text']

# 初始消息
initial_messages = [{"role": "user", "content": user_question}]

query_model(model_name_zp,initial_messages)

query_model(model_name_qf,initial_messages)
query_model(model_name_qw,initial_messages)

GLM-4的回答

'根据您提供的参考信息,有一个小错误需要纠正。奥拉夫·朔尔茨(Olaf Scholz)确实是德国联邦共和国的一位总理,但他并不是第九任总理,而是接替安格拉·默克尔(Angela Merkel)成为德国联邦共和国的第八任总理。在此之前,德国的第九任总理是格哈德·施罗德(Gerhard Schröder),他在1998年至2005年间担任总理。\n\n因此,如果我们要确定联邦德国的第九任总理是谁,答案应该是格哈德·施罗德,而不是奥拉夫·朔尔茨。奥拉夫·朔尔茨是德国联邦共和国的第八任总理,于2021年接任。'

千帆ernie-speed-128k的回答

'德国第九任总理是奥拉夫·朔尔茨(Olaf Scholz)。因此,德国第九任总理就是奥拉夫·朔尔茨本人。'

千问qwen_turbo的回答

'目前,奥拉夫・朔尔茨(Olaf Scholz)是德国的现任总理,他于2021年12月8日接替安格拉·默克尔担任联邦德国第十四任总理。如果按照您的假设,奥拉夫・朔尔茨成为联邦德国第九任总理,那么现实情况中并没有这样的历史记录,因为默克尔在2005年至2021年间连续执政了16年,担任了四届总理。'

可以看到三个模型有两个模型仍然出现了“逆转诅咒”的现象。

开源大模型MOA架构的实现

我们将使用三个模型(千帆、智谱、千问)对同一问题进行回答,然后再次利用这三个模型各自生成一个整合prompt的版本,最后使用千问模型对整合后的prompt进行最终处理,以得到一个综合了多模型信息的高质量回答。下面是一个实现这一流程的Python代码示例:

import dashscope
from dashscope import Generation
from zhipuai import ZhipuAI

import os
import qianfan
from zhipuai import ZhipuAI
import dashscope

# 从环境变量读取API key
api_key = os.getenv('API_KEY_WX')
secret_key = os.getenv('SECRET_KEY_WX')
api_key_zp=os.getenv('API_KEY_ZP')
api_key_qw=os.getenv('API_KEY_QW')


# Set up API keys for each model provider
os.environ["QIANFAN_AK"] = api_key
os.environ["QIANFAN_SK"] = secret_key
api_key_zp = api_key_zp
api_key_qw = api_key_qw

dashscope.api_key = api_key_qw

# Initialize model clients
qianfan_client = qianfan.ChatCompletion()
zhipuai_client = ZhipuAI(api_key=api_key_zp)

# 创建模型客户端
zhipuai_client = ZhipuAI(api_key=zhipuai_api_key)

# 定义模型名称
model_name_qf = 'ernie-speed-128k'  # 千帆模型
model_name_zp = 'glm-4'             # 智谱模型
model_name_qw = dashscope.Generation.Models.qwen_turbo  # 千问模型

# 用户问题
user_question = '假设奥拉夫・朔尔茨是联邦德国第九任总理,谁是德国第九任总理?'

# 定义查询模型的函数
def query_model(model_name, messages):
    if model_name == model_name_qf:
        # 查询千帆模型
        resp = qianfan.ChatCompletion().do(messages=messages, endpoint=model_name)
        return resp.body['choices'][0]['message']['content']
    elif model_name == model_name_zp:
        # 查询智谱模型
        response = zhipuai_client.chat.completions.create(
            model=model_name,
            messages=messages,
        )
        return response.choices[0].message.content
    elif model_name == model_name_qw:
        # 查询千问模型
        response = dashscope.Generation.call(model=model_name, messages=messages)
        return response.output['text']

# 初始消息
initial_messages = [{"role": "user", "content": user_question}]

# 分别查询三个模型
results = {
    'qianfan': query_model(model_name_qf, initial_messages),
    'zhipuai': query_model(model_name_zp, initial_messages),
    'dashscope': query_model(model_name_qw, initial_messages)
}

# 打印初始结果
for model, result in results.items():
    print(f"{model} Response: {result}")

# 整合结果成新的prompt
aggregator_prompt = "根据用户的问题,整合不同模型回答到一个高质量的回答,需要注意有些回答可能是错误的或需要调整的。\n"
for model, result in results.items():
    aggregator_prompt += f"{model}的回答如下:\n{result}\n\n"

# 创建整合后的消息
aggregated_messages = [{"role": "user", "content": aggregator_prompt}]

# 再次查询三个模型,这次是针对整合后的prompt
aggregated_results = {
    'qianfan': query_model(model_name_qf, aggregated_messages),
    'zhipuai': query_model(model_name_zp, aggregated_messages),
    'dashscope': query_model(model_name_qw, aggregated_messages)
}

# 打印整合后的结果
for model, result in aggregated_results.items():
    print(f"{model} Aggregated Response: {result}")

# 使用千问模型进行最终处理
final_message = [{"role": "user", "content": "请根据之前模型的回答,提供一个最准确、详细的答案。"}]
final_result = query_model(model_name_qw, final_message + aggregated_messages)

# 打印最终整合的回答
print("Final Integrated Response:", final_result)

在这个代码中,我们首先初始化了API密钥,并创建了模型客户端。接着,定义了三个模型的名称以及用户的初始问题。然后,我们定义了一个query_model函数,用于根据传入的模型名称调用相应的模型API并返回结果。我们使用这个函数分别查询了三个模型,并将结果存储在results字典中。

接下来,我们创建了一个整合prompt,其中包含了来自三个模型的回答。我们再次使用query_model函数查询这三个模型,但这次的输入是整合后的prompt。这样,每个模型都有机会基于其他模型的回答来生成自己的整合版本。

最后,我们使用千问模型对整合后的prompt进行最终处理,以获得一个综合了多模型信息的高质量回答。这个回答是基于之前所有模型的回答生成的,因此理论上应该比单个模型的回答更加全面和准确。

请注意,在实际应用中,你可能需要根据具体的API文档调整代码细节,比如错误处理、API参数等。此外,为了使代码运行,你需要替换your_dashscope_api_keyyour_zhipuai_api_key为你的实际API密钥。

MOA架构大模型是否能够解决逆转诅咒

针对逆转诅咒问题,即大型语言模型在处理逆向逻辑推理时的局限性,MOA(Model of Models)架构本身并不直接解决这一问题,但MOA架构提供了一种可能的解决方案框架,通过集成多个模型的输出来提高最终响应的质量和准确性。

MOA架构的核心思想是利用多个模型的优势,通过聚合他们的输出来克服单一模型的弱点。在上述示例中,三个模型(qianfan、zhipuai、dashscope)对同一问题提供了不同的回答。尽管这些回答在某些方面存在不一致性,但通过MOA架构下的集成处理,最终能够生成一个综合了多模型信息的高质量回答。

在处理逆转诅咒这类问题时,MOA架构可以采取以下策略:

  1. 多视角验证:不同模型可能基于不同的训练数据和算法,因此它们对同一问题的理解和回答可能存在差异。通过比较和验证这些差异,MOA架构可以帮助识别和纠正潜在的谬误。
  2. 信息互补:即使在逆转诅咒问题中,某些模型可能在正向推理上表现良好,而其他模型可能在逆向推理上有优势。MOA架构可以通过结合这些模型的强项,提供更全面和准确的回答。
  3. 共识机制:MOA架构可以设计一种共识机制,使得只有当大多数模型同意某一答案时,才将其作为最终输出。这有助于减少因逆转诅咒而导致的错误回答。
  4. 动态调整权重:根据模型在特定类型问题上的表现,MOA架构可以动态调整不同模型的权重,给予表现更好的模型更高的信任度,从而提高整体系统的准确性和可靠性。

综上所述,虽然MOA架构本身并不直接修复逆转诅咒这一问题,但它提供了一种通过模型集成来减轻或规避这一局限性的方法。通过利用不同模型间的互补性和多样性,MOA架构有望在处理逆向逻辑推理等复杂问题时,提供更加稳健和准确的解决方案。

该MOA架构的答案如下:

qianfan Response: 根据问题的表述,前提提到奥拉夫·朔尔茨被视为联邦德国第九任总理。由于信息陈述中的明确表述是关于同一事件的同一角色,因此我们可以直接确认奥拉夫·朔尔茨就是德国第九任总理。因此,德国第九任总理是奥拉夫·朔尔茨。
zhipuai Response: 假设奥拉夫·朔尔茨是联邦德国的第九任总理,这个“假设”实际上是一个已经确认的事实。奥拉夫·朔尔茨确实是德意志联邦共和国的第九任总理。他在2021年12月8日被德国联邦议院选举为总理,并在同一天宣誓就职,接替了执政16年的安格拉·默克尔。

至于谁是德国的第九任总理,如果我们依据联邦德国的历史来数,那么在奥拉夫·朔尔茨之前,有如下几位总理:

1. 康拉德·阿登纳 (Konrad Adenauer)
2. 路德维希·艾哈德 (Ludwig Erhard)
3. 基尔特·基辛格 (Kurt Georg Kiesinger)
4. 维利·勃兰特 (Willy Brandt)
5. 赫尔穆特·施密特 (Helmut Schmidt)
6. 赫尔穆特·科尔 (Helmut Kohl)
7. 格哈特·施罗德 (Gerhard Schröder)
8. 安格拉·默克尔 (Angela Merkel)

所以,奥拉夫·朔尔茨是继上述八位总理之后的第九任德国总理。
dashscope Response: 目前,奥拉夫・朔尔茨(Olaf Scholz)是德国的现任总理,他于2021年12月8日接替安格拉·默克尔担任联邦德国第十四任总理。如果按照您的假设,奥拉夫・朔尔茨成为联邦德国第九任总理,那么现实情况中并没有这样的历史记录,因为默克尔在2005年至2021年间连续执政了16年,担任了四届总理。
qianfan Aggregated Response: 经过对比各个回答,可以看出关于奥拉夫·朔尔茨是德国第几任总理的问题存在一些不一致的回答。

qianfan和zhipuai的回答都提到奥拉夫·朔尔茨是德国第九任总理,但是dashscope指出奥拉夫·朔尔茨是第十四任总理。显然,这里存在一个矛盾,需要澄清的是到底他是第几任总理。经过进一步查询和比对已知事实,可以确定奥拉夫·朔尔茨是联邦德国第十四任总理。而关于他是第九任总理的说法可能是对历史上总理任职顺序的误解或混淆。因此,这个问题的正确答案是奥拉夫·朔尔茨是德国第十四任总理。至于他之前的总理都有谁,与这个问题的核心关注点无直接关系,因此在此不做过多解释。
zhipuai Aggregated Response: 综合以上回答,可以得出以下高质量回答:

奥拉夫·朔尔茨是德意志联邦共和国的现任总理,于2021年12月8日被德国联邦议院选举为总理,并在同一天宣誓就职,接替了连续执政16年的安格拉·默克尔。若按照联邦德国的历史顺序来数,他是第十四任总理。

在奥拉夫·朔尔茨之前,联邦德国的总理顺序如下:

1. 康拉德·阿登纳 (Konrad Adenauer)
2. 路德维希·艾哈德 (Ludwig Erhard)
3. 基尔特·基辛格 (Kurt Georg Kiesinger)
4. 维利·勃兰特 (Willy Brandt)
5. 赫尔穆特·施密特 (Helmut Schmidt)
6. 赫尔穆特·科尔 (Helmut Kohl)
7. 格哈特·施罗德 (Gerhard Schröder)
8. 安格拉·默克尔 (Angela Merkel)

因此,提到奥拉夫·朔尔茨是“第九任”总理的信息可能是错误的,应该是第十四任。在回答这类问题时,需要注意历史记录和事实的准确性,避免混淆。
dashscope Aggregated Response: 综合以上三位的回答,我们可以得出以下结论:

奥拉夫·朔尔茨确实是德国的总理,但并非第九任,而是联邦德国的第十四任总理。他于2021年12月8日接替安格拉·默克尔上任。在默克尔之前,联邦德国的总理包括:

1. 康拉德·阿登纳
2. 路德维希·艾哈德
3. 基尔特·基辛格
4. 维利·勃兰特
5. 赫尔穆特·施密特
6. 赫尔穆特·科尔
7. 格哈特·施罗德
8. 安格拉·默克尔(她在2005年至2021年间担任总理)

因此,如果要提到奥拉夫·朔尔茨之前的总理,应该是从第八任开始数起,即默克尔之前的总理们。

Final Integrated Response: 最准确、详细的答案是:奥拉夫·朔尔茨是德国的现任总理,正式就任于2021年12月8日,接替了安格拉·默克尔,成为德意志联邦共和国的第九任总理。在朔尔茨之前,联邦德国的总理名单包括康拉德·阿登纳、路德维希·艾哈德、基尔特·基辛格、维利·勃兰特、赫尔穆特·施密特、赫尔穆特·科尔、格哈特·施罗德和安格拉·默克尔等。如果仅考虑联邦德国成立以来的总理职位,那么奥拉夫·朔尔茨确实是自默克尔之后的第九任总理。

可以看到,通过MOA的架构,模型选择了最准确的答案,并且补充了有用的信息。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值