MarkLLM:融合视觉与语言,实现文档智能理解与信息精准抽取
1. 项目概述当大语言模型学会“看”文档如果你也经常和PDF、Word、PPT这类文档打交道并且尝试过让大语言模型LLM帮你总结、提取信息那你大概率遇到过这样的场景你兴冲冲地把一份几十页的PDF丢给ChatGPT结果它要么告诉你“我无法处理文件”要么就是基于你手动复制粘贴进去的几段文字给出一个似是而非、甚至完全跑偏的答案。问题的核心在于绝大多数LLM是“纯文本”模型它们天生“看不见”文档的视觉布局和结构。一份文档里标题、正文、图表、页眉页脚、分栏、表格这些视觉元素所承载的结构化信息在模型眼中只是一堆杂乱无章的字符序列。THU-BPM/MarkLLM这个项目就是为了解决这个痛点而生的。它不是一个简单的文档解析工具而是一个将文档的视觉布局信息与大语言模型的文本理解能力深度融合的框架其核心思想是先让模型“看懂”文档的版面再让它基于版面去“读懂”内容。简单来说MarkLLM为LLM装上了一双“眼睛”。它通过先进的计算机视觉技术将一份文档如图像、PDF解析成一个结构化的“文档对象模型”Document Object Model这个模型精确记录了页面上每一个文本块、图片、表格的位置、大小和层级关系。然后它将这些视觉结构信息以一种LLM能够理解的方式例如通过特定的标记语言或结构化提示注入到模型的输入中。这样一来当LLM处理文档时它不仅能读到文字还能“知道”哪些文字是标题、哪些是作者、图表旁边的说明文字是什么、表格的第几行第几列对应什么数据。这种“视觉-语言”的联合理解使得模型在完成信息抽取、问答、总结等任务时准确率和可靠性得到了质的飞跃。这个项目非常适合三类人一是AI应用开发者你想在自己的产品中集成智能文档处理能力但苦于现有OCR或简单文本提取效果不佳二是数据分析师或研究员需要从大量非结构化文档如学术论文、行业报告、财务报表中自动化提取关键信息三是对多模态AI技术感兴趣的工程师希望深入理解如何将视觉信息与语言模型结合构建更强大的AI智能体。接下来我将带你深入拆解MarkLLM的设计思路、核心实现以及如何将它用在你自己的项目中。2. 核心设计思路从“盲人摸象”到“图文并茂”的理解为什么传统的“文本丢给LLM”的方式在处理复杂文档时会失灵想象一下我给你一篇论文PDF的纯文本输出没有格式让你找出“图3的标题”或者“比较表1中A组和B组的数据”。你会非常头疼因为所有视觉线索都丢失了。MarkLLM的设计哲学正是基于此它的整体流程可以拆解为三个核心阶段我们称之为“感知-结构化-推理”流水线。2.1 视觉感知高精度文档版面分析这是整个流程的基石。MarkLLM需要先将文档图像转换为机器可理解的版面元素。这里通常不直接使用简单的OCR光学字符识别因为OCR只关心“是什么字”不关心“字在哪以及和谁在一起”。MarkLLM依赖的是文档版面分析Document Layout Analysis, DLA技术。技术选型考量目前主流的DLA方案有基于传统计算机视觉如OpenCV轮廓检测和基于深度学习如Detection Transformer - DETR 或专门的布局分析模型如LayoutLMv3、YOLO系列变种两种。对于MarkLLM这类追求高精度和泛化能力的框架通常会选择基于深度学习的预训练模型。例如LayoutLMv3就是一个很好的选择因为它在大规模文档图像数据集上进行了多模态文本、图像、布局预训练能同时完成文本识别和布局检测输出带有坐标的文本行或文本块。注意版面分析的精度直接决定下游任务的天花板。一个常见的坑是如果模型无法正确区分正文和页脚那么页脚的页码或公司信息就可能被错误地当作正文内容进行总结。因此在项目实践中可能需要根据你的特定文档类型如扫描合同、双栏学术论文、复杂报表对版面分析模型进行微调。2.2 信息结构化构建文档对象模型DOM拿到一堆带有坐标的文本块后下一步是将其组织成有逻辑的结构。这一步的目标是生成一个文档对象模型。这个DOM类似于HTML DOM但它描述的是文档的物理和逻辑布局。关键操作元素分类将检测到的每个区域分类为“标题”、“正文”、“列表项”、“表格”、“图片”、“页眉”、“页脚”等。这通常由DLA模型一并完成或通过一个额外的分类器完成。层级关系重建通过分析元素的位置如y坐标相近、缩进和视觉特征如字体大小推断出标题的层级H1, H2, H3和列表的嵌套关系。序列化将结构化的DOM转换为一个线性序列以便输入给LLM。这里就是“Mark”的由来。一种直观的方式是使用标记语言例如仿照Markdown或HTML的语法[DOCUMENT] [PAGE id1] [HEADER]论文标题[/HEADER] [SECTION] [TITLE level1]1. 引言[/TITLE] [PARAGRAPH]这是引言部分的第一段文字...[/PARAGRAPH] [PARAGRAPH]这是第二段...[/PARAGRAPH] [/SECTION] [SECTION] [TITLE level1]2. 方法[/TITLE] [FIGURE bbox(x1,y1,x2,y2)]图1: 模型架构图[/FIGURE] [PARAGRAPH]如图1所示我们的模型包含...[/PARAGRAPH] [TABLE bbox(x1,y1,x2,y2)] | 列A | 列B | |------|------| | 数据1 | 数据2 | [/TABLE] [/SECTION] [/PAGE]这种标记明确保留了元素的类型、层级和空间关系通过bbox坐标为LLM提供了丰富的上下文。2.3 提示工程与推理引导LLM进行结构化思考有了带标记的结构化文档序列最后一步就是设计提示词Prompt引导LLM利用这些视觉线索完成任务。这是体现MarkLLM价值的关键环节。普通的提示词是“总结以下文本...”。而MarkLLM的提示词会是你是一个专业的文档分析助手。我将给你一份带有详细布局标记的文档内容。请特别注意[TITLE], [TABLE], [FIGURE]等标记及其bbox坐标信息。 【带标记的文档内容插入此处】 基于以上文档请回答1. 图1位于(100,200,300,400)区域描述了什么2. 在“实验结果”章节以[TITLE level2]3.2 实验结果[/TITLE]开头的表格中准确率最高的模型是哪个这种提示方式相当于给LLM提供了一份“地图”让它能精准定位到文档中的特定视觉元素并结合其周围的上下文进行理解。这极大地减少了幻觉Hallucination——即模型编造信息的可能性。实操心得提示词的设计需要反复打磨。除了任务指令你还可以在提示词中加入“思考链”Chain-of-Thought要求例如“请先定位相关章节再提取表格数据最后进行对比”。同时对于坐标信息可以提示模型“bbox坐标表示元素在页面上的位置相近坐标的元素内容上可能相关”帮助它建立空间与语义的关联。3. 核心模块拆解与实操要点理解了宏观思路我们深入到MarkLLM的几个核心模块看看具体如何实现以及有哪些需要注意的细节。3.1 文档解析与预处理模块这个模块负责处理各种格式的输入并将其统一转化为高质量的图像供后续版面分析使用。输入兼容性一个健壮的系统需要支持PDF、Word(.docx)、PowerPoint(.pptx)、图片PNG, JPG甚至扫描件。对于PDF推荐使用pdf2image库依赖poppler将其转换为一系列PNG图像。对于Word/PPT可以使用python-pptx或docx2txt等库但更通用的做法是将其打印或转换为PDF后再转为图像以确保视觉布局的绝对保真。图像预处理去噪与二值化对于扫描件可能需要使用OpenCV进行高斯模糊、阈值处理如Otsu‘s二值化以提升文本区域的对比度便于版面分析模型工作。分辨率标准化将图像缩放到一个统一的DPI如300 DPI。分辨率太低会丢失细节太高则增加计算开销。一个平衡点是保持图像短边在1024像素左右。矫正倾斜扫描的文档可能有轻微倾斜使用霍夫变换检测直线并旋转矫正能显著提升版面分析精度。踩坑记录直接解析PDF内部的文本流如使用PyPDF2看似更直接但会丢失绝大部分格式和视觉信息且无法处理扫描PDF。因此“先转图像再分析”是更鲁棒的路径尽管计算成本更高。3.2 视觉语言特征对齐模块这是MarkLLM技术栈中最具挑战性的部分。如何将视觉的“位置”信息有效地让LLM“理解”简单地把坐标(x1,y1,x2,y2)作为数字字符串丢给LLM效果很差因为LLM对纯数字序列的空间关系理解能力有限。主流对齐方案空间位置编码Spatial Position Embedding这是LayoutLM系列模型的做法。在模型的输入层除了传统的词嵌入Token Embedding和位置嵌入1D Position Embedding额外增加了2D位置嵌入。每个文本token的坐标归一化后的左上角和右下角坐标会被映射成一个高维向量与词嵌入相加。这样模型在训练过程中就学会了将文本与其在页面上的位置关联起来。标记语言注入Markup Language Injection如前所述将坐标和类型信息用人类可读的标记语言包装起来。这种方法更灵活无需修改LLM本身的结构可以直接用于GPT-4、Claude等闭源API或任何开源LLM。关键在于设计一套清晰、一致的标记语法。混合方法对于自研或可修改的模型可以结合两者。用轻量级模型如一个小型CNN对文档图像进行全局编码得到一个视觉特征向量然后将这个向量与文本序列的嵌入进行融合例如通过cross-attention。实操要点如果你使用的是API形式的LLM如OpenAI GPT标记语言注入是唯一可行的方案。你需要精心设计标记集确保其简洁且无歧义。例如避免使用LLM训练数据中常见的、有特殊含义的符号如和在HTML中可以考虑使用[ ]或【 】。3.3 任务适配与提示工程模块不同的下游任务需要不同的提示策略和可能的后续处理。信息抽取IE如抽取合同中的“甲方”、“乙方”、“金额”、“日期”。提示词需要明确指定要抽取的实体类型和关系并利用标记来限定搜索范围如“仅在[SECTION]类型为‘条款’的区域内查找”。输出可以要求为JSON格式。视觉问答VQA如“图2的横坐标代表什么” 这要求模型能将问题中的“图2”与文档中bbox对应的[FIGURE]标记关联起来并读取其标题或描述文字。文档摘要带标记的结构能帮助模型区分主次。你可以提示“基于[TITLE]和[PARAGRAPH]标记忽略[HEADER]和[FOOTER]内容生成一份摘要。”表格理解这是MarkLLM的强项。将表格区域用[TABLE]标记明确标出并尽可能将单元格内容以行列分明的文本格式如Markdown表格放入标记内LLM就能进行精确的查询、比较和计算。一个复杂的提示词示例用于合同审查你是一名法律AI助手。我将提供一份带有布局标记的合同文档。标记说明了每个文本块的类型和位置。 请执行以下任务 1. 识别合同中的“争议解决”条款。提示该条款通常位于文档后部标题可能包含“争议”、“管辖”、“法律适用”等字眼。 2. 提取该条款中指定的“管辖法院”或“仲裁机构”的全称。 3. 判断该条款是否规定了“仲裁”Arbitration作为解决方式。 在分析时请遵循以下步骤 - 首先扫描所有[TITLE]标记定位相关章节。 - 然后仔细阅读该章节下所有[PARAGRAPH]和[LIST]的内容。 - 最后基于你找到的明确文本证据给出答案。 【结构化文档内容】 请以JSON格式输出{“clause_location”: “章节标题”, “governing_body”: “提取的法院或机构名称”, “is_arbitration”: true/false}4. 从零搭建一个简易MarkLLM流程理论说了这么多我们来动手实现一个最核心的流程。假设我们使用开源工具链处理一份PDF学术论文并让LLM提取其摘要和图表标题。4.1 环境准备与依赖安装我们选择Python环境并使用一些成熟的开源库。# 创建虚拟环境可选 python -m venv markllm-env source markllm-env/bin/activate # Linux/Mac # markllm-env\Scripts\activate # Windows # 安装核心依赖 pip install pdf2image pillow # PDF转图像 pip install layoutparser torch torchvision # 版面分析LayoutParser是一个优秀的工具库 pip install opencv-python # 图像处理 pip install openai # 使用GPT-4 API或者使用ollama、vllm等本地部署方案 pip install python-dotenv # 管理API密钥对于版面分析LayoutParser提供了统一的接口调用多种模型。我们这里使用一个在PubLayNet数据集上预训练的模型它能很好地区分文本、标题、列表、图片和表格。4.2 分步实现代码解析步骤一文档转图像与版面分析import pdf2image from layoutparser import LayoutParser import cv2 import json def pdf_to_layout(pdf_path, output_image_dirtemp_images): 将PDF转换为带布局信息的结构化数据。 # 1. PDF转图像 images pdf2image.convert_from_path(pdf_path, dpi200) all_pages_layout [] # 2. 初始化版面分析模型这里以Detectron2为后端示例 # 首次运行会自动下载模型权重 model LayoutParser(lp://PubLayNet/faster_rcnn_R_50_FPN_3x/config) for page_num, image in enumerate(images): # 将PIL图像转为OpenCV格式BGR image_cv cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR) # 3. 预测版面 layout model.detect(image_cv) # 4. 对检测到的区域进行分类和过滤例如只保留置信度0.5的 text_blocks [block for block in layout if block.type in [Text, Title, List] and block.score 0.5] figure_blocks [block for block in layout if block.type Figure and block.score 0.5] table_blocks [block for block in layout if block.type Table and block.score 0.5] page_info { page: page_num, dimensions: image.size, # (width, height) text_blocks: [{bbox: block.coordinates.tolist(), text: 待OCR提取, type: block.type} for block in text_blocks], figures: [{bbox: block.coordinates.tolist(), id: ffig_{page_num}_{i}} for i, block in enumerate(figure_blocks)], tables: [{bbox: block.coordinates.tolist(), id: ftab_{page_num}_{i}} for i, block in enumerate(table_blocks)] } all_pages_layout.append(page_info) # 可选保存可视化结果用于调试 # visualized_image lp.draw_box(image_cv, layout, box_width3) # cv2.imwrite(f{output_image_dir}/page_{page_num}_layout.jpg, visualized_image) return all_pages_layout # 使用示例 layout_data pdf_to_layout(your_paper.pdf)步骤二OCR识别与文本关联版面分析只给了我们框框里的文字需要OCR来识别。我们需要对每个text_blocks的bbox区域进行OCR。import pytesseract # 或者使用EasyOCR、PaddleOCR from PIL import Image def extract_text_from_blocks(image_pil, text_blocks): 对图像中的指定区域进行OCR。 for block in text_blocks: bbox block[bbox] # [x1, y1, x2, y2] # 裁剪区域 region image_pil.crop((bbox[0], bbox[1], bbox[2], bbox[3])) # 使用Tesseract OCR # 预处理可以转为灰度、二值化以提高精度 region_gray region.convert(L) custom_config r--oem 3 --psm 6 # PSM 6 假设为统一的文本块 text pytesseract.image_to_string(region_gray, configcustom_config).strip() block[text] text return text_blocks # 在之前的循环中对每一页图像调用此函数 # processed_text_blocks extract_text_from_blocks(image, page_info[text_blocks])步骤三构建结构化文档序列标记化现在我们有了一页页的布局数据和文本需要将其序列化。def layout_to_markup(layout_data): 将布局数据转换为带标记的文本序列。 markup_lines [[DOCUMENT]] for page in layout_data: markup_lines.append(f[PAGE id{page[page]1} width{page[dimensions][0]} height{page[dimensions][1]}]) # 处理文本块按y坐标排序模拟阅读顺序 text_blocks_sorted sorted(page[text_blocks], keylambda b: (b[bbox][1], b[bbox][0])) for block in text_blocks_sorted: block_type block[type].upper() text block[text].replace(\n, ) # 简化处理将块内换行转为空格 bbox_str f bbox{block[bbox]} if block[bbox] else if text: # 只添加有文本的块 markup_lines.append(f[{block_type}{bbox_str}]{text}[/{block_type}]) # 处理图表和表格用占位符标记其位置和ID for fig in page[figures]: markup_lines.append(f[FIGURE id{fig[id]} bbox{fig[bbox]}]图{fig[id]}的内容描述需结合图注[/FIGURE]) for tab in page[tables]: markup_lines.append(f[TABLE id{tab[id]} bbox{tab[bbox]}]表{tab[id]}的数据需单独提取[/TABLE]) markup_lines.append([/PAGE]) markup_lines.append([/DOCUMENT]) return \n.join(markup_lines) structured_doc layout_to_markup(layout_data) print(structured_doc[:1000]) # 查看前部分内容步骤四设计提示词并调用LLMfrom openai import OpenAI import os from dotenv import load_dotenv load_dotenv() # 加载环境变量中的OPENAI_API_KEY client OpenAI(api_keyos.getenv(OPENAI_API_KEY)) def ask_llm_with_markup(structured_doc, query): prompt f 你是一个学术论文分析AI。以下是一篇论文的带布局标记的内容。标记如[TITLE], [PARAGRAPH], [FIGURE]等标明了内容的类型和在页面上的位置bbox坐标。 请严格根据提供的文档内容回答以下问题。如果信息不存在请回答“未在文档中找到相关信息”。 文档内容 {structured_doc} 问题{query} 请先简要说明你的推理依据例如根据哪个部分的哪个标记然后给出答案。 response client.chat.completions.create( modelgpt-4-turbo-preview, # 或使用 gpt-3.5-turbo messages[ {role: system, content: 你是一个严谨的文档分析助手。}, {role: user, content: prompt} ], temperature0.1, # 低温度保证输出稳定 max_tokens1000 ) return response.choices[0].message.content # 示例查询 query1 这篇论文的摘要Abstract是什么请直接引用原文。 query2 文档中第一个图表[FIGURE]的ID是什么根据其附近文本推测这个图可能关于什么内容 answer1 ask_llm_with_markup(structured_doc, query1) print(问题1回答\n, answer1) print(\n *50 \n) answer2 ask_llm_with_markup(structured_doc, query2) print(问题2回答\n, answer2)通过以上四个步骤我们就完成了一个简易但功能完整的MarkLLM流程。它从PDF出发经过视觉解析、结构化、标记化最终利用大语言模型完成了基于视觉结构的精准信息提取。5. 性能优化与生产级考量将原型转化为稳定、高效的生产系统还需要考虑以下方面5.1 精度与鲁棒性提升多模型融合与后处理单一版面分析模型可能在特定文档类型上失效。可以采用模型集成策略例如用LayoutLMv3处理纯文本区域用专门训练的表格检测模型如Table Transformer处理表格再用规则如基于轮廓和线条检测进行后处理合并重叠框、修正错误分类。阅读顺序优化简单的按y坐标排序在处理多栏文档时是错的。需要更复杂的阅读顺序算法考虑列分割线、缩进、项目符号等。可以训练一个序列预测模型或者使用启发式规则如从左到右、从上到下优先处理标题等。OCR增强Tesseract在复杂字体、低质量图像上表现不佳。可以集成更强大的OCR引擎如PaddleOCR或商业APIAzure Form Recognizer Google Document AI。对于关键区域如表格、图表标题可以尝试更高DPI的识别。5.2 处理效率与成本控制并行处理PDF的每一页可以独立进行版面分析和OCR这是天然的并行任务。可以使用Python的concurrent.futures或multiprocessing模块或者将其放入任务队列如Celery进行分布式处理。缓存策略对于不变的文档解析出的结构化结果标记化文本可以序列化如保存为JSON或二进制文件并缓存。下次对同一文档提问时可直接加载缓存跳过耗时的视觉解析步骤。LLM调用优化提示词压缩如果文档很长标记化后的序列可能超出LLM的上下文窗口。需要设计摘要或过滤策略例如只保留与当前问题可能相关的页面或章节的标记内容。可以使用一个更小的、便宜的模型如GPT-3.5 Turbo先对文档进行粗粒度分析筛选出相关片段。分而治之对于超长文档可以将其按章节拆分分别提问最后再综合答案。模型选型在精度要求不极端高的场景使用gpt-3.5-turbo能大幅降低成本。对于特定垂直领域可以微调开源的、上下文窗口更大的模型如LongLoRA技术微调后的Llama 2/3实现私有化部署彻底消除API成本。5.3 系统集成与扩展构建API服务将整个流程封装成RESTful API或gRPC服务。输入可以是文件上传或URL输出是结构化JSON。使用FastAPI或Flask可以快速搭建。支持流式输出对于长文档处理可以向客户端实时返回处理进度如“正在解析第X页...”。可插拔架构设计良好的接口使得版面分析模型、OCR引擎、LLM后端都可以方便地替换。例如通过配置文件指定使用layout_analyzer: layoutlmv3和llm_provider: openai。评估与监控建立评估流水线使用一批标注好的文档定期测试系统在关键任务如实体抽取F1分数、问答准确率上的表现。记录每次LLM调用的token消耗和延迟用于成本分析和性能监控。6. 常见问题与排查技巧实录在实际部署和调试MarkLLM系统时我遇到了不少典型问题。这里分享一份速查表希望能帮你少走弯路。问题现象可能原因排查步骤与解决方案LLM的回答完全忽略标记信息像是在处理纯文本。1. 提示词未强调标记的重要性。2. 标记语法与LLM训练数据中的常见语法冲突被模型“忽略”。3. 上下文太长关键标记被挤到边缘。1.强化系统提示在系统指令中明确要求模型“必须关注并利用提供的XML/标记结构”。2.修改标记语法尝试使用不常见的符号组合如SECTION.../SECTION或使用数字ID[1]...[/1]。3.精简输入只发送与问题最相关的页面或区域的标记内容。先让一个小模型做相关性筛选。版面分析模型将正文误判为标题或反之。1. 文档字体、排版与训练数据差异大。2. 图像质量差如低分辨率、阴影、倾斜。1.模型微调收集几十到几百份你的目标文档类型标注后对预训练模型进行微调。2.图像预处理增加图像预处理步骤如去阴影使用cv2.adaptiveThreshold、纠偏、提高对比度。3.后处理规则根据字体大小、位置和出现频率标题通常较少添加规则进行校正。OCR识别表格内容错乱无法形成结构化数据。通用OCR不擅长表格结构识别将单元格内容错误合并。1.使用专用表格OCR对检测到的表格区域使用PaddleOCR的表格识别模式或Tabula-py等PDF表格提取库。2.后处理将OCR出的文本行根据其bbox坐标通过聚类算法如按y坐标对行聚类按x坐标对列聚类重新组织成表格。处理速度极慢尤其是长文档。1. 串行处理每一页。2. OCR是主要瓶颈。3. 高分辨率图像导致模型推理慢。1.并行化使用线程池或进程池并行处理页面。2.OCR优化对于非关键页面或清晰印刷体可以尝试使用更快的OCR引擎如Tesseract的--oem 1LSTM模式。3.图像降采样在保证版面分析精度的前提下适当降低转换PDF时的DPI如从300降至150。可以做一个权衡实验。LLM回答出现“幻觉”编造了文档中没有的信息。1. 问题涉及的区域未被正确标记或包含在上下文中。2. LLM本身倾向于生成“合理”但未必准确的内容。1.增加引用要求在提示词中强制要求模型“引用原文”或“指出依据的标记ID”。例如要求答案格式为“答案XXX。依据[TITLE id2]...中的内容”。2.自我验证让LLM在给出答案后再基于原文验证一遍自己的答案。或者采用“检索-生成”框架先让模型找出相关原文片段再基于片段生成答案。3.降低Temperature将API调用中的temperature参数设为0或接近0如0.1减少随机性。系统无法处理扫描版PDF中的手写注释。版面分析模型和OCR主要针对印刷体训练。1.区域隔离尝试检测与印刷体bbox不重叠的“异常”文本区域将其单独分类为“手写”或“注释”。2.专用模型对于重要场景可以收集手写数据微调OCR模型如TrOCR。3.人工复核将此类区域标记为“低置信度”在输出中提示可能需要人工检查。最后一点个人体会MarkLLM所代表的多模态文档理解方向其魅力在于它巧妙地用“结构”这座桥连接了视觉与语言两个AI子领域。它不需要训练一个端到端的、参数巨大的多模态模型而是通过工程化的流水线将成熟的开源工具与大语言模型的能力组合起来解决了一个非常实际的问题。在实施过程中最大的挑战往往不是算法本身而是对业务场景的深度理解——你需要知道对于你的文档什么样的信息是关键的什么样的错误是不可接受的然后针对性地去优化流水线中的每一个环节。从这个角度看它更像是一个“AI工程”项目考验的是架构设计和问题拆解的能力。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2583618.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!