Skip to content

多模态应用入门 ​

多模态模型能直接理解图片、音频甚至视频:识别发票、读懂图表、把截图还原成页面、审核图片内容。第一次接入时,常见的意外是:

  • 上线一周,账单是预估的十倍,原因是用户上传的都是 4000 万像素的手机原图;
  • 有些照片的识别结果完全不对,后来发现图片是“躺着”的;
  • 发票识别的金额偶尔差一位小数,财务对账时才发现;
  • 模型描述了一个图片里根本不存在的物品,而且说得很肯定。

这篇讲清多模态模型的工作方式和成本结构,以及这些问题的处理方法。

读完这篇你会

  • 理解图片怎么变成 Token,以及它对成本和速度的影响
  • 在上传前正确地预处理图片
  • 判断哪些任务适合多模态,哪些需要传统方案或人工兜底

1. 原理:把图片切成小块,翻译成模型能读的“词” ​

文本模型处理的是 Token。多模态模型处理图片时,会先把图片切成很多小方块,再把每一块转换成模型内部的表示,相当于“图片版的 Token”。

text
原图 ──缩放到模型支持的尺寸──► 切成小方块 ──每块转换──► 一串“图像 Token” ──和文字一起──► 模型

这直接决定了几件事:

  • 像素越多,切出来的块越多,Token 就越多:费用更高、速度更慢;
  • 太小的细节可能被“压缩”掉:一张大图里很小的文字,缩放之后可能就看不清了;
  • 不同厂商的切块和计费规则不一样,接入前要查看所用模型的文档,用真实图片测算一次费用。

音频、视频也是类似的道理:音频按时长换算,视频通常是抽取若干帧图片,再加上音频。

2. 多模态擅长什么 ​

能力场景
图片理解识别物体和场景、解读图表、截图转代码、图片内容审核
文档理解发票、合同、表单、扫描件转成结构化数据
音频理解语音转文字、会议纪要
视频理解关键片段分析、生成字幕

和“先用 OCR 把图片转成文字、再交给文本模型”的方案相比,多模态模型能同时理解版式和内容,在表格、复杂排版的文档上通常更好。但它在精确性和成本上有明显的边界,后面会讲到。

3. 坑一:直接上传原图,费用和延迟暴涨 ​

现象:功能上线后,单次调用的费用和耗时都远超测试时的预估。日志显示用户上传的图片大多是手机拍摄的原图,单张 5~10MB。

原因:测试时用的是小截图,线上用户上传的是高分辨率原图。像素越多,Token 越多。而且很多模型会把超大的图片先缩小再处理,原图多出来的像素只是白白增加了上传时间。

修复:上传前在客户端压缩图片,把长边限制在模型推荐的尺寸范围内(具体数值参考所用模型的文档,常见的是一千多像素):

js
async function resizeImage(file, maxSide = 1536, quality = 0.85) {
  // 现代浏览器解码时会按照照片里的方向信息自动摆正,见坑二
  const bitmap = await createImageBitmap(file)
  const scale = Math.min(1, maxSide / Math.max(bitmap.width, bitmap.height))

  const canvas = document.createElement('canvas')
  canvas.width = Math.round(bitmap.width * scale)
  canvas.height = Math.round(bitmap.height * scale)
  canvas.getContext('2d').drawImage(bitmap, 0, 0, canvas.width, canvas.height)

  return new Promise((resolve) => canvas.toBlob(resolve, 'image/jpeg', quality))
}

需要识别小字的场景(比如发票上的细节),与其整体放大分辨率,不如先裁剪出目标区域,只把需要的部分发给模型。

怎么避免再犯:在日志里记录每次调用的图片尺寸和 Token 用量,设置费用告警。

4. 坑二:手机拍的照片,识别时是“躺着”的 ​

现象:同一张身份证照片,在相册里看是正的,识别结果却很差。把发给模型的图片保存下来一看,是横着的。

原因:手机拍照时,很多时候并不会真的旋转像素,而是在照片的 EXIF 信息里记录“这张图应该旋转 90 度显示”。相册应用会读取这个信息摆正显示;但如果处理图片的程序忽略了它,拿到的就是“躺着”的像素。

修复:在预处理阶段把方向“固化”到像素里。按照现行标准,浏览器的 createImageBitmap 默认会根据 EXIF 方向摆正图片,上面的压缩函数重新绘制一遍后,输出的就是方向正确、且不再依赖 EXIF 的新图片(较旧的浏览器行为可能不同,上线前用几张不同方向拍摄的照片实测一下)。在服务端处理时,使用图片库提供的“根据 EXIF 自动旋转”功能,作为第二道保险。

