Skip to content

Commit 445ad52

Browse files
authored
Add Windows system support of pipelines (#2903)
* Add Windows system support of pipelines * Fix the utf-8 on windows messy code * Support delete index and update indexing data of pipelines * Add numba dependency
1 parent 1c498bc commit 445ad52

File tree

8 files changed

+277
-6
lines changed

8 files changed

+277
-6
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# WINDOWS环境下搭建端到端智能问答系统
2+
3+
以下的流程都是使用的Anaconda的环境进行的搭建,Anaconda安装好以后,进入 `Anaconda Powershell Prompt`,然后执行下面的流程。
4+
5+
## 1. 快速开始: 城市百科知识问答系统搭建
6+
7+
### 1.1 运行环境和安装说明
8+
9+
a. 依赖安装:
10+
```bash
11+
pip install -r requirements.txt
12+
# 1) 安装 pipelines package
13+
cd ${HOME}/PaddleNLP/applications/experimental/pipelines/
14+
python setup.py install
15+
```
16+
### 1.2 数据说明
17+
问答知识库数据是我们爬取了百度百科上对国内重点城市的百科介绍文档。我们将所有文档中的非结构化文本数据抽取出来, 按照段落切分后作为问答系统知识库的数据,一共包含 365 个城市的百科介绍文档、切分后共 1318 个段落。
18+
19+
### 1.3 一键体验问答系统
20+
我们预置了搭建城市百科知识问答系统的代码示例,您可以通过如下命令快速体验问答系统的效果。
21+
22+
23+
```bash
24+
# 我们建议在 GPU 环境下运行本示例,运行速度较快
25+
# 设置 1 个空闲的 GPU 卡,此处假设 0 卡为空闲 GPU
26+
export CUDA_VISIBLE_DEVICES=0
27+
python examples/question-answering/dense_qa_example.py --device gpu
28+
# 如果只有 CPU 机器,可以通过 --device 参数指定 cpu 即可, 运行耗时较长
29+
unset CUDA_VISIBLE_DEVICES
30+
python examples/question-answering/dense_qa_example.py --device cpu
31+
```
32+
33+
### 1.4 构建 Web 可视化问答系统
34+
35+
整个 Web 可视化问答系统主要包含 3 大组件: 1. 基于 ElasticSearch 的 ANN 服务 2. 基于 RestAPI 构建模型服务 3. 基于 Streamlit 构建 WebUI。接下来我们依次搭建这 3 个服务并串联构成可视化的问答系统
36+
37+
#### 1.4.1 启动 ANN 服务
38+
1. 参考官方文档下载安装 [elasticsearch-8.3.2](https://www.elastic.co/cn/downloads/elasticsearch) 并解压。
39+
2. 启动 ES 服务
40+
`xpack.security.enabled` 设置成false,如下:
41+
```
42+
xpack.security.enabled: false
43+
```
44+
45+
然后直接双击bin目录下的elasticsearch.bat即可启动。
46+
47+
3. elasticsearch可视化工具Kibana(可选)
48+
为了更好的对数据进行管理,可以使用Kibana可视化工具进行管理和分析,下载链接为[Kibana](https://www.elastic.co/cn/downloads/kibana),下载完后解压,直接双击运行 `bin\kibana.bat`即可。
49+
50+
#### 1.4.2 文档数据写入 ANN 索引库
51+
```
52+
# 以百科城市数据为例建立 ANN 索引库
53+
python utils/offline_ann.py --index_name baike_cities --doc_dir data/baike
54+
```
55+
56+
参数含义说明
57+
* `index_name`: 索引的名称
58+
* `doc_dir`: txt文本数据的路径
59+
* `delete_index`: 是否删除现有的索引和数据,用于清空es的数据,默认为false
60+
61+
运行成功后会输出如下的日志:
62+
```
63+
INFO - pipelines.utils.logger - Logged parameters:
64+
{'processor': 'TextSimilarityProcessor', 'tokenizer': 'NoneType', 'max_seq_len': '0', 'dev_split': '0.1'}
65+
INFO - pipelines.document_stores.elasticsearch - Updating embeddings for all 1318 docs ...
66+
Updating embeddings: 10000 Docs [00:16, 617.76 Docs/s]
67+
```
68+
运行结束后,可使用Kibana查看数据
69+
70+
#### 1.4.3 启动 RestAPI 模型服务
71+
```bash
72+
# 指定智能问答系统的Yaml配置文件
73+
$env:PIPELINE_YAML_PATH='rest_api/pipeline/dense_qa.yaml'
74+
# 使用端口号 8891 启动模型服务
75+
python rest_api/application.py 8891
76+
```
77+
78+
#### 1.4.4 启动 WebUI
79+
```bash
80+
# 配置模型服务地址
81+
$env:API_ENDPOINT='http://127.0.0.1:8891'
82+
# 在指定端口 8502 启动 WebUI
83+
python -m streamlit run ui/webapp_question_answering.py --server.port 8502
84+
```
85+
86+
到这里您就可以打开浏览器访问 http://127.0.0.1:8502 地址体验城市百科知识问答系统服务了。
87+
88+
#### 1.4.5 数据更新
89+
90+
数据更新的方法有两种,第一种使用前面的 `utils/offline_ann.py`进行数据更新,另一种是使用前端界面的文件上传进行数据更新,支持txt,pdf,image,word的格式,以txt格式的文件为例,每段文本需要使用空行隔开,程序会根据空行进行分段建立索引,示例数据如下(demo.txt):
91+
92+
```
93+
兴证策略认为,最恐慌的时候已经过去,未来一个月市场迎来阶段性修复窗口。
94+
95+
从海外市场表现看,
96+
对俄乌冲突的恐慌情绪已显著释放,
97+
海外权益市场也从单边下跌转入双向波动。
98+
99+
长期,继续聚焦科技创新的五大方向。1)新能源(新能源汽车、光伏、风电、特高压等),2)新一代信息通信技术(人工智能、大数据、云计算、5G等),3)高端制造(智能数控机床、机器人、先进轨交装备等),4)生物医药(创新药、CXO、医疗器械和诊断设备等),5)军工(导弹设备、军工电子元器件、空间站、航天飞机等)。
100+
```
101+
102+
## FAQ
103+
104+
#### pip安装htbuilder包报错,`UnicodeDecodeError: 'gbk' codec can't decode byte....`
105+
106+
windows的默认字符gbk导致的,可以使用源码进行安装,源码已经进行了修复。
107+
108+
```
109+
git clone https://github.com/tvst/htbuilder.git
110+
cd htbuilder/
111+
python setup install
112+
```

applications/experimental/pipelines/examples/question-answering/README.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
## 3. 快速开始: 城市百科知识问答系统搭建
2727

28+
以下是针对mac和linux的安装流程,windows的安装和使用流程请参考[windows](./Install_windows.md)
29+
2830
### 3.1 运行环境和安装说明
2931

3032
本实验采用了以下的运行环境进行,详细说明如下,用户也可以在自己 GPU 硬件环境进行:
@@ -90,8 +92,15 @@ curl http://localhost:9200/_aliases?pretty=true
9092
```
9193
# 以百科城市数据为例建立 ANN 索引库
9294
python utils/offline_ann.py --index_name baike_cities \
93-
--doc_dir data/baike
95+
--doc_dir data/baike \
96+
--delete_index
9497
```
98+
99+
参数含义说明
100+
* `index_name`: 索引的名称
101+
* `doc_dir`: txt文本数据的路径
102+
* `delete_index`: 是否删除现有的索引和数据,用于清空es的数据,默认为false
103+
95104
运行成功后会输出如下的日志:
96105
```
97106
INFO - pipelines.utils.logger - Logged parameters:
@@ -142,6 +151,20 @@ sh scripts/run_qa_web.sh
142151

143152
到这里您就可以打开浏览器访问 http://127.0.0.1:8502 地址体验城市百科知识问答系统服务了。
144153

154+
#### 3.4.5 数据更新
155+
156+
数据更新的方法有两种,第一种使用前面的 `utils/offline_ann.py`进行数据更新,另一种是使用前端界面的文件上传进行数据更新,支持txt,pdf,image,word的格式,以txt格式的文件为例,每段文本需要使用空行隔开,程序会根据空行进行分段建立索引,示例数据如下(demo.txt):
157+
158+
```
159+
兴证策略认为,最恐慌的时候已经过去,未来一个月市场迎来阶段性修复窗口。
160+
161+
从海外市场表现看,
162+
对俄乌冲突的恐慌情绪已显著释放,
163+
海外权益市场也从单边下跌转入双向波动。
164+
165+
长期,继续聚焦科技创新的五大方向。1)新能源(新能源汽车、光伏、风电、特高压等),2)新一代信息通信技术(人工智能、大数据、云计算、5G等),3)高端制造(智能数控机床、机器人、先进轨交装备等),4)生物医药(创新药、CXO、医疗器械和诊断设备等),5)军工(导弹设备、军工电子元器件、空间站、航天飞机等)。
166+
```
167+
145168
## Reference
146169
[1]Y. Sun et al., “[ERNIE 3.0: Large-scale Knowledge Enhanced Pre-training for Language Understanding and Generation](https://arxiv.org/pdf/2107.02137.pdf),” arXiv:2107.02137 [cs], Jul. 2021, Accessed: Jan. 17, 2022. [Online]. Available: http://arxiv.org/abs/2107.02137
147170

applications/experimental/pipelines/examples/question-answering/dense_qa_example.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ def dense_qa_pipeline():
4141
doc_dir = "data/baike"
4242
city_data = "https://paddlenlp.bj.bcebos.com/applications/baike.zip"
4343
fetch_archive_from_http(url=city_data, output_dir=doc_dir)
44-
dicts = convert_files_to_dicts(dir_path=doc_dir, split_paragraphs=True)
44+
dicts = convert_files_to_dicts(dir_path=doc_dir,
45+
split_paragraphs=True,
46+
encoding='utf-8')
4547

4648
if os.path.exists(args.index_name):
4749
os.remove(args.index_name)
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# WINDOWS环境下搭建端到端语义检索系统
2+
以下的流程都是使用的Anaconda的环境进行的搭建,Anaconda安装好以后,进入 `Anaconda Powershell Prompt`,然后执行下面的流程。
3+
4+
## 1. 快速开始: 快速搭建语义检索系统
5+
6+
### 1.1 运行环境和安装说明
7+
8+
a. 依赖安装:
9+
```bash
10+
pip install -r requirements.txt
11+
# 1) 安装 pipelines package
12+
cd ${HOME}/PaddleNLP/applications/experimental/pipelines/
13+
python setup.py install
14+
```
15+
### 1.2 数据说明
16+
语义检索数据库的数据来自于[DuReader-Robust数据集](https://github.com/baidu/DuReader/tree/master/DuReader-Robust),共包含 46972 个段落文本。
17+
18+
### 1.3 一键体验语义检索系统
19+
我们预置了基于[DuReader-Robust数据集](https://github.com/baidu/DuReader/tree/master/DuReader-Robust)搭建语义检索系统的代码示例,您可以通过如下命令快速体验语义检索系统的效果
20+
```bash
21+
# 我们建议在 GPU 环境下运行本示例,运行速度较快
22+
# 设置 1 个空闲的 GPU 卡,此处假设 0 卡为空闲 GPU
23+
export CUDA_VISIBLE_DEVICES=0
24+
python examples/semantic-search/semantic_search_example.py --device gpu
25+
# 如果只有 CPU 机器,可以通过 --device 参数指定 cpu 即可, 运行耗时较长
26+
unset CUDA_VISIBLE_DEVICES
27+
python examples/semantic-search/semantic_search_example.py --device cpu
28+
```
29+
30+
### 1.4 构建 Web 可视化语义检索系统
31+
32+
整个 Web 可视化语义检索系统主要包含 3 大组件: 1. 基于 ElasticSearch 的 ANN 服务 2. 基于 RestAPI 构建模型服务 3. 基于 Streamlit 构建 WebUI,接下来我们依次搭建这 3 个服务并最终形成可视化的语义检索系统。
33+
34+
#### 1.4.1 启动 ANN 服务
35+
1. 参考官方文档下载安装 [elasticsearch-8.3.2](https://www.elastic.co/cn/downloads/elasticsearch) 并解压。
36+
2. 启动 ES 服务
37+
`xpack.security.enabled` 设置成false,如下:
38+
```
39+
xpack.security.enabled: false
40+
```
41+
42+
然后直接双击bin目录下的elasticsearch.bat即可启动。
43+
44+
3. elasticsearch可视化工具Kibana(可选)
45+
为了更好的对数据进行管理,可以使用Kibana可视化工具进行管理和分析,下载链接为[Kibana](https://www.elastic.co/cn/downloads/kibana),下载完后解压,直接双击运行 `bin\kibana.bat`即可。
46+
47+
#### 1.4.2 文档数据写入 ANN 索引库
48+
```
49+
# 以DuReader-Robust 数据集为例建立 ANN 索引库
50+
python utils/offline_ann.py --index_name dureader_robust_query_encoder --doc_dir data/dureader_robust_processed
51+
```
52+
53+
参数含义说明
54+
* `index_name`: 索引的名称
55+
* `doc_dir`: txt文本数据的路径
56+
* `delete_index`: 是否删除现有的索引和数据,用于清空es的数据,默认为false
57+
58+
59+
运行结束后,可使用Kibana查看数据
60+
61+
#### 1.4.3 启动 RestAPI 模型服务
62+
```bash
63+
# 指定语义检索系统的Yaml配置文件
64+
$env:PIPELINE_YAML_PATH='rest_api/pipeline/semantic_search.yaml'
65+
# 使用端口号 8891 启动模型服务
66+
python rest_api/application.py 8891
67+
```
68+
69+
#### 1.4.4 启动 WebUI
70+
```bash
71+
# 配置模型服务地址
72+
$env:API_ENDPOINT='http://127.0.0.1:8891'
73+
# 在指定端口 8502 启动 WebUI
74+
python -m streamlit run ui/webapp_semantic_search.py --server.port 8502
75+
```
76+
77+
到这里您就可以打开浏览器访问 http://127.0.0.1:8502 地址体验语义检索系统服务了。
78+
79+
#### 1.4.5 数据更新
80+
81+
数据更新的方法有两种,第一种使用前面的 `utils/offline_ann.py`进行数据更新,另一种是使用前端界面的文件上传进行数据更新,支持txt,pdf,image,word的格式,以txt格式的文件为例,每段文本需要使用空行隔开,程序会根据空行进行分段建立索引,示例数据如下(demo.txt):
82+
83+
```
84+
兴证策略认为,最恐慌的时候已经过去,未来一个月市场迎来阶段性修复窗口。
85+
86+
从海外市场表现看,
87+
对俄乌冲突的恐慌情绪已显著释放,
88+
海外权益市场也从单边下跌转入双向波动。
89+
90+
长期,继续聚焦科技创新的五大方向。1)新能源(新能源汽车、光伏、风电、特高压等),2)新一代信息通信技术(人工智能、大数据、云计算、5G等),3)高端制造(智能数控机床、机器人、先进轨交装备等),4)生物医药(创新药、CXO、医疗器械和诊断设备等),5)军工(导弹设备、军工电子元器件、空间站、航天飞机等)。
91+
```

applications/experimental/pipelines/examples/semantic-search/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030

3131
## 3. 快速开始: 快速搭建语义检索系统
3232

33+
以下是针对mac和linux的安装流程,windows的安装和使用流程请参考[windows](./Install_windows.md)
34+
3335
### 3.1 运行环境和安装说明
3436

3537
本实验采用了以下的运行环境进行,详细说明如下,用户也可以在自己 GPU 硬件环境进行:
@@ -95,6 +97,12 @@ curl http://localhost:9200/_aliases?pretty=true
9597
python utils/offline_ann.py --index_name dureader_robust_query_encoder \
9698
--doc_dir data/dureader_dev
9799
```
100+
101+
参数含义说明
102+
* `index_name`: 索引的名称
103+
* `doc_dir`: txt文本数据的路径
104+
* `delete_index`: 是否删除现有的索引和数据,用于清空es的数据,默认为false
105+
98106
#### 3.4.3 启动 RestAPI 模型服务
99107
```bash
100108
# 指定语义检索系统的Yaml配置文件
@@ -123,6 +131,20 @@ sh scripts/run_search_web.sh
123131

124132
到这里您就可以打开浏览器访问 http://127.0.0.1:8502 地址体验语义检索系统服务了。
125133

134+
#### 3.4.5 数据更新
135+
136+
数据更新的方法有两种,第一种使用前面的 `utils/offline_ann.py`进行数据更新,另一种是使用前端界面的文件上传进行数据更新,支持txt,pdf,image,word的格式,以txt格式的文件为例,每段文本需要使用空行隔开,程序会根据空行进行分段建立索引,示例数据如下(demo.txt):
137+
138+
```
139+
兴证策略认为,最恐慌的时候已经过去,未来一个月市场迎来阶段性修复窗口。
140+
141+
从海外市场表现看,
142+
对俄乌冲突的恐慌情绪已显著释放,
143+
海外权益市场也从单边下跌转入双向波动。
144+
145+
长期,继续聚焦科技创新的五大方向。1)新能源(新能源汽车、光伏、风电、特高压等),2)新一代信息通信技术(人工智能、大数据、云计算、5G等),3)高端制造(智能数控机床、机器人、先进轨交装备等),4)生物医药(创新药、CXO、医疗器械和诊断设备等),5)军工(导弹设备、军工电子元器件、空间站、航天飞机等)。
146+
```
147+
126148
## FAQ
127149

128150
#### 语义检索系统可以跑通,但终端输出字符是乱码怎么解决?

applications/experimental/pipelines/examples/semantic-search/semantic_search_example.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ def semantic_search_tutorial():
4040
dureader_data = "https://paddlenlp.bj.bcebos.com/applications/dureader_dev.zip"
4141

4242
fetch_archive_from_http(url=dureader_data, output_dir=doc_dir)
43-
dicts = convert_files_to_dicts(dir_path=doc_dir, split_paragraphs=True)
43+
dicts = convert_files_to_dicts(dir_path=doc_dir,
44+
split_paragraphs=True,
45+
encoding='utf-8')
4446

4547
if os.path.exists(args.index_name):
4648
os.remove(args.index_name)

applications/experimental/pipelines/requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ st-annotated-text
2020
streamlit==1.9.0
2121
fastapi
2222
uvicorn
23-
markdown
23+
markdown
24+
numba

applications/experimental/pipelines/utils/offline_ann.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
default='data/baike/',
1616
type=str,
1717
help="The doc path of the corpus")
18+
parser.add_argument(
19+
'--delete_index',
20+
action='store_true',
21+
help='whether to delete existing index while updating index')
1822

1923
args = parser.parse_args()
2024

@@ -28,9 +32,10 @@ def offline_ann(index_name, doc_dir):
2832
username="",
2933
password="",
3034
index=index_name)
31-
3235
# 将每篇文档按照段落进行切分
33-
dicts = convert_files_to_dicts(dir_path=doc_dir, split_paragraphs=True)
36+
dicts = convert_files_to_dicts(dir_path=doc_dir,
37+
split_paragraphs=True,
38+
encoding='utf-8')
3439

3540
print(dicts[:3])
3641

@@ -53,5 +58,18 @@ def offline_ann(index_name, doc_dir):
5358
document_store.update_embeddings(retriever)
5459

5560

61+
def delete_data(index_name):
62+
document_store = ElasticsearchDocumentStore(host="127.0.0.1",
63+
port="9200",
64+
username="",
65+
password="",
66+
index=index_name)
67+
68+
document_store.delete_index(index_name)
69+
print('Delete an existing elasticsearch index {} Done.'.format(index_name))
70+
71+
5672
if __name__ == "__main__":
73+
if (args.delete_index):
74+
delete_data(args.index_name)
5775
offline_ann(args.index_name, args.doc_dir)

0 commit comments

Comments
 (0)