资讯动态

029、VLM在机器人视觉问答中的应用:从场景理解到任务决策

发布时间:2026/8/19 20:57:50 来源:尧图企业网站定制
029、VLM在机器人视觉问答中的应用从场景理解到任务决策昨天半夜在实验室调一个抓取demo机械臂死活认不出桌面上的红色马克杯——不是识别不到是它把杯子和旁边的红色胶带卷搞混了。我盯着屏幕上的CLIP相似度分数看了十分钟突然意识到问题不在视觉编码器而在prompt设计。这个场景太典型了值得单独写一篇。从看到什么到该做什么的鸿沟传统视觉系统输出的是检测框、分割掩码、类别标签这些是名词。但机器人执行任务需要的是动词名词约束条件——比如用两指夹爪从侧面捏住杯柄施加2N力抬升15cm。VLM视觉语言模型的介入让这个跨越成为可能但前提是你得知道怎么跟它对话。我见过太多人直接把VLM当黑盒用输入一张图加一句what should I do?然后期待输出一个可执行的轨迹。现实是模型会给你一段充满幻觉的散文。关键区别在于VLM不是规划器它是感知到决策之间的翻译器。你要做的是设计好翻译的中间格式。场景理解别让模型猜你问什么先解决最基础的问题——让VLM准确描述场景。这里有个反直觉的坑你给的指令越自然模型越容易出错。比如描述这个场景这种开放性问题VLM会给你一段包含背景噪音的冗长描述而机器人真正需要的可能只是桌面上有三个物体红色马克杯中心坐标320,240银色金属罐蓝色海绵。我的做法是强制结构化输出。用JSON schema约束回答格式每个物体包含类别、位置、颜色、姿态估计、可抓取性判断。这里踩过坑一开始我让模型直接输出坐标结果它经常把像素坐标和归一化坐标搞混。后来我改成让它输出物体在图像中的相对位置左/中/右上/中/下再用传统视觉方法精确定位。混合方案比纯VLM方案稳定得多。另一个关键点是上下文注入。单张图对VLM来说信息量太大它会平均分配注意力。我习惯先做一次粗检测用YOLO或者Grounding DINO把候选区域裁剪出来再让VLM针对每个区域做细粒度分析。这样既保留了VLM的语义理解能力又避免了它在杂乱背景中迷失。别这样写直接整图输入然后期望模型自己找到重点除非你的场景极其干净。任务决策把VLM输出变成机器人动作当VLM理解了场景下一步是让它参与决策。这里我推荐分层设计高层用VLM做任务分解和物体选择低层用传统规划器或RL策略执行具体动作。举个例子任务指令是把红色杯子放到蓝色托盘里。VLM需要回答三个问题哪个是红色杯子哪个是蓝色托盘当前状态离目标状态差几步第一个问题通过视觉 grounding 解决第二个类似第三个需要模型理解空间关系和操作顺序。我在实际代码里是这样做的先让VLM输出一个结构化动作序列比如[{action: pick, target: red_mug, grasp_point: handle, approach_vector: [0, -1, 0]}, {action: place, target: blue_tray, position: center}]。然后每个动作映射到具体的运动规划器。这里有个重要经验不要指望VLM直接输出关节角度或末端坐标它没有那个精度。VLM负责语义决策数值计算交给确定性算法。代码实现一个最小可用的VQA机器人模块下面是我在项目里实际用的一个简化版本去掉了一些工程细节保留核心逻辑。importjsonimporttorchfromtransformersimportAutoProcessor,AutoModelForVisionText2TextfromPILimportImage# 这里踩过坑不同版本的transformers对VLM的支持差异很大# 我用的是llava-1.5-7b如果你用更新的模型注意调整prompt格式model_idllava-hf/llava-1.5-7b-hfprocessorAutoProcessor.from_pretrained(model_id)modelAutoModelForVisionText2Text.from_pretrained(model_id,torch_dtypetorch.float16,device_mapauto)# 关键定义输出格式用few-shot示例引导模型SYSTEM_PROMPTYou are a robot perception assistant. Given an image and a task instruction, output a JSON object with: - objects: list of detected objects, each with name, bbox (relative coordinates 0-1), graspable (bool) - plan: list of action steps, each with action (pick/place/push), target, constraints Example: Input: Move the apple to the green bowl Output: {objects: [{name: apple, bbox: [0.2, 0.3, 0.4, 0.5], graspable: true}, {name: green_bowl, bbox: [0.6, 0.7, 0.8, 0.9], graspable: false}], plan: [{action: pick, target: apple, constraints: top-down grasp}, {action: place, target: green_bowl, constraints: center}]} defvlm_scene_understanding(image_path,task_instruction):imageImage.open(image_path)# 构建对话格式注意llava需要特殊的chat template# 别这样写直接拼接字符串llava对格式敏感必须用processor的chat templatemessages[{role:system,content:SYSTEM_PROMPT},{role:user,content:fTask:{task_instruction}. Analyze the scene and output JSON.}]promptprocessor.apply_chat_template(messages,add_generation_promptTrue)inputsprocessor(textprompt,imagesimage,return_tensorspt).to(model.device,torch.float16)# 生成参数调优经验temperature别太高0.1-0.3之间# max_new_tokens根据输出复杂度调整我一般给512outputmodel.generate(**inputs,max_new_tokens512,temperature0.2,do_sampleFalse,# 这里用贪心解码减少随机性pad_token_idprocessor.tokenizer.pad_token_id)responseprocessor.decode(output[0],skip_special_tokensTrue)# 提取JSON部分模型有时会输出额外文本try:# 找到第一个{和最后一个}之间的内容startresponse.find({)endresponse.rfind(})1json_strresponse[start:end]resultjson.loads(json_str)returnresultexceptjson.JSONDecodeError:# 这里踩过坑模型偶尔会输出不合法JSON需要重试或降级处理print(fJSON parse failed. Raw response:{response})returnNone# 使用示例if__name____main__:resultvlm_scene_understanding(table_scene.jpg,Pick up the red mug and place it on the saucer)ifresult:print(Detected objects:,result[objects])print(Action plan:,result[plan])这段代码在真实机器人上跑的时候我发现几个问题值得注意。第一VLM的推理速度很慢7B模型在A100上也要几百毫秒在Jetson上可能要几秒。所以不能每帧都调用我通常只在任务开始时调用一次或者当场景发生显著变化时用帧差检测触发。第二输出中的bbox是相对坐标需要乘以图像尺寸得到像素坐标再经过相机标定转到机器人坐标系。实验与调优那些让你怀疑人生的时刻我在一个桌面抓取任务上对比了不同方案。纯视觉方法YOLO规则在固定场景下准确率95%但换一个背景就掉到60%。VLM方案在多样场景下能保持85%左右但偶尔会犯低级错误——比如把阴影当成物体。调优过程中最有效的三个手段一是few-shot示例的质量我手工标注了20个典型场景覆盖不同光照、遮挡、物体组合模型表现提升明显二是输出格式约束用正则表达式强制JSON结构减少解析失败三是置信度阈值当VLM输出graspable: false时不要硬抓触发重试或人工介入。还有一个容易被忽视的点VLM对语言指令的措辞很敏感。我测试过pick up the mug和grasp the mug前者更容易触发正确的抓取姿态。这可能是因为训练数据中pick up更常与完整操作关联。所以我在系统里加了一个指令规范化模块把用户输入映射到一组预定义的动作模板上。落地经验别把VLM当万能钥匙最后说点实在的。VLM在机器人视觉问答中的定位应该是语义增强器而不是唯一感知源。我的建议是构建一个混合感知管线传统视觉方法负责快速、精确的几何信息提取VLM负责处理模糊语义、开放词汇、复杂关系推理。两者通过一个简单的仲裁机制结合——当传统方法置信度高时直接用低时交给VLM兜底。另外模型选择上别盲目追新。7B级别的VLM在边缘设备上勉强可用13B以上基本只能云端推理。如果你的机器人需要实时响应考虑蒸馏一个小模型专门做场景理解或者用API调用云端VLM但加上本地缓存。调试VLM时最痛苦的是不确定性——同样的输入两次推理可能给出不同结果。我的经验是固定随机种子、关闭采样、增加温度惩罚把输出确定性提到最高。如果业务允许还可以做多数投票跑三次取一致结果。这篇先写到这里。下一期我打算聊聊怎么用VLM做失败检测——就是机器人执行完动作后让VLM判断任务是否真的完成了。这个场景比任务规划更实用也更容易踩坑。有问题欢迎评论区交流我尽量回复。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价