天天看点

重新定义聊天机器人:GPT 4o 的多模态交互创新

作者:ChatGPT扫地僧

重新定义聊天机器人:GPT 4o 的多模态交互创新

原文:Multimodal Chatbot with Text and Audio Using GPT 4o

介绍

自 OpenAI 推出 GPT 模型(如 GPT 4o)以来,自然语言处理的格局已经完全改变,并转向了一个称为生成式人工智能的新概念。大型语言模型是其核心,它们能够理解复杂的人类查询并生成相关的答案。对于这种大型语言模型的下一步发展是多模态性,即能够理解除文本以外的数据。这可能包括图像、音频和视频。最近一些多模型已经发布,包括开源和闭源的,比如谷歌的 Gemini、LlaVa 和 GPT 4v。最近,OpenAI 宣布推出了一种新的多模型,名为 GPT 4o(Omni)。在本文中,我们将使用这个 OpenAI GPT 4o 创建一个多模态聊天机器人。

重新定义聊天机器人:GPT 4o 的多模态交互创新

学习目标

  • • 了解 GPT-4o 在文本、音频和图像生成方面的能力
  • • 学习为处理用户输入(图像和音频)创建辅助函数以供 GPT-4o 使用
  • • 使用 Chainlit 构建一个与 GPT-4o 交互的多模态聊天机器人
  • • 实现处理聊天机器人中的文本、图像和音频输入的功能
  • • 了解使用多模态方法进行聊天机器人交互的好处
  • • 探索 GPT-4o 多模态能力的潜在应用

目录

什么是 GPT 4o?

最近宣布的 OpenAI 的 GPT-4o 在速度、准确性和理解以及生成文本、音频和图像方面的能力上标志着人工智能的重大飞跃。这个“多语言”模型可以翻译语言、撰写创意内容、分析或生成具有不同语调的语音,甚至描述现实场景或根据您的描述创建图像。除了其令人印象深刻的能力,GPT-4o 与 ChatGPT 无缝集成,允许实时对话,它可以识别视觉信息并提出相关问题。跨模态交互的能力为与计算机更自然、更直观地交互铺平了道路,可能有助于视觉受障碍用户,并创造新的艺术媒介。GPT-4o 作为突破性的下一代模型,推动了人工智能的边界。

创建辅助函数

在本节中,我们将开始编写多模态聊天机器人的代码。第一步是下载我们将在此代码中使用的必要库。为此,我们运行以下命令

pip install openai chainlit           

运行此命令将安装 OpenAI 库。这将让我们使用不同的 OpenAI 模型,包括文本生成模型(如 GPT 4o 和 GPT 3.5)、图像生成模型(如 DallE-3)和语音转文本模型(如 Whisper)。

我们安装 chainlit 以创建用户界面。Chainlit 库让我们完全使用 Python 创建快速聊天机器人,无需编写 Javascript、HTML 或 CSS。在开始聊天机器人之前,我们需要创建一些辅助函数。首先是处理图像的函数。我们不能直接提供模型的图像。我们需要将它们编码为 base64,然后再提供。为此,我们使用以下代码

import base64
def image2base64(image_path):
    with open(image_path, "rb") as img:
        encoded_string =, base64.b64encode(img.read())
    return encoded_string.decode("utf-8")           
  • • 首先,我们导入 base64 库进行编码。然后,我们创建一个名为 image_2_base64() 的函数,以图像路径作为输入。
  • • 接下来,我们以读取字节的模式打开提供的路径中的图像。然后,我们调用 base64 库的 b64encode() 方法,将图像编码为 base64。
  • • 编码的数据是字节形式的,因此我们需要将其转换为模型期望的 Unicode 格式,以便将此图像与用户查询一起传递。
  • • 因此,我们调用 decode() 方法,该方法接受 base64 编码的字节并使用 UTF-8 编码对其进行解码,最终返回 base64 编码的字符串。
  • • 最后,我们返回 base64 编码的字符串,可以与要发送给 GPT-4o 模型的文本连接在一起。
  • • 从高层次上来看,我们所做的是将图像转换为“Base 64 编码的字节”,然后将“Base 64 编码的字节”转换为“Base 64 编码的字符串”。

多模态聊天甚至需要音频输入。因此,我们在将其发送到模型之前需要处理音频。为此,我们使用 OpenAI 的语音转文本模型。其代码如下所示。

