五、谁更胜一筹?多模态模型VS传统方案

241 阅读13分钟

声明:我是引用的 付费文章,文章搬过来只是为了自己学习方便,不用每次输入验证口令。如果侵权,第一时间删除。 原文链接: gxlbvdk4ilp.feishu.cn/wiki/Vxh6w1…

前言

至此,我们已经围绕VLM+LLM做了一个全栈应用

细心的朋友可能会问,一些任务,传统OCR好像也可以做,他们有什么不同?

对!当下VLM之所以达到生产标准,也得益于OCR领域多年的数据积累

OCR的一些优势,在VLM当道的现在,也无法被取代

而这些微妙的可选择性,让我们在实际应用中可以根据具体需求灵活选择解决方案

OCR技术经过多年的发展,已经在许多场景下表现出极高的成熟度和可靠性,尤其是在处理结构化、规则明确的文字信息时,OCR的精度和效率几乎无可挑剔,例如:

银行票据处理、身份证件识别、发票扫描等任务

传统OCR依然占据着重要地位,然而,VLM(视觉语言模型)的优势在于其更强大的上下文理解能力和多模态处理能力,它不仅仅局限于识别文字本身,还可以结合图像内容、语义信息以及任务背景进行综合分析

这种能力使得VLM能够应对更加复杂和多样化的场景,比如从一张复杂的广告图片中提取关键信息并生成描述性文本,或者根据一段自然语言指令对图片中的元素进行操作

虽然VLM在某些方面展现出了超越OCR的能力,但并不意味着它可以完全取代OCR

相反,两者的结合才是未来发展的方向,例如,我们可以利用OCR作为基础工具来快速提取高质量的文字信息,再借助VLM完成更高层次的分析与决策

这种“强强联合”的模式不仅提升了整体系统的性能,拓宽应用场景的边界

你知道他们的能与不能,再跟着下一课,跑一个传统方案,你才能做到心中有数,得心应手

一、优劣势

正如技术发展史上无数次证明过的那样,没有一种技术是万能的,每种方法都有其独特的优势和局限性,而最终的选择取决于具体的业务需求和条件

在我们当下,我们更加希望能一次开发,在多个任务中,得到较高的重用率

对比OCR、VLM二者,我们看到这些:

维度OCRVLM
任务范围文字识别为主,聚焦于结构化文本提取多模态任务,支持文字、图像、语义的理解与生成
上下文理解缺乏上下文理解能力,主要依赖字符级别的特征匹配强大上下文理解能力,能结合图像与文本进行推理
灵活性对新领域适应性较差,需要重新调整模型或模板泛化能力强,可通过迁移学习快速适应新任务
交互性单向输出结果,较少支持动态交互支持双向互动,可通过对话形式接收指令并调整输出
计算复杂度较低,基于CNN/RNN等轻量化模型较高,基于Transformer架构,参数量巨大
推理速度快速,适合实时应用较慢,需平衡精度与效率
硬件依赖普通CPU即可运行,对GPU需求较小需要高性能GPU/TPU,尤其在大模型场景下
训练成本数据量有限,任务明确,训练成本较低海量多模态数据,训练成本极高

讲到底,现在数据类型任务的投入产出比太低了,多模态的高成本,导致高拓展、高复用的优势,都淡化了

汇总讲讲会影响我们选择技术栈的核心区别

1.1 任务范围

  • OCR主要聚焦于文字识别,适合处理清晰、结构化的文本数据
  • VLM则擅长处理非结构化或半结构化的多模态数据,能够在图像与文本之间建立深层次的关联

比如这张图,我们要把他作为可用数据,导入到你的AI应用中,你觉得应用什么技术栈接入?

这种需要深度理解的图像数据,使用OCR(第五课会实跑)来做,你通常只能得到几行文本,可用信息几乎为0

而,使用多模态,能把这张图的核心意图,理解之后,结构化输出(敢想吗):

