Merge branch 'dev'
This commit is contained in:
commit
82f1b7f2e3
|
|
@ -172,3 +172,5 @@ llm/*
|
||||||
embedding/*
|
embedding/*
|
||||||
|
|
||||||
pyrightconfig.json
|
pyrightconfig.json
|
||||||
|
loader/tmp_files
|
||||||
|
flagged/*
|
||||||
|
|
@ -82,6 +82,7 @@ docker run --gpus all -d --name chatglm -p 7860:7860 -v ~/github/langchain-ChatG
|
||||||
本项目已在 Python 3.8 - 3.10,CUDA 11.7 环境下完成测试。已在 Windows、ARM 架构的 macOS、Linux 系统中完成测试。
|
本项目已在 Python 3.8 - 3.10,CUDA 11.7 环境下完成测试。已在 Windows、ARM 架构的 macOS、Linux 系统中完成测试。
|
||||||
|
|
||||||
vue前端需要node18环境
|
vue前端需要node18环境
|
||||||
|
|
||||||
### 从本地加载模型
|
### 从本地加载模型
|
||||||
|
|
||||||
请参考 [THUDM/ChatGLM-6B#从本地加载模型](https://github.com/THUDM/ChatGLM-6B#从本地加载模型)
|
请参考 [THUDM/ChatGLM-6B#从本地加载模型](https://github.com/THUDM/ChatGLM-6B#从本地加载模型)
|
||||||
|
|
@ -177,6 +178,7 @@ Web UI 可以实现如下功能:
|
||||||
|
|
||||||
- [ ] Langchain 应用
|
- [ ] Langchain 应用
|
||||||
- [x] 接入非结构化文档(已支持 md、pdf、docx、txt 文件格式)
|
- [x] 接入非结构化文档(已支持 md、pdf、docx、txt 文件格式)
|
||||||
|
- [x] jpg 与 png 格式图片的 OCR 文字识别
|
||||||
- [ ] 搜索引擎与本地网页接入
|
- [ ] 搜索引擎与本地网页接入
|
||||||
- [ ] 结构化数据接入(如 csv、Excel、SQL 等)
|
- [ ] 结构化数据接入(如 csv、Excel、SQL 等)
|
||||||
- [ ] 知识图谱/图数据库接入
|
- [ ] 知识图谱/图数据库接入
|
||||||
|
|
@ -200,6 +202,7 @@ Web UI 可以实现如下功能:
|
||||||
- [ ] 增加知识库管理
|
- [ ] 增加知识库管理
|
||||||
- [x] 选择知识库开始问答
|
- [x] 选择知识库开始问答
|
||||||
- [x] 上传文件/文件夹至知识库
|
- [x] 上传文件/文件夹至知识库
|
||||||
|
- [x] 知识库测试
|
||||||
- [ ] 删除知识库中文件
|
- [ ] 删除知识库中文件
|
||||||
- [ ] 利用 streamlit 实现 Web UI Demo
|
- [ ] 利用 streamlit 实现 Web UI Demo
|
||||||
- [ ] 增加 API 支持
|
- [ ] 增加 API 支持
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ import numpy as np
|
||||||
from utils import torch_gc
|
from utils import torch_gc
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
from pypinyin import lazy_pinyin
|
from pypinyin import lazy_pinyin
|
||||||
|
from loader import UnstructuredPaddleImageLoader
|
||||||
|
from loader import UnstructuredPaddlePDFLoader
|
||||||
|
|
||||||
DEVICE_ = EMBEDDING_DEVICE
|
DEVICE_ = EMBEDDING_DEVICE
|
||||||
DEVICE_ID = "0" if torch.cuda.is_available() else None
|
DEVICE_ID = "0" if torch.cuda.is_available() else None
|
||||||
|
|
@ -21,16 +23,31 @@ def load_file(filepath, sentence_size=SENTENCE_SIZE):
|
||||||
loader = UnstructuredFileLoader(filepath, mode="elements")
|
loader = UnstructuredFileLoader(filepath, mode="elements")
|
||||||
docs = loader.load()
|
docs = loader.load()
|
||||||
elif filepath.lower().endswith(".pdf"):
|
elif filepath.lower().endswith(".pdf"):
|
||||||
loader = UnstructuredFileLoader(filepath, strategy="fast")
|
loader = UnstructuredPaddlePDFLoader(filepath)
|
||||||
textsplitter = ChineseTextSplitter(pdf=True, sentence_size=sentence_size)
|
textsplitter = ChineseTextSplitter(pdf=True, sentence_size=sentence_size)
|
||||||
docs = loader.load_and_split(textsplitter)
|
docs = loader.load_and_split(textsplitter)
|
||||||
|
elif filepath.lower().endswith(".jpg") or filepath.lower().endswith(".png"):
|
||||||
|
loader = UnstructuredPaddleImageLoader(filepath, mode="elements")
|
||||||
|
textsplitter = ChineseTextSplitter(pdf=False, sentence_size=sentence_size)
|
||||||
|
docs = loader.load_and_split(text_splitter=textsplitter)
|
||||||
else:
|
else:
|
||||||
loader = UnstructuredFileLoader(filepath, mode="elements")
|
loader = UnstructuredFileLoader(filepath, mode="elements")
|
||||||
textsplitter = ChineseTextSplitter(pdf=False, sentence_size=sentence_size)
|
textsplitter = ChineseTextSplitter(pdf=False, sentence_size=sentence_size)
|
||||||
docs = loader.load_and_split(text_splitter=textsplitter)
|
docs = loader.load_and_split(text_splitter=textsplitter)
|
||||||
|
write_check_file(filepath, docs)
|
||||||
return docs
|
return docs
|
||||||
|
|
||||||
|
|
||||||
|
def write_check_file(filepath, docs):
|
||||||
|
fout = open('load_file.txt', 'a')
|
||||||
|
fout.write("filepath=%s,len=%s" % (filepath, len(docs)))
|
||||||
|
fout.write('\n')
|
||||||
|
for i in docs:
|
||||||
|
fout.write(str(i))
|
||||||
|
fout.write('\n')
|
||||||
|
fout.close()
|
||||||
|
|
||||||
|
|
||||||
def generate_prompt(related_docs: List[str], query: str,
|
def generate_prompt(related_docs: List[str], query: str,
|
||||||
prompt_template=PROMPT_TEMPLATE) -> str:
|
prompt_template=PROMPT_TEMPLATE) -> str:
|
||||||
context = "\n".join([doc.page_content for doc in related_docs])
|
context = "\n".join([doc.page_content for doc in related_docs])
|
||||||
|
|
@ -212,7 +229,7 @@ class LocalDocQA:
|
||||||
if not vs_path or not one_title or not one_conent:
|
if not vs_path or not one_title or not one_conent:
|
||||||
logger.info("知识库添加错误,请确认知识库名字、标题、内容是否正确!")
|
logger.info("知识库添加错误,请确认知识库名字、标题、内容是否正确!")
|
||||||
return None, [one_title]
|
return None, [one_title]
|
||||||
docs = [Document(page_content=one_conent+"\n", metadata={"source": one_title})]
|
docs = [Document(page_content=one_conent + "\n", metadata={"source": one_title})]
|
||||||
if not one_content_segmentation:
|
if not one_content_segmentation:
|
||||||
text_splitter = ChineseTextSplitter(pdf=False, sentence_size=sentence_size)
|
text_splitter = ChineseTextSplitter(pdf=False, sentence_size=sentence_size)
|
||||||
docs = text_splitter.split_documents(docs)
|
docs = text_splitter.split_documents(docs)
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,10 @@
|
||||||
## 硬件需求
|
## 硬件需求
|
||||||
|
|
||||||
- ChatGLM-6B 模型硬件需求
|
- ChatGLM-6B 模型硬件需求
|
||||||
|
|
||||||
|
注:如未将模型下载至本地,请执行前检查`$HOME/.cache/huggingface/`文件夹剩余空间,模型文件下载至本地需要 15 GB 存储空间。
|
||||||
|
|
||||||
|
模型下载方法可参考 [常见问题](docs/FAQ.md) 中 Q8。
|
||||||
|
|
||||||
| **量化等级** | **最低 GPU 显存**(推理) | **最低 GPU 显存**(高效参数微调) |
|
| **量化等级** | **最低 GPU 显存**(推理) | **最低 GPU 显存**(高效参数微调) |
|
||||||
| -------------- | ------------------------- | --------------------------------- |
|
| -------------- | ------------------------- | --------------------------------- |
|
||||||
|
|
@ -38,6 +42,17 @@
|
||||||
| INT8 | 8 GB | 9 GB |
|
| INT8 | 8 GB | 9 GB |
|
||||||
| INT4 | 6 GB | 7 GB |
|
| INT4 | 6 GB | 7 GB |
|
||||||
|
|
||||||
|
- MOSS 模型硬件需求
|
||||||
|
|
||||||
|
注:如未将模型下载至本地,请执行前检查`$HOME/.cache/huggingface/`文件夹剩余空间,模型文件下载至本地需要 70 GB 存储空间
|
||||||
|
|
||||||
|
模型下载方法可参考 [常见问题](docs/FAQ.md) 中 Q8。
|
||||||
|
|
||||||
|
| **量化等级** | **最低 GPU 显存**(推理) | **最低 GPU 显存**(高效参数微调) |
|
||||||
|
|-------------------|-----------------------| --------------------------------- |
|
||||||
|
| FP16(无量化) | 68 GB | - |
|
||||||
|
| INT8 | 20 GB | - |
|
||||||
|
|
||||||
- Embedding 模型硬件需求
|
- Embedding 模型硬件需求
|
||||||
|
|
||||||
本项目中默认选用的 Embedding 模型 [GanymedeNil/text2vec-large-chinese](https://huggingface.co/GanymedeNil/text2vec-large-chinese/tree/main) 约占用显存 3GB,也可修改为在 CPU 中运行。
|
本项目中默认选用的 Embedding 模型 [GanymedeNil/text2vec-large-chinese](https://huggingface.co/GanymedeNil/text2vec-large-chinese/tree/main) 约占用显存 3GB,也可修改为在 CPU 中运行。
|
||||||
|
|
@ -66,6 +81,7 @@ docker run --gpus all -d --name chatglm -p 7860:7860 -v ~/github/langchain-ChatG
|
||||||
|
|
||||||
本项目已在 Python 3.8 - 3.10,CUDA 11.7 环境下完成测试。已在 Windows、ARM 架构的 macOS、Linux 系统中完成测试。
|
本项目已在 Python 3.8 - 3.10,CUDA 11.7 环境下完成测试。已在 Windows、ARM 架构的 macOS、Linux 系统中完成测试。
|
||||||
|
|
||||||
|
vue前端需要node18环境
|
||||||
### 从本地加载模型
|
### 从本地加载模型
|
||||||
|
|
||||||
请参考 [THUDM/ChatGLM-6B#从本地加载模型](https://github.com/THUDM/ChatGLM-6B#从本地加载模型)
|
请参考 [THUDM/ChatGLM-6B#从本地加载模型](https://github.com/THUDM/ChatGLM-6B#从本地加载模型)
|
||||||
|
|
@ -97,19 +113,31 @@ $ python webui.py
|
||||||
```shell
|
```shell
|
||||||
$ python api.py
|
$ python api.py
|
||||||
```
|
```
|
||||||
|
或成功部署 API 后,执行以下脚本体验基于 VUE 的前端页面
|
||||||
|
```shell
|
||||||
|
$ cd views
|
||||||
|
|
||||||
|
$ pnpm i
|
||||||
|
|
||||||
注:如未将模型下载至本地,请执行前检查`$HOME/.cache/huggingface/`文件夹剩余空间,至少15G。
|
$ npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
执行后效果如下图所示:
|
执行后效果如下图所示:
|
||||||

|
1. `对话` Tab 界面
|
||||||
|

|
||||||
|
2. `知识库测试 Beta` Tab 界面
|
||||||
|

|
||||||
|
3. `模型配置` Tab 界面
|
||||||
|

|
||||||
|
|
||||||
Web UI 可以实现如下功能:
|
Web UI 可以实现如下功能:
|
||||||
|
|
||||||
1. 运行前自动读取`configs/model_config.py`中`LLM`及`Embedding`模型枚举及默认模型设置运行模型,如需重新加载模型,可在 `模型配置` 标签页重新选择后点击 `重新加载模型` 进行模型加载;
|
1. 运行前自动读取`configs/model_config.py`中`LLM`及`Embedding`模型枚举及默认模型设置运行模型,如需重新加载模型,可在 `模型配置` Tab 重新选择后点击 `重新加载模型` 进行模型加载;
|
||||||
2. 可手动调节保留对话历史长度、匹配知识库文段数量,可根据显存大小自行调节;
|
2. 可手动调节保留对话历史长度、匹配知识库文段数量,可根据显存大小自行调节;
|
||||||
3. 具备模式选择功能,可选择 `LLM对话` 与 `知识库问答` 模式进行对话,支持流式对话;
|
3. `对话` Tab 具备模式选择功能,可选择 `LLM对话` 与 `知识库问答` 模式进行对话,支持流式对话;
|
||||||
4. 添加 `配置知识库` 功能,支持选择已有知识库或新建知识库,并可向知识库中**新增**上传文件/文件夹,使用文件上传组件选择好文件后点击 `上传文件并加载知识库`,会将所选上传文档数据加载至知识库中,并基于更新后知识库进行问答;
|
4. 添加 `配置知识库` 功能,支持选择已有知识库或新建知识库,并可向知识库中**新增**上传文件/文件夹,使用文件上传组件选择好文件后点击 `上传文件并加载知识库`,会将所选上传文档数据加载至知识库中,并基于更新后知识库进行问答;
|
||||||
5. 后续版本中将会增加对知识库的修改或删除,及知识库中已导入文件的查看。
|
5. 新增 `知识库测试 Beta` Tab,可用于测试不同文本切分方法与检索相关度阈值设置,暂不支持将测试参数作为 `对话` Tab 设置参数。
|
||||||
|
6. 后续版本中将会增加对知识库的修改或删除,及知识库中已导入文件的查看。
|
||||||
|
|
||||||
### 常见问题
|
### 常见问题
|
||||||
|
|
||||||
|
|
@ -159,6 +187,7 @@ Web UI 可以实现如下功能:
|
||||||
- [x] [THUDM/chatglm-6b-int4](https://huggingface.co/THUDM/chatglm-6b-int4)
|
- [x] [THUDM/chatglm-6b-int4](https://huggingface.co/THUDM/chatglm-6b-int4)
|
||||||
- [x] [THUDM/chatglm-6b-int4-qe](https://huggingface.co/THUDM/chatglm-6b-int4-qe)
|
- [x] [THUDM/chatglm-6b-int4-qe](https://huggingface.co/THUDM/chatglm-6b-int4-qe)
|
||||||
- [x] [ClueAI/ChatYuan-large-v2](https://huggingface.co/ClueAI/ChatYuan-large-v2)
|
- [x] [ClueAI/ChatYuan-large-v2](https://huggingface.co/ClueAI/ChatYuan-large-v2)
|
||||||
|
- [x] [fnlp/moss-moon-003-sft](https://huggingface.co/fnlp/moss-moon-003-sft)
|
||||||
- [ ] 增加更多 Embedding 模型支持
|
- [ ] 增加更多 Embedding 模型支持
|
||||||
- [x] [nghuyong/ernie-3.0-nano-zh](https://huggingface.co/nghuyong/ernie-3.0-nano-zh)
|
- [x] [nghuyong/ernie-3.0-nano-zh](https://huggingface.co/nghuyong/ernie-3.0-nano-zh)
|
||||||
- [x] [nghuyong/ernie-3.0-base-zh](https://huggingface.co/nghuyong/ernie-3.0-base-zh)
|
- [x] [nghuyong/ernie-3.0-base-zh](https://huggingface.co/nghuyong/ernie-3.0-base-zh)
|
||||||
|
|
@ -178,6 +207,6 @@ Web UI 可以实现如下功能:
|
||||||
- [ ] 实现调用 API 的 Web UI Demo
|
- [ ] 实现调用 API 的 Web UI Demo
|
||||||
|
|
||||||
## 项目交流群
|
## 项目交流群
|
||||||

|

|
||||||
|
|
||||||
🎉 langchain-ChatGLM 项目交流群,如果你也对本项目感兴趣,欢迎加入群聊参与讨论交流。
|
🎉 langchain-ChatGLM 项目交流群,如果你也对本项目感兴趣,欢迎加入群聊参与讨论交流。
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 7.9 KiB |
Binary file not shown.
|
|
@ -29,7 +29,14 @@ $ git clone https://github.com/imClumsyPanda/langchain-ChatGLM.git
|
||||||
# 进入目录
|
# 进入目录
|
||||||
$ cd langchain-ChatGLM
|
$ cd langchain-ChatGLM
|
||||||
|
|
||||||
|
# 项目中 pdf 加载由先前的 detectron2 替换为使用 paddleocr,如果之前有安装过 detectron2 需要先完成卸载避免引发 tools 冲突
|
||||||
|
$ pip uninstall detectron2
|
||||||
|
|
||||||
# 安装依赖
|
# 安装依赖
|
||||||
$ pip install -r requirements.txt
|
$ pip install -r requirements.txt
|
||||||
|
|
||||||
|
# 验证paddleocr是否成功,首次运行会下载约18M模型到~/.paddleocr
|
||||||
|
$ python loader/image_loader.py
|
||||||
|
|
||||||
```
|
```
|
||||||
注:使用 `langchain.document_loaders.UnstructuredFileLoader` 进行非结构化文件接入时,可能需要依据文档进行其他依赖包的安装,请参考 [langchain 文档](https://python.langchain.com/en/latest/modules/indexes/document_loaders/examples/unstructured_file.html)。
|
注:使用 `langchain.document_loaders.UnstructuredFileLoader` 进行非结构化文件接入时,可能需要依据文档进行其他依赖包的安装,请参考 [langchain 文档](https://python.langchain.com/en/latest/modules/indexes/document_loaders/examples/unstructured_file.html)。
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 7.9 KiB |
|
|
@ -0,0 +1,2 @@
|
||||||
|
from .image_loader import UnstructuredPaddleImageLoader
|
||||||
|
from .pdf_loader import UnstructuredPaddlePDFLoader
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
"""Loader that loads image files."""
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
from langchain.document_loaders.unstructured import UnstructuredFileLoader
|
||||||
|
from paddleocr import PaddleOCR
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
class UnstructuredPaddleImageLoader(UnstructuredFileLoader):
|
||||||
|
"""Loader that uses unstructured to load image files, such as PNGs and JPGs."""
|
||||||
|
|
||||||
|
def _get_elements(self) -> List:
|
||||||
|
def image_ocr_txt(filepath, dir_path="tmp_files"):
|
||||||
|
full_dir_path = os.path.join(os.path.dirname(filepath), dir_path)
|
||||||
|
if not os.path.exists(full_dir_path):
|
||||||
|
os.makedirs(full_dir_path)
|
||||||
|
filename = os.path.split(filepath)[-1]
|
||||||
|
ocr = PaddleOCR(lang="ch", use_gpu=False, show_log=False)
|
||||||
|
result = ocr.ocr(img=filepath)
|
||||||
|
|
||||||
|
ocr_result = [i[1][0] for line in result for i in line]
|
||||||
|
txt_file_path = os.path.join(full_dir_path, "%s.txt" % (filename))
|
||||||
|
with open(txt_file_path, 'w', encoding='utf-8') as fout:
|
||||||
|
fout.write("\n".join(ocr_result))
|
||||||
|
return txt_file_path
|
||||||
|
|
||||||
|
txt_file_path = image_ocr_txt(self.file_path)
|
||||||
|
from unstructured.partition.text import partition_text
|
||||||
|
return partition_text(filename=txt_file_path, **self.unstructured_kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
filepath = "../content/samples/test.jpg"
|
||||||
|
loader = UnstructuredPaddleImageLoader(filepath, mode="elements")
|
||||||
|
docs = loader.load()
|
||||||
|
for doc in docs:
|
||||||
|
print(doc)
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
"""Loader that loads image files."""
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
from langchain.document_loaders.unstructured import UnstructuredFileLoader
|
||||||
|
from paddleocr import PaddleOCR
|
||||||
|
import os
|
||||||
|
import fitz
|
||||||
|
|
||||||
|
|
||||||
|
class UnstructuredPaddlePDFLoader(UnstructuredFileLoader):
|
||||||
|
"""Loader that uses unstructured to load image files, such as PNGs and JPGs."""
|
||||||
|
|
||||||
|
def _get_elements(self) -> List:
|
||||||
|
def pdf_ocr_txt(filepath, dir_path="tmp_files"):
|
||||||
|
full_dir_path = os.path.join(os.path.dirname(filepath), dir_path)
|
||||||
|
if not os.path.exists(full_dir_path):
|
||||||
|
os.makedirs(full_dir_path)
|
||||||
|
filename = os.path.split(filepath)[-1]
|
||||||
|
ocr = PaddleOCR(lang="ch", use_gpu=False, show_log=False)
|
||||||
|
doc = fitz.open(filepath)
|
||||||
|
txt_file_path = os.path.join(full_dir_path, "%s.txt" % (filename))
|
||||||
|
img_name = os.path.join(full_dir_path, '.tmp.png')
|
||||||
|
with open(txt_file_path, 'w', encoding='utf-8') as fout:
|
||||||
|
|
||||||
|
for i in range(doc.page_count):
|
||||||
|
page = doc[i]
|
||||||
|
text = page.get_text("")
|
||||||
|
fout.write(text)
|
||||||
|
fout.write("\n")
|
||||||
|
|
||||||
|
img_list = page.get_images()
|
||||||
|
for img in img_list:
|
||||||
|
pix = fitz.Pixmap(doc, img[0])
|
||||||
|
|
||||||
|
pix.save(img_name)
|
||||||
|
|
||||||
|
result = ocr.ocr(img_name)
|
||||||
|
ocr_result = [i[1][0] for line in result for i in line]
|
||||||
|
fout.write("\n".join(ocr_result))
|
||||||
|
os.remove(img_name)
|
||||||
|
return txt_file_path
|
||||||
|
|
||||||
|
txt_file_path = pdf_ocr_txt(self.file_path)
|
||||||
|
from unstructured.partition.text import partition_text
|
||||||
|
return partition_text(filename=txt_file_path, **self.unstructured_kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
filepath = "../content/samples/test.pdf"
|
||||||
|
loader = UnstructuredPaddlePDFLoader(filepath, mode="elements")
|
||||||
|
docs = loader.load()
|
||||||
|
for doc in docs:
|
||||||
|
print(doc)
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
pymupdf
|
||||||
|
paddlepaddle==2.4.2
|
||||||
|
paddleocr
|
||||||
langchain==0.0.146
|
langchain==0.0.146
|
||||||
transformers==4.27.1
|
transformers==4.27.1
|
||||||
unstructured[local-inference]
|
unstructured[local-inference]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
from configs.model_config import *
|
||||||
|
import nltk
|
||||||
|
|
||||||
|
nltk.data.path = [NLTK_DATA_PATH] + nltk.data.path
|
||||||
|
|
||||||
|
filepath = "./img/test.jpg"
|
||||||
|
from loader import UnstructuredPaddleImageLoader
|
||||||
|
|
||||||
|
loader = UnstructuredPaddleImageLoader(filepath, mode="elements")
|
||||||
|
docs = loader.load()
|
||||||
|
for doc in docs:
|
||||||
|
print(doc)
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
from configs.model_config import *
|
||||||
|
import nltk
|
||||||
|
|
||||||
|
nltk.data.path = [NLTK_DATA_PATH] + nltk.data.path
|
||||||
|
|
||||||
|
filepath = "docs/test.pdf"
|
||||||
|
from loader import UnstructuredPaddlePDFLoader
|
||||||
|
|
||||||
|
loader = UnstructuredPaddlePDFLoader(filepath, mode="elements")
|
||||||
|
docs = loader.load()
|
||||||
|
for doc in docs:
|
||||||
|
print(doc)
|
||||||
Loading…
Reference in New Issue