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 配置离线大模型3.1.1 配置LLM平台 (yahboom.yaml)3.1.2 配置模型接口 (large_model_interface.yaml)3.2 启动并测试功能4. 常见问题与解决方案4.1 响应非常慢

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.1 配置离线大模型

3.1.1 配置LLM平台 (yahboom.yaml)

此文件决定了 model_service 节点加载哪个大模型平台作为其主要的语言模型。

  1. 在终端打开文件 :

xxxxxxxxxx vim ~/yahboom_ws/src/largemodel/config/yahboom.yaml 2. 修改/确认llm_platform:

xxxxxxxxxx model_service : #模型服务器节点参数 ros__parameters : language : 'zh' #大模型接口语言 useolinetts : True #文字模式下此项无效,可忽略 ​ # 大模型配置 llm_platform : 'ollama' # 关键: 确保这里是 'ollama' regional_setting : "China"

3.1.2 配置模型接口 (large_model_interface.yaml)

此文件定义了当平台被选为 ollama 时,具体使用哪个视觉模型。

1.在终端打开文件

xxxxxxxxxx vim ~/yahboom_ws/src/largemodel/config/large_model_interface.yaml

2.找到ollama相关的配置

xxxxxxxxxx #..... ## 离线大模型 (Offline Large Language Models) # Ollama配置 ollama_host: "http://localhost:11434" # Ollama服务器地址 ollama_model: "llava" # 关键: 将这里改为你已下载的多模态模型,如 "llava" #.....

注意 : 请确保配置参数中指定的模型(如llava)能够处理多模态输入。

3.2 启动并测试功能

注:Jetson Orin Nano 4GB 由于性能限制,无法运行此案例。如需体验此功能,请参考 <在线大模型(语音交互)>对应章节

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

xxxxxxxxxx ros2 launch largemodel largemodel_control.launch.py 2. 初始化成功之后,说出唤醒词,然后开始提问:你看到了什么?或者描述一下当前的环境

  1. 观察结果 : 在第一个运行主程序的终端中,你将看到日志输出,显示系统接收到文本指令,调用seewhat工具,并最终打印出由LLaVA模型生成的文字描述。然后扬声器也会播报生成的结果

4. 常见问题与解决方案

4.1 响应非常慢

问题 : 提问后,需要等很久才有语音回答。 解决方案 : 多模态模型的推理成本远高于纯文本模型,因此延迟较高是正常的。

  1. 使用更小的模型 : 在large_model_interface.yaml中,尝试使用更轻量的llava模型版本。