{
  "assembly": {
    "name": "机械部件装配图",
    "description": "包含轴系组件的详细装配图",
    "dimensions": [
      { "label": "80", "value": 80, "unit": "mm" },
      { "label": "60", "value": 60, "unit": "mm" },
      { "label": "50", "value": 50, "unit": "mm" },
      { "label": "76", "value": 76, "unit": "mm" },
      { "label": "39", "value": 39, "unit": "mm" },
      { "label": "90", "value": 90, "unit": "mm" },
      { "label": "160", "value": 160, "unit": "mm" }
    ],
    "technical_requirements": [
      "装配前所有零件要用煤油清洗,机体内壁涂防锈油漆。",
      "固定调整轴承时,应留轴向间隙0.2~0.3mm。",
      "机体表面涂灰色油漆。"
    ]
  },
  "components": [
    {
      "part_number": 1,
      "name": "轴",
      "quantity": 1,
      "material": "45",
      "standard": "",
      "notes": ""
    },
    {
      "part_number": 2,
      "name": "螺母M35",
      "quantity": 1,
      "material": "中粗羊毛毡",
      "standard": "JB/T 4656-1997",
      "notes": "外购"
    },
    {
      "part_number": 3,
      "name": "轴承盖",
      "quantity": 1,
      "material": "HT200",
      "standard": "",
      "notes": ""
    },
    {
      "part_number": 4,
      "name": "圆锥滚子轴承",
      "quantity": 2,
      "material": "",
      "standard": "GB/T 276-1994",
      "notes": "外购"
    },
    {
      "part_number": 5,
      "name": "封油环",
      "quantity": 1,
      "material": "Q235",
      "standard": "",
      "notes": ""
    },
    {
      "part_number": 6,
      "name": "键14×9",
      "quantity": 1,
      "material": "45",
      "standard": "GB/T 1096-2003",
      "notes": "外购"
    },
    {
      "part_number": 7,
      "name": "大齿轮(m=3,z=10)",
      "quantity": 1,
      "material": "45",
      "standard": "",
      "notes": ""
    },
    {
      "part_number": 8,
      "name": "封油环",
      "quantity": 2,
      "material": "Q235",
      "standard": "",
      "notes": ""
    },
    {
      "part_number": 9,
      "name": "调整垫片",
      "quantity": 1,
      "material": "Q235",
      "standard": "",
      "notes": ""
    },
    {
      "part_number": 10,
      "name": "轴承盖",
      "quantity": 1,
      "material": "HT200",
      "standard": "",
      "notes": ""
    }
  ],
  "assembly_structure": {
    "main_component": {
      "part_number": 1,
      "name": "轴",
      "children": [
        {
          "part_number": 2,
          "name": "螺母M35",
          "position": "轴端"
        },
        {
          "part_number": 3,
          "name": "轴承盖",
          "position": "轴端"
        },
        {
          "part_number": 4,
          "name": "圆锥滚子轴承",
          "position": "轴上"
        },
        {
          "part_number": 5,
          "name": "封油环",
          "position": "轴上"
        },
        {
          "part_number": 6,
          "name": "键14×9",
          "position": "轴槽内"
        },
        {
          "part_number": 7,
          "name": "大齿轮(m=3,z=10)",
          "position": "轴上"
        },
        {
          "part_number": 8,
          "name": "封油环",
          "position": "轴上"
        },
        {
          "part_number": 9,
          "name": "调整垫片",
          "position": "轴承盖与机体之间"
        },
        {
          "part_number": 10,
          "name": "轴承盖",
          "position": "轴端"
        }
      ]
    }
  },
  "design_notes": {
    "designer": "机械设计课程设计",
    "reviewer": "",
    "date": ""
  }
}

1.2 上下文理解

  • 传统OCR通常缺乏对上下文的理解,难以处理模糊、变形或嵌入复杂背景中的文字
  • VLM通过融合视觉和语言模型,具备更强的推理能力,可以推测出隐含的语义信息,甚至纠正错误的输入

直接来一题【简单】物理题目:

OCR只能识别,无法理解上下文,直接罢工!

我们看看多模态接入后,对于数据的理解:

题目描述了一个光学问题,涉及平面镜反射和视角范围。具体如下:
已知条件 :
水平地面上有一个障碍物 ABCD。
一个较大的平面镜 MN 水平放置在某一高度
眼睛位于点 O
问题要求 :
使用作图法求出眼睛从平面镜中能看到的障碍物后方地面的范围
如果想在原处看到更大范围的地面,水平放置的镜子的高度应如何调整
解题步骤
第一步:理解平面镜成像原理
根据平面镜成像的原理,物体在平面镜中的像是虚像,且像与物体关于平面镜对称。因此,要确定眼睛通过平面镜能看到的范围,需要考虑以下几点:
光线从障碍物的边缘(如 AB)反射到平面镜 MN,再反射到眼睛 O
反射光线遵循“入射角等于反射角”的规律
第二步:作图法确定能看到的范围
为了确定眼睛能看到的范围,我们需要作图分析:
确定障碍物的边缘点 :
假设障碍物的两个关键点是 AB
作平面镜的对称点 :
根据平面镜成像原理,AB 在平面镜中的像分别是 A′ 和 BA′ 和 B′ 的位置可以通过作图得到,它们与 AB 关于平面镜 MN 对称
连接眼睛 O 和像点 A′、B′ 
从眼睛 O 分别向 A′ 和 B′ 作直线。
这两条直线与地面的交点分别标记为 PQ
确定能看到的范围 :
地面上从 PQ 的区域就是眼睛通过平面镜能看到的范围
第三步:调整镜子高度以增大视野
如果想在原处看到更大范围的地面,需要调整平面镜的高度。根据几何关系:
当平面镜的高度降低时,像点 A′ 和 B′ 会更靠近地面
连接眼睛 O 和新的像点 A′、B′ 的直线会与地面形成更大的夹角,从而能看到更广阔的地面范围
因此,镜子的高度应该降低

最终答案
如果想在原处看到更大范围的地面,水平放置的镜子的高度应 降低 

