mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Merge branch 'main' of github.com:invoke-ai/InvokeAI
This commit is contained in:
@ -112,7 +112,7 @@ def main():
|
||||
|
||||
extras = get_extras()
|
||||
|
||||
print(f":crossed_fingers: Upgrading to [yellow]{tag if tag else release}[/yellow]")
|
||||
print(f":crossed_fingers: Upgrading to [yellow]{tag or release or branch}[/yellow]")
|
||||
if release:
|
||||
cmd = f'pip install "invokeai{extras} @ {INVOKE_AI_SRC}/{release}.zip" --use-pep517 --upgrade'
|
||||
elif tag:
|
||||
|
@ -58,6 +58,9 @@ logger = InvokeAILogger.getLogger()
|
||||
# from https://stackoverflow.com/questions/92438/stripping-non-printable-characters-from-a-string-in-python
|
||||
NOPRINT_TRANS_TABLE = {i: None for i in range(0, sys.maxunicode + 1) if not chr(i).isprintable()}
|
||||
|
||||
# maximum number of installed models we can display before overflowing vertically
|
||||
MAX_OTHER_MODELS = 72
|
||||
|
||||
|
||||
def make_printable(s: str) -> str:
|
||||
"""Replace non-printable characters in a string"""
|
||||
@ -102,7 +105,7 @@ class addModelsForm(CyclingForm, npyscreen.FormMultiPage):
|
||||
SingleSelectColumns,
|
||||
values=[
|
||||
"STARTER MODELS",
|
||||
"MORE MODELS",
|
||||
"MAIN MODELS",
|
||||
"CONTROLNETS",
|
||||
"LORA/LYCORIS",
|
||||
"TEXTUAL INVERSION",
|
||||
@ -153,7 +156,7 @@ class addModelsForm(CyclingForm, npyscreen.FormMultiPage):
|
||||
BufferBox,
|
||||
name="Log Messages",
|
||||
editable=False,
|
||||
max_height=8,
|
||||
max_height=15,
|
||||
)
|
||||
|
||||
self.nextrely += 1
|
||||
@ -271,6 +274,11 @@ class addModelsForm(CyclingForm, npyscreen.FormMultiPage):
|
||||
)
|
||||
)
|
||||
|
||||
truncation = False
|
||||
if len(model_labels) > MAX_OTHER_MODELS:
|
||||
model_labels = model_labels[0:MAX_OTHER_MODELS]
|
||||
truncation = True
|
||||
|
||||
widgets.update(
|
||||
models_selected=self.add_widget_intelligent(
|
||||
MultiSelectColumns,
|
||||
@ -289,6 +297,16 @@ class addModelsForm(CyclingForm, npyscreen.FormMultiPage):
|
||||
models=model_list,
|
||||
)
|
||||
|
||||
if truncation:
|
||||
widgets.update(
|
||||
warning_message=self.add_widget_intelligent(
|
||||
npyscreen.FixedText,
|
||||
value=f"Too many models to display (max={MAX_OTHER_MODELS}). Some are not displayed.",
|
||||
editable=False,
|
||||
color="CAUTION",
|
||||
)
|
||||
)
|
||||
|
||||
self.nextrely += 1
|
||||
widgets.update(
|
||||
download_ids=self.add_widget_intelligent(
|
||||
@ -313,7 +331,7 @@ class addModelsForm(CyclingForm, npyscreen.FormMultiPage):
|
||||
widgets = self.add_model_widgets(
|
||||
model_type=model_type,
|
||||
window_width=window_width,
|
||||
install_prompt=f"Additional {model_type.value.title()} models already installed.",
|
||||
install_prompt=f"Installed {model_type.value.title()} models. Unchecked models in the InvokeAI root directory will be deleted. Enter URLs, paths or repo_ids to import.",
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -399,7 +417,7 @@ class addModelsForm(CyclingForm, npyscreen.FormMultiPage):
|
||||
self.ok_button.hidden = True
|
||||
self.display()
|
||||
|
||||
# for communication with the subprocess
|
||||
# TO DO: Spawn a worker thread, not a subprocess
|
||||
parent_conn, child_conn = Pipe()
|
||||
p = Process(
|
||||
target=process_and_execute,
|
||||
@ -414,7 +432,6 @@ class addModelsForm(CyclingForm, npyscreen.FormMultiPage):
|
||||
self.subprocess_connection = parent_conn
|
||||
self.subprocess = p
|
||||
app.install_selections = InstallSelections()
|
||||
# process_and_execute(app.opt, app.install_selections)
|
||||
|
||||
def on_back(self):
|
||||
self.parentApp.switchFormPrevious()
|
||||
@ -489,8 +506,6 @@ class addModelsForm(CyclingForm, npyscreen.FormMultiPage):
|
||||
|
||||
# rebuild the form, saving and restoring some of the fields that need to be preserved.
|
||||
saved_messages = self.monitor.entry_widget.values
|
||||
# autoload_dir = str(config.root_path / self.pipeline_models['autoload_directory'].value)
|
||||
# autoscan = self.pipeline_models['autoscan_on_startup'].value
|
||||
|
||||
app.main_form = app.addForm(
|
||||
"MAIN",
|
||||
@ -544,12 +559,6 @@ class addModelsForm(CyclingForm, npyscreen.FormMultiPage):
|
||||
if downloads := section.get("download_ids"):
|
||||
selections.install_models.extend(downloads.value.split())
|
||||
|
||||
# load directory and whether to scan on startup
|
||||
# if self.parentApp.autoload_pending:
|
||||
# selections.scan_directory = str(config.root_path / self.pipeline_models['autoload_directory'].value)
|
||||
# self.parentApp.autoload_pending = False
|
||||
# selections.autoscan_on_startup = self.pipeline_models['autoscan_on_startup'].value
|
||||
|
||||
|
||||
class AddModelApplication(npyscreen.NPSAppManaged):
|
||||
def __init__(self, opt):
|
||||
@ -639,6 +648,10 @@ def process_and_execute(
|
||||
selections: InstallSelections,
|
||||
conn_out: Connection = None,
|
||||
):
|
||||
# need to reinitialize config in subprocess
|
||||
config = InvokeAIAppConfig.get_config()
|
||||
config.parse_args()
|
||||
|
||||
# set up so that stderr is sent to conn_out
|
||||
if conn_out:
|
||||
translator = StderrToMessage(conn_out)
|
||||
@ -656,38 +669,11 @@ def process_and_execute(
|
||||
conn_out.close()
|
||||
|
||||
|
||||
def do_listings(opt) -> bool:
|
||||
"""List installed models of various sorts, and return
|
||||
True if any were requested."""
|
||||
model_manager = ModelManager(config.model_conf_path)
|
||||
if opt.list_models == "diffusers":
|
||||
print("Diffuser models:")
|
||||
model_manager.print_models()
|
||||
elif opt.list_models == "controlnets":
|
||||
print("Installed Controlnet Models:")
|
||||
cnm = model_manager.list_controlnet_models()
|
||||
print(textwrap.indent("\n".join([x for x in cnm if cnm[x]]), prefix=" "))
|
||||
elif opt.list_models == "loras":
|
||||
print("Installed LoRA/LyCORIS Models:")
|
||||
cnm = model_manager.list_lora_models()
|
||||
print(textwrap.indent("\n".join([x for x in cnm if cnm[x]]), prefix=" "))
|
||||
elif opt.list_models == "tis":
|
||||
print("Installed Textual Inversion Embeddings:")
|
||||
cnm = model_manager.list_ti_models()
|
||||
print(textwrap.indent("\n".join([x for x in cnm if cnm[x]]), prefix=" "))
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
# --------------------------------------------------------
|
||||
def select_and_download_models(opt: Namespace):
|
||||
precision = "float32" if opt.full_precision else choose_precision(torch.device(choose_torch_device()))
|
||||
config.precision = precision
|
||||
helper = lambda x: ask_user_for_prediction_type(x)
|
||||
# if do_listings(opt):
|
||||
# pass
|
||||
|
||||
installer = ModelInstall(config, prediction_type_helper=helper)
|
||||
if opt.list_models:
|
||||
installer.list_models(opt.list_models)
|
||||
@ -706,8 +692,6 @@ def select_and_download_models(opt: Namespace):
|
||||
# needed to support the probe() method running under a subprocess
|
||||
torch.multiprocessing.set_start_method("spawn")
|
||||
|
||||
# the third argument is needed in the Windows 11 environment in
|
||||
# order to launch and resize a console window running this program
|
||||
set_min_terminal_size(MIN_COLS, MIN_LINES)
|
||||
installApp = AddModelApplication(opt)
|
||||
try:
|
||||
|
Reference in New Issue
Block a user