This commit is contained in:
saloui 2023-06-19 16:51:41 +02:00
parent ca4a4a7802
commit 9298e9dcb6
5 changed files with 262 additions and 92 deletions

View File

@ -0,0 +1 @@
C:\Users\sa226037\Downloads\CHLOE-Application-Form-Letter-of-Interest.pdf

View File

@ -0,0 +1,163 @@
import argparse
import socketio
from pathlib import Path
from lollms import MSG_TYPE
from lollms.helpers import ASCIIColors
import time
import json
from pathlib import Path
import PyPDF2
from docx import Document
from bs4 import BeautifulSoup
import json
import csv
from pptx import Presentation
# Connect to the Socket.IO server
sio = socketio.Client()
def read_pdf_file(file_path):
with open(file_path, 'rb') as file:
pdf_reader = PyPDF2.PdfReader(file)
text = ""
for page in pdf_reader.pages:
text += page.extract_text()
return text
def read_docx_file(file_path):
doc = Document(file_path)
text = ""
for paragraph in doc.paragraphs:
text += paragraph.text + "\n"
return text
def read_json_file(file_path):
with open(file_path, 'r') as file:
data = json.load(file)
return data
def read_csv_file(file_path):
with open(file_path, 'r') as file:
csv_reader = csv.reader(file)
lines = [row for row in csv_reader]
return lines
def read_html_file(file_path):
with open(file_path, 'r') as file:
soup = BeautifulSoup(file, 'html.parser')
text = soup.get_text()
return text
def read_pptx_file(file_path):
prs = Presentation(file_path)
text = ""
for slide in prs.slides:
for shape in slide.shapes:
if shape.has_text_frame:
for paragraph in shape.text_frame.paragraphs:
for run in paragraph.runs:
text += run.text
return text
def read_text_file(file_path):
with open(file_path, 'r', encoding='utf-8') as file:
content = file.read()
return content
def chunk(input_text, word_count):
# Check for empty text case (word count = 0)
if not input_text or word_count == 0:
return []
# Split the string into words using .split() method. Remove leading and trailing whitespace characters from each word by replacing them with an empty strinng ""
cleaned_words = [word.strip(' ') for word in input_text.lower().split()]
return [' '.join(cleaned_words[i:i+word_count]) for i in range(0,len(cleaned_words),word_count)]
# Event handler for receiving generated text
@sio.event
def text_generated(data):
print('Generated text:', data)
def test_generate_text(host, port):
docs=Path(__file__).parent/"docs.txt"
questions_path = Path(__file__).parent/"questions.txt"
outputs=Path(__file__).parent/"outputs.txt"
files = []
# Read the text file and split by multiple newlines
print("Loading files")
with open(docs, 'r') as file:
file = file.read().split('\n')
files.append(Path(file[0]))
for file in files:
infos={
"is_ready":False,
"answer":""
}
if file.suffix.lower()==".pdf":
txt = read_pdf_file(file)
file_chunks = chunk(txt,512)
# Event handler for successful connection
@sio.event
def connect():
print('Connected to Socket.IO server')
questions = []
with open(questions_path, 'r') as file:
questions = file.read().split('\n')
for question in questions:
print(f"Question:{question}")
useful_chunks=[]
for chunk in file_chunks:
prompt="Document:\n"+chunk+"\n"+question
# Trigger the 'generate_text' event with the prompt
infos["is_ready"]=False
print(f"Sending prompt:{prompt}")
sio.emit('generate_text', {'prompt': prompt, 'personality':-1, "n_predicts":1024})
while infos["is_ready"]==False:
time.sleep(0.1)
if(infos["answer"].lower()=="yes"):
ASCIIColors.info("Found useful chunk")
useful_chunks.append(chunk)
with open(outputs, 'w') as file:
file.writelines([question,"Useful chunks"])
for i in range(len(useful_chunks)):
file.writelines([useful_chunks[i]])
@sio.event
def text_chunk(data):
print(data["chunk"],end="",flush=True)
@sio.event
def text_generated(data):
print("text_generated_ok")
print(data["text"])
infos["answer"]=data["text"]
infos["is_ready"]=True
print(f"Connecting to http://{host}:{port}")
# Connect to the Socket.IO server
sio.connect(f'http://{host}:{port}')
# Start the event loop
sio.wait()
if __name__ == '__main__':
# Parse command-line arguments
parser = argparse.ArgumentParser(description='Socket.IO endpoint test')
parser.add_argument('--host', type=str, default='localhost', help='Socket.IO server host')
parser.add_argument('--port', type=int, default=9601, help='Socket.IO server port')
parser.add_argument('--text-file', type=str, default=str(Path(__file__).parent/"example_text_gen.txt"),help='Path to the text file')
args = parser.parse_args()
# Run the test with provided arguments
test_generate_text(args.host, args.port)

