From a5baaf5d03874b711ed89495bd9e8039385fe297 Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sun, 26 Feb 2023 05:23:44 +1100 Subject: [PATCH 01/26] chore: update requirements.txt --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index bde266e..27996f9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,4 @@ sseclient_py==1.7.2 streamlit==1.18.1 streamlit_tags==1.2.8 streamlit_toggle_switch==1.0.2 +langchain==0.0.94 \ No newline at end of file From 92106eb514291715821e9eabf39fcad9e13b54e2 Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sun, 26 Feb 2023 05:23:59 +1100 Subject: [PATCH 02/26] feat: add token estimation --- GPT/query.py | 27 ++++++++++++++------------- Seanium_Brain.py | 24 +++++++++++++----------- streamlit_toolkit/tools.py | 9 +++++++++ 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/GPT/query.py b/GPT/query.py index 1a00b24..b6e4b61 100644 --- a/GPT/query.py +++ b/GPT/query.py @@ -11,7 +11,6 @@ API_KEY = util.read_file(r'.user\API-KEYS.txt').strip() openai.api_key = API_KEY - SESSION_LANG = st.session_state['SESSION_LANGUAGE'] _ = language.set_language() @@ -61,21 +60,23 @@ def run(query, model, prompt_file, isQuestion, params, info_file=None): return all_response -def run_stream(query, model, prompt_file, isQuestion, params, info_file=None): - client = None +def get_stream_prompt(query, prompt_file, isQuestion, info_file=None): + openai.api_key = API_KEY if isQuestion: data = util.read_json(INFO.BRAIN_DATA) - results = GPT.toolkit.search_chunks(query, data, count=1) - for result in results: - my_info = util.read_file(info_file) - prompt = util.read_file(prompt_file) - prompt = prompt.replace('<>', result['content']) - prompt = prompt.replace('<>', query) - prompt = prompt.replace('<>', my_info) - client = GPT.toolkit.gpt3_stream(API_KEY, prompt, model, params) - + result = GPT.toolkit.search_chunks(query, data, count=1) + my_info = util.read_file(info_file) + prompt = util.read_file(prompt_file) + prompt = prompt.replace('<>', result[0]['content']) + prompt = prompt.replace('<>', query) + prompt = prompt.replace('<>', my_info) else: chunk = textwrap.wrap(query, 10000)[0] prompt = util.read_file(prompt_file).replace('<>', chunk) - client = GPT.toolkit.gpt3_stream(API_KEY, prompt, model, params) + return prompt + + +def run_stream(query, model, prompt_file, isQuestion, params, info_file=None): + prompt = get_stream_prompt(query, prompt_file, isQuestion, info_file) + client = GPT.toolkit.gpt3_stream(API_KEY, prompt, model, params) return client diff --git a/Seanium_Brain.py b/Seanium_Brain.py index e0533e6..3a6c9c1 100644 --- a/Seanium_Brain.py +++ b/Seanium_Brain.py @@ -136,7 +136,7 @@ with header: # main with body: - question = st.text_area(_('Ask Brain: ')) + query = st.text_area(_('Ask Brain: ')) col1, col2 = st.columns([1, 3]) with col1: send = st.button(_('📩Send')) @@ -144,13 +144,15 @@ with body: if os.path.exists(CURRENT_LOG_FILE): st_tool.download_as(_("📥download log")) # execute brain calculation - if not question == '' and send: - st_tool.execute_brain(question, - param, - op, - models, - prompt_core, - prompt_dictionary, - _('question'), - enable_stream, - SESSION_LANG) + if not query == '': + st.markdown(f'Token estimation: `{st_tool.predict_token(query, prompt_core)}`') + if send: + st_tool.execute_brain(query, + param, + op, + models, + prompt_core, + prompt_dictionary, + _('question'), + enable_stream, + SESSION_LANG) diff --git a/streamlit_toolkit/tools.py b/streamlit_toolkit/tools.py index 5d4a7c2..d93798c 100644 --- a/streamlit_toolkit/tools.py +++ b/streamlit_toolkit/tools.py @@ -4,6 +4,7 @@ import json import streamlit as st import tkinter as tk from tkinter import filedialog +from langchain.llms import OpenAI import modules.utilities as util import modules.INFO as INFO @@ -18,6 +19,14 @@ SESSION_TIME = st.session_state['SESSION_TIME'] CURRENT_LOG_FILE = f'{INFO.LOG_PATH}/log_{SESSION_TIME}.log' +def predict_token(query: str, prompt_core: GPT.model.prompt_core) -> int: + """predict how many tokens to generate""" + llm = OpenAI() + token = llm.get_num_tokens(GPT.query.get_stream_prompt(query, prompt_file=prompt_core.question, + isQuestion=True, + info_file=prompt_core.my_info)) + return token + def create_log(): if not os.path.exists(CURRENT_LOG_FILE): util.write_file(f'Session {SESSION_TIME}\n\n', CURRENT_LOG_FILE) From 290264397618e4fe195893efa6fb95e691d8c2b6 Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sun, 26 Feb 2023 05:48:09 +1100 Subject: [PATCH 03/26] feat: add estimation with max token --- GPT/query.py | 1 + Seanium_Brain.py | 24 +++++++++++++++++------- streamlit_toolkit/tools.py | 17 +++++++++++------ 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/GPT/query.py b/GPT/query.py index b6e4b61..b954bae 100644 --- a/GPT/query.py +++ b/GPT/query.py @@ -16,6 +16,7 @@ _ = language.set_language() def build(chunk_size=4000): + openai.api_key = API_KEY all_text = util.read_file(r'.user\input.txt') # split text into smaller chunk of 4000 char each diff --git a/Seanium_Brain.py b/Seanium_Brain.py index 3a6c9c1..732459b 100644 --- a/Seanium_Brain.py +++ b/Seanium_Brain.py @@ -64,12 +64,15 @@ with st.sidebar: "your prompt plus `max_tokens` cannot exceed the model's context length. Most " "models have a context length of 2048 tokens (except for the newest models, " "which support 4096).")) - chunk_size = st.slider(_('Chunk size'), 1500, 4500, - value=util.read_json_at(INFO.BRAIN_MEMO, 'chunk_size', 4000), - help=_("The number of tokens to consider at each step. The larger this is, the more " - "context the model has to work with, but the slower generation and expensive " - "will it be.")) - + col1, col2 = st.columns([3, 1]) + with col1: + chunk_size = st.slider(_('Chunk size'), 1500, 4500, + value=util.read_json_at(INFO.BRAIN_MEMO, 'chunk_size', 4000), + help=_("The number of tokens to consider at each step. The larger this is, the more " + "context the model has to work with, but the slower generation and expensive " + "will it be.")) + with col2: + update_brain = st.button(_('Update Brain')) with st.expander(label=_('Advanced Options')): top_p = st.slider(_('Top_P'), 0.0, 1.0, value=util.read_json_at(INFO.BRAIN_MEMO, 'top_p', 1.0), help=_("An alternative to sampling with temperature, called nucleus sampling, where the " @@ -144,8 +147,15 @@ with body: if os.path.exists(CURRENT_LOG_FILE): st_tool.download_as(_("📥download log")) # execute brain calculation + if update_brain: + st_tool.rebuild_brain(chunk_size) if not query == '': - st.markdown(f'Token estimation: `{st_tool.predict_token(query, prompt_core)}`') + if models.question_model == 'text-davinci-003' or 'text-davinci-003' in models.other_models: + max_model_token = 4000 + else: + max_model_token = 2048 + + st.markdown(f'Token estimation: `{st_tool.predict_token(query, prompt_core)}/{max_model_token}`') if send: st_tool.execute_brain(query, param, diff --git a/streamlit_toolkit/tools.py b/streamlit_toolkit/tools.py index d93798c..36b2455 100644 --- a/streamlit_toolkit/tools.py +++ b/streamlit_toolkit/tools.py @@ -27,6 +27,7 @@ def predict_token(query: str, prompt_core: GPT.model.prompt_core) -> int: info_file=prompt_core.my_info)) return token + def create_log(): if not os.path.exists(CURRENT_LOG_FILE): util.write_file(f'Session {SESSION_TIME}\n\n', CURRENT_LOG_FILE) @@ -259,6 +260,15 @@ def process_response_stream(query, target_model, prompt_file: str, params: GPT.m log(previous_chars, delimiter=f'{file_name.upper()}') +def rebuild_brain(chunk_size: int): + msg = st.warning(_('Updating Brain...'), icon="⏳") + progress_bar = st.progress(0) + for idx, chunk_num in GPT.query.build(chunk_size): + progress_bar.progress((idx + 1) / chunk_num) + msg.success(_('Brain Updated!'), icon="👍") + time.sleep(2) + + def execute_brain(q, params: GPT.model.param, op: GPT.model.Operation, model: GPT.model.Model, @@ -272,12 +282,7 @@ def execute_brain(q, params: GPT.model.param, log(f'\n\n\n\n[{str(time.ctime())}] - QUESTION: {q}') if mod.check_update.is_input_updated() or mod.check_update.is_param_updated(params.chunk_size, 'chunk_size'): - msg = st.warning(_('Updating Brain...'), icon="⏳") - progress_bar = st.progress(0) - for idx, chunk_num in GPT.query.build(params.chunk_size): - progress_bar.progress((idx + 1) / chunk_num) - msg.success(_('Brain Updated!'), icon="👍") - time.sleep(2) + rebuild_brain(params.chunk_size) # =================stream================= if stream: From 9c535a14ba4a4e8c3f691505df8f086eda7c577d Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sun, 26 Feb 2023 16:55:37 +1100 Subject: [PATCH 04/26] refactor: change to gpt_tools.py for clarity --- GPT/__init__.py | 2 +- GPT/{toolkit.py => gpt_tools.py} | 0 GPT/query.py | 12 ++++++------ 3 files changed, 7 insertions(+), 7 deletions(-) rename GPT/{toolkit.py => gpt_tools.py} (100%) diff --git a/GPT/__init__.py b/GPT/__init__.py index 5a13bef..aed902b 100644 --- a/GPT/__init__.py +++ b/GPT/__init__.py @@ -1,3 +1,3 @@ from GPT import query -from GPT import toolkit +from GPT import gpt_tools from GPT import model \ No newline at end of file diff --git a/GPT/toolkit.py b/GPT/gpt_tools.py similarity index 100% rename from GPT/toolkit.py rename to GPT/gpt_tools.py diff --git a/GPT/query.py b/GPT/query.py index b954bae..52c4968 100644 --- a/GPT/query.py +++ b/GPT/query.py @@ -24,7 +24,7 @@ def build(chunk_size=4000): chunk_count = len(chunks) result = [] for idx, chunk in enumerate(chunks): - embedding = GPT.toolkit.embedding(chunk.encode(encoding='ASCII', errors='ignore').decode()) + embedding = GPT.gpt_tools.embedding(chunk.encode(encoding='ASCII', errors='ignore').decode()) info = {'content': chunk, 'vector': embedding} print(info, '\n\n\n') @@ -38,7 +38,7 @@ def build(chunk_size=4000): def run(query, model, prompt_file, isQuestion, params, info_file=None): if isQuestion: data = util.read_json(INFO.BRAIN_DATA) - results = GPT.toolkit.search_chunks(query, data, params.chunk_count) + results = GPT.gpt_tools.search_chunks(query, data, params.chunk_count) answers = [] for result in results: my_info = util.read_file(info_file) @@ -47,7 +47,7 @@ def run(query, model, prompt_file, isQuestion, params, info_file=None): prompt = prompt.replace('<>', query) prompt = prompt.replace('<>', my_info) - answer = GPT.toolkit.gpt3(prompt, model, params) + answer = GPT.gpt_tools.gpt3(prompt, model, params) answers.append(answer) all_response = '\n\n'.join(answers) else: @@ -55,7 +55,7 @@ def run(query, model, prompt_file, isQuestion, params, info_file=None): responses = [] for chunk in chunks: prompt = util.read_file(prompt_file).replace('<>', chunk) - response = GPT.toolkit.gpt3(prompt, model, params) + response = GPT.gpt_tools.gpt3(prompt, model, params) responses.append(response) all_response = '\n\n'.join(responses) return all_response @@ -65,7 +65,7 @@ def get_stream_prompt(query, prompt_file, isQuestion, info_file=None): openai.api_key = API_KEY if isQuestion: data = util.read_json(INFO.BRAIN_DATA) - result = GPT.toolkit.search_chunks(query, data, count=1) + result = GPT.gpt_tools.search_chunks(query, data, count=1) my_info = util.read_file(info_file) prompt = util.read_file(prompt_file) prompt = prompt.replace('<>', result[0]['content']) @@ -79,5 +79,5 @@ def get_stream_prompt(query, prompt_file, isQuestion, info_file=None): def run_stream(query, model, prompt_file, isQuestion, params, info_file=None): prompt = get_stream_prompt(query, prompt_file, isQuestion, info_file) - client = GPT.toolkit.gpt3_stream(API_KEY, prompt, model, params) + client = GPT.gpt_tools.gpt3_stream(API_KEY, prompt, model, params) return client From a366adae9b3acce67ec9461e943d82e42070c914 Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sun, 26 Feb 2023 16:57:34 +1100 Subject: [PATCH 05/26] refactor: change variable name --- GPT/gpt_tools.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GPT/gpt_tools.py b/GPT/gpt_tools.py index 9e93993..79bab6b 100644 --- a/GPT/gpt_tools.py +++ b/GPT/gpt_tools.py @@ -17,8 +17,8 @@ def embedding(content, engine='text-embedding-ada-002'): return vector -def search_chunks(text, data, count=1): - vector = embedding(text) +def search_chunks(query, data, count=1): + vector = embedding(query) points = [] for item in data: From 3b16aa236c8c8c33794e84cfda1f4746a5d6b3d9 Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sun, 26 Feb 2023 17:27:14 +1100 Subject: [PATCH 06/26] refactor: change function name --- modules/utilities.py | 2 +- pages/1_Configs.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/utilities.py b/modules/utilities.py index 12346fb..4b7cb7a 100644 --- a/modules/utilities.py +++ b/modules/utilities.py @@ -77,7 +77,7 @@ def parse_data(data, delimiter='', force=False): return data -def read_files(file_dir, delimiter='', force=False, single_string=True, exclude_dir: list = None, supported_formats: list = None): +def read_bind_files(file_dir, delimiter='', force=False, single_string=True, exclude_dir: list = None, supported_formats: list = None): contents = [] if exclude_dir is None: exclude_dir = [] diff --git a/pages/1_Configs.py b/pages/1_Configs.py index 7f1a5a4..bf6609d 100644 --- a/pages/1_Configs.py +++ b/pages/1_Configs.py @@ -132,13 +132,13 @@ def main(): exclude_dir = exclude_dir_official # if advanced mode enabled if advanced_mode: - note_datas = util.read_files(note_dir, single_string=False, exclude_dir=exclude_dir) + note_datas = util.read_bind_files(note_dir, single_string=False, exclude_dir=exclude_dir) note_datas, filter_info = st_tools.filter_data(note_datas, add_filter_button, del_filter_button) # note_datas, filter_key, filter_logic, filter_val = filter_data(note_datas, True) modified_data = util.parse_data(note_datas, delimiter, force_delimiter) else: - modified_data = util.read_files(note_dir, single_string=True, delimiter=delimiter, - force=force_delimiter, exclude_dir=exclude_dir) + modified_data = util.read_bind_files(note_dir, single_string=True, delimiter=delimiter, + force=force_delimiter, exclude_dir=exclude_dir) # append mode if append_mode: From 41a3130578e60c0e7da17699064825f4ebf22ef2 Mon Sep 17 00:00:00 2001 From: sean1832 Date: Fri, 3 Mar 2023 22:46:09 +1100 Subject: [PATCH 07/26] fix: stream mode not written to json --- Seanium_Brain.py | 21 +++++++++++++++++++++ streamlit_toolkit/tools.py | 18 ------------------ 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/Seanium_Brain.py b/Seanium_Brain.py index 732459b..34e088d 100644 --- a/Seanium_Brain.py +++ b/Seanium_Brain.py @@ -166,3 +166,24 @@ with body: _('question'), enable_stream, SESSION_LANG) + + # convert param to dictionary + param_dict = vars(param) + + # write param to json + for key in param_dict: + value = param_dict[key] + util.update_json(INFO.BRAIN_MEMO, key, value) + + # write operation to json + util.update_json(INFO.BRAIN_MEMO, f'operations_{SESSION_LANG}', op.operations) + + # write question model to json + util.update_json(INFO.BRAIN_MEMO, 'question_model', models.question_model) + + # write other models to json + for i in range(len(op.operations_no_question)): + util.update_json(INFO.BRAIN_MEMO, f'{op.operations_no_question[i]}_model', models.other_models[i]) + + # write stream to json + util.update_json(INFO.BRAIN_MEMO, 'enable_stream', enable_stream) diff --git a/streamlit_toolkit/tools.py b/streamlit_toolkit/tools.py index 36b2455..3f404a4 100644 --- a/streamlit_toolkit/tools.py +++ b/streamlit_toolkit/tools.py @@ -337,24 +337,6 @@ def execute_brain(q, params: GPT.model.param, other_model = model.other_models[i] process_response(answer, other_model, prompt_path, params) - # convert param to dictionary - param_dict = vars(params) - - # write param to json - for key in param_dict: - value = param_dict[key] - util.update_json(INFO.BRAIN_MEMO, key, value) - - # write operation to json - util.update_json(INFO.BRAIN_MEMO, f'operations_{session_language}', op.operations) - - # write question model to json - util.update_json(INFO.BRAIN_MEMO, 'question_model', model.question_model) - - # write other models to json - for i in range(len(op.operations_no_question)): - util.update_json(INFO.BRAIN_MEMO, f'{op.operations_no_question[i]}_model', model.other_models[i]) - def message(msg, condition=None): if condition is not None: From 37d06167cb051783a4fc7d40d19ede87d477c882 Mon Sep 17 00:00:00 2001 From: sean1832 Date: Fri, 3 Mar 2023 22:50:05 +1100 Subject: [PATCH 08/26] build: update library version --- requirements.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 27996f9..685347f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,9 @@ numpy==1.24.2 -openai==0.26.5 +openai==0.27.0 requests==2.28.2 sseclient==0.0.27 sseclient_py==1.7.2 -streamlit==1.18.1 +streamlit==1.19.0 streamlit_tags==1.2.8 streamlit_toggle_switch==1.0.2 -langchain==0.0.94 \ No newline at end of file +langchain==0.0.100 \ No newline at end of file From b2c6f8f20296be50039d912f7cfef330021a3384 Mon Sep 17 00:00:00 2001 From: sean1832 Date: Fri, 3 Mar 2023 23:07:46 +1100 Subject: [PATCH 09/26] chore: rename prompt token estimation --- Seanium_Brain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Seanium_Brain.py b/Seanium_Brain.py index 34e088d..b308be9 100644 --- a/Seanium_Brain.py +++ b/Seanium_Brain.py @@ -155,7 +155,7 @@ with body: else: max_model_token = 2048 - st.markdown(f'Token estimation: `{st_tool.predict_token(query, prompt_core)}/{max_model_token}`') + st.markdown(f'Prompt token: `{st_tool.predict_token(query, prompt_core)}/{max_model_token}`') if send: st_tool.execute_brain(query, param, From 559dd4700e91fa0fd7a67b23f341ba4878c86baf Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sat, 4 Mar 2023 01:33:58 +1100 Subject: [PATCH 10/26] fix: no error code for stream mode --- GPT/gpt_tools.py | 47 +++++++++++++---------- GPT/query.py | 8 +++- Seanium_Brain.py | 3 +- modules/INFO.py | 2 +- streamlit_toolkit/tools.py | 78 ++++++++++++++++++++++---------------- 5 files changed, 81 insertions(+), 57 deletions(-) diff --git a/GPT/gpt_tools.py b/GPT/gpt_tools.py index 79bab6b..9512f64 100644 --- a/GPT/gpt_tools.py +++ b/GPT/gpt_tools.py @@ -48,24 +48,31 @@ def gpt3(prompt, model, params): return text -def gpt3_stream(API_KEY, prompt, model, params): - url = 'https://api.openai.com/v1/completions' - headers = { - 'Accept': 'text/event-stream', - 'Authorization': 'Bearer ' + API_KEY - } - body = { - 'model': model, - 'prompt': prompt, - 'max_tokens': params.max_tokens, - 'temperature': params.temp, - 'top_p': params.top_p, - 'frequency_penalty': params.frequency_penalty, - 'presence_penalty': params.present_penalty, - 'stream': True, - } +def gpt3_stream(prompt, model, params): + response = openai.Completion.create( + model=model, + stream=True, + prompt=prompt, + temperature=params.temp, + max_tokens=params.max_tokens, + top_p=params.top_p, + frequency_penalty=params.frequency_penalty, + presence_penalty=params.present_penalty + ) + return response - req = requests.post(url, stream=True, headers=headers, json=body) - client = sseclient.SSEClient(req) - return client - # print(json.loads(event.data)['choices'][0]['text'], end='', flush=True) + +def gpt35_stream(prompt, params, system_role_content: str = 'You are a helpful assistant.'): + completions = openai.ChatCompletion.create( + model="gpt-3.5-turbo", + max_tokens=params.max_tokens, + temperature=params.temp, + top_p=params.top_p, + frequency_penalty=params.frequency_penalty, + presence_penalty=params.present_penalty, + stream=True, + messages=[ + {"role": "system", "content": system_role_content}, + {"role": "user", "content": prompt} + ]) + return completions diff --git a/GPT/query.py b/GPT/query.py index 52c4968..72e4acb 100644 --- a/GPT/query.py +++ b/GPT/query.py @@ -79,5 +79,11 @@ def get_stream_prompt(query, prompt_file, isQuestion, info_file=None): def run_stream(query, model, prompt_file, isQuestion, params, info_file=None): prompt = get_stream_prompt(query, prompt_file, isQuestion, info_file) - client = GPT.gpt_tools.gpt3_stream(API_KEY, prompt, model, params) + client = GPT.gpt_tools.gpt3_stream(prompt, model, params) + return client + + +def run_35_Stream(query, prompt_file, isQuestion, params, info_file=None): + prompt = get_stream_prompt(query, prompt_file, isQuestion, info_file) + client = GPT.gpt_tools.gpt35_stream(prompt, params) return client diff --git a/Seanium_Brain.py b/Seanium_Brain.py index b308be9..db2109f 100644 --- a/Seanium_Brain.py +++ b/Seanium_Brain.py @@ -164,8 +164,7 @@ with body: prompt_core, prompt_dictionary, _('question'), - enable_stream, - SESSION_LANG) + enable_stream) # convert param to dictionary param_dict = vars(param) diff --git a/modules/INFO.py b/modules/INFO.py index 51c1f95..6413726 100644 --- a/modules/INFO.py +++ b/modules/INFO.py @@ -33,4 +33,4 @@ if 'FILTER_ROW_COUNT' not in st.session_state: st.session_state['FILTER_ROW_COUNT'] = util.read_json_at(BRAIN_MEMO, 'filter_row_count', default_value=1) # models -MODELS_OPTIONS = ['text-davinci-003', 'text-curie-001', 'text-babbage-001', 'text-ada-001'] +MODELS_OPTIONS = ['gpt-3.5-turbo', 'text-davinci-003', 'text-curie-001', 'text-babbage-001', 'text-ada-001'] diff --git a/streamlit_toolkit/tools.py b/streamlit_toolkit/tools.py index 3f404a4..3b69465 100644 --- a/streamlit_toolkit/tools.py +++ b/streamlit_toolkit/tools.py @@ -239,22 +239,28 @@ def process_response_stream(query, target_model, prompt_file: str, params: GPT.m # check if exclude model is not target model file_name = util.get_file_name(prompt_file) with st.spinner(_('Thinking on ') + f"{file_name}..."): - client = GPT.query.run_stream(query, - target_model, - prompt_file, - isQuestion=False, - params=params) + responses = GPT.query.run_stream(query, + target_model, + prompt_file, + isQuestion=False, + params=params) # displaying results st.header(f'📃{file_name}') response_panel = st.empty() previous_chars = '' - for event in client.events(): - if event.data != '[DONE]': - char = json.loads(event.data)['choices'][0]['text'] - response = previous_chars + char - response_panel.info(f'{response}') - previous_chars += char + for response_json in responses: + choice = response_json['choices'][0] + if choice['finish_reason'] == 'stop': + break + # error handling + if choice['finish_reason'] == 'length': + st.warning("⚠️ " + _('Result cut off. max_tokens') + f' ({params.max_tokens}) ' + _('too small. Consider increasing max_tokens.')) + break + char = choice['text'] + response = previous_chars + char + response_panel.info(f'{response}') + previous_chars += char time.sleep(1) log(previous_chars, delimiter=f'{file_name.upper()}') @@ -275,8 +281,7 @@ def execute_brain(q, params: GPT.model.param, prompt_core: GPT.model.prompt_core, prompt_dictionary: dict, question_prompt: str, - stream: bool, - session_language, + stream: bool ): # log question log(f'\n\n\n\n[{str(time.ctime())}] - QUESTION: {q}') @@ -289,23 +294,30 @@ def execute_brain(q, params: GPT.model.param, previous_chars = '' is_question_selected = util.contains(op.operations, question_prompt) with st.spinner(_('Thinking on Answer')): - answer_clients = GPT.query.run_stream(q, model.question_model, - prompt_file=prompt_core.question, - isQuestion=True, - params=params, - info_file=prompt_core.my_info) + responses = GPT.query.run_stream(q, model.question_model, + prompt_file=prompt_core.question, + isQuestion=True, + params=params, + info_file=prompt_core.my_info) if is_question_selected: # displaying results st.header(_('💬Answer')) answer_panel = st.empty() - for event in answer_clients.events(): - if event.data != '[DONE]': - char = json.loads(event.data)['choices'][0]['text'] - answer = previous_chars + char - if is_question_selected: - answer_panel.info(f'{answer}') - previous_chars += char + for response_json in responses: + choice = response_json['choices'][0] + if choice['finish_reason'] == 'stop': + break + # error handling + if choice['finish_reason'] == 'length': + st.warning("⚠️ " + _('Result cut off. max_tokens') + f' ({params.max_tokens}) ' + _('too small. Consider increasing max_tokens.')) + break + + char = choice['text'] + answer = previous_chars + char + if is_question_selected: + answer_panel.info(f'{answer}') + previous_chars += char time.sleep(0.1) log(previous_chars, delimiter='ANSWER') @@ -318,24 +330,24 @@ def execute_brain(q, params: GPT.model.param, else: # thinking on answer with st.spinner(_('Thinking on Answer')): - answer = GPT.query.run(q, model.question_model, - prompt_file=prompt_core.question, - isQuestion=True, - params=params, - info_file=prompt_core.my_info) + responses = GPT.query.run(q, model.question_model, + prompt_file=prompt_core.question, + isQuestion=True, + params=params, + info_file=prompt_core.my_info) if util.contains(op.operations, question_prompt): # displaying results st.header(_('💬Answer')) - st.info(f'{answer}') + st.info(f'{responses}') time.sleep(1.5) - log(answer, delimiter='ANSWER') + log(responses, delimiter='ANSWER') # thinking on other outputs if len(op.operations_no_question) > 0: for i in range(len(op.operations_no_question)): prompt_path = prompt_dictionary[op.operations_no_question[i]] other_model = model.other_models[i] - process_response(answer, other_model, prompt_path, params) + process_response(responses, other_model, prompt_path, params) def message(msg, condition=None): From 680e542607db5a16e491d0567a6313fb705b0193 Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sat, 4 Mar 2023 01:47:28 +1100 Subject: [PATCH 11/26] feat: Add support for GPT-3.5-Turbo (ChatGPT) model This commit adds support for the GPT-3.5-Turbo model in ChatGPT. This model is an improved version of the existing GPT-3 model and offers better performance and accuracy in language generation tasks. --- GPT/query.py | 11 ++++------- streamlit_toolkit/tools.py | 20 +++++++++++++++++--- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/GPT/query.py b/GPT/query.py index 72e4acb..6cf8fea 100644 --- a/GPT/query.py +++ b/GPT/query.py @@ -79,11 +79,8 @@ def get_stream_prompt(query, prompt_file, isQuestion, info_file=None): def run_stream(query, model, prompt_file, isQuestion, params, info_file=None): prompt = get_stream_prompt(query, prompt_file, isQuestion, info_file) - client = GPT.gpt_tools.gpt3_stream(prompt, model, params) - return client - - -def run_35_Stream(query, prompt_file, isQuestion, params, info_file=None): - prompt = get_stream_prompt(query, prompt_file, isQuestion, info_file) - client = GPT.gpt_tools.gpt35_stream(prompt, params) + if model == 'gpt-3.5-turbo': + client = GPT.gpt_tools.gpt35_stream(prompt, params) + else: + client = GPT.gpt_tools.gpt3_stream(prompt, model, params) return client diff --git a/streamlit_toolkit/tools.py b/streamlit_toolkit/tools.py index 3b69465..43d78cf 100644 --- a/streamlit_toolkit/tools.py +++ b/streamlit_toolkit/tools.py @@ -257,7 +257,15 @@ def process_response_stream(query, target_model, prompt_file: str, params: GPT.m if choice['finish_reason'] == 'length': st.warning("⚠️ " + _('Result cut off. max_tokens') + f' ({params.max_tokens}) ' + _('too small. Consider increasing max_tokens.')) break - char = choice['text'] + + if 'gpt-3.5-turbo' in target_model: + delta = choice['delta'] + if "role" in delta or delta == {}: + char = '' + else: + char = delta['content'] + else: + char = choice['text'] response = previous_chars + char response_panel.info(f'{response}') previous_chars += char @@ -312,8 +320,14 @@ def execute_brain(q, params: GPT.model.param, if choice['finish_reason'] == 'length': st.warning("⚠️ " + _('Result cut off. max_tokens') + f' ({params.max_tokens}) ' + _('too small. Consider increasing max_tokens.')) break - - char = choice['text'] + if 'gpt-3.5-turbo' in model.question_model: + delta = choice['delta'] + if "role" in delta or delta == {}: + char = '' + else: + char = delta['content'] + else: + char = choice['text'] answer = previous_chars + char if is_question_selected: answer_panel.info(f'{answer}') From 8c2380d1f8a428968f855c274c29f589f490755a Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sat, 4 Mar 2023 01:53:25 +1100 Subject: [PATCH 12/26] build: add tiktoken library --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 685347f..97ed0bd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,4 +6,5 @@ sseclient_py==1.7.2 streamlit==1.19.0 streamlit_tags==1.2.8 streamlit_toggle_switch==1.0.2 -langchain==0.0.100 \ No newline at end of file +langchain==0.0.100 +tiktoken==0.3.0 \ No newline at end of file From 021366ca67bddcb6c99314dd8af06b2ca9c8792e Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sat, 4 Mar 2023 01:53:55 +1100 Subject: [PATCH 13/26] fix: change max token for gpt-3.5 and davinci to 4096 --- Seanium_Brain.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Seanium_Brain.py b/Seanium_Brain.py index db2109f..e4d7605 100644 --- a/Seanium_Brain.py +++ b/Seanium_Brain.py @@ -151,7 +151,9 @@ with body: st_tool.rebuild_brain(chunk_size) if not query == '': if models.question_model == 'text-davinci-003' or 'text-davinci-003' in models.other_models: - max_model_token = 4000 + max_model_token = 4096 + elif models.question_model == 'gpt-3.5-turbo' or 'gpt-3.5-turbo' in models.other_models: + max_model_token = 4096 else: max_model_token = 2048 From 3d8c291b1742ec7f6de06d331f1afc15f1b2644d Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sat, 4 Mar 2023 02:09:15 +1100 Subject: [PATCH 14/26] fix: update.bat not activating venv --- update.bat | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/update.bat b/update.bat index 33cdfbf..f5fa7be 100644 --- a/update.bat +++ b/update.bat @@ -1,3 +1,7 @@ +@echo off +echo Activating Virtural environment! +call .\venv\Scripts\activate + echo Checking library updates... set "REQUIREMENTS=requirements.txt" set "LAST_MODIFIED=requirements.temp" From c8c12b81e2996d223028e0491b9ae07021b77e50 Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sat, 4 Mar 2023 02:10:08 +1100 Subject: [PATCH 15/26] fix: update.bat no pause --- update.bat | 1 + 1 file changed, 1 insertion(+) diff --git a/update.bat b/update.bat index f5fa7be..d2d729c 100644 --- a/update.bat +++ b/update.bat @@ -31,3 +31,4 @@ if "%mod_date%" neq "%last_mod_date%" ( rem copy example prompt to user folder without overwrite xcopy "example_prompt\*.*" ".user\prompt" /I /E /Y /D +pause \ No newline at end of file From e1e94db2b37990d336f363944d15a711fa092377 Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sat, 4 Mar 2023 03:09:12 +1100 Subject: [PATCH 16/26] fix: tokens not display if brain is not build yet --- GPT/query.py | 16 ++++++++++------ Seanium_Brain.py | 8 ++++++-- modules/check_update.py | 13 +++++++++++++ streamlit_toolkit/tools.py | 19 +++++++++++-------- 4 files changed, 40 insertions(+), 16 deletions(-) diff --git a/GPT/query.py b/GPT/query.py index 6cf8fea..986f463 100644 --- a/GPT/query.py +++ b/GPT/query.py @@ -6,6 +6,7 @@ import modules.utilities as util import modules.language as language import GPT import modules.INFO as INFO +import streamlit_toolkit.tools as st_tools API_KEY = util.read_file(r'.user\API-KEYS.txt').strip() @@ -65,12 +66,15 @@ def get_stream_prompt(query, prompt_file, isQuestion, info_file=None): openai.api_key = API_KEY if isQuestion: data = util.read_json(INFO.BRAIN_DATA) - result = GPT.gpt_tools.search_chunks(query, data, count=1) - my_info = util.read_file(info_file) - prompt = util.read_file(prompt_file) - prompt = prompt.replace('<>', result[0]['content']) - prompt = prompt.replace('<>', query) - prompt = prompt.replace('<>', my_info) + if data: + result = GPT.gpt_tools.search_chunks(query, data, count=1) + my_info = util.read_file(info_file) + prompt = util.read_file(prompt_file) + prompt = prompt.replace('<>', result[0]['content']) + prompt = prompt.replace('<>', query) + prompt = prompt.replace('<>', my_info) + else: + prompt = '' else: chunk = textwrap.wrap(query, 10000)[0] prompt = util.read_file(prompt_file).replace('<>', chunk) diff --git a/Seanium_Brain.py b/Seanium_Brain.py index e4d7605..c7ede57 100644 --- a/Seanium_Brain.py +++ b/Seanium_Brain.py @@ -156,8 +156,12 @@ with body: max_model_token = 4096 else: max_model_token = 2048 - - st.markdown(f'Prompt token: `{st_tool.predict_token(query, prompt_core)}/{max_model_token}`') + tokens, isTokenZero = st_tool.predict_token(query, prompt_core) + token_panel = st.empty() + if isTokenZero: + token_panel.markdown('Prompt token: `Not Available`') + else: + token_panel.markdown(f'Prompt token: `{tokens}/{max_model_token}`') if send: st_tool.execute_brain(query, param, diff --git a/modules/check_update.py b/modules/check_update.py index ddad5f2..4b9f2eb 100644 --- a/modules/check_update.py +++ b/modules/check_update.py @@ -11,6 +11,19 @@ def compare_time(t1, t2): return t1 == t2 +def update_time(): + if os.path.exists(file_path): + # get modification time of the file + mod_time = os.path.getmtime(file_path) + + # convert the modification time to readable format + read_mod_time = time.ctime(mod_time) + + util.write_file(read_mod_time, temp_file) + else: + raise FileNotFoundError(f'File: {file_path} does not exist.') + + def is_input_updated(): if os.path.exists(file_path): # get modification time of the file diff --git a/streamlit_toolkit/tools.py b/streamlit_toolkit/tools.py index 43d78cf..3b8bef7 100644 --- a/streamlit_toolkit/tools.py +++ b/streamlit_toolkit/tools.py @@ -19,13 +19,14 @@ SESSION_TIME = st.session_state['SESSION_TIME'] CURRENT_LOG_FILE = f'{INFO.LOG_PATH}/log_{SESSION_TIME}.log' -def predict_token(query: str, prompt_core: GPT.model.prompt_core) -> int: +def predict_token(query: str, prompt_core: GPT.model.prompt_core) -> (int, bool): """predict how many tokens to generate""" llm = OpenAI() - token = llm.get_num_tokens(GPT.query.get_stream_prompt(query, prompt_file=prompt_core.question, - isQuestion=True, - info_file=prompt_core.my_info)) - return token + prompt = GPT.query.get_stream_prompt(query, prompt_file=prompt_core.question, + isQuestion=True, + info_file=prompt_core.my_info) + token = llm.get_num_tokens(prompt) + return token, token == 0 def create_log(): @@ -255,7 +256,8 @@ def process_response_stream(query, target_model, prompt_file: str, params: GPT.m break # error handling if choice['finish_reason'] == 'length': - st.warning("⚠️ " + _('Result cut off. max_tokens') + f' ({params.max_tokens}) ' + _('too small. Consider increasing max_tokens.')) + st.warning("⚠️ " + _('Result cut off. max_tokens') + f' ({params.max_tokens}) ' + _( + 'too small. Consider increasing max_tokens.')) break if 'gpt-3.5-turbo' in target_model: @@ -280,7 +282,7 @@ def rebuild_brain(chunk_size: int): for idx, chunk_num in GPT.query.build(chunk_size): progress_bar.progress((idx + 1) / chunk_num) msg.success(_('Brain Updated!'), icon="👍") - time.sleep(2) + time.sleep(1) def execute_brain(q, params: GPT.model.param, @@ -318,7 +320,8 @@ def execute_brain(q, params: GPT.model.param, break # error handling if choice['finish_reason'] == 'length': - st.warning("⚠️ " + _('Result cut off. max_tokens') + f' ({params.max_tokens}) ' + _('too small. Consider increasing max_tokens.')) + st.warning("⚠️ " + _('Result cut off. max_tokens') + f' ({params.max_tokens}) ' + _( + 'too small. Consider increasing max_tokens.')) break if 'gpt-3.5-turbo' in model.question_model: delta = choice['delta'] From b1ac973ff9a8a3183e5434f4883e47293fb6a5f2 Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sat, 4 Mar 2023 03:18:20 +1100 Subject: [PATCH 17/26] Revert "fix: tokens not display if brain is not build yet" This reverts commit e1e94db2b37990d336f363944d15a711fa092377. --- GPT/query.py | 16 ++++++---------- Seanium_Brain.py | 8 ++------ modules/check_update.py | 13 ------------- streamlit_toolkit/tools.py | 19 ++++++++----------- 4 files changed, 16 insertions(+), 40 deletions(-) diff --git a/GPT/query.py b/GPT/query.py index 986f463..6cf8fea 100644 --- a/GPT/query.py +++ b/GPT/query.py @@ -6,7 +6,6 @@ import modules.utilities as util import modules.language as language import GPT import modules.INFO as INFO -import streamlit_toolkit.tools as st_tools API_KEY = util.read_file(r'.user\API-KEYS.txt').strip() @@ -66,15 +65,12 @@ def get_stream_prompt(query, prompt_file, isQuestion, info_file=None): openai.api_key = API_KEY if isQuestion: data = util.read_json(INFO.BRAIN_DATA) - if data: - result = GPT.gpt_tools.search_chunks(query, data, count=1) - my_info = util.read_file(info_file) - prompt = util.read_file(prompt_file) - prompt = prompt.replace('<>', result[0]['content']) - prompt = prompt.replace('<>', query) - prompt = prompt.replace('<>', my_info) - else: - prompt = '' + result = GPT.gpt_tools.search_chunks(query, data, count=1) + my_info = util.read_file(info_file) + prompt = util.read_file(prompt_file) + prompt = prompt.replace('<>', result[0]['content']) + prompt = prompt.replace('<>', query) + prompt = prompt.replace('<>', my_info) else: chunk = textwrap.wrap(query, 10000)[0] prompt = util.read_file(prompt_file).replace('<>', chunk) diff --git a/Seanium_Brain.py b/Seanium_Brain.py index c7ede57..e4d7605 100644 --- a/Seanium_Brain.py +++ b/Seanium_Brain.py @@ -156,12 +156,8 @@ with body: max_model_token = 4096 else: max_model_token = 2048 - tokens, isTokenZero = st_tool.predict_token(query, prompt_core) - token_panel = st.empty() - if isTokenZero: - token_panel.markdown('Prompt token: `Not Available`') - else: - token_panel.markdown(f'Prompt token: `{tokens}/{max_model_token}`') + + st.markdown(f'Prompt token: `{st_tool.predict_token(query, prompt_core)}/{max_model_token}`') if send: st_tool.execute_brain(query, param, diff --git a/modules/check_update.py b/modules/check_update.py index 4b9f2eb..ddad5f2 100644 --- a/modules/check_update.py +++ b/modules/check_update.py @@ -11,19 +11,6 @@ def compare_time(t1, t2): return t1 == t2 -def update_time(): - if os.path.exists(file_path): - # get modification time of the file - mod_time = os.path.getmtime(file_path) - - # convert the modification time to readable format - read_mod_time = time.ctime(mod_time) - - util.write_file(read_mod_time, temp_file) - else: - raise FileNotFoundError(f'File: {file_path} does not exist.') - - def is_input_updated(): if os.path.exists(file_path): # get modification time of the file diff --git a/streamlit_toolkit/tools.py b/streamlit_toolkit/tools.py index 3b8bef7..43d78cf 100644 --- a/streamlit_toolkit/tools.py +++ b/streamlit_toolkit/tools.py @@ -19,14 +19,13 @@ SESSION_TIME = st.session_state['SESSION_TIME'] CURRENT_LOG_FILE = f'{INFO.LOG_PATH}/log_{SESSION_TIME}.log' -def predict_token(query: str, prompt_core: GPT.model.prompt_core) -> (int, bool): +def predict_token(query: str, prompt_core: GPT.model.prompt_core) -> int: """predict how many tokens to generate""" llm = OpenAI() - prompt = GPT.query.get_stream_prompt(query, prompt_file=prompt_core.question, - isQuestion=True, - info_file=prompt_core.my_info) - token = llm.get_num_tokens(prompt) - return token, token == 0 + token = llm.get_num_tokens(GPT.query.get_stream_prompt(query, prompt_file=prompt_core.question, + isQuestion=True, + info_file=prompt_core.my_info)) + return token def create_log(): @@ -256,8 +255,7 @@ def process_response_stream(query, target_model, prompt_file: str, params: GPT.m break # error handling if choice['finish_reason'] == 'length': - st.warning("⚠️ " + _('Result cut off. max_tokens') + f' ({params.max_tokens}) ' + _( - 'too small. Consider increasing max_tokens.')) + st.warning("⚠️ " + _('Result cut off. max_tokens') + f' ({params.max_tokens}) ' + _('too small. Consider increasing max_tokens.')) break if 'gpt-3.5-turbo' in target_model: @@ -282,7 +280,7 @@ def rebuild_brain(chunk_size: int): for idx, chunk_num in GPT.query.build(chunk_size): progress_bar.progress((idx + 1) / chunk_num) msg.success(_('Brain Updated!'), icon="👍") - time.sleep(1) + time.sleep(2) def execute_brain(q, params: GPT.model.param, @@ -320,8 +318,7 @@ def execute_brain(q, params: GPT.model.param, break # error handling if choice['finish_reason'] == 'length': - st.warning("⚠️ " + _('Result cut off. max_tokens') + f' ({params.max_tokens}) ' + _( - 'too small. Consider increasing max_tokens.')) + st.warning("⚠️ " + _('Result cut off. max_tokens') + f' ({params.max_tokens}) ' + _('too small. Consider increasing max_tokens.')) break if 'gpt-3.5-turbo' in model.question_model: delta = choice['delta'] From 9d24713faad05f4885bb12ada022688fdd3d3759 Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sat, 4 Mar 2023 03:18:39 +1100 Subject: [PATCH 18/26] Revert "Revert "fix: tokens not display if brain is not build yet"" This reverts commit b1ac973ff9a8a3183e5434f4883e47293fb6a5f2. --- GPT/query.py | 16 ++++++++++------ Seanium_Brain.py | 8 ++++++-- modules/check_update.py | 13 +++++++++++++ streamlit_toolkit/tools.py | 19 +++++++++++-------- 4 files changed, 40 insertions(+), 16 deletions(-) diff --git a/GPT/query.py b/GPT/query.py index 6cf8fea..986f463 100644 --- a/GPT/query.py +++ b/GPT/query.py @@ -6,6 +6,7 @@ import modules.utilities as util import modules.language as language import GPT import modules.INFO as INFO +import streamlit_toolkit.tools as st_tools API_KEY = util.read_file(r'.user\API-KEYS.txt').strip() @@ -65,12 +66,15 @@ def get_stream_prompt(query, prompt_file, isQuestion, info_file=None): openai.api_key = API_KEY if isQuestion: data = util.read_json(INFO.BRAIN_DATA) - result = GPT.gpt_tools.search_chunks(query, data, count=1) - my_info = util.read_file(info_file) - prompt = util.read_file(prompt_file) - prompt = prompt.replace('<>', result[0]['content']) - prompt = prompt.replace('<>', query) - prompt = prompt.replace('<>', my_info) + if data: + result = GPT.gpt_tools.search_chunks(query, data, count=1) + my_info = util.read_file(info_file) + prompt = util.read_file(prompt_file) + prompt = prompt.replace('<>', result[0]['content']) + prompt = prompt.replace('<>', query) + prompt = prompt.replace('<>', my_info) + else: + prompt = '' else: chunk = textwrap.wrap(query, 10000)[0] prompt = util.read_file(prompt_file).replace('<>', chunk) diff --git a/Seanium_Brain.py b/Seanium_Brain.py index e4d7605..c7ede57 100644 --- a/Seanium_Brain.py +++ b/Seanium_Brain.py @@ -156,8 +156,12 @@ with body: max_model_token = 4096 else: max_model_token = 2048 - - st.markdown(f'Prompt token: `{st_tool.predict_token(query, prompt_core)}/{max_model_token}`') + tokens, isTokenZero = st_tool.predict_token(query, prompt_core) + token_panel = st.empty() + if isTokenZero: + token_panel.markdown('Prompt token: `Not Available`') + else: + token_panel.markdown(f'Prompt token: `{tokens}/{max_model_token}`') if send: st_tool.execute_brain(query, param, diff --git a/modules/check_update.py b/modules/check_update.py index ddad5f2..4b9f2eb 100644 --- a/modules/check_update.py +++ b/modules/check_update.py @@ -11,6 +11,19 @@ def compare_time(t1, t2): return t1 == t2 +def update_time(): + if os.path.exists(file_path): + # get modification time of the file + mod_time = os.path.getmtime(file_path) + + # convert the modification time to readable format + read_mod_time = time.ctime(mod_time) + + util.write_file(read_mod_time, temp_file) + else: + raise FileNotFoundError(f'File: {file_path} does not exist.') + + def is_input_updated(): if os.path.exists(file_path): # get modification time of the file diff --git a/streamlit_toolkit/tools.py b/streamlit_toolkit/tools.py index 43d78cf..3b8bef7 100644 --- a/streamlit_toolkit/tools.py +++ b/streamlit_toolkit/tools.py @@ -19,13 +19,14 @@ SESSION_TIME = st.session_state['SESSION_TIME'] CURRENT_LOG_FILE = f'{INFO.LOG_PATH}/log_{SESSION_TIME}.log' -def predict_token(query: str, prompt_core: GPT.model.prompt_core) -> int: +def predict_token(query: str, prompt_core: GPT.model.prompt_core) -> (int, bool): """predict how many tokens to generate""" llm = OpenAI() - token = llm.get_num_tokens(GPT.query.get_stream_prompt(query, prompt_file=prompt_core.question, - isQuestion=True, - info_file=prompt_core.my_info)) - return token + prompt = GPT.query.get_stream_prompt(query, prompt_file=prompt_core.question, + isQuestion=True, + info_file=prompt_core.my_info) + token = llm.get_num_tokens(prompt) + return token, token == 0 def create_log(): @@ -255,7 +256,8 @@ def process_response_stream(query, target_model, prompt_file: str, params: GPT.m break # error handling if choice['finish_reason'] == 'length': - st.warning("⚠️ " + _('Result cut off. max_tokens') + f' ({params.max_tokens}) ' + _('too small. Consider increasing max_tokens.')) + st.warning("⚠️ " + _('Result cut off. max_tokens') + f' ({params.max_tokens}) ' + _( + 'too small. Consider increasing max_tokens.')) break if 'gpt-3.5-turbo' in target_model: @@ -280,7 +282,7 @@ def rebuild_brain(chunk_size: int): for idx, chunk_num in GPT.query.build(chunk_size): progress_bar.progress((idx + 1) / chunk_num) msg.success(_('Brain Updated!'), icon="👍") - time.sleep(2) + time.sleep(1) def execute_brain(q, params: GPT.model.param, @@ -318,7 +320,8 @@ def execute_brain(q, params: GPT.model.param, break # error handling if choice['finish_reason'] == 'length': - st.warning("⚠️ " + _('Result cut off. max_tokens') + f' ({params.max_tokens}) ' + _('too small. Consider increasing max_tokens.')) + st.warning("⚠️ " + _('Result cut off. max_tokens') + f' ({params.max_tokens}) ' + _( + 'too small. Consider increasing max_tokens.')) break if 'gpt-3.5-turbo' in model.question_model: delta = choice['delta'] From 6d5f8bf3134be1b67f431790b200991284ae38eb Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sat, 4 Mar 2023 03:18:53 +1100 Subject: [PATCH 19/26] Revert "Revert "Revert "fix: tokens not display if brain is not build yet""" This reverts commit 9d24713faad05f4885bb12ada022688fdd3d3759. --- GPT/query.py | 16 ++++++---------- Seanium_Brain.py | 8 ++------ modules/check_update.py | 13 ------------- streamlit_toolkit/tools.py | 19 ++++++++----------- 4 files changed, 16 insertions(+), 40 deletions(-) diff --git a/GPT/query.py b/GPT/query.py index 986f463..6cf8fea 100644 --- a/GPT/query.py +++ b/GPT/query.py @@ -6,7 +6,6 @@ import modules.utilities as util import modules.language as language import GPT import modules.INFO as INFO -import streamlit_toolkit.tools as st_tools API_KEY = util.read_file(r'.user\API-KEYS.txt').strip() @@ -66,15 +65,12 @@ def get_stream_prompt(query, prompt_file, isQuestion, info_file=None): openai.api_key = API_KEY if isQuestion: data = util.read_json(INFO.BRAIN_DATA) - if data: - result = GPT.gpt_tools.search_chunks(query, data, count=1) - my_info = util.read_file(info_file) - prompt = util.read_file(prompt_file) - prompt = prompt.replace('<>', result[0]['content']) - prompt = prompt.replace('<>', query) - prompt = prompt.replace('<>', my_info) - else: - prompt = '' + result = GPT.gpt_tools.search_chunks(query, data, count=1) + my_info = util.read_file(info_file) + prompt = util.read_file(prompt_file) + prompt = prompt.replace('<>', result[0]['content']) + prompt = prompt.replace('<>', query) + prompt = prompt.replace('<>', my_info) else: chunk = textwrap.wrap(query, 10000)[0] prompt = util.read_file(prompt_file).replace('<>', chunk) diff --git a/Seanium_Brain.py b/Seanium_Brain.py index c7ede57..e4d7605 100644 --- a/Seanium_Brain.py +++ b/Seanium_Brain.py @@ -156,12 +156,8 @@ with body: max_model_token = 4096 else: max_model_token = 2048 - tokens, isTokenZero = st_tool.predict_token(query, prompt_core) - token_panel = st.empty() - if isTokenZero: - token_panel.markdown('Prompt token: `Not Available`') - else: - token_panel.markdown(f'Prompt token: `{tokens}/{max_model_token}`') + + st.markdown(f'Prompt token: `{st_tool.predict_token(query, prompt_core)}/{max_model_token}`') if send: st_tool.execute_brain(query, param, diff --git a/modules/check_update.py b/modules/check_update.py index 4b9f2eb..ddad5f2 100644 --- a/modules/check_update.py +++ b/modules/check_update.py @@ -11,19 +11,6 @@ def compare_time(t1, t2): return t1 == t2 -def update_time(): - if os.path.exists(file_path): - # get modification time of the file - mod_time = os.path.getmtime(file_path) - - # convert the modification time to readable format - read_mod_time = time.ctime(mod_time) - - util.write_file(read_mod_time, temp_file) - else: - raise FileNotFoundError(f'File: {file_path} does not exist.') - - def is_input_updated(): if os.path.exists(file_path): # get modification time of the file diff --git a/streamlit_toolkit/tools.py b/streamlit_toolkit/tools.py index 3b8bef7..43d78cf 100644 --- a/streamlit_toolkit/tools.py +++ b/streamlit_toolkit/tools.py @@ -19,14 +19,13 @@ SESSION_TIME = st.session_state['SESSION_TIME'] CURRENT_LOG_FILE = f'{INFO.LOG_PATH}/log_{SESSION_TIME}.log' -def predict_token(query: str, prompt_core: GPT.model.prompt_core) -> (int, bool): +def predict_token(query: str, prompt_core: GPT.model.prompt_core) -> int: """predict how many tokens to generate""" llm = OpenAI() - prompt = GPT.query.get_stream_prompt(query, prompt_file=prompt_core.question, - isQuestion=True, - info_file=prompt_core.my_info) - token = llm.get_num_tokens(prompt) - return token, token == 0 + token = llm.get_num_tokens(GPT.query.get_stream_prompt(query, prompt_file=prompt_core.question, + isQuestion=True, + info_file=prompt_core.my_info)) + return token def create_log(): @@ -256,8 +255,7 @@ def process_response_stream(query, target_model, prompt_file: str, params: GPT.m break # error handling if choice['finish_reason'] == 'length': - st.warning("⚠️ " + _('Result cut off. max_tokens') + f' ({params.max_tokens}) ' + _( - 'too small. Consider increasing max_tokens.')) + st.warning("⚠️ " + _('Result cut off. max_tokens') + f' ({params.max_tokens}) ' + _('too small. Consider increasing max_tokens.')) break if 'gpt-3.5-turbo' in target_model: @@ -282,7 +280,7 @@ def rebuild_brain(chunk_size: int): for idx, chunk_num in GPT.query.build(chunk_size): progress_bar.progress((idx + 1) / chunk_num) msg.success(_('Brain Updated!'), icon="👍") - time.sleep(1) + time.sleep(2) def execute_brain(q, params: GPT.model.param, @@ -320,8 +318,7 @@ def execute_brain(q, params: GPT.model.param, break # error handling if choice['finish_reason'] == 'length': - st.warning("⚠️ " + _('Result cut off. max_tokens') + f' ({params.max_tokens}) ' + _( - 'too small. Consider increasing max_tokens.')) + st.warning("⚠️ " + _('Result cut off. max_tokens') + f' ({params.max_tokens}) ' + _('too small. Consider increasing max_tokens.')) break if 'gpt-3.5-turbo' in model.question_model: delta = choice['delta'] From 3b23f212b63e966d660649bf2abcc50695a38858 Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sat, 4 Mar 2023 03:23:33 +1100 Subject: [PATCH 20/26] fix: tokens not display if brain is not build yet --- GPT/query.py | 15 +++++++++------ Seanium_Brain.py | 7 ++++++- streamlit_toolkit/tools.py | 11 ++++++----- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/GPT/query.py b/GPT/query.py index 6cf8fea..642d40d 100644 --- a/GPT/query.py +++ b/GPT/query.py @@ -65,12 +65,15 @@ def get_stream_prompt(query, prompt_file, isQuestion, info_file=None): openai.api_key = API_KEY if isQuestion: data = util.read_json(INFO.BRAIN_DATA) - result = GPT.gpt_tools.search_chunks(query, data, count=1) - my_info = util.read_file(info_file) - prompt = util.read_file(prompt_file) - prompt = prompt.replace('<>', result[0]['content']) - prompt = prompt.replace('<>', query) - prompt = prompt.replace('<>', my_info) + if data: + result = GPT.gpt_tools.search_chunks(query, data, count=1) + my_info = util.read_file(info_file) + prompt = util.read_file(prompt_file) + prompt = prompt.replace('<>', result[0]['content']) + prompt = prompt.replace('<>', query) + prompt = prompt.replace('<>', my_info) + else: + prompt = '' else: chunk = textwrap.wrap(query, 10000)[0] prompt = util.read_file(prompt_file).replace('<>', chunk) diff --git a/Seanium_Brain.py b/Seanium_Brain.py index e4d7605..a91ec4d 100644 --- a/Seanium_Brain.py +++ b/Seanium_Brain.py @@ -157,7 +157,12 @@ with body: else: max_model_token = 2048 - st.markdown(f'Prompt token: `{st_tool.predict_token(query, prompt_core)}/{max_model_token}`') + tokens, isTokenZero = st_tool.predict_token(query, prompt_core) + token_panel = st.empty() + if isTokenZero: + token_panel.markdown('Prompt token: `Not Available`') + else: + token_panel.markdown(f'Prompt token: `{tokens}/{max_model_token}`') if send: st_tool.execute_brain(query, param, diff --git a/streamlit_toolkit/tools.py b/streamlit_toolkit/tools.py index 43d78cf..f34df7e 100644 --- a/streamlit_toolkit/tools.py +++ b/streamlit_toolkit/tools.py @@ -19,13 +19,14 @@ SESSION_TIME = st.session_state['SESSION_TIME'] CURRENT_LOG_FILE = f'{INFO.LOG_PATH}/log_{SESSION_TIME}.log' -def predict_token(query: str, prompt_core: GPT.model.prompt_core) -> int: +def predict_token(query: str, prompt_core: GPT.model.prompt_core) -> (int, bool): """predict how many tokens to generate""" llm = OpenAI() - token = llm.get_num_tokens(GPT.query.get_stream_prompt(query, prompt_file=prompt_core.question, - isQuestion=True, - info_file=prompt_core.my_info)) - return token + prompt = GPT.query.get_stream_prompt(query, prompt_file=prompt_core.question, + isQuestion=True, + info_file=prompt_core.my_info) + token = llm.get_num_tokens(prompt) + return token, token == 0 def create_log(): From 229aa6eca6ba2f3fe5f088cdeec877258a259250 Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sat, 4 Mar 2023 03:25:42 +1100 Subject: [PATCH 21/26] chore: remove pause --- update.bat | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/update.bat b/update.bat index d2d729c..48eb73c 100644 --- a/update.bat +++ b/update.bat @@ -30,5 +30,4 @@ if "%mod_date%" neq "%last_mod_date%" ( ) rem copy example prompt to user folder without overwrite -xcopy "example_prompt\*.*" ".user\prompt" /I /E /Y /D -pause \ No newline at end of file +xcopy "example_prompt\*.*" ".user\prompt" /I /E /Y /D \ No newline at end of file From d1bc2aa6c861387ed756b4e253c44129fbb6ed8c Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sat, 4 Mar 2023 03:38:43 +1100 Subject: [PATCH 22/26] fix: non stream mode cannot use gpt-3.5 --- GPT/gpt_tools.py | 16 ++++++++++++++++ GPT/query.py | 10 ++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/GPT/gpt_tools.py b/GPT/gpt_tools.py index 9512f64..7f0d32f 100644 --- a/GPT/gpt_tools.py +++ b/GPT/gpt_tools.py @@ -48,6 +48,22 @@ def gpt3(prompt, model, params): return text +def gpt35(prompt, params, system_role_content: str = 'You are a helpful assistant.'): + completions = openai.ChatCompletion.create( + model="gpt-3.5-turbo", + max_tokens=params.max_tokens, + temperature=params.temp, + top_p=params.top_p, + frequency_penalty=params.frequency_penalty, + presence_penalty=params.present_penalty, + messages=[ + {"role": "system", "content": system_role_content}, + {"role": "user", "content": prompt} + ]) + text = completions['choices'][0]['message']['content'] + return text + + def gpt3_stream(prompt, model, params): response = openai.Completion.create( model=model, diff --git a/GPT/query.py b/GPT/query.py index 642d40d..e25b75d 100644 --- a/GPT/query.py +++ b/GPT/query.py @@ -47,7 +47,10 @@ def run(query, model, prompt_file, isQuestion, params, info_file=None): prompt = prompt.replace('<>', query) prompt = prompt.replace('<>', my_info) - answer = GPT.gpt_tools.gpt3(prompt, model, params) + if model == 'gpt-3.5-turbo': + answer = GPT.gpt_tools.gpt35(prompt, params) + else: + answer = GPT.gpt_tools.gpt3(prompt, model, params) answers.append(answer) all_response = '\n\n'.join(answers) else: @@ -55,7 +58,10 @@ def run(query, model, prompt_file, isQuestion, params, info_file=None): responses = [] for chunk in chunks: prompt = util.read_file(prompt_file).replace('<>', chunk) - response = GPT.gpt_tools.gpt3(prompt, model, params) + if model == 'gpt-3.5-turbo': + response = GPT.gpt_tools.gpt35(prompt, params) + else: + response = GPT.gpt_tools.gpt3(prompt, model, params) responses.append(response) all_response = '\n\n'.join(responses) return all_response From f253d7e76868e89b7d866ccf8c320750a69b6d4d Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sat, 4 Mar 2023 03:41:32 +1100 Subject: [PATCH 23/26] chore: change default stream mode to true --- Seanium_Brain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Seanium_Brain.py b/Seanium_Brain.py index a91ec4d..cc21f95 100644 --- a/Seanium_Brain.py +++ b/Seanium_Brain.py @@ -93,7 +93,7 @@ with st.sidebar: "(https://platform.openai.com/docs/api-reference/parameter-details)")) enable_stream = st_toggle.st_toggle_switch(_('Stream (experimental)'), default_value=util.read_json_at(INFO.BRAIN_MEMO, 'enable_stream', - False)) + True)) if not enable_stream: chunk_count = st.slider(_('Answer count'), 1, 5, value=util.read_json_at(INFO.BRAIN_MEMO, 'chunk_count', 1), From 9cdc37125da4f98e087d3b08b6d55341f56448c6 Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sat, 4 Mar 2023 03:57:54 +1100 Subject: [PATCH 24/26] build: update version --- .core/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.core/manifest.json b/.core/manifest.json index d17df3d..e76b815 100644 --- a/.core/manifest.json +++ b/.core/manifest.json @@ -1,6 +1,6 @@ { "name": "GPT-Brain", - "version": "0.1.0", + "version": "1.1.0", "license": "MIT", "author": "Zeke Zhang", "homepage": "https://github.com/sean1832/GPT-Brain", From f2826dc61317c43a025f75ba35398e0fcd07a0bb Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sat, 4 Mar 2023 04:15:24 +1100 Subject: [PATCH 25/26] doc: update README.md --- Documentation/README_CN.md | 19 +++++++++++-------- Documentation/README_JP.md | 23 +++++++++++++++-------- README.md | 28 ++++++++++++++++++++-------- 3 files changed, 46 insertions(+), 24 deletions(-) diff --git a/Documentation/README_CN.md b/Documentation/README_CN.md index 9df7554..76c7852 100644 --- a/Documentation/README_CN.md +++ b/Documentation/README_CN.md @@ -9,8 +9,15 @@ *💡本人并非专业程序猿,并且是一个python小白,此项目可能会出现各种bug。如果你遇到bug,请在[问题栏](https://github.com/sean1832/GPT-Brain/issues)里提出,我会尽可能的进行修补。* +### 简介 +本程序利用[GPT-3](https://platform.openai.com/docs/models/gpt-3)和[3.5](https://platform.openai.com/docs/models/gpt-3-5)的能力,提供对原子笔记内容的概括,以及针对笔记的特定内容的回答。 +该程序扫描指定目录(通常是包含多个笔记的vault),并将所有笔记的内容附加到单个文件中。 +该文件随后用作用户查询的上下文。程序能够识别笔记内容之间的关系,并生成一个精炼的回答,概括关键要点。 + +尽管该程序与使用markdown或txt的其他笔记软件兼容,但它主要是针对[Obsidian](https://obsidian.md/)设计的。 + ### 功能 -- [x] 使用 [OpenAI GPT-3](https://platform.openai.com/docs/models/gpt-3) 生成回答。 +- [x] 使用 [OpenAI GPT-3](https://platform.openai.com/docs/models/gpt-3)和 [GPT-3.5 (ChatGPT)](https://platform.openai.com/docs/models/gpt-3-5) 生成回答。 - [x] 使用 [OpenAI embedding](https://platform.openai.com/docs/guides/embeddings/what-are-embeddings) 对笔记内容和问题进行对称比较,以增强搜索效果。 - [x] 可配置prompt。 - [x] 可个性化的个人背景信息以获得更贴切的答案。 @@ -23,13 +30,9 @@ - [x] 基本和高级参数滑块,以便于调整OpenAI语言模型配置。 ### 未来计划 -- [x] ~~batch脚本更新库。~~ -- [x] ~~版本控制。~~ -- [x] ~~参数提示。~~ -- [x] ~~支持多语言UI~~。 -- [x] ~~支持多语言检索。~~ -- [ ] 提供详细操作指南。 -- [ ] 发布windows版本。 +- [ ] 支持PDF笔记格式。 +- [ ] 支持PDF OCR扫描。 +- [ ] 支持Word文档格式。 ## 安装 ### 1. 所需条件 diff --git a/Documentation/README_JP.md b/Documentation/README_JP.md index d4fbdfd..0412b66 100644 --- a/Documentation/README_JP.md +++ b/Documentation/README_JP.md @@ -9,8 +9,19 @@ *💡私はプロのプログラマーではなく、Pythonにもかなり慣れていないため、このプロジェクトにはバグが含まれているかもしれません。もし何か問題があれば、[Issues section](https://github.com/sean1832/GPT-Brain/issues)で提案してください。* +### 紹介 +このプログラムは、[GPT-3](https://platform.openai.com/docs/models/gpt-3)と[3.5](https://platform.openai.com/docs/models/gpt-3-5)の力を活用して、原子的なノートの内容の要約と、 +特定のノートに関連する質問に回答することを提供します。 +プログラムは、通常、複数のノートを含むvaultとして指定されたディレクトリをスキャンし、 +すべてのノートの内容を単一のファイルに追加します。 +このファイルは、ユーザーのクエリの文脈として機能します。プログラムは、ノートの内容の関係を識別し、 +主要なポイントを要約する洗練された応答を生成できます。 + +このプログラムは、markdownまたはtxtを使用する他のノート取りソフトウェアでも互換性がありますが、 +主に[Obsidian](https://obsidian.md/)を想定して設計されています。 + ### フィーチャー -- [x] [OpenAI GPT-3](https://platform.openai.com/docs/models/gpt-3)を使って、レスポンスを生成します。 +- [x] [OpenAI GPT-3](https://platform.openai.com/docs/models/gpt-3)と[GPT-3.5 (ChatGPT)](https://platform.openai.com/docs/models/gpt-3-5)を使って、レスポンスを生成します。 - [x] [OpenAIエンベッディング](https://platform.openai.com/docs/guides/embeddings/what-are-embeddings)を使用して、質問とノートの内容を意味的に比較し、検索を強化します。 - [x] 設定可能なプロンプト。 - [x] より正確な回答を得るために、個人の背景情報をカスタマイズすることができます。 @@ -23,13 +34,9 @@ - [x] OpenAI言語モデルの構成に対する基本的および高度なパラメータースライダー。。 ### Todo -- [x] ~~ライブラリの更新を行うバッチスクリプト。~~ -- [x] ~~バージョニング。~~ -- [x] ~~パラメータに関するヒント。~~ -- [x] ~~多言語UI。~~ -- [x] ~~多言語検索に対応。~~ -- [ ] ユーザー向けの詳細なドキュメントを提供する。 -- [ ] Windows用をリリース。 +- [ ] PDFサポート。 +- [ ] PDF OCRスキャンをサポート。 +- [ ] Word文書をサポート。 ## 設置 ### 1. 必要なもの diff --git a/README.md b/README.md index c20c67f..bb2a2e2 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,23 @@ *💡As I am not a professional programmer and am fairly new to Python, this project may contain bugs. If you encounter any issues, please suggest them in the [Issues section](https://github.com/sean1832/GPT-Brain/issues).* +### Description +This program leverages the power of [GPT-3](https://platform.openai.com/docs/models/gpt-3) & [3.5](https://platform.openai.com/docs/models/gpt-3-5) to provide a summary of the content of atomic notes, +as well as answer questions related specifically to your notes. +The program scans a designated directory, +which is typically a vault containing multiple notes, +and appends the contents of all the notes to a single file. +This file then serves as the context for the user's query. +The program is able to identify +relationships between the contents of the notes, +and generate a refined response that summarizes the key points. + +Although the program is compatible with other note-taking software that uses +markdown or txt, +it is primarily designed with [Obsidian](https://obsidian.md/) in mind. + ### Feature -- [x] Use [OpenAI GPT-3](https://platform.openai.com/docs/models/gpt-3) to generate response. +- [x] Use [OpenAI GPT-3](https://platform.openai.com/docs/models/gpt-3) and [GPT-3.5 (ChatGPT)](https://platform.openai.com/docs/models/gpt-3-5) to generate response. - [x] Use [OpenAI embedding](https://platform.openai.com/docs/guides/embeddings/what-are-embeddings) for semetic comparison of question and note content for enhanced searching. - [x] Configurable prompts. - [x] Customizable personal background information for more accurate answers. @@ -23,13 +38,10 @@ - [x] Basic & Advanced parameter sliders for OpenAI Language model configurations. ### Todo -- [x] ~~Batch script to update library.~~ -- [x] ~~Versioning.~~ -- [x] ~~Tooltips for parameters.~~ -- [x] ~~Multilingual support for UI.~~ -- [x] ~~Multilingual search support.~~ -- [ ] Provide detail documentation for users. -- [ ] Release for windows. +- [ ] Support PDF format。 +- [ ] Support PDF OCR scan。 +- [ ] Support Word document。 + ## Install ### 1. What you need From b8a70f3dba2103ac807ad34c89ef8cdbcb8d6c41 Mon Sep 17 00:00:00 2001 From: sean1832 Date: Sat, 4 Mar 2023 04:16:45 +1100 Subject: [PATCH 26/26] build: Change version --- .core/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.core/manifest.json b/.core/manifest.json index e76b815..7c5ca95 100644 --- a/.core/manifest.json +++ b/.core/manifest.json @@ -1,6 +1,6 @@ { "name": "GPT-Brain", - "version": "1.1.0", + "version": "1.0.0", "license": "MIT", "author": "Zeke Zhang", "homepage": "https://github.com/sean1832/GPT-Brain",