1.场景:票据信息结构化提取
某客户业务中涉及的票据类型繁多,包括手写票据、打印小票、文档电子表格等,如下图所示。客户希望利用我们的多模态大模型qwen-vl来将这些不同类型的票据信息提取为结构化数据,以便后续进行自动化处理和分析。最关键的需求是确保所提取的票据信息准确无误,尤其是关键信息(如编号编码),不能遗漏也不能出现错误。这将使客户能够更高效地管理他们大量的票据数据,减少人工处理的工作量,提高工作效率。
2.难点:VL-LLM
测试方案可以从最简单的方式开始,即直接调用qwen-vl。只需将图片上传至OSS,然后编写一段提示即可让大模型为我们处理任务。通过api调用qwen-vl模型_大模型服务平台百炼(Model Studio)-阿里云帮助中心 (aliyun.com)[1]。
测试样例为下图:
prompt如下:
prompt_with_message=""" 请结合图片输出结构化的JSON信息。注意要返回完整的数据,不能遗漏,不能省略; 对于包含多行的项目用列表表示;只输出JSON不要输出任何额外内容;不同行的内容应该分别输出 """
调用最新的vl-max-0809模型:
messages = [ { "role": "user", "content": [ {"image": url}, {"text": prompt_with_message} ] } ] response = dashscope.MultiModalConversation.call( model='qwen-vl-max-0809', messages=messages)
响应结果:见评论区
对比图片内容可以看出,存在以下关键信息的错误:
- “收货单位:家宴”识别成了“发票单位:某宾馆”
- 货名“80/30无芯40”与“57/40刷卡纸”识别成了"货物名称": ["57/40无芯纸", "80/30无芯纸"]
- “单价”: [145.00, 530.00],“金额”: [290.00, 2120.00], “金额合计”: 2410.00 也与票据信息对应不上
- 出现了签收日期、签收人图中本来不存在的幻觉信息。
这个例子可以看到,使用VL-LLM在“从图像中提取文本”这个特定场景中的效果有时并不太好,但在其他语义指令上,比如“输出json格式数据”,是有效的。
那么如果有其他方式可以更快更好地处理“从图像中提取文本”这个任务呢?受语言大模型中"RAG"思路的启发,也许我们可以先提取图像中的文本,然后将其作为“知识参考”输入VL-LLM,结合VL-LLM强大的语义理解能力,或许就能够准确提取出票据中的信息,并输出结构化数据。
那么给到VL-LLM的prompt template就会是这样的:
prompt_with_message=f"""供参考的票据文字如下,输出时结合上下文对有错误的予以纠正。 {text} 请结合图片输出结构化的JSON信息。注意要返回完成的数据,不能遗漏,不能省略; 对于包含多行的项目用列表表示;只输出JSON不要输出任何额外内容;不同行的内容应该分别输出 """
目前的任务是要获取图像中的文字内容,也就是说,我们想知道图中的文字有哪些,这让我们很容易联想到文本识别领域中的“老炮儿”——OCR技术。
3.比较:OCR与VL-LLM
问:OCR是什么?
通义千问:OCR是光学字符识别(Optical Character Recognition)的缩写,是一种技术,用于将印刷文本、手写文字或文档中的字符转换为机器编码的文本。通过扫描或拍照的方式捕捉文字图像,然后利用计算机软件分析图像中的字符形状,并将其转换成可编辑和可搜索的数据。这种技术在很多领域都有应用,比如文档数字化、数据录入、书籍扫描、发票处理等,大大提高了信息处理的效率和准确性。
尽管多模态大模型也具备通用的文本识别能力,但OCR技术在不同的业务场景下可以通过特定的训练和加强。例如,阿里云产品文字识别_OCR 文字识别_图片识别文字_数据智能-阿里云 (aliyun.com)[2]覆盖了通用文字识别、个人证照识别、车辆物流识别、票据凭证识别、企业资质识别和混贴等多个场景。
我们将OCR与VL-LLM做个对比:
4.合作:OCR + VL-LLM
因此,我们想到在原有方案的基础上加入OCR作为辅助,让OCR与VL协同工作:
考虑到手写票据的情况,我们利用阿里云OCR产品的通用手写体识别接口调用:
RecognizeHandwriting进行通用手写体识别_文字识别(OCR)-阿里云帮助中心 (aliyun.com)[3],逐行识别图像中的中文文字,并将所识别的文字替换prompt中的{text},提供给大模型作为参考。这样做类似于VL中的“RAG”(Retrieval-Augmented Generation)模式,既结合了OCR高精准文本识别的能力,同时也利用了大模型的指令分析和上下文理解等优势。
5.效果对比
以下case中vl模型使用qwen-vl-max-0809,ocr使用阿里云OCR通用手写体识别。
case1:
- OCR,耗时:0.7s,识别结果:
****纸品 送货单 NO:20240323******* 收货单位:**家宴洛溪店 送货日期:2024年3月23日 编号 货 名 规格 单位 数量 单价 金额 备注 1 80/30无芯40 箱 4 145.00 580.00 2 57/40刷卡纸 箱 2 80.00 160.00 金额合计(大写):柒佰肆拾元整 6 Y740.00 送货单位及经手人(签章):收货单位及经手人(签名):恒 审核员:复核员:三
可以看到与只有VL-LLM结果相比,融合方案结果中的关键信息收货单位、货物名称、金额、总价等都输出正确。
VL |
OCR+VL |
```json { "发票单位": "**某宾馆", "送货单号": "20240323******", "送货日期": "2024年3月23日", "送货单位及经手人": "****纸品", "收货单位及经手人": "****纸品", "货物名称": ["57/40无芯纸", "80/30无芯纸"], "规格": ["57/40", "80/30"], "单位": ["箱", "箱"], "数量": [2, 4], "单价": [145.00, 530.00], "金额": [290.00, 2120.00], "金额合计": 2410.00, "金额合计(大写)": "贰仟肆佰壹拾元整", "备注": "", "签收人": "张三", "签收日期": "2024年3月23日" } ```
|
```json { "company_name": "****纸品", "document_type": "送货单", "document_number": "20240323******", "recipient_unit": "**家宴洛溪店", "delivery_date": "2024年3月23日", "items": [ { "item_number": "1", "item_name": "80/30无芯40", "specification": "箱", "unit": "箱", "quantity": 4, "unit_price": 145.00, "total_amount": 580.00 }, { "item_number": "2", "item_name": "57/40刷卡纸", "specification": "箱", "unit": "箱", "quantity": 2, "unit_price": 80.00, "total_amount": 160.00 } ], "total_amount": "柒佰肆拾元整", "total_amount_numeric": 740.00, "delivery_unit_and_handler": "", "recipient_unit_and_handler": "", "reviewer": "", "checker": "", "seal": "****纸品" } ``` |
case2:
- OCR,耗时:0.75s,识别结果:
骨*购物 收银员:0012 机号:018 时间:2024.05.06 16:20 品名 数量 t 单价 小计 绿箭无糖花香薄荷糖樱花白桃味 20202058 2 12.50 25.00 西兰花(散) 10100335 0.582 13.16 7.66 中购物袋 70700002 0.20 0.20 [惠]水产扁蚕蛹(散) 10400287 0.284 13.80 3.92 原价:19.80 油蟠桃(盒) 10100208 1 19.90 19.90 QQ南瓜(散) 10101272 1.102 5.96 6.57 鳕鱼片(散) 10200357 0.172 98.00 16.86 冻干糖葫芦(散) 10200406 0.246 98.00 24.11 整单优惠:1.70 抹零:0.02 件数:9 应付:104.20 实收:山东一卡通人民币 104.20 小票号:NO.2024050****** 会员消费-卡号(600*****) 本次积分(100.30) 最 最新积分(14404. 07) 电子储零(0) 如需发票,请持此单致客服中心开换 散称商品重量以称签重量为准 热线电话:xxxxxxxx 地址:xxxxxxxxxx 谢谢惠顾,欢迎下次光临!
这个案例两个方案的输出信息基本准确无误,在格式上略有区别。OCR把“昌隆”识别为“骨隆”,大模型并没有采用。
VL | OCR+VL |
```json { "store": "昌*购物", "cashier": "0012", "machine_number": "018", "date": "2024.05.06", "time": "16:20", "items": [ { "name": "绿箭无糖花香薄荷糖樱花白桃味", "code": "20202058", "quantity": 2, "unit_price": 12.50, "total": 25.00}, { "name": "西兰花(散)", "code": "10100335" ,"quantity": 0.582, "unit_price": 13.16, "total": 7.66}, { "name": "中购物袋", "code": "70700002", "quantity": 1, "unit_price": 0.20,"total": 0.20 }, { "name": "水产扁蚕蛹(散)", "code": "10400287", "quantity": 0.284, "unit_price": 13.80, "total": 3.92}, { "name": "油蟠桃(盒)", "code": "10100208", "quantity": 1, "unit_price": 19.90, "total": 19.90 }, { "name": "QQ南瓜(散)", "code": "10101272" ,"quantity": 1.102, "unit_price": 5.96, "total": 6.57 }, { "name": "鳕鱼片(散)", "code": "10200357", "quantity": 0.172, "unit_price": 98.00, "total": 16.86 }, { "name": "冻干糖葫芦(散)", "code": "10200406", "quantity": 0.246, "unit_price": 98.00, "total": 24.11 } ], "discount": 1.70, "rounding": 0.02, "total_items": 9, "total_amount": 104.20, "payment": 104.20, "payment_method": "**一卡通人民币", "receipt_number": "NO.20240********", "member_number": "600******", "points_earned": 100.30, "current_points": 14404.07, "electronic_wallet": 0, "note": "如需发票,请持此单致客服中心开换!", "note2": "散称商品重量以称签重量为准", "contact_number": "**", "address": "**", "greeting": "谢谢惠顾,欢迎下次光临!" } ```
|
```json { "store": "昌*购物", "cashier": "0012", "machine_number": "018", "date": "2024.05.06", "time": "16:20", "items": [ { "name": "绿箭无糖花香薄荷糖樱花白桃味", "code": "20202058", "quantity": 2, "unit_price": 12.50, "total": 25.00 }, { "name": "西兰花(散)", "code": "10100335", "quantity": 0.582, "unit_price": 13.16, "total": 7.66}, { "name": "中购物袋", "code": "70700002", "quantity": 1, "unit_price": 0.20, "total": 0.20}, { "name": "[惠]水产扁蚕蛹(散)", "code": "10400287", "quantity": 0.284,"unit_price": 13.80, "total": 3.92}, { "name": "油蟠桃(盒)", "code": "10100208", "quantity": 1, "unit_price": 19.90, "total": 19.90 }, { "name": "QQ南瓜(散)", "code": "10101272", "quantity": 1.102, "unit_price": 5.96, "total": 6.57 }, { "name": "鳕鱼片(散)", "code": "10200357", "quantity": 0.172, "unit_price": 98.00, "total": 16.86}, { "name": "冻干糖葫芦(散)", "code": "10200406", "quantity": 0.246, "unit_price": 98.00, "total": 24.11} ], "discount": 1.70, "rounding": 0.02, "total_items": 9, "total_amount": 104.20, "payment": { "method": "**一卡通人民币", "amount": 104.20}, "receipt_number": "NO.2024050**********","member": { "card_number": "600*****", "points": { "current": 100.30,"total": 14404.07 } }, "electronic_storage": 0, "note": "如需发票,请持此单致客服中心开换", "note2": "散称商品重量以称签重量为准", "contact": {"phone": "**","address": "**"}, "greeting": "谢谢惠顾,欢迎下次光临!"} ```
|
case3:
- OCR,耗时:1s,识别结果:
送货单 *****农牧开发有限公司 第2/3页 番禺配送中心 日期:2024-03-18 车牌号:502 单据编号:p4-030042-XS-******* 收货单位 ****(**) 编号 商品全名 规格 单位 数量 单价 金额 备注 家乡龙口粉丝 包 2 4.5 9 菠菜面 包 2 6 12 南瓜面 包 2 6 12 鲜牛肉 7 斤 3.23 50 150 160 鲈鱼骨 斤 5 2. 10 美味源胡椒粉 包 1 6.5 6.5 雀巢美极鸡鲜粉 包 40.5 40.5 刀板香 斤 1.21 26 2 31.2 湖南辣椒 斤 6 6.5 39 独蒜 斤 2 18 36 页小计 每页合计:元 Address:******** Tel:152171***** 制单员:** 收货单位签章:1月1 七 13
图中“鲜牛肉”和“刀板香”的数量和金额都有人为的手写修改,OCR把修改前后都输出了,而大模型在输出时结合图片内容正确输出了最终的数量与金额,体现了大模型在图像内容分析、上下文理解上的优势。
VL | OCR+VL |
```json { "公司名称": "*****农牧开发有限公司", "配送中心": "***配送中心", "日期": "2024-03-18", "车牌号": "502", "单据编号": "p4-030042-XS-2*******", "收货单位": "***(南沙店)", "商品信息": [ { "编号": "1", "商品全名": "家乡龙口粉丝", "规格": "包", "单位": "包", "数量": "2", "单价": "4.5", "金额": "9" }, { "编号": "2", "商品全名": "菠菜面", "规格": "包", "单位": "包", "数量": "2", "单价": "6", "金额": "12" }, { "编号": "3", "商品全名": "南瓜面", "规格": "包", "单位": "包", "数量": "2", "单价": "6", "金额": "12" }, { "编号": "4", "商品全名": "鲜牛肉", "规格": "斤", "单位": "斤", "数量": "3.2", "单价": "50", "金额": "160" }, { "编号": "5", "商品全名": "鲈鱼骨", "规格": "斤", "单位": "斤", "数量": "5", "单价": "2", "金额": "10" }, { "编号": "6", "商品全名": "美味源胡椒粉", "规格": "包", "单位": "包", "数量": "1", "单价": "6.5", "金额": "6.5" }, { "编号": "7", "商品全名": "雀巢美极鸡鲜粉", "规格": "包", "单位": "包", "数量": "1", "单价": "40.5", "金额": "40.5" }, { "编号": "8", "商品全名": "刀板香", "规格": "斤", "单位": "斤", "数量": "1.2", "单价": "26", "金额": "31.2" }, { "编号": "9", "商品全名": "湖南辣椒", "规格": "斤", "单位": "斤", "数量": "6", "单价": "6.5", "金额": "39" }, { "编号": "10", "商品全名": "独蒜", "规格": "斤", "单位": "斤", "数量": "2", "单价": "18", "金额": "36" } ], "页小计": "343.7", "地址": "*******", "制单员": "***", "联系电话": "15217******", "收货单位签章": "****" } ``` |
```json { "送货单": { "公司名称": "****农牧开发有限公司", "配送中心": "***配送中心", "日期": "2024-03-18", "车牌号": "502", "单据编号": "p4-030042-XS-2*****", "收货单位": "****(南沙店)", "商品列表": [ { "编号": "", "商品全名": "家乡龙口粉丝", "规格": "", "单位": "包", "数量": 2, "单价": 4.5, "金额": 9, "备注": "" }, { "编号": "", "商品全名": "菠菜面", "规格": "", "单位": "包", "数量": 2, "单价": 6, "金额": 12, "备注": "" }, { "编号": "", "商品全名": "南瓜面", "规格": "", "单位": "包", "数量": 2, "单价": 6, "金额": 12, "备注": "" }, { "编号": "", "商品全名": "鲜牛肉", "规格": "7", "单位": "斤", "数量": 3.23, "单价": 50, "金额": 160, "备注": "" }, { "编号": "", "商品全名": "鲈鱼骨", "规格": "", "单位": "斤", "数量": 5, "单价": 2, "金额": 10, "备注": "" }, { "编号": "", "商品全名": "美味源胡椒粉", "规格": "", "单位": "包", "数量": 1, "单价": 6.5, "金额": 6.5, "备注": "" }, { "编号": "", "商品全名": "雀巢美极鸡鲜粉", "规格": "", "单位": "包", "数量": 1, "单价": 40.5, "金额": 40.5, "备注": "" }, { "编号": "", "商品全名": "刀板香", "规格": "", "单位": "斤", "数量": 1.21, "单价": 26, "金额": 31.2, "备注": "" }, { "编号": "", "商品全名": "湖南辣椒", "规格": "", "单位": "斤", "数量": 6, "单价": 6.5, "金额": 39, "备注": "" }, { "编号": "", "商品全名": "独蒜", "规格": "", "单位": "斤", "数量": 2, "单价": 18, "金额": 36, "备注": "" } ], "页小计": { "每页合计": "312.2", "单位": "元" }, "地址": "*******", "联系电话": "152171******", "制单员": "**", "收货单位签章": "1月1 七 13" } } ``` |
6.总结:融合传统方法的必要
OCR技术在识别静态文本方面表现出色,但缺乏对图像内容的识别和上下文理解能力。而大模型具有强大的特征提取和抽象能力,可以有效捕捉数据中的潜在关联和复杂性。将这两种技术相融合,能够有效减少误识别的几率,实现更高精度的识别结果。两种技术的优劣势相互补充,形成一种更具适应性、灵活性和高效性的解决方案。
大模型并非“万能”的,支持服务的客户越多,就越能体会到“能不让大模型做的事情就不让它做”的实践经验对提升效果的重要性。许多传统方法仍然在特定领域下表现出色,可以为大模型提供前置输入处理。另外,从计算资源和响应时延的角度来看,传统技术相对于大模型也具有不少优势。结合传统技术可以满足实时性和高效性的需求,从而增强用户体验。
将大模型与传统技术融合,不仅能弥补各自的不足,还能在多个层面提升信息处理的能力和效率。这种融合不仅是技术发展的必然趋势,也是推动各行业智能化转型的重要驱动力。
来自团队:公共云业务-技术服务部
参考链接:
来源 | 阿里云开发者公众号
作者 | 舟谨