diff --git a/examples/lllm_qt_client/lllm_qt_client.py b/examples/lllm_qt_client/lllm_qt_client.py index 3b48590..78656a3 100644 --- a/examples/lllm_qt_client/lllm_qt_client.py +++ b/examples/lllm_qt_client/lllm_qt_client.py @@ -16,25 +16,25 @@ class ServerConnector(QObject): def __init__(self, parent=None): super(ServerConnector, self).__init__(parent) - self.socketio = Client() + self.sio = Client() self.connected = False self.personalities = [] self.selected_personality_id = 0 - self.socketio.on('connect', self.handle_connect) - self.socketio.on('text_chunk', self.handle_text_chunk) - self.socketio.on('text_generated', self.handle_text_generated) - self.socketio.on('active_personalities_list', self.handle_personalities_received) + self.sio.on('connect', self.handle_connect) + self.sio.on('text_chunk', self.handle_text_chunk) + self.sio.on('text_generated', self.handle_text_generated) + self.sio.on('active_personalities_list', self.handle_personalities_received) def handle_connect(self): - self.socketio.emit('connect') + self.sio.emit('connect') self.list_personalities() def connect_to_server(self): if not self.connected: try: - self.socketio.connect('http://localhost:9600') + self.sio.connect('http://localhost:9600') self.connected = True self.connection_status_changed.emit(True) except ConnectionError: @@ -43,12 +43,12 @@ class ServerConnector(QObject): def disconnect_from_server(self): if self.connected: - self.socketio.disconnect() + self.sio.disconnect() self.connected = False self.connection_status_changed.emit(False) def list_personalities(self): - self.socketio.emit('list_active_personalities') + self.sio.emit('list_active_personalities') @pyqtSlot(str) def generate_text(self, prompt): @@ -57,11 +57,11 @@ class ServerConnector(QObject): return data = { - 'client_id': self.socketio.sid, + 'client_id': self.sio.sid, 'prompt': prompt, 'personality': self.selected_personality_id } - self.socketio.emit('generate_text', data) + self.sio.emit('generate_text', data) def handle_personalities_list(self, data): personalities = data['personalities'] diff --git a/lollms/app.py b/lollms/app.py index 74ba258..1216330 100644 --- a/lollms/app.py +++ b/lollms/app.py @@ -13,7 +13,7 @@ from typing import Callable from pathlib import Path from datetime import datetime from functools import partial -from flask_socketio import SocketIO +from socketio import AsyncServer import subprocess import importlib import sys, os @@ -33,13 +33,13 @@ class LollmsApplication(LoLLMsCom): try_select_binding=False, try_select_model=False, callback=None, - socketio:SocketIO=None, + sio:AsyncServer=None, free_mode=False ) -> None: """ Creates a LOLLMS Application """ - super().__init__(socketio) + super().__init__(sio) self.app_name = app_name self.config = config self.lollms_paths = lollms_paths diff --git a/lollms/apps/server/__init__.py b/lollms/apps/server/__init__.py index 2761299..5af9350 100644 --- a/lollms/apps/server/__init__.py +++ b/lollms/apps/server/__init__.py @@ -255,21 +255,21 @@ class LoLLMsServer(LollmsApplication): ) - self.socketio = SocketIO(self.app, cors_allowed_origins='*', ping_timeout=1200, ping_interval=4000) + self.sio = SocketIO(self.app, cors_allowed_origins='*', ping_timeout=1200, ping_interval=4000) # Set log level to warning self.app.logger.setLevel(logging.WARNING) # Configure a custom logger for Flask-SocketIO - self.socketio_log = logging.getLogger('socketio') - self.socketio_log.setLevel(logging.WARNING) - self.socketio_log.addHandler(logging.StreamHandler()) + self.sio_log = logging.getLogger('socketio') + self.sio_log.setLevel(logging.WARNING) + self.sio_log.addHandler(logging.StreamHandler()) self.initialize_routes() self.run(self.config.host, self.config.port) def initialize_routes(self): - @self.socketio.on('connect') + @self.sio.on('connect') def handle_connect(): client_id = request.sid self.clients[client_id] = { @@ -280,7 +280,7 @@ class LoLLMsServer(LollmsApplication): } ASCIIColors.success(f'Client connected with session ID: {client_id}') - @self.socketio.on('disconnect') + @self.sio.on('disconnect') def handle_disconnect(): client_id = request.sid if client_id in self.clients: @@ -289,7 +289,7 @@ class LoLLMsServer(LollmsApplication): - @self.socketio.on('list_available_bindings') + @self.sio.on('list_available_bindings') def handle_list_bindings(): binding_infs = [] for p in self.bindings_path.iterdir(): @@ -307,7 +307,7 @@ class LoLLMsServer(LollmsApplication): emit('bindings_list', {'success':True, 'bindings': binding_infs}, room=request.sid) - @self.socketio.on('list_available_personalities') + @self.sio.on('list_available_personalities') def handle_list_available_personalities(): personalities_folder = self.personalities_path personalities = {} @@ -359,7 +359,7 @@ class LoLLMsServer(LollmsApplication): print(f"Couldn't load personality from {personality_folder} [{ex}]") emit('personalities_list', {'personalities': personalities}, room=request.sid) - @self.socketio.on('list_available_models') + @self.sio.on('list_available_models') def handle_list_available_models(): """List the available models @@ -408,7 +408,7 @@ class LoLLMsServer(LollmsApplication): emit('available_models_list', {'success':True, 'available_models': models}, room=request.sid) - @self.socketio.on('list_available_personalities_categories') + @self.sio.on('list_available_personalities_categories') def handle_list_available_personalities_categories(data): try: categories = [l for l in (self.personalities_path).iterdir()] @@ -416,7 +416,7 @@ class LoLLMsServer(LollmsApplication): except Exception as ex: emit('available_personalities_categories_list', {'success': False, 'error':str(ex)}) - @self.socketio.on('list_available_personalities_names') + @self.sio.on('list_available_personalities_names') def handle_list_available_personalities_names(data): try: category = data["category"] @@ -425,7 +425,7 @@ class LoLLMsServer(LollmsApplication): except Exception as ex: emit('list_available_personalities_names_list', {'success': False, 'error':str(ex)}) - @self.socketio.on('select_binding') + @self.sio.on('select_binding') def handle_select_binding(data): self.cp_config = copy.deepcopy(self.config) self.cp_config["binding_name"] = data['binding_name'] @@ -446,7 +446,7 @@ class LoLLMsServer(LollmsApplication): print(ex) emit('select_binding', {'success':False, 'binding_name': self.cp_config["binding_name"], 'error':f"Couldn't load binding:\n{ex}"}, room=request.sid) - @self.socketio.on('select_model') + @self.sio.on('select_model') def handle_select_model(data): model_name = data['model_name'] if self.binding is None: @@ -468,7 +468,7 @@ class LoLLMsServer(LollmsApplication): print(ex) emit('select_model', {'success':False, 'model_name': model_name, 'error':f"Please select a binding first"}, room=request.sid) - @self.socketio.on('add_personality') + @self.sio.on('add_personality') def handle_add_personality(data): personality_path = data['path'] try: @@ -489,7 +489,7 @@ class LoLLMsServer(LollmsApplication): - @self.socketio.on('vectorize_text') + @self.sio.on('vectorize_text') def vectorize_text(parameters:dict): """Vectorizes text @@ -535,7 +535,7 @@ class LoLLMsServer(LollmsApplication): json.dump(json_db, file, indent=4) - @self.socketio.on('query_database') + @self.sio.on('query_database') def query_database(parameters:dict): """queries a database @@ -578,12 +578,12 @@ class LoLLMsServer(LollmsApplication): }) - @self.socketio.on('list_active_personalities') + @self.sio.on('list_active_personalities') def handle_list_active_personalities(): personality_names = [p.name for p in self.personalities] emit('active_personalities_list', {'success':True, 'personalities': personality_names}, room=request.sid) - @self.socketio.on('activate_personality') + @self.sio.on('activate_personality') def handle_activate_personality(data): personality_id = data['id'] if personality_idLLMBinding: binding_path = Path(bindings_path) / cfg["binding_name"] @@ -813,7 +813,7 @@ class LoLLMsServer(LollmsApplication): print(f"{ASCIIColors.color_red}Current personality : {ASCIIColors.color_reset}{self.config.personalities[self.config.active_personality_id]}") ASCIIColors.info(f"Serving on address: http://{host}:{port}") - self.socketio.run(self.app, host=host, port=port) + self.sio.run(self.app, host=host, port=port) def main(): LoLLMsServer() diff --git a/lollms/binding.py b/lollms/binding.py index d4c0d17..ab9b747 100644 --- a/lollms/binding.py +++ b/lollms/binding.py @@ -24,8 +24,9 @@ from lollms.main_config import LOLLMSConfig from lollms.com import NotificationType, NotificationDisplayType, LoLLMsCom import urllib import inspect +from datetime import datetime from enum import Enum - +from lollms.utilities import trace_exception __author__ = "parisneo" __github__ = "https://github.com/ParisNeo/lollms_bindings_zoo" __copyright__ = "Copyright 2023, " @@ -70,6 +71,8 @@ class LLMBinding: self.lollmsCom = lollmsCom + self.download_infos={} + self.add_default_configurations(binding_config) self.interrogatorStorer = None @@ -100,7 +103,192 @@ class LLMBinding: self.configuration_file_path.parent.mkdir(parents=True, exist_ok=True) binding_config.config.file_path = self.configuration_file_path + def install_model(self, model_type:str, model_path:str, variant_name:str, client_id:int=None): + print("Install model triggered") + model_path = model_path.replace("\\","/") + if model_type.lower() in model_path.lower(): + model_type:str=model_type + else: + mtt = None + for mt in self.models_dir_names: + if mt.lower() in model_path.lower(): + mtt = mt + break + if mtt: + model_type = mtt + else: + model_type:str=self.models_dir_names[0] + + progress = 0 + installation_dir = self.searchModelParentFolder(model_path.split('/')[-1], model_type) + if model_type=="gptq" or model_type=="awq" or model_type=="transformers": + parts = model_path.split("/") + if len(parts)==2: + filename = parts[1] + else: + filename = parts[4] + installation_path = installation_dir / filename + elif model_type=="gpt4all": + filename = variant_name + model_path = "http://gpt4all.io/models/gguf/"+filename + installation_path = installation_dir / filename + else: + filename = Path(model_path).name + installation_path = installation_dir / filename + print("Model install requested") + print(f"Model path : {model_path}") + + model_name = filename + binding_folder = self.config["binding_name"] + model_url = model_path + signature = f"{model_name}_{binding_folder}_{model_url}" + try: + self.download_infos[signature]={ + "start_time":datetime.now(), + "total_size":self.get_file_size(model_path), + "downloaded_size":0, + "progress":0, + "speed":0, + "cancel":False + } + + if installation_path.exists(): + print("Error: Model already exists. please remove it first") + + self.lollmsCom.notify_model_install( + installation_path, + model_name, + binding_folder, + model_url, + self.download_infos[signature]['start_time'].strftime("%Y-%m-%d %H:%M:%S"), + self.download_infos[signature]['total_size'], + self.download_infos[signature]['downloaded_size'], + self.download_infos[signature]['progress'], + self.download_infos[signature]['speed'], + client_id, + status=True, + error="", + ) + + return + + + def callback(downloaded_size, total_size): + progress = (downloaded_size / total_size) * 100 + now = datetime.now() + dt = (now - self.download_infos[signature]['start_time']).total_seconds() + speed = downloaded_size/dt + self.download_infos[signature]['downloaded_size'] = downloaded_size + self.download_infos[signature]['speed'] = speed + + if progress - self.download_infos[signature]['progress']>2: + self.download_infos[signature]['progress'] = progress + self.lollmsCom.notify_model_install( + installation_path, + model_name, + binding_folder, + model_url, + self.download_infos[signature]['start_time'].strftime("%Y-%m-%d %H:%M:%S"), + self.download_infos[signature]['total_size'], + self.download_infos[signature]['downloaded_size'], + self.download_infos[signature]['progress'], + self.download_infos[signature]['speed'], + client_id, + status=True, + error="", + ) + + if self.download_infos[signature]["cancel"]: + raise Exception("canceled") + + + if hasattr(self, "download_model"): + try: + self.download_model(model_path, installation_path, callback) + except Exception as ex: + ASCIIColors.warning(str(ex)) + trace_exception(ex) + self.lollmsCom.notify_model_install( + installation_path, + model_name, + binding_folder, + model_url, + self.download_infos[signature]['start_time'].strftime("%Y-%m-%d %H:%M:%S"), + self.download_infos[signature]['total_size'], + self.download_infos[signature]['downloaded_size'], + self.download_infos[signature]['progress'], + self.download_infos[signature]['speed'], + client_id, + status=False, + error="Canceled", + ) + + del self.download_infos[signature] + try: + if installation_path.is_dir(): + shutil.rmtree(installation_path) + else: + installation_path.unlink() + except Exception as ex: + trace_exception(ex) + ASCIIColors.error(f"Couldn't delete file. Please try to remove it manually.\n{installation_path}") + return + + else: + try: + self.download_file(model_path, installation_path, callback) + except Exception as ex: + ASCIIColors.warning(str(ex)) + trace_exception(ex) + self.lollmsCom.notify_model_install( + installation_path, + model_name, + binding_folder, + model_url, + self.download_infos[signature]['start_time'].strftime("%Y-%m-%d %H:%M:%S"), + self.download_infos[signature]['total_size'], + self.download_infos[signature]['downloaded_size'], + self.download_infos[signature]['progress'], + self.download_infos[signature]['speed'], + client_id, + status=False, + error="Canceled", + ) + del self.download_infos[signature] + installation_path.unlink() + return + self.lollmsCom.notify_model_install( + installation_path, + model_name, + binding_folder, + model_url, + self.download_infos[signature]['start_time'].strftime("%Y-%m-%d %H:%M:%S"), + self.download_infos[signature]['total_size'], + self.download_infos[signature]['downloaded_size'], + self.download_infos[signature]['progress'], + self.download_infos[signature]['speed'], + client_id, + status=True, + error="", + ) + del self.download_infos[signature] + except Exception as ex: + trace_exception(ex) + self.lollmsCom.notify_model_install( + installation_path, + model_name, + binding_folder, + model_url, + '', + 0, + 0, + 0, + 0, + client_id, + status=False, + error=str(ex), + ) def add_default_configurations(self, binding_config:TypedConfig): binding_config.addConfigs([ diff --git a/lollms/com.py b/lollms/com.py index f584ddf..5c8438d 100644 --- a/lollms/com.py +++ b/lollms/com.py @@ -36,8 +36,8 @@ class NotificationDisplayType(Enum): class LoLLMsCom: - def __init__(self, socketio:socketio.AsyncServer=None) -> None: - self.socketio= socketio + def __init__(self, sio:socketio.AsyncServer=None) -> None: + self.sio= sio def InfoMessage(self, content, client_id=None, verbose:bool=True): @@ -76,7 +76,7 @@ class LoLLMsCom: "wait":True, "result":False } - @self.socketio.on('yesNoRes') + @self.sio.on('yesNoRes') def yesnores(result): infos["result"] = result["yesRes"] infos["wait"]=False @@ -92,7 +92,7 @@ class LoLLMsCom: # wait ASCIIColors.yellow("Waiting for yes no question to be answered") while infos["wait"]: - self.socketio.sleep(1) + self.sio.sleep(1) return infos["result"] def info(self, content, duration:int=4, client_id=None, verbose:bool=True): @@ -153,4 +153,21 @@ class LoLLMsCom: elif notification_type==NotificationType.NOTIF_WARNING: ASCIIColors.warning(content) else: - ASCIIColors.red(content) \ No newline at end of file + ASCIIColors.red(content) + + + def notify_model_install(self, + installation_path, + model_name, + binding_folder, + model_url, + start_time, + total_size, + downloaded_size, + progress, + speed, + client_id, + status=True, + error="", + ): + pass \ No newline at end of file diff --git a/lollms/media.py b/lollms/media.py index 9953f1d..89b932d 100644 --- a/lollms/media.py +++ b/lollms/media.py @@ -152,7 +152,7 @@ class WebcamImageSender: Args: socketio (socketio.Client): The SocketIO client object. """ - self.socketio = sio + self.sio = sio self.last_image = None self.last_change_time = None self.capture_thread = None @@ -191,7 +191,7 @@ class WebcamImageSender: _, buffer = cv2.imencode('.jpg', frame) image_base64 = base64.b64encode(buffer) - run_async(partial(self.socketio.emit,"video_stream_image", image_base64.decode('utf-8'))) + run_async(partial(self.sio.emit,"video_stream_image", image_base64.decode('utf-8'))) cap.release() except Exception as ex: diff --git a/lollms/server/elf_server.py b/lollms/server/elf_server.py index 7a24a0f..ef4074f 100644 --- a/lollms/server/elf_server.py +++ b/lollms/server/elf_server.py @@ -12,6 +12,8 @@ from lollms.paths import LollmsPaths from lollms.personality import AIPersonality from pathlib import Path from socketio import AsyncServer +from functools import partial +from lollms.utilities import trace_exception, run_async class LOLLMSElfServer(LollmsApplication): __instance = None @@ -27,7 +29,7 @@ class LOLLMSElfServer(LollmsApplication): try_select_binding=False, try_select_model=False, callback=None, - socketio:AsyncServer = None + sio:AsyncServer = None ): if LOLLMSElfServer.__instance is None: LOLLMSElfServer( @@ -40,7 +42,7 @@ class LOLLMSElfServer(LollmsApplication): try_select_binding=try_select_binding, try_select_model=try_select_model, callback=callback, - socketio=socketio + sio=sio ) return LOLLMSElfServer.__instance @staticmethod @@ -58,7 +60,7 @@ class LOLLMSElfServer(LollmsApplication): try_select_binding=False, try_select_model=False, callback=None, - socketio:AsyncServer=None + sio:AsyncServer=None ) -> None: super().__init__( "LOLLMSElfServer", @@ -71,7 +73,7 @@ class LOLLMSElfServer(LollmsApplication): try_select_binding=try_select_binding, try_select_model=try_select_model, callback=callback, - socketio=socketio + sio=sio ) if LOLLMSElfServer.__instance is not None: raise Exception("This class is a singleton!") @@ -85,3 +87,33 @@ class LOLLMSElfServer(LollmsApplication): if full_path.exists(): return full_path return None + + + def notify_model_install(self, + installation_path, + model_name, + binding_folder, + model_url, + start_time, + total_size, + downloaded_size, + progress, + speed, + client_id, + status=True, + error="", + ): + run_async( partial(self.sio.emit,'install_progress',{ + 'status': status, + 'error': error, + 'model_name' : model_name, + 'binding_folder' : binding_folder, + 'model_url' : model_url, + 'start_time': start_time, + 'total_size': total_size, + 'downloaded_size': downloaded_size, + 'progress': progress, + 'speed': speed, + }, room=client_id + ) + ) diff --git a/lollms/server/endpoints/lollms_binding_infos.py b/lollms/server/endpoints/lollms_binding_infos.py index b795cdf..3cd7cfa 100644 --- a/lollms/server/endpoints/lollms_binding_infos.py +++ b/lollms/server/endpoints/lollms_binding_infos.py @@ -17,7 +17,7 @@ from lollms.utilities import load_config, trace_exception, gc from pathlib import Path from typing import List import json - +import os # ----------------------------------- Personal files ----------------------------------------- class ReloadBindingParams(BaseModel): binding_name: str diff --git a/lollms/server/endpoints/lollms_configuration_infos.py b/lollms/server/endpoints/lollms_configuration_infos.py index dc4b28e..84ac528 100644 --- a/lollms/server/endpoints/lollms_configuration_infos.py +++ b/lollms/server/endpoints/lollms_configuration_infos.py @@ -162,5 +162,5 @@ def save_settings(): if lollmsElfServer.config["debug"]: print("Configuration saved") # Tell that the setting was changed - lollmsElfServer.socketio.emit('save_settings', {"status":True}) + lollmsElfServer.sio.emit('save_settings', {"status":True}) return {"status":True} \ No newline at end of file diff --git a/lollms/server/endpoints/lollms_models_infos.py b/lollms/server/endpoints/lollms_models_infos.py index ed27a89..ca9f00d 100644 --- a/lollms/server/endpoints/lollms_models_infos.py +++ b/lollms/server/endpoints/lollms_models_infos.py @@ -17,7 +17,7 @@ from pathlib import Path from typing import List import psutil - +from lollms.utilities import trace_exception class ModelReferenceParams(BaseModel): path: str @@ -60,6 +60,7 @@ async def get_available_models(): try: model_list = lollmsElfServer.binding.get_available_models(lollmsElfServer) except Exception as ex: + trace_exception(ex) lollmsElfServer.error("Coudln't list models. Please reinstall the binding or notify ParisNeo on the discord server") return [] diff --git a/lollms/server/events/lollms_generation_events.py b/lollms/server/events/lollms_generation_events.py index f4981ce..3547095 100644 --- a/lollms/server/events/lollms_generation_events.py +++ b/lollms/server/events/lollms_generation_events.py @@ -44,7 +44,7 @@ def add_events(sio:socketio): client_id = sid lollmsElfServer.connections[client_id]["requested_stop"]=True print(f"Client {client_id} requested canceling generation") - run_async(partial(lollmsElfServer.socketio.emit,"generation_canceled", {"message":"Generation is canceled."}, to=client_id)) + run_async(partial(lollmsElfServer.sio.emit,"generation_canceled", {"message":"Generation is canceled."}, to=client_id)) lollmsElfServer.busy = False @@ -55,7 +55,7 @@ def add_events(sio:socketio): lollmsElfServer.cancel_gen = False ASCIIColors.info(f"Text generation requested by client: {client_id}") if lollmsElfServer.busy: - run_async(partial(lollmsElfServer.socketio.emit,"busy", {"message":"I am busy. Come back later."}, to=client_id)) + run_async(partial(lollmsElfServer.sio.emit,"busy", {"message":"I am busy. Come back later."}, to=client_id)) ASCIIColors.warning(f"OOps request {client_id} refused!! Server busy") return lollmsElfServer.busy = True @@ -89,7 +89,7 @@ def add_events(sio:socketio): ASCIIColors.success(f"generated:{len(lollmsElfServer.answer['full_text'].split())} words", end='\r') if text is not None: lollmsElfServer.answer["full_text"] = lollmsElfServer.answer["full_text"] + text - run_async(partial(lollmsElfServer.socketio.emit,'text_chunk', {'chunk': text, 'type':MSG_TYPE.MSG_TYPE_CHUNK.value}, to=client_id)) + run_async(partial(lollmsElfServer.sio.emit,'text_chunk', {'chunk': text, 'type':MSG_TYPE.MSG_TYPE_CHUNK.value}, to=client_id)) if client_id in lollmsElfServer.connections:# Client disconnected if lollmsElfServer.connections[client_id]["requested_stop"]: return False @@ -120,9 +120,9 @@ def add_events(sio:socketio): if client_id in lollmsElfServer.connections: if not lollmsElfServer.connections[client_id]["requested_stop"]: # Emit the generated text to the client - run_async(partial(lollmsElfServer.socketio.emit,'text_generated', {'text': generated_text}, to=client_id)) + run_async(partial(lollmsElfServer.sio.emit,'text_generated', {'text': generated_text}, to=client_id)) except Exception as ex: - run_async(partial(lollmsElfServer.socketio.emit,'generation_error', {'error': str(ex)}, to=client_id)) + run_async(partial(lollmsElfServer.sio.emit,'generation_error', {'error': str(ex)}, to=client_id)) ASCIIColors.error(f"\ndone") lollmsElfServer.busy = False else: @@ -161,7 +161,7 @@ def add_events(sio:socketio): def callback(text, message_type: MSG_TYPE, metadata:dict={}): if message_type == MSG_TYPE.MSG_TYPE_CHUNK: lollmsElfServer.answer["full_text"] = lollmsElfServer.answer["full_text"] + text - run_async(partial(lollmsElfServer.socketio.emit,'text_chunk', {'chunk': text}, to=client_id)) + run_async(partial(lollmsElfServer.sio.emit,'text_chunk', {'chunk': text}, to=client_id)) try: if lollmsElfServer.connections[client_id]["requested_stop"]: return False @@ -191,14 +191,14 @@ def add_events(sio:socketio): ASCIIColors.success("\ndone") # Emit the generated text to the client - run_async(partial(lollmsElfServer.socketio.emit,'text_generated', {'text': generated_text}, to=client_id)) + run_async(partial(lollmsElfServer.sio.emit,'text_generated', {'text': generated_text}, to=client_id)) except Exception as ex: - run_async(partial(lollmsElfServer.socketio.emit,'generation_error', {'error': str(ex)}, to=client_id)) + run_async(partial(lollmsElfServer.sio.emit,'generation_error', {'error': str(ex)}, to=client_id)) ASCIIColors.error(f"\ndone") lollmsElfServer.busy = False except Exception as ex: trace_exception(ex) - run_async(partial(lollmsElfServer.socketio.emit,'generation_error', {'error': str(ex)}, to=client_id)) + run_async(partial(lollmsElfServer.sio.emit,'generation_error', {'error': str(ex)}, to=client_id)) lollmsElfServer.busy = False @@ -242,7 +242,7 @@ def add_events(sio:socketio): lollmsElfServer.connections[client_id]['generation_thread'] = threading.Thread(target=lollmsElfServer.start_message_generation, args=(message, message.id, client_id)) lollmsElfServer.connections[client_id]['generation_thread'].start() - lollmsElfServer.socketio.sleep(0.01) + lollmsElfServer.sio.sleep(0.01) ASCIIColors.info("Started generation task") lollmsElfServer.busy=True #tpe = threading.Thread(target=lollmsElfServer.start_message_generation, args=(message, message_id, client_id)) diff --git a/lollms/server/events/lollms_model_events.py b/lollms/server/events/lollms_model_events.py index c1602f0..2bc1445 100644 --- a/lollms/server/events/lollms_model_events.py +++ b/lollms/server/events/lollms_model_events.py @@ -32,202 +32,8 @@ lollmsElfServer = LOLLMSElfServer.get_instance() def add_events(sio:socketio): @sio.on('install_model') def install_model(sid, data): - room_id = sid - def install_model_(): - print("Install model triggered") - model_path = data["path"].replace("\\","/") - - if data["type"].lower() in model_path.lower(): - model_type:str=data["type"] - else: - mtt = None - for mt in lollmsElfServer.binding.models_dir_names: - if mt.lower() in model_path.lower(): - mtt = mt - break - if mtt: - model_type = mtt - else: - model_type:str=lollmsElfServer.binding.models_dir_names[0] - - progress = 0 - installation_dir = lollmsElfServer.binding.searchModelParentFolder(model_path.split('/')[-1], model_type) - if model_type=="gptq" or model_type=="awq" or model_type=="transformers": - parts = model_path.split("/") - if len(parts)==2: - filename = parts[1] - else: - filename = parts[4] - installation_path = installation_dir / filename - elif model_type=="gpt4all": - filename = data["variant_name"] - model_path = "http://gpt4all.io/models/gguf/"+filename - installation_path = installation_dir / filename - else: - filename = Path(model_path).name - installation_path = installation_dir / filename - print("Model install requested") - print(f"Model path : {model_path}") - - model_name = filename - binding_folder = lollmsElfServer.config["binding_name"] - model_url = model_path - signature = f"{model_name}_{binding_folder}_{model_url}" - try: - lollmsElfServer.download_infos[signature]={ - "start_time":datetime.now(), - "total_size":lollmsElfServer.binding.get_file_size(model_path), - "downloaded_size":0, - "progress":0, - "speed":0, - "cancel":False - } - - if installation_path.exists(): - print("Error: Model already exists. please remove it first") - run_async( partial(sio.emit,'install_progress',{ - 'status': False, - 'error': f'model already exists. Please remove it first.\nThe model can be found here:{installation_path}', - 'model_name' : model_name, - 'binding_folder' : binding_folder, - 'model_url' : model_url, - 'start_time': lollmsElfServer.download_infos[signature]['start_time'].strftime("%Y-%m-%d %H:%M:%S"), - 'total_size': lollmsElfServer.download_infos[signature]['total_size'], - 'downloaded_size': lollmsElfServer.download_infos[signature]['downloaded_size'], - 'progress': lollmsElfServer.download_infos[signature]['progress'], - 'speed': lollmsElfServer.download_infos[signature]['speed'], - }, room=room_id - ) - ) - return - - run_async( partial(sio.emit,'install_progress',{ - 'status': True, - 'progress': progress, - 'model_name' : model_name, - 'binding_folder' : binding_folder, - 'model_url' : model_url, - 'start_time': lollmsElfServer.download_infos[signature]['start_time'].strftime("%Y-%m-%d %H:%M:%S"), - 'total_size': lollmsElfServer.download_infos[signature]['total_size'], - 'downloaded_size': lollmsElfServer.download_infos[signature]['downloaded_size'], - 'progress': lollmsElfServer.download_infos[signature]['progress'], - 'speed': lollmsElfServer.download_infos[signature]['speed'], - - }, room=room_id) - ) - - def callback(downloaded_size, total_size): - progress = (downloaded_size / total_size) * 100 - now = datetime.now() - dt = (now - lollmsElfServer.download_infos[signature]['start_time']).total_seconds() - speed = downloaded_size/dt - lollmsElfServer.download_infos[signature]['downloaded_size'] = downloaded_size - lollmsElfServer.download_infos[signature]['speed'] = speed - - if progress - lollmsElfServer.download_infos[signature]['progress']>2: - lollmsElfServer.download_infos[signature]['progress'] = progress - run_async( partial(sio.emit,'install_progress',{ - 'status': True, - 'model_name' : model_name, - 'binding_folder' : binding_folder, - 'model_url' : model_url, - 'start_time': lollmsElfServer.download_infos[signature]['start_time'].strftime("%Y-%m-%d %H:%M:%S"), - 'total_size': lollmsElfServer.download_infos[signature]['total_size'], - 'downloaded_size': lollmsElfServer.download_infos[signature]['downloaded_size'], - 'progress': lollmsElfServer.download_infos[signature]['progress'], - 'speed': lollmsElfServer.download_infos[signature]['speed'], - }, room=room_id) - ) - - if lollmsElfServer.download_infos[signature]["cancel"]: - raise Exception("canceled") - - - if hasattr(lollmsElfServer.binding, "download_model"): - try: - lollmsElfServer.binding.download_model(model_path, installation_path, callback) - except Exception as ex: - ASCIIColors.warning(str(ex)) - trace_exception(ex) - run_async( partial(sio.emit,'install_progress',{ - 'status': False, - 'error': 'canceled', - 'model_name' : model_name, - 'binding_folder' : binding_folder, - 'model_url' : model_url, - 'start_time': lollmsElfServer.download_infos[signature]['start_time'].strftime("%Y-%m-%d %H:%M:%S"), - 'total_size': lollmsElfServer.download_infos[signature]['total_size'], - 'downloaded_size': lollmsElfServer.download_infos[signature]['downloaded_size'], - 'progress': lollmsElfServer.download_infos[signature]['progress'], - 'speed': lollmsElfServer.download_infos[signature]['speed'], - }, room=room_id - ) - ) - del lollmsElfServer.download_infos[signature] - try: - if installation_path.is_dir(): - shutil.rmtree(installation_path) - else: - installation_path.unlink() - except Exception as ex: - trace_exception(ex) - ASCIIColors.error(f"Couldn't delete file. Please try to remove it manually.\n{installation_path}") - return - - else: - try: - lollmsElfServer.download_file(model_path, installation_path, callback) - except Exception as ex: - ASCIIColors.warning(str(ex)) - trace_exception(ex) - run_async( partial(sio.emit,'install_progress',{ - 'status': False, - 'error': 'canceled', - 'model_name' : model_name, - 'binding_folder' : binding_folder, - 'model_url' : model_url, - 'start_time': lollmsElfServer.download_infos[signature]['start_time'].strftime("%Y-%m-%d %H:%M:%S"), - 'total_size': lollmsElfServer.download_infos[signature]['total_size'], - 'downloaded_size': lollmsElfServer.download_infos[signature]['downloaded_size'], - 'progress': lollmsElfServer.download_infos[signature]['progress'], - 'speed': lollmsElfServer.download_infos[signature]['speed'], - }, room=room_id - ) - ) - del lollmsElfServer.download_infos[signature] - installation_path.unlink() - return - run_async( partial(sio.emit,'install_progress',{ - 'status': True, - 'error': '', - 'model_name' : model_name, - 'binding_folder' : binding_folder, - 'model_url' : model_url, - 'start_time': lollmsElfServer.download_infos[signature]['start_time'].strftime("%Y-%m-%d %H:%M:%S"), - 'total_size': lollmsElfServer.download_infos[signature]['total_size'], - 'downloaded_size': lollmsElfServer.download_infos[signature]['downloaded_size'], - 'progress': 100, - 'speed': lollmsElfServer.download_infos[signature]['speed'], - }, room=room_id) - ) - del lollmsElfServer.download_infos[signature] - except Exception as ex: - trace_exception(ex) - run_async( partial(sio.emit,'install_progress',{ - 'status': False, - 'error': str(ex), - 'model_name' : model_name, - 'binding_folder' : binding_folder, - 'model_url' : model_url, - 'start_time': '', - 'total_size': 0, - 'downloaded_size': 0, - 'progress': 0, - 'speed': 0, - }, room=room_id - ) - ) - tpe = threading.Thread(target=install_model_, args=()) + client_id = sid + tpe = threading.Thread(target=lollmsElfServer.binding.install_model, args=(data["type"], data["path"], data["variant_name"], client_id)) tpe.start() @sio.on('uninstall_model') @@ -302,9 +108,10 @@ def add_events(sio:socketio): ) except Exception as ex: trace_exception(ex) - sio.emit('canceled', { + run_async( partial(sio.emit,'canceled', { 'status': False, 'error':str(ex) }, room=sid - ) + ) + ) diff --git a/lollms/server/events/lollms_rag_events.py b/lollms/server/events/lollms_rag_events.py index 2154c4f..7278f1a 100644 --- a/lollms/server/events/lollms_rag_events.py +++ b/lollms/server/events/lollms_rag_events.py @@ -36,7 +36,7 @@ def add_events(sio:socketio): if lollmsElfServer.config.data_vectorization_activate and lollmsElfServer.config.use_discussions_history: try: run_async(partial(sio.emit,'show_progress')) - lollmsElfServer.socketio.sleep(0) + lollmsElfServer.sio.sleep(0) ASCIIColors.yellow("0- Detected discussion vectorization request") folder = lollmsElfServer.lollms_paths.personal_databases_path/"vectorized_dbs" folder.mkdir(parents=True, exist_ok=True) @@ -49,7 +49,7 @@ def add_events(sio:socketio): nb_discussions = len(discussions) for (title,discussion) in tqdm(discussions): run_async(partial(sio.emit,'update_progress',{'value':int(100*(index/nb_discussions))})) - lollmsElfServer.socketio.sleep(0) + lollmsElfServer.sio.sleep(0) index += 1 if discussion!='': skill = lollmsElfServer.learn_from_discussion(title, discussion) @@ -65,4 +65,4 @@ def add_events(sio:socketio): except Exception as ex: ASCIIColors.error(f"Couldn't vectorize database:{ex}") run_async(partial(sio.emit,'hide_progress')) - lollmsElfServer.socketio.sleep(0) \ No newline at end of file + lollmsElfServer.sio.sleep(0) \ No newline at end of file diff --git a/lollms/services/ollama/lollms_ollama.py b/lollms/services/ollama/lollms_ollama.py index b30adba..b84fbd1 100644 --- a/lollms/services/ollama/lollms_ollama.py +++ b/lollms/services/ollama/lollms_ollama.py @@ -7,7 +7,6 @@ # All rights are reserved from pathlib import Path -import os import sys from lollms.app import LollmsApplication from lollms.paths import LollmsPaths diff --git a/lollms/services/ollama/run_ollama.sh b/lollms/services/ollama/run_ollama.sh index 90169b4..3548e09 100644 --- a/lollms/services/ollama/run_ollama.sh +++ b/lollms/services/ollama/run_ollama.sh @@ -8,18 +8,5 @@ OLLAMA_HOST="0.0.0.0:11434" # Start the OLLAMA server OLLAMA_MODELS=~/ollama/models ollama serve & -# Check if models.txt exists -if [ ! -f models.txt ]; then - # Create models.txt and add "mixtral" to it - echo "mistral" > ~/models.txt -fi - -# Read the models from the file -while IFS= read -r model -do - # Run each model in the background - ollama run "$model" & -done < ~/models.txt - # Wait for all background processes to finish wait diff --git a/lollms/services/sd/lollms_sd.py b/lollms/services/sd/lollms_sd.py index 6228609..e568615 100644 --- a/lollms/services/sd/lollms_sd.py +++ b/lollms/services/sd/lollms_sd.py @@ -7,7 +7,6 @@ # All rights are reserved from pathlib import Path -import os import sys from lollms.app import LollmsApplication from lollms.paths import LollmsPaths diff --git a/lollms/services/xtts/lollms_xtts.py b/lollms/services/xtts/lollms_xtts.py index c418579..30b1f64 100644 --- a/lollms/services/xtts/lollms_xtts.py +++ b/lollms/services/xtts/lollms_xtts.py @@ -7,7 +7,6 @@ # All rights are reserved from pathlib import Path -import os import sys from lollms.app import LollmsApplication from lollms.paths import LollmsPaths