# 1. 使用Marker解析PDF文档
# 1.1 Marker简介
Marker能将PDF、EPUB和MOBI转换为markdown。它比nougat快10倍,对大多数文档的准确度更高,并且幻觉风险低。
- 支持各种PDF文档(针对书籍和科学论文进行优化)
- 移除页眉/页脚/其他杂项
- 将大部分方程式转换为LaTeX
- 格式化代码块和表格
- 支持多种语言(尽管大部分测试都是用英语完成),查看settings.py以获取语言列表
- 可在GPU、CPU或MPS上运行
项目地址:https://github.com/VikParuchuri/marker (opens new window)
# 1.2 运行Marker使用实例
# 1.2.1 准备运行环境
实验环境:Macbook Pro 2021,M1 pro芯片,16G内存,macOS Ventura13.2.1系统,Python3.9环境
$ git clone https://github.com/VikParuchuri/marker.git
$ pip3 install -r requirements.txt
$ pip3 install -r scripts/install/brew-requirements.txt
2
3
使用官方requirements安装完依赖后,我这里有各种报错,又安装了如下依赖才成功跑起来。
$ brew install tesseract-lang
$ brew install ghostscript
$ brew install libmagic
$ pip3 install ftfy
$ pip3 install pyspellchecker
$ pip3 install ocrmypdf
$ pip3 install thefuzz
$ pip3 uninstall nougat
$ pip3 install nougat-ocr
$ pip3 install --upgrade transformers
$ pip3 install python-magic
$ pip3 install ray
报错信息:ImportError: cannot import name 'NougatModel' from 'nougat'
解决方案:不要安装 Nougat,只需安装 Nougat-OCR。pip3 uninstall nougat 及 pip3 install nougat-ocr
报错信息:ValueError: Non-consecutive added token '<pad>' found. Should have index 259 but has index 0 in saved vocabulary.
解决方案:更新transformers即可。pip3 install --upgrade transformers
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 1.2.2 解析PDF文档
这里以转换单个文件为例,首次执行时,会自动下载模型。官方支持对文档进行批处理,也有很多超参可以控制转换配置,详见官方README,这里就不赘述了。
$ python3 convert_single.py input/input.pdf output/output.md --parallel_factor 20
--parallel_factor 是批量大小和并行 OCR 工作人员增加多少。数字越大,需要的 VRAM 和 CPU 越多,但处理速度越快,默认设置为 1。
注:这个工具只提取PDF文档里的文本,表格什么的也能解析,但对于图表,解析时会将其丢弃。
# 1.3 将Marker封装成Docker
实验环境:Debian 11 x86_64、Docker version 20.10.17、无GPU。
- 将Marker封装成Docker,方便在其他服务器环境上迁移部署。
- 实测安装依赖及模型需要占用大约12GB存储,运行时至少需要4GB内存,对资源的占用要求还是不小的。
requirements.txt
scikit-learn == 1.3.2
Pillow == 10.1.0
pytesseract == 0.3.10
PyMuPDF == 1.23.5
pymupdf-fonts == 1.0.5
pydantic == 2.4.2
pydantic-settings == 2.0.3
nougat-ocr == 0.1.17
transformers == 4.34.1
numpy == 1.26.1
python-dotenv == 1.0.0
torch == 2.1.1
ray == 2.7.1
tqdm == 4.66.1
tabulate == 0.9.0
thefuzz == 0.20.0
python-magic == 0.4.27
pyspellchecker == 0.7.2
ftfy == 6.1.1
nltk == 3.8.1
ocrmypdf == 15.4.0
bitsandbytes == 0.41.2.post2
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Dockerfile
# 基于python3.9镜像创建新镜像
FROM python:3.9
# 创建容器内部目录
RUN mkdir /code
# 将项目复制到内部目录
ADD . /code/
# 切换到工作目录
WORKDIR /code
# 安装项目依赖
RUN pip install -r requirements.txt
# 安装vim命令
RUN apt-get update && apt-get install vim -y
2
3
4
5
6
7
8
9
10
11
12
build.sh
#!/bin/bash
base_path=$(cd `dirname $0`; pwd)
input_path="${base_path}/input"
output_path="${base_path}/output"
docker build -t marker-image .
docker run -itd --name marker -v ${input_path}:/code/input -v ${output_path}:/code/output marker-image:latest
docker update marker --restart=always
2
3
4
5
6
7
8
9
新建 input 和 output 目录,执行 build.sh 脚本构建镜像与容器,之后在 input 目录上传用于测试的 PDF 文件,进入容器执行。
$ docker exec -it marker /bin/bash
$ python3 convert_single.py input/input.pdf output/output.md --parallel_factor 1
2
# 1.4 其他解析PDF文档的方案
pdf2docx库也可用于解析PDF文档,将其转换成word格式,适用于非扫描版的情形。
$ pip3 install pdf2docx
pdf2word.py
# -*- coding: utf-8 -*-
import os
from pdf2docx import Converter
def pdf2word_by_lib(pdf_file, docx_file):
cv = Converter(pdf_file)
cv.convert(docx_file, start=0, end=None)
cv.close()
def remove_blank_lines_with_spaces(input_string):
lines = input_string.split("\n")
result_lines = []
for line in lines:
# 如果该行不只包含空格,就将其添加到结果中
if line.strip() != "":
result_lines.append(line)
# 使用换行符将结果连接成一个字符串
result_string = "\n".join(result_lines)
return result_string
if __name__ == '__main__':
src_dir = "./pdf/"
dest_dir = "./doc"
num = 0
for root, _, files in os.walk(src_dir):
for filename in files:
if filename.lower().endswith(".pdf"):
try:
src_path = os.path.join(root, filename)
dest_path = os.path.join(dest_dir, os.path.relpath(src_path, src_dir))
txt_filename = os.path.splitext(os.path.basename(dest_path))[0] + ".docx"
os.makedirs(os.path.dirname(dest_path), exist_ok=True)
if os.path.exists(os.path.join(os.path.dirname(dest_path), txt_filename)):
print("continue")
continue
docx = pdf2word_by_lib(src_path,os.path.join(os.path.dirname(dest_path), txt_filename))
except Exception as e:
num = num + 1
print("文件损坏数量:", num)
print("error:", e)
continue
print("文件损坏总数:", num)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 2. 使用ChatGPT翻译文档
# 2.1 ChatGPT-for-Translation简介
项目简介:使用ChatGPT完成文件翻译。该工具接受一个文本文件(.pdf
, .txt
, .md
, .html
或.rtf
)或者一个包含文本的文件夹。它将生成一个直接翻译和一个双语文本文件,对于 PDF 解析做了优化。
项目地址:https://github.com/Raychanan/ChatGPT-for-Translation (opens new window)
# 2.2 ChatGPT-for-Translation使用实例
# 2.2.1 准备运行环境
实验环境:Macbook Pro 2021,M1 pro芯片,16G内存,macOS Ventura13.2.1系统,Python3.9环境
$ git clone https://github.com/Raychanan/ChatGPT-for-Translation.git
$ cd ./ChatGPT-for-Translation/
$ pip3 install -r requirements.txt
$ pip3 install tenacity
2
3
4
# 2.2.2 翻译PDF文档
项目使用:建议使用 gpt-3.5-turbo 模型进行翻译,经济实惠,我翻译了个200页的英文文献,耗时12分钟,花费0.23美刀。
$ python3 ChatGPT-translate.py --input_path=./your_path/your_doc.pdf --openai_key=your_openai_key
默认值是使用gpt-3.5-turbo模型,翻译成简体中文,支持的参数如下:
arguments = [
("--input_path", {"type": str,
"help": "input file or folder to translate"}),
("--openai_key", {"type": str,
"default": "", "help": "OpenAI API key"}),
("--model", {"type": str, "default": "gpt-3.5-turbo",
"help": "Model to use for translation, e.g., 'gpt-3.5-turbo' or 'gpt-4'"}),
("--num_threads", {"type": int, "default": 10,
"help": "number of threads to use for translation"}),
("--target_language", {"type": str, "default": "Simplified Chinese",
"help": "target language to translate to"}),
("--only_process_this_file_extension",
{"type": str, "default": "", "help": "only process files with this extension"}),
("--use_azure", {"action": "store_true", "default": False,
"help": "Use Azure OpenAI service instead of OpenAI platform."}),
("--azure_endpoint",
{"type": str, "default": "", "help": "Endpoint URL of Azure OpenAI service. Only require when use AOAI."}),
("--azure_deployment_name",
{"type": str, "default": "", "help": "Deployment of Azure OpenAI service. Only require when use AOAI."}),
]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
翻译效果:会生成5个文档,分别是txt格式的原文提取、纯中文译文、双语对照译文,以及docx格式的纯中文译文、双语对照译文。
# 2.3 其他文本内容翻译的方案
# 2.3.1 破解Google翻译
破解Google翻译的 py-googletrans (opens new window) 库,使用时需要联网(被墙,国内需要设置代理)
$ pip install googletrans
这个库的工作原理(摘自官方说明):
- 您可能想知道为什么这个库可以正常工作,而其他方法(例如 goslate)却不起作用,因为 Google 最近使用票证机制更新了其翻译服务,以防止大量爬虫程序。
- 我最终找到了一种方法,通过对 Google 用来生成此类令牌的混淆和缩小代码进行逆向工程来生成票证,并在 Python 之上实现。 但是,这可能随时被阻止。
2
示例代码如下:
#-*- coding:utf-8 -*-
from googletrans import Translator
import os
os.environ["https_proxy"] = "http://127.0.0.1:7890"
translator = Translator()
result = translator.translate('hello world', dest='zh-cn').text
print(result)
2
3
4
5
6
7
8
9
10
注:单次请求的最大字符数为5000,超出的话可以拆分成多份,分开请求再对结果进行拼接。另外该破解方式随时可能会被阻止,如果想使用稳定的 API,建议使用 谷歌官方的翻译 API (opens new window)。
# 2.3.2 LibreTranslate机器翻译
LibreTranslate是一个开源的、可以自行搭建的翻译服务,支持多种语言的互相翻译,包括中文。翻译的准确度远不如商业API,效果很一般,但它是永久免费的。服务器上部署LibreTranslate共计需要大约13GB的存储空间。
$ docker run -itd -p 5000:5000 --name libretranslate libretranslate/libretranslate
$ docker logs -f libretranslate --tail 100
2
注:创建容器后会自动下载语言包,这个过程会比较慢,等待它安装完毕后,浏览器访问http://ip:5000
即可查看以下Web页面。
# 3. 搭建QAnything知识库问答系统
# 3.1 QAnything简介
网易有道开源的知识库问答引擎 QAnything,包括专门优化的自研的 embedding 和 rerank 模型,微调后的 LLM,优化后的推理代码,向量数据库,以及一个立即上手可用的前端。所有的算法模型(包括 7B 大模型+embedding/rerank+OCR)占用显存不超过 16G。
# 3.2 QAnything搭建
# 3.2.1 准备运行环境
实验环境:CentOS7,512GB内存,128TB存储,NVIDIA 4090显卡(24GB显存)、CUDA11.7环境
如下是QAnything官方要求的基础环境:
System | Required item | Minimum Requirement | Note |
---|---|---|---|
Linux | NVIDIA GPU Memory | >= 4GB (use OpenAI API) | Minimum: GTX 1050Ti(use OpenAI API) Recommended: RTX 3090 |
NVIDIA Driver Version | >= 525.105.17 | ||
Docker version | >= 20.10.5 | Docker install (opens new window) | |
docker compose version | >= 2.23.3 | docker compose install (opens new window) | |
git-lfs | git-lfs install (opens new window) |
[1] 准备Docker和Docker Compose环境
安装Docker环境
$ curl -fsSL get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh --mirror Aliyun
$ sudo systemctl enable docker
$ sudo systemctl start docker
$ docker version
2
3
4
5
安装Docker Compose环境
$ sudo curl -L https://github.com/docker/compose/releases/download/v2.24.5/docker-compose-Linux-x86_64 -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ docker-compose --version
2
3
[2] 准备NVIDIA驱动环境
安装 nvidia-smi 及 nvidia-cuda-toolkit 工具
$ sudo yum update
$ sudo yum install nvidia-utils-520
$ sudo yum install nvidia-cuda-toolkit
2
3
使用 nvidia-smi
命令可以显示出GPU的所有基础信息。
$ nvidia-smi // 查询GPU详情
$ nvidia-smi -q // 查询GPU型号
$ nvcc --version // 查看CUDA驱动版本
2
3
配置Docker使用GPU,需要安装官方提供的nvidia-container-toolkit工具。
$ curl -s -L https://nvidia.github.io/libnvidia-container/stable/rpm/nvidia-container-toolkit.repo | sudo tee /etc/yum.repos.d/nvidia-container-toolkit.repo
$ sudo yum install -y nvidia-container-toolkit
$ sudo nvidia-ctk runtime configure --runtime=docker
$ sudo systemctl restart docker
2
3
4
[3] 安装git及git-lfs环境
$ sudo yum update
$ yum install git
$ wget https://packagecloud.io/github/git-lfs/packages/el/7/git-lfs-3.4.1-1.el7.x86_64.rpm/download -O git-lfs-3.4.1-1.el7.x86_64.rpm
$ sudo yum install git-lfs-3.4.1-1.el7.x86_64.rpm -y
2
3
4
[4] 安装其他缺失的命令
官方提供的run脚本里需要使用jq命令,未安装的话会启动失败。
$ sudo yum install jq
# 3.2.2 官方脚本一键安装
拉取项目代码,使用官方脚本一键安装,按照脚本提示,输入OpenAI API KEY和服务器IP地址等信息,之后会自动下载模型及环境。
$ git clone https://github.com/netease-youdao/QAnything.git
$ cd QAnything
$ chmod u+x run.sh
$ bash ./run.sh -c cloud -i 0 -b default
2
3
4
这个一键脚本搭建的方式,很多信息都写死了,密码也是最简单的,建议启动之前,先把 docker-compose-linux.yaml 里的配置及相应代码里的连接配置改改。
参数说明及使用方法详见:
当所有环境成功运行起来了之后,后台日志如下:
注意事项:如果服务无法正常使用,检查log里的日志文件即可,看看是不是有的服务没有成功启动。如果需要卸载重新搭建,执行close.sh脚本即可。
# 3.3 QAnything使用
使用 Chrome 浏览器打开后台日志打印出来的 http://xxx.xxx.xxx.xxx:5052/qanything
地址,可以看到如下界面:
之后新建一个知识库,上传一些文档,等待其完成解析。
之后就可以输入问题,根据知识库进行问答了。
# 4. 基于Ollama及AnythingLLM构建知识库问答
# 4.1 Ollama及AnythingLLM简介
# 4.1.1 Ollama基本介绍
Ollama是一个开源的大型语言模型服务工具,它帮助用户快速在本地运行大模型。
- 项目地址:https://github.com/ollama/ollama (opens new window)
- 官方网站:https://ollama.com (opens new window)
- 系统支持:支持Windows、MacOS、Linux系统
# 4.1.2 AnythingLLM基本介绍
AnythingLLM 是一个开源的、可定制的、功能丰富的文档聊天机器人。这是一个全栈应用程序,它能够将任何文档、资源或内容片段转化为LLM在聊天中可以利用的相关上下文。该应用允许用户选择并配置要使用的LLM或向量数据库,并支持多用户管理及权限控制,以确保数据安全和高效协作。
- 项目地址:https://github.com/Mintplex-Labs/anything-llm (opens new window)
- 官方网站:https://useanything.com (opens new window)
- 系统支持:支持Windows、MacOS、Linux系统
# 4.2 Ollama及AnythingLLM安装
实验环境:Macbook Pro 2021,M1 pro芯片,16G内存,macOS Ventura13.2.1系统
# 4.2.1 安装Ollama并下载模型
从官网下载Ollama对应系统的客户端进行安装即可,之后在终端里输入 ollama 命令,即可查看帮助。
$ ollama
然后使用 ollama run 命令启动模型(模型不存在的话会自动下载),这里我使用qwen:0.5b进行测试,支持的模型可在这里查看:https://ollama.com/library (opens new window)
$ ollama run qwen:0.5b
模型服务启动之后,打开 http://127.0.0.1:11434
地址,会告知“Ollama is running”,在终端里可以直接进行问答。
注:如果想要添加 Ollama 未支持的模型或者自己微调的模型,可以使用 llama.cpp (opens new window) 工具将模型转换成 GGUF 格式,然后导入 Ollama,详见:Import a model (opens new window)
# 4.2.2 安装AnythingLLM并配置
从官网下载AnythingLLM对应系统的客户端进行安装即可,首次启动需要进行一些配置。
Step1:LLM模型选择Ollama(参数直接使用默认的)
Step2:Embedding模型选择Ollama(参数直接使用默认的)
Step3:向量数据库选择LanceDB(这个是本地的,比较省事)
Step4:确认AnythingLLM的配置,下一步的邮箱及用途可以随便填,再下一步创建一个Workspace。
Step5:全部配置完成之后,可以进入到AnythingLLM的主界面
# 4.3 在AnythingLLM里进行本地知识库问答
# 4.3.1 构建本地知识库
点击工作空间旁边的上传按钮,上传一些文档,将其加入右侧的工作空间,保存Embedding。
# 4.3.2 本地知识库问答
在 Send a message 处输入要问的问题,大模型很快便可给予回复,点击 Show Citations 可以查看参考了什么文档,这个文档是可以点开来看的。
注:这里的效果不好是因为选用的是qwen:0.5b模型,下面将其换成GPT-4的模型效果就好多了。
# 4.3.3 将LLM服务换成GPT4
点击左侧底部的“扳手”图标,即可进入到 AnythingLLM设置页,在这里可以对之前的初始化配置进行重新设置。
需要注意的是,国内用户使用GPT-4 别选择那个OpenAI(没有配置代理的地方,国内网络访问不通)。而是应该选择Local Al,这里去自定义配置,相当于使用BaseURL的方式。
同理,Embedding Model(选择text-embedding-ada-002)与 Vector Database (还是选择LanceDB)也重新配置。然后删掉之间的工作空间,重新上传文档构建本地知识库,再重新进行问答即可。
注:因为Vector Database 还是使用LanceDB,一开始我并没有将其重配,但是问答时报错 LanceDBError: No vector column found to create index,我将之前的Vector Database、工作空间、本地知识库全部删了重新配置即可正常使用。
# 5. 参考资料
[1] cannot import name 'cached_property' from 'nougat.utils' from Github issues (opens new window)
[2] privateGPT不支持中文吗 from Github issues (opens new window)
[3] 免费且无限制的 Python 谷歌翻译 API from Github (opens new window)
[4] 网易有道开源的知识库问答引擎 QAnything from Github (opens new window)
[5] 阿里云推出企业级大模型RAG系统,几次点击即可连接PB级知识库 from 微信公众号 (opens new window)
[6] Ollama + AnythingLLM,有手就行本地知识库+LLM 组合拳 from Bilibili (opens new window)
[7] Ollama导入 GGUF、PyTorch 或 Safetensors 模型 from Github (opens new window)
[8] llama.cpp是在本地以最少硬件配置和最先进的性能实现 LLM 推理 from Github (opens new window)