added few needed stuff

This commit is contained in:
Saifeddine ALOUI 2024-02-27 17:06:04 +01:00
parent 11f823bb8a
commit 487aa45ce2
6 changed files with 165 additions and 118 deletions

View File

@ -1,5 +1,5 @@
# =================== Lord Of Large Language Multimodal Systems Configuration file ===========================
version: 73
version: 74
binding_name: null
model_name: null
model_variant: null
@ -85,6 +85,10 @@ current_language: en
enable_sd_service: false
sd_base_url: http://localhost:7860
# Motion control service
enable_motion_ctrl_service: false
motion_ctrl_base_url: http://localhost:7861
# ollama service
enable_ollama_service: false
ollama_base_url: http://localhost:11434

View File

@ -163,6 +163,15 @@ class LollmsApplication(LoLLMsCom):
except:
self.warning(f"Couldn't load SD")
if self.config.enable_motion_ctrl_service:
try:
from lollms.services.motion_ctrl.lollms_motion_ctrl import Service
self.motion_ctrl = Service(self, base_url=self.config.motion_ctrl_base_url)
except Exception as ex:
trace_exception(ex)
self.warning(f"Couldn't load Motion control")
def build_long_term_skills_memory(self):
discussion_db_name:Path = self.lollms_paths.personal_discussions_path/self.config.discussion_db_name.split(".")[0]
discussion_db_name.mkdir(exist_ok=True, parents=True)

View File

@ -1,5 +1,5 @@
# =================== Lord Of Large Language Multimodal Systems Configuration file ===========================
version: 73
version: 74
binding_name: null
model_name: null
model_variant: null
@ -85,6 +85,10 @@ current_language: en
enable_sd_service: false
sd_base_url: http://localhost:7860
# Motion control service
enable_motion_ctrl_service: false
motion_ctrl_base_url: http://localhost:7861
# ollama service
enable_ollama_service: false
ollama_base_url: http://localhost:11434

View File