View File

@ -0,0 +1 @@
Does this document provide information about the buisinessplan (Yes/No):

View File

@ -21,22 +21,102 @@ from threading import Thread
class LoLLMsServer:
def __init__(self):
self.app = Flask("LoLLMsServer_Server")
#self.app.config['SECRET_KEY'] = 'lollmssecret'
CORS(self.app) # Enable CORS for all routes
self.socketio = SocketIO(self.app, cors_allowed_origins='*')
host = "localhost"
port = "9601"
self.clients = {}
self.current_binding = None
self.current_model = None
self.personalities = []
self.answer = ['']
self.is_ready = True
self.lollms_paths = LollmsPaths.find_paths(force_local=False)
self.menu = MainMenu(self)
parser = argparse.ArgumentParser()
parser.add_argument('--host', '-hst', default=host, help='Host name')
parser.add_argument('--port', '-prt', default=port, help='Port number')
parser.add_argument('--config', '-cfg', default=None, help='Path to the configuration file')
parser.add_argument('--bindings_path', '-bp', default=str(self.lollms_paths.bindings_zoo_path),
help='The path to the Bindings folder')
parser.add_argument('--personalities_path', '-pp',
default=str(self.lollms_paths.personalities_zoo_path),
help='The path to the personalities folder')
parser.add_argument('--models_path', '-mp', default=str(self.lollms_paths.personal_models_path),
help='The path to the models folder')
parser.add_argument('--binding_name', '-b', default="llama_cpp_official",
help='Binding to be used by default')
parser.add_argument('--model_name', '-m', default=None,
help='Model name')
parser.add_argument('--personality_full_name', '-p', default="personality",
help='Personality path relative to the personalities folder (language/category/name)')
parser.add_argument('--reset_personal_path', action='store_true', help='Reset the personal path')
parser.add_argument('--reset_config', action='store_true', help='Reset the configurations')
parser.add_argument('--reset_installs', action='store_true', help='Reset all installation status')
args = parser.parse_args()
if args.reset_installs:
reset_all_installs()
if args.reset_personal_path:
LollmsPaths.reset_configs()
if args.reset_config:
cfg_path = LollmsPaths.find_paths().personal_configuration_path / "local_config.yaml"
try:
cfg_path.unlink()
ASCIIColors.success("LOLLMS configuration reset successfully")
except:
ASCIIColors.success("Couldn't reset LOLLMS configuration")
# Configuration loading part
self.config = LOLLMSConfig.autoload(self.lollms_paths, args.config)
if args.binding_name:
self.config.binding_name = args.binding_name
if args.model_name:
self.config.model_name = args.model_name
# Recover bindings path
self.personalities_path = Path(args.personalities_path)
self.bindings_path = Path(args.bindings_path)
self.models_path = Path(args.models_path)
if self.config.binding_name is None:
self.menu.select_binding()
else:
self.binding_class = self.build_binding(self.bindings_path, self.config)
if self.config.model_name is None:
self.menu.select_model()
else:
try:
self.current_model = self.binding_class(self.config)
except Exception as ex:
print(f"{ASCIIColors.color_red}Couldn't load model Please select a valid model{ASCIIColors.color_reset}")
print(f"{ASCIIColors.color_red}{ex}{ASCIIColors.color_reset}")
self.menu.select_model()
for p in self.config.personalities:
personality = AIPersonality(self.lollms_paths, self.config.lollms_paths.personalities_zoo_path/p, self.current_model)
self.personalities.append(personality)
if self.config.active_personality_id>len(self.personalities):
self.config.active_personality_id = 0
self.active_personality = self.personalities[self.config.active_personality_id]
self.menu.show_logo()
self.app = Flask("LoLLMsServer_Server")
#self.app.config['SECRET_KEY'] = 'lollmssecret'
CORS(self.app) # Enable CORS for all routes
self.socketio = SocketIO(self.app, cors_allowed_origins='*', ping_timeout=1200, ping_interval=4000)
# Set log level to warning
self.app.logger.setLevel(logging.WARNING)
@ -333,11 +413,14 @@ class LoLLMsServer:
@self.socketio.on('generate_text')
def handle_generate_text(data):
client_id = request.sid
ASCIIColors.info(f"Text generation requested by client: {client_id}")
if not self.is_ready:
emit("buzzy", {"message":"I am buzzy. Come back later."})
self.socketio.sleep(0)
ASCIIColors.warning(f"OOps request {client_id} refused!! Server buzy")
return
def generate_text():
self.is_ready = False
model = self.current_model
self.clients[client_id]["is_generating"]=True
self.clients[client_id]["requested_stop"]=False
@ -346,7 +429,6 @@ class LoLLMsServer:
n_predicts = data["n_predicts"]
if personality_id==-1:
# Raw text generation
print(f"Text generation requested by client: {client_id}")
self.answer = {"full_text":""}
def callback(text, message_type: MSG_TYPE):
if message_type == MSG_TYPE.MSG_TYPE_CHUNK:
@ -374,7 +456,7 @@ class LoLLMsServer:
# Emit the generated text to the client
self.socketio.emit('text_generated', {'text': generated_text}, room=client_id)
self.socketio.sleep(0)
self.is_ready = True
else:
personality: AIPersonality = self.personalities[personality_id]
personality.model = model
@ -439,8 +521,9 @@ class LoLLMsServer:
# Emit the generated text to the client
self.socketio.emit('text_generated', {'text': generated_text}, room=client_id)
self.socketio.sleep(0)
self.is_ready = True
# Start the text generation task in a separate thread
self.socketio.start_background_task(target=generate_text,)
self.socketio.start_background_task(target=generate_text, once=True)
generate_text()
def build_binding(self, bindings_path: Path, cfg: LOLLMSConfig)->LLMBinding:
@ -467,88 +550,10 @@ class LoLLMsServer:
def run(self, host="localhost", port="9601"):
parser = argparse.ArgumentParser()
parser.add_argument('--host', '-hst', default=host, help='Host name')
parser.add_argument('--port', '-prt', default=port, help='Port number')
parser.add_argument('--config', '-cfg', default=None, help='Path to the configuration file')
parser.add_argument('--bindings_path', '-bp', default=str(self.lollms_paths.bindings_zoo_path),
help='The path to the Bindings folder')
parser.add_argument('--personalities_path', '-pp',
default=str(self.lollms_paths.personalities_zoo_path),
help='The path to the personalities folder')
parser.add_argument('--models_path', '-mp', default=str(self.lollms_paths.personal_models_path),
help='The path to the models folder')
parser.add_argument('--binding_name', '-b', default="llama_cpp_official",
help='Binding to be used by default')
parser.add_argument('--model_name', '-m', default=None,
help='Model name')
parser.add_argument('--personality_full_name', '-p', default="personality",
help='Personality path relative to the personalities folder (language/category/name)')
parser.add_argument('--reset_personal_path', action='store_true', help='Reset the personal path')
parser.add_argument('--reset_config', action='store_true', help='Reset the configurations')
parser.add_argument('--reset_installs', action='store_true', help='Reset all installation status')
args = parser.parse_args()
if args.reset_installs:
reset_all_installs()
if args.reset_personal_path:
LollmsPaths.reset_configs()
if args.reset_config:
cfg_path = LollmsPaths.find_paths().personal_configuration_path / "local_config.yaml"
try:
cfg_path.unlink()
ASCIIColors.success("LOLLMS configuration reset successfully")
except:
ASCIIColors.success("Couldn't reset LOLLMS configuration")
# Configuration loading part
self.config = LOLLMSConfig.autoload(self.lollms_paths, args.config)
if args.binding_name:
self.config.binding_name = args.binding_name
if args.model_name:
self.config.model_name = args.model_name
# Recover bindings path
self.personalities_path = Path(args.personalities_path)
self.bindings_path = Path(args.bindings_path)
self.models_path = Path(args.models_path)
if self.config.binding_name is None:
self.menu.select_binding()
else:
self.binding_class = self.build_binding(self.bindings_path, self.config)
if self.config.model_name is None:
self.menu.select_model()
else:
try:
self.current_model = self.binding_class(self.config)
except Exception as ex:
print(f"{ASCIIColors.color_red}Couldn't load model Please select a valid model{ASCIIColors.color_reset}")
print(f"{ASCIIColors.color_red}{ex}{ASCIIColors.color_reset}")
self.menu.select_model()
for p in self.config.personalities:
personality = AIPersonality(self.lollms_paths, self.config.lollms_paths.personalities_zoo_path/p, self.current_model)
self.personalities.append(personality)
if self.config.active_personality_id>len(self.personalities):
self.config.active_personality_id = 0
self.active_personality = self.personalities[self.config.active_personality_id]
self.menu.show_logo()
print(f"{ASCIIColors.color_red}Current personality : {ASCIIColors.color_reset}{self.active_personality}")
ASCIIColors.info(f"Serving on address: http://{args.host}:{args.port}")
ASCIIColors.info(f"Serving on address: http://{host}:{port}")
self.socketio.run(self.app, host=args.host, port=args.port)
self.socketio.run(self.app, host=host, port=port)
def main():
LoLLMsServer()

View File

@ -26,7 +26,7 @@ def get_all_files(path):
setuptools.setup(
name="lollms",
version="1.2.8",
version="1.2.9",
author="Saifeddine ALOUI",
author_email="aloui.saifeddine@gmail.com",
description="A python library for AI personality definition",