From 88d8f815f547443b55eb16984ddefe2f65c2cf42 Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Sun, 11 Sep 2022 19:46:51 +0200 Subject: [PATCH 01/22] init --- aiserver.py | 4 +++- requirements.txt | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/aiserver.py b/aiserver.py index 1802a502..553f4d04 100644 --- a/aiserver.py +++ b/aiserver.py @@ -17,7 +17,8 @@ os.environ['TOKENIZERS_PARALLELISM'] = 'false' from eventlet import tpool import logging -logging.basicConfig(format='%(levelname)s - %(module)s:%(lineno)d - %(message)s',level=logging.WARNING) +from loguru import logger +logger.debug("That's it, beautiful and simple logging!") logging.getLogger("urllib3").setLevel(logging.ERROR) from os import path, getcwd @@ -66,6 +67,7 @@ try: except: pass import transformers.generation_utils + global tpu_mtj_backend diff --git a/requirements.txt b/requirements.txt index 5dd27bce..4923a140 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,3 +15,4 @@ accelerate flask-session marshmallow>=3.13 apispec-webframeworks +loguru \ No newline at end of file From ee357fff3d362e3c79b80cc4d9715da689187dc1 Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Sun, 11 Sep 2022 19:51:23 +0200 Subject: [PATCH 02/22] reqs --- requirements_mtj.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements_mtj.txt b/requirements_mtj.txt index 67ff0e25..e50dafe7 100644 --- a/requirements_mtj.txt +++ b/requirements_mtj.txt @@ -20,3 +20,4 @@ bleach==4.1.0 flask-session marshmallow>=3.13 apispec-webframeworks +loguru \ No newline at end of file From 432af79fa56a20d2ae64bd05b5dc10b63112303c Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Sun, 11 Sep 2022 19:56:36 +0200 Subject: [PATCH 03/22] reqs --- environments/huggingface.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/environments/huggingface.yml b/environments/huggingface.yml index 2d9ace1d..77f239b4 100644 --- a/environments/huggingface.yml +++ b/environments/huggingface.yml @@ -25,3 +25,4 @@ dependencies: - lupa==1.10 - transformers>=4.20.1 - accelerate + - loguru From ce2d1ff65415362fb89ba64dce958c7b91bb382b Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Sun, 11 Sep 2022 22:59:19 +0200 Subject: [PATCH 04/22] logger file --- aiserver.py | 8 +++++++- logger.py | 23 +++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 logger.py diff --git a/aiserver.py b/aiserver.py index 553f4d04..4400c724 100644 --- a/aiserver.py +++ b/aiserver.py @@ -17,8 +17,14 @@ os.environ['TOKENIZERS_PARALLELISM'] = 'false' from eventlet import tpool import logging -from loguru import logger +from logger import logger +logger.generation("This is a generation message") logger.debug("That's it, beautiful and simple logging!") +logger.info("That's it, beautiful and simple logging!") +logger.error("That's it, beautiful and simple logging!") +logger.critical("That's it, beautiful and simple logging!") + + logging.getLogger("urllib3").setLevel(logging.ERROR) from os import path, getcwd diff --git a/logger.py b/logger.py new file mode 100644 index 00000000..33484235 --- /dev/null +++ b/logger.py @@ -0,0 +1,23 @@ +import sys +from functools import partialmethod +from loguru import logger + +def is_stdout_log(record): + if record["level"].name == "GENERATION": + return(True) + return(False) +def is_stderr_log(record): + if record["level"].name != "GENERATION": + return(True) + return(False) +logfmt = "{level: <10} | {name}:{function}:{line} - {message}" +genfmt = "{level: <10} @ {time:YYYY-MM-DD HH:mm:ss} | {message}" +new_level = logger.level("GENERATION", no=21, color="") +logger.__class__.generation = partialmethod(logger.__class__.log, "GENERATION") +config = { + "handlers": [ + {"sink": sys.stderr, "format": logfmt, "colorize":True, "filter": is_stderr_log}, + {"sink": sys.stdout, "format": genfmt, "level": "GENERATION", "colorize":True, "filter": is_stdout_log}, + ], +} +logger.configure(**config) From e29f6c94d373cac0c15cbcb8d9f3f72f188a717e Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Sun, 11 Sep 2022 23:08:17 +0200 Subject: [PATCH 05/22] prompt_colors --- logger.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/logger.py b/logger.py index 33484235..46a785b1 100644 --- a/logger.py +++ b/logger.py @@ -2,22 +2,32 @@ import sys from functools import partialmethod from loguru import logger +STDOUT_LEVELS = ["GENERATION", "PROMPT"] + def is_stdout_log(record): - if record["level"].name == "GENERATION": + if record["level"].name in STDOUT_LEVELS: return(True) return(False) + def is_stderr_log(record): - if record["level"].name != "GENERATION": + if record["level"].name not in STDOUT_LEVELS: return(True) return(False) + logfmt = "{level: <10} | {name}:{function}:{line} - {message}" genfmt = "{level: <10} @ {time:YYYY-MM-DD HH:mm:ss} | {message}" -new_level = logger.level("GENERATION", no=21, color="") +promptfmt = "{level: <10} @ {time:YYYY-MM-DD HH:mm:ss} | {message}" + +new_level = logger.level("GENERATION", no=22, color="") +new_level = logger.level("PROMPT", no=21, color="") + logger.__class__.generation = partialmethod(logger.__class__.log, "GENERATION") +logger.__class__.prompt = partialmethod(logger.__class__.log, "PROMPT") + config = { "handlers": [ {"sink": sys.stderr, "format": logfmt, "colorize":True, "filter": is_stderr_log}, - {"sink": sys.stdout, "format": genfmt, "level": "GENERATION", "colorize":True, "filter": is_stdout_log}, + {"sink": sys.stdout, "format": genfmt, "level": "PROMPT", "colorize":True, "filter": is_stdout_log}, ], } logger.configure(**config) From 2a8a223473e459201fa493d952bf60a2e1aaef56 Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Sun, 11 Sep 2022 23:55:48 +0200 Subject: [PATCH 06/22] added init logs --- aiserver.py | 12 +++--------- logger.py | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/aiserver.py b/aiserver.py index 4400c724..8663c52f 100644 --- a/aiserver.py +++ b/aiserver.py @@ -18,12 +18,6 @@ from eventlet import tpool import logging from logger import logger -logger.generation("This is a generation message") -logger.debug("That's it, beautiful and simple logging!") -logger.info("That's it, beautiful and simple logging!") -logger.error("That's it, beautiful and simple logging!") -logger.critical("That's it, beautiful and simple logging!") - logging.getLogger("urllib3").setLevel(logging.ERROR) @@ -78,7 +72,7 @@ global tpu_mtj_backend if lupa.LUA_VERSION[:2] != (5, 4): - print(f"Please install lupa==1.10. You have lupa {lupa.__version__}.", file=sys.stderr) + logging.error(f"Please install lupa==1.10. You have lupa {lupa.__version__}.") patch_causallm_patched = False @@ -409,7 +403,7 @@ log = logging.getLogger('werkzeug') log.setLevel(logging.ERROR) # Start flask & SocketIO -print("{0}Initializing Flask... {1}".format(colors.PURPLE, colors.END), end="") +logger.init("Flask Initialization", status="Starting") from flask import Flask, render_template, Response, request, copy_current_request_context, send_from_directory, session, jsonify, abort, redirect from flask_socketio import SocketIO from flask_socketio import emit as _emit @@ -422,7 +416,7 @@ app.config['SESSION_TYPE'] = 'filesystem' app.config['TEMPLATES_AUTO_RELOAD'] = True Session(app) socketio = SocketIO(app, async_method="eventlet") -print("{0}OK!{1}".format(colors.GREEN, colors.END)) +logger.init("Flask Initialization", status="OK") old_socketio_on = socketio.on def new_socketio_on(*a, **k): diff --git a/logger.py b/logger.py index 46a785b1..2549920b 100644 --- a/logger.py +++ b/logger.py @@ -3,31 +3,40 @@ from functools import partialmethod from loguru import logger STDOUT_LEVELS = ["GENERATION", "PROMPT"] +INIT_LEVELS = ["INIT"] def is_stdout_log(record): if record["level"].name in STDOUT_LEVELS: return(True) return(False) +def is_init_log(record): + if record["level"].name in INIT_LEVELS: + return(True) + return(False) + def is_stderr_log(record): - if record["level"].name not in STDOUT_LEVELS: + if record["level"].name not in STDOUT_LEVELS + INIT_LEVELS: return(True) return(False) logfmt = "{level: <10} | {name}:{function}:{line} - {message}" genfmt = "{level: <10} @ {time:YYYY-MM-DD HH:mm:ss} | {message}" -promptfmt = "{level: <10} @ {time:YYYY-MM-DD HH:mm:ss} | {message}" +initfmt = "{level: <10} | {extra[status]: <8} | {message}" -new_level = logger.level("GENERATION", no=22, color="") -new_level = logger.level("PROMPT", no=21, color="") +logger.level("GENERATION", no=24, color="") +logger.level("PROMPT", no=23, color="") +logger.level("INIT", no=21, color="") logger.__class__.generation = partialmethod(logger.__class__.log, "GENERATION") logger.__class__.prompt = partialmethod(logger.__class__.log, "PROMPT") +logger.__class__.init = partialmethod(logger.__class__.log, "INIT") config = { "handlers": [ {"sink": sys.stderr, "format": logfmt, "colorize":True, "filter": is_stderr_log}, {"sink": sys.stdout, "format": genfmt, "level": "PROMPT", "colorize":True, "filter": is_stdout_log}, + {"sink": sys.stdout, "format": initfmt, "level": "INIT", "colorize":True, "filter": is_init_log} ], } logger.configure(**config) From 11eac686760c7d54ecdcc32e870ca93a5d52d8f3 Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Mon, 12 Sep 2022 00:19:51 +0200 Subject: [PATCH 07/22] more init messages --- aiserver.py | 21 +++++++++++---------- logger.py | 14 ++++++++++++-- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/aiserver.py b/aiserver.py index 8663c52f..49ffa02b 100644 --- a/aiserver.py +++ b/aiserver.py @@ -403,7 +403,7 @@ log = logging.getLogger('werkzeug') log.setLevel(logging.ERROR) # Start flask & SocketIO -logger.init("Flask Initialization", status="Starting") +logger.init("Flask", status="Starting") from flask import Flask, render_template, Response, request, copy_current_request_context, send_from_directory, session, jsonify, abort, redirect from flask_socketio import SocketIO from flask_socketio import emit as _emit @@ -416,7 +416,7 @@ app.config['SESSION_TYPE'] = 'filesystem' app.config['TEMPLATES_AUTO_RELOAD'] = True Session(app) socketio = SocketIO(app, async_method="eventlet") -logger.init("Flask Initialization", status="OK") +logger.init("Flask", status="OK") old_socketio_on = socketio.on def new_socketio_on(*a, **k): @@ -2829,7 +2829,7 @@ def lua_startup(): #==================================================================# print("", end="", flush=True) - print(colors.PURPLE + "Initializing Lua Bridge... " + colors.END, end="", flush=True) + logger.init("LUA bridge", status="Starting") # Set up Lua state vars.lua_state = lupa.LuaRuntime(unpack_returned_tuples=True) @@ -2855,7 +2855,7 @@ def lua_startup(): print("{0}{1}{2}".format(colors.RED, "***LUA ERROR***: ", colors.END), end="", file=sys.stderr) print("{0}{1}{2}".format(colors.RED, str(e).replace("\033", ""), colors.END), file=sys.stderr) exit(1) - print(colors.GREEN + "OK!" + colors.END) + logger.init("LUA bridge", status="OK") def lua_log_format_name(name): @@ -2879,7 +2879,7 @@ def load_callback(filename, modulename): # Load all Lua scripts #==================================================================# def load_lua_scripts(): - print(colors.GREEN + "Loading Core Script" + colors.END) + logger.init("LUA Scripts", status="Starting") filenames = [] modulenames = [] @@ -2911,11 +2911,11 @@ def load_lua_scripts(): if(vars.serverstarted): emit('from_server', {'cmd': 'errmsg', 'data': 'Lua script error; please check console.'}, broadcast=True) sendUSStatItems() - print("{0}{1}{2}".format(colors.RED, "***LUA ERROR***: ", colors.END), end="", file=sys.stderr) - print("{0}{1}{2}".format(colors.RED, str(e).replace("\033", ""), colors.END), file=sys.stderr) - print("{0}{1}{2}".format(colors.YELLOW, "Lua engine stopped; please open 'Userscripts' and press Load to reinitialize scripts.", colors.END), file=sys.stderr) + logger.error('LUA ERROR: ' + str(e).replace("\033", "")) + logger.warning("Lua engine stopped; please open 'Userscripts' and press Load to reinitialize scripts.") if(vars.serverstarted): set_aibusy(0) + logger.init("LUA Scripts", status="OK") #==================================================================# # Print message that originates from the userscript with the given name @@ -9989,9 +9989,8 @@ for schema in config_endpoint_schemas: #==================================================================# # Final startup commands to launch Flask app #==================================================================# -print("", end="", flush=True) if __name__ == "__main__": - print("{0}\nStarting webserver...{1}".format(colors.GREEN, colors.END), flush=True) + logger.init("Webserver", status="Begin") general_startup() patch_transformers() @@ -10060,6 +10059,8 @@ if __name__ == "__main__": .format(colors.GREEN, port, colors.END)) vars.serverstarted = True socketio.run(app, port=port) + logger.init("Webserver", status="Closed") + else: general_startup() diff --git a/logger.py b/logger.py index 2549920b..7d4d71d3 100644 --- a/logger.py +++ b/logger.py @@ -4,6 +4,7 @@ from loguru import logger STDOUT_LEVELS = ["GENERATION", "PROMPT"] INIT_LEVELS = ["INIT"] +MESSAGE_LEVELS = ["MESSAGE"] def is_stdout_log(record): if record["level"].name in STDOUT_LEVELS: @@ -15,28 +16,37 @@ def is_init_log(record): return(True) return(False) +def is_msg_log(record): + if record["level"].name in MESSAGE_LEVELS: + return(True) + return(False) + def is_stderr_log(record): - if record["level"].name not in STDOUT_LEVELS + INIT_LEVELS: + if record["level"].name not in STDOUT_LEVELS + INIT_LEVELS + MESSAGE_LEVELS: return(True) return(False) logfmt = "{level: <10} | {name}:{function}:{line} - {message}" genfmt = "{level: <10} @ {time:YYYY-MM-DD HH:mm:ss} | {message}" initfmt = "{level: <10} | {extra[status]: <8} | {message}" +msgfmt = "{level: <10} | {message}" logger.level("GENERATION", no=24, color="") logger.level("PROMPT", no=23, color="") logger.level("INIT", no=21, color="") +logger.level("MESSAGE", no=20, color="") logger.__class__.generation = partialmethod(logger.__class__.log, "GENERATION") logger.__class__.prompt = partialmethod(logger.__class__.log, "PROMPT") logger.__class__.init = partialmethod(logger.__class__.log, "INIT") +logger.__class__.message = partialmethod(logger.__class__.log, "MESSAGE") config = { "handlers": [ {"sink": sys.stderr, "format": logfmt, "colorize":True, "filter": is_stderr_log}, {"sink": sys.stdout, "format": genfmt, "level": "PROMPT", "colorize":True, "filter": is_stdout_log}, - {"sink": sys.stdout, "format": initfmt, "level": "INIT", "colorize":True, "filter": is_init_log} + {"sink": sys.stdout, "format": initfmt, "level": "INIT", "colorize":True, "filter": is_init_log}, + {"sink": sys.stdout, "format": msgfmt, "level": "MESSAGE", "colorize":True, "filter": is_msg_log} ], } logger.configure(**config) From 4817a27552c360e04104b1f07f3d36b4d7fb1427 Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Mon, 12 Sep 2022 00:49:51 +0200 Subject: [PATCH 08/22] multicolored init --- aiserver.py | 18 +++++++++--------- logger.py | 12 +++++++++--- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/aiserver.py b/aiserver.py index 49ffa02b..f28c45aa 100644 --- a/aiserver.py +++ b/aiserver.py @@ -416,7 +416,7 @@ app.config['SESSION_TYPE'] = 'filesystem' app.config['TEMPLATES_AUTO_RELOAD'] = True Session(app) socketio = SocketIO(app, async_method="eventlet") -logger.init("Flask", status="OK") +logger.init_ok("Flask", status="OK") old_socketio_on = socketio.on def new_socketio_on(*a, **k): @@ -1405,9 +1405,10 @@ def general_startup(override_args=None): vars.model = "NeoCustom" vars.custmodpth = modpath elif args.model: - print("Welcome to KoboldAI!\nYou have selected the following Model:", vars.model) + logger.message(f"Welcome to KoboldAI!") + logger.message(f"You have selected the following Model: {vars.model}") if args.path: - print("You have selected the following path for your Model :", args.path) + logger.message(f"You have selected the following path for your Model: {args.path}") vars.custmodpth = args.path; vars.colaburl = args.path + "/request"; # Lets just use the same parameter to keep it simple #==================================================================# @@ -2188,8 +2189,7 @@ def load_model(use_gpu=True, gpu_layers=None, disk_layers=None, initial_load=Fal if(not vars.use_colab_tpu and vars.model not in ["InferKit", "Colab", "API", "CLUSTER", "OAI", "GooseAI" , "ReadOnly", "TPUMeshTransformerGPTJ", "TPUMeshTransformerGPTNeoX"]): loadmodelsettings() loadsettings() - print(2) - print("{0}Looking for GPU support...{1}".format(colors.PURPLE, colors.END), end="") + logger.init("GPU support", status="Searching") vars.hascuda = torch.cuda.is_available() vars.bmsupported = (utils.HAS_ACCELERATE or vars.model_type in ("gpt_neo", "gptj", "xglm", "opt")) and not vars.nobreakmodel if(args.breakmodel is not None and args.breakmodel): @@ -2202,9 +2202,9 @@ def load_model(use_gpu=True, gpu_layers=None, disk_layers=None, initial_load=Fal if(not vars.bmsupported and (args.breakmodel_gpulayers is not None or args.breakmodel_layers is not None or args.breakmodel_disklayers is not None)): print("WARNING: This model does not support hybrid generation. --breakmodel_gpulayers will be ignored.", file=sys.stderr) if(vars.hascuda): - print("{0}FOUND!{1}".format(colors.GREEN, colors.END)) + logger.init_ok("GPU support", status="Found") else: - print("{0}NOT FOUND!{1}".format(colors.YELLOW, colors.END)) + logger.init_warn("GPU support", status="Not Found") if args.cpu: vars.usegpu = False @@ -2855,7 +2855,7 @@ def lua_startup(): print("{0}{1}{2}".format(colors.RED, "***LUA ERROR***: ", colors.END), end="", file=sys.stderr) print("{0}{1}{2}".format(colors.RED, str(e).replace("\033", ""), colors.END), file=sys.stderr) exit(1) - logger.init("LUA bridge", status="OK") + logger.init_ok("LUA bridge", status="OK") def lua_log_format_name(name): @@ -2915,7 +2915,7 @@ def load_lua_scripts(): logger.warning("Lua engine stopped; please open 'Userscripts' and press Load to reinitialize scripts.") if(vars.serverstarted): set_aibusy(0) - logger.init("LUA Scripts", status="OK") + logger.init_ok("LUA Scripts", status="OK") #==================================================================# # Print message that originates from the userscript with the given name diff --git a/logger.py b/logger.py index 7d4d71d3..a715426c 100644 --- a/logger.py +++ b/logger.py @@ -3,7 +3,7 @@ from functools import partialmethod from loguru import logger STDOUT_LEVELS = ["GENERATION", "PROMPT"] -INIT_LEVELS = ["INIT"] +INIT_LEVELS = ["INIT", "INIT_OK", "INIT_WARN", "INIT_ERR"] MESSAGE_LEVELS = ["MESSAGE"] def is_stdout_log(record): @@ -28,17 +28,23 @@ def is_stderr_log(record): logfmt = "{level: <10} | {name}:{function}:{line} - {message}" genfmt = "{level: <10} @ {time:YYYY-MM-DD HH:mm:ss} | {message}" -initfmt = "{level: <10} | {extra[status]: <8} | {message}" +initfmt = "INIT | {extra[status]: <8} | {message}" msgfmt = "{level: <10} | {message}" logger.level("GENERATION", no=24, color="") logger.level("PROMPT", no=23, color="") -logger.level("INIT", no=21, color="") +logger.level("INIT", no=21, color="") +logger.level("INIT_OK", no=21, color="") +logger.level("INIT_WARN", no=21, color="") +logger.level("INIT_ERR", no=21, color="") logger.level("MESSAGE", no=20, color="") logger.__class__.generation = partialmethod(logger.__class__.log, "GENERATION") logger.__class__.prompt = partialmethod(logger.__class__.log, "PROMPT") logger.__class__.init = partialmethod(logger.__class__.log, "INIT") +logger.__class__.init_ok = partialmethod(logger.__class__.log, "INIT_OK") +logger.__class__.init_warn = partialmethod(logger.__class__.log, "INIT_WARN") +logger.__class__.init_err = partialmethod(logger.__class__.log, "INIT_ERR") logger.__class__.message = partialmethod(logger.__class__.log, "MESSAGE") config = { From 48f6b5a939cbfcb3c66cb081453ae3701f509d26 Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Mon, 12 Sep 2022 01:00:03 +0200 Subject: [PATCH 09/22] more init messages --- aiserver.py | 25 +++++++++++-------------- logger.py | 8 ++++---- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/aiserver.py b/aiserver.py index f28c45aa..52bfb450 100644 --- a/aiserver.py +++ b/aiserver.py @@ -805,7 +805,7 @@ def device_config(config): breakmodel.gpu_blocks = [n_layers - max(0, min(n_layers, args.breakmodel_layers))] n_layers -= sum(breakmodel.gpu_blocks) elif(args.model is not None): - print("Breakmodel not specified, assuming GPU 0") + logger.info("Breakmodel not specified, assuming GPU 0") breakmodel.gpu_blocks = [n_layers] n_layers = 0 else: @@ -864,7 +864,7 @@ def device_config(config): else: print(f"{colors.RED}Please enter an integer between -1 and {n_layers}.{colors.END}") - print(colors.PURPLE + "\nFinal device configuration:") + logger.init_ok("Final device configuration:", status="Info") device_list(n_layers) # If all layers are on the same device, use the old GPU generation mode @@ -2193,18 +2193,18 @@ def load_model(use_gpu=True, gpu_layers=None, disk_layers=None, initial_load=Fal vars.hascuda = torch.cuda.is_available() vars.bmsupported = (utils.HAS_ACCELERATE or vars.model_type in ("gpt_neo", "gptj", "xglm", "opt")) and not vars.nobreakmodel if(args.breakmodel is not None and args.breakmodel): - print("WARNING: --breakmodel is no longer supported. Breakmodel mode is now automatically enabled when --breakmodel_gpulayers is used (see --help for details).", file=sys.stderr) + logger.warning("WARNING: --breakmodel is no longer supported. Breakmodel mode is now automatically enabled when --breakmodel_gpulayers is used (see --help for details).") if(args.breakmodel_layers is not None): - print("WARNING: --breakmodel_layers is deprecated. Use --breakmodel_gpulayers instead (see --help for details).", file=sys.stderr) + logger.warning("WARNING: --breakmodel_layers is deprecated. Use --breakmodel_gpulayers instead (see --help for details).") if(args.model and vars.bmsupported and not args.breakmodel_gpulayers and not args.breakmodel_layers and (not utils.HAS_ACCELERATE or not args.breakmodel_disklayers)): - print("WARNING: Model launched without the --breakmodel_gpulayers argument, defaulting to GPU only mode.", file=sys.stderr) + logger.warning("WARNING: Model launched without the --breakmodel_gpulayers argument, defaulting to GPU only mode.") vars.bmsupported = False if(not vars.bmsupported and (args.breakmodel_gpulayers is not None or args.breakmodel_layers is not None or args.breakmodel_disklayers is not None)): - print("WARNING: This model does not support hybrid generation. --breakmodel_gpulayers will be ignored.", file=sys.stderr) + logger.warning("WARNING: This model does not support hybrid generation. --breakmodel_gpulayers will be ignored.") if(vars.hascuda): - logger.init_ok("GPU support", status="Found") + logger.init_ok("GPU support", status="Found") else: - logger.init_warn("GPU support", status="Not Found") + logger.init_warn("GPU support", status="Not Found") if args.cpu: vars.usegpu = False @@ -2241,7 +2241,7 @@ def load_model(use_gpu=True, gpu_layers=None, disk_layers=None, initial_load=Fal # Start transformers and create pipeline if(not vars.use_colab_tpu and vars.model not in ["InferKit", "Colab", "API", "CLUSTER", "OAI", "GooseAI" , "ReadOnly", "TPUMeshTransformerGPTJ", "TPUMeshTransformerGPTNeoX"]): if(not vars.noai): - print("{0}Initializing transformers, please wait...{1}".format(colors.PURPLE, colors.END)) + logger.init("Transformers", status='Starting') for m in ("GPTJModel", "XGLMModel"): try: globals()[m] = getattr(__import__("transformers"), m) @@ -2306,7 +2306,6 @@ def load_model(use_gpu=True, gpu_layers=None, disk_layers=None, initial_load=Fal num_tensors = len(utils.get_sharded_checkpoint_num_tensors(utils.from_pretrained_model_name, utils.from_pretrained_index_filename, **utils.from_pretrained_kwargs)) else: num_tensors = len(device_map) - print(flush=True) utils.bar = tqdm(total=num_tensors, desc="Loading model tensors", file=Send_to_socketio()) with zipfile.ZipFile(f, "r") as z: @@ -2377,7 +2376,7 @@ def load_model(use_gpu=True, gpu_layers=None, disk_layers=None, initial_load=Fal def maybe_low_cpu_mem_usage() -> Dict[str, Any]: if(packaging.version.parse(transformers_version) < packaging.version.parse("4.11.0")): - print(f"\nWARNING: Please upgrade to transformers 4.11.0 for lower RAM usage. You have transformers {transformers_version}.", file=sys.stderr) + logger.warning(f"Please upgrade to transformers 4.11.0 for lower RAM usage. You have transformers {transformers_version}.") return {} return {"low_cpu_mem_usage": True} @@ -2434,7 +2433,6 @@ def load_model(use_gpu=True, gpu_layers=None, disk_layers=None, initial_load=Fal if os.path.isdir(vars.model.replace('/', '_')): import shutil shutil.move(vars.model.replace('/', '_'), "models/{}".format(vars.model.replace('/', '_'))) - print("\n", flush=True) if(vars.lazy_load): # If we're using lazy loader, we need to figure out what the model's hidden layers are called with torch_lazy_loader.use_lazy_torch_load(dematerialized_modules=True, use_accelerate_init_empty_weights=True): try: @@ -2556,7 +2554,6 @@ def load_model(use_gpu=True, gpu_layers=None, disk_layers=None, initial_load=Fal elif(vars.breakmodel): # Use both RAM and VRAM (breakmodel) vars.modeldim = get_hidden_size_from_model(model) if(not vars.lazy_load): - print(2) device_config(model.config) move_model_to_devices(model) elif(utils.HAS_ACCELERATE and __import__("breakmodel").disk_blocks > 0): @@ -2583,7 +2580,7 @@ def load_model(use_gpu=True, gpu_layers=None, disk_layers=None, initial_load=Fal #for key in vars.badwords: # vars.badwordsids.append([vocab[key]]) - print("{0}OK! {1} pipeline created!{2}".format(colors.GREEN, vars.model, colors.END)) + logger.info(f"Pipeline created: {vars.model}") else: from transformers import GPT2TokenizerFast diff --git a/logger.py b/logger.py index a715426c..c5c8101c 100644 --- a/logger.py +++ b/logger.py @@ -33,10 +33,10 @@ msgfmt = "{level: <10} | {message}" logger.level("GENERATION", no=24, color="") logger.level("PROMPT", no=23, color="") -logger.level("INIT", no=21, color="") -logger.level("INIT_OK", no=21, color="") -logger.level("INIT_WARN", no=21, color="") -logger.level("INIT_ERR", no=21, color="") +logger.level("INIT", no=31, color="") +logger.level("INIT_OK", no=31, color="") +logger.level("INIT_WARN", no=31, color="") +logger.level("INIT_ERR", no=31, color="") logger.level("MESSAGE", no=20, color="") logger.__class__.generation = partialmethod(logger.__class__.log, "GENERATION") From 656e3995f0a29813a6a55c0ff642d2c71cae2fea Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Mon, 12 Sep 2022 01:09:21 +0200 Subject: [PATCH 10/22] model tensors info --- aiserver.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/aiserver.py b/aiserver.py index 52bfb450..9b212ddd 100644 --- a/aiserver.py +++ b/aiserver.py @@ -2306,7 +2306,7 @@ def load_model(use_gpu=True, gpu_layers=None, disk_layers=None, initial_load=Fal num_tensors = len(utils.get_sharded_checkpoint_num_tensors(utils.from_pretrained_model_name, utils.from_pretrained_index_filename, **utils.from_pretrained_kwargs)) else: num_tensors = len(device_map) - utils.bar = tqdm(total=num_tensors, desc="Loading model tensors", file=Send_to_socketio()) + utils.bar = tqdm(total=num_tensors, desc=f"{colors.PURPLE}INIT{colors.END} | Loading model tensors", file=Send_to_socketio()) with zipfile.ZipFile(f, "r") as z: try: @@ -10027,10 +10027,11 @@ if __name__ == "__main__": if(args.localtunnel or args.ngrok or args.remote): with open('cloudflare.log', 'w') as cloudflarelog: cloudflarelog.write("KoboldAI has finished loading and is available at the following link : " + cloudflare) - print(format(colors.GREEN) + "KoboldAI has finished loading and is available at the following link : " + cloudflare + format(colors.END)) + logger.init_ok("Webserver", status="OK") + logger.message(f"KoboldAI has finished loading and is available at the following link: {cloudflare}") else: - print("{0}Webserver has started, you can now connect to this machine at port {1}{2}" - .format(colors.GREEN, port, colors.END)) + logger.init_ok("Webserver", status="OK") + logger.message(f"Webserver has started, you can now connect to this machine at port: {port}") vars.serverstarted = True socketio.run(app, host='0.0.0.0', port=port) else: @@ -10038,8 +10039,8 @@ if __name__ == "__main__": if not args.no_ui: import webbrowser webbrowser.open_new('http://localhost:{0}'.format(port)) - print("{0}Server started!\nYou may now connect with a browser at http://127.0.0.1:{1}/{2}" - .format(colors.GREEN, port, colors.END)) + logger.init_ok("Webserver", status="OK") + logger.message(f"Webserver started! You may now connect with a browser at http://127.0.0.1:{port}") vars.serverstarted = True socketio.run(app, port=port, host='0.0.0.0') else: @@ -10052,8 +10053,8 @@ if __name__ == "__main__": if not args.no_ui: import webbrowser webbrowser.open_new('http://localhost:{0}'.format(port)) - print("{0}Server started!\nYou may now connect with a browser at http://127.0.0.1:{1}/{2}" - .format(colors.GREEN, port, colors.END)) + logger.init_ok("Webserver", status="OK") + logger.message(f"Webserver started! You may now connect with a browser at http://127.0.0.1:{port}") vars.serverstarted = True socketio.run(app, port=port) logger.init("Webserver", status="Closed") From 5692e5ce161169bce3d5f9aaa32088c35df91a70 Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Mon, 12 Sep 2022 01:13:12 +0200 Subject: [PATCH 11/22] finished all init messages --- aiserver.py | 4 ++-- logger.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/aiserver.py b/aiserver.py index 9b212ddd..d548e62f 100644 --- a/aiserver.py +++ b/aiserver.py @@ -1085,7 +1085,7 @@ def savesettings(): #==================================================================# @debounce(2) def settingschanged(): - print("{0}Saving settings!{1}".format(colors.GREEN, colors.END)) + logger.info("Saving settings.") savesettings() #==================================================================# @@ -9987,7 +9987,7 @@ for schema in config_endpoint_schemas: # Final startup commands to launch Flask app #==================================================================# if __name__ == "__main__": - logger.init("Webserver", status="Begin") + logger.init("Webserver", status="Starting") general_startup() patch_transformers() diff --git a/logger.py b/logger.py index c5c8101c..2b3dceea 100644 --- a/logger.py +++ b/logger.py @@ -28,7 +28,7 @@ def is_stderr_log(record): logfmt = "{level: <10} | {name}:{function}:{line} - {message}" genfmt = "{level: <10} @ {time:YYYY-MM-DD HH:mm:ss} | {message}" -initfmt = "INIT | {extra[status]: <8} | {message}" +initfmt = "INIT | {extra[status]: <10} | {message}" msgfmt = "{level: <10} | {message}" logger.level("GENERATION", no=24, color="") From 66ae5c35c06332cd209d9de75d3aac6ced06c61f Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Mon, 12 Sep 2022 01:18:25 +0200 Subject: [PATCH 12/22] replaced all warnings with logger --- aiserver.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/aiserver.py b/aiserver.py index d548e62f..cfa5a635 100644 --- a/aiserver.py +++ b/aiserver.py @@ -798,7 +798,7 @@ def device_config(config): breakmodel.disk_blocks = args.breakmodel_disklayers n_layers -= args.breakmodel_disklayers except: - print("WARNING: --breakmodel_gpulayers is malformatted. Please use the --help option to see correct usage of --breakmodel_gpulayers. Defaulting to all layers on device 0.", file=sys.stderr) + logger.warning("--breakmodel_gpulayers is malformatted. Please use the --help option to see correct usage of --breakmodel_gpulayers. Defaulting to all layers on device 0.") breakmodel.gpu_blocks = [n_layers] n_layers = 0 elif(args.breakmodel_layers is not None): @@ -2183,7 +2183,7 @@ def load_model(use_gpu=True, gpu_layers=None, disk_layers=None, initial_load=Fal elif(vars.model_type == "not_found" and vars.model == "GPT2Custom"): vars.model_type = "gpt2" elif(vars.model_type == "not_found"): - print("WARNING: No model type detected, assuming Neo (If this is a GPT2 model use the other menu option or --model GPT2Custom)") + logger.warning("No model type detected, assuming Neo (If this is a GPT2 model use the other menu option or --model GPT2Custom)") vars.model_type = "gpt_neo" if(not vars.use_colab_tpu and vars.model not in ["InferKit", "Colab", "API", "CLUSTER", "OAI", "GooseAI" , "ReadOnly", "TPUMeshTransformerGPTJ", "TPUMeshTransformerGPTNeoX"]): @@ -2193,14 +2193,14 @@ def load_model(use_gpu=True, gpu_layers=None, disk_layers=None, initial_load=Fal vars.hascuda = torch.cuda.is_available() vars.bmsupported = (utils.HAS_ACCELERATE or vars.model_type in ("gpt_neo", "gptj", "xglm", "opt")) and not vars.nobreakmodel if(args.breakmodel is not None and args.breakmodel): - logger.warning("WARNING: --breakmodel is no longer supported. Breakmodel mode is now automatically enabled when --breakmodel_gpulayers is used (see --help for details).") + logger.warning("--breakmodel is no longer supported. Breakmodel mode is now automatically enabled when --breakmodel_gpulayers is used (see --help for details).") if(args.breakmodel_layers is not None): - logger.warning("WARNING: --breakmodel_layers is deprecated. Use --breakmodel_gpulayers instead (see --help for details).") + logger.warning("--breakmodel_layers is deprecated. Use --breakmodel_gpulayers instead (see --help for details).") if(args.model and vars.bmsupported and not args.breakmodel_gpulayers and not args.breakmodel_layers and (not utils.HAS_ACCELERATE or not args.breakmodel_disklayers)): - logger.warning("WARNING: Model launched without the --breakmodel_gpulayers argument, defaulting to GPU only mode.") + logger.warning("Model launched without the --breakmodel_gpulayers argument, defaulting to GPU only mode.") vars.bmsupported = False if(not vars.bmsupported and (args.breakmodel_gpulayers is not None or args.breakmodel_layers is not None or args.breakmodel_disklayers is not None)): - logger.warning("WARNING: This model does not support hybrid generation. --breakmodel_gpulayers will be ignored.") + logger.warning("This model does not support hybrid generation. --breakmodel_gpulayers will be ignored.") if(vars.hascuda): logger.init_ok("GPU support", status="Found") else: @@ -3874,14 +3874,14 @@ def get_message(msg): elif(msg['cmd'] == 'delete_model'): if "{}/models".format(os.getcwd()) in os.path.abspath(msg['data']) or "{}\\models".format(os.getcwd()) in os.path.abspath(msg['data']): if check_if_dir_is_model(msg['data']): - print(colors.YELLOW + "WARNING: Someone deleted " + msg['data']) + logger.warning(f"Someone deleted {msg['data']}") import shutil shutil.rmtree(msg['data']) sendModelSelection(menu=msg['menu']) else: - print(colors.RED + "ERROR: Someone attempted to delete " + msg['data'] + " but this is not a valid model") + logger.error(f"Someone attempted to delete {msg['data']} but this is not a valid model") else: - print(colors.RED + "WARNING!!: Someone maliciously attempted to delete " + msg['data'] + " the attempt has been blocked.") + logger.critical(f"Someone maliciously attempted to delete {msg['data']}. The attempt has been blocked.") elif(msg['cmd'] == 'OAI_Key_Update'): get_oai_models(msg['key']) elif(msg['cmd'] == 'Cluster_Key_Update'): @@ -4118,7 +4118,7 @@ def actionsubmit(data, actionmode=0, force_submit=False, force_prompt_gen=False, except: tokenizer = AutoTokenizer.from_pretrained(tokenizer_id, revision=vars.revision, cache_dir="cache", use_fast=False) except: - print(f"WARNING: Unknown tokenizer {repr(tokenizer_id)}") + logger.warning(f"Unknown tokenizer {repr(tokenizer_id)}") vars.api_tokenizer_id = tokenizer_id if(disable_recentrng): @@ -5631,7 +5631,7 @@ def inlineedit(chunk, data): vars.actions_metadata[chunk-1]['Selected Text'] = data vars.actions[chunk-1] = data else: - print(f"WARNING: Attempted to edit non-existent chunk {chunk}") + logger.warning(f"Attempted to edit non-existent chunk {chunk}") setgamesaved(False) update_story_chunk(chunk) @@ -5659,7 +5659,7 @@ def inlinedelete(chunk): vars.actions_metadata[chunk-1]['Selected Text'] = '' del vars.actions[chunk-1] else: - print(f"WARNING: Attempted to delete non-existent chunk {chunk}") + logger.warning(f"Attempted to delete non-existent chunk {chunk}") setgamesaved(False) remove_story_chunk(chunk) emit('from_server', {'cmd': 'editmode', 'data': 'false'}, broadcast=True) From d30bbd28a173ef23c2c3c8ab038d08daf963f16c Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Mon, 12 Sep 2022 01:57:41 +0200 Subject: [PATCH 13/22] logger for prompt and gen --- aiserver.py | 70 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/aiserver.py b/aiserver.py index cfa5a635..74888172 100644 --- a/aiserver.py +++ b/aiserver.py @@ -2849,8 +2849,8 @@ def lua_startup(): except lupa.LuaError as e: print(colors.RED + "ERROR!" + colors.END) vars.lua_koboldbridge.obliterate_multiverse() - print("{0}{1}{2}".format(colors.RED, "***LUA ERROR***: ", colors.END), end="", file=sys.stderr) - print("{0}{1}{2}".format(colors.RED, str(e).replace("\033", ""), colors.END), file=sys.stderr) + logger.debug('LUA ERROR: ' + str(e).replace("\033", "")) + logger.warning("Lua engine stopped; please open 'Userscripts' and press Load to reinitialize scripts.") exit(1) logger.init_ok("LUA bridge", status="OK") @@ -2908,7 +2908,7 @@ def load_lua_scripts(): if(vars.serverstarted): emit('from_server', {'cmd': 'errmsg', 'data': 'Lua script error; please check console.'}, broadcast=True) sendUSStatItems() - logger.error('LUA ERROR: ' + str(e).replace("\033", "")) + logger.debug('LUA ERROR: ' + str(e).replace("\033", "")) logger.warning("Lua engine stopped; please open 'Userscripts' and press Load to reinitialize scripts.") if(vars.serverstarted): set_aibusy(0) @@ -3405,9 +3405,8 @@ def execute_inmod(): vars.lua_running = False emit('from_server', {'cmd': 'errmsg', 'data': 'Lua script error; please check console.'}, broadcast=True) sendUSStatItems() - print("{0}{1}{2}".format(colors.RED, "***LUA ERROR***: ", colors.END), end="", file=sys.stderr) - print("{0}{1}{2}".format(colors.RED, str(e).replace("\033", ""), colors.END), file=sys.stderr) - print("{0}{1}{2}".format(colors.YELLOW, "Lua engine stopped; please open 'Userscripts' and press Load to reinitialize scripts.", colors.END), file=sys.stderr) + logger.debug('LUA ERROR: ' + str(e).replace("\033", "")) + logger.warning("Lua engine stopped; please open 'Userscripts' and press Load to reinitialize scripts.") set_aibusy(0) def execute_genmod(): @@ -3423,9 +3422,8 @@ def execute_outmod(): vars.lua_running = False emit('from_server', {'cmd': 'errmsg', 'data': 'Lua script error; please check console.'}, broadcast=True) sendUSStatItems() - print("{0}{1}{2}".format(colors.RED, "***LUA ERROR***: ", colors.END), end="", file=sys.stderr) - print("{0}{1}{2}".format(colors.RED, str(e).replace("\033", ""), colors.END), file=sys.stderr) - print("{0}{1}{2}".format(colors.YELLOW, "Lua engine stopped; please open 'Userscripts' and press Load to reinitialize scripts.", colors.END), file=sys.stderr) + logger.debug('LUA ERROR: ' + str(e).replace("\033", "")) + logger.warning("Lua engine stopped; please open 'Userscripts' and press Load to reinitialize scripts.") set_aibusy(0) if(vars.lua_koboldbridge.resend_settings_required): vars.lua_koboldbridge.resend_settings_required = False @@ -3445,7 +3443,7 @@ def execute_outmod(): #==================================================================# @socketio.on('connect') def do_connect(): - print("{0}Client connected!{1}".format(colors.GREEN, colors.END)) + logger.info("Client connected!") emit('from_server', {'cmd': 'setchatname', 'data': vars.chatname}) emit('from_server', {'cmd': 'setanotetemplate', 'data': vars.authornotetemplate}) emit('from_server', {'cmd': 'connected', 'smandelete': vars.smandelete, 'smanrename': vars.smanrename, 'modelname': getmodelname()}) @@ -3498,7 +3496,7 @@ def do_connect(): @socketio.on('message') def get_message(msg): if not vars.quiet: - print("{0}Data received:{1}{2}".format(colors.GREEN, msg, colors.END)) + logger.debug(f"Data received: {msg}") # Submit action if(msg['cmd'] == 'submit'): if(vars.mode == "play"): @@ -3788,8 +3786,7 @@ def get_message(msg): elif(msg['cmd'] == 'list_model'): sendModelSelection(menu=msg['data']) elif(msg['cmd'] == 'load_model'): - print(msg) - print(vars.model_selected) + logger.debug(vars.model_selected) if not os.path.exists("settings/"): os.mkdir("settings") changed = True @@ -3823,7 +3820,7 @@ def get_message(msg): vars.cluster_requested_models = msg['online_model'] load_model(use_gpu=msg['use_gpu'], gpu_layers=msg['gpu_layers'], disk_layers=msg['disk_layers'], online_model=msg['online_model']) elif(msg['cmd'] == 'show_model'): - print("Model Name: {}".format(getmodelname())) + logger.info(f"Model Name: {getmodelname()}") emit('from_server', {'cmd': 'show_model_name', 'data': getmodelname()}, broadcast=True) elif(msg['cmd'] == 'selectmodel'): # This is run when a model line is selected from the UI (line from the model_menu variable) that is tagged as not a menu @@ -4229,8 +4226,8 @@ def actionsubmit(data, actionmode=0, force_submit=False, force_prompt_gen=False, try: alternatives = [item['Text'] for item in vars.actions_metadata[len(vars.actions)-1]["Alternative Text"]] except: - print(len(vars.actions)) - print(vars.actions_metadata) + logger.debug(len(vars.actions)) + logger.debug(vars.actions_metadata) raise if data in alternatives: alternatives = [item for item in vars.actions_metadata[vars.actions.get_last_key() ]["Alternative Text"] if item['Text'] != data] @@ -4282,7 +4279,10 @@ def apiactionsubmit_generate(txt, minimum, maximum): vars.generated_tkns = 0 if not vars.quiet: - print("{0}Min:{1}, Max:{2}, Txt:{3}{4}".format(colors.YELLOW, minimum, maximum, utils.decodenewlines(tokenizer.decode(txt)), colors.END)) + logger.debug(f"Prompt Min:{minimum}, Max:{maximum}") + split_prompt = utils.decodenewlines(tokenizer.decode(txt)).split('\n') + for line in split_prompt: + logger.prompt(line) # Clear CUDA cache if using GPU if(vars.hascuda and (vars.usegpu or vars.breakmodel)): @@ -4309,7 +4309,10 @@ def apiactionsubmit_tpumtjgenerate(txt, minimum, maximum): tpu_mtj_backend.set_rng_seed(vars.seed) if not vars.quiet: - print("{0}Min:{1}, Max:{2}, Txt:{3}{4}".format(colors.YELLOW, minimum, maximum, utils.decodenewlines(tokenizer.decode(txt)), colors.END)) + logger.debug(f"Prompt Min:{minimum}, Max:{maximum}") + split_prompt = utils.decodenewlines(tokenizer.decode(txt)).split('\n') + for line in split_prompt: + logger.prompt(line) vars._actions = vars.actions vars._prompt = vars.prompt @@ -4821,7 +4824,10 @@ def generate(txt, minimum, maximum, found_entries=None): found_entries = tuple(found_entries.copy() for _ in range(vars.numseqs)) if not vars.quiet: - print("{0}Min:{1}, Max:{2}, Txt:{3}{4}".format(colors.YELLOW, minimum, maximum, utils.decodenewlines(tokenizer.decode(txt)), colors.END)) + logger.debug(f"Prompt Min:{minimum}, Max:{maximum}") + split_prompt = utils.decodenewlines(tokenizer.decode(txt)).split('\n') + for line in split_prompt: + logger.prompt(line) # Store context in memory to use it for comparison with generated content vars.lastctx = utils.decodenewlines(tokenizer.decode(txt)) @@ -4840,12 +4846,11 @@ def generate(txt, minimum, maximum, found_entries=None): vars.lua_running = False emit('from_server', {'cmd': 'errmsg', 'data': 'Lua script error; please check console.'}, broadcast=True) sendUSStatItems() - print("{0}{1}{2}".format(colors.RED, "***LUA ERROR***: ", colors.END), end="", file=sys.stderr) - print("{0}{1}{2}".format(colors.RED, str(e).replace("\033", ""), colors.END), file=sys.stderr) - print("{0}{1}{2}".format(colors.YELLOW, "Lua engine stopped; please open 'Userscripts' and press Load to reinitialize scripts.", colors.END), file=sys.stderr) + logger.debug('LUA ERROR: ' + str(e).replace("\033", "")) + logger.warning("Lua engine stopped; please open 'Userscripts' and press Load to reinitialize scripts.") else: emit('from_server', {'cmd': 'errmsg', 'data': 'Error occurred during generator call; please check console.'}, broadcast=True) - print("{0}{1}{2}".format(colors.RED, traceback.format_exc().replace("\033", ""), colors.END), file=sys.stderr) + logger.error(traceback.format_exc().replace("\033", "")) set_aibusy(0) return @@ -4884,7 +4889,9 @@ def generate(txt, minimum, maximum, found_entries=None): #==================================================================# def genresult(genout, flash=True, ignore_formatting=False): if not vars.quiet: - print("{0}{1}{2}".format(colors.CYAN, genout, colors.END)) + split_gen = genout.split('\n') + for line in split_gen: + logger.generation(line) # Format output before continuing if not ignore_formatting: @@ -4918,7 +4925,10 @@ def genselect(genout): # Apply output formatting rules to sequences result["generated_text"] = applyoutputformatting(result["generated_text"]) if not vars.quiet: - print("{0}[Result {1}]\n{2}{3}".format(colors.CYAN, i, result["generated_text"], colors.END)) + logger.info(f"Generation Result {i}") + split_gen = result["generated_text"].split('\n') + for line in split_gen: + logger.generation(line) i += 1 # Add the options to the actions metadata @@ -5257,7 +5267,10 @@ def tpumtjgenerate(txt, minimum, maximum, found_entries=None): found_entries = tuple(found_entries.copy() for _ in range(vars.numseqs)) if not vars.quiet: - print("{0}Min:{1}, Max:{2}, Txt:{3}{4}".format(colors.YELLOW, minimum, maximum, utils.decodenewlines(tokenizer.decode(txt)), colors.END)) + logger.debug(f"Prompt Min:{minimum}, Max:{maximum}") + split_prompt = utils.decodenewlines(tokenizer.decode(txt)).split('\n') + for line in split_prompt: + logger.prompt(line) vars._actions = vars.actions vars._prompt = vars.prompt @@ -5345,9 +5358,8 @@ def tpumtjgenerate(txt, minimum, maximum, found_entries=None): vars.lua_running = False emit('from_server', {'cmd': 'errmsg', 'data': 'Lua script error; please check console.'}, broadcast=True) sendUSStatItems() - print("{0}{1}{2}".format(colors.RED, "***LUA ERROR***: ", colors.END), end="", file=sys.stderr) - print("{0}{1}{2}".format(colors.RED, str(e).replace("\033", ""), colors.END), file=sys.stderr) - print("{0}{1}{2}".format(colors.YELLOW, "Lua engine stopped; please open 'Userscripts' and press Load to reinitialize scripts.", colors.END), file=sys.stderr) + logger.debug('LUA ERROR: ' + str(e).replace("\033", "")) + logger.warning("Lua engine stopped; please open 'Userscripts' and press Load to reinitialize scripts.") else: emit('from_server', {'cmd': 'errmsg', 'data': 'Error occurred during generator call; please check console.'}, broadcast=True) print("{0}{1}{2}".format(colors.RED, traceback.format_exc().replace("\033", ""), colors.END), file=sys.stderr) From 239a141d7e7e0ab5fe756ba8b53aa670f7196ce7 Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Mon, 12 Sep 2022 02:04:33 +0200 Subject: [PATCH 14/22] added loguru dependency --- environments/finetuneanon.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/environments/finetuneanon.yml b/environments/finetuneanon.yml index 995bd8fa..5cc53ac8 100644 --- a/environments/finetuneanon.yml +++ b/environments/finetuneanon.yml @@ -23,3 +23,4 @@ dependencies: - flask-cloudflared - flask-ngrok - lupa==1.10 + - loguru From 3ed39f98635feb15be03253c444200032608e03e Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Mon, 12 Sep 2022 02:06:37 +0200 Subject: [PATCH 15/22] loguru to deps --- environments/finetuneanon.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environments/finetuneanon.yml b/environments/finetuneanon.yml index 5cc53ac8..85d5ea66 100644 --- a/environments/finetuneanon.yml +++ b/environments/finetuneanon.yml @@ -18,9 +18,9 @@ dependencies: - git=2.35.1 - marshmallow>=3.13 - apispec-webframeworks + - loguru - pip: - git+https://github.com/finetuneanon/transformers@gpt-neo-localattention3-rp-b - flask-cloudflared - flask-ngrok - lupa==1.10 - - loguru From 68aaef9090da03f0b0708d79c355f96f1ed440e4 Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Mon, 12 Sep 2022 11:49:59 +0200 Subject: [PATCH 16/22] escapig gen/prompt logs so that they stay in one line --- aiserver.py | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/aiserver.py b/aiserver.py index 74888172..45ab66d0 100644 --- a/aiserver.py +++ b/aiserver.py @@ -4280,9 +4280,7 @@ def apiactionsubmit_generate(txt, minimum, maximum): if not vars.quiet: logger.debug(f"Prompt Min:{minimum}, Max:{maximum}") - split_prompt = utils.decodenewlines(tokenizer.decode(txt)).split('\n') - for line in split_prompt: - logger.prompt(line) + logger.prompt(utils.decodenewlines(tokenizer.decode(txt)).encode("unicode_escape").decode("utf-8")) # Clear CUDA cache if using GPU if(vars.hascuda and (vars.usegpu or vars.breakmodel)): @@ -4310,9 +4308,7 @@ def apiactionsubmit_tpumtjgenerate(txt, minimum, maximum): if not vars.quiet: logger.debug(f"Prompt Min:{minimum}, Max:{maximum}") - split_prompt = utils.decodenewlines(tokenizer.decode(txt)).split('\n') - for line in split_prompt: - logger.prompt(line) + logger.prompt(utils.decodenewlines(tokenizer.decode(txt)).encode("unicode_escape").decode("utf-8")) vars._actions = vars.actions vars._prompt = vars.prompt @@ -4825,9 +4821,7 @@ def generate(txt, minimum, maximum, found_entries=None): if not vars.quiet: logger.debug(f"Prompt Min:{minimum}, Max:{maximum}") - split_prompt = utils.decodenewlines(tokenizer.decode(txt)).split('\n') - for line in split_prompt: - logger.prompt(line) + logger.prompt(utils.decodenewlines(tokenizer.decode(txt)).encode("unicode_escape").decode("utf-8")) # Store context in memory to use it for comparison with generated content vars.lastctx = utils.decodenewlines(tokenizer.decode(txt)) @@ -4889,9 +4883,7 @@ def generate(txt, minimum, maximum, found_entries=None): #==================================================================# def genresult(genout, flash=True, ignore_formatting=False): if not vars.quiet: - split_gen = genout.split('\n') - for line in split_gen: - logger.generation(line) + logger.generation(genout.encode("unicode_escape").decode("utf-8")) # Format output before continuing if not ignore_formatting: @@ -4926,9 +4918,7 @@ def genselect(genout): result["generated_text"] = applyoutputformatting(result["generated_text"]) if not vars.quiet: logger.info(f"Generation Result {i}") - split_gen = result["generated_text"].split('\n') - for line in split_gen: - logger.generation(line) + logger.generation(result["generated_text"].encode("unicode_escape").decode("utf-8")) i += 1 # Add the options to the actions metadata @@ -5268,9 +5258,7 @@ def tpumtjgenerate(txt, minimum, maximum, found_entries=None): if not vars.quiet: logger.debug(f"Prompt Min:{minimum}, Max:{maximum}") - split_prompt = utils.decodenewlines(tokenizer.decode(txt)).split('\n') - for line in split_prompt: - logger.prompt(line) + logger.prompt(utils.decodenewlines(tokenizer.decode(txt)).encode("unicode_escape").decode("utf-8")) vars._actions = vars.actions vars._prompt = vars.prompt From c858452740fb2d4e2ce728f51eb39d8c97a61dea Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Mon, 12 Sep 2022 12:00:30 +0200 Subject: [PATCH 17/22] Added logger to fileops --- fileops.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/fileops.py b/fileops.py index c303764e..a416f24d 100644 --- a/fileops.py +++ b/fileops.py @@ -3,6 +3,7 @@ from typing import Tuple, Union, Optional import os import json import zipfile +from logger import logger #==================================================================# # Generic Method for prompting for file path @@ -149,16 +150,16 @@ def getspfiles(model_dimension: int): continue z, version, shape, fortran_order, dtype = checksp(file, model_dimension) if z == 1: - print(f"Browser SP loading error: {file} is malformed or not a soft prompt ZIP file.") + logger.warning(f"Softprompt {file} is malformed or not a soft prompt ZIP file.") continue if z == 2: - print(f"Browser SP loading error: {file} tensor.npy has unsupported dtype '{dtype.name}'.") + logger.warning(f"Softprompt {file} tensor.npy has unsupported dtype '{dtype.name}'.") continue if z == 3: - print(f"Browser SP loading error: {file} tensor.npy has model dimension {shape[1]} which does not match your model's model dimension of {model_dimension}. This usually means this soft prompt is not compatible with your model.") + logger.debug(f"Softprompt {file} tensor.npy has model dimension {shape[1]} which does not match your model's model dimension of {model_dimension}. This usually means this soft prompt is not compatible with your model.") continue if z == 4: - print(f"Browser SP loading error: {file} tensor.npy has {shape[0]} tokens but it is supposed to have less than 2048 tokens.") + logger.warning(f"Softprompt {file} tensor.npy has {shape[0]} tokens but it is supposed to have less than 2048 tokens.") continue assert isinstance(z, zipfile.ZipFile) try: From 86256ca4e30b5c9e6fd0c9ae0e65c2e316ff27af Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Mon, 12 Sep 2022 12:03:38 +0200 Subject: [PATCH 18/22] Made messages the highest priority --- logger.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logger.py b/logger.py index 2b3dceea..e54e1368 100644 --- a/logger.py +++ b/logger.py @@ -37,7 +37,7 @@ logger.level("INIT", no=31, color="") logger.level("INIT_OK", no=31, color="") logger.level("INIT_WARN", no=31, color="") logger.level("INIT_ERR", no=31, color="") -logger.level("MESSAGE", no=20, color="") +logger.level("MESSAGE", no=51, color="") logger.__class__.generation = partialmethod(logger.__class__.log, "GENERATION") logger.__class__.prompt = partialmethod(logger.__class__.log, "PROMPT") From c05e0864c4d762b82fb9a123bcc9e39616546067 Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Mon, 12 Sep 2022 16:30:19 +0200 Subject: [PATCH 19/22] added verbosity controls --- logger.py | 67 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 13 deletions(-) diff --git a/logger.py b/logger.py index e54e1368..2557d730 100644 --- a/logger.py +++ b/logger.py @@ -5,26 +5,65 @@ from loguru import logger STDOUT_LEVELS = ["GENERATION", "PROMPT"] INIT_LEVELS = ["INIT", "INIT_OK", "INIT_WARN", "INIT_ERR"] MESSAGE_LEVELS = ["MESSAGE"] +# By default we're at error level or higher +verbosity = 40 +quiet = 0 + +def set_logger_verbosity(count): + global verbosity + # The count comes reversed. So count = 0 means minimum verbosity + # While count 5 means maximum verbosity + # So the more count we have, the lowe we drop the versbosity maximum + verbosity = 40 - (count * 10) + +def quiesce_logger(count): + global quiet + # The bigger the count, the more silent we want our logger + quiet = count * 10 def is_stdout_log(record): - if record["level"].name in STDOUT_LEVELS: - return(True) - return(False) + if record["level"].name not in STDOUT_LEVELS: + return(False) + if record["level"].no < verbosity + quiet: + return(False) + return(True) def is_init_log(record): - if record["level"].name in INIT_LEVELS: - return(True) - return(False) + if record["level"].name not in INIT_LEVELS: + return(False) + if record["level"].no < verbosity + quiet: + return(False) + return(True) def is_msg_log(record): - if record["level"].name in MESSAGE_LEVELS: - return(True) - return(False) + if record["level"].name not in MESSAGE_LEVELS: + return(False) + if record["level"].no < verbosity + quiet: + return(False) + return(True) def is_stderr_log(record): - if record["level"].name not in STDOUT_LEVELS + INIT_LEVELS + MESSAGE_LEVELS: - return(True) - return(False) + if record["level"].name in STDOUT_LEVELS + INIT_LEVELS + MESSAGE_LEVELS: + return(False) + if record["level"].no < verbosity + quiet: + return(False) + return(True) + +def test_logger(): + logger.generation("This is a generation message\nIt is typically multiline\nThee Lines".encode("unicode_escape").decode("utf-8")) + logger.prompt("This is a prompt message") + logger.debug("Debug Message") + logger.info("Info Message") + logger.warning("Info Warning") + logger.error("Error Message") + logger.critical("Critical Message") + logger.init("This is an init message", status="Starting") + logger.init_ok("This is an init message", status="OK") + logger.init_warn("This is an init message", status="Warning") + logger.init_err("This is an init message", status="Error") + logger.message("This is user message") + sys.exit() + logfmt = "{level: <10} | {name}:{function}:{line} - {message}" genfmt = "{level: <10} @ {time:YYYY-MM-DD HH:mm:ss} | {message}" @@ -37,7 +76,9 @@ logger.level("INIT", no=31, color="") logger.level("INIT_OK", no=31, color="") logger.level("INIT_WARN", no=31, color="") logger.level("INIT_ERR", no=31, color="") -logger.level("MESSAGE", no=51, color="") +# Messages contain important information without which this application might not be able to be used +# As such, they have the highest priority +logger.level("MESSAGE", no=61, color="") logger.__class__.generation = partialmethod(logger.__class__.log, "GENERATION") logger.__class__.prompt = partialmethod(logger.__class__.log, "PROMPT") From 6bc702854f0693cb8609e4e2477761a9d0366e6c Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Mon, 12 Sep 2022 16:47:10 +0200 Subject: [PATCH 20/22] added verbosity controls --- aiserver.py | 7 ++++++- logger.py | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/aiserver.py b/aiserver.py index 45ab66d0..460cac02 100644 --- a/aiserver.py +++ b/aiserver.py @@ -17,7 +17,7 @@ os.environ['TOKENIZERS_PARALLELISM'] = 'false' from eventlet import tpool import logging -from logger import logger +from logger import logger, set_logger_verbosity, quiesce_logger logging.getLogger("urllib3").setLevel(logging.ERROR) @@ -1325,6 +1325,9 @@ def general_startup(override_args=None): parser.add_argument("--savemodel", action='store_true', help="Saves the model to the models folder even if --colab is used (Allows you to save models to Google Drive)") parser.add_argument("--customsettings", help="Preloads arguements from json file. You only need to provide the location of the json file. Use customsettings.json template file. It can be renamed if you wish so that you can store multiple configurations. Leave any settings you want as default as null. Any values you wish to set need to be in double quotation marks") parser.add_argument("--no_ui", action='store_true', default=False, help="Disables the GUI and Socket.IO server while leaving the API server running.") + parser.add_argument('-v', '--verbosity', action='count', default=0, help="The default logging level is ERROR or higher. This value increases the amount of logging seen in your screen") + parser.add_argument('-q', '--quiesce', action='count', default=0, help="The default logging level is ERROR or higher. This value decreases the amount of logging seen in your screen") + #args: argparse.Namespace = None if "pytest" in sys.modules and override_args is None: args = parser.parse_args([]) @@ -1338,6 +1341,8 @@ def general_startup(override_args=None): else: args = parser.parse_args() + set_logger_verbosity(args.verbosity) + quiesce_logger(args.quiesce) if args.customsettings: f = open (args.customsettings) importedsettings = json.load(f) diff --git a/logger.py b/logger.py index 2557d730..8da2aa7e 100644 --- a/logger.py +++ b/logger.py @@ -6,7 +6,7 @@ STDOUT_LEVELS = ["GENERATION", "PROMPT"] INIT_LEVELS = ["INIT", "INIT_OK", "INIT_WARN", "INIT_ERR"] MESSAGE_LEVELS = ["MESSAGE"] # By default we're at error level or higher -verbosity = 40 +verbosity = 20 quiet = 0 def set_logger_verbosity(count): @@ -14,7 +14,7 @@ def set_logger_verbosity(count): # The count comes reversed. So count = 0 means minimum verbosity # While count 5 means maximum verbosity # So the more count we have, the lowe we drop the versbosity maximum - verbosity = 40 - (count * 10) + verbosity = 20 - (count * 10) def quiesce_logger(count): global quiet From 9280102cb327f77932519bee67f2a10ac34004d7 Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Mon, 12 Sep 2022 16:56:09 +0200 Subject: [PATCH 21/22] Moved Flask Startup into __main__ This allows command line arguments to be parsed first --- aiserver.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/aiserver.py b/aiserver.py index 460cac02..5c27d9ce 100644 --- a/aiserver.py +++ b/aiserver.py @@ -402,8 +402,6 @@ import logging log = logging.getLogger('werkzeug') log.setLevel(logging.ERROR) -# Start flask & SocketIO -logger.init("Flask", status="Starting") from flask import Flask, render_template, Response, request, copy_current_request_context, send_from_directory, session, jsonify, abort, redirect from flask_socketio import SocketIO from flask_socketio import emit as _emit @@ -414,9 +412,7 @@ app = Flask(__name__, root_path=os.getcwd()) app.secret_key = secrets.token_hex() app.config['SESSION_TYPE'] = 'filesystem' app.config['TEMPLATES_AUTO_RELOAD'] = True -Session(app) socketio = SocketIO(app, async_method="eventlet") -logger.init_ok("Flask", status="OK") old_socketio_on = socketio.on def new_socketio_on(*a, **k): @@ -9992,9 +9988,13 @@ for schema in config_endpoint_schemas: # Final startup commands to launch Flask app #==================================================================# if __name__ == "__main__": - logger.init("Webserver", status="Starting") general_startup() + # Start flask & SocketIO + logger.init("Flask", status="Starting") + Session(app) + logger.init_ok("Flask", status="OK") + logger.init("Webserver", status="Starting") patch_transformers() #show_select_model_list() if vars.model == "" or vars.model is None: @@ -10067,6 +10067,10 @@ if __name__ == "__main__": else: general_startup() + # Start flask & SocketIO + logger.init("Flask", status="Starting") + Session(app) + logger.init_ok("Flask", status="OK") patch_transformers() #show_select_model_list() if vars.model == "" or vars.model is None: From a75351668fb1635b4cda719ffdb0422e5ab49221 Mon Sep 17 00:00:00 2001 From: Divided by Zer0 Date: Mon, 12 Sep 2022 17:16:10 +0200 Subject: [PATCH 22/22] switched model retrieval and sendtocluster to loguru --- aiserver.py | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/aiserver.py b/aiserver.py index 5c27d9ce..25666245 100644 --- a/aiserver.py +++ b/aiserver.py @@ -72,7 +72,7 @@ global tpu_mtj_backend if lupa.LUA_VERSION[:2] != (5, 4): - logging.error(f"Please install lupa==1.10. You have lupa {lupa.__version__}.") + logger.error(f"Please install lupa==1.10. You have lupa {lupa.__version__}.") patch_causallm_patched = False @@ -626,7 +626,7 @@ def get_config_filename(model_name = None): elif vars.configname != '': return(f"settings/{vars.configname.replace('/', '_')}.settings") else: - print(f"Empty configfile name sent back. Defaulting to ReadOnly") + logger.warning(f"Empty configfile name sent back. Defaulting to ReadOnly") return(f"settings/ReadOnly.settings") #==================================================================# # Function to get model selection at startup @@ -873,7 +873,7 @@ def device_config(config): return if(not breakmodel.gpu_blocks): - print("Nothing assigned to a GPU, reverting to CPU only mode") + logger.warning("Nothing assigned to a GPU, reverting to CPU only mode") import breakmodel breakmodel.primary_device = "cpu" vars.breakmodel = False @@ -1556,7 +1556,7 @@ def get_oai_models(key): return # Get list of models from OAI - print("{0}Retrieving engine list...{1}".format(colors.PURPLE, colors.END), end="") + logger.init("OAI Engines", status="Retrieving") req = requests.get( url, headers = { @@ -1568,7 +1568,7 @@ def get_oai_models(key): try: engines = [[en["id"], "{} ({})".format(en['id'], "Ready" if en["ready"] == True else "Not Ready")] for en in engines] except: - print(engines) + logger.error(engines) raise online_model = "" @@ -1595,11 +1595,12 @@ def get_oai_models(key): js["apikey"] = key file.write(json.dumps(js, indent=3)) + logger.init_ok("OAI Engines", status="OK") emit('from_server', {'cmd': 'oai_engines', 'data': engines, 'online_model': online_model}, broadcast=True) else: # Something went wrong, print the message and quit since we can't initialize an engine - print("{0}ERROR!{1}".format(colors.RED, colors.END)) - print(req.json()) + logger.init_err("OAI Engines", status="Failed") + logger.error(req.json()) emit('from_server', {'cmd': 'errmsg', 'data': req.json()}) def get_cluster_models(msg): @@ -1609,17 +1610,16 @@ def get_cluster_models(msg): # Get list of models from public cluster - print("{0}Retrieving engine list...{1}".format(colors.PURPLE, colors.END), end="") + logger.init("KAI Horde Models", status="Retrieving") req = requests.get("{}/models".format(url)) if(req.status_code == 200): engines = req.json() - print(engines) + logger.debug(engines) try: engines = [[en, en] for en in engines] except: - print(engines) + logger.error(engines) raise - print(engines) online_model = "" changed=False @@ -1645,11 +1645,12 @@ def get_cluster_models(msg): js["apikey"] = vars.oaiapikey file.write(json.dumps(js, indent=3)) + logger.init_ok("KAI Horde Models", status="OK") emit('from_server', {'cmd': 'oai_engines', 'data': engines, 'online_model': online_model}, broadcast=True) else: # Something went wrong, print the message and quit since we can't initialize an engine - print("{0}ERROR!{1}".format(colors.RED, colors.END)) - print(req.json()) + logger.init_err("KAI Horde Models", status="Failed") + logger.error(req.json()) emit('from_server', {'cmd': 'errmsg', 'data': req.json()}) # Function to patch transformers to use our soft prompt @@ -5150,7 +5151,8 @@ def sendtoapi(txt, min, max): def sendtocluster(txt, min, max): # Log request to console if not vars.quiet: - print("{0}Tokens:{1}, Txt:{2}{3}".format(colors.YELLOW, min-1, txt, colors.END)) + logger.debug(f"Tokens Min:{min-1}") + logger.prompt(txt.encode("unicode_escape").decode("utf-8")) # Store context in memory to use it for comparison with generated content vars.lastctx = txt @@ -5185,30 +5187,30 @@ def sendtocluster(txt, min, max): js = req.json() except requests.exceptions.ConnectionError: errmsg = f"Horde unavailable. Please try again later" - print("{0}{1}{2}".format(colors.RED, errmsg, colors.END)) + logger.error(errmsg) emit('from_server', {'cmd': 'errmsg', 'data': errmsg}, broadcast=True) set_aibusy(0) return except requests.exceptions.JSONDecodeError: errmsg = f"Unexpected message received from the Horde: '{req.text}'" - print("{0}{1}{2}".format(colors.RED, errmsg, colors.END)) + logger.error(errmsg) emit('from_server', {'cmd': 'errmsg', 'data': errmsg}, broadcast=True) set_aibusy(0) return if(req.status_code == 503): errmsg = f"KoboldAI API Error: No available KoboldAI servers found in Horde to fulfil this request using the selected models or other properties." - print("{0}{1}{2}".format(colors.RED, json.dumps(js, indent=2), colors.END)) + logger.error(json.dumps(js)) emit('from_server', {'cmd': 'errmsg', 'data': errmsg}, broadcast=True) set_aibusy(0) return if(req.status_code != 200): errmsg = f"KoboldAI API Error: Failed to get a standard reply from the Horde. Please check the console." - print("{0}{1}{2}".format(colors.RED, json.dumps(js, indent=2), colors.END)) + logger.error(json.dumps(js)) emit('from_server', {'cmd': 'errmsg', 'data': errmsg}, broadcast=True) set_aibusy(0) return gen_servers = [(cgen['server_name'],cgen['server_id']) for cgen in js] - print(f"{colors.GREEN}Generations by: {gen_servers}{colors.END}") + logger.info(f"Generations by: {gen_servers}") # Just in case we want to announce it to the user if len(js) == 1: warnmsg = f"Text generated by {js[0]['server_name']}"