因此,我们看到很多VLM,都可以具备批改作业的水平!

1.3 灵活性与泛化能力

  • OCR更多是单向输出结果,较少涉及人机交互
  • VLM则支持双向互动,可以通过对话形式接收用户指令,并动态调整输出内容

这才是AI应用该有的样子!

多模态可以直接接入到应用中,可以直接拿着图片与他对话,甚至生产!

而OCR,只能识别,不具备互动属性!

任务:识别身份证号码

OCR方案:

from PIL import Image
import pytesseract

# 加载身份证图片
image_path = "id_card.jpg"
image = Image.open(image_path)

# 使用OCR提取文字
extracted_text = pytesseract.image_to_string(image)

# 输出结果
print("提取的文字内容:", extracted_text)

运行结果 :

提取的文字内容: 
姓名: 张三
身份证号: 123456789012345678
地址: 北京市朝阳区某街道

VLM方案:

from vlmsdk import VisionLanguageModel

# 初始化VLM模型
vlm = VisionLanguageModel()

# 加载身份证图片
image_path = "id_card.jpg"

# 第一轮对话:提取所有信息
response1 = vlm.ask(image_path, "请告诉我这张图片中的所有信息。")
print("第一轮回答:", response1)

# 第二轮对话:提取特定字段
response2 = vlm.ask(image_path, "请告诉我身份证号是多少?")
print("第二轮回答:", response2)

# 第三轮对话:更复杂的需求
response3 = vlm.ask(image_path, "如果这个人的生日是1990年1月1日,请告诉我他今年多少岁?")
print("第三轮回答:", response3)

运行结果 :

第一轮回答: 这是一张身份证图片,包含以下信息:姓名为张三,身份证号为123456789012345678,地址为北京市朝阳区某街道
第二轮回答: 身份证号是123456789012345678
第三轮回答: 根据提供的生日信息,这个人今年33岁

你想喔,一些复杂的任务,比如客服场景,货物理赔,接入多模态:

VLM:“根据图片显示,商品的外壳有轻微划痕,但功能部件完好,建议联系售后维修”

这如果接入到传统方案,如何完成这个任务?

那OCR是不是就一点用处都没有呢?

我们列了一些OCR擅长干的任务,后面,也会用OCR来跑一个生产任务!

二、OCR并非一无是处啊

推理一个VLM,GPU花销是刚需,而许多任务,资源都非常珍贵

一些简单任务,这些特性,让OCR还是成为首选:

2.1 稳定性

VLM最大的风险,就是幻觉与不稳定性,这恰恰是OCR的优势

经过多年的研究和实践,已经高度成熟,尤其是在特定领域(如票据识别、身份证件识别等)表现出了极高的稳定性和可靠性

优势:
  • 高精度 :OCR在处理清晰、规则化的文本时,识别准确率非常高,通常可以达到99%以上
  • 抗干扰能力强 :经过优化的OCR模型能够很好地应对常见的干扰因素,例如噪声、倾斜、字体变化等
  • 结果一致性 :OCR的输出通常是固定的格式,便于后续处理。例如,在发票识别场景中,OCR可以直接返回结构化数据(如金额、日期、发票号),而无需额外的后处理逻辑
这些优势,让他可以在许多需求严谨场景应用:
  • 银行票据处理 :OCR被广泛应用于支票、汇票等票据的自动识别。由于票据模板固定且内容规范,OCR能够以极高精度提取关键信息,避免人工录入错误
  • 身份证件识别 :OCR在身份证、护照等证件识别中表现出色,能够快速提取姓名、身份证号、出生日期等字段,并生成结构化数据供后续系统使用

后面,我们会使用它,接入LLM,去生产数据!

2.2 轻量化

OCR模型通常设计得非常轻量化,适合在资源受限的设备上运行

优势:
  • 参数量小 :相比VLM动辄数十亿甚至上千亿参数的大模型,OCR模型的参数量通常只有几百万到几千万,计算开销显著降低
  • 部署灵活 :OCR可以在普通的CPU上运行,甚至可以在嵌入式设备(如树莓派、智能手机)上实现高效的实时处理
  • 能耗低 :由于计算需求较低,OCR在边缘设备上的能耗也更低,非常适合长时间运行的应用场景
实际应用示例:
  • 移动设备上的文档扫描 :许多手机App(如Adobe Scan、Microsoft Office Lens)都可以集成OCR功能,用户可以通过手机摄像头快速扫描文档并提取文字,这些应用能够在本地完成OCR处理,无需依赖云端服务

  • 工业自动化 :在制造业中,OCR被用于读取产品标签上的序列号或生产日期。这种场景通常需要在工厂现场进行实时处理,而OCR的轻量化特性使其成为理想选择

这些特性,你要结合整个项目可支配的资源、任务、目标,综合权衡

所以,不管你的是什么项目,应该都能在这些任务中,找到取舍!

下一课,我们会用传统方案,接入LLM中,去做财务票据的数据提取、结构化输出!

三、视频