5. 坑三:发票上的数字偶尔识别错 ​

现象:发票识别整体准确率很高,但偶尔会把金额的小数点位置弄错、把 8 识别成 3,财务对账时才发现。

原因:多模态模型的输出依然是概率性的。对于密集的小字、相似的字符、复杂的表格,出错是必然会发生的,而且模型不会主动告诉你“这里我不太确定”。

修复:对关键字段做程序校验,让数据之间互相印证:

js
function validateInvoice(invoice) {
  const problems = []
  const itemsTotal = invoice.items.reduce((sum, item) => sum + item.amountCents, 0)
  if (itemsTotal !== invoice.subtotalCents) problems.push('明细合计与小计不一致')
  if (invoice.subtotalCents + invoice.taxCents !== invoice.totalCents) problems.push('小计加税额不等于总额')
  if (!/^\d{8,20}$/.test(invoice.invoiceNumber)) problems.push('发票号码格式异常')
  return problems // 有问题的发票转人工复核,而不是直接入账
}

怎么避免再犯:涉及金额、证件号码等关键数据时,设计好“校验 → 不通过就人工复核”的流程;在界面上把识别结果展示给用户确认,而不是悄悄入库。

6. 坑四:模型描述了图片里没有的东西 ​

现象:让模型描述商品图,它提到了“附赠的充电器”,但图片里根本没有充电器。

原因:和文本模型一样,多模态模型也会产生幻觉。它可能根据“这类商品通常会有什么”来推测,而不是严格描述画面内容。

修复:

  • 在提示词里明确要求“只描述图片中能看到的内容,看不清或不确定的写‘无法确定’”;
  • 对于审核、质检这类需要确定结论的场景,让模型输出明确的结构(比如每一项“是否存在”以及判断依据),再由规则或人工复核关键结论;
  • 精确计数(“图里有几个人”)、精确定位等任务,模型很容易出错,优先使用专门的检测算法。

7. 坑五:把证件照、病历发给了第三方模型 ​

现象:为了做“证件识别”,直接把用户的身份证照片发给了第三方模型服务,之后在合规检查中被指出问题。

原因:图片里往往包含大量个人敏感信息(身份证号、人脸、住址、病历内容),发送给外部服务就意味着数据离开了你的系统。

修复:

  • 明确告知用户并取得同意,确认服务商的数据处理和保存政策(是否用于训练、保存多久);
  • 只发送必要的部分:裁剪掉无关区域,对不需要识别的敏感信息先打码;
  • 对数据合规要求高的场景,考虑私有化部署的模型或本地的专用识别方案;
  • 识别结果和原图的保存期限要有明确的规定。

8. 什么时候不该用多模态 ​

情况更好的方案
文档本身就是可复制文字的 PDF直接提取文字,再交给文本模型
只需要识别规范的印刷体文字专用 OCR 引擎,更快、更便宜、更稳定
需要 100% 准确的计数或数值专用算法、程序校验或人工核对
实时性要求极高(几百毫秒内)端侧专用模型或传统算法
流量大、成本敏感先用便宜的方案筛选,只把难的部分交给多模态模型

只有那些“需要理解语义、版式多变、传统方案搞不定”的场景,才真正值得用多模态。

排查思路 ​

  1. 费用或延迟异常:查看日志中记录的图片尺寸、文件大小和 Token 用量,确认预处理是否生效。
  2. 识别结果差:把实际发送给模型的那张图片保存下来查看,检查方向、清晰度、目标区域是否被压缩得太小。
  3. 偶发错误:把出错的样本(经过脱敏、并取得授权)收集成测试集,每次调整提示词或更换模型时都跑一遍。
  4. 对比方案:同一批样本,分别用多模态模型和传统 OCR 跑一遍,比较准确率、速度和成本,用数据决定方案。

检查清单 ​

  • [ ] 上传前压缩图片,长边限制在模型推荐的范围内
  • [ ] 预处理时根据 EXIF 摆正图片方向
  • [ ] 需要细节时先裁剪目标区域,而不是整体放大
  • [ ] 关键字段有程序校验,不通过的转人工复核
  • [ ] 提示词要求只描述能看到的内容,不确定时明确说明
  • [ ] 敏感图片有用户授权、最小化发送和保存期限规定
  • [ ] 记录每次调用的图片尺寸、Token 用量和耗时,设置费用告警

延伸阅读 ​

为复用而记录,为理解而整理。