多模态大模型——pdf 识别

1. 多模态大模型——pdf 识别

图片

本文将会介绍两种 pdf 识别理解的方法
下面的内容都是在百炼大模型中实现的。

首先,我通过通义 qwen OCR 的角度入手。
我发现ocr 可以识别图片但是,在处理 pdf 的过程中需要操作一下。

我在文档中发现这么一段话:

通义千问 OCR 是否支持处理 PDF、EXCEL、DOC 等文本文件吗?

不支持,通义千问 OCR 模型属于视觉理解模型,只能处理图片格式的文件,无法直接处理文本文件,但是推荐以下两种解决方案:

  • 将文本文件转换为图片格式,但是注意转换后的图像尺寸可能过大,建议您将文件切分为多张图像并将 max_pixels 设置为更大的值(如最大值 23520000),每张图像单独发起 API 请求。
  • Qwen-Long 是能用于处理文本文件的模型,您可以使用 Qwen-Long 模型解析文件内容。

所以,接下来我也会从这两方面进行处理。

1.1. 通义千问 OCR

通义千问 OCR 是一款专业的文字识别模型,专注于从文档、表格、试卷、手写体等多种图像类型中高效准确地提取文字内容。
该模型具备多语言识别能力,目前支持汉语、英语、阿拉伯语、法语、德语、意大利语、日语、韩语、葡萄牙语、俄语、西班牙语、越南语等多种语言。

package com.example.demo.test;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;

public class 直接传入文本 {
    public static void simpleMultiModalConversationCall(String localPath)
            throws ApiException, NoApiKeyException, UploadFileException {
        String filePath = "file://"+"/幻灯片1.jpg";
        MultiModalConversation conv = new MultiModalConversation();
        Map<String, Object> map = new HashMap<>();
        map.put("image", filePath);
        // 输入图像的最大像素阈值,超过该值图像会按原比例缩小,直到总像素低于max_pixels
        map.put("max_pixels", "6422528");
        // 输入图像的最小像素阈值,小于该值图像会按原比例放大,直到总像素大于min_pixels
        map.put("min_pixels", "3136");
        // 开启图像自动转正功能
        map.put("enable_rotate", true);
        MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
                .content(Arrays.asList(
                        map,
                        // qwen-vl-ocr-latest未设置内置任务时,支持在以下text字段中传入Prompt,若未传入则使用默认的Prompt:Please output only the text content from the image without any additional descriptions or formatting.
                        // 如调用qwen-vl-ocr-1028,模型会使用固定Prompt:Read all the text in the image.,不支持用户在text中传入自定义Prompt
                        Collections.singletonMap("text", "# ********************* 系统提示 ***********************************\n" +
                                "你是一个文档图像理解引擎。收到图片或 OCR 文本后,请**严格返回单个 JSON 对象**,结构必须与下方最小 JSON Schema 一致。所有文本输出必须为中文(字段名中的 _cn 表示中文文本)。禁止输出任何非 JSON 的内容、说明、注释或多余文字。若某字段无法识别请使用 null 或 []。\n" +
                                "\n" +
                                "## 输入字段(任意提供)\n" +
                                "  image_id, image_text, image_region_desc。\n" +
                                "\n" +
                                "## 任务说明\n" +
                                "1、提取页面中的所有图片。\n" +
                                " - 若页面有多张图片,请放到 images 数组中。\n" +
                                " - 每张图片输出 title_cn、content_cn、keywords_cn 和 location。\n" +
                                "2、location 包含:\n" +
                                " - region_desc(文本位置描述,如"左上角""正文下方")\n" +
                                " - bbox(边界框 [x1, y1, x2, y2],无则填 null)\n" +
                                "3、输出必须严格遵守以下 JSON Schema,并且只返回该 JSON 对象。\n" +
                                "\n" +
                                "## 输出格式\n" +
                                "{\n" +
                                "  \"image_id\": \"string or null\",\n" +
                                "  \"language\": \"zh|en|mixed|other|null\",\n" +
                                "  \"images\": [\n" +
                                "    {\n" +
                                "      \"image_index\": 1,\n" +
                                "      \"title_cn\": \"string or null\",\n" +
                                "      \"content_cn\": \"string or null\",\n" +
                                "      \"keywords_cn\": [\"string\", ...] or [],\n" +
                                "      \"location\": {\"region_desc\": \"string or null\", \"bbox\": [x1,y1,x2,y2] or null}\n" +
                                "    }\n" +
                                "  ]\n" +
                                "}\n" +
                                "\n" +
                                "## Few-shot 示例\n" +
                                "### 输入\n" +
                                "image_id: \"page_001\"\n" +
                                "image_text: \"图1 中国经济发展趋势图。说明:近年来中国GDP稳步增长,主要驱动力包括消费升级与科技创新。\"\n" +
                                "image_region_desc: \"正文中部\"\n" +
                                "### 输出\n" +
                                "{\n" +
                                "  \"image_id\": \"page_001\",\n" +
                                "  \"language\": \"zh\",\n" +
                                "  \"images\": [\n" +
                                "    {\n" +
                                "      \"image_index\": 1,\n" +
                                "      \"title_cn\": \"中国经济发展趋势图\",\n" +
                                "      \"content_cn\": \"近年来中国GDP稳步增长,主要驱动力包括消费升级与科技创新。\",\n" +
                                "      \"keywords_cn\": [\"GDP\", \"经济发展\", \"消费升级\", \"科技创新\"],\n" +
                                "      \"location\": {\n" +
                                "        \"region_desc\": \"正文中部\",\n" +
                                "        \"bbox\": null\n" +
                                "      }\n" +
                                "    }\n" +
                                "  ]\n" +
                                "}\n" +
                                "\n"))).build();
        MultiModalConversationParam param = MultiModalConversationParam.builder()
                // 若没有配置环境变量,请用百炼API Key将下行替换为:.apiKey("sk-xxx")
                .apiKey("<YOUR_DASHSCOPE_API_KEY>")
                .model("qwen-vl-max")
                .message(userMessage)
                .topP(0.001)
                .temperature(0.1f)
                .maxLength(8192)
                .build();
        MultiModalConversationResult result = conv.call(param);
        System.out.println(result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text"));
    }
    public static void main(String[] args) {
        try {
            // 将xxxx/test.jpg替换为您本地图像的绝对路径
            simpleMultiModalConversationCall("xxx/test.jpg");
        } catch (ApiException | NoApiKeyException | UploadFileException e) {
            System.out.println(e.getMessage());
        }
        System.exit(0);
    }
}

1.1.1. 代码解释

一、程序初始化与入口