from openai import OpenAI
client = OpenAI()
def audio_process(audio_path):
    audio_file = open(audio_path, "rb")
    transcription = client.audio.transcriptions.create(
        model="whisper-1", file=audio_file
    )
    return transcription.text           
  • • 我们首先从 OpenAI 函数中导入 OpenAI 类。确保 .env 文件中存在 OpenAI API 密钥。
  • • 接下来,我们实例化一个 OpenAI 对象,并将该对象存储在变量 client 中。
  • • 现在,我们创建一个名为 audio_process() 的函数,该函数期望输入音频路径。
  • • 然后,我们以只读模式打开文件,并将结果字节存储在变量 audio_file 中。
  • • 然后,我们调用 client.audio.transcriptions.create() 函数,并将 audio_file 传递给该函数。除此之外,我们还告诉要使用哪个模型进行语音转文本转换。这里我们给出了“whisper-1”。
  • • 调用上述函数将会将 audio_file 的内容传递给该模型,并将相应的转录存储在 transcription 变量中。
  • • 最后,我们返回文本部分,即从该函数中实际转录的音频的文本。

我们无法预料用户会向模型询问什么类型的消息。用户有时可能只发送纯文本,有时可能包含图片,有时可能包含音频文件。因此,基于此,我们需要修改将发送给 OpenAI 模型的消息。为此,我们可以编写另一个函数,该函数将向模型提供不同的用户输入。其代码如下:

def append_messages(image_url=None, query=None, audio_transcript=None):
    message_list = []
    if image_url:
        message_list.append({"type": "image_url", "image_url": {"url": image_url}})
    if query and not audio_transcript:
        message_list.append({"type": "text", "text": query})
    if audio_transcript:
        message_list.append({"type": "text", "text": query + "\n" + audio_transcript})
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": message_list}],
        max_tokens=1024,
    )
    return response.choices[0]           
  • • 我们创建了一个名为 append_messages() 的函数,其中定义了三个参数。一个是 image_url,第二个是用户查询,最后一个是音频转录。
  • • 然后,我们通过将空列表赋值给空的 message_list 变量来创建一个空的 message_list 变量。
  • • 接下来,我们检查是否提供了 image_url,如果提供了,我们将创建一个字典,其中键为“type”,值为“image_url”,另一个键为“image_url”,我们通过给出调用该函数的 image_url 来传递另一个字典。这是 OpenAI 期望发送图片的格式。
  • • 然后,我们检查是否提供了查询,并且没有提供音频转录。然后,我们只需将另一个字典附加到 messag_list,其中包含代码中看到的键值对。
  • • 最后,我们检查是否向函数提供了音频转录,如果是,则将其与用户查询组合在一起,并将其附加到消息列表中。
  • • 然后,我们调用 client.chat.completions.create() 函数,在其中传递模型,这里是 GPT-4o,以及我们之前创建的 message_list,并将结果存储在 response 变量中。
  • • 我们甚至将 max_tokens 设置为 1024。除此之外,我们还可以提供额外的参数,如 temperature、top_p 和 top_k。
  • • 最后,我们通过返回 response.choices[0] 存储由 GPT 4 Omni 生成的响应。

通过这样做,我们已经创建了辅助函数。稍后我们将调用这些辅助函数,以传递用户查询、音频和图像数据,并获取响应。

构建聊天机器人界面

现在,我们将构建 Chatbot 的 UI 部分。这可以很容易地使用 Chainlit 库构建。我们将编写的代码将与定义辅助函数的同一文件中。代码如下:

import chainlit as cl
@cl.on_message
async def chat(msg: cl.Message):
    images = [file for file in msg.elements if "image" in file.mime]
    audios = [file for file in msg.elements if "audio" in file.mime]
    if len(images) > 0:
        base64_image = image2base64(images[0].path)
        image_url = f"data:image/png;base64,{base64_image}"
    elif len(audios) > 0:
        text = audio_process(audios[0].path)
    response_msg = cl.Message(content="")
    if len(images) == 0 and len(audios) == 0:
        response = append_messages(query=msg.content)
    elif len(audios) == 0:
        response = append_messages(image_url=image_url, query=msg.content)
    else:
        response = append_messages(query=msg.content, audio_transcript=text)
    response_msg.content = response.message.content
    await response_msg.send()           
  • • 我们首先导入 chainlit 库。然后,我们创建一个装饰器 @cl.on_message(),它告诉下面的函数在用户输入消息时运行。
  • • Chainlit 库期望一个异步函数。因此,我们定义了一个名为 chat 的异步函数,它接受一个名为 cl.Message 的变量。无论用户输入的是文本、音频还是图片,所有内容都存储在 cl.Message 中。
  • • msg.elements 包含用户发送的消息类型列表。这些可以是纯文本用户查询,也可以是带有图片或音频的用户查询。
  • • 因此,我们检查用户消息中是否存在一些图片或音频文件,并将它们存储在 images 和 audio 变量中。
  • • 现在,我们使用 if 块检查是否存在图片,然后将它们转换为 base64 字符串,并以 GPT-4o 模型期望的格式存储在 image_url 变量中。
  • • 我们甚至检查音频是否存在,如果存在,我们通过调用 audio_process() 函数处理该音频,该函数返回音频转录,并将其存储在名为 text 的变量中。
  • • 然后,我们通过给它一个空消息来创建一个消息占位符 response_img。
  • • 然后再次检查是否存在图片或音频。如果两者都不存在,我们只将用户查询发送到 append_message 函数;如果有音频/图片,我们甚至将它们传递给 append_messages 函数。
  • • 然后,我们将模型的结果存储在 response 变量中,并将其附加到我们之前创建的占位符消息变量 response_msg 中。
  • • 最后,我们调用 response_msg.send(),这将在用户界面中显示响应。

