Skip to main content

4. 多模态视觉语音交互

4. 多模态视觉语音交互1. 概念介绍1.1 “视觉理解”是什么?1.2 实现原理简述2. 项目架构关键代码1. 工具层入口 (largemodel/utils/tools_manager.py)2. 模型接口层 (largemodel/utils/large_model_interface.py)代码解析3.1 配置在线LLM3.2 启动并测试功能

1. 概念介绍

1.1 “视觉理解”是什么?

largemodel项目中,多模态视觉理解 功能,指的是让机器人不仅仅能“看到”一个像素矩阵,而是能真正“理解”图像中的内容、物体、场景和它们之间的关系。这就像赋予了机器人一双能思考的眼睛。

该功能的核心工具是 seewhat 。当用户下达“看看这里有什么”之类的指令时,系统会调用这个工具,触发一系列的后台操作,最终将AI对实时画面的分析结果以自然语言的形式反馈给用户。

1.2 实现原理简述

其基本原理是将两种不同类型的信息——图像(视觉信息)文本(语言信息) ——输入给一个强大的多模态大模型(例如LLaVA)。

  1. 图像编码 : 模型首先通过一个视觉编码器(Vision Encoder)将输入的图像转换成计算机可以理解的数字向量,这些向量捕捉了图像的色彩、形状、纹理等特征。
  2. 文本编码 : 同时,用户的提问(如“桌子上有什么?”)也被转换成文本向量。
  3. 跨模态融合 : 最关键的一步,模型在一个特殊的“注意力层”(Attention Layer)中,将图像向量和文本向量进行融合。模型在这里学习“关注”图像中与问题相关的部分。例如,当问到“桌子”时,模型会更加关注图像中符合“桌子”特征的区域。
  4. 生成答案 : 最后,一个大型语言模型(LLM)部分会基于融合后的信息,生成一段描述性的文本作为答案。

简单来说,就是用文字“点亮”图像中对应的部分,然后用语言把“点亮”的部分描述出来

2. 项目架构

关键代码

1. 工具层入口 (largemodel/utils/tools_manager.py)

此文件中的seewhat函数定义了该工具的执行流程。

​ x # From largemodel/utils/tools_manager.py ​ class ToolsManager : # ... ​ def seewhat ( self ): """ Capture camera frame and analyze environment with AI model. 捕获摄像头画面并使用AI模型分析环境。 :return: Dictionary with scene description and image path, or None if failed. """ self . node . get_logger (). info ( "Executing seewhat() tool" ) image_path = self . capture_frame () if image_path : # Use isolated context for image analysis. / 使用隔离的上下文进行图像分析。 analysis_text = self . _get_actual_scene_description ( image_path ) ​ # Return structured data for the tool chain. / 为工具链返回结构化数据。 return { "description" : analysis_text , "image_path" : image_path } else : # ... (Error handling) return None ​ def _get_actual_scene_description ( self , image_path , message_context = None ): """ Get AI-generated scene description for captured image. 获取捕获图像的AI生成场景描述。 :param image_path: Path to captured image file. :return: Plain text description of scene. """ try : # ... (构建Prompt) # Force use of a plain text system prompt with a clean, one-time context. / 强制使用纯文本系统提示和干净的一次性上下文。 simple_context = [{ "role" : "system" , "content" : "You are an image description assistant. ..." }] ​ result = self . node . model_client . infer_with_image ( image_path , scene_prompt , message = simple_context ) # ... (处理结果) return description except Exception as e : # ...

2. 模型接口层 (largemodel/utils/large_model_interface.py)

此文件中的infer_with_image函数是所有图像理解任务的统一入口,它负责根据配置调用具体的模型实现。

