From b4c3c4c650fed2e021d7808531c220a8a5359c0f Mon Sep 17 00:00:00 2001 From: JeLuF Date: Sun, 9 Jul 2023 21:18:07 +0200 Subject: [PATCH 01/28] Fix dialog closing when interacting with +
- - - - - + - -2 2   -
+ + diff --git a/ui/media/css/main.css b/ui/media/css/main.css index f806e026..0297228f 100644 --- a/ui/media/css/main.css +++ b/ui/media/css/main.css @@ -1678,3 +1678,7 @@ body.wait-pause { #embeddings-list::-webkit-scrollbar-thumb { background: var(--background-color3); } + +.model_entry .model_name { + width: 70%; +} \ No newline at end of file diff --git a/ui/media/js/auto-save.js b/ui/media/js/auto-save.js index bbcbf9a5..1ff51e2e 100644 --- a/ui/media/js/auto-save.js +++ b/ui/media/js/auto-save.js @@ -16,7 +16,9 @@ const SETTINGS_IDS_LIST = [ "clip_skip", "vae_model", "hypernetwork_model", - "lora_model", + "lora_model_0", + "lora_model_1", + "lora_model_2", "sampler_name", "width", "height", @@ -24,7 +26,9 @@ const SETTINGS_IDS_LIST = [ "guidance_scale", "prompt_strength", "hypernetwork_strength", - "lora_alpha", + "lora_alpha_0", + "lora_alpha_1", + "lora_alpha_2", "tiling", "output_format", "output_quality", @@ -176,13 +180,14 @@ function loadSettings() { // So this is likely the first time Easy Diffusion is running. // Initialize vram_usage_level based on the available VRAM function initGPUProfile(event) { - if ( "detail" in event - && "active" in event.detail - && "cuda:0" in event.detail.active - && event.detail.active["cuda:0"].mem_total <4.5 ) - { - vramUsageLevelField.value = "low" - vramUsageLevelField.dispatchEvent(new Event("change")) + if ( + "detail" in event && + "active" in event.detail && + "cuda:0" in event.detail.active && + event.detail.active["cuda:0"].mem_total < 4.5 + ) { + vramUsageLevelField.value = "low" + vramUsageLevelField.dispatchEvent(new Event("change")) } document.removeEventListener("system_info_update", initGPUProfile) } diff --git a/ui/media/js/dnd.js b/ui/media/js/dnd.js index 4e50b638..7128bc69 100644 --- a/ui/media/js/dnd.js +++ b/ui/media/js/dnd.js @@ -292,29 +292,58 @@ const TASK_MAPPING = { use_lora_model: { name: "LoRA model", setUI: (use_lora_model) => { - const oldVal = loraModelField.value - use_lora_model = - use_lora_model === undefined || use_lora_model === null || use_lora_model === "None" - ? "" - : use_lora_model + use_lora_model.forEach((model_name, i) => { + let field = loraModels[i][0] + const oldVal = field.value - if (use_lora_model !== "") { - use_lora_model = getModelPath(use_lora_model, [".ckpt", ".safetensors"]) - use_lora_model = use_lora_model !== "" ? use_lora_model : oldVal + if (model_name !== "") { + model_name = getModelPath(model_name, [".ckpt", ".safetensors"]) + model_name = model_name !== "" ? model_name : oldVal + } + field.value = model_name + }) + + // clear the remaining entries + for (let i = use_lora_model.length; i < loraModels.length; i++) { + loraModels[i][0].value = "" } - loraModelField.value = use_lora_model }, - readUI: () => loraModelField.value, - parse: (val) => val, + readUI: () => { + let values = loraModels.map((e) => e[0].value) + values = values.filter((e) => e.trim() !== "") + values = values.length > 0 ? values : "None" + return values + }, + parse: (val) => { + val = !val || val === "None" ? "" : val + val = Array.isArray(val) ? val : [val] + return val + }, }, lora_alpha: { name: "LoRA Strength", setUI: (lora_alpha) => { - loraAlphaField.value = lora_alpha - updateLoraAlphaSlider() + lora_alpha.forEach((model_strength, i) => { + let field = loraModels[i][1] + field.value = model_strength + }) + + // clear the remaining entries + for (let i = lora_alpha.length; i < loraModels.length; i++) { + loraModels[i][1].value = 0 + } + }, + readUI: () => { + let models = loraModels.filter((e) => e[0].value.trim() !== "") + let values = models.map((e) => e[1].value) + values = values.length > 0 ? values : 0 + return values + }, + parse: (val) => { + val = Array.isArray(val) ? val : [val] + val = val.map((e) => parseFloat(e)) + return val }, - readUI: () => parseFloat(loraAlphaField.value), - parse: (val) => parseFloat(val), }, use_hypernetwork_model: { name: "Hypernetwork model", @@ -426,8 +455,11 @@ function restoreTaskToUI(task, fieldsToSkip) { } if (!("use_lora_model" in task.reqBody)) { - loraModelField.value = "" - loraModelField.dispatchEvent(new Event("change")) + loraModels.forEach((e) => { + e[0].value = "" + e[1].value = 0 + e[0].dispatchEvent(new Event("change")) + }) } // restore the original prompt if provided (e.g. use settings), fallback to prompt as needed (e.g. copy/paste or d&d) diff --git a/ui/media/js/main.js b/ui/media/js/main.js index b2ebdbed..e31bdd10 100644 --- a/ui/media/js/main.js +++ b/ui/media/js/main.js @@ -103,9 +103,6 @@ let vaeModelField = new ModelDropdown(document.querySelector("#vae_model"), "vae let hypernetworkModelField = new ModelDropdown(document.querySelector("#hypernetwork_model"), "hypernetwork", "None") let hypernetworkStrengthSlider = document.querySelector("#hypernetwork_strength_slider") let hypernetworkStrengthField = document.querySelector("#hypernetwork_strength") -let loraModelField = new ModelDropdown(document.querySelector("#lora_model"), "lora", "None") -let loraAlphaSlider = document.querySelector("#lora_alpha_slider") -let loraAlphaField = document.querySelector("#lora_alpha") let outputFormatField = document.querySelector("#output_format") let outputLosslessField = document.querySelector("#output_lossless") let outputLosslessContainer = document.querySelector("#output_lossless_container") @@ -159,6 +156,8 @@ let undoButton = document.querySelector("#undo") let undoBuffer = [] const UNDO_LIMIT = 20 +let loraModels = [] + imagePreview.addEventListener("drop", function(ev) { const data = ev.dataTransfer?.getData("text/plain") if (!data) { @@ -1292,13 +1291,31 @@ function getCurrentUserRequest() { newTask.reqBody.use_hypernetwork_model = hypernetworkModelField.value newTask.reqBody.hypernetwork_strength = parseFloat(hypernetworkStrengthField.value) } - if (testDiffusers.checked && loraModelField.value) { - newTask.reqBody.use_lora_model = loraModelField.value - newTask.reqBody.lora_alpha = parseFloat(loraAlphaField.value) + if (testDiffusers.checked) { + let [modelNames, modelStrengths] = getModelInfo(loraModels) + + if (modelNames.length > 0) { + modelNames = modelNames.length == 1 ? modelNames[0] : modelNames + modelStrengths = modelStrengths.length == 1 ? modelStrengths[0] : modelStrengths + + newTask.reqBody.use_lora_model = modelNames + newTask.reqBody.lora_alpha = modelStrengths + } } return newTask } +function getModelInfo(models) { + let modelInfo = models.map((e) => [e[0].value, e[1].value]) + modelInfo = modelInfo.filter((e) => e[0].trim() !== "") + modelInfo = modelInfo.map((e) => [e[0], parseFloat(e[1])]) + + let modelNames = modelInfo.map((e) => e[0]) + let modelStrengths = modelInfo.map((e) => e[1]) + + return [modelNames, modelStrengths] +} + function getPrompts(prompts) { if (typeof prompts === "undefined") { prompts = promptField.value @@ -1836,33 +1853,6 @@ function updateHypernetworkStrengthContainer() { hypernetworkModelField.addEventListener("change", updateHypernetworkStrengthContainer) updateHypernetworkStrengthContainer() -/********************* LoRA alpha **********************/ -function updateLoraAlpha() { - loraAlphaField.value = loraAlphaSlider.value / 100 - loraAlphaField.dispatchEvent(new Event("change")) -} - -function updateLoraAlphaSlider() { - if (loraAlphaField.value < -2) { - loraAlphaField.value = -2 - } else if (loraAlphaField.value > 2) { - loraAlphaField.value = 2 - } - - loraAlphaSlider.value = loraAlphaField.value * 100 - loraAlphaSlider.dispatchEvent(new Event("change")) -} - -loraAlphaSlider.addEventListener("input", updateLoraAlpha) -loraAlphaField.addEventListener("input", updateLoraAlphaSlider) -updateLoraAlpha() - -function updateLoraAlphaContainer() { - document.querySelector("#lora_alpha_container").style.display = loraModelField.value === "" ? "none" : "" -} -loraModelField.addEventListener("change", updateLoraAlphaContainer) -updateLoraAlphaContainer() - /********************* JPEG/WEBP Quality **********************/ function updateOutputQuality() { outputQualityField.value = 0 | outputQualitySlider.value @@ -2250,3 +2240,43 @@ prettifyInputs(document) // set the textbox as focused on start promptField.focus() promptField.selectionStart = promptField.value.length + +// multi-models +function addModelEntry(i, modelContainer, modelsList, modelType, defaultValue, minStrength, maxStrength, strengthStep) { + let nameId = modelType + "_model_" + i + let strengthId = modelType + "_alpha_" + i + + const modelEntry = document.createElement("div") + modelEntry.className = "model_entry" + modelEntry.innerHTML = ` + +
+ ` + + let modelName = new ModelDropdown(modelEntry.querySelector(".model_name"), modelType, "None") + let modelStrength = modelEntry.querySelector(".model_strength") + + modelContainer.appendChild(modelEntry) + modelsList.push([modelName, modelStrength]) +} + +function createLoRAEntries() { + let container = document.querySelector("#lora_model_container .model_entries") + for (let i = 0; i < 3; i++) { + addModelEntry(i, container, loraModels, "lora", 0.5, -2, 2, 0.02) + } +} +createLoRAEntries() + +// chrome-like spinners only on hover +function showSpinnerOnlyOnHover(e) { + e.addEventListener("mouseenter", () => { + e.setAttribute("type", "number") + }) + e.addEventListener("mouseleave", () => { + e.removeAttribute("type") + }) + e.removeAttribute("type") +} + +document.querySelectorAll("input[type=number]").forEach(showSpinnerOnlyOnHover) diff --git a/ui/media/js/parameters.js b/ui/media/js/parameters.js index f8dc8066..30b1f33f 100644 --- a/ui/media/js/parameters.js +++ b/ui/media/js/parameters.js @@ -426,7 +426,6 @@ async function getAppConfig() { if (!testDiffusersEnabled) { document.querySelector("#lora_model_container").style.display = "none" - document.querySelector("#lora_alpha_container").style.display = "none" document.querySelector("#tiling_container").style.display = "none" document.querySelectorAll("#sampler_name option.diffusers-only").forEach((option) => { @@ -434,7 +433,6 @@ async function getAppConfig() { }) } else { document.querySelector("#lora_model_container").style.display = "" - document.querySelector("#lora_alpha_container").style.display = loraModelField.value ? "" : "none" document.querySelector("#tiling_container").style.display = "" document.querySelectorAll("#sampler_name option.k_diffusion-only").forEach((option) => { From 7c358c2842413ede1536035cd015fe80a23284ce Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Sat, 15 Jul 2023 19:34:32 +0530 Subject: [PATCH 27/28] changelog --- CHANGES.md | 1 + ui/index.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index f1360942..df8a7b80 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -22,6 +22,7 @@ Our focus continues to remain on an easy installation experience, and an easy user-interface. While still remaining pretty powerful, in terms of features and speed. ### Detailed changelog +* 2.5.44 - 15 Jul 2023 - (beta-only) Support for multiple LoRA files. * 2.5.43 - 9 Jul 2023 - (beta-only) Support for loading Textual Inversion embeddings. You can find the option in the Image Settings panel. Thanks @JeLuf. * 2.5.43 - 9 Jul 2023 - Improve the startup time of the UI. * 2.5.42 - 4 Jul 2023 - Keyboard shortcuts for the Image Editor. Thanks @JeLuf. diff --git a/ui/index.html b/ui/index.html index af7f1fde..7a1cbab2 100644 --- a/ui/index.html +++ b/ui/index.html @@ -31,7 +31,7 @@

Easy Diffusion - v2.5.43 + v2.5.44

From 0d610c5393d52eda0c57f35837bc1c126f2854ad Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Sat, 15 Jul 2023 21:48:51 +0530 Subject: [PATCH 28/28] Remove the +/- 2 limit on lora strengths --- ui/media/js/main.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/media/js/main.js b/ui/media/js/main.js index e31bdd10..70d27fd5 100644 --- a/ui/media/js/main.js +++ b/ui/media/js/main.js @@ -2242,7 +2242,7 @@ promptField.focus() promptField.selectionStart = promptField.value.length // multi-models -function addModelEntry(i, modelContainer, modelsList, modelType, defaultValue, minStrength, maxStrength, strengthStep) { +function addModelEntry(i, modelContainer, modelsList, modelType, defaultValue, strengthStep) { let nameId = modelType + "_model_" + i let strengthId = modelType + "_alpha_" + i @@ -2250,7 +2250,7 @@ function addModelEntry(i, modelContainer, modelsList, modelType, defaultValue, m modelEntry.className = "model_entry" modelEntry.innerHTML = ` -
+
` let modelName = new ModelDropdown(modelEntry.querySelector(".model_name"), modelType, "None") @@ -2263,7 +2263,7 @@ function addModelEntry(i, modelContainer, modelsList, modelType, defaultValue, m function createLoRAEntries() { let container = document.querySelector("#lora_model_container .model_entries") for (let i = 0; i < 3; i++) { - addModelEntry(i, container, loraModels, "lora", 0.5, -2, 2, 0.02) + addModelEntry(i, container, loraModels, "lora", 0.5, 0.02) } } createLoRAEntries()