摘要
传统的OCR系统(OCR-1.0)越来越无法满足人们对智能处理人造光学字符的需求。在本文中,我们将所有人造光学信号(例如,普通文本、数学/分子公式、表格、图表、乐谱,甚至是几何形状)统称为“字符”,并提出了通用OCR理论以及一个优秀的模型,即GOT,以促进OCR-2.0的到来。GOT拥有5.8亿参数,是一个统一的、优雅的、端到端的模型,由高压缩编码器和长上下文解码器组成。作为一个OCR-2.0模型,GOT可以在各种OCR任务下处理上述所有“字符”。在输入端,模型支持常用的场景和文档样式图像,包括切片和整页风格。在输出端,GOT可以通过简单的提示生成纯文本或格式化结果(markdown/tikz/smiles/kern)。此外,该模型还享有交互式OCR特性,即通过坐标或颜色引导的区域级识别。进一步地,我们还为GOT适应了动态分辨率和多页OCR技术,以提高实用性。在实验中,我们提供了充分的结果来证明我们模型的优越性。
1 引言
光学字符识别(OCR)是一种广泛使用的技术,它将光学图像中嵌入的字符提取成可编辑的格式。典型的OCR系统[10]在OCR-1.0时代主要是基于多模块流水线风格设计的,通常包括元素检测、区域裁剪和字符识别部分。每个模块都容易陷入局部最优,使得整个系统产生高昂的维护成本。此外,传统OCR方法的泛化能力不足,表现为不同的OCR-1.0网络通常为不同的子任务设计。尽管如此,为特殊任务从多样化的OCR模型中选择一个合适的模型对用户来说总是不方便的。
在过去的一年中,大型视觉语言模型(LVLMs)[5, 9, 24, 27, 36, 46, 49]迅速发展,并展示了令人印象深刻的性能。作为一个备受期待的能力,当前LVLMs的OCR性能正在不断提高。基于CLIP[37],LLaVA[24]在指导调整阶段后自然获得了英语OCR能力。为了提高OCR准确性并支持其他语言,例如中文,Qwen-VL[5]在其第二阶段训练中解冻了其图像编码器(一个CLIP-G)并使用了大量的OCR数据。创新地,Vary[46]生成了一个新的高分辨率OCR视觉词汇表,与CLIP分支并行,以处理文档级密集OCR。相比之下,InternVL-1.5[9]和其他模型[27,50]采用滑动窗口方式将整个图像裁剪成多个子块,以进行高分辨率OCR。因此,人们普遍认为,光学字符感知和识别是文本驱动图像理解的基础,这吸引了更多的研究人员关注LVLMs的OCR助推器。
然而,流行的LVLMs设计可能不适合多样化的OCR任务,原因如下:1)感知与推理之间的冲突。LVLMs主要关注视觉推理性能,例如VQA[33, 42],因为这是LLM擅长的。为了快速从LLMs获得QA增益效益,大多数LVLMs[15, 24, 49]将图像标记与文本标记对齐。然而,对于纯粹的感知OCR任务来说,这样做是不合理的,尤其是高密度文本场景,因为每个对齐的视觉标记(偏向文本标记)无法压缩足够的字符。想象一下,使用成千上万的图像标记,例如图像裁剪方式[9, 23],来编码等量的光学字符(例如,仅A4-PDF页面内的文字)是多么浪费。2)高迭代和部署成本。LVLM通常拥有数十亿参数,导致后期训练和部署成本过高。一般来说,对于LVLMs,一旦我们想要添加新的OCR模式,例如新的语言,仅仅进行微调是不够的,而是需要足够的GPU资源进行预训练。然而,为了引入新的OCR特性,重新运行数十亿参数的预训练,也是浪费的。
因此,我们提出了通用OCR理论,即OCR-2.0,以打破传统和LVLM方式在OCR任务上的瓶颈。我们认为,OCR 2.0模型应该具备以下基本特征:
- 端到端。与具有复杂程序的OCR-1.0模型相比,OCR-2.0模型应该享受统一且端到端的架构,以确保更低的维护成本。在2.0时代,初学者可以快速掌握整个OCR系统,这很酷。
- 低训练和推理成本。OCR-2.0模型不应该是一个聊天机器人,像LVLM那样专注于推理任务。它的重点应该是强大的光学字符感知和识别,因此它需要一个合理的模型参数数量,以换取更低的训练和推理成本。
- 多功能性。OCR-2.0模型的另一个重要点是多功能性,包括识别更广泛的人造光学“字符”,例如乐谱、图表、几何形状等。此外,模型应该支持具有更强可读性的输出格式,例如,公式和表格的\mathrm{AT}_{\mathrm{E}} \mathrm{X} / Markdown格式。
基于提出的通用OCR理论,我们提出了一个初级OCR-2.0模型(GOT),以弥合OCR-1.0模型和人们对更高光学字符处理需求之间的差距。在架构上,我们采用了简单的编码器-解码器范式。具体来说,GOT拥有一个高压缩率编码器,将光学图像转换为标记,以及一个长上下文长度解码器,输出相应的OCR结果。编码器大约有8000万个参数,支持1024×1024的输入尺寸,足以处理常用的照片/文档输入样式。每个输入图像将被压缩为256×1024维度的标记。GOT的解码器拥有5亿参数,支持8K最大长度标记,以确保它可以处理长上下文场景。我们为GOT设计了一种有效且高效的训练策略,可以分为三个步骤,即编码器的解耦预训练、编码器与新解码器的联合训练,以及解码器的进一步后训练。此外,为了进一步提高GOT的实用性,我们还额外适应了细粒度OCR特性,以获得更好的交互性,动态分辨率策略用于超高分辨率图像(例如,超过2K),以及多页OCR技术,以缓解PDF图像-文本对中页面断裂问题的困难(例如.tex文件中的页面断裂)。为了支持每个训练阶段,我们为合成数据生产做了很多数据引擎,这是GOT成功的关键,将在本文中详细描述。我们模型支持的主要输入数据格式可以在图1中看到。
作为一个设想OCR-2.0的模型,GOT在各种OCR任务中的实验中展示了有希望的性能。我们希望提出的简单而优雅的GOT能够吸引更多的研究人员投入到OCR-2.0的研究中。当然,通往OCR-2.0的道路仍然很长,GOT也有很多改进空间,例如支持更多语言、更广泛的人造信号和更复杂的几何形状。在由LVLMs引领的这个新时代,我们相信纯粹的OCR模式并没有结束,它甚至可能是一个新的开始。
2 相关工作
2.1 传统OCR
光学字符识别(OCR)是一个经典研究课题,旨在将图像的光学内容转换为可编辑格式,以便进一步的下游处理。传统OCR系统,称为OCR-1.0,通常使用由多个专家模块组装而成的框架。例如,为了处理多样化的光学字符,OCR系统[10]通常通过集成多个领域专家网络来开发,如布局分析[54]、文本检测[18, 19, 26, 30, 43, 45, 52, 55]、区域提取和内容识别[11, 14, 16]。使用这种流水线方案的原因是,文本识别模块(OCR部分)未能成功扩展,只能处理小切片的图像格式,导致整个OCR过程以先检测文本/裁剪区域,然后识别切片内的结果的形式进行。然而,复杂程序的系统可能会遭受潜在的系统性错误和高昂的维护成本。尽管一些OCR-1.0模型,例如Nougat[6]可以直接处理整页文档,但它们通常针对特定子任务设计和训练,导致泛化能力不佳。在OCR-1.0时代,一个不便之处是,我们通常需要根据不同的OCR需求切换不同的模型。
2.2 由LVLM驱动的OCR
大型视觉语言模型(LVLMs)[5, 9, 20, 24, 27, 46, 49]由于其强大的泛化能力,在AI界引起了广泛关注。对于目前拥有感知-推理综合能力的LVLMs来说,OCR能力已经成为一个热点,随着对文本驱动视觉理解的需求不断增加。大多数LVLMs的OCR能力来自现成的CLIP[37],特别是那些冻结CLIP编码器[24]来完成整个LVLM训练的模型。对于这样的模型,普通的CLIP,主要具有英语场景文本知识,是OCR性能在领域外任务,如其他语言或文档的瓶颈。一些其他LVLMs[5, 49]选择解冻编码器并冻结LLM进行训练,以增强CLIP-编码器并将图像标记与文本标记对齐。这些模型将面临光学字符压缩率低的问题,因为冻结的LLM很难从对齐的图像标记中解码太多文本。为了缓解这个问题,一些模型[9, 27, 50]采用滑动窗口方式将输入图像分解成更小的补丁。尽管这种动态分辨率方法在处理高分辨率输入图像,例如PDF时非常有效,但它将导致过多的图像标记,并在一定程度上限制生成的OCR结果的最大长度。
3 通用OCR理论
在这项工作中,我们提出了通用OCR理论,即OCR-2.0(在第1节中阐述),以促进OCR领域的发展。基于提出的新理论,我们提出了一个新颖的OCR模型(GOT)。在本节中,我们将介绍我们模型的技术细节,包括框架、多阶段训练策略和相应的数据引擎。
3.1 框架
如图2所示,GOT由三个模块组成,即图像编码器、线性层和输出解码器。线性层充当连接器,将视觉编码器和语言解码器之间的通道维度映射起来。我们在优化整个GOT模型时采用三个主要步骤。首先,我们进行纯文本识别任务以预训练视觉编码器。为了提高训练效率并节省GPU资源,我们选择一个小型解码器来向编码器传递梯度。在这个阶段,我们将包含场景文本和手动图像的文档级字符输入模型,以允许编码器收集两种最常用的字符编码能力。在下一阶段,我们通过将训练有素的视觉编码器连接到一个新的更大的解码器来构建GOT的架构。我们准备了更多的通用OCR数据(例如,乐谱、数学/分子公式和几何形状),以扩展这一阶段的OCR-2.0知识。在最后阶段,我们打算进一步提高GOT的泛化能力和适用性。具体来说,我们生成并添加了细粒度和多裁剪/页面合成数据,以支持GOT进行区域提示OCR[20]、超大图像OCR和批量PDF OCR功能。
3.2 预训练OCR专用视觉编码器
如前所述,GOT采用了编码器-解码器结构。受LVLMs设计的启发,解码器可以通过一个训练有素的语言模型进行初始化。然而,我们没有找到一个适合OCR-2.0模型的预训练编码器,所以我们必须自己训练一个。我们希望新的OCR编码器能够在各种输入形状(包括切片和整页)上很好地工作于常用的场景和文档文本识别。
3.2.1 视觉编码器的生成
我们选择的编码器结构是VitDet[17](基础版本,大约有8000万个参数),因为它的局部注意力可以大大降低高分辨率图像的计算成本。我们遵循Vary-tiny设置[46]来设计编码器的最后两层,这将把一个1024×1024×3的输入图像转换为256×1024的图像标记。然后,这些图像标记通过一个1024×768的线性层投影到语言模型(OPT-125M[53])的维度。与仅关注单一文档任务且输入形状相对单一的Vary编码器不同,我们在预训练期间加入了自然场景和裁剪切片。在预处理阶段,每种形状的图像都直接调整为1024×1024的正方形,因为正方形可以用来适应不同长宽比的图像,尽管会有一些妥协。
3.2.2 针对编码器预训练的数据引擎
在这样一个编码器预训练阶段,我们使用了大约500万张图像-文本对,包括300万张场景文本OCR数据和200万张文档OCR数据。它们的获取方法如下:
对于自然场景数据,英文和中文图像分别从Laion-2B[40]和Wukong[12]数据集中采样。然后,使用PaddleOCR[10]工具捕获这些多样化真实场景中的伪基准真值。总的来说,我们获得了200万条数据,其中一半是中文,一半是英文。对于文本基准真值,我们执行了两种类型的处理:1)移除边界框,并将每个文本内容从上到下、从左到右依次组合。2)根据边界框从原始图像中裁剪文本区域,并将其保存为图像切片。后面的第2种方法使我们能够获得另外100万张切片类型的图像-文本对。
对于文档级数据,我们首先从Common Crawl收集开源PDF风格文件,并使用Fitz Python包提取相应的密集文本内容。在这样一个过程中,我们获得了120万张全页PDF风格图像-文本对和80万张图像切片数据。切片数据,包括行级和段落级,是通过解析边界框从PDF图像中裁剪出来的。
3.3 通过多任务联合训练扩展OCR-2.0知识
3.3.1 GOT的最终架构
在视觉编码器的预训练步骤之后,我们将其连接到一个更强大的大型语言模型,以构建GOT的最终架构。在这里,我们采用Qwen[4](参数为5亿)作为解码器,因为它在参数数量相对较少的同时融入了多种语言的先验知识。连接器(即线性嵌入层)的维度调整为1024×1024,以与Qwen-0.5 B的输入通道对齐。因此,GOT享有无缝的编码器-解码器范式,总共约有5.8亿个参数,这在计算资源上更友好,也更容易部署在具有4G内存的消费级GPU上。编码器的高压缩率(1024×1024光学像素到256图像标记)为解码器生成新标记节省了大量的标记空间。与此同时,解码器的满意解码上下文长度(我们使用的最大长度约为8K)确保GOT能够在密集场景下有效地输出OCR结果。
3.3.2 联合训练的数据引擎
为了向GOT注入足够的OCR-2.0知识,我们在这阶段仔细探索了几种合成方法和数据引擎,如图3所示。我们将在以下段落中详细探讨每种类型的合成数据的细节。
普通OCR数据。我们使用第3.2.2节中提到的数据的80%作为普通OCR数据。为了进一步增强GOT的鲁棒性,我们还添加了手写文本识别子任务,涉及不同语言的各种手写风格。我们收集了中文CASIA-HWDB2[1]、英文IAM[2]和挪威NorHand-v3[3]数据集来满足我们的要求。对于原始图像-文本对的行级切片格式,将6到8对组合并随机粘贴到空白文档页面中,以实现长文本手写识别并提高训练效率。
Mathpix-markdown格式数据。保持光学内容格式对于保持输出结果的强可读性至关重要,特别是对于数学公式和表格。为此,我们使用多种方法收集尽可能多的格式化数据。数据收集和生产的详细信息如下:
-
数学公式。我们在Arxiv上爬取了大量的ETEX源.tex文件,并从中提取了约100万个公式片段。接下来,我们将公式源转换为Mathpix格式,并使用Chrome-driver调用Mathpix-markdown-it工具将源渲染为HTML格式。然后,我们将HTML文件转换为SVG,并将其保存为PNG图像。我们发现这种渲染方法比直接使用IT_EX快20倍以上。
-
分子公式。我们首先下载包含200万个微笑源的ChEMBL_25文件。然后,我们使用Mathpix-markdown-it工具和rdkit.Chem包收集了约100万个分子公式图像-文本对。
-
表格。从爬取的tex文件中,我们提取了约30万个表格源,并将其渲染成图像。与Mathpix-markdown-it不同,我们直接使用LT_EX作为渲染工具,因为它在渲染高级表格方面效果更好。
-
全页数据。使用Nougat[6]方法,我们获得了约50万对英文markdown PDF-文本对。此外,按照Vary[46, 47],我们收集了另外50万对中文markdown对。我们将它们的内容转换为Mathpix格式。此外,我们还额外添加了20万个内部数据,这些数据是直接使用Mathpix标记的,包括书籍、论文和财务报告。
更多通用OCR数据。我们希望GOT能够处理更多通用的光学人造“字符”。因此,我们收集了三个相关的挑战性任务,并生成了相应的数据。它们分别是乐谱、几何形状和图表。
-
乐谱。音乐是文化遗产的宝贵部分,光学音乐识别在实现乐谱的自动识别和转录中扮演着重要角色[7, 38]。我们选择GrandStaff[39]数据集作为渲染源。多声部乐谱数据集提供了来自音乐片段的Humdrum ** kern转录。除了现有的大约10万个图像-文本样本外,我们还通过Verovio Python包提取了一些文本样本进行重新渲染。我们主要将新背景从白色更改为真实纸张风格,并随机添加标题和作者信息。请注意,我们只渲染单系统乐谱,因为我们没有相关领域的专业人员,我们不知道如何将单系统乐谱组装成整页。渲染后,我们收集了约50万个样本。
-
几何形状。几何是LVLMs的关键能力,是朝着通用人工智能(AGI)迈进的必要步骤。GOT有望将光学几何元素转换为TikZ[34]文本格式。TikZ包含一些简洁的命令,可以产生基本的几何元素,它们可以使用LATE_EX编译。我们采用TikZ风格的点和线,并使用最简单的点线空间关系构建简单的基本几何形状(例如,圆形、矩形、三角形和组合形状)以及简单的函数曲线(例如,直线、抛物线、椭圆、双曲线等)。通过这种方法,我们获得了大约100万个几何TikZ数据。当然,几何渲染很复杂,我们目前的工作只是一个初步尝试。GOT目前只能识别基本几何形状,但我们相信,随着合成数据技术和OCR-2.0的发展,未来的模型将能够识别复杂的几何形状。
-
图表。图表在多个研究领域的数据可视化和数据分析中至关重要。我们提出的GOT将图表结构提取子任务称为“图表OCR”,它将图表图像上的视觉知识(例如,标题、来源、x-标题、y-标题和值)转换为可编辑的输出,格式为表格/Python-dict。按照OneChart[8],图表图像-文本对是使用Matplotlib和Pyecharts工具渲染的。由于GOT只是一个OCR模型,我们不需要图表合成的元素在语义上相关。因此,我们只是随机从开放访问的NLP语料库中提取实体文本(用于标题、来源、x-标题、y-标题等)。数值是控制分布下的随机数。通过这种方法,我们获得了200万个图表数据,其中一半来自Matplotlib,一半来自Pyecharts。
3.4 通过后训练解码器定制新的OCR特性
通过上述两个步骤压缩了多样化OCR-2.0光学信号的通用视觉信息后,GOT已准备好在各种场景中执行图像级OCR任务。基于这个感知能力强大的视觉编码器,GOT可以轻松调整以满足用户对输入和输出的需求。在这里,我们通过仅后训练解码器部分,定制GOT以启用三个新特性,即细粒度、多页和动态分辨率OCR。
3.4.1 用于交互式OCR的细粒度数据引擎
作为一种高交互性特性,细粒度OCR[20]是受空间坐标或颜色控制的区域级视觉感知。用户可以在问题提示中添加框坐标(框引导OCR)或彩色文本(颜色引导OCR),以请求在感兴趣区域(RoI)内进行识别,避免输出其他无关字符。对于自然细粒度OCR,源图像和注释来自开源数据集,包括RCTW[41]、ReCTS[25]、ShopSign[51]和COCO-Text[44]数据集。上述提到的数据集提供了文本边界框,因此我们可以直接用它们来生产细粒度(区域/颜色提示)OCR数据。对于文档级细粒度OCR,我们遵循Fox[20],过滤掉下载的PDF文件中的扫描格式,并使用Python包(Fitz/PDFminer)解析左侧部分。我们记录了页面级图像、每行/段落的边界框和相应的文本,以生产框引导OCR子任务的基准真值。对于这样一个任务,每个坐标值首先被归一化,然后放大1000倍。对于颜色引导任务,我们选择最常用的颜色(红色、绿色和蓝色)作为框架颜色,并在原始图像上通过相应的边界框绘制它们。总的来说,我们收集了大约60万个样本。
3.4.2 用于超大图像OCR的多裁剪数据引擎
GOT支持1024×1024输入分辨率,这对于常用的OCR任务来说已经足够了,例如场景OCR或A4页面PDF OCR。然而,对于一些具有巨大图像的场景,例如两页PDF水平拼接(在阅读论文时常见),则需要动态分辨率。由于我们编码器的高压缩率,GOT的动态分辨率是在一个大滑动窗口(1024×1024)下实现的,确保我们的模型可以完成极端分辨率OCR任务,并接受可接受的图像标记。我们使用InternVL-1.5[9]裁剪方法,将瓦片最大值设置为12。超分辨率图像是使用上述提到的单页PDF数据合成的,包括水平和垂直拼接。通过这种方法,我们总共获得了50万个图像-文本对。
3.4.3 用于批量PDF文件OCR的多页数据引擎
对于OCR任务,使用“for循环”进行多页处理是合理的。我们为GOT引入了多页OCR(无“for循环”)特性,因为一些格式化PDF数据使得页面断裂变得困难(以获得与每一页完全不兼容的文本),以进一步扩展,例如Arxiv中的.tex。我们希望,有了GOT,研究人员不再需要担心PDF基准真值页面断裂(例如,Nougat[6]),因为他们可以直接在多页上进行训练。为了实现这样的特性,我们从我们的Mathpix格式化PDF数据中随机抽取2-8页,并将它们组合在一起,形成一个单独的回合OCR任务。每个选定的页面包含的文本少于650个标记,以确保整体长度不超过8K。总的来说,我们生成了大约20万个多页OCR数据,其中大部分是中文和英文页面的交错。
4 实验
4.1 实施细节
我们使用8×8 L40s GPU来训练GOT。在预训练阶段,我们使用128的全局批量大小优化所有模型参数,并训练3个周期。我们使用AdamW[29]优化器和余弦退火调度器[28],起始学习率设置为1e-4。这个阶段的最大标记长度设置为4096。在联合训练阶段,我们将最大标记长度设置为6000,并使用与第一阶段相同的优化器设置训练模型1个周期。在最后的后训练阶段,我们将最大标记长度扩展到8192,以允许模型支持多补丁/页面OCR特性。在这个阶段,起始学习率设置为2e-5,周期设置为1。
在每个训练数据处理过程中,从前一阶段抽取80%的数据用于下一阶段,以确保在添加新特性时基本能力不会下降。
4.2 主要结果
在本节中,我们在5个不同的OCR任务上验证了GOT的性能,包括1)普通文档OCR;2)场景文本OCR;3)细粒度文档OCR;4)格式化(Mathpix markdown)文档OCR;5)更多通用字符OCR。请注意,每个基准测试的测试数据都经过了严格的文本相似性筛选,以确保它不包含在训练数据中。每个测试基准的来源和模型性能分析如下。
4.2.1 普通文档OCR性能
我们使用开源的Fox[20]基准测试来测试GOT在中英文PDF OCR上的性能。我们使用的指标是OCR任务中常见的,即编辑距离、F1分数、精确度、召回率、BLEU和METEOR。由于文档文本较长,我们使用词级分割来计算每个指标。如表1所示,仅凭5.8亿个参数,GOT在文档中的纯文本OCR上就取得了先进的性能,证明了其出色的PDF文本感知和识别能力。
4.2.2 场景文本OCR性能
我们收集了400张自然图像,其中一半是中文,一半是英文,作为场景文本OCR的基准测试。这个基准测试中的所有基准真值都是人工校正的。由于场景图像中的文本相对较短,我们使用字符级分割来计算各种指标。如表2所示,我们可以看到GOT在自然图像上也表现良好,展示了模型在大多数基本OCR任务(文档和场景文本)上的卓越性能。
4.2.3 格式化文档OCR性能
将光学PDF图像转换为类似markdown的格式是OCR模型的一个重要特性。为了验证GOT在这方面的能力,我们精心准备了90页样本作为高质量基准测试。该基准测试包含中英文文档页面,首先通过Mathpix生成伪标签,然后手动校正错误。在表3中,我们可以看到单尺度(1024×1024)的GOT可以产生令人满意的结果。当我们使用多裁剪推理时,GOT的性能得到了进一步提升,尤其是在公式和表格的小文本上。结果证明了GOT在具有格式化输出的文档上的有效性。此外,动态分辨率方案是在处理更高分辨率图像时的一个不错的选择。
4.2.4 细粒度OCR性能
我们报告了GOT在细粒度OCR指标上的表现。如表4所示,GOT在基于边界框和基于颜色的参照OCR任务上总体上优于Fox[20],表明我们的模型拥有出色的交互式OCR能力。
4.2.5 更通用的OCR性能
我们使用乐谱、几何和图表基准测试来验证GOT在更通用OCR任务上的性能。对于前两个任务,我们分别渲染了100和180个额外样本作为基准测试,正如表3所示,GOT在这些新的OCR任务上仍然表现良好。对于图表OCR,我们使用结构提取版本的ChartQA[32]和PlotQA[35]作为基准测试。在表5中,GOT的图表OCR能力甚至比专门的图表模型和流行的LVLMs还要好。所有结果都证明了我们的模型在更通用的OCR任务上的有效性。
5 结论
本文提出了一个结构比OCR-1.0系统更简单、比LVLMs更专注于纯OCR任务、并且性能更优越的初级OCR-2.0模型。OCR-2.0将各种泛OCR任务集成到一个模型中,是模型设计、数据工程和应用场景中一个有价值的研究方向。我们希望简单、优雅、有效且有前景的GOT OCR-2.0模型能吸引更多关注此类任务。
6 附录
在本节中,我们提供了GOT的足够输出结果,以展示其卓越的OCR性能。我们还展示了不同类型OCR任务的相应输入提示的格式。
标签:Unified,OCR,模型,Towards,图像,GOT,文本,我们 From: https://blog.csdn.net/hhhhhhhhhhwwwwwwwwww/article/details/142323093