@ -126,6 +126,7 @@ class AIPersonality:
self.text_files = []
self.image_files = []
self.audio_files = []
self.images_descriptions = []
self.vectorizer = None
@ -928,68 +929,69 @@ class AIPersonality:
self.vectorizer = None
return True
def add_file(self, path, client:Client, callback=None):
def add_file(self, path, client:Client, callback=None, process=True):
output = ""
if not self.callback:
self.callback = callback
path = Path(path)
if path.suffix in [".wav",".mp3"]:
self.new_message("")
self.info(f"Transcribing ... ")
self.step_start("Transcribing ... ")
if self.whisper is None:
if not PackageManager.check_package_installed("whisper"):
PackageManager.install_package("openai-whisper")
try:
import conda.cli
conda.cli.main("install", "conda-forge::ffmpeg", "-y")
except:
ASCIIColors.bright_red("Couldn't install ffmpeg. whisper won't work. Please install it manually")
self.audio_files.append(path)
if process:
self.new_message("")
self.info(f"Transcribing ... ")
self.step_start("Transcribing ... ")
if self.whisper is None:
if not PackageManager.check_package_installed("whisper"):
PackageManager.install_package("openai-whisper")
try:
import conda.cli
conda.cli.main("install", "conda-forge::ffmpeg", "-y")
except:
ASCIIColors.bright_red("Couldn't install ffmpeg. whisper won't work. Please install it manually")
import whisper
self.whisper = whisper.load_model("base")
import whisper
self.whisper = whisper.load_model("base")
result = self.whisper.transcribe(str(path))
transcription_fn = str(path)+".txt"
with open(transcription_fn, "w", encoding="utf-8") as f:
f.write(result["text"])
result = self.whisper.transcribe(str(path))
transcription_fn = str(path)+".txt"
with open(transcription_fn, "w", encoding="utf-8") as f:
f.write(result["text"])
self.info(f"File saved to {transcription_fn}")
self.full(result["text"])
self.step_end("Transcribing ... ")
self.info(f"File saved to {transcription_fn}")
self.full(result["text"])
self.step_end("Transcribing ... ")
elif path.suffix in [".png",".jpg",".jpeg",".gif",".bmp",".svg",".webp"]:
if self.callback:
try:
pth = str(path).replace("\\","/").split('/')
if "discussion_databases" in pth:
pth = discussion_path_to_url(path)
self.new_message("",MSG_TYPE.MSG_TYPE_FULL)
output = f'<img src="{pth}" width="800">\n\n'
self.full(output)
if self.model.binding_type not in [BindingType.TEXT_IMAGE, BindingType.TEXT_IMAGE_VIDEO]:
# self.ShowBlockingMessage("Understanding image (please wait)")
from PIL import Image
img = Image.open(str(path))
# Convert the image to RGB mode
img = img.convert("RGB")
output += "## image description :\n"+ self.model.interrogate_blip([img])[0]
# output += "## image description :\n"+ self.model.qna_blip([img],"q:Describe this photo with as much details as possible.\na:")[0]
self.full(output)
self.HideBlockingMessage("Understanding image (please wait)")
if self.config.debug:
ASCIIColors.yellow(output)
else:
# self.ShowBlockingMessage("Importing image (please wait)")
self.HideBlockingMessage("Importing image (please wait)")
except Exception as ex:
trace_exception(ex)
self.HideBlockingMessage("Understanding image (please wait)", False)
ASCIIColors.error("Couldn't create new message")
self.image_files.append(path)
if process:
if self.callback:
try:
pth = str(path).replace("\\","/").split('/')
if "discussion_databases" in pth:
pth = discussion_path_to_url(path)
self.new_message("",MSG_TYPE.MSG_TYPE_FULL)
output = f'<img src="{pth}" width="800">\n\n'
self.full(output)
if self.model.binding_type not in [BindingType.TEXT_IMAGE, BindingType.TEXT_IMAGE_VIDEO]:
# self.ShowBlockingMessage("Understanding image (please wait)")
from PIL import Image
img = Image.open(str(path))
# Convert the image to RGB mode
img = img.convert("RGB")
output += "## image description :\n"+ self.model.interrogate_blip([img])[0]
# output += "## image description :\n"+ self.model.qna_blip([img],"q:Describe this photo with as much details as possible.\na:")[0]
self.full(output)
self.HideBlockingMessage("Understanding image (please wait)")
if self.config.debug:
ASCIIColors.yellow(output)
else:
# self.ShowBlockingMessage("Importing image (please wait)")
self.HideBlockingMessage("Importing image (please wait)")
except Exception as ex:
trace_exception(ex)
self.HideBlockingMessage("Understanding image (please wait)", False)
ASCIIColors.error("Couldn't create new message")
ASCIIColors.info("Received image file")
if callback is not None:
callback("Image file added successfully", MSG_TYPE.MSG_TYPE_INFO)
@ -998,21 +1000,22 @@ class AIPersonality:
# self.ShowBlockingMessage("Adding file to vector store.\nPlease stand by")
self.text_files.append(path)
ASCIIColors.info("Received text compatible file")
if self.vectorizer is None:
self.vectorizer = TextVectorizer(
self.config.data_vectorization_method, # supported "model_embedding" or "tfidf_vectorizer"
model=self.model, #needed in case of using model_embedding
database_path=client.discussion.discussion_rag_folder/"db.json",
save_db=self.config.data_vectorization_save_db,
data_visualization_method=VisualizationMethod.PCA,
database_dict=None)
data = GenericDataLoader.read_file(path)
self.vectorizer.add_document(path, data, self.config.data_vectorization_chunk_size, self.config.data_vectorization_overlap_size, add_first_line_to_all_chunks=True if path.suffix==".csv" else False)
self.vectorizer.index()
if callback is not None:
callback("File added successfully",MSG_TYPE.MSG_TYPE_INFO)
self.HideBlockingMessage("Adding file to vector store.\nPlease stand by")
return True
if process:
if self.vectorizer is None:
self.vectorizer = TextVectorizer(
self.config.data_vectorization_method, # supported "model_embedding" or "tfidf_vectorizer"
model=self.model, #needed in case of using model_embedding
database_path=client.discussion.discussion_rag_folder/"db.json",
save_db=self.config.data_vectorization_save_db,
data_visualization_method=VisualizationMethod.PCA,
database_dict=None)
data = GenericDataLoader.read_file(path)
self.vectorizer.add_document(path, data, self.config.data_vectorization_chunk_size, self.config.data_vectorization_overlap_size, add_first_line_to_all_chunks=True if path.suffix==".csv" else False)
self.vectorizer.index()
if callback is not None:
callback("File added successfully",MSG_TYPE.MSG_TYPE_INFO)
self.HideBlockingMessage("Adding file to vector store.\nPlease stand by")
return True
except Exception as e:
trace_exception(e)
self.HideBlockingMessage("Adding file to vector store.\nPlease stand by")
@ -1950,10 +1953,10 @@ class APScript(StateMachine):
ASCIIColors.blue("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*")
def add_file(self, path, client:Client, callback=None):
def add_file(self, path, client:Client, callback=None, process=True):
self.personality.add_file(path, client=client,callback=callback, process=process)
if callback is not None:
callback("File added successfully",MSG_TYPE.MSG_TYPE_INFO)
self.personality.add_file(path, client=client,callback=callback)
return True
def remove_file(self, path):

