aipib commited on
Commit
75e2ab3
·
verified ·
1 Parent(s): 0557122

Upload 2 files

Browse files
Files changed (2) hide show
  1. app_indigo4GB.py +737 -0
  2. requirements.txt +20 -0
app_indigo4GB.py ADDED
@@ -0,0 +1,737 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os, tempfile
2
+ import re
3
+ import json
4
+ from pathlib import Path
5
+ import streamlit as st
6
+ st.set_page_config(page_title="QA_AIボット+要約")
7
+ st.title("Q&A-AIボット & 資料要約\n Demo running on just 4Core CPU/4GB RAM")
8
+ st.text("【取扱説明書等をアップロードすればその文書に関する質問にAIが回答します。資料の要約もできます。】")
9
+ st.text("""※アップロードされたファイルはサーバーには保存されず、ブラウザを閉じるとバイナリデータも自動的に消去されます。""")
10
+ #import torch
11
+ from typing import Any, List
12
+ from datetime import datetime
13
+
14
+ from llama_index import (
15
+ download_loader,
16
+ VectorStoreIndex,
17
+ ServiceContext,
18
+ StorageContext,
19
+ SimpleDirectoryReader,
20
+ )
21
+ from llama_index.postprocessor import SentenceEmbeddingOptimizer
22
+ from llama_index.prompts.prompts import QuestionAnswerPrompt
23
+ from llama_index.readers import WikipediaReader, Document
24
+
25
+ from langchain_community.chat_models import ChatOllama
26
+ from langchain.embeddings.huggingface import HuggingFaceEmbeddings
27
+ from langchain.callbacks.base import BaseCallbackHandler
28
+ from langchain_community.document_loaders import TextLoader
29
+ from langchain_text_splitters import CharacterTextSplitter
30
+
31
+ from pysummarization.nlpbase.auto_abstractor import AutoAbstractor
32
+ from pysummarization.tokenizabledoc.mecab_tokenizer import MeCabTokenizer
33
+ from pysummarization.abstractabledoc.top_n_rank_abstractor import TopNRankAbstractor
34
+ from pysummarization.abstractabledoc.std_abstractor import StdAbstractor
35
+ from pysummarization.nlp_base import NlpBase
36
+ from pysummarization.similarityfilter.tfidf_cosine import TfIdfCosine
37
+ #from pysummarization.similarityfilter.dice import Dice
38
+
39
+ if "messages" not in st.session_state:
40
+ st.session_state.messages = []
41
+ class StreamHandler(BaseCallbackHandler):
42
+ def __init__(self, initial_text="お調べしますので少々お待ち下さい。\n\n"):
43
+ self.initial_text = initial_text
44
+ self.text = initial_text
45
+ self.flag = True
46
+ def on_llm_start(self, *args: Any, **kwargs: Any):
47
+ self.text = self.initial_text
48
+ with st.chat_message("assistant"):
49
+ self.container = st.empty()
50
+ self.container.markdown(self.text+" "+" ")
51
+ print("LLM start: ",datetime.now())
52
+ def on_llm_new_token(self, token: str, **kwargs: Any) -> None:
53
+ if self.flag == True:
54
+ print("Stream start: ",datetime.now())
55
+ self.flag = False
56
+ self.text += token
57
+ self.container.markdown(self.text)
58
+ def on_llm_end(self, *args: Any, **kwargs: Any) -> None:
59
+ st.session_state.messages.append({
60
+ "role": "assistant",
61
+ "content": self.text
62
+ })
63
+ print("LLM end: ",datetime.now())
64
+
65
+ from rake_ja import JapaneseRake
66
+ from rake_ja.tokenizer import Tokenizer
67
+ tok = Tokenizer()
68
+ ja_rake = JapaneseRake()
69
+
70
+ import chromadb
71
+ from llama_index.vector_stores import ChromaVectorStore
72
+
73
+ import wikipedia
74
+ class JaWikipediaReader(WikipediaReader):
75
+ def load_wiki(self, pages: List[str], **load_kwargs: Any) -> List[Document]:
76
+ """Load data from the input directory.
77
+ Args:
78
+ pages (List[str]): List of pages to read.
79
+ """
80
+ wikipedia.set_lang('ja')
81
+ results = []
82
+ for page in pages:
83
+ page_content = wikipedia.page(page, **load_kwargs).content
84
+ results.append(page_content)
85
+ return results
86
+
87
+ from duckduckgo_search import DDGS
88
+ maxsearch_results = 3
89
+ def search_general(input_text):
90
+ with DDGS() as ddgs:
91
+ results = [r for r in ddgs.text(f"{input_text}", region="jp-jp", timelimit="y", max_results=maxsearch_results, safesearch="off")]
92
+ print(results)
93
+ return results
94
+
95
+ STORAGE_DIR = "./storage/"
96
+ TEMP_DIR = "./temp_data/"
97
+ HISTORY_DIR = "./history/"
98
+ SUMMARY_DIR = "./summary/"
99
+
100
+ os.makedirs(STORAGE_DIR, exist_ok=True)
101
+ os.makedirs(TEMP_DIR, exist_ok=True)
102
+ os.makedirs(HISTORY_DIR, exist_ok=True)
103
+ os.makedirs(SUMMARY_DIR, exist_ok=True)
104
+
105
+
106
+ class PDFReader:
107
+ def __init__(self):
108
+ self.pdf_reader = download_loader("PDFReader", custom_path="local_dir")()
109
+ def load_data(self, file_name):
110
+ return self.pdf_reader.load_data(file=Path(file_name))
111
+
112
+ ollama_url = "http://localhost:11434"
113
+ ollama_remote = "https://ai.pib.co.jp"
114
+ llamacpp_url = "http://localhost:8000/v1"
115
+ LM_Studio_url = "http://localhost:1234/v1"
116
+ class QAResponseGenerator:
117
+ def __init__(self, selected_model, pdf_reader, device=None):
118
+ stream_handler = StreamHandler()
119
+ #self.llm = ChatOllama(base_url=ollama_remote, model=selected_model, streaming=True, callbacks=[stream_handler], verbose=True)
120
+ self.llm = ChatOllama(base_url=ollama_url, model=selected_model, streaming=True, callbacks=[stream_handler], verbose=True)
121
+ self.pdf_reader = pdf_reader
122
+ if selected_model == "llama3":
123
+ self.QA_PROMPT_TMPL = "<|begin_of_text|><|start_header_id|>system<|end_header_id|>\nあなたは日本人のコールセンター管理者です。次の質問に日本語で回答してください。<|eot_id|><|start_header_id|>user<|end_header_id|>\n{query_str}<|eot_id|><start_header_id|>assistant<|end_header_id|><|eot_id|>"
124
+ #self.QA_PROMPT_TMPL = "<|begin_of_text|><|start_header_id|>system<|end_header_id|>あなたは日本語で回答するAIアシスタントです。<|eot_id|><|start_header_id|>user<|end_header_id|>\n{query_str}<|eot_id|><start_header_id|>assistant<|end_header_id|><|eot_id|>"
125
+ if selected_model == "Elyza":
126
+ self.QA_PROMPT_TMPL =("""<s>[INST] <<SYS>>#あなたは誠実で優秀な日本人のコールセンター管理者です。<</SYS>>{query_str} [/INST]""")
127
+ #self.QA_PROMPT_TMPL =("""<s>[INST] <<SYS>>#あなたは誠実で優秀な日本人のアシスタントです。<</SYS>>{query_str} [/INST]""")
128
+ self.CHAT_REFINE_PROMPT_TMPL_MSGS = ("""<s>[INST] <<SYS>>
129
+ "あなたは、既存の回答を改良する際に2つのモードで厳密に動作するQAシステムのエキスパートです。\n"
130
+ "1. 新しいコンテキストを使用して元の回答を**書き直す**。\n"
131
+ "2. 新しいコンテキストが役に立たない場合は、元の回答を**繰り返す**。\n"
132
+ "回答内で元の回答やコンテキストを直接参照しないでください。\n"
133
+ "疑問がある場合は、元の答えを繰り返してください。"
134
+ "New Context: {context_msg}\n"
135
+ <</SYS>>
136
+ "Query: {query_str}\n"
137
+ "Original Answer: {existing_answer}\n"
138
+ "New Answer: "
139
+ [/INST]"""
140
+ )
141
+ if selected_model == "swallow":
142
+ self.QA_PROMPT_TMPL ='### 指示:{query_str}\n ### 応答:'
143
+ #self.QA_PROMPT_TMPL ="""
144
+ #以下の「コンテキスト情報」を元に、質問に回答してください。
145
+ # コンテキスト情報
146
+ #---------------------
147
+ #{context_str}
148
+ #---------------------
149
+ # 制約条件
150
+ #- コンテキスト情報に無い情報は絶対に回答に含めないでください。
151
+ #- コンテキスト情報の内容を丸投げするのではなく、ちゃんと文章にして回答してください。
152
+ #- 質問の答えを知らない場合は、回答しないで知らない事を伝えてください。\n\n### 指示:\n{query_str}\n\n### 応答:
153
+ #"""
154
+ if selected_model == "mist300":
155
+ ###Mistral/Stability系
156
+ #self.QA_PROMPT_TMPL = "<s>[INST]あなたは優秀な日本人のコールセンター管理者です。次の質問に回答して下さい。[/INST]</s> [INST]{query_str}[/INST]"
157
+ #self.QA_PROMPT_TMPL = r'<s>\n以下は、タスクを説明する指示と、文脈のある入力の組み合わせです。要求を適切に満たす応答を書きなさい。\n[SEP]\n指示:\n{query_str}\n[SEP]\n入力:\n{context_str}\n[SEP]\n応答:\n'
158
+ self.QA_PROMPT_TMPL = r'<s>\n以下は、タスクを説明する指示です。要求を適切に満たす応答を書きなさい。\n[SEP]\n指示:\n{query_str}\n[SEP]\n応答:\n'
159
+ #self.QA_PROMPT_TMPL ='### 指示:{query_str}\n ### 応答:'
160
+ #self.QA_PROMPT_TMPL ='### 指示:{query_str}\n ### 入力:{context_str}\n ### 応答:'
161
+ #self.QA_PROMPT_TMPL ="""### 指示:あなたは優秀なコールセンター管理者です。参考文献を元に次の質問に回答して下さい。###質問:{query_str}\n ### 応答:"""
162
+ #self.QA_PROMPT_TMPL ="あなたは優秀な日本人のコールセンター管理者です。次の質問に日本語で回答してください。{query_str}"
163
+ if selected_model == "TinyLlama":
164
+ ###Tinyllama
165
+ #querystr = "上給水ハイブリッド加湿器のお手入れの仕方を、日本語で教えて下さい。"
166
+ #self.QA_PROMPT_TMPL = "<|im_start|>user\n{query_str}<|im_end|>\n<|im_start|>assistant\n"
167
+ #system_message = "あなたは優秀な日本人のコールセンター管理者です。"
168
+ self.QA_PROMPT_TMPL = "<|system|>\nあなたは日本人です。</s>\n<|user|>\n{query_str}</s>\n<|assistant|>"
169
+ if selected_model == "tinycodellamajp":
170
+ self.QA_PROMPT_TMPL = "<|im_start|>user\n{query_str}<|im_end|>\n<|im_start|>assistant\n"
171
+ if selected_model == "tinyllamamoe":
172
+ self.QA_PROMPT_TMPL = "<|システム|>\nあなたは日本人のコールセンターの管理者です。参考情報を元に、日本語で質問に回答してください。</s>\n<|ユーザー|>\n{query_str}</s>\n<|アシスタント|>"
173
+ #self.QA_PROMPT_TMPL = "<|system|>\nあなたは日本人のコールセンターの管理者です。次の情報を元に質問に回答してください。\n{context_str}</s>\n<|user|>\n{query_str}</s>\n<|assistant|>"
174
+ #self.QA_PROMPT_TMPL = "<|システム|>\nあなたは日本人です。</s>\n<|ユーザー|>\n{query_str}</s>\n<|アシスタント|>"
175
+ #self.QA_PROMPT_TMPL = "<|im_start|>user\n{query_str}<|im_end|>\n<|im_start|>assistant\n"
176
+ if selected_model == "phillama":
177
+ self.QA_PROMPT_TMPL = "<|system|>\nあなたは日本人のコールセンターの管理者です。参考情報を元に質問に日本語で回答してください。<|end|><|user|>{query_str}<|end|><|assistant|>"
178
+ if selected_model == "stabilty":
179
+ #self.QA_PROMPT_TMPL = "### 指示: {query_str} \n ### 応答:"
180
+ #self.QA_PROMPT_TMPL = r"""<s>\n以下は、タスクを説明する指示と、文脈のある入力の組み合わせです。要求を適切に満たす応答を書きなさい。\n[SEP]\n指示:\n{query_str}\n[SEP]\n入力:\n{context_str}\n[SEP]\n応答:\n"""
181
+
182
+ self.QA_PROMPT_TMPL = r"""<s>\nあなたは優秀なコールセンター管理者です。参考文献を元に次の質問に回答して下さい。\n[SEP]\n指示:\n{query_str}\n[SEP]\n入力:\n{context_str}\n[SEP]\n応答:\n"""
183
+ #self.QA_PROMPT_TMPL = r"""<s>\nあなたは優秀なコールセンター管理者です。参考文献を元に次の質問に回答して下さい。\n[SEP]\n指示:\n{query_str}\n[SEP]\n応答:\n"""
184
+ #self.QA_PROMPT_TMPL = r'<s>\n以下は、タスクを説明する指示と、文脈のある入力の組み合わせです。要求を適切に満たす応答を書きなさい。\n[SEP]\n指示:\n{query_str}\n[SEP]\n入力:\n{context_str}\n[SEP]\n応答:\n'
185
+ if selected_model == "stabilq4":
186
+ #self.QA_PROMPT_TMPL = r"""<s>\nあなたは優秀なコールセンター管理者です。入力情報を元に次の質問に回答して下さい。\n[SEP]\n指示:\n{query_str}\n[SEP]\n入力:\n{context_str}\n[SEP]\n応答:\n"""
187
+ self.QA_PROMPT_TMPL = """以下は、タスクを説明する指示と、文脈のある入力の組み合わせです。要求を適切に満たす応答を書きなさい。
188
+
189
+ ### 指示:
190
+ {query_str}
191
+
192
+ ### 入力:
193
+ {context_str}
194
+
195
+ ### 応答:
196
+ """
197
+ if selected_model == "stabilq3":
198
+ #self.QA_PROMPT_TMPL = """以下は、タスクを説明する指示と、文脈のある入力の組み合わせです。要求を適切に満たす応答を書きなさい。
199
+
200
+ ### 指示:
201
+ #{query_str}
202
+
203
+ ### 入力:
204
+ #{context_str}
205
+
206
+ ### 応答:
207
+ #"""
208
+ self.QA_PROMPT_TMPL = '### 指示:{query_str}\n### 応答:'
209
+ #self.QA_PROMPT_TMPL = r"""<s>\nあなたは優秀なコールセンター管理者です。次の入力情報を元に指示に応答して下さい。\n[SEP]\n指示:\n{query_str}\n[SEP]\n入力:\n{context_str}\n[SEP]\n応答:\n"""
210
+ #self.QA_PROMPT_TMPL = 'ユーザー: {query_str} システム: '
211
+ #self.QA_PROMPT_TMPL = """<|ユーザ|>{query_str}<|endoftext|> <|アシスタント|><|endoftext|>"""
212
+ #self.QA_PROMPT_TMPL = r"""
213
+ #<|system|>あなたは優秀なコールセンター管理者です。参考情報を元に質問に回答して下さい。<|endoftext|>
214
+
215
+ #<|user|>{query_str}<|endoftext|>
216
+
217
+ #<|assistant|>
218
+ #"""
219
+ if selected_model == "stabilzephyr":
220
+ #self.QA_PROMPT_TMPL = """<|ユーザ|>{query_str}<|endoftext|> <|アシスタント|><|endoftext|>"""
221
+ #self.QA_PROMPT_TMPL = """<|システム|>あなたは優秀なコールセンター管理者です。参考情報を元に質問に回答して下さい。<|endoftext|><|ユーザ|>{query_str}<|endoftext|><|アシスタント|> <|endoftext|>"""
222
+ #self.QA_PROMPT_TMPL = """<|ユーザ|>{query_str}<|endoftext|> <|アシスタント|>"""
223
+ #self.QA_PROMPT_TMPL = """<|ユーザ|>{query_str}<|endoftext|> <|アシスタント|><|endoftext|>"""
224
+ self.QA_PROMPT_TMPL = """
225
+ <|system|>あなたは優秀なコールセンター管理者です。参考情報を元に質問に回答して下さい。<|endoftext|>
226
+
227
+ <|user|>{query_str}<|endoftext|>
228
+
229
+ <|assistant|>
230
+ """
231
+ #self.QA_PROMPT_TMPL = r"""
232
+ #<|system|>あなたは優秀なコールセンター管理者です。次の参考情報を元に質問に回答して下さい。{context_str}<|endoftext|>
233
+
234
+ #<|user|>{query_str}<|endoftext|>
235
+
236
+ #<|assistant|>
237
+ #"""
238
+ #self.QA_PROMPT_TMPL = """以下は、タスクを説明する指示と、文脈のある入力の組み合わせです。要求を適切に満たす応答を書きなさい。
239
+
240
+ ### 指示:
241
+ #{query_str}
242
+
243
+ ### 入力:
244
+ #{context_str}
245
+
246
+ ### 応答:
247
+ #"""
248
+ if selected_model == "stabil2instruct":
249
+ #self.QA_PROMPT_TMPL = """<|ユーザ|>{query_str}<|endoftext|> <|アシスタント|><|endoftext|>"""
250
+ self.QA_PROMPT_TMPL = r"""
251
+ <|system|>あなたは役立つアシスタントです。<|endoftext|>
252
+
253
+ <|user|>{query_str}<|endoftext|>
254
+
255
+ <|assistant|>
256
+ """
257
+ #self.QA_PROMPT_TMPL = r"""
258
+ #<|system|>あなたは優秀なコールセンター管理者です。次の参考情報を元に質問に回答して下さい。{context_str}<|endoftext|>
259
+
260
+ #<|user|>{query_str}<|endoftext|>
261
+
262
+ #<|assistant|>
263
+ #"""
264
+ if selected_model == "h2o":
265
+ #self.QA_PROMPT_TMPL = 'ユーザー: {query_str} システム: '
266
+ self.QA_PROMPT_TMPL = "<|im_start|>システム\nあなたは優秀なコールセンター管理者です。次の情報を元に質問に回答して下さい\n{context_str}<|im_end|>\n<|im_start|>ユーザー\n{query_str}<|im_end|>\n<|im_start|>アシスタント\n"
267
+ if selected_model == "phi2":
268
+ #self.QA_PROMPT_TMPL = """
269
+ # <|im_start|>システム
270
+ # あなたは日本人の優秀なコールセンター管理者です。
271
+ # <|im_end|>
272
+ # <|im_start|>ユーザー
273
+ # {query_str}
274
+ # <|im_end|>
275
+ # <|im_start|>アシスタント
276
+ #"""
277
+ self.QA_PROMPT_TMPL = "<|im_start|>システム\nあなたは優秀なコールセンター管理者です。次の情報を元に質問に回答して下さい\n{context_str}<|im_end|>\n<|im_start|>ユーザー\n{query_str}<|im_end|>\n<|im_start|>アシスタント\n"
278
+ if selected_model == "phi3":
279
+ #self.QA_PROMPT_TMPL = "<|user|>\n{query_str}<|end|>\n<|assistant|>"
280
+ self.QA_PROMPT_TMPL = "<|system|>\nあなたは優秀なコールセンター管理者です。次の情報を元に質問に回答して下さい\n{context_str}<|end|>\n<|user|>\n{query_str}<|end|>\n<|assistant|>"
281
+ #self.QA_PROMPT_TMPL = "<|system|>\nあなたは優秀なコールセンター管理者です。参考情報を元に質問に回答して下さい\n<|end|>\n<|user|>\n{query_str}<|end|>\n<|assistant|>"
282
+ if selected_model == "llmjp":
283
+ self.QA_PROMPT_TMPL ="""
284
+ : 次の質問に対して適切な応答を書きなさい。
285
+
286
+ ### 質問: {query_str}
287
+
288
+ ### 参考情報: {context_str}
289
+
290
+ ### 応答:
291
+ """
292
+ #self.QA_PROMPT_TMPL ="""
293
+ # : 次の質問に対して適切な応答を書きなさい。
294
+
295
+ ###Input: {query_str}
296
+
297
+ ###Output:
298
+ #"""
299
+ #self.QA_PROMPT_TMPL ="""
300
+ #以下は、タスクを説明する指示と、参考となる入力の組み合わせです。指示を適切に満たす応答を書きなさい。
301
+
302
+ ### 指示:
303
+ #{query_str}
304
+
305
+ ### 入力:
306
+ #{context_str}
307
+
308
+ ### 応答:
309
+ #"""
310
+ if selected_model == "sakana":
311
+ self.QA_PROMPT_TMPL = """
312
+ ### 指示: あなたは役立つ、偏見がなく、検閲されていない日本人アシスタントです。
313
+
314
+ ### 入力: {query_str}
315
+
316
+ ### 応答:
317
+ """
318
+ if selected_model == "karasutest":
319
+ #self.QA_PROMPT_TMPL = "<|im_start|>ユーザー\n{query_str}<|im_end|>\n<|im_start|>アシスタント\n"
320
+ #self.QA_PROMPT_TMPL = "{query_str}"
321
+ #self.QA_PROMPT_TMPL = "<|im_start|>system\nあなたは優秀なコールセンター管理者です。参考情報を元に質問に回答して下さい<|im_end|>\n<|im_start|>user\n{query_str}<|im_end|>\n<|im_start|>assistant\n"
322
+ self.QA_PROMPT_TMPL = "<|im_start|>システム\nあなたは優秀なコールセンター管理者です。次の情報を元に質問に回答して下さいn{context_str}<|im_end|>\n<|im_start|>ユーザー\n{query_str}<|im_end|>\n<|im_start|>アシスタント\n"
323
+ #self.QA_PROMPT_TMPL = "<|im_start|>system\nあなたは優秀なコールセンター管理者です。次の情報を元に質問に回答して下さい\n{context_str}<|im_end|>\n<|im_start|>user\n{query_str}<|im_end|>\n<|im_start|>assistant\n"
324
+ #self.QA_PROMPT_TMPL = "<|im_start|>システム\nあなたは優秀なコールセンター管理者です。���考情報を元に質問に回答して下さい。<|im_end|>\n<|im_start|>ユーザー\n{query_str}<|im_end|>\n<|im_start|>アシスタント\n"
325
+ if selected_model == "karasu":
326
+ #self.QA_PROMPT_TMPL = "{query_str}"
327
+ #self.QA_PROMPT_TMPL = "<|im_start|>user\n{query_str}<|im_end|>\n<|im_start|>assistant\n"
328
+ #self.QA_PROMPT_TMPL = "<|im_start|>system\nあなたは優秀なコールセンター管理者です。次の情報を元に質問に回答して下さい\n{context_str}<|im_end|>\n<|im_start|>user\n{query_str}<|im_end|>\n<|im_start|>assistant\n"
329
+ self.QA_PROMPT_TMPL = "<|im_start|>system\nあなたは優秀なコールセンター管理者です。参考情報を元に質問に回答して下さい<|im_end|>\n<|im_start|>user\n{query_str}<|im_end|>\n<|im_start|>assistant\n"
330
+ if selected_model == "karasu_slerp1":
331
+ self.QA_PROMPT_TMPL = "{query_str}"
332
+ if selected_model == "karasu_slerp2":
333
+ #self.QA_PROMPT_TMPL = "{query_str}"
334
+ #self.QA_PROMPT_TMPL = "<|im_start|>user\n{query_str}<|im_end|>\n<|im_start|>assistant\n"
335
+ #self.QA_PROMPT_TMPL = "<|im_start|>system\nあなたは優秀なコールセンター管理者です。次の情報を元に質問に回答して下さい\n{context_str}<|im_end|>\n<|im_start|>user\n{query_str}<|im_end|>\n<|im_start|>assistant\n"
336
+ self.QA_PROMPT_TMPL = """
337
+ <|im_start|>system
338
+ あなたは優秀なコールセンター管理者です。次の情報を元に質問に回答して下さい
339
+ {context_str}<|im_end|>
340
+ <|im_start|>user
341
+ {query_str}<|im_end|>
342
+ <|im_start|>assistant
343
+ """
344
+ if selected_model == "suzume":
345
+ #self.QA_PROMPT_TMPL = "あなたは優秀なコールセンター管理者です。\n{query_str}"
346
+ self.QA_PROMPT_TMPL = "{query_str}"
347
+ if selected_model == "line":
348
+ self.QA_PROMPT_TMPL = 'ユーザー: {query_str} システム: '
349
+ if selected_model == "mist-merge":
350
+ self.QA_PROMPT_TMPL = r"""<s>\nあなたは優秀なコールセンター管理者です。参考文献を元に次の質問に回答して下さい。\n[SEP]\n指示:\n{query_str}\n[SEP]\n入力:\n{context_str}\n[SEP]\n応答:\n"""
351
+ #self.QA_PROMPT_TMPL ='### 指示:{query_str}\n ### 応答:'
352
+ if selected_model == "rinna1":
353
+ self.QA_PROMPT_TMPL = r"""<s>\nあなたは優秀なコールセンター管理者です。参考文献を元に次の質問に回答して下さい。\n[SEP]\n指示:\n{query_str}\n[SEP]\n入力:\n{context_str}\n[SEP]\n応答:\n"""
354
+ #self.QA_PROMPT_TMPL ='### 指示:{query_str}\n ### 応答:'
355
+ if selected_model == "stockmark":
356
+ #self.QA_PROMPT_TMPL ='{query_str}\n'
357
+ self.QA_PROMPT_TMPL ="""
358
+ #「コンテキスト情報」を元に、質問に回答してください。
359
+
360
+ ###質問:{query_str}
361
+
362
+ ###「コンテキスト情報」:{context_str}
363
+
364
+ ###回答:
365
+ """
366
+ if selected_model == "rinna":
367
+ self.QA_PROMPT_TMPL ='ユーザー: {query_str} システム: '
368
+ #self.QA_PROMPT_TMPL ="""
369
+ #「コンテキスト情報」を元に、質問に回答してください。
370
+
371
+ ###質問:{query_str}
372
+
373
+ ###「コンテキスト情報」:{context_str}
374
+
375
+ ###回答:
376
+ #"""
377
+ if device is None:
378
+ #device = "mps" if torch.backends.mps.is_available() else "cpu" #cubaをmpsに変更
379
+ device = "cpu"
380
+ #self.device = torch.device(device)
381
+ self.device = "cpu"
382
+ #print("torch.device,device:",torch.device(device),device)
383
+ self.embed_model = HuggingFaceEmbeddings(model_name="cheonboy/sentence_embedding_japanese", model_kwargs={"device": self.device})
384
+ #self.embed_model = HuggingFaceEmbeddings(model_name="intfloat/multilingual-e5-base", model_kwargs={"device": self.device})
385
+ self.service_context = ServiceContext.from_defaults(llm=self.llm, embed_model=self.embed_model)
386
+
387
+ def generate(self, question, file_name, uploaded_file, maxsearch_results):
388
+ #質問文からキーワドを抽出
389
+ print(question)
390
+ text = question
391
+ #import re
392
+ #keywords = re.split('[のはがをとに]', text)
393
+ #exclude_kyw = ""
394
+ tokens = tok.tokenize(text)
395
+ ja_rake.extract_keywords_from_text(tokens)
396
+ ranked_phrases = ja_rake.get_ranked_phrases_with_scores()
397
+ print("ranked_phrases: ", ranked_phrases)
398
+ keyphrases = [x[0] for x in ranked_phrases], [x[1] for x in ranked_phrases]
399
+ keywords = [x[1] for x in ranked_phrases]
400
+ print("keyphrases: ", keyphrases, "keyphrases[0]: ", keyphrases[0])
401
+ print("keypwords: ", keywords)
402
+
403
+ #PDF検索処理
404
+ try:
405
+ db2 = chromadb.PersistentClient(path="./chroma_db")
406
+ chroma_collection = db2.get_collection(file_name)
407
+ print("chroma collection count: ",chroma_collection.count())
408
+
409
+ #chroma_st_conn =
410
+
411
+ vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
412
+ pdf_index = VectorStoreIndex.from_vector_store(
413
+ vector_store,
414
+ service_context=self.service_context,
415
+ )
416
+ print("load existing file..")
417
+ except: #FileNotFoundError
418
+ print("loaddata from pdf file")
419
+ pdf_documents = self.pdf_reader.load_data(file_name)
420
+ #print("pdf_doc:", pdf_documents)
421
+ db = chromadb.PersistentClient(path="./chroma_db")
422
+ chroma_collection = db.get_or_create_collection(
423
+ name=uploaded_file.name,
424
+ metadata={"hnsw:space": "cosine"}
425
+ )
426
+ print("chroma collection count: ",chroma_collection.count())
427
+ vector_store = ChromaVectorStore(
428
+ chroma_collection=chroma_collection,
429
+ )
430
+ storage_context = StorageContext.from_defaults(vector_store=vector_store)
431
+ pdf_index = VectorStoreIndex.from_documents(
432
+ pdf_documents, storage_context=storage_context, service_context=self.service_context
433
+ )
434
+ print("save new file..")
435
+ #chat履歴をIndexに追加 sourceが書き変わってしまうのでsourceを削除
436
+ #history_docs = SimpleDirectoryReader("./history").load_data()
437
+ #for d in history_docs:
438
+ # pdf_index.insert(document = d, service_context = self.service_context)
439
+ #summaryをIndexに追加
440
+ #summary_docs = SimpleDirectoryReader(f"./summary/{file_name[:file_name.find('.')]}").load_data()
441
+ #summary_docs = SimpleDirectoryReader(
442
+ # input_files=[
443
+ # "./summary/"+str(file_name)[:file_name.find('.')]+"_summary1.txt",
444
+ # "./summary/"+str(file_name)[:file_name.find('.')]+"_summary2.txt"
445
+ # ]
446
+ #)
447
+ #summary_docs = SimpleDirectoryReader("./summary").load_data()
448
+ #print(type(summary_docs), summary_docs)
449
+ #for d in summary_docs:
450
+ # pdf_index.insert(document = d, service_context = self.service_context)
451
+ #pdf_index.insert(document = summary_docs, service_context = self.service_context)
452
+ pdf_engine = pdf_index.as_query_engine(
453
+ similarity_top_k=2,
454
+ text_qa_template=QuestionAnswerPrompt(self.QA_PROMPT_TMPL),
455
+ required_keywords= keywords[0] if keyphrases[0][0] > 0.5 else "",
456
+ #required_keywords=[keywords[0]]
457
+ #required_keywords=[keywords],
458
+ node_postprocessors=[SentenceEmbeddingOptimizer(embed_model=self.service_context.embed_model, threshold_cutoff=0.4)],
459
+ #node_postprocessors=[SentenceEmbeddingOptimizer(embed_model=self.service_context.embed_model,percentile_cutoff=0.9)],
460
+ #streaming=True,
461
+ )
462
+ try:
463
+ pdf_result = pdf_engine.query(question)
464
+ #pdf_result.print_response_stream()
465
+ print("Num of nodes:",len(pdf_result.source_nodes))
466
+ if len(pdf_result.source_nodes) == 1:
467
+ print("source_nodes.SCORE: ", pdf_result.source_nodes[0].score)
468
+ else:
469
+ print("source_nodes.SCORE: ", pdf_result.source_nodes[0].score, pdf_result.source_nodes[1].score)
470
+ #return pdf_result.response, pdf_result.get_formatted_sources(1000)
471
+ #match = re.findall('[1-9]+'+'.', pdf_result.response)
472
+ #print(pdf_result.response.replace(match, "\n"+match))
473
+ #return pdf_result.response.replace("\n", " "+" \n"), pdf_result.source_nodes[0].text.strip().replace(" ", "")
474
+
475
+ print("count before", chroma_collection.count())
476
+ doc_to_update = chroma_collection.get() #(limit=10)
477
+ chroma_collection.delete(ids=[id for id in doc_to_update["ids"]])
478
+
479
+ #print("count after", chroma_collection.count())
480
+ return pdf_result.response, pdf_result.source_nodes[0].text.strip().replace(" ", "")
481
+ #return re.sub("[1-9]+.", "\n[1-9]+.", pdf_result.response).replace("。", "。\n"), pdf_result.source_nodes[0].text.strip().replace(" ", "")
482
+ except ValueError as e:
483
+ print("PDF Error: ",e)
484
+ #st.session_state["chat_history"].append({"assistant": "所定のドキュメンには適切な情報が無いため、ネット検索で回答します(あくまで参考情報ですので、ご自身での確認をお勧めします)。"})
485
+ #st.write["chat_history"].append({"assistant": "所定のドキュメンには適切な情報が無いため、ネット検索で回答します(あくまで参考情報ですので、ご自身での確認をお勧めします)。"})
486
+ #検索前処理
487
+ count = len(keywords)
488
+ search_words = ""
489
+ for index in range(count): #最初と最後のワードを除く(製品名と製品番号があるとベター)
490
+ search_words += " " + keywords[index]
491
+ print("serch_words: ",search_words)
492
+ try:
493
+ #Wikipedia
494
+ wikidocuments = JaWikipediaReader().load_wiki(pages=[search_words])
495
+ strwikidocuments = "".join(map(str, wikidocuments))
496
+ #print("Wiki Contents: ",strwikidocuments)
497
+ with open("./temp_data/wiki/wikisearch.txt", "w") as fp:
498
+ fp.write(strwikidocuments)
499
+ wiki_documents = SimpleDirectoryReader("./temp_data//wiki").load_data()
500
+ wiki_index = VectorStoreIndex.from_documents(wiki_documents, service_context=self.service_context)
501
+ wiki_index.storage_context.persist(persist_dir=f"{STORAGE_DIR}"+"wikisearch.txt")
502
+ wiki_engine = wiki_index.as_query_engine(
503
+ similarity_top_k=2,
504
+ #text_qa_template=QuestionAnswerPrompt(self.QA_PROMPT_TMPL),
505
+ refine_template=QuestionAnswerPrompt(self.CHAT_REFINE_PROMPT_TMPL_MSGS),
506
+ #required_keywords=[keywords[0],keywords[1]],
507
+ #required_keywords=[search_words],
508
+ #exclude_keywords=[exclude_kyw],
509
+ #streaming=True,
510
+ )
511
+ #extend_answer(st.session_state["chat_history"])
512
+ wiki_result = wiki_engine.query(question)
513
+ #return wiki_result.print_response_stream, wiki_result.get_formatted_sources(1000)
514
+ return wiki_result.response, wiki_result.get_formatted_sources(1000)
515
+ except Exception as e:
516
+ #st.error(f"Error: {e}")
517
+ print("Wiki Error: ",e)
518
+ #Duck Search
519
+ try:
520
+ search_results = search_general(search_words)
521
+ #search_results = search_general(keywords[1])
522
+ #search_results = search_general(question)
523
+ with open("./temp_data/duck/ducksearch.txt", "w") as fp:
524
+ contents = ""
525
+ for index in range(maxsearch_results):
526
+ contents += json.dumps(search_results[index]).encode().decode('unicode-escape')
527
+ fp.write(contents)
528
+ web_documents = SimpleDirectoryReader("./temp_data/duck").load_data()
529
+ web_index = VectorStoreIndex.from_documents(web_documents, service_context=self.service_context)
530
+ web_index.storage_context.persist(persist_dir=f"{STORAGE_DIR}"+"ducksearch.txt")
531
+ web_engine = web_index.as_query_engine(
532
+ similarity_top_k=3,
533
+ #text_qa_template=QuestionAnswerPrompt(self.QA_PROMPT_TMPL),
534
+ refine_template=QuestionAnswerPrompt(self.CHAT_REFINE_PROMPT_TMPL_MSGS),
535
+ required_keywords=[search_words],
536
+ #required_keywords=[keywords[0],keywords[1],keywords[2]],
537
+ #exclude_keywords=[exclude_kyw],
538
+ #streaming=True,
539
+ )
540
+ #extend_answer(st.session_state["chat_history"])
541
+ web_result = web_engine.query(question)
542
+ #return web_result.print_response_stream, web_result.get_formatted_sources(1000)
543
+ return web_result.response, web_result.get_formatted_sources(1000)
544
+ except Exception as e:
545
+ #st.error(f"Error: {e}")
546
+ print("Duck Error: ",e)
547
+ #ここにWiki検索を追加する
548
+ return "現在Web検索が停止中。", "Wikipediaの検索結果で代替えします。"
549
+
550
+ def save_uploaded_file(uploaded_file, save_dir):
551
+ try:
552
+ with open(os.path.join(save_dir, uploaded_file.name), "wb") as f:
553
+ f.write(uploaded_file.getvalue())
554
+ return True
555
+ except Exception as e:
556
+ st.error(f"Error: {e}")
557
+ return False
558
+
559
+ def upload_pdf_file():
560
+ uploaded_file = st.sidebar.file_uploader("ファイルアップロード", type=["pdf", "txt"])
561
+ print("uploaded_file",uploaded_file)
562
+ if uploaded_file is not None:
563
+ st.success(f"ファイル {uploaded_file.name} のアップロードが完了しました.")
564
+ return uploaded_file
565
+ # if uploaded_file.type == "application/pdf" and save_uploaded_file(uploaded_file, PDF_DATA_DIR):
566
+ # st.success(f"ファイル {uploaded_file.name} は {PDF_DATA_DIR}に保存されました.")
567
+ # elif uploaded_file.type == "text/plain" and save_uploaded_file(uploaded_file, TXT_DATA_DIR):
568
+ # st.success(f"ファイル {uploaded_file.name} は {TXT_DATA_DIR}に保存されました.")
569
+ # else:
570
+ # st.error("このファイルは保存できません.")
571
+
572
+ def main():
573
+ #st.title('PDF Q&A app')
574
+ #file_list = []
575
+ #for file in os.listdir(PDF_DATA_DIR):
576
+ # if file.endswith(".pdf") and not file.startswith("._"):
577
+ # file_list.append(file)
578
+ #for file in os.listdir(TXT_DATA_DIR):
579
+ # if file.endswith(".txt") and not file.startswith("._"):
580
+ # file_list.append(file)
581
+ #file_name = st.sidebar.selectbox("ファイルの選択", file_list)
582
+ #if uploaded_file is not None:
583
+ # file_name = uploaded_file.name
584
+ # print("file_name",file_name)
585
+ pdf_reader = PDFReader()
586
+
587
+ #uploaded_file = upload_pdf_file()
588
+ uploaded_file = st.sidebar.file_uploader("ファイルアップロード", type=["pdf", "txt"])
589
+ if uploaded_file is not None:
590
+ st.sidebar.success(f"{uploaded_file.name} のアップロード完了")
591
+ with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
592
+ tmp_file.write(uploaded_file.read())
593
+ #selected_model = st.sidebar.selectbox("生成AIモデルの選択", ["phillama", "llama3", "line", "llmjp", "mist300", "TinyLlama", "stabilty", "stabilq4", "stabilq3", "Elyza", "swallow", "sakana", "karasu", "karasu_slerp1", "karasu_slerp2", "karasutest", "tinycodellamajp", "stockmark", "stabilzephyr", "h2o", "rinna", "phi2", "phi3", "suzume"])
594
+ selected_model = st.sidebar.selectbox("生成AIモデルの選択", ["標準", "次候補", "試行版", "llmjp"])
595
+
596
+ if selected_model == "標準":
597
+ selected_model = "line"
598
+ elif selected_model == "次候補":
599
+ selected_model = "karasu_slerp2" #"stabil2instruct"
600
+ elif selected_model == "試行版":
601
+ selected_model = "mist300" #"tinycodellamajp","karasu"
602
+ elif selected_model == "llmjp":
603
+ selected_model = "llmjp"
604
+
605
+ choice = st.radio("参照情報を表示:", ["表示する", "表示しない"])
606
+ question = st.text_input("質問入力")
607
+ response_generator = QAResponseGenerator(selected_model, pdf_reader)
608
+
609
+ # メインの画面に質問送信ボタンを設定
610
+ submit_question = st.button("質問")
611
+ clear_chat = st.sidebar.button("履歴消去")
612
+ st.session_state.last_updated = ""
613
+ st.session_state.last_updated_json = []
614
+
615
+ # チャット履歴を保存
616
+ if "chat_history" not in st.session_state:
617
+ st.session_state["chat_history"] = []
618
+
619
+ if clear_chat:
620
+ st.session_state["chat_history"] = []
621
+ st.session_state.last_updated = ""
622
+ st.session_state.last_updated_json = []
623
+
624
+ # 質問ボタンがクリックされた場合の処理
625
+ if submit_question:
626
+ print("pushed question button!")
627
+ if question: # 質問が入力されている場合
628
+ #response, source = response_generator.generate(question, file.name, maxsearch_results)
629
+ response, source = response_generator.generate(question, tmp_file.name, uploaded_file, maxsearch_results)
630
+ #response = re.sub("[1-9]"+".", "\n[1-9]"+".", response).replace("。", "。\n")
631
+ # 質問と応答をチャット履歴に追加
632
+ #response = response.replace("\n", " "+" \n")
633
+ st.session_state["chat_history"].append({"user": question})
634
+ st.session_state["chat_history"].append({"assistant": response})
635
+ if choice == "表示する":
636
+ source = source.replace("page_label", "該当ページ番号").replace("file_name", " ファイル名:"+uploaded_file.name)
637
+ response = f"\n\n参照した情報は次の通りです:\n\n{source}"
638
+ #st.session_state["chat_history"].append({"assistant": response})
639
+ #stored_response += f"\n\n参照した情報は次の通りです:\n\n{source}"
640
+ with st.chat_message("assistant"): #参照情報の表示
641
+ st.markdown(response)
642
+ #st.session_state.last_updated += json.dumps(st.session_state["chat_history"],indent=2, ensure_ascii=False).replace("]", ",\n{")+re.sub(r"\s", "", f"""\"source\":\"{source}\""""+"\n}\n]")
643
+ st.session_state.last_updated += json.dumps(st.session_state["chat_history"],indent=2, ensure_ascii=False)
644
+ with open("./history/chat_history.txt","w") as o:
645
+ print(st.session_state.last_updated,sep="",file=o)
646
+ with open("./history/chat_history.txt", "r") as f:
647
+ history_str = f.read()
648
+ history_json = json.loads(history_str)
649
+ #print(history_json)
650
+ with open("./history/chat_history.json", "w") as o:
651
+ json.dump(history_json, o, ensure_ascii=False)
652
+
653
+ elif st.button("要約開始"):
654
+ stream_handler = StreamHandler()
655
+ try:
656
+ with st.spinner('要約中...'):
657
+ #print("file_name",file_name)
658
+ if uploaded_file.name.endswith(".pdf"):
659
+ pdf_reader = download_loader("PDFReader", custom_path="local_dir")()
660
+ #docs = pdf_reader.load_data(file=PDF_DATA_DIR+file_name)
661
+ docs = pdf_reader.load_data(file=tmp_file.name)
662
+ alltext = ""
663
+ all_count = len(docs)
664
+ for count in range(all_count):
665
+ text = docs[count].text
666
+ alltext += text
667
+ #print("全文字数:",len(alltext))
668
+ elif uploaded_file.name.endswith(".txt"):
669
+ #loader = TextLoader(TXT_DATA_DIR+file_name)
670
+ loader = TextLoader(tmp_file.name)
671
+ documents = loader.load()
672
+ text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
673
+ docs = text_splitter.split_documents(documents)
674
+ allcount = len(docs)
675
+ alltext = ""
676
+ for n in range(allcount):
677
+ text = docs[n].page_content
678
+ alltext += text
679
+ #print("alltext:",alltext)
680
+ #Summarize By pysummarization
681
+ auto_abstractor = AutoAbstractor()
682
+ auto_abstractor.tokenizable_doc = MeCabTokenizer()
683
+ auto_abstractor.delimiter_list = ["。", "\n"]
684
+ abstractable_doc = StdAbstractor()
685
+ result_dict = auto_abstractor.summarize(alltext, abstractable_doc)
686
+ summary1 = "Original word count(原文文字数): "+str(len(alltext))+"\n\n"
687
+ for x in result_dict["summarize_result"]:
688
+ summary1 += x+"\n"
689
+ summary1 = summary1+"\nNormal Summary word count(標準要約文字数): "+str(len(summary1))+" compression ratio(圧縮率): "+'{:.0%}'.format(len(summary1)/len(alltext))
690
+ similarity_limit = 0.8 #@param {type:"slider", min:0.05, max:0.5, step:0.05}
691
+ nlp_base = NlpBase()
692
+ nlp_base.tokenizable_doc = MeCabTokenizer()
693
+ similarity_filter = TfIdfCosine() #Cosine類似度
694
+ #similarity_filter = Jaccard()
695
+ #similarity_filter = Dice()
696
+ #similarity_filter = Simpson()
697
+ similarity_filter.nlp_base = nlp_base
698
+ similarity_filter.similarity_limit = similarity_limit
699
+ result_dict2 = auto_abstractor.summarize(alltext, abstractable_doc, similarity_filter)
700
+ summary2 = ''
701
+ for sentence in result_dict2["summarize_result"]:
702
+ summary2 += sentence+"\n"
703
+ summary2 = summary2+"\nFiltered Summary word count(フィルタ要約文字数): "+str(len(summary2))+" compression ratio(圧縮率): "+'{:.0%}'.format(len(summary2)/len(alltext))
704
+ auto_abstractor = AutoAbstractor()
705
+ auto_abstractor.tokenizable_doc = MeCabTokenizer()
706
+ auto_abstractor.delimiter_list = ["。", "\n"]
707
+ abstractable_doc = TopNRankAbstractor()
708
+ result_dict = auto_abstractor.summarize(alltext, abstractable_doc)
709
+ summary3 = ''
710
+ for x in result_dict["summarize_result"]:
711
+ summary3 += x+"\n"
712
+ summary3 = summary3+"\nTopNRank word count(トップNランク要約文字数): "+str(len(summary3))+" compression ratio(圧縮率): "+'{:.0%}'.format(len(summary3)/len(alltext))
713
+ #print("TopNrank_Sum文字数: ", len(summary3))
714
+ st.success("[pysum_nomal]\n"+summary1)
715
+ st.success("[pysum_filtered]\n"+summary2)
716
+ st.success("[pysum_topnrank]\n"+summary3)
717
+ st.download_button('要約1をダウンロード', summary1, file_name=uploaded_file.name[:uploaded_file.name.find('.')]+'_summary1.txt')
718
+ st.download_button('要約2をダウンロード', summary2, file_name=uploaded_file.name[:uploaded_file.name.find('.')]+'_summary2.txt')
719
+ st.download_button('要約2をダウンロード', summary3, file_name=uploaded_file.name[:uploaded_file.name.find('.')]+'_summary3.txt')
720
+ #with open("./summary/summary1.txt","w") as o:
721
+ # print(summary1,sep="",file=o)
722
+ #with open("./summary/summary2.txt","w") as o:
723
+ # print(summary2,sep="",file=o)
724
+ except Exception as e:
725
+ if 'NoneType' in str(e):
726
+ st.success("ファイルがアップロードされてません。先にアップロードして下さい。")
727
+ else:
728
+ st.exception(f"An error occurred: {e}")
729
+
730
+ if __name__ == "__main__":
731
+ try:
732
+ main()
733
+ except Exception as e:
734
+ if "'tmp_file' referenced before assignment" in str(e) :
735
+ st.success("ファイルがアップロードされてません。先にアップロードして下さい。")
736
+ else:
737
+ st.exception(f"An error occurred: {e}")
requirements.txt ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Automatically generated by https://github.com/damnever/pigar.
2
+ # Additional install :torch see https://pytorch.org/get-started/locally/
3
+ #Indigo4GBのubuntuLTS24.04はデフォルトpython 3.12.X
4
+
5
+ chromadb==0.5.0
6
+ duckduckgo_search==4.2
7
+ langchain==0.1.20
8
+ langchain_community==0.0.38
9
+ langchain_text_splitters==0.0.1
10
+ llama-index==0.9.34
11
+ pypdf[crypto]
12
+ pysummarization==1.1.9
13
+ rake_ja==0.0.1
14
+ #torch==2.3.0
15
+ wikipedia==1.4.0
16
+ streamlit
17
+ streamlit-chat
18
+ sentence-transformers
19
+ sentencepiece
20
+ #mecab-python3==1.0.8