  1. 程序启动:

二、构建多模态请求消息

  1. 设置图像源与预处理参数:
  2. 构建系统提示与用户消息:

三、配置模型参数并发起调用

  1. 配置模型调用参数:
  2. 执行模型调用:

四、处理并输出结果

  1. 提取并打印结果:
  2. 异常处理与程序退出:

逻辑流程总结

准备数据(图像 + 指令)→ 配置模型 → 发起请求 → 解析并输出结果
整个过程旨在将非结构化的图像内容转化为结构化的数据,类似于通过 AI 模型完成了一项定制化的信息提取任务。


1.1.2. 优势

但是我发现 ocr 模型的优势在此:

qwen-vl-ocr-latest 模型全新升级,显著优势如下:

  • 更强的适应性:智能旋转矫正功能,轻松应对图像倾斜挑战。
  • 更专的识别力:新增六大内置 OCR 任务(通用、信息抽取、文档、表格、公式、多语言),精准覆盖核心应用场景。
  • 更优的灵活性:既可使用内置优化指令保障效果,也支持自定义 Prompt 以满足特定需求,兼顾效率与灵活性。

1.1.3. 模型限制

  • 由于通义千问 OCR 模型是一个专用于文字提取的模型,对用户输入的其他文本的回答无法保证准确性。
  • 用户需要在 image 参数中传入图像的 URL 或者 Base64 编码;如果请求中输入了多个图像,模型只会识别第一个图像,不支持对多图识别。
  • 通义千问 OCR 模型目前不支持多轮对话能力,只会对用户最新的问题进行回答。
  • 当图像中的文字太小或分辨率低时,模型可能会出现幻觉。

感觉它在处理 pdf 可能并不是最最合适的。


1.2. Qwen-Long

  • 常规长文本场景:推荐使用通义千问 Plus 或通义千问 Flash,两者均支持高达 100 万 Token 的上下文,足以满足绝大多数需求。
  • 超长文本分析与问答:若您需要处理超过百万级的超长内容,Qwen-Long 模型是您的理想选择。
    它提供惊人的 1,000 万 Token(约 1,500 万字)上下文窗口,支持上传完整文档并进行深度问答。
    更值得一提的是,其成本极具竞争力,输入低至 0.0005 元/千 Token,相当于每 1 元可处理长达 200 万 Token 的文本。

1.2.1. 场景示例

Qwen-Long 可以用于快速分析代码、网页、论文、报告、合同、书籍、规范手册、技术文档等
示例场景如下:

基于公司年报分析战略风险与机遇

为测试 Qwen-Long 的长文本处理能力,本次任务上传了某公司 2015–2024 年共 10 份 10-K 年报(PDF 格式,每份约 200 页)。
这些报告经审计并提交至纽约证券交易所,涵盖完整财务与业务信息,具备真实参考价值。

Prompt 要求:

  1. 提取每年报告核心内容(财务数据、管理讨论与分析);
  2. 生成 2015–2024 年报摘要,突出财务状况与重大事件;
  3. 详述 2018 年市场扩展策略及财务影响;
  4. 分析 2019 年公司面临的主要风险因素。

模型输出摘要:

1.2.1.1. 每年核心内容提取

  • 2015:关注信息系统安全,加强防护;美国市场收入受经济条件影响。
  • 2016:强调信息安全与风险管理,美国营收占比高,经济波动带来潜在负面影响。
  • 2017:信息系统攻击风险,加大人员与技术投入;美国市场收入及经济影响显著。
  • 2018:税务改革法案导致其他负债增加;管理层对财报责任予以说明。
  • 2019:收购咖啡公司,扩展热饮市场;管理层对财务报告责任重申。
  • 2020:新冠疫情导致产品销售下降。
  • 2021:疫情持续影响非家庭渠道销售。
  • 2022:疫情与政府措施对全球业务产生冲击。
  • 2023:经济压力下消费者转向低价产品,盈利能力承压。
  • 2024:为应对供应链中断,主动增加库存。

1.2.1.2. 2015–2024 年报摘要

该公司在美国市场收入占比持续显著,常年面临信息安全和经济波动等风险。
2018 年通过收购咖啡公司拓展热饮市场。
2020 年起受疫情冲击销售下滑,公司采取增加库存等措施以应对供应链风险。

1.2.1.3. 年市场扩展策略及财务影响

该公司于 2018 年收购一家咖啡公司,以增强在热饮市场的地位。
此次收购带来市场份额扩大的预期,但同时受税务改革影响,其他负债因一次性过渡税而增加。

1.2.1.4. 年主要风险因素