xxxxxxxxxx # From largemodel/utils/large_model_interface.py ​ class model_interface : # ... def infer_with_image ( self , image_path , text = None , message = None ): """Unified image inference interface. / 统一的图像推理接口。""" # ... (准备消息) try : # 根据 self.llm_platform 的值,决定调用哪个具体实现 if self . llm_platform == 'ollama' : response_content = self . ollama_infer ( self . messages , image_path = image_path ) elif self . llm_platform == 'tongyi' : # ... 调用通义模型的逻辑 pass # ... (其他平台的逻辑) # ... return { 'response' : response_content , 'messages' : self . messages . copy ()} ​

代码解析

该功能的实现涉及两个主要层次:工具层定义业务逻辑,模型接口层负责与大语言模型进行通信。这种分层设计是实现平台通用性的关键。

  1. 工具层 (tools_manager.py):

    • seewhat函数是视觉理解功能的业务核心。它封装了“看”这个动作的完整流程:首先调用capture_frame方法获取图像,然后调用_get_actual_scene_description来准备一个用于请求模型分析图像的指令(Prompt)。
    • 最关键的一步是,它调用模型接口层的infer_with_image方法。它不关心底层用的是哪个模型,只负责将“图像”和“分析指令”这两个核心数据传递过去。
    • 最后,它将从模型接口层收到的分析结果(纯文本描述)打包成一个结构化的字典返回。这使得上层应用可以方便地使用分析结果。
  2. 模型接口层 (large_model_interface.py):

    • infer_with_image函数扮演着一个“调度中心”的角色。它的主要职责是检查当前的平台配置(self.llm_platform),并根据配置值将任务分发给对应的具体处理函数(例如ollama_infertongyi_infer等)。
    • 这一层是适配不同AI平台的关键。所有平台特有的操作(如数据编码、API调用格式等)都被封装在各自的处理函数中。
    • 通过这种方式,tools_manager.py中的业务逻辑代码完全无需改动,就可以支持多种不同的后端大模型服务。它只需要与infer_with_image这个统一的、稳定的接口交互即可。

总结来说,seewhat工具的执行流程体现了一个清晰的责任分离模式:ToolsManager负责定义“做什么”(获取图像并请求分析),而model_interface负责定义“怎么做”(根据当前配置,选择合适的模型平台并与其完成交互)。这使得教程的解析具有通用性,无论用户是在线还是离线模式,其核心代码逻辑都是一致的。3. 实践操作

3.1 配置在线LLM

  1. 先从前面教程的任意一个平台中获取API Key

  2. 然后需要更新配置文件中的key,打开模型接口配置文件large_model_interface.yaml:

xxxxxxxxxx vim ~/yahboom_ws/src/largemodel/config/large_model_interface.yaml 3. 填入你的API Key : 找到对应的部分,将你刚刚复制的API Key粘贴进去。这里以通义千问配置为例

xxxxxxxxxx # large_model_interface.yaml ​ ## 通义千问 qianwen_api_key : "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # 粘贴你的Key qianwen_model : "qwen-vl-max-latest" # 可以根据需要选择模型, 如qwen-turbo, qwen-plus 4. 打开主配置文件yahboom.yaml:

xxxxxxxxxx vim ~/yahboom_ws/src/largemodel/config/yahboom.yaml 5. 选择要使用的在线平台 : 修改llm_platform参数为你想要使用的平台名称

xxxxxxxxxx # yahboom.yaml ​ model_service : ros__parameters : # ... llm_platform : 'tongyi' #可选平台: 'ollama', 'tongyi', 'spark', 'qianfan', 'openrouter'

3.2 启动并测试功能

  1. 启动largemodel 主程序: 打开一个终端,然后运行下面的指令:

xxxxxxxxxx ros2 launch largemodel largemodel_control.launch.py 2. 测试 :

* **唤醒** : 对着麦克风说:“你好,小亚。”

* **对话** : 扬声器回应之后,就可以说:`你看到了什么?`

* **观察日志** : 在运行`launch`文件的终端中,你应该能看到:

1. ASR节点识别出你的问题并打印出来。
2. `model_service`节点收到文本,调用LLM,并打印出LLM的回复。
* **听回答** : 稍后,你应该能从扬声器听到回答。