最终代码将是

from openai import OpenAI
import base64
import chainlit as cl
client = OpenAI()
def append_messages(image_url=None, query=None, audio_transcript=None):
    message_list = []
    if image_url:
        message_list.append({"type": "image_url", "image_url": {"url": image_url}})
    if query and not audio_transcript:
        message_list.append({"type": "text", "text": query})
    if audio_transcript:
        message_list.append({"type": "text", "text": query + "\n" + audio_transcript})
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": message_list}],
        max_tokens=1024,
    )
    return response.choices[0]
def image2base64(image_path):
    with open(image_path, "rb") as img:
        encoded_string = base64.b64encode(img.read())
    return encoded_string.decode("utf-8")
def audio_process(audio_path):
    audio_file = open(audio_path, "rb")
    transcription = client.audio.transcriptions.create(
        model="whisper-1", file=audio_file
    )
    return transcription.text
@cl.on_message
async def chat(msg: cl.Message):
    images = [file for file in msg.elements if "image" in file.mime]
    audios = [file for file in msg.elements if "audio" in file.mime]
    if len(images) > 0:
        base64_image = image2base64(images[0].path)
        image_url = f"data:image/png;base64,{base64_image}"
    elif len(audios) > 0:
        text = audio_process(audios[0].path)
    response_msg = cl.Message(content="")
    if len(images) == 0 and len(audios) == 0:
        response = append_messages(query=msg.content)
    elif len(audios) == 0:
        response = append_messages(image_url=image_url, query=msg.content)
    else:
        response = append_messages(query=msg.content, audio_transcript=text)
    response_msg.content = response.message.content
    await response_msg.send()           

要运行此代码,请键入 chainlit run app.py,假设代码存储在名为 app.py 的文件中。运行此命令后,localhost:8000 端口将变为活动状态,并且我们将看到以下图像

重新定义聊天机器人:GPT 4o 的多模态交互创新

现在让我们只输入一个普通文本查询,看看生成的输出

重新定义聊天机器人:GPT 4o 的多模态交互创新

我们看到 GPT-4o 成功为用户查询生成了输出。我们甚至注意到这里正在突出显示代码,并且我们可以快速复制和粘贴。这一切都由 Chainlit 管理,它处理底层的 HTML、CSS 和 Javascript。接下来,让我们尝试上传一张图片并询问模型相关信息。

重新定义聊天机器人:GPT 4o 的多模态交互创新

在这里,模型对我们上传的图片做出了良好的响应。它识别出图片是一个表情符号,并提供了关于它的信息以及可以在哪里使用它。现在,让我们传递一个音频文件并进行测试

重新定义聊天机器人:GPT 4o 的多模态交互创新

speech.mp3 音频包含有关机器学习的信息,因此我们要求模型总结其内容。模型生成了与音频文件中的内容相关的摘要。

结论

总之,利用OpenAI的GPT-4o (Omni)开发多模态聊天机器人标志着人工智能技术迈出了重要一步,开启了互动体验的新时代。在这里,我们探讨了如何无缝地将文本、图像和音频输入整合到与聊天机器人的对话中,充分利用了GPT-4o的能力。这种创新的方法增强了用户参与度,并为不同的实际应用打开了大门,从帮助视障用户到创造新的艺术媒介。通过将语言理解的能力与多模态功能相结合,GPT-4o展现了其革新人们与人工智能系统互动方式的潜力。

主要观点

  • • GPT-4o代表了人工智能的重要时刻,仅通过一个模型就能提供文本、音频和图像的理解和生成能力
  • • 将多模态功能整合到聊天机器人中,使互动更加自然和直观,增加了用户的参与度和体验
  • • 助手功能在预处理输入中起着至关重要的作用,例如将图像编码为base64并转录音频文件,然后再将它们输入模型
  • • append_messages函数根据用户查询动态调整输入格式,因此可以接受纯文本、图像和音频转录
  • • Chainlit库简化了聊天机器人界面的开发,处理底层的HTML、CSS和JavaScript,使UI创建变得简单易行 [20]