diff --git a/.gitignore b/.gitignore index 216ffd1a..a6109f39 100644 --- a/.gitignore +++ b/.gitignore @@ -32,7 +32,8 @@ tmp .vscode/ ocr_demo .coveragerc - + + # sphinx docs _build/ diff --git a/docs/specification/output_format/content_list_spec.md b/docs/specification/output_format/content_list_spec.md index 73f21bd4..420795b0 100644 --- a/docs/specification/output_format/content_list_spec.md +++ b/docs/specification/output_format/content_list_spec.md @@ -1,5 +1,7 @@ # 流水线content_list格式数据输出标准 +## https://aicarrier.feishu.cn/wiki/RWZywKLW8iSvn6kZWGBc70JSn6f + ## 目的 定义content_list的目的是为了统一流水线输出的数据格式,无论是网页、电子书、富文本pdf,word,ppt等,都可以转化到这个格式。 @@ -50,35 +52,45 @@ 支持的文档元素类型 -| ---- | 网页 | 文档 | 说明 | -| ------------------ | ---- | ---- | ------------------------------------------------------------------------------------ | -| code | ✅ | ✅ | 代码 | -| algorithm | ❌ | ✅ | 伪代码 | -| equation-interline | ✅ | ✅ | 行内公式 | -| image | ✅ | ✅ | 图片 | -| simple_table | ✅ | ✅ | 可转化为markdown的表格 | -| complex_table | ✅ | ✅ | 含有合并单元格的表格,不可转为markdown | -| list | ✅ | ✅ | 列表 | -| ref_list | ❌ | ✅ | 论文参考文献列表 | -| title | ✅ | ✅ | 标题 | -| paragraph | ✅ | ✅ | 文字可表示内容,内部可以含有多种文字类型,`纯文本`,`行内公式`,`行内代码`,`拼音`等 | -| audio | ✅ | ❌ | 音频,只在网页数据里有 | -| video | ✅ | ❌ | 视频,只在网页数据里有 | -| page_header | ❌ | ✅ | 文档页眉 | -| page_footer | ❌ | ✅ | 文档页脚 | -| page_number | ❌ | ✅ | 文档页码 | -| page_aside_text | ❌ | ✅ | 文档边注 | -| page_footnote | ❌ | ✅ | 文档论文脚注 | - -其中`paragraph`又由以下几种类型组成: - -- `equation-inline`代表行内公式 -- `text`代表普通纯文本 -- `code-inline`代表行内文本,例如“执行linux`ls`命令” +| ---- | 网页 | 文档 | 子类型 | 说明 | +| ------------------ | ---- | ---- | ------------------------------- | ----------------------------------------------------------- | +| code | ✅ | ✅ | - | 代码 | +| algorithm | ❌ | ✅ | - | 伪代码 | +| equation-interline | ✅ | ✅ | - | 行内公式 | +| image | ✅ | ✅ | `general`, `chart` | 图片 | +| table | ✅ | ✅ | `simple_table`, `complex_table` | simple table可转化为markdown的表格 ,否则是complex_table | +| list | ✅ | ✅ | `text_list`, `reference_list` | text_list是普通的列表,reference_list是论文里的参考文献列表 | +| title | ✅ | ✅ | | 标题 | +| paragraph | ✅ | ✅ | | 文字可表示可打印内容,由`text_content`所表示 | +| page_header | ❌ | ✅ | | 文档页眉 | +| page_footer | ❌ | ✅ | | 文档页脚 | +| page_number | ❌ | ✅ | | 文档页码 | +| page_aside_text | ❌ | ✅ | | 文档边注 | +| page_footnote | ❌ | ✅ | | 文档论文脚注 | + +其中可打印文本均使用`text_content`结构表示(例如拼音,普通纯文本,行内公式,行内代码,markdown文本): + +```json +{ + "type": "text|equation_inline|code_inline|md|phonetic", + "content": "printable string" +} + +``` + +其中type可以取值为: + +- `text` : 普通文字 +- `equation_inline` : 行内公式,例如`爱因斯坦的智能方程公式E=MC^2是个伟大的发现。` +- `code_inline`: 行内代码,例如`执行ls命令查看目录下的文件` +- `md`: markdown格式的文本 +- `phonetic`: 汉语拼音 + +**如有必要刻意继续扩展** ## 字段定义 -### 代码段 +### 代码段(code) 代表多行的独立代码段 @@ -90,7 +102,7 @@ "type": "code", "bbox":[x1, y1, x2, y2] "content": { - "caption":["下面是一段python求和函数"], + "code_caption":[text_content_1, text_content_2], "code_content": "def add(a, b):\\n return a + b", "language":"python", "by": "tag_code" @@ -98,15 +110,15 @@ } ``` -| 字段 | 类型 | 描述 | 是否必须 | -| -------------------- | ------ | ---------------------------------------------- | -------- | -| type | string | 值固定为code | 是 | -| content.code_content | string | 干净的,格式化过的代码内容 | 是 | -| content.caption | list | 代码标题,可以有多个。网页没有此字段 | 否 | -| content.language | string | 代码语言,python\\cpp\\php... | 可选 | -| content.by | string | 哪种代码高亮工具 、自定义规则,目前只在网页里有 | 可选 | +| 字段 | 类型 | 描述 | 是否必须(文档) | 是否必须(网页) | +| -------------------- | -------------------- | ------------------------------------------------------------------------ | -------------- | -------------- | +| type | string | 值固定为code | 是 | 是 | +| content.code_content | string | 干净的,格式化过的代码内容 | 是 | 是 | +| content.code_caption | list\[text_content\] | 代码标题,可以有多个。网页没有此字段, 每一个元素是一个`text_content`结构 | 否 | 无 | +| content.language | string | 代码语言,python\\cpp\\php... | 可选 | 可选 | +| content.by | string | 哪种代码高亮工具 、自定义规则,目前只在网页里有 | 可选 | 可选 | -### 伪代码 +### 伪代码(algorithm) > ⚠️只在文档中出现,网页中无 @@ -116,23 +128,23 @@ "bbox": [x1, y1, x2, y2], "content":{ "algorithm_content":"循环:\n当x<0时停止", - "caption":["title-1", "title-2"] + "algorithm_caption":[text_content_1, text_content_2] } } ``` -| 字段 | 类型 | 描述 | 是否必须 | -| ------------------------- | ------ | ------------------------------------ | -------- | -| type | string | 固定为algorithm,代表伪代码内容 | 是 | -| content.algorithm_content | string | 干净的,格式化过的代码内容 | 是 | -| content.caption | list | 代码标题,可以有多个。网页没有此字段 | 否 | +| 字段 | 类型 | 描述 | 是否必须(文档) | 是否必须(网页) | +| ------------------------- | -------------------- | ------------------------------------------------------------------ | -------------- | -------------- | +| type | string | 固定为algorithm,代表伪代码内容 | 是 | 无 | +| content.algorithm_content | string | 干净的,格式化过的代码内容 | 是 | 无 | +| content.algorithm_caption | list\[text_content\] | 代码标题,可以有多个。网页没有此字段。每个元素是`text_content`结构 | 可选 | 无 | -### 行间公式段 +### 行间公式段(equation_interline) ```json { - "type": "equation-interline", + "type": "equation_interline", "bbox": [x1, y1, x2, y2], "content": { "math_content": "a^2 + b^2 = c^2", @@ -142,98 +154,44 @@ } ``` -| 字段 | 类型 | 描述 | 是否必须 | -| -------------------- | ------ | --------------------------------------------------------------- | -------- | -| type | string | 可选为equation-interline或者equation-inline | 是 | -| content.math_content | string | 干净的,格式化过的公式内容。无论是行内还是行间公式两边都不能有$ | 是 | -| content.math_type | string | 公式语言类型,latex\\mathml\\asciimath | 可选 | -| content.by | string | 原html中使用公式渲染器,mathjax\\katex | 可选 | +| 字段 | 类型 | 描述 | 是否必须(文档) | 是否必须(网页) | +| -------------------- | ------ | --------------------------------------------------------------------- | -------------- | -------------- | +| type | string | 可选为equation-interline或者equation-inline | 是 | 是 | +| content.math_content | string | 干净的,格式化过的公式内容。无论是行内还是行间公式两边都不能有$ | 是 | 是 | +| content.math_type | string | 公式语言类型,latex\\mathml\\asciimath | 无 | 是 | +| content.by | string | 原html中使用公式渲染器,mathjax\\katex | 无 | 是 | +| content.image_source | dict | {"url":"http://xxx.com/1.png", "path":"/mnt/data/1.png", "base64":""} | 需要有 | 无 | -### 图片段 +### 图片段(image) ```json { "type": "image", "bbox": [x1, y1, x2, y2], "content": { - "url": "http://static4.wikia.nocookie.net/__cb20120619225143/central/images/thumb/3/30/Screen_Shot_2012-06-19_at_6.25.45_PM.png/180px-Screen_Shot_2012-06-19_at_6.25.45_PM.png", - "data": null, - "alt": "Screen Shot 2012-06-19 at 6.25.45 PM", - "title": null, - "caption": ["What it ACTUALLY looks like"], - "footnote":[], - "caption_bbox":[[x1,y1, x2, y2]], // html没有 - "footnote_bbox":[[x1, y1, x2, y2]] // html没有 + "image_type":"general | chat", + "image_source": {"url":"http://xxx.com/1.png", "path":"/mnt/data/1.png", "base64":""}, + "image_caption": [text_content_1, text_content_2], + "image_footnote":[text_content_1, text_content_2], + "alt": text_content, + "title": text_content } } ``` -| 字段 | 类型 | 描述 | 是否必须 | -| ---------------- | ------ | -------------------- | -------- | -| type | string | 值固定为image | 是 | -| content.url | string | 图片的url地址 | 可选 | -| content.data | string | base64形式的图片数据 | 可选 | -| content.alt | string | 图片的alt属性 | 可选 | -| content.title | string | 图片的title属性 | 可选 | -| content.caption | list | 图片的caption属性 | 可选 | -| content.footnote | list | 图片的footnote属性 | 可选 | - -> `content.url`和`content.data`二者必须有一个,数据使用优先级是`data`>`url`。 +| 字段 | 类型 | 描述 | 是否必须(文档) | 是否必须(网页) | +| ---------------------- | -------------------- | ------------------------------------------------------------------------------------------------ | ------------------- | ------------------ | +| type | string | 值固定为`image` | 是 | 是 | +| content.image_type | string | 可选值为`general`普通图片,`chat` 图表(柱状图,折线图等) | 是 | 固定为`general` | +| content.image_source | dict | key有`url`代表网络图片地址, `path`代表本地存储如磁盘,s3, ftp等, `base64` 代表以base64编码的图片 | 支持`path`,`base64` | 支持`url`,`base64` | +| content.image_caption | list\[text_content\] | 图片的caption属性 | 可以有多个 | 只有1个元素 | +| content.image_footnote | list\[text_content\] | 图片的footnote属性 | 可以有多个 | 没有 | +| content.alt | `text_content` | 网页图片的alt属性 | 没有 | 只有一个 | +| content.title | `text_content` | 网页图片的title属性 | 没有 | 只有一个 | -### 音频段 +> 对于网页来说image_source里`url`和`base64`二者必须有一个,数据使用优先级是`base64`>`url`。 -> ⚠️网页中有,文档中没有 - -```json -{ - "type": "audio", - "content": { - "sources": ["https://www.example.com/audio.mp3"], - "path": "s3://llm-media/audio.mp3", - "title": "example audio", - "caption": ["text from somewhere"] - } -} -``` - -| 字段 | 类型 | 描述 | 是否必须 | -| --------------- | ------ | ------------------ | -------- | -| type | string | 值固定为audio | 是 | -| bbox | array | \[x1, y1, x2, y2\] | 可选 | -| content.sources | array | 音频的url地址 | 可选 | -| content.path | string | 音频的存储路径 | 可选 | -| content.title | string | 音频的title属性 | 可选 | -| content.caption | list | 音频的caption属性 | 可选 | - -### 视频段 - -> ⚠️网页中有,文档中没有 - -```json -{ - "type": "video", - "bbox": [0, 0, 50, 50], - "raw_content": null, - "content": { - "sources": ["https://www.example.com/video.avi"], - "path": "s3://llm-media/video.mp4", - "title": "example video", - "caption": ["text from somewhere"] - } - } -``` - -| 字段 | 类型 | 描述 | 是否必须 | -| --------------- | ------ | ------------------ | -------- | -| type | string | 值固定为video | 是 | -| bbox | array | \[x1, y1, x2, y2\] | 可选 | -| raw_content | string | 原始文本内容 | 可选 | -| content.sources | array | 视频的url地址 | 可选 | -| content.path | string | 视频的存储路径 | 可选 | -| content.title | string | 视频的title属性 | 可选 | -| content.caption | list | 视频的caption属性 | 可选 | - -### 复杂表格\[含跨行、列合并,嵌套\] +### 表格\[含跨行、列合并,嵌套表格\] ```json { @@ -241,11 +199,11 @@ "bbox": [x1, y1, x2, y2], "content": { "html": "
指标数据
20232024
营收1015
", - "table_nest_level": "1", - "caption":[], - "footnote":[], - "caption_bbox":[[]], // html无 - "footnote_bbox":[[]] // html无 + "table_type":"comlex_table | simple_table" # 复杂表 | 简单表 + "table_nest_level": 1, + "table_caption":[text_content_1, text_content_2], + "table_footnote":[text_content_1, text_content_2], + "image_source":{"url":"", "path":"", "base64":""} } } ``` @@ -255,33 +213,12 @@ | type | string | 可选值为simple_table、complex_table | 是 | | bbox | 四元组 | 元素位置坐标 | 可选 | | content.html | string | 表格的html内容 | 是 | +| content.table_type | string | 取值为`complex_table`或者`simple_table` | 是 | | content.table_nest_level | int | table嵌套层级(单个table为1,两层为2,以此类推) | 可选 | -| content.caption | string | 表格的caption内容 | 否 | -| content.footnote | string | 表格的footnote内容 | 否 | +| content.table_caption | list | 表格的caption内容 | 否 | +| content.table_footnote | list | 表格的footnote内容 | 否 | -### 简单表格 \[可用markdown表达的表格\] - -```json -{ - "type":"simple_table", - "bbox": [x1, y1, x2, y2], - "content": { - "html":"", - "caption":[], - "footnote":[], - "caption_bbox":[[]], // html无 - "footnote_bbox":[[]] // html无 - } -} -``` - -| 字段 | 类型 | 描述 | 是否必须 | -| ---------------- | ------ | ----------------------------------- | -------- | -| type | string | 可选值为simple_table、complex_table | 是 | -| bbox | 四元组 | 元素位置坐标 | 可选 | -| content.html | string | 表格的html内容 | 是 | -| content.caption | list | 表格的caption内容 | 否 | -| content.footnote | list | 表格的footnote内容 | 否 | +> **complex_table** 是有单元格合并的表,不能转为markdown;**simple_table** 是没有单元格合并的表格,可以用markdown表达 ### 列表段\[支持嵌套\] @@ -290,39 +227,28 @@ "type": "list", "bbox": [x1, y1, x2, y2], "content": { - "items": [ - { - "c": "外层列表项" - }, - { - "child_list": { - "list_attribute": "ordered", - "items": [ - { - "c": "行内公式: $E=mc^2$" - }, - { - "c": "行内代码: `x = 1`" - } - ] - } - }, + "list_type": "text_list | reference_list" ,// 普通list 或者是论文里的引文列表(html里没有) + "attribute": "definition", + "list_nest_level": 1, + "list_items":[ { - "c": "外层另一个列表项" + "item_type":"text", // 此处是text的例子,如果是list类型,那么item_content就是一个新的list + "item_content": text_content }, { - "child_list": { - "list_attribute": "unordered", - "items": [ - { - "c": "第二层菜单项" + "item_type": "list", // 嵌套的列表,此时item_content是一个新的list + "item_content": { + "type": "list", + "bbox":[a,b,c,d], + "content": { + "list_type": "text_list", + "attribute":"definition", + "list_nest_level": 2, + "list_items":[] } - ] - } + }//end item_content } - ], - "list_attribute": "definition", - "list_nest_level": "2" + ] } } ``` @@ -332,7 +258,7 @@ | type | string | 值固定为list | 是 | | bbox | 四元组 | 元素位置坐标 | 可选 | | content.items | array | 列表项,每个元素是N个段落,段落里的元素是文本、公式或代码 | 是 | -| content.list_attribute | string | unordered/ordered/definition | 可选 | +| content.attribute | string | unordered/ordered/definition | 可选 | | content.list_nest_level | int | list的嵌套层级(单层list list_nest_level为1) | 可选 | items字段说明 @@ -341,21 +267,6 @@ - 每个元素是一个对象,包含字段:c和t。 c是内容content首字母,t是类型type首字母。 - t的取值同`paragraph` -### ref_list 参考文献列表 - -> ⚠️仅在文档论文中有 - -```json -{ - "type":"ref_list", - "bbox": [x1, y1, x2, y2], - "content":{ - // same as list - } -} - -``` - ### 标题段 ```json @@ -363,18 +274,18 @@ "type": "title", "bbox": [x1, y1, x2, y2], "content": { - "title_content": "大模型好,大模型棒1", - "level": "1" + "title_content": text_content, + "level": 1 } } ``` -| 字段 | 类型 | 描述 | 是否必须 | -| --------------------- | ------ | -------------------- | -------- | -| type | string | 值固定为title | 是 | -| bbox | 四元组 | 元素位置坐标 | 可选 | -| content.title_content | string | 标题内容 | 是 | -| content.level | int | 标题级别,1-N, 1最大 | 可选 | +| 字段 | 类型 | 描述 | 是否必须 | +| --------------------- | ------------ | -------------------- | -------- | +| type | string | 值固定为title | 是 | +| bbox | 四元组 | 元素位置坐标 | 可选 | +| content.title_content | text_content | 标题内容 | 是 | +| content.level | int | 标题级别,1-N, 1最大 | 可选 | ### 段落 @@ -383,30 +294,20 @@ "type": "paragraph", "bbox": [x1, y1, x2, y2], "content": [ - { - "bbox":[x1, y1, x2, y2], // html没有 - "c": "Who Is In Your Top 3 Mentalists Of All Time? x = 1", - "t": "text" - }, - { - "bbox":[x1, y1, x2, y2], // html没有 - "c": "E=mc^2", - "t": "equation-inline" - }, - { - "bbox":[x1, y1, x2, y2], // html没有 - "c": "• MAGICIANSANDMAGIC.COM", - "t": "text" - } + text_content_1, # 代表一句纯文本 + text_content_2, # 行内公式 + text_content_3, # 纯文本 + text_content_4, # 行内代码 + text_content_5, # 拼音 ] } ``` -| 字段 | 类型 | 描述 | 是否必须 | -| ------- | ------ | --------------------------------------------------------------- | -------- | -| type | string | 值固定为paragraph | 是 | -| bbox | 四元组 | 元素位置坐标 | 可选 | -| content | array | 段落内容,每个元素是一个对象,包含字段c和t。 c是内容,t是类型。 | 是 | +| 字段 | 类型 | 描述 | 是否必须 | +| ------- | -------------------- | --------------------------------------------------------------- | -------- | +| type | string | 值固定为paragraph | 是 | +| bbox | 四元组 | 元素位置坐标 | 可选 | +| content | list\[text_content\] | 段落内容,每个元素是一个对象,包含字段c和t。 c是内容,t是类型。 | 是 | content字段说明 @@ -427,7 +328,7 @@ "type": "page_header", "bbox":[x0, y0, x1, y1], "content": { - "page_header_content": "大模型学习资料", + "page_header_content": text_content, } } ``` @@ -441,7 +342,7 @@ "type": "page_footer", "bbox":[x0, y0, x1, y1], "content": { - "page_footer_content": "~~内部资料请勿外传~~", + "page_footer_content": text_content, } } ``` @@ -455,7 +356,7 @@ "type": "page_number", "bbox":[x0, y0, x1, y1], "content": { - "page_number_content": "--12--", + "page_number_content": text_content, } } ``` @@ -469,7 +370,7 @@ "type": "page_aside_text", "bbox":[x0, y0, x1, y1], "content": { - "page_aside_text_content": "LLM大模型学习资料", + "page_aside_text_content": text_content, } } ``` @@ -483,7 +384,7 @@ "type": "page_footnote", "bbox":[x0, y0, x1, y1], "content": { - "page_footnote_content": "大模型的代表公司有OpenAI、Claude等", + "page_footnote_content": text_content, } } ```