  • 信息系统可能遭受攻击,导致敏感信息泄露;
  • 美国经济状况不佳,可能抑制消费者需求,影响公司盈利与财务表现。

1.2.2. 提示词

你是一个高可靠性的"文档图像理解引擎(Document Image Understanding Engine)"。你的任务是:**把上传的 PDF 文件(或已 OCR 的文本 + 关联图片)解析为结构化中文文本并按章节顺序输出**。请严格遵守以下规则(新增:图片描述精简且优先与段落主旨相关;必须去重):
1. **唯一输出形式**:必须且仅返回一个顶层 JSON 对象(UTF-8 编码),禁止输出任何其它文本或多余字符。任何异常或说明应放在该 JSON 的 `processing_notes_cn` 或 `error_cn` 字段。 
2. **语言**:所有字段名和字段值必须为中文(字段名可用英文下划线并以 `_cn` 结尾表示中文)。 
3. **严格执行顺序**:处理**必须按章节顺序从第 1 章到最后一章逐章执行并输出**;顶层 `chapters` 数组需保持文档内出现顺序。 
4. **第一步 — 段落识别(强制)**:在任何章节/分段识别之前,首先做页面级与段落级的文本块识别(识别页眉/页脚、自然段落、换行、缩进、对齐等),并把识别到的段落作为后续最小单元的基础。必须为每页返回 `page_paragraphs_cn`(按页的段落列表,保留段落原始 OCR 文本)。 
5. **以最小字标题为最小输出单元**:  
   - 优先使用目录(TOC)识别章节边界。  
   - 章节内部识别所有字标题(一级、二级、三级...),把**最小层级的字标题(最小字标题)**作为 `segment` 的边界。  
   - 若章节内无字标题,则以段落或按 `max_chars_per_segment`/按页规则拆分,自动生成 `segment_title_cn`。 
6. **段落与 segment 定义**:每个 `segment`(最小字标题)必须包含:`subheading_cn`(最小字标题文本或 null)、有序的 `paragraphs_cn`(数组;每项包含 `para_id`、`raw_text_cn`、`clean_text_cn`)、`summary_cn`(对该最小字标题下所有段落的 1–3 行阐述)、`keywords_cn`(3–8 个)及关联 `images`(若有)。 
7. **图片处理原则(精简且相关优先)**:  
   - 图片描述必须**精简**并**以段落主旨为准**:仅保留与该 segment 主旨直接相关或补充说明性的视觉信息;与段落主旨无关的细节应省略。  
   - 若图片内包含大量文字且与段落文本重复,则只保留图片中文本中**与段落中未出现的**关键信息或简要标注"图片文字与段落重复,已省略"。  
   - 图片描述建议简短(例如 20–80 字),但必须能表达图片与段落主旨的关联与关键视觉要素。  
   - 图片字段包括:`image_id`、`page`、`bbox`(若不可得置为 null)、`image_type`、`caption_cn`(若有)、`ocr_on_image_cn`(如需保留图片内文字且非重复,否则可置为 null 或简化)、`description_cn`(精简描述,优先与段落主旨相关)、`chart_info`、`table_structured`。  
   - 若图片仅为装饰或与正文主旨无关,可将其标记为 `image_type: "other"` 并在 `description_cn` 中以一句话简短说明或省略详细描述。 
8. **去重规则(强制)**:  
   - 在 `page_paragraphs_cn`、`segments` 与 `images` 中必须对**重复文本或重复图片文字**执行去重:完全相同或高度重复的段落/句子应合并或标为重复并保留一次主条目;在被删除/合并的地方留下引用指针(如 `dup_of_para_id`)便于溯源。  
   - 若同一文字同时出现在正文与图片内,应优先保留正文中的那份并在图片对象中记录"与正文重复已省略"或只保留差异部分。  
   - `processing_notes_cn` 须列出去重策略和重要去重实例(例如"第3页第2段与第5页第1段高度重复,已合并为 para_id p12,原位置标注 dup_of_para_id:p12")。 
9. **图片与段落关联**:图片应关联到其所在的最小字标题(segment);若图片跨段或无法确定所属段,则挂在最近的上一最小字标题下并在 `processing_notes_cn` 中说明。 
10. **分段规则可配置**:支持 `max_chars_per_segment`(默认 2000 汉字)、`split_by_page_threshold_pages`(默认 3 页)。但优先保证"最小字标题"为边界;仅在无字标题或单个字标题过长时使用这些阈值进行子拆分。 
11. **文本清洗**:每个段落提供 `raw_text_cn` 与 `clean_text_cn`(去页眉页脚、页码、重复行等)。清洗过程须尽量保留语义并在 `processing_notes_cn` 中简述做了哪些清洗规则(例如"删除全局页眉'公司名'与页码X/Y")。 
12. **处理记录与错误**:在 `processing_notes_cn` 中记录关键决策(包括去重操作、图片简化策略、段落识别异常等),遇不可处理问题在 `error_cn` 中说明。 
13. **安全与合规**:若含敏感信息,按原文返回并在 `processing_notes_cn` 标注"包含敏感内容,建议…"。

1.2.3. 模型特点

  • 强大的长文本处理能力:Qwen-Long 模型能够处理高达 1,000 万 Token 的超长文本,相当于约 1,500 万字的文档内容。
  • 多种文件格式支持:支持文本文件(TXT、DOCX、PDF、XLSX、EPUB、MOBI、MD、CSV),图片文件(BMP、PNG、JPG/JPEG、GIF 以及 PDF 扫描件等)。
  • 文件大小限制:图片格式文件大小限制为 20M,其他格式文件大小限制为 150MB。
    单个阿里云账号最多可上传 1 万个文件,总文件大小不得超过 100GB。
  • 输入限制:支持通过 JSON 字符串传入文档信息。
    在组织信息时,建议保持以下字段结构构建 JSON,以避免格式错误:
    • content:文档内容
    • file_type:文档类型
    • filename:文档名
    • title:文档标题

1.2.4. 常见问题

Q:Qwen-Long 是否支持通过 System Message 指定模型行为?
A:支持
您可以通过 System Message 规范模型行为,具体使用方法请参考上方的 " 快速开始 " 部分。

Q:如何在 JSON 格式组织文档信息?
A:请参考 " 通过 JSON 字符串传入文档信息 " 部分的说明
在组织信息时,建议保持以下字段结构构建 JSON,以避免格式错误:

  • content:文档内容
  • file_type:文档类型
  • filename:文档名
  • title:文档标题

Q:Qwen-Long 是否支持流式回复?
A:支持
只需将 stream 参数和 stream_options 中的 include_usage 设置为 True,模型即可以流式形式返回结果,并在最终通过 usage 字段提供 Token 使用情况。

Q:是否支持特性提交任务?
A:支持
Qwen-Long 兼容 OpenAI Batch 接口,支持以文件方式异步提交批量任务,按实时调用费用的 50% 计费。
任务将在完成后或超时后返回结果。