From 21553316f21fc10646273fdf27d7073e4b0116c2 Mon Sep 17 00:00:00 2001 From: m957ymj75urz Date: Thu, 9 Mar 2023 18:02:03 +0100 Subject: [PATCH 01/32] add batch count to the menu --- web/scripts/app.js | 40 +++++++++++++++++++++------------------- web/scripts/ui.js | 9 +++++++-- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/web/scripts/app.js b/web/scripts/app.js index 1cf81b8f9..8dd76f398 100644 --- a/web/scripts/app.js +++ b/web/scripts/app.js @@ -641,31 +641,33 @@ class ComfyApp { return { workflow, output }; } - async queuePrompt(number) { - const p = await this.graphToPrompt(); + async queuePrompt(number, batchCount = 1) { + for (let i = 0; i < batchCount; i++) { + const p = await this.graphToPrompt(); - try { - await api.queuePrompt(number, p); - } catch (error) { - this.ui.dialog.show(error.response || error.toString()); - return; - } + try { + await api.queuePrompt(number, p); + } catch (error) { + this.ui.dialog.show(error.response || error.toString()); + return; + } - for (const n of p.workflow.nodes) { - const node = graph.getNodeById(n.id); - if (node.widgets) { - for (const widget of node.widgets) { - // Allow widgets to run callbacks after a prompt has been queued - // e.g. random seed after every gen - if (widget.afterQueued) { - widget.afterQueued(); + for (const n of p.workflow.nodes) { + const node = graph.getNodeById(n.id); + if (node.widgets) { + for (const widget of node.widgets) { + // Allow widgets to run callbacks after a prompt has been queued + // e.g. random seed after every gen + if (widget.afterQueued) { + widget.afterQueued(); + } } } } - } - this.canvas.draw(true, true); - await this.ui.queue.update(); + this.canvas.draw(true, true); + await this.ui.queue.update(); + } } /** diff --git a/web/scripts/ui.js b/web/scripts/ui.js index 2c5a75f39..f839fef29 100644 --- a/web/scripts/ui.js +++ b/web/scripts/ui.js @@ -254,9 +254,14 @@ export class ComfyUI { $el("span", { $: (q) => (this.queueSize = q) }), $el("button.comfy-settings-btn", { textContent: "⚙️", onclick: () => this.settings.show() }), ]), - $el("button.comfy-queue-btn", { textContent: "Queue Prompt", onclick: () => app.queuePrompt(0) }), + $el("div", { style: { width: "100%" }}, [ + $el("label", { innerHTML: "Batch count" }, [ + $el("input", { type: "number", value: "1", min: "1", style: { width: "30%", "margin-left": "0.4em" }, onchange: (i) => this.batchCount = i.target.value }) + ]), + ]), + $el("button.comfy-queue-btn", { textContent: "Queue Prompt", onclick: () => app.queuePrompt(0, this.batchCount) }), $el("div.comfy-menu-btns", [ - $el("button", { textContent: "Queue Front", onclick: () => app.queuePrompt(-1) }), + $el("button", { textContent: "Queue Front", onclick: () => app.queuePrompt(-1, this.batchCount) }), $el("button", { $: (b) => (this.queue.button = b), textContent: "View Queue", From 67795e40850ec0585cbb517858f8914a327dc477 Mon Sep 17 00:00:00 2001 From: m957ymj75urz Date: Fri, 10 Mar 2023 10:38:35 +0100 Subject: [PATCH 02/32] added a range input --- web/scripts/ui.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/web/scripts/ui.js b/web/scripts/ui.js index f839fef29..1ba95bb40 100644 --- a/web/scripts/ui.js +++ b/web/scripts/ui.js @@ -231,6 +231,7 @@ export class ComfyUI { this.dialog = new ComfyDialog(); this.settings = new ComfySettingsDialog(); + this.batchCount = 1; this.queue = new ComfyList("Queue"); this.history = new ComfyList("History"); @@ -256,7 +257,20 @@ export class ComfyUI { ]), $el("div", { style: { width: "100%" }}, [ $el("label", { innerHTML: "Batch count" }, [ - $el("input", { type: "number", value: "1", min: "1", style: { width: "30%", "margin-left": "0.4em" }, onchange: (i) => this.batchCount = i.target.value }) + $el("input", { id: "batchCountInputNumber", type: "number", value: this.batchCount, min: "1", style: { width: "35%", "margin-left": "0.4em" }, + oninput: (i) => { + this.batchCount = i.target.value; + document.getElementById('batchCountInputRange').value = this.batchCount; + console.log("number"); + } + }), + $el("input", { id: "batchCountInputRange", type: "range", min: "1", max: "100", value: this.batchCount, + oninput: (i) => { + this.batchCount = i.srcElement.value; + document.getElementById('batchCountInputNumber').value = i.srcElement.value; + console.log("range"); + } + }), ]), ]), $el("button.comfy-queue-btn", { textContent: "Queue Prompt", onclick: () => app.queuePrompt(0, this.batchCount) }), From 6db777b3489798740c0ffdc6f503fe4279f2c435 Mon Sep 17 00:00:00 2001 From: pythongosssss <125205205+pythongosssss@users.noreply.github.com> Date: Mon, 13 Mar 2023 19:34:05 +0000 Subject: [PATCH 03/32] Added ability to save images to temp dir --- main.py | 9 +++++++++ nodes.py | 21 ++++++++++++++++++--- server.py | 2 +- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/main.py b/main.py index b2b3f1c40..889e2cef7 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,6 @@ import os import sys +import shutil import threading import asyncio @@ -53,7 +54,14 @@ def hijack_progress(server): return v setattr(tqdm, "update", wrapped_func) +def cleanup_temp(): + temp_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "temp") + if os.path.exists(temp_dir): + shutil.rmtree(temp_dir) + if __name__ == "__main__": + cleanup_temp() + loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) server = server.PromptServer(loop) @@ -93,3 +101,4 @@ if __name__ == "__main__": else: loop.run_until_complete(run(server, address=address, port=port, verbose=not dont_print, call_on_start=call_on_start)) + cleanup_temp() diff --git a/nodes.py b/nodes.py index 0a0a0a9cd..b201c352c 100644 --- a/nodes.py +++ b/nodes.py @@ -775,12 +775,14 @@ class KSamplerAdvanced: class SaveImage: def __init__(self): self.output_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "output") + self.temp_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "temp") @classmethod def INPUT_TYPES(s): return {"required": {"images": ("IMAGE", ), - "filename_prefix": ("STRING", {"default": "ComfyUI"})}, + "filename_prefix": ("STRING", {"default": "ComfyUI"}), + "use_temp_file": (["yes", "no"], {"default" : "no"} ),}, "hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"}, } @@ -791,7 +793,7 @@ class SaveImage: CATEGORY = "image" - def save_images(self, images, filename_prefix="ComfyUI", prompt=None, extra_pnginfo=None): + def save_images(self, images, filename_prefix="ComfyUI", use_temp_file="no", prompt=None, extra_pnginfo=None): def map_filename(filename): prefix_len = len(filename_prefix) prefix = filename[:prefix_len + 1] @@ -818,8 +820,21 @@ class SaveImage: if extra_pnginfo is not None: for x in extra_pnginfo: metadata.add_text(x, json.dumps(extra_pnginfo[x])) + file = f"{filename_prefix}_{counter:05}_.png" - img.save(os.path.join(self.output_dir, file), pnginfo=metadata, optimize=True) + + if use_temp_file == "yes": + if not os.path.exists(self.temp_dir): + os.makedirs(self.temp_dir) + dir = self.temp_dir + else: + dir = self.output_dir + + img.save(os.path.join(dir, file), pnginfo=metadata, optimize=True) + + if use_temp_file == "yes": + file += "?type=temp" + paths.append(file) counter += 1 return { "ui": { "images": paths } } diff --git a/server.py b/server.py index a29d85974..eb6857010 100644 --- a/server.py +++ b/server.py @@ -113,7 +113,7 @@ class PromptServer(): async def view_image(request): if "file" in request.match_info: type = request.rel_url.query.get("type", "output") - if type != "output" and type != "input": + if type not in ["output", "input", "temp"]: return web.Response(status=400) output_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), type) From e5318d918cde493eb2100bd308cf76425d828da1 Mon Sep 17 00:00:00 2001 From: pythongosssss <125205205+pythongosssss@users.noreply.github.com> Date: Mon, 13 Mar 2023 19:34:29 +0000 Subject: [PATCH 04/32] Combo support detault value --- web/scripts/app.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/web/scripts/app.js b/web/scripts/app.js index e70e1c157..8b832eba1 100644 --- a/web/scripts/app.js +++ b/web/scripts/app.js @@ -497,7 +497,11 @@ class ComfyApp { if (Array.isArray(type)) { // Enums e.g. latent rotation - this.addWidget("combo", inputName, type[0], () => {}, { values: type }); + let defaultValue = type[0]; + if (inputData[1] && inputData[1].default) { + defaultValue = inputData[1].default; + } + this.addWidget("combo", inputName, defaultValue, () => {}, { values: type }); } else if (`${type}:${inputName}` in widgets) { // Support custom widgets by Type:Name Object.assign(config, widgets[`${type}:${inputName}`](this, inputName, inputData, app) || {}); From ee46bef03a98903831c01d31094a0c30ea411b28 Mon Sep 17 00:00:00 2001 From: comfyanonymous Date: Mon, 13 Mar 2023 21:30:01 -0400 Subject: [PATCH 05/32] Make --cpu have priority over everything else. --- comfy/model_management.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/comfy/model_management.py b/comfy/model_management.py index 482b1add9..c26d682f7 100644 --- a/comfy/model_management.py +++ b/comfy/model_management.py @@ -50,8 +50,6 @@ if "--use-pytorch-cross-attention" in sys.argv: XFORMERS_IS_AVAILBLE = False -if "--cpu" in sys.argv: - vram_state = CPU if "--lowvram" in sys.argv: set_vram_to = LOW_VRAM if "--novram" in sys.argv: @@ -73,6 +71,8 @@ if set_vram_to == LOW_VRAM or set_vram_to == NO_VRAM: total_vram_available_mb = (total_vram - 1024) // 2 total_vram_available_mb = int(max(256, total_vram_available_mb)) +if "--cpu" in sys.argv: + vram_state = CPU print("Set vram state to:", ["CPU", "NO VRAM", "LOW VRAM", "NORMAL VRAM", "HIGH VRAM"][vram_state]) From a1b30f102be4989fb31132f11415c9dcd2ab2705 Mon Sep 17 00:00:00 2001 From: m957ymj75urz Date: Tue, 14 Mar 2023 08:16:48 +0100 Subject: [PATCH 06/32] toggle extra options --- web/scripts/ui.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/web/scripts/ui.js b/web/scripts/ui.js index 1ba95bb40..8134e3415 100644 --- a/web/scripts/ui.js +++ b/web/scripts/ui.js @@ -255,25 +255,28 @@ export class ComfyUI { $el("span", { $: (q) => (this.queueSize = q) }), $el("button.comfy-settings-btn", { textContent: "⚙️", onclick: () => this.settings.show() }), ]), - $el("div", { style: { width: "100%" }}, [ + $el("button.comfy-queue-btn", { textContent: "Queue Prompt", onclick: () => app.queuePrompt(0, this.batchCount) }), + $el("div", {}, [ + $el("label", { innerHTML: "Extra options"}, [ + $el("input", { type: "checkbox", onchange: (i) => document.getElementById('extraOptions').style.visibility = i.srcElement.checked ? "visible" : "collapse" }) + ]) + ]), + $el("div", { id: "extraOptions", style: { width: "100%", visibility: "collapse" }}, [ $el("label", { innerHTML: "Batch count" }, [ $el("input", { id: "batchCountInputNumber", type: "number", value: this.batchCount, min: "1", style: { width: "35%", "margin-left": "0.4em" }, oninput: (i) => { this.batchCount = i.target.value; document.getElementById('batchCountInputRange').value = this.batchCount; - console.log("number"); } }), $el("input", { id: "batchCountInputRange", type: "range", min: "1", max: "100", value: this.batchCount, oninput: (i) => { this.batchCount = i.srcElement.value; document.getElementById('batchCountInputNumber').value = i.srcElement.value; - console.log("range"); } }), ]), ]), - $el("button.comfy-queue-btn", { textContent: "Queue Prompt", onclick: () => app.queuePrompt(0, this.batchCount) }), $el("div.comfy-menu-btns", [ $el("button", { textContent: "Queue Front", onclick: () => app.queuePrompt(-1, this.batchCount) }), $el("button", { From ca25f0c0c15e0a622e508bd22aab4c0d58faeefb Mon Sep 17 00:00:00 2001 From: comfyanonymous Date: Tue, 14 Mar 2023 13:39:58 -0400 Subject: [PATCH 07/32] Update standalone readme with recommended way to update. --- .ci/nightly/windows_base_files/README_VERY_IMPORTANT.txt | 6 +++++- .ci/windows_base_files/README_VERY_IMPORTANT.txt | 7 +++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.ci/nightly/windows_base_files/README_VERY_IMPORTANT.txt b/.ci/nightly/windows_base_files/README_VERY_IMPORTANT.txt index 3c73a27ac..4c6a20a7a 100755 --- a/.ci/nightly/windows_base_files/README_VERY_IMPORTANT.txt +++ b/.ci/nightly/windows_base_files/README_VERY_IMPORTANT.txt @@ -18,5 +18,9 @@ You can download the stable diffusion 1.5 one from: https://huggingface.co/runwa +RECOMMENDED WAY TO UPDATE: To update only the ComfyUI code: update\update_comfyui_only.bat -To update ComfyUI with the python dependencies: update\update_all.bat + + + +To update ComfyUI with the python dependencies (ONLY USE IF YOU NEED TO UPDATE THE PYTHON PACKAGES): update\update_all.bat diff --git a/.ci/windows_base_files/README_VERY_IMPORTANT.txt b/.ci/windows_base_files/README_VERY_IMPORTANT.txt index 3c73a27ac..69520db98 100755 --- a/.ci/windows_base_files/README_VERY_IMPORTANT.txt +++ b/.ci/windows_base_files/README_VERY_IMPORTANT.txt @@ -17,6 +17,9 @@ IF YOU GET A RED ERROR IN THE UI MAKE SURE YOU HAVE A MODEL/CHECKPOINT IN: Comfy You can download the stable diffusion 1.5 one from: https://huggingface.co/runwayml/stable-diffusion-v1-5/blob/main/v1-5-pruned-emaonly.ckpt - +RECOMMENDED WAY TO UPDATE: To update only the ComfyUI code: update\update_comfyui_only.bat -To update ComfyUI with the python dependencies: update\update_all.bat + + + +To update ComfyUI with the python dependencies (ONLY USE IF YOU NEED TO UPDATE THE PYTHON PACKAGES): update\update_all.bat From 6a6256a75c39c0e945db40670e2855808c2f4663 Mon Sep 17 00:00:00 2001 From: pythongosssss <125205205+pythongosssss@users.noreply.github.com> Date: Tue, 14 Mar 2023 19:28:07 +0000 Subject: [PATCH 08/32] Changed flag to new node --- nodes.py | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/nodes.py b/nodes.py index b201c352c..b5aa3efe0 100644 --- a/nodes.py +++ b/nodes.py @@ -775,14 +775,13 @@ class KSamplerAdvanced: class SaveImage: def __init__(self): self.output_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "output") - self.temp_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "temp") + self.url_suffix = "" @classmethod def INPUT_TYPES(s): return {"required": {"images": ("IMAGE", ), - "filename_prefix": ("STRING", {"default": "ComfyUI"}), - "use_temp_file": (["yes", "no"], {"default" : "no"} ),}, + "filename_prefix": ("STRING", {"default": "ComfyUI"}),}, "hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"}, } @@ -810,6 +809,9 @@ class SaveImage: os.mkdir(self.output_dir) counter = 1 + if not os.path.exists(self.output_dir): + os.makedirs(self.output_dir) + paths = list() for image in images: i = 255. * image.cpu().numpy() @@ -820,25 +822,24 @@ class SaveImage: if extra_pnginfo is not None: for x in extra_pnginfo: metadata.add_text(x, json.dumps(extra_pnginfo[x])) - file = f"{filename_prefix}_{counter:05}_.png" - - if use_temp_file == "yes": - if not os.path.exists(self.temp_dir): - os.makedirs(self.temp_dir) - dir = self.temp_dir - else: - dir = self.output_dir - - img.save(os.path.join(dir, file), pnginfo=metadata, optimize=True) - - if use_temp_file == "yes": - file += "?type=temp" - - paths.append(file) + img.save(os.path.join(self.output_dir, file), pnginfo=metadata, optimize=True) + paths.append(file + self.url_suffix) counter += 1 return { "ui": { "images": paths } } +class PreviewImage(SaveImage): + def __init__(self): + self.output_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "temp") + self.url_suffix = "?type=temp" + + @classmethod + def INPUT_TYPES(s): + return {"required": + {"images": ("IMAGE", ), }, + "hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"}, + } + class LoadImage: input_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "input") @classmethod @@ -959,6 +960,7 @@ NODE_CLASS_MAPPINGS = { "EmptyLatentImage": EmptyLatentImage, "LatentUpscale": LatentUpscale, "SaveImage": SaveImage, + "PreviewImage": PreviewImage, "LoadImage": LoadImage, "LoadImageMask": LoadImageMask, "ImageScale": ImageScale, From 94a279373bf5104b9ad9ac2bc6da3e8bbe1e5141 Mon Sep 17 00:00:00 2001 From: pythongosssss <125205205+pythongosssss@users.noreply.github.com> Date: Tue, 14 Mar 2023 19:39:49 +0000 Subject: [PATCH 09/32] Better auto pos of images --- web/scripts/app.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/web/scripts/app.js b/web/scripts/app.js index 8b832eba1..445bc5d4b 100644 --- a/web/scripts/app.js +++ b/web/scripts/app.js @@ -142,7 +142,14 @@ class ComfyApp { if (numImages === 1 && !imageIndex) { this.imageIndex = imageIndex = 0; } - let shiftY = this.type === "SaveImage" ? 55 : this.imageOffset || 0; + + let shiftY; + if (this.imageOffset != null) { + shiftY = this.imageOffset; + } else { + shiftY = this.computeSize()[1]; + } + let dw = this.size[0]; let dh = this.size[1]; dh -= shiftY; From 8537ab6f45cdfe060e5fc3fb4aff87a35a0b9072 Mon Sep 17 00:00:00 2001 From: pythongosssss <125205205+pythongosssss@users.noreply.github.com> Date: Tue, 14 Mar 2023 19:42:28 +0000 Subject: [PATCH 10/32] tidy --- nodes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nodes.py b/nodes.py index b5aa3efe0..650d7f65d 100644 --- a/nodes.py +++ b/nodes.py @@ -781,7 +781,7 @@ class SaveImage: def INPUT_TYPES(s): return {"required": {"images": ("IMAGE", ), - "filename_prefix": ("STRING", {"default": "ComfyUI"}),}, + "filename_prefix": ("STRING", {"default": "ComfyUI"})}, "hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"}, } @@ -792,7 +792,7 @@ class SaveImage: CATEGORY = "image" - def save_images(self, images, filename_prefix="ComfyUI", use_temp_file="no", prompt=None, extra_pnginfo=None): + def save_images(self, images, filename_prefix="ComfyUI", prompt=None, extra_pnginfo=None): def map_filename(filename): prefix_len = len(filename_prefix) prefix = filename[:prefix_len + 1] From 255ff2d6ddd34b377a31e247fde9b2afa2cff730 Mon Sep 17 00:00:00 2001 From: pythongosssss <125205205+pythongosssss@users.noreply.github.com> Date: Tue, 14 Mar 2023 20:29:18 +0000 Subject: [PATCH 11/32] Added ctrl+enter to queue prompt --- web/scripts/app.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/web/scripts/app.js b/web/scripts/app.js index e70e1c157..6703908da 100644 --- a/web/scripts/app.js +++ b/web/scripts/app.js @@ -398,6 +398,15 @@ class ComfyApp { api.init(); } + #addKeyboardHandler() { + window.addEventListener("keydown", (e) => { + // Queue prompt using ctrl or command + enter + if ((e.ctrlKey || e.metaKey) && (e.key === "Enter" || e.keyCode === 13 || e.keyCode === 10)) { + this.queuePrompt(0); + } + }); + } + /** * Loads all extensions from the API into the window */ @@ -464,6 +473,7 @@ class ComfyApp { this.#addApiUpdateHandlers(); this.#addDropHandler(); this.#addPasteHandler(); + this.#addKeyboardHandler(); await this.#invokeExtensionsAsync("setup"); } From 01ec3db9324a6c2a3ac2bdc6b99ed729528a10e1 Mon Sep 17 00:00:00 2001 From: pythongosssss <125205205+pythongosssss@users.noreply.github.com> Date: Tue, 14 Mar 2023 20:31:27 +0000 Subject: [PATCH 12/32] Add ctrl+shift+enter for queue front --- web/scripts/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/scripts/app.js b/web/scripts/app.js index 6703908da..942fc9028 100644 --- a/web/scripts/app.js +++ b/web/scripts/app.js @@ -402,7 +402,7 @@ class ComfyApp { window.addEventListener("keydown", (e) => { // Queue prompt using ctrl or command + enter if ((e.ctrlKey || e.metaKey) && (e.key === "Enter" || e.keyCode === 13 || e.keyCode === 10)) { - this.queuePrompt(0); + this.queuePrompt(e.shiftKey ? -1 : 0); } }); } From f2a6cff466c4e0d91adc6b42ec2c071a4f48cc8c Mon Sep 17 00:00:00 2001 From: pythongosssss <125205205+pythongosssss@users.noreply.github.com> Date: Tue, 14 Mar 2023 21:13:29 +0000 Subject: [PATCH 13/32] Add dragdrop handling to nodes with upload widget --- web/scripts/app.js | 51 +++++++++++++++++++++----- web/scripts/widgets.js | 81 +++++++++++++++++++++++++++++------------- 2 files changed, 99 insertions(+), 33 deletions(-) diff --git a/web/scripts/app.js b/web/scripts/app.js index e70e1c157..80a4eb35f 100644 --- a/web/scripts/app.js +++ b/web/scripts/app.js @@ -284,9 +284,37 @@ class ComfyApp { document.addEventListener("drop", async (event) => { event.preventDefault(); event.stopPropagation(); - const file = event.dataTransfer.files[0]; - await this.handleFile(file); + + const n = this.dragOverNode; + this.dragOverNode = null; + // Node handles file drop, we dont use the built in onDropFile handler as its buggy + // If you drag multiple files it will call it multiple times with the same file + if (n && n.onDragDrop && await n.onDragDrop(event)) { + return; + } + + await this.handleFile(event.dataTransfer.files[0]); }); + + // Add handler for dropping onto a specific node + this.canvasEl.addEventListener( + "dragover", + (e) => { + this.canvas.adjustMouseEvent(e); + const node = this.graph.getNodeOnPos(e.canvasX, e.canvasY); + if (node) { + if (node.onDragOver && node.onDragOver(e)) { + this.dragOverNode = node; + requestAnimationFrame(() => { + this.graph.setDirtyCanvas(false, true); + }); + return; + } + } + this.dragOverNode = null; + }, + false + ); } /** @@ -314,15 +342,22 @@ class ComfyApp { } /** - * Draws currently executing node highlight and progress bar + * Draws currently node highlights and progress bar */ - #addDrawNodeProgressHandler() { + #addDrawNodeHandler() { const orig = LGraphCanvas.prototype.drawNodeShape; const self = this; LGraphCanvas.prototype.drawNodeShape = function (node, ctx, size, fgcolor, bgcolor, selected, mouse_over) { const res = orig.apply(this, arguments); - if (node.id + "" === self.runningNodeId) { + let color = null; + if (node.id === +self.runningNodeId) { + color = "#0f0"; + } else if (self.dragOverNode && node.id === self.dragOverNode.id) { + color = "dodgerblue"; + } + + if (color) { const shape = node._shape || node.constructor.shape || LiteGraph.ROUND_SHAPE; ctx.lineWidth = 1; ctx.globalAlpha = 0.8; @@ -348,7 +383,7 @@ class ComfyApp { ); else if (shape == LiteGraph.CIRCLE_SHAPE) ctx.arc(size[0] * 0.5, size[1] * 0.5, size[0] * 0.5 + 6, 0, Math.PI * 2); - ctx.strokeStyle = "#0f0"; + ctx.strokeStyle = color; ctx.stroke(); ctx.strokeStyle = fgcolor; ctx.globalAlpha = 1; @@ -419,7 +454,7 @@ class ComfyApp { await this.#loadExtensions(); // Create and mount the LiteGraph in the DOM - const canvasEl = Object.assign(document.createElement("canvas"), { id: "graph-canvas" }); + const canvasEl = (this.canvasEl = Object.assign(document.createElement("canvas"), { id: "graph-canvas" })); document.body.prepend(canvasEl); this.graph = new LGraph(); @@ -460,7 +495,7 @@ class ComfyApp { // Save current workflow automatically setInterval(() => localStorage.setItem("workflow", JSON.stringify(this.graph.serialize())), 1000); - this.#addDrawNodeProgressHandler(); + this.#addDrawNodeHandler(); this.#addApiUpdateHandlers(); this.#addDropHandler(); this.#addPasteHandler(); diff --git a/web/scripts/widgets.js b/web/scripts/widgets.js index 55bdd8f18..3c4641964 100644 --- a/web/scripts/widgets.js +++ b/web/scripts/widgets.js @@ -132,7 +132,7 @@ export const ComfyWidgets = { function showImage(name) { // Position the image somewhere sensible - if(!node.imageOffset) { + if (!node.imageOffset) { node.imageOffset = uploadWidget.last_y ? uploadWidget.last_y + 25 : 75; } @@ -162,6 +162,36 @@ export const ComfyWidgets = { } }); + async function uploadFile(file, updateNode) { + try { + // Wrap file in formdata so it includes filename + const body = new FormData(); + body.append("image", file); + const resp = await fetch("/upload/image", { + method: "POST", + body, + }); + + if (resp.status === 200) { + const data = await resp.json(); + // Add the file as an option and update the widget value + if (!imageWidget.options.values.includes(data.name)) { + imageWidget.options.values.push(data.name); + } + + if (updateNode) { + showImage(data.name); + + imageWidget.value = data.name; + } + } else { + alert(resp.status + " - " + resp.statusText); + } + } catch (error) { + alert(error); + } + } + const fileInput = document.createElement("input"); Object.assign(fileInput, { type: "file", @@ -169,30 +199,7 @@ export const ComfyWidgets = { style: "display: none", onchange: async () => { if (fileInput.files.length) { - try { - // Wrap file in formdata so it includes filename - const body = new FormData(); - body.append("image", fileInput.files[0]); - const resp = await fetch("/upload/image", { - method: "POST", - body, - }); - - if (resp.status === 200) { - const data = await resp.json(); - showImage(data.name); - - // Add the file as an option and update the widget value - if (!imageWidget.options.values.includes(data.name)) { - imageWidget.options.values.push(data.name); - } - imageWidget.value = data.name; - } else { - alert(resp.status + " - " + resp.statusText); - } - } catch (error) { - alert(error); - } + await uploadFile(fileInput.files[0], true); } }, }); @@ -204,6 +211,30 @@ export const ComfyWidgets = { }); uploadWidget.serialize = false; + // Add handler to check if an image is being dragged over our node + node.onDragOver = function (e) { + if (e.dataTransfer && e.dataTransfer.items) { + const image = [...e.dataTransfer.items].find((f) => f.kind === "file" && f.type.startsWith("image/")); + return !!image; + } + + return false; + }; + + // On drop upload files + node.onDragDrop = function (e) { + console.log("onDragDrop called"); + let handled = false; + for (const file of e.dataTransfer.files) { + if (file.type.startsWith("image/")) { + uploadFile(file, !handled); // Dont await these, any order is fine, only update on first one + handled = true; + } + } + + return handled; + }; + return { widget: uploadWidget }; }, }; From 019bd519cb12b0be8dc5d24bb14dc95712350729 Mon Sep 17 00:00:00 2001 From: pythongosssss <125205205+pythongosssss@users.noreply.github.com> Date: Tue, 14 Mar 2023 21:21:50 +0000 Subject: [PATCH 14/32] Add dragleave handler to remove stuck highlight --- web/scripts/app.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/web/scripts/app.js b/web/scripts/app.js index 80a4eb35f..257d8524f 100644 --- a/web/scripts/app.js +++ b/web/scripts/app.js @@ -289,13 +289,21 @@ class ComfyApp { this.dragOverNode = null; // Node handles file drop, we dont use the built in onDropFile handler as its buggy // If you drag multiple files it will call it multiple times with the same file - if (n && n.onDragDrop && await n.onDragDrop(event)) { + if (n && n.onDragDrop && (await n.onDragDrop(event))) { return; } await this.handleFile(event.dataTransfer.files[0]); }); + // Always clear over node on drag leave + this.canvasEl.addEventListener("dragleave", async () => { + if (this.dragOverNode) { + this.dragOverNode = null; + this.graph.setDirtyCanvas(false, true); + } + }); + // Add handler for dropping onto a specific node this.canvasEl.addEventListener( "dragover", From 4758752939e60c7e8023bcebffbf346f36e482c0 Mon Sep 17 00:00:00 2001 From: pythongosssss <125205205+pythongosssss@users.noreply.github.com> Date: Tue, 14 Mar 2023 21:22:47 +0000 Subject: [PATCH 15/32] Updated comment --- web/scripts/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/scripts/app.js b/web/scripts/app.js index 257d8524f..4d757adb2 100644 --- a/web/scripts/app.js +++ b/web/scripts/app.js @@ -350,7 +350,7 @@ class ComfyApp { } /** - * Draws currently node highlights and progress bar + * Draws node highlights (executing, drag drop) and progress bar */ #addDrawNodeHandler() { const orig = LGraphCanvas.prototype.drawNodeShape; From 235dce3977704d22c47ace893fc5890d0e63ffa7 Mon Sep 17 00:00:00 2001 From: pythongosssss <125205205+pythongosssss@users.noreply.github.com> Date: Tue, 14 Mar 2023 21:25:52 +0000 Subject: [PATCH 16/32] Explain why animation frame used --- web/scripts/app.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/scripts/app.js b/web/scripts/app.js index 4d757adb2..8b761b9bc 100644 --- a/web/scripts/app.js +++ b/web/scripts/app.js @@ -313,6 +313,8 @@ class ComfyApp { if (node) { if (node.onDragOver && node.onDragOver(e)) { this.dragOverNode = node; + + // dragover event is fired very frequently, run this on an animation frame requestAnimationFrame(() => { this.graph.setDirtyCanvas(false, true); }); From ff255d9dcdea17e1a017268e165268079617b46a Mon Sep 17 00:00:00 2001 From: comfyanonymous Date: Tue, 14 Mar 2023 18:07:09 -0400 Subject: [PATCH 17/32] Make sure windows permission issues don't mess things up. --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 889e2cef7..a7f6541fb 100644 --- a/main.py +++ b/main.py @@ -57,7 +57,7 @@ def hijack_progress(server): def cleanup_temp(): temp_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "temp") if os.path.exists(temp_dir): - shutil.rmtree(temp_dir) + shutil.rmtree(temp_dir, ignore_errors=True) if __name__ == "__main__": cleanup_temp() From 6d44cf74e39d510b22e427d42a0975d4c9f2b1de Mon Sep 17 00:00:00 2001 From: comfyanonymous Date: Tue, 14 Mar 2023 19:08:23 -0400 Subject: [PATCH 18/32] Make it more clear the recommended way to update the standalone build. --- .../update_comfyui_and_python_dependencies.bat | 3 +++ .ci/nightly/update_windows/update_all.bat | 3 --- .../{update_comfyui_only.bat => update_comfyui.bat} | 0 .ci/nightly/windows_base_files/README_VERY_IMPORTANT.txt | 5 +++-- .ci/setup_windows_zip.ps1 | 4 ++-- .ci/setup_windows_zip_nightly_pytorch.ps1 | 4 ++-- .../update_comfyui_and_python_dependencies.bat | 3 +++ .ci/update_windows/update_all.bat | 3 --- .../{update_comfyui_only.bat => update_comfyui.bat} | 0 .ci/windows_base_files/README_VERY_IMPORTANT.txt | 6 ++++-- nodes.py | 6 +++--- 11 files changed, 20 insertions(+), 17 deletions(-) create mode 100755 .ci/nightly/update_windows/ONLY_RUN_THIS_IF_YOU_HAVE_TO/update_comfyui_and_python_dependencies.bat delete mode 100755 .ci/nightly/update_windows/update_all.bat rename .ci/nightly/update_windows/{update_comfyui_only.bat => update_comfyui.bat} (100%) create mode 100755 .ci/update_windows/ONLY_RUN_THIS_IF_YOU_HAVE_TO/update_comfyui_and_python_dependencies.bat delete mode 100755 .ci/update_windows/update_all.bat rename .ci/update_windows/{update_comfyui_only.bat => update_comfyui.bat} (100%) diff --git a/.ci/nightly/update_windows/ONLY_RUN_THIS_IF_YOU_HAVE_TO/update_comfyui_and_python_dependencies.bat b/.ci/nightly/update_windows/ONLY_RUN_THIS_IF_YOU_HAVE_TO/update_comfyui_and_python_dependencies.bat new file mode 100755 index 000000000..d58e3341e --- /dev/null +++ b/.ci/nightly/update_windows/ONLY_RUN_THIS_IF_YOU_HAVE_TO/update_comfyui_and_python_dependencies.bat @@ -0,0 +1,3 @@ +..\..\python_embeded\python.exe ..\update.py ..\..\ComfyUI\ +..\..\python_embeded\python.exe -s -m pip install --upgrade --pre torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu118 -r ../../ComfyUI/requirements.txt pygit2 +pause diff --git a/.ci/nightly/update_windows/update_all.bat b/.ci/nightly/update_windows/update_all.bat deleted file mode 100755 index c5e0c6be7..000000000 --- a/.ci/nightly/update_windows/update_all.bat +++ /dev/null @@ -1,3 +0,0 @@ -..\python_embeded\python.exe .\update.py ..\ComfyUI\ -..\python_embeded\python.exe -s -m pip install --upgrade --pre torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu118 -r ../ComfyUI/requirements.txt pygit2 -pause diff --git a/.ci/nightly/update_windows/update_comfyui_only.bat b/.ci/nightly/update_windows/update_comfyui.bat similarity index 100% rename from .ci/nightly/update_windows/update_comfyui_only.bat rename to .ci/nightly/update_windows/update_comfyui.bat diff --git a/.ci/nightly/windows_base_files/README_VERY_IMPORTANT.txt b/.ci/nightly/windows_base_files/README_VERY_IMPORTANT.txt index 4c6a20a7a..7066f91bf 100755 --- a/.ci/nightly/windows_base_files/README_VERY_IMPORTANT.txt +++ b/.ci/nightly/windows_base_files/README_VERY_IMPORTANT.txt @@ -19,8 +19,9 @@ You can download the stable diffusion 1.5 one from: https://huggingface.co/runwa RECOMMENDED WAY TO UPDATE: -To update only the ComfyUI code: update\update_comfyui_only.bat +To update the ComfyUI code: update\update_comfyui.bat -To update ComfyUI with the python dependencies (ONLY USE IF YOU NEED TO UPDATE THE PYTHON PACKAGES): update\update_all.bat +To update ComfyUI with the python dependencies: +update\ONLY_RUN_THIS_IF_YOU_HAVE_TO\update_comfyui_and_python_dependencies.bat diff --git a/.ci/setup_windows_zip.ps1 b/.ci/setup_windows_zip.ps1 index 4bd2f0b4a..6b38f498b 100755 --- a/.ci/setup_windows_zip.ps1 +++ b/.ci/setup_windows_zip.ps1 @@ -16,8 +16,8 @@ mv ComfyUI_copy ComfyUI_windows_portable/ComfyUI cd ComfyUI_windows_portable mkdir update -cp ComfyUI/.ci/update_windows/* ./update/ -cp ComfyUI/.ci/windows_base_files/* ./ +cp -r ComfyUI/.ci/update_windows/* ./update/ +cp -r ComfyUI/.ci/windows_base_files/* ./ cd .. diff --git a/.ci/setup_windows_zip_nightly_pytorch.ps1 b/.ci/setup_windows_zip_nightly_pytorch.ps1 index b4d5633a1..31721e5f6 100755 --- a/.ci/setup_windows_zip_nightly_pytorch.ps1 +++ b/.ci/setup_windows_zip_nightly_pytorch.ps1 @@ -18,8 +18,8 @@ mv ComfyUI_copy ComfyUI_windows_portable_nightly_pytorch/ComfyUI cd ComfyUI_windows_portable_nightly_pytorch mkdir update -cp ComfyUI/.ci/nightly/update_windows/* ./update/ -cp ComfyUI/.ci/nightly/windows_base_files/* ./ +cp -r ComfyUI/.ci/nightly/update_windows/* ./update/ +cp -r ComfyUI/.ci/nightly/windows_base_files/* ./ cd .. diff --git a/.ci/update_windows/ONLY_RUN_THIS_IF_YOU_HAVE_TO/update_comfyui_and_python_dependencies.bat b/.ci/update_windows/ONLY_RUN_THIS_IF_YOU_HAVE_TO/update_comfyui_and_python_dependencies.bat new file mode 100755 index 000000000..514621935 --- /dev/null +++ b/.ci/update_windows/ONLY_RUN_THIS_IF_YOU_HAVE_TO/update_comfyui_and_python_dependencies.bat @@ -0,0 +1,3 @@ +..\..\python_embeded\python.exe ..\update.py ..\..\ComfyUI\ +..\..\python_embeded\python.exe -s -m pip install --upgrade torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu117 xformers -r ../../ComfyUI/requirements.txt pygit2 +pause diff --git a/.ci/update_windows/update_all.bat b/.ci/update_windows/update_all.bat deleted file mode 100755 index b7308550d..000000000 --- a/.ci/update_windows/update_all.bat +++ /dev/null @@ -1,3 +0,0 @@ -..\python_embeded\python.exe .\update.py ..\ComfyUI\ -..\python_embeded\python.exe -s -m pip install --upgrade torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu117 xformers -r ../ComfyUI/requirements.txt pygit2 -pause diff --git a/.ci/update_windows/update_comfyui_only.bat b/.ci/update_windows/update_comfyui.bat similarity index 100% rename from .ci/update_windows/update_comfyui_only.bat rename to .ci/update_windows/update_comfyui.bat diff --git a/.ci/windows_base_files/README_VERY_IMPORTANT.txt b/.ci/windows_base_files/README_VERY_IMPORTANT.txt index 69520db98..143ee462f 100755 --- a/.ci/windows_base_files/README_VERY_IMPORTANT.txt +++ b/.ci/windows_base_files/README_VERY_IMPORTANT.txt @@ -18,8 +18,10 @@ You can download the stable diffusion 1.5 one from: https://huggingface.co/runwa RECOMMENDED WAY TO UPDATE: -To update only the ComfyUI code: update\update_comfyui_only.bat +To update the ComfyUI code: update\update_comfyui.bat -To update ComfyUI with the python dependencies (ONLY USE IF YOU NEED TO UPDATE THE PYTHON PACKAGES): update\update_all.bat +To update ComfyUI with the python dependencies: +update\ONLY_RUN_THIS_IF_YOU_HAVE_TO\update_comfyui_and_python_dependencies.bat + diff --git a/nodes.py b/nodes.py index 650d7f65d..f956eaa6e 100644 --- a/nodes.py +++ b/nodes.py @@ -811,7 +811,7 @@ class SaveImage: if not os.path.exists(self.output_dir): os.makedirs(self.output_dir) - + paths = list() for image in images: i = 255. * image.cpu().numpy() @@ -835,11 +835,11 @@ class PreviewImage(SaveImage): @classmethod def INPUT_TYPES(s): - return {"required": + return {"required": {"images": ("IMAGE", ), }, "hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"}, } - + class LoadImage: input_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "input") @classmethod From fade8a352756958d7b2bcc173dea0d449f211a8b Mon Sep 17 00:00:00 2001 From: comfyanonymous Date: Tue, 14 Mar 2023 21:38:59 -0400 Subject: [PATCH 19/32] Don't need to be that explicit. --- .../update_comfyui_and_python_dependencies.bat | 3 --- .../update_windows/update_comfyui_and_python_dependencies.bat | 3 +++ .ci/nightly/windows_base_files/README_VERY_IMPORTANT.txt | 2 +- .../update_comfyui_and_python_dependencies.bat | 3 --- .ci/update_windows/update_comfyui_and_python_dependencies.bat | 3 +++ .ci/windows_base_files/README_VERY_IMPORTANT.txt | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) delete mode 100755 .ci/nightly/update_windows/ONLY_RUN_THIS_IF_YOU_HAVE_TO/update_comfyui_and_python_dependencies.bat create mode 100755 .ci/nightly/update_windows/update_comfyui_and_python_dependencies.bat delete mode 100755 .ci/update_windows/ONLY_RUN_THIS_IF_YOU_HAVE_TO/update_comfyui_and_python_dependencies.bat create mode 100755 .ci/update_windows/update_comfyui_and_python_dependencies.bat diff --git a/.ci/nightly/update_windows/ONLY_RUN_THIS_IF_YOU_HAVE_TO/update_comfyui_and_python_dependencies.bat b/.ci/nightly/update_windows/ONLY_RUN_THIS_IF_YOU_HAVE_TO/update_comfyui_and_python_dependencies.bat deleted file mode 100755 index d58e3341e..000000000 --- a/.ci/nightly/update_windows/ONLY_RUN_THIS_IF_YOU_HAVE_TO/update_comfyui_and_python_dependencies.bat +++ /dev/null @@ -1,3 +0,0 @@ -..\..\python_embeded\python.exe ..\update.py ..\..\ComfyUI\ -..\..\python_embeded\python.exe -s -m pip install --upgrade --pre torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu118 -r ../../ComfyUI/requirements.txt pygit2 -pause diff --git a/.ci/nightly/update_windows/update_comfyui_and_python_dependencies.bat b/.ci/nightly/update_windows/update_comfyui_and_python_dependencies.bat new file mode 100755 index 000000000..c5e0c6be7 --- /dev/null +++ b/.ci/nightly/update_windows/update_comfyui_and_python_dependencies.bat @@ -0,0 +1,3 @@ +..\python_embeded\python.exe .\update.py ..\ComfyUI\ +..\python_embeded\python.exe -s -m pip install --upgrade --pre torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu118 -r ../ComfyUI/requirements.txt pygit2 +pause diff --git a/.ci/nightly/windows_base_files/README_VERY_IMPORTANT.txt b/.ci/nightly/windows_base_files/README_VERY_IMPORTANT.txt index 7066f91bf..656b9db43 100755 --- a/.ci/nightly/windows_base_files/README_VERY_IMPORTANT.txt +++ b/.ci/nightly/windows_base_files/README_VERY_IMPORTANT.txt @@ -24,4 +24,4 @@ To update the ComfyUI code: update\update_comfyui.bat To update ComfyUI with the python dependencies: -update\ONLY_RUN_THIS_IF_YOU_HAVE_TO\update_comfyui_and_python_dependencies.bat +update\update_comfyui_and_python_dependencies.bat diff --git a/.ci/update_windows/ONLY_RUN_THIS_IF_YOU_HAVE_TO/update_comfyui_and_python_dependencies.bat b/.ci/update_windows/ONLY_RUN_THIS_IF_YOU_HAVE_TO/update_comfyui_and_python_dependencies.bat deleted file mode 100755 index 514621935..000000000 --- a/.ci/update_windows/ONLY_RUN_THIS_IF_YOU_HAVE_TO/update_comfyui_and_python_dependencies.bat +++ /dev/null @@ -1,3 +0,0 @@ -..\..\python_embeded\python.exe ..\update.py ..\..\ComfyUI\ -..\..\python_embeded\python.exe -s -m pip install --upgrade torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu117 xformers -r ../../ComfyUI/requirements.txt pygit2 -pause diff --git a/.ci/update_windows/update_comfyui_and_python_dependencies.bat b/.ci/update_windows/update_comfyui_and_python_dependencies.bat new file mode 100755 index 000000000..b7308550d --- /dev/null +++ b/.ci/update_windows/update_comfyui_and_python_dependencies.bat @@ -0,0 +1,3 @@ +..\python_embeded\python.exe .\update.py ..\ComfyUI\ +..\python_embeded\python.exe -s -m pip install --upgrade torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu117 xformers -r ../ComfyUI/requirements.txt pygit2 +pause diff --git a/.ci/windows_base_files/README_VERY_IMPORTANT.txt b/.ci/windows_base_files/README_VERY_IMPORTANT.txt index 143ee462f..a6214e735 100755 --- a/.ci/windows_base_files/README_VERY_IMPORTANT.txt +++ b/.ci/windows_base_files/README_VERY_IMPORTANT.txt @@ -23,5 +23,5 @@ To update the ComfyUI code: update\update_comfyui.bat To update ComfyUI with the python dependencies: -update\ONLY_RUN_THIS_IF_YOU_HAVE_TO\update_comfyui_and_python_dependencies.bat +update\update_comfyui_and_python_dependencies.bat From 760f10d173e26fcf959accb815d6437c29453af3 Mon Sep 17 00:00:00 2001 From: comfyanonymous Date: Tue, 14 Mar 2023 21:46:59 -0400 Subject: [PATCH 20/32] Test workflow for cu118 test build. --- .github/workflows/windows_release_cu118.yml | 61 +++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 .github/workflows/windows_release_cu118.yml diff --git a/.github/workflows/windows_release_cu118.yml b/.github/workflows/windows_release_cu118.yml new file mode 100644 index 000000000..05a818419 --- /dev/null +++ b/.github/workflows/windows_release_cu118.yml @@ -0,0 +1,61 @@ +name: "Windows Release cu118" + +on: + workflow_dispatch: +# push: +# branches: +# - master + +jobs: + build: + permissions: + contents: "write" + packages: "write" + pull-requests: "read" + runs-on: windows-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - run: | + cd .. + cp ComfyUI/.ci/setup_windows_zip.ps1 ./ + cp -r ComfyUI ComfyUI_copy + + Invoke-WebRequest -URI https://www.python.org/ftp/python/3.10.9/python-3.10.9-embed-amd64.zip -O python_embeded.zip + Expand-Archive python_embeded.zip + cd python_embeded + Add-Content -Path .\python310._pth -Value 'import site' + Invoke-WebRequest -Uri https://bootstrap.pypa.io/get-pip.py -OutFile get-pip.py + .\python.exe get-pip.py + .\python.exe -s -m pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu118 xformers -r ../ComfyUI/requirements.txt pygit2 + "../ComfyUI`n" + (Get-Content .\python310._pth -Raw) | Set-Content .\python310._pth + cd .. + + + mkdir ComfyUI_windows_portable + mv python_embeded ComfyUI_windows_portable + mv ComfyUI_copy ComfyUI_windows_portable/ComfyUI + + cd ComfyUI_windows_portable + + mkdir update + cp -r ComfyUI/.ci/update_windows/* ./update/ + cp -r ComfyUI/.ci/windows_base_files/* ./ + + cd .. + + & "C:\Program Files\7-Zip\7z.exe" a -t7z -m0=lzma -mx=8 -mfb=64 -md=32m -ms=on ComfyUI_windows_portable.7z ComfyUI_windows_portable + mv ComfyUI_windows_portable.7z ComfyUI/ComfyUI_windows_portable_nvidia_cu118_or_cpu.7z + + ls + + - name: Upload binaries to release + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: ComfyUI_windows_portable_nvidia_cu118_or_cpu.7z + tag: "latest" + overwrite: true + From b5f2bc971183c9b846151de4aa1b7a1a19465461 Mon Sep 17 00:00:00 2001 From: comfyanonymous Date: Tue, 14 Mar 2023 22:09:15 -0400 Subject: [PATCH 21/32] Try to make the workflow actually fail when there's a problem. --- .github/workflows/windows_release_cu118.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/windows_release_cu118.yml b/.github/workflows/windows_release_cu118.yml index 05a818419..65f0d29bb 100644 --- a/.github/workflows/windows_release_cu118.yml +++ b/.github/workflows/windows_release_cu118.yml @@ -20,7 +20,6 @@ jobs: - run: | cd .. - cp ComfyUI/.ci/setup_windows_zip.ps1 ./ cp -r ComfyUI ComfyUI_copy Invoke-WebRequest -URI https://www.python.org/ftp/python/3.10.9/python-3.10.9-embed-amd64.zip -O python_embeded.zip @@ -29,8 +28,13 @@ jobs: Add-Content -Path .\python310._pth -Value 'import site' Invoke-WebRequest -Uri https://bootstrap.pypa.io/get-pip.py -OutFile get-pip.py .\python.exe get-pip.py - .\python.exe -s -m pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu118 xformers -r ../ComfyUI/requirements.txt pygit2 "../ComfyUI`n" + (Get-Content .\python310._pth -Raw) | Set-Content .\python310._pth + + - shell: bash + run: | + cd .. + cd python_embeded + ./python.exe -s -m pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu118 xformers -r ../ComfyUI/requirements.txt pygit2 cd .. @@ -46,7 +50,7 @@ jobs: cd .. - & "C:\Program Files\7-Zip\7z.exe" a -t7z -m0=lzma -mx=8 -mfb=64 -md=32m -ms=on ComfyUI_windows_portable.7z ComfyUI_windows_portable + "C:\Program Files\7-Zip\7z.exe" a -t7z -m0=lzma -mx=8 -mfb=64 -md=32m -ms=on ComfyUI_windows_portable.7z ComfyUI_windows_portable mv ComfyUI_windows_portable.7z ComfyUI/ComfyUI_windows_portable_nvidia_cu118_or_cpu.7z ls From 5ad9f86514822a0aa3d1ce113676ae1b46874681 Mon Sep 17 00:00:00 2001 From: comfyanonymous Date: Tue, 14 Mar 2023 23:02:57 -0400 Subject: [PATCH 22/32] Do a quick test on the CI to see if ComfyUI actually runs before pushing the build. --- .github/workflows/windows_release_cu118.yml | 22 ++++++++++----------- main.py | 3 +++ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/workflows/windows_release_cu118.yml b/.github/workflows/windows_release_cu118.yml index 65f0d29bb..b757a540e 100644 --- a/.github/workflows/windows_release_cu118.yml +++ b/.github/workflows/windows_release_cu118.yml @@ -18,23 +18,18 @@ jobs: with: fetch-depth: 0 - - run: | - cd .. - cp -r ComfyUI ComfyUI_copy - - Invoke-WebRequest -URI https://www.python.org/ftp/python/3.10.9/python-3.10.9-embed-amd64.zip -O python_embeded.zip - Expand-Archive python_embeded.zip - cd python_embeded - Add-Content -Path .\python310._pth -Value 'import site' - Invoke-WebRequest -Uri https://bootstrap.pypa.io/get-pip.py -OutFile get-pip.py - .\python.exe get-pip.py - "../ComfyUI`n" + (Get-Content .\python310._pth -Raw) | Set-Content .\python310._pth - - shell: bash run: | cd .. + cp -r ComfyUI ComfyUI_copy + wget https://www.python.org/ftp/python/3.10.9/python-3.10.9-embed-amd64.zip -O python_embeded.zip + unzip python_embeded.zip cd python_embeded + echo 'import site' >> ./python310._pth + wget https://bootstrap.pypa.io/get-pip.py -O get-pip.py + ./python.exe get-pip.py ./python.exe -s -m pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu118 xformers -r ../ComfyUI/requirements.txt pygit2 + sed -i '1i../ComfyUI' ./python310._pth cd .. @@ -53,6 +48,9 @@ jobs: "C:\Program Files\7-Zip\7z.exe" a -t7z -m0=lzma -mx=8 -mfb=64 -md=32m -ms=on ComfyUI_windows_portable.7z ComfyUI_windows_portable mv ComfyUI_windows_portable.7z ComfyUI/ComfyUI_windows_portable_nvidia_cu118_or_cpu.7z + cd ComfyUI_windows_portable + python_embeded/python.exe -s ComfyUI/main.py --quick-test-for-ci --cpu + ls - name: Upload binaries to release diff --git a/main.py b/main.py index a7f6541fb..3c03381d6 100644 --- a/main.py +++ b/main.py @@ -86,6 +86,9 @@ if __name__ == "__main__": except: pass + if '--quick-test-for-ci' in sys.argv: + exit(0) + call_on_start = None if "--windows-standalone-build" in sys.argv: def startup_server(address, port): From 5bde13495527a40ea3110ca91442db14243a8dc3 Mon Sep 17 00:00:00 2001 From: comfyanonymous Date: Tue, 14 Mar 2023 23:17:50 -0400 Subject: [PATCH 23/32] More proper ci workflows. --- .ci/setup_windows_zip.ps1 | 25 ------------- .ci/setup_windows_zip_nightly_pytorch.ps1 | 27 -------------- .github/workflows/windows_release.yml | 35 ++++++++++++++++-- .github/workflows/windows_release_cu118.yml | 2 +- .../windows_release_nightly_pytorch.yml | 36 +++++++++++++++++-- 5 files changed, 66 insertions(+), 59 deletions(-) delete mode 100755 .ci/setup_windows_zip.ps1 delete mode 100755 .ci/setup_windows_zip_nightly_pytorch.ps1 diff --git a/.ci/setup_windows_zip.ps1 b/.ci/setup_windows_zip.ps1 deleted file mode 100755 index 6b38f498b..000000000 --- a/.ci/setup_windows_zip.ps1 +++ /dev/null @@ -1,25 +0,0 @@ -Invoke-WebRequest -URI https://www.python.org/ftp/python/3.10.9/python-3.10.9-embed-amd64.zip -O python_embeded.zip -Expand-Archive python_embeded.zip -cd python_embeded -Add-Content -Path .\python310._pth -Value 'import site' -Invoke-WebRequest -Uri https://bootstrap.pypa.io/get-pip.py -OutFile get-pip.py -.\python.exe get-pip.py -.\python.exe -s -m pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu117 xformers -r ../ComfyUI/requirements.txt pygit2 -"../ComfyUI`n" + (Get-Content .\python310._pth -Raw) | Set-Content .\python310._pth -cd .. - - -mkdir ComfyUI_windows_portable -mv python_embeded ComfyUI_windows_portable -mv ComfyUI_copy ComfyUI_windows_portable/ComfyUI - -cd ComfyUI_windows_portable - -mkdir update -cp -r ComfyUI/.ci/update_windows/* ./update/ -cp -r ComfyUI/.ci/windows_base_files/* ./ - -cd .. - -& "C:\Program Files\7-Zip\7z.exe" a -t7z -m0=lzma -mx=8 -mfb=64 -md=32m -ms=on ComfyUI_windows_portable.7z ComfyUI_windows_portable -mv ComfyUI_windows_portable.7z ComfyUI/ComfyUI_windows_portable_nvidia_or_cpu.7z diff --git a/.ci/setup_windows_zip_nightly_pytorch.ps1 b/.ci/setup_windows_zip_nightly_pytorch.ps1 deleted file mode 100755 index 31721e5f6..000000000 --- a/.ci/setup_windows_zip_nightly_pytorch.ps1 +++ /dev/null @@ -1,27 +0,0 @@ -Invoke-WebRequest -URI https://www.python.org/ftp/python/3.10.9/python-3.10.9-embed-amd64.zip -O python_embeded.zip -Expand-Archive python_embeded.zip -rm python_embeded.zip -cd python_embeded -Add-Content -Path .\python310._pth -Value 'import site' -Invoke-WebRequest -Uri https://bootstrap.pypa.io/get-pip.py -OutFile get-pip.py -.\python.exe get-pip.py -python -m pip wheel torch torchvision torchaudio --pre --extra-index-url https://download.pytorch.org/whl/nightly/cu118 -r ../ComfyUI/requirements.txt pygit2 -w ../temp_wheel_dir -ls ../temp_wheel_dir -.\python.exe -s -m pip install --pre (get-item ..\temp_wheel_dir\*) -"../ComfyUI`n" + (Get-Content .\python310._pth -Raw) | Set-Content .\python310._pth -cd .. - -mkdir ComfyUI_windows_portable_nightly_pytorch -mv python_embeded ComfyUI_windows_portable_nightly_pytorch -mv ComfyUI_copy ComfyUI_windows_portable_nightly_pytorch/ComfyUI - -cd ComfyUI_windows_portable_nightly_pytorch - -mkdir update -cp -r ComfyUI/.ci/nightly/update_windows/* ./update/ -cp -r ComfyUI/.ci/nightly/windows_base_files/* ./ - -cd .. - -& "C:\Program Files\7-Zip\7z.exe" a -t7z -m0=lzma -mx=8 -mfb=64 -md=32m -ms=on ComfyUI_windows_portable_nightly_pytorch.7z ComfyUI_windows_portable_nightly_pytorch -mv ComfyUI_windows_portable_nightly_pytorch.7z ComfyUI/ComfyUI_windows_portable_nvidia_or_cpu_nightly_pytorch.7z diff --git a/.github/workflows/windows_release.yml b/.github/workflows/windows_release.yml index be48b7eae..1b2694a35 100644 --- a/.github/workflows/windows_release.yml +++ b/.github/workflows/windows_release.yml @@ -18,13 +18,42 @@ jobs: with: fetch-depth: 0 - - run: | + - shell: bash + run: | cd .. - cp ComfyUI/.ci/setup_windows_zip.ps1 ./ cp -r ComfyUI ComfyUI_copy - .\setup_windows_zip.ps1 + wget https://www.python.org/ftp/python/3.10.9/python-3.10.9-embed-amd64.zip -O python_embeded.zip + unzip python_embeded.zip -d python_embeded + cd python_embeded + echo 'import site' >> ./python310._pth + wget https://bootstrap.pypa.io/get-pip.py -O get-pip.py + ./python.exe get-pip.py + ./python.exe -s -m pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu117 xformers -r ../ComfyUI/requirements.txt pygit2 + sed -i '1i../ComfyUI' ./python310._pth + cd .. + + + mkdir ComfyUI_windows_portable + mv python_embeded ComfyUI_windows_portable + mv ComfyUI_copy ComfyUI_windows_portable/ComfyUI + + cd ComfyUI_windows_portable + + mkdir update + cp -r ComfyUI/.ci/update_windows/* ./update/ + cp -r ComfyUI/.ci/windows_base_files/* ./ + + cd .. + + "C:\Program Files\7-Zip\7z.exe" a -t7z -m0=lzma -mx=8 -mfb=64 -md=32m -ms=on ComfyUI_windows_portable.7z ComfyUI_windows_portable + mv ComfyUI_windows_portable.7z ComfyUI/ComfyUI_windows_portable_nvidia_or_cpu.7z + + cd ComfyUI_windows_portable + python_embeded/python.exe -s ComfyUI/main.py --quick-test-for-ci --cpu + ls + - name: Upload binaries to release uses: svenstaro/upload-release-action@v2 with: diff --git a/.github/workflows/windows_release_cu118.yml b/.github/workflows/windows_release_cu118.yml index b757a540e..773483f6c 100644 --- a/.github/workflows/windows_release_cu118.yml +++ b/.github/workflows/windows_release_cu118.yml @@ -23,7 +23,7 @@ jobs: cd .. cp -r ComfyUI ComfyUI_copy wget https://www.python.org/ftp/python/3.10.9/python-3.10.9-embed-amd64.zip -O python_embeded.zip - unzip python_embeded.zip + unzip python_embeded.zip -d python_embeded cd python_embeded echo 'import site' >> ./python310._pth wget https://bootstrap.pypa.io/get-pip.py -O get-pip.py diff --git a/.github/workflows/windows_release_nightly_pytorch.yml b/.github/workflows/windows_release_nightly_pytorch.yml index 1aeaef45a..2679b0b6f 100644 --- a/.github/workflows/windows_release_nightly_pytorch.yml +++ b/.github/workflows/windows_release_nightly_pytorch.yml @@ -20,11 +20,41 @@ jobs: - uses: actions/setup-python@v4 with: python-version: '3.10.9' - - run: | + - shell: bash + run: | cd .. - cp ComfyUI/.ci/setup_windows_zip_nightly_pytorch.ps1 ./ cp -r ComfyUI ComfyUI_copy - .\setup_windows_zip_nightly_pytorch.ps1 + wget https://www.python.org/ftp/python/3.10.9/python-3.10.9-embed-amd64.zip -O python_embeded.zip + unzip python_embeded.zip -d python_embeded + cd python_embeded + echo 'import site' >> ./python310._pth + wget https://bootstrap.pypa.io/get-pip.py -O get-pip.py + ./python.exe get-pip.py + python -m pip wheel torch torchvision torchaudio --pre --extra-index-url https://download.pytorch.org/whl/nightly/cu118 -r ../ComfyUI/requirements.txt pygit2 -w ../temp_wheel_dir + ls ../temp_wheel_dir + ./python.exe -s -m pip install --pre ../temp_wheel_dir/* + sed -i '1i../ComfyUI' ./python310._pth + cd .. + + + mkdir ComfyUI_windows_portable_nightly_pytorch + mv python_embeded ComfyUI_windows_portable_nightly_pytorch + mv ComfyUI_copy ComfyUI_windows_portable_nightly_pytorch/ComfyUI + + cd ComfyUI_windows_portable_nightly_pytorch + + mkdir update + cp -r ComfyUI/.ci/update_windows/* ./update/ + cp -r ComfyUI/.ci/windows_base_files/* ./ + + cd .. + + "C:\Program Files\7-Zip\7z.exe" a -t7z -m0=lzma -mx=8 -mfb=64 -md=32m -ms=on ComfyUI_windows_portable_nightly_pytorch.7z ComfyUI_windows_portable_nightly_pytorch + mv ComfyUI_windows_portable_nightly_pytorch.7z ComfyUI/ComfyUI_windows_portable_nvidia_or_cpu_nightly_pytorch.7z + + cd ComfyUI_windows_portable_nightly_pytorch + python_embeded/python.exe -s ComfyUI/main.py --quick-test-for-ci --cpu + ls - name: Upload binaries to release From ed4810e6701cdea1f6bf59e667736efc87e4f600 Mon Sep 17 00:00:00 2001 From: comfyanonymous Date: Tue, 14 Mar 2023 23:22:41 -0400 Subject: [PATCH 24/32] CI fix. --- .github/workflows/windows_release.yml | 4 ++-- .github/workflows/windows_release_cu118.yml | 4 ++-- .github/workflows/windows_release_nightly_pytorch.yml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/windows_release.yml b/.github/workflows/windows_release.yml index 1b2694a35..3f7d4d739 100644 --- a/.github/workflows/windows_release.yml +++ b/.github/workflows/windows_release.yml @@ -22,11 +22,11 @@ jobs: run: | cd .. cp -r ComfyUI ComfyUI_copy - wget https://www.python.org/ftp/python/3.10.9/python-3.10.9-embed-amd64.zip -O python_embeded.zip + curl https://www.python.org/ftp/python/3.10.9/python-3.10.9-embed-amd64.zip -o python_embeded.zip unzip python_embeded.zip -d python_embeded cd python_embeded echo 'import site' >> ./python310._pth - wget https://bootstrap.pypa.io/get-pip.py -O get-pip.py + curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py ./python.exe get-pip.py ./python.exe -s -m pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu117 xformers -r ../ComfyUI/requirements.txt pygit2 sed -i '1i../ComfyUI' ./python310._pth diff --git a/.github/workflows/windows_release_cu118.yml b/.github/workflows/windows_release_cu118.yml index 773483f6c..cd0ca9a62 100644 --- a/.github/workflows/windows_release_cu118.yml +++ b/.github/workflows/windows_release_cu118.yml @@ -22,11 +22,11 @@ jobs: run: | cd .. cp -r ComfyUI ComfyUI_copy - wget https://www.python.org/ftp/python/3.10.9/python-3.10.9-embed-amd64.zip -O python_embeded.zip + curl https://www.python.org/ftp/python/3.10.9/python-3.10.9-embed-amd64.zip -o python_embeded.zip unzip python_embeded.zip -d python_embeded cd python_embeded echo 'import site' >> ./python310._pth - wget https://bootstrap.pypa.io/get-pip.py -O get-pip.py + curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py ./python.exe get-pip.py ./python.exe -s -m pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu118 xformers -r ../ComfyUI/requirements.txt pygit2 sed -i '1i../ComfyUI' ./python310._pth diff --git a/.github/workflows/windows_release_nightly_pytorch.yml b/.github/workflows/windows_release_nightly_pytorch.yml index 2679b0b6f..291d754e3 100644 --- a/.github/workflows/windows_release_nightly_pytorch.yml +++ b/.github/workflows/windows_release_nightly_pytorch.yml @@ -24,11 +24,11 @@ jobs: run: | cd .. cp -r ComfyUI ComfyUI_copy - wget https://www.python.org/ftp/python/3.10.9/python-3.10.9-embed-amd64.zip -O python_embeded.zip + curl https://www.python.org/ftp/python/3.10.9/python-3.10.9-embed-amd64.zip -o python_embeded.zip unzip python_embeded.zip -d python_embeded cd python_embeded echo 'import site' >> ./python310._pth - wget https://bootstrap.pypa.io/get-pip.py -O get-pip.py + curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py ./python.exe get-pip.py python -m pip wheel torch torchvision torchaudio --pre --extra-index-url https://download.pytorch.org/whl/nightly/cu118 -r ../ComfyUI/requirements.txt pygit2 -w ../temp_wheel_dir ls ../temp_wheel_dir From 54593db6dcc9081c58fb9688a49aab49286bb741 Mon Sep 17 00:00:00 2001 From: comfyanonymous Date: Wed, 15 Mar 2023 01:58:27 -0400 Subject: [PATCH 25/32] Update install instructions for torch. --- README.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 8877d4495..b5a0c48ff 100644 --- a/README.md +++ b/README.md @@ -56,19 +56,14 @@ At the time of writing this pytorch has issues with python versions higher than ### AMD (Linux only) AMD users can install rocm and pytorch with pip if you don't have it already installed, this is the command to install the stable version: -```pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/rocm5.2``` - - -I highly recommend you use the nightly/unstable pytorch builds though because they work a lot better for me (run this in the ComfyUI folder so it picks up the requirements.txt): - -```pip install --upgrade --pre torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/nightly/rocm5.4.2 -r requirements.txt``` +```pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/rocm5.4.2``` ### NVIDIA Nvidia users should install torch using this command: -```pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu117``` +```pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu118``` Nvidia users should also install Xformers for a speed boost but can still run the software without it. From 29cee297a09494fc43f4d16dbf659740ed79ae19 Mon Sep 17 00:00:00 2001 From: m957ymj75urz Date: Wed, 15 Mar 2023 11:44:49 +0100 Subject: [PATCH 26/32] ignore/restore custom batch count when extra options is unchecked --- web/scripts/ui.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/web/scripts/ui.js b/web/scripts/ui.js index 8134e3415..cb31f10e9 100644 --- a/web/scripts/ui.js +++ b/web/scripts/ui.js @@ -258,7 +258,12 @@ export class ComfyUI { $el("button.comfy-queue-btn", { textContent: "Queue Prompt", onclick: () => app.queuePrompt(0, this.batchCount) }), $el("div", {}, [ $el("label", { innerHTML: "Extra options"}, [ - $el("input", { type: "checkbox", onchange: (i) => document.getElementById('extraOptions').style.visibility = i.srcElement.checked ? "visible" : "collapse" }) + $el("input", { type: "checkbox", + onchange: (i) => { + document.getElementById('extraOptions').style.visibility = i.srcElement.checked ? "visible" : "collapse"; + this.batchCount = i.srcElement.checked ? document.getElementById('batchCountInputRange').value : 1; + } + }) ]) ]), $el("div", { id: "extraOptions", style: { width: "100%", visibility: "collapse" }}, [ From 07598e27e57de5ea630f63dffa84acb87dd79035 Mon Sep 17 00:00:00 2001 From: comfyanonymous Date: Wed, 15 Mar 2023 14:32:52 -0400 Subject: [PATCH 27/32] I think it looks a bit better like this. --- web/scripts/ui.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/scripts/ui.js b/web/scripts/ui.js index cb31f10e9..c056371e1 100644 --- a/web/scripts/ui.js +++ b/web/scripts/ui.js @@ -260,13 +260,13 @@ export class ComfyUI { $el("label", { innerHTML: "Extra options"}, [ $el("input", { type: "checkbox", onchange: (i) => { - document.getElementById('extraOptions').style.visibility = i.srcElement.checked ? "visible" : "collapse"; + document.getElementById('extraOptions').style.display = i.srcElement.checked ? "block" : "none"; this.batchCount = i.srcElement.checked ? document.getElementById('batchCountInputRange').value : 1; } }) ]) ]), - $el("div", { id: "extraOptions", style: { width: "100%", visibility: "collapse" }}, [ + $el("div", { id: "extraOptions", style: { width: "100%", display: "none" }}, [ $el("label", { innerHTML: "Batch count" }, [ $el("input", { id: "batchCountInputNumber", type: "number", value: this.batchCount, min: "1", style: { width: "35%", "margin-left": "0.4em" }, oninput: (i) => { From 494cfe5444598f22eced91b6f4bfffc24c4af339 Mon Sep 17 00:00:00 2001 From: comfyanonymous Date: Wed, 15 Mar 2023 15:18:18 -0400 Subject: [PATCH 28/32] Prevent model_management from being loaded twice. --- comfy_extras/nodes_upscale_model.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/comfy_extras/nodes_upscale_model.py b/comfy_extras/nodes_upscale_model.py index 98e9863e1..965e5e7a6 100644 --- a/comfy_extras/nodes_upscale_model.py +++ b/comfy_extras/nodes_upscale_model.py @@ -1,7 +1,7 @@ import os from comfy_extras.chainner_models import model_loading from comfy.sd import load_torch_file -import comfy.model_management +import model_management from nodes import filter_files_extensions, recursive_search, supported_ckpt_extensions import torch import comfy.utils @@ -38,7 +38,7 @@ class ImageUpscaleWithModel: CATEGORY = "image/upscaling" def upscale(self, upscale_model, image): - device = comfy.model_management.get_torch_device() + device = model_management.get_torch_device() upscale_model.to(device) in_img = image.movedim(-1,-3).to(device) s = comfy.utils.tiled_scale(in_img, lambda a: upscale_model(a), tile_x=128 + 64, tile_y=128 + 64, overlap = 8, upscale_amount=upscale_model.scale) From d834eed7d0f46b449bbe6a6886b85b54382ab175 Mon Sep 17 00:00:00 2001 From: comfyanonymous Date: Wed, 15 Mar 2023 17:58:13 -0400 Subject: [PATCH 29/32] Fix bug when applying controlnet to negative prompt. --- nodes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nodes.py b/nodes.py index f956eaa6e..766be75dc 100644 --- a/nodes.py +++ b/nodes.py @@ -691,8 +691,8 @@ def common_ksampler(model, seed, steps, cfg, sampler_name, scheduler, positive, if t.shape[0] < noise.shape[0]: t = torch.cat([t] * noise.shape[0]) t = t.to(device) - if 'control' in p[1]: - control_nets += [p[1]['control']] + if 'control' in n[1]: + control_nets += [n[1]['control']] negative_copy += [[t] + n[1:]] control_net_models = [] From 7dd6fc9f8ab3f9052454e97c0953f7435e62125f Mon Sep 17 00:00:00 2001 From: comfyanonymous Date: Thu, 16 Mar 2023 01:59:53 -0400 Subject: [PATCH 30/32] Put a command that actually works for installing xformers for nvidia. --- README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b5a0c48ff..277d5d997 100644 --- a/README.md +++ b/README.md @@ -61,13 +61,9 @@ AMD users can install rocm and pytorch with pip if you don't have it already ins ### NVIDIA -Nvidia users should install torch using this command: +Nvidia users should install torch and xformers using this command: -```pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu118``` - -Nvidia users should also install Xformers for a speed boost but can still run the software without it. - -```pip install xformers``` +```pip install torch==1.13.1 torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu117 xformers``` #### Troubleshooting From 74b0104c84f92593e07b656fd2d997e3939b799f Mon Sep 17 00:00:00 2001 From: comfyanonymous Date: Thu, 16 Mar 2023 02:36:42 -0400 Subject: [PATCH 31/32] Test github workflow for standalone build with cu118 torch+xformers. --- ...update_comfyui_and_python_dependencies.bat | 3 + .../README_VERY_IMPORTANT.txt | 2 +- .github/workflows/windows_release_cu118.yml | 84 ++++++++++++++++++- 3 files changed, 85 insertions(+), 4 deletions(-) create mode 100755 .ci/update_windows_cu118/update_comfyui_and_python_dependencies.bat diff --git a/.ci/update_windows_cu118/update_comfyui_and_python_dependencies.bat b/.ci/update_windows_cu118/update_comfyui_and_python_dependencies.bat new file mode 100755 index 000000000..4fb011a32 --- /dev/null +++ b/.ci/update_windows_cu118/update_comfyui_and_python_dependencies.bat @@ -0,0 +1,3 @@ +..\python_embeded\python.exe .\update.py ..\ComfyUI\ +..\python_embeded\python.exe -s -m pip install --upgrade torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu118 xformers -r ../ComfyUI/requirements.txt pygit2 +pause diff --git a/.ci/windows_base_files/README_VERY_IMPORTANT.txt b/.ci/windows_base_files/README_VERY_IMPORTANT.txt index a6214e735..c19085320 100755 --- a/.ci/windows_base_files/README_VERY_IMPORTANT.txt +++ b/.ci/windows_base_files/README_VERY_IMPORTANT.txt @@ -22,6 +22,6 @@ To update the ComfyUI code: update\update_comfyui.bat -To update ComfyUI with the python dependencies: +To update ComfyUI with the python dependencies, note that you should ONLY run this if you have issues with python dependencies. update\update_comfyui_and_python_dependencies.bat diff --git a/.github/workflows/windows_release_cu118.yml b/.github/workflows/windows_release_cu118.yml index cd0ca9a62..c680d7b87 100644 --- a/.github/workflows/windows_release_cu118.yml +++ b/.github/workflows/windows_release_cu118.yml @@ -7,17 +7,94 @@ on: # - master jobs: - build: + build_dependencies: + env: + # you need at least cuda 5.0 for some of the stuff compiled here. + TORCH_CUDA_ARCH_LIST: "5.0+PTX 6.0 6.1 7.0 7.5 8.0 8.6 8.9" + FORCE_CUDA: 1 + MAX_JOBS: 1 # will crash otherwise + DISTUTILS_USE_SDK: 1 # otherwise distutils will complain on windows about multiple versions of msvc + XFORMERS_BUILD_TYPE: "Release" + runs-on: windows-latest + steps: + - name: Cache Built Dependencies + uses: actions/cache@v3 + id: cache-cu118_python_stuff + with: + path: cu118_python_deps.tar + key: ${{ runner.os }}-build-cu118 + + - if: ${{ steps.cache-cu118_python_stuff.cache-hit != 'true' }} + uses: actions/checkout@v3 + + - if: ${{ steps.cache-cu118_python_stuff.cache-hit != 'true' }} + uses: actions/setup-python@v4 + with: + python-version: '3.10.9' + + - if: ${{ steps.cache-cu118_python_stuff.cache-hit != 'true' }} + uses: comfyanonymous/cuda-toolkit@test + id: cuda-toolkit + with: + cuda: '11.8.0' + # copied from xformers github + - name: Setup MSVC + uses: ilammy/msvc-dev-cmd@v1 + - name: Configure Pagefile + # windows runners will OOM with many CUDA architectures + # we cheat here with a page file + uses: al-cheb/configure-pagefile-action@v1.3 + with: + minimum-size: 2GB + # really unfortunate: https://github.com/ilammy/msvc-dev-cmd#name-conflicts-with-shell-bash + - name: Remove link.exe + shell: bash + run: rm /usr/bin/link + + - if: ${{ steps.cache-cu118_python_stuff.cache-hit != 'true' }} + shell: bash + run: | + python -m pip wheel --no-cache-dir torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu118 -r requirements.txt pygit2 -w ./temp_wheel_dir + python -m pip install --no-cache-dir ./temp_wheel_dir/* + echo installed basic + git clone --recurse-submodules https://github.com/facebookresearch/xformers.git + cd xformers + python -m pip install --no-cache-dir wheel setuptools twine + echo building xformers + python setup.py bdist_wheel -d ../temp_wheel_dir/ + cd .. + rm -rf xformers + ls -lah temp_wheel_dir + mv temp_wheel_dir cu118_python_deps + tar cf cu118_python_deps.tar cu118_python_deps + - uses: actions/upload-artifact@v3 + with: + name: cu118_python_deps + path: cu118_python_deps.tar + + + package_comfyui: + needs: build_dependencies permissions: contents: "write" packages: "write" pull-requests: "read" runs-on: windows-latest steps: + - uses: actions/download-artifact@v3 + with: + name: cu118_python_deps + - shell: bash + run: | + mv cu118_python_deps.tar ../ + cd .. + tar xf cu118_python_deps.tar + pwd + ls + - uses: actions/checkout@v3 with: fetch-depth: 0 - - shell: bash run: | cd .. @@ -28,7 +105,7 @@ jobs: echo 'import site' >> ./python310._pth curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py ./python.exe get-pip.py - ./python.exe -s -m pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu118 xformers -r ../ComfyUI/requirements.txt pygit2 + ./python.exe -s -m pip install ../cu118_python_deps/* sed -i '1i../ComfyUI' ./python310._pth cd .. @@ -41,6 +118,7 @@ jobs: mkdir update cp -r ComfyUI/.ci/update_windows/* ./update/ + cp -r ComfyUI/.ci/update_windows_cu118/* ./update/ cp -r ComfyUI/.ci/windows_base_files/* ./ cd .. From f11d5e074872db0c60d6b9670441614eb8acbca7 Mon Sep 17 00:00:00 2001 From: comfyanonymous Date: Thu, 16 Mar 2023 11:52:49 -0400 Subject: [PATCH 32/32] Add note to update bat. --- .../update_comfyui_and_python_dependencies.bat | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci/update_windows_cu118/update_comfyui_and_python_dependencies.bat b/.ci/update_windows_cu118/update_comfyui_and_python_dependencies.bat index 4fb011a32..1e45075f3 100755 --- a/.ci/update_windows_cu118/update_comfyui_and_python_dependencies.bat +++ b/.ci/update_windows_cu118/update_comfyui_and_python_dependencies.bat @@ -1,3 +1,4 @@ ..\python_embeded\python.exe .\update.py ..\ComfyUI\ ..\python_embeded\python.exe -s -m pip install --upgrade torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu118 xformers -r ../ComfyUI/requirements.txt pygit2 +echo NOTE If you get an error with pip you can ignore it, it's pip being pip as usual, your ComfyUI should have updated anyways. pause