Skip to content

Commit 7c419a2

Browse files
committed
pdf parse doc (#3990)
1 parent e131465 commit 7c419a2

File tree

9 files changed

+123
-52
lines changed

9 files changed

+123
-52
lines changed

docSite/assets/imgs/image copy.png

329 KB
Loading

docSite/assets/imgs/marker2.png

216 KB
Loading

docSite/assets/imgs/marker3.png

85.3 KB
Loading

docSite/content/zh-cn/docs/development/configuration.md

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,52 @@ weight: 707
2525
"qaMaxProcess": 15, // 问答拆分线程数量
2626
"vlmMaxProcess": 15, // 图片理解模型最大处理进程
2727
"tokenWorkers": 50, // Token 计算线程保持数,会持续占用内存,不能设置太大。
28-
"pgHNSWEfSearch": 100 // 向量搜索参数。越大,搜索越精确,但是速度越慢。设置为100,有99%+精度。
28+
"pgHNSWEfSearch": 100, // 向量搜索参数。越大,搜索越精确,但是速度越慢。设置为100,有99%+精度。
29+
"customPdfParse": { // 4.9.0 新增配置
30+
"url": "", // 自定义 PDF 解析服务地址
31+
"key": "", // 自定义 PDF 解析服务密钥
32+
"doc2xKey": "", // doc2x 服务密钥
33+
"price": 0 // PDF 解析服务价格
34+
}
2935
}
3036
}
3137
```
38+
39+
## 自定义 PDF 解析配置
40+
41+
自定义 PDF 服务解析的优先级高于 Doc2x 服务,所以如果使用 Doc2x 服务,请勿配置自定义 PDF 服务。
42+
43+
### 使用 Sealos PDF 解析服务
44+
45+
#### 1. 申请 Sealos AI proxy API Key
46+
47+
[点击打开 Sealos Pdf parser 官网](https://cloud.sealos.run/?uid=fnWRt09fZP&openapp=system-aiproxy),并进行对应 API Key 的申请。
48+
49+
#### 2. 修改 FastGPT 配置文件
50+
51+
`systemEnv.customPdfParse.url`填写成`https://aiproxy.hzh.sealos.run/v1/parse/pdf?model=parse-pdf`
52+
`systemEnv.customPdfParse.key`填写成在 Sealos AI proxy 中申请的 API Key。
53+
54+
![](/imgs/deployconfig-aiproxy.png)
55+
56+
### 使用 Doc2x 解析 PDF 文件
57+
58+
`Doc2x`是一个国内提供专业 PDF 解析。
59+
60+
#### 1. 申请 Doc2x 服务
61+
62+
[点击打开 Doc2x 官网](https://doc2x.noedgeai.com?inviteCode=9EACN2),并进行对应 API Key 的申请。
63+
64+
#### 2. 修改 FastGPT 配置文件
65+
66+
开源版用户在 `config.json` 文件中添加 `systemEnv.customPdfParse.doc2xKey` 配置,并填写上申请到的 API Key。并重启服务。
67+
68+
商业版用户在 Admin 后台根据表单指引填写 Doc2x 服务密钥。
69+
70+
#### 3. 开始使用
71+
72+
在知识库导入数据或应用文件上传配置中,可以勾选`PDF 增强解析`,则在对 PDF 解析时候,会使用 Doc2x 服务进行解析。
73+
74+
### 使用 Marker 解析 PDF 文件
75+
76+
[点击查看 Marker 接入教程](/docs/development/custom-models/marker)

docSite/content/zh-cn/docs/development/custom-models/marker.md

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ weight: 909
1111

1212
PDF 是一个相对复杂的文件格式,在 FastGPT 内置的 pdf 解析器中,依赖的是 pdfjs 库解析,该库基于逻辑解析,无法有效的理解复杂的 pdf 文件。所以我们在解析 pdf 时候,如果遇到图片、表格、公式等非简单文本内容,会发现解析效果不佳。
1313

14-
市面上目前有多种解析 PDF 的方法,比如使用 [Marker](https://github.com/VikParuchuri/marker),该项目使用了 Surya 模型,基于视觉解析,可以有效提取图片、表格、公式等复杂内容。为了可以让 Marker 快速接入 FastGPT,我们做了一个自定义解析的拓展 Demo。
14+
市面上目前有多种解析 PDF 的方法,比如使用 [Marker](https://github.com/VikParuchuri/marker),该项目使用了 Surya 模型,基于视觉解析,可以有效提取图片、表格、公式等复杂内容。
1515

16-
在 FastGPT 4.8.15 版本中,你可以通过增加一个环境变量,来替换掉 FastGPT 系统内置解析器,实现自定义的文档解析服务。该功能只是 Demo 阶段,后期配置模式和交互规则会发生改动
16+
`FastGPT v4.9.0` 版本中,开源版用户可以在`config.json`文件中添加`systemEnv.customPdfParse`配置,来使用 Marker 解析 PDF 文件。商业版用户直接在 Admin 后台根据表单指引填写即可。需重新拉取 Marker 镜像,接口格式已变动
1717

1818
## 使用教程
1919

20-
### 1. 按照 Marker
20+
### 1. 安装 Marker
2121

2222
参考文档 [Marker 安装教程](https://github.com/labring/FastGPT/tree/main/plugins/model/pdf-marker),安装 Marker 模型。封装的 API 已经适配了 FastGPT 自定义解析服务。
2323

@@ -28,29 +28,46 @@ docker pull crpi-h3snc261q1dosroc.cn-hangzhou.personal.cr.aliyuncs.com/marker11/
2828
docker run --gpus all -itd -p 7231:7231 --name model_pdf_v1 crpi-h3snc261q1dosroc.cn-hangzhou.personal.cr.aliyuncs.com/marker11/marker_images:latest
2929
```
3030

31-
### 2. 添加 FastGPT 环境变量
32-
33-
```
34-
CUSTOM_READ_FILE_URL=http://xxxx.com/v1/parse/file
35-
CUSTOM_READ_FILE_EXTENSION=pdf
31+
### 2. 添加 FastGPT 文件配置
32+
33+
```json
34+
{
35+
xxx
36+
"systemEnv": {
37+
xxx
38+
"customPdfParse": {
39+
"url": "http://xxxx.com/v1/parse/file", // 自定义 PDF 解析服务地址
40+
"key": "", // 自定义 PDF 解析服务密钥
41+
"doc2xKey": "", // doc2x 服务密钥
42+
"price": 0 // PDF 解析服务价格
43+
}
44+
}
45+
}
3646
```
3747

38-
* CUSTOM_READ_FILE_URL - 自定义解析服务的地址, host改成解析服务的访问地址,path 不能变动。
39-
* CUSTOM_READ_FILE_EXTENSION - 支持的文件后缀,多个文件类型,可用逗号隔开。
48+
需要重启服务。
4049

4150
### 3. 测试效果
4251

43-
通过知识库上传一个 pdf 文件,并确认上传,可以在日志中看到 LOG (LOG_LEVEL需要设置 info 或者 debug):
52+
通过知识库上传一个 pdf 文件,并勾选上 `PDF 增强解析`
53+
54+
![alt text](/imgs/marker2.png)
55+
56+
确认上传后,可以在日志中看到 LOG (LOG_LEVEL需要设置 info 或者 debug):
4457

4558
```
46-
[Info] 2024-12-05 15:04:42 Parsing files from an external service
59+
[Info] 2024-12-05 15:04:42 Parsing files from an external service
4760
[Info] 2024-12-05 15:07:08 Custom file parsing is complete, time: 1316ms
4861
```
4962

5063
然后你就可以发现,通过 Marker 解析出来的 pdf 会携带图片链接:
5164

5265
![alt text](/imgs/image-10.png)
5366

67+
同样的,在应用中,你可以在文件上传配置里,勾选上 `PDF 增强解析`
68+
69+
![alt text](/imgs/marker3.png)
70+
5471

5572
## 效果展示
5673

docSite/content/zh-cn/docs/development/upgrading/490.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: 'FastGPT V4.9.0 更新说明'
44
icon: 'upgrade'
55
draft: false
66
toc: true
7-
weight: 803
7+
weight: 801
88
---
99

1010

@@ -32,9 +32,10 @@ curl --location --request POST 'https://{{host}}/api/admin/initv490' \
3232

3333
## 兼容 & 弃用
3434

35-
1. 弃用 - 弃用旧版本地文件上传 API:/api/core/dataset/collection/create/file(以前仅商业版可用的 API,该接口已放切换成:/api/core/dataset/collection/create/localFile)
36-
2. 停止维护,即将弃用 - 外部文件库相关 API,可通过 API 文件库替代。
37-
3. API更新 - 上传文件至知识库、创建连接集合、API 文件库、推送分块数据等带有 `trainingType` 字段的接口,`trainingType`字段未来仅支持`chunk``QA`两种模式。增强索引模式将设置单独字段:`autoIndexes`,目前仍有适配旧版`trainingType=auto`代码,但请尽快变更成新接口类型。具体可见:[知识库 OpenAPI 文档](/docs/development/openapi/dataset.md)
35+
1. 弃用 - 之前私有化部署的自定义文件解析方案,请同步更新到最新的配置方案。[点击查看 PDF 增强解析配置](/docs/development/configuration/#使用-doc2x-解析-pdf-文件)
36+
2. 弃用 - 弃用旧版本地文件上传 API:/api/core/dataset/collection/create/file(以前仅商业版可用的 API,该接口已放切换成:/api/core/dataset/collection/create/localFile)
37+
3. 停止维护,即将弃用 - 外部文件库相关 API,可通过 API 文件库替代。
38+
4. API更新 - 上传文件至知识库、创建连接集合、API 文件库、推送分块数据等带有 `trainingType` 字段的接口,`trainingType`字段未来仅支持`chunk``QA`两种模式。增强索引模式将设置单独字段:`autoIndexes`,目前仍有适配旧版`trainingType=auto`代码,但请尽快变更成新接口类型。具体可见:[知识库 OpenAPI 文档](/docs/development/openapi/dataset.md)
3839

3940
## 🚀 新增内容
4041

packages/service/common/file/read/utils.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,9 @@ export const readRawContentByFileBuffer = async ({
8181
filename: `file.${extension}`
8282
});
8383
const { data: response } = await axios.post<{
84-
success: boolean;
85-
message: string;
86-
data: {
87-
page?: number; // abandon
88-
pages: number;
89-
markdown: string;
90-
};
84+
pages: number;
85+
markdown: string;
86+
error?: Object | string;
9187
}>(url, data, {
9288
timeout: 600000,
9389
headers: {
@@ -96,15 +92,19 @@ export const readRawContentByFileBuffer = async ({
9692
}
9793
});
9894

95+
if (response.error) {
96+
return Promise.reject(response.error);
97+
}
98+
9999
addLog.info(`Custom file parsing is complete, time: ${Date.now() - start}ms`);
100100

101-
const rawText = response.data.markdown;
101+
const rawText = response.markdown;
102102
const { text, imageList } = matchMdImgTextAndUpload(rawText);
103103

104104
createPdfParseUsage({
105105
teamId,
106106
tmbId,
107-
pages: response.data.page || response.data.pages
107+
pages: response.pages
108108
});
109109

110110
return {

projects/app/data/config.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@
88
"qaMaxProcess": 10, // 问答拆分线程数量
99
"vlmMaxProcess": 10, // 图片理解模型最大处理进程
1010
"tokenWorkers": 30, // Token 计算线程保持数,会持续占用内存,不能设置太大。
11-
"pgHNSWEfSearch": 100 // 向量搜索参数。越大,搜索越精确,但是速度越慢。设置为100,有99%+精度。
11+
"pgHNSWEfSearch": 100, // 向量搜索参数。越大,搜索越精确,但是速度越慢。设置为100,有99%+精度。
12+
"customPdfParse": {
13+
"url": "", // 自定义 PDF 解析服务地址
14+
"key": "", // 自定义 PDF 解析服务密钥
15+
"doc2xKey": "", // doc2x 服务密钥
16+
"price": 0 // PDF 解析服务价格
17+
}
1218
}
1319
}

projects/app/src/pageComponents/dataset/detail/Import/commonProgress/PreviewData.tsx

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -127,31 +127,33 @@ const PreviewData = () => {
127127
{t('dataset:preview_chunk_intro')}
128128
</Box>
129129
</Flex>
130-
<MyBox isLoading={isLoading} flex={'1 0 0'} overflowY={'auto'} px={5} py={3}>
131-
{previewFile ? (
132-
<>
133-
{data.map((item, index) => (
134-
<Box
135-
key={index}
136-
fontSize={'sm'}
137-
color={'myGray.600'}
138-
_notLast={{
139-
mb: 3,
140-
pb: 3,
141-
borderBottom: 'base'
142-
}}
143-
_hover={{
144-
bg: 'myGray.100'
145-
}}
146-
>
147-
<Markdown source={item.q} />
148-
<Markdown source={item.a} />
149-
</Box>
150-
))}
151-
</>
152-
) : (
153-
<EmptyTip text={t('dataset:preview_chunk_not_selected')} />
154-
)}
130+
<MyBox isLoading={isLoading} flex={'1 0 0'} h={0}>
131+
<Box h={'100%'} overflowY={'auto'} px={5} py={3}>
132+
{previewFile ? (
133+
<>
134+
{data.map((item, index) => (
135+
<Box
136+
key={index}
137+
fontSize={'sm'}
138+
color={'myGray.600'}
139+
_notLast={{
140+
mb: 3,
141+
pb: 3,
142+
borderBottom: 'base'
143+
}}
144+
_hover={{
145+
bg: 'myGray.100'
146+
}}
147+
>
148+
<Markdown source={item.q} />
149+
<Markdown source={item.a} />
150+
</Box>
151+
))}
152+
</>
153+
) : (
154+
<EmptyTip text={t('dataset:preview_chunk_not_selected')} />
155+
)}
156+
</Box>
155157
</MyBox>
156158
</Flex>
157159
</Flex>

0 commit comments

Comments
 (0)