ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AI辅导系统如何实现视觉接地?拍照讲题Demo全解析

AI辅导系统如何实现视觉接地?拍照讲题Demo全解析 在 AI 辅导系统的开发中有一个很常见的需求学生上传一道几何题图片AI 能给出答案却说不清图上哪一条边对应哪一步。这个场景背后正是 Visual Grounding视觉接地要解决的问题。本文会从概念讲起结合完整可运行的“拍照讲题”Demo拆解如何把一个带视觉接地能力的 AI 辅导原型落地。无论你是做教育产品的后端开发还是刚接触多模态大模型的学生都能按这套流程把项目跑起来。1. 背景与核心概念什么是 AI Tutoring 与 Visual Grounding1.1 从“能做题”到“能讲题”的 AI 辅导系统传统意义上的 AI 辅导通常指知识库问答、题目搜索、答案解析这类能力。学生输入一道文字题AI 返回解题步骤和答案。这类系统对纯文字题目已经比较成熟但一旦进入数学几何、物理受力分析、化学实验图谱、生物结构图等场景问题就来了AI 知道答案是“两条边相等”但它没有告诉学生图上的哪两条边是相等的。用户需要的不是一句冷冰冰的答案而是像老师那样“指着图讲”。AI 要能圈出底边、标出高、框住关键条件再把讲解和图像位置对应起来。这种能力被称为“视觉接地”英文叫 Visual Grounding是 AI 辅导从“能做题”升级到“能讲题”的关键一步。如果拆开看一个带视觉接地能力的 AI 辅导系统至少包含三层能力看懂图像内容包括图形结构、文字区域、手写公式、图表坐标等。理解自然语言提问例如“哪条边是底边”“哪一步化简错了”“这个实验现象发生在哪个位置”。将语言描述映射到图像中的具体区域最终输出一个或多个坐标框让前端可以高亮标注。这三层能力分别涉及视觉理解、语义理解、跨模态对齐。近几年多模态大模型和开放词汇目标检测模型发展很快上述能力已经可以从原型走向工程化落地。1.2 Visual Grounding 是什么Visual Grounding中文常翻译为“视觉接地”或“视觉定位”。它的核心任务是给定一张图片和一句自然语言描述模型需要找出图片中与该描述对应的区域通常输出一个矩形框 bbox 或分割掩码 mask。举例来说输入图片一张三角形几何图。输入文本“三角形底边”。期望输出底边附近的坐标框[x1, y1, x2, y2]。这个任务在学术上也被称为 Referring Expression Comprehension即“指代表达理解”。它和我们常说的目标检测不太一样。传统目标检测是“类别限定”模型只会查找训练集中出现过的物体类别例如 person、car、cat而 Visual Grounding 的文本描述是开放式的可以是任意自然语言例如“图片左下角的红色三角形”“从 A 点到 B 点的辅助线”“第二行第三个选项”模型需要把语言和视觉区域进行对齐。它也不是 OCR。OCR 只负责从图像里识别文字内容而 Visual Grounding 可以定位“不是文字”的区域比如一条边、一个角、一个实验容器的位置。简单理解就是OCR 告诉 AI“图上写了什么字”Visual Grounding 告诉 AI“学生问的东西在图上的哪个位置”。1.3 为什么辅导场景必须引入视觉接地在 AI 辅导场景中引入视觉接地主要有四个价值第一提升讲解可理解性。人类教师讲题时天然会配合“指着图说话”的动作。AI 如果只会输出文字学生很难把抽象描述和具体图像对应起来一旦 AI 给出位置框讲解就能从“虚空描述”变成“视觉证据”。第二提高解题推理质量。很多几何、物理题目推理过程依赖图形中的位置关系。AI 若能先定位“关键区域”再针对该区域做推理逻辑会更加严谨也更容易发现学生的错误点。第三支撑自动批改和错因分析。比如学生手写作业拍照上传AI 需要定位到“某一道题”“某个步骤”“某个答案”才能判断对错而不是把整张图片当成一个整体。第四为 AI Agent 操作界面打基础。如果 AI 要进一步实现“点击演示”“框选重点”“在图上画辅助线”就必须具备视觉接地能力让模型知道往哪里点、往哪里画。所以Visual Grounding 不是炫技而是 AI 教育产品走向实用化的基础设施。2. AI 辅导 视觉接地的整体架构2.1 一条典型的“拍照-定位-讲解”链路一个最简单的 AI 拍照讲题系统可以按照下面的数据流来设计上传图片 题目文本 ↓ 视觉接地模型 → 得到候选区域 bbox ↓ 多模态大模型 → 基于 bbox 和图像生成讲解 ↓ 前端可视化 → 在原图标注框 步骤文字第一层是输入层负责接收用户上传的图片、题目文本以及可选的历史对话信息。第二层是定位层由视觉接地模型完成关键词或问题句到图像坐标的映射。第三层是讲解层一般由一个多模态大模型或教育领域模型完成它会把图像内容、定位结果、用户问题一起组织成自然语言讲解。最后一层是输出层返回给前端的不仅是文字还包括可视化标注数据例如框的坐标、标签、置信度。这套链路看起来简单但每个环节都有不少细节。实际项目中图片可能模糊、倾斜、反光题目可能是手写体用户提问也可能包含口语化表达。因此需要把视觉接地模型和讲解模型分开设计或者使用一个统一的多模态大模型同时完成定位和讲解。2.2 两种主流实现路线目前主流实现路线有两种两阶段路线和统一模型路线。两阶段路线是“视觉接地模型 多模态大模型”。先用 Grounding DINO、SAM、Florence-2 这类模型定位目标区域再把定位结果和图片一起交给 Qwen-VL、GPT-4V 等模型生成讲解。这种路线的好处是定位环节独立可控方便评估检测效果缺点是链路较长中间坐标如果处理不好讲解模型拿到的上下文会不够准确。统一模型路线是直接用一个大模型完成视觉、定位和文本生成。比如 Florence-2 把目标检测、区域描述、视觉问答等任务统一成序列生成任务Qwen2-VL、GPT-4V 这类多模态大模型也支持在对话中输出坐标框。这种路线开发效率高省去多模型拼接的复杂度缺点是模型更重部分场景下坐标精度可能不如专业检测模型。选型时主要看三点硬件条件、延迟要求、精度要求。如果只需要快速出 Demo优先选统一模型如果要上线到高并发生产环境且对坐标精度要求很高建议走两阶段路线把“定位”和“讲解”解耦分别优化。2.3 模块与数据流设计从工程角度看整个系统可以拆成四个模块输入模块负责图片上传、格式校验、压缩、方向校正。定位模块负责执行视觉接地任务绑定具体模型。讲解模块负责把定位结果转成教学语言可以选择本地模型或云端 API。输出模块负责封装统一 JSON 结构、保存标注图片、返回给前端。为了降低前后端耦合建议统一约定一个返回结构{ explanation: 讲解文本, marked_image: /static/uploads/marked_result.png, boxes: [ { label: 底边, bbox: [0.10, 0.80, 0.90, 0.95], score: 0.97 } ] }这里的 bbox 建议统一使用 0 到 1 的归一化坐标前端拿到原图宽高后再换算成像素坐标避免图片缩放导致标注偏移。3. 环境准备与依赖说明3.1 运行环境与硬件要求本文的示例代码以 Python 为主需要 Python 3.9 及以上版本。你可以在 Ubuntu 22.04、Windows WSL2 或 macOS 上运行但建议优先使用 Linux 环境因为很多视觉模型依赖的 CUDA 生态在 Linux 下最稳定。如果只是跑通 Mock 模式熟悉流程CPU 环境就足够。如果要加载 Florence-2、Grounding DINO、SAM 这类真实模型建议准备一块至少 16GB 显存的 GPU例如 RTX 4090、A10、A100 等。模型量化后可以降低显存需求但不建议新手一开始就做量化先把链路跑通更重要。3.2 依赖安装先创建项目目录和虚拟环境mkdir ai-tutor-grounding cd ai-tutor-grounding python -m venv venv source venv/bin/activate # Windows 使用 venv\Scripts\activate在项目目录下新建requirements.txttorch transformers accelerate opencv-python pillow flask requests然后在终端里执行安装pip install -r requirements.txt这里没有锁具体版本因为视觉模型相关的库更新非常快版本差异可能导致 API 不兼容。建议你在自己的环境里安装当前稳定版本如果遇到 API 变动以官方文档为准。3.3 项目结构本文示例项目结构如下ai-tutor-grounding/ ├── app.py # Flask 服务 ├── tutor.py # 核心逻辑接地引擎、讲解、画框 ├── requirements.txt ├── static/ │ └── uploads/ # 上传图片和标注图片存放目录 └── templates/ └── index.html # 前端演示页面这样划分后tutor.py可以独立测试app.py只负责 HTTP 接口后续替换模型时不需要大改服务层。4. 核心原理拆解视觉接地模型怎么工作4.1 目标检测、引用表达理解与视觉接地的边界理解 Visual Grounding 之前需要先分清几个概念目标检测Object Detection解决的是“图里有什么”输出类别和位置类别通常来自固定集合。引用表达理解Referring Expression Comprehension解决的是“用户说的东西在图哪里”输入是一句自然语言输出位置。Visual Grounding 在实际项目中经常等同于后者但它的范围更广可以包含指代表达、视觉定位、文本到区域匹配等子任务。在 AI 辅导场景中我们真正需要的是“开放式的指代表达理解”。因为学生可能会说“右边那个角的辅助线画错了”“第二问的化简结果”“图上标了红点的位置”这些表达无法靠固定类别覆盖。视觉接地模型通常包含三个模块图像编码器提取视觉特征文本编码器提取语言特征跨模态融合模块在图像和文本之间做对齐最终通过检测头或分割头输出坐标框或 mask。4.2 主流模型能力对比下面列几个常见的模型方向帮助大家快速认识选型空间模型 / 系列类型输入输出适用场景Grounding DINO开放词汇目标检测图像 文本描述bbox 类别区域定位常用两阶段路线SAM分割模型图像 点/框/文本 promptmask精确分割目标区域Florence-2统一多模态模型图像 任务指令文本 / bbox / mask多任务统一适合快速 DemoQwen2-VL多模态 LLM图像 对话文本文本 / bbox对话式讲解 定位GPT-4V闭源多模态 LLM图像 文本文本 / 位置引用效果强但要注意数据合规需要注意的是不同模型对“视觉接地”的表达形式差异很大。有的直接输出像素坐标有的输出归一化坐标有的输出带有自然语言的描述。工程落地时建议在“模型接入层”做统一封装无论底层用哪个模型对外都返回标准 JSON。4.3 坐标体系与归一化视觉接地模型最常见的输出格式是矩形框坐标。不同模型的坐标体系并不一致坐标范围可能是 0~1 的浮点数。坐标范围可能是 0~1000 的整数。坐标可能是相对原图的像素值。坐标可能经过了模型内部的输入分辨率缩放。如果前端展示时没有做坐标换算就会看到“框偏移”“框太小”“框位置错误”等问题。这里提供一个通用的归一化坐标转换函数def normalize_bbox(box, img_w, img_h, scale1000): 将模型输出的坐标统一为 0~1 归一化坐标。 实际使用时scale 要根据模型输出范围调整。 if scale and all(c scale for c in box): x_min, y_min, x_max, y_max [c / scale for c in box] else: x_min, y_min, x_max, y_max box x_min max(0, min(1, x_min)) y_min max(0, min(1, y_min)) x_max max(0, min(1, x_max)) y_max max(0, min(1, y_max)) return [x_min, y_min, x_max, y_max]这段代码只是演示思路。实际模型接入时一定要先打印模型原始输出明确坐标含义后再做转换否则很容易在坐标环节踩坑。5. 完整实战实现一个“拍照讲题”Demo5.1 场景定义与功能拆解我们要实现一个最小可运行的 AI 拍照讲题 Demo。用户上传一张图片输入一个问题例如“哪条边是底边”系统返回一段讲解文本。一张画好红框的图片。定位框的标准化数据。为了确保没有任何 GPU 的读者也能跑通完整流程我会先实现一个 Mock 接地引擎用规则返回模拟定位结果。Mock 模式跑通后再给出替换成真实模型的接入思路。功能拆解如下图片上传接口接收图片和问题文本。视觉接地引擎根据问题返回目标框。讲解生成根据问题、定位框生成讲解文字。图片标注在原始图片上绘制红色矩形框。前端页面上传图片、显示讲解、显示标注结果。5.2 先跑通 Mock 模式推荐大家先用 mock 模式把整条链路跑通。这样做的好处是可以先验证前后端交互、图片处理、坐标归一化、标注绘制这些工程逻辑是否正确再接入真实模型时只需要替换接地引擎内部实现。启动服务时通过环境变量控制export USE_MOCKtrue python app.py如果设置了USE_MOCKfalse则会尝试加载真实模型。5.3 核心逻辑 tutor.py创建tutor.py代码如下# 文件路径tutor.py import os from PIL import Image, ImageDraw USE_MOCK os.getenv(USE_MOCK, true).lower() in (1, true, yes) class GroundingEngine: 视觉接地引擎。 USE_MOCKtrue 时返回模拟定位结果用于先跑通完整链路 USE_MOCKfalse 时加载 Florence-2 等真实模型替换下方真实模型调用即可。 def __init__(self, use_mock: bool True): self.use_mock use_mock self.model None self.processor None if not self.use_mock: from transformers import AutoProcessor, AutoModelForCausalLM self.processor AutoProcessor
返回列表