View File

@ -20,4 +20,15 @@ from typing import List
from safe_store.text_vectorizer import TextVectorizer, VectorizationMethod, VisualizationMethod
import tqdm
from pathlib import Path
# ----------------------- Defining router and main class ------------------------------
router = APIRouter()
lollmsElfServer:LOLLMSWebUI = LOLLMSWebUI.get_instance()
class DiscussionInfos(BaseModel):
client_id: str
@router.get("/add_discussion_to_skills_library")
def add_discussion_to_skills_library(discussionInfos:DiscussionInfos):
client = lollmsElfServer.session.get_client(discussionInfos.client_id)
lollmsElfServer.add_discussion_tto_skills_library(client)

View File

@ -31,7 +31,7 @@ from ascii_colors import ASCIIColors, trace_exception
from lollms.paths import LollmsPaths
from lollms.utilities import git_pull
import subprocess
import shutil
@ -44,6 +44,8 @@ def verify_motion_ctrl(lollms_paths:LollmsPaths):
return motion_ctrl_folder.exists()
def install_motion_ctrl(lollms_app:LollmsApplication):
import conda.cli
root_dir = lollms_app.lollms_paths.personal_path
shared_folder = root_dir/"shared"
motion_ctrl_folder = shared_folder / "auto_motion_ctrl"
@ -51,9 +53,17 @@ def install_motion_ctrl(lollms_app:LollmsApplication):
if not show_yes_no_dialog("warning!","I have detected that there is a previous installation of motion ctrl.\nShould I remove it and continue installing?"):
return
else:
motion_ctrl_folder.unlink(True)
try:
shutil.rmtree(motion_ctrl_folder)
except Exception as ex:
trace_exception(ex)
try:
conda.cli.main('conda', 'remove', '--name', env_name, '--all', '--yes')
except Exception as ex:
trace_exception(ex)
subprocess.run(["git", "clone", "https://github.com/ParisNeo/MotionCtrl.git", str(motion_ctrl_folder)])
import conda.cli
env_name = "MotionCtrl"
conda.cli.main('conda', 'create', '--name', env_name, 'python=3.10', '--yes')
@ -62,7 +72,7 @@ def install_motion_ctrl(lollms_app:LollmsApplication):
pip_install_command = "pip install -r " + str(motion_ctrl_folder) + "/requirements.txt"
# Run the combined command
subprocess.run(activate_env_command + pip_install_command, shell=True, executable='/bin/bash')
subprocess.run(activate_env_command + pip_install_command, shell=True)
#pip install -r requirements.txt
ASCIIColors.green("Motion ctrl installed successfully")
@ -83,78 +93,68 @@ def get_motion_ctrl(lollms_paths:LollmsPaths):
return LollmsMotionCtrl
class LollmsMotionCtrl:
class Service:
has_controlnet = False
def __init__(
self,
app:LollmsApplication,
wm = "Artbot",
max_retries=50,
sampler="Euler a",
steps=20,
use_https=False,
username=None,
password=None,
auto_motion_ctrl_base_url=None,
base_url=None,
share=False,
wait_for_service=True
wait_for_service=True,
max_retries=5
):
if auto_motion_ctrl_base_url=="" or auto_motion_ctrl_base_url=="http://127.0.0.1:7860":
auto_motion_ctrl_base_url = None
if base_url=="" or base_url=="http://127.0.0.1:7861":
base_url = None
# Get the current directory
lollms_paths = app.lollms_paths
self.app = app
root_dir = lollms_paths.personal_path
self.wm = wm
# Store the path to the script
if auto_motion_ctrl_base_url is None:
self.auto_motion_ctrl_base_url = "http://127.0.0.1:7860"
if base_url is None:
self.base_url = "http://127.0.0.1:7860"
if not verify_motion_ctrl(lollms_paths):
install_motion_ctrl(app.lollms_paths)
else:
self.auto_motion_ctrl_base_url = auto_motion_ctrl_base_url
self.base_url = base_url
self.auto_motion_ctrl_url = self.auto_motion_ctrl_base_url+"/sdapi/v1"
self.auto_motion_ctrl_url = self.base_url+"/sdapi/v1"
shared_folder = root_dir/"shared"
self.motion_ctrl_folder = shared_folder / "motion_ctrl"
self.output_dir = root_dir / "outputs/motion_ctrl"
self.output_dir.mkdir(parents=True, exist_ok=True)
ASCIIColors.red(" ")
ASCIIColors.red(" __ _____ __ __ _____ _____ _____ ____ ")
ASCIIColors.red("| | | | | | | | | __| | __| \ ")
ASCIIColors.red("| |__| | | |__| |__| | | |__ | |__ | | |")
ASCIIColors.red("|_____|_____|_____|_____|_|_|_|_____|_____|_____|____/ ")
ASCIIColors.red(" |_____| ")
ASCIIColors.red(" ")
ASCIIColors.red("_ _ _ _ _ _ _ ")
ASCIIColors.red("| | | | | | | (_) | | | |")
ASCIIColors.red("| | ___ | | |_ __ ___ ___ _ __ ___ ___ | |_ _ ___ _ __ ___| |_ _ __| |")
ASCIIColors.red("| |/ _ \| | | '_ ` _ \/ __| | '_ ` _ \ / _ \| __| |/ _ \| '_ \ / __| __| '__| |")
ASCIIColors.red("| | (_) | | | | | | | \__ \ | | | | | | (_) | |_| | (_) | | | || (__| |_| | | |")
ASCIIColors.red("|_|\___/|_|_|_| |_| |_|___/ |_| |_| |_|\___/ \__|_|\___/|_| |_| \___|\__|_| |_|")
ASCIIColors.red(" ______ ______ ")
ASCIIColors.red(" |______| |______| ")
ASCIIColors.red(" Forked from TencentARC's MotionCtrl api")
ASCIIColors.red(" Integration in lollms by ParisNeo")
motion_ctrl_folder = shared_folder / "auto_motion_ctrl"
env_name = "MotionCtrl"
if not self.wait_for_service(1,False) and auto_motion_ctrl_base_url is None:
if not self.wait_for_service(1,False):
ASCIIColors.info("Loading lollms_motion_ctrl")
os.environ['motion_ctrl_WEBUI_RESTARTING'] = '1' # To forbid sd webui from showing on the browser automatically
# Get the current operating system
os_name = platform.system()
conda_path = get_conda_path()
# Construct the command to activate the environment and start the server
if os_name == "Windows":
activate_env_command = f"call {conda_path}\\activate {env_name} && "
else: # Linux or macOS
activate_env_command = f"source {conda_path}/activate {env_name} && "
start_server_command = f"python -m app --share"
import conda.cli
env_name = "MotionCtrl"
# Replace 'your_env_name' with the name of the environment you created
activate_env_command = f"conda activate {env_name} && "
pip_install_command = "python -m app --share"
# Run the combined command
if os_name == "Windows":
subprocess.run(activate_env_command + start_server_command, shell=True, cwd=motion_ctrl_folder)
else: # Linux or macOS
subprocess.run(activate_env_command + start_server_command, shell=True, executable='/bin/bash', cwd=motion_ctrl_folder)
subprocess.run(activate_env_command + pip_install_command, shell=True)
# Wait until the service is available at http://127.0.0.1:7860/
@ -163,12 +163,28 @@ class LollmsMotionCtrl:
else:
ASCIIColors.warning("We are not waiting for the MotionCtrl service to be up.\nThis means that you may need to wait a bit before you can use it.")
self.default_sampler = sampler
self.default_steps = steps
self.session = requests.Session()
if username and password:
self.set_auth(username, password)
else:
self.check_controlnet()
def wait_for_service(self, max_retries = 50, show_warning=True):
url = f"{self.base_url}"
# Adjust this value as needed
retries = 0
while retries < max_retries or max_retries<0:
try:
response = requests.get(url)
if response.status_code == 200:
print("Service is available.")
if self.app is not None:
self.app.success("Motion ctrl is now available.")
return True
except requests.exceptions.RequestException:
pass
retries += 1
time.sleep(1)
if show_warning:
print("Service did not become available within the given time.")
if self.app is not None:
self.app.error("SD Service did not become available within the given time.")
return False