lenzcomvth commited on
Commit
7906fb3
·
1 Parent(s): d29b146

Add application files for ComfyUI API

Browse files
Client/.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ __pycache__/
2
+ cai_platform_key.txt
Client/README.md ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Clarity AI node for ComfyUI
2
+
3
+ This is a ComfyUI node for Clarity AI, the creative image upscaler. It upscales and enhances images to high resolution.
4
+
5
+ ![alt text](dog_example.png)
6
+
7
+ ## Free Usage:
8
+
9
+ We now have a fully ComfyUI workflow of Clarity upscaler, it seems to uses the same tech and is getting close to the clarity results. Needs some final tweaking to reach the same quality.
10
+ Feel free to experiment and let me know if you discover great parameters.
11
+
12
+ ### 1. Install
13
+
14
+ Just drag and drop the `free-workflow.json` workflow json file into your ComfyUI
15
+
16
+ ## Simple but paid usage:
17
+
18
+ ### 1. Install Clarity AI node
19
+
20
+ Open ComfyUI Manager, search for Clarity AI, and install the node.
21
+
22
+ Alternatively:
23
+
24
+ ```bash
25
+ cd custom_nodes
26
+ git clone https://github.com/philz1337x/ComfyUI-ClarityAI
27
+ ```
28
+
29
+ ### 2. Create your API key
30
+
31
+ Create an API key at: https://clarityai.co/comfyui
32
+
33
+ ### 3. Add the key to the node
34
+
35
+ Add the API key to the environment variable "`CAI_API_KEY`"
36
+
37
+ Alternatively, you can write your API key to a "`cai_platform_key.txt`" text file in the ComfyUI-ClarityAI folder.
38
+
39
+ Not recommended: You can also use and/or override the above by entering your API key in the '`api_key_override`' field. But be careful to delete the api_key_override when sharing your workflow.
40
+
41
+ <!--
42
+ A) Drag and drop this image, with the workflow inside, into ComfyUI and install missing nodes. -->
43
+ <!-- ![alt text](workflow_inside.png) -->
Client/__init__.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ from .clarityai_api import ClarityAIUpscaler
2
+
3
+ NODE_CLASS_MAPPINGS = {
4
+ "Clarity AI Upscaler": ClarityAIUpscaler,
5
+ }
Client/before_after.png ADDED

Git LFS Details

  • SHA256: 7c7b2ee2fee194e43f003b8533efef3dbc64e5dabf28f4a3606ef0821e962317
  • Pointer size: 132 Bytes
  • Size of remote file: 1.86 MB
Client/cai_api.png ADDED

Git LFS Details

  • SHA256: eca7be9aaaa430c30afd8140c8d8f1cb602450a50e8d16de3ce4d13df444b52d
  • Pointer size: 131 Bytes
  • Size of remote file: 695 kB
Client/clarityai_api.py ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ from requests.models import PreparedRequest
3
+ from PIL import Image
4
+ import numpy as np
5
+ import torch
6
+ from torchvision.transforms import ToPILImage
7
+ from io import BytesIO
8
+ import os
9
+ import time
10
+
11
+ API_KEY = os.environ.get("CAI_API_KEY")
12
+
13
+ # Check for API key in file as a backup, not recommended
14
+ try:
15
+ if not API_KEY:
16
+ dir_path = os.path.dirname(os.path.realpath(__file__))
17
+ with open(os.path.join(dir_path, "cai_platform_key.txt"), "r") as f:
18
+ API_KEY = f.read().strip()
19
+ # Validate the key is not empty
20
+ if API_KEY.strip() == "":
21
+ raise Exception(f"API Key is required to use Clarity AI. \nPlease set the CAI_API_KEY environment variable to your API key or place in {dir_path}/cai_platform_key.txt.")
22
+
23
+ except Exception as e:
24
+ print(f"\n\n***API Key is required to use Clarity AI. Please set the CAI_API_KEY environment variable to your API key or place in {dir_path}/cai_platform_key.txt.***\n\n")
25
+
26
+ #ROOT_API = "https://api.clarityai.cc/v1/upscale"
27
+ ROOT_API = "https://v1-upscale-endpoint-oak26mtdga-ey.a.run.app"
28
+
29
+
30
+ class ClarityBase:
31
+ API_ENDPOINT = ""
32
+ POLL_ENDPOINT = ""
33
+ ACCEPT = ""
34
+
35
+ @classmethod
36
+ def INPUT_TYPES(cls):
37
+ return cls.INPUT_SPEC
38
+
39
+ RETURN_TYPES = ("IMAGE",)
40
+ FUNCTION = "call"
41
+ CATEGORY = "Clarity AI"
42
+
43
+ def call(self, *args, **kwargs):
44
+
45
+ buffered = BytesIO()
46
+ files = {'none': None}
47
+ data = None
48
+
49
+ image = kwargs.get('image', None)
50
+ if image is not None:
51
+ kwargs["mode"] = "image-to-image"
52
+ kwargs.pop("aspect_ratio", None)
53
+ image = ToPILImage()(image.squeeze(0).permute(2,0,1))
54
+ image.save(buffered, format="PNG")
55
+ files = self._get_files(buffered, **kwargs)
56
+ else:
57
+ kwargs.pop("strength", None)
58
+
59
+ style = kwargs.get('style', False)
60
+ if style is False:
61
+ kwargs.pop('style_preset', None)
62
+
63
+ kwargs['comfyui'] = True
64
+
65
+ headers = {
66
+ "Authorization": API_KEY,
67
+ }
68
+
69
+ if kwargs.get("api_key_override"):
70
+ headers = {
71
+ "Authorization": kwargs.get("api_key_override"),
72
+ }
73
+
74
+ if headers.get("Authorization") is None:
75
+ raise Exception(f"No Clarity AI key set.\n\nUse your Clarity AI API key by:\n1. Setting the CAI_API_KEY environment variable to your API key\n3. Placing inside cai_platform_key.txt\n4. Passing the API key as an argument to the function with the key 'api_key_override'")
76
+
77
+ headers["Accept"] = self.ACCEPT
78
+
79
+ data = self._get_data(**kwargs)
80
+
81
+ req = PreparedRequest()
82
+ req.prepare_method('POST')
83
+ req.prepare_url(f"{ROOT_API}{self.API_ENDPOINT}", None)
84
+ req.prepare_headers(headers)
85
+ req.prepare_body(data=data, files=files)
86
+ response = requests.Session().send(req)
87
+
88
+ if response.status_code == 200:
89
+ if self.POLL_ENDPOINT != "":
90
+ id = response.json().get("id")
91
+ timeout = 550
92
+ start_time = time.time()
93
+ while True:
94
+ response = requests.get(f"{ROOT_API}{self.POLL_ENDPOINT}{id}", headers=headers, timeout=timeout)
95
+ if response.status_code == 200:
96
+ print("took time: ", time.time() - start_time)
97
+ if self.ACCEPT == "image/*":
98
+ return self._return_image(response)
99
+ if self.ACCEPT == "video/*":
100
+ return self._return_video(response)
101
+ break
102
+ elif response.status_code == 202:
103
+ time.sleep(10)
104
+ elif time.time() - start_time > timeout:
105
+ raise Exception("Clarity AI API Timeout: Request took too long to complete")
106
+ else:
107
+ error_info = response.json()
108
+ raise Exception(f"Clarity AI API Error: {error_info}")
109
+ else:
110
+ result_image = Image.open(BytesIO(response.content))
111
+ result_image = result_image.convert("RGBA")
112
+ result_image = np.array(result_image).astype(np.float32) / 255.0
113
+ result_image = torch.from_numpy(result_image)[None,]
114
+ return (result_image,)
115
+ else:
116
+ print("Fehler!! Status Code:", response.status_code)
117
+ error_info = response.text
118
+ print("error_info: " + error_info)
119
+ if response.status_code == 401:
120
+ raise Exception("Clarity AI API Error: Unauthorized.\n\nUse your Clarity AI API key by:\n1. Setting the CAI_API_KEY environment variable to your API key\n3. Placing inside cai_platform_key.txt\n4. Passing the API key as an argument to the function with the key 'api_key_override' \n\n \n\n")
121
+ if response.status_code == 402:
122
+ raise Exception("Clarity AI API Error: Not enough credits.\n\nPlease ensure your Clarity AI API account has enough credits to complete this action. \n\n \n\n")
123
+ if response.status_code == 400:
124
+ raise Exception(f"Clarity AI API Error: Bad request.\n\n{error_info} \n\n \n\n")
125
+ else:
126
+ raise Exception(f"Clarity AI API Error: {error_info}")
127
+
128
+ def _return_image(self, response):
129
+ result_image = Image.open(BytesIO(response.content))
130
+ result_image = result_image.convert("RGBA")
131
+ result_image = np.array(result_image).astype(np.float32) / 255.0
132
+ result_image = torch.from_numpy(result_image)[None,]
133
+ return (result_image,)
134
+
135
+ def _return_video(self, response):
136
+ result_video = response.content
137
+ return (result_video,)
138
+
139
+ def _get_files(self, buffered, **kwargs):
140
+ return {
141
+ "image": buffered.getvalue()
142
+ }
143
+
144
+ def _get_data(self, **kwargs):
145
+ return {k: v for k, v in kwargs.items() if k != "image"}
146
+
147
+
148
+ class ClarityAIUpscaler(ClarityBase):
149
+ API_ENDPOINT = ""
150
+ POLL_ENDPOINT = ""
151
+ ACCEPT = "image/*"
152
+ INPUT_SPEC = {
153
+ "required": {
154
+ "image": ("IMAGE",),
155
+ },
156
+ "optional": {
157
+ "prompt": ("STRING", {"multiline": True}),
158
+ "creativity": ("FLOAT", {"default": 0, "min": -10, "max": 10, "step": 1}),
159
+ "resemblance": ("FLOAT", {"default": 0, "min": -10, "max": 10, "step": 1}),
160
+ "dynamic": ("FLOAT", {"default": 0, "min": -10, "max": 10, "step": 1}),
161
+ "fractality": ("FLOAT", {"default": 0, "min": -10, "max": 10, "step": 1}),
162
+ "style": (["default", "portrait", "anime"],),
163
+ "scale_factor": (["2", "4", "6", "8", "10", "12", "14", "16"],),
164
+ "api_key_override": ("STRING", {"multiline": False}),
165
+ }
166
+ }
Client/dog_example.png ADDED

Git LFS Details

  • SHA256: f8855bffc6aba9a6b5c4813721b9340c19ac4a6290d9250e4b6b407bd905176e
  • Pointer size: 132 Bytes
  • Size of remote file: 1.78 MB
Client/workflow_inside.png ADDED

Git LFS Details

  • SHA256: 1f678011f38bdd65336274d888e8b2c9b9dc0b64ea0805f7f9a9408a612b4aed
  • Pointer size: 132 Bytes
  • Size of remote file: 3.35 MB
Dockerfile ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Sử dụng phiên bản Python 3.10
2
+ FROM python:3.10-slim
3
+
4
+ # Tạo một người dùng không phải root để bảo mật hơn
5
+ RUN useradd -m -u 1000 user
6
+ USER user
7
+ ENV PATH="/home/user/.local/bin:$PATH"
8
+
9
+ # Đặt thư mục làm việc
10
+ WORKDIR /app
11
+
12
+ # Sao chép file requirements và cài đặt thư viện
13
+ # Bước này được làm riêng để tận dụng cache của Docker
14
+ COPY --chown=user ./requirements.txt requirements.txt
15
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
16
+
17
+ # Sao chép toàn bộ dự án vào thư mục làm việc
18
+ # Điều này bao gồm thư mục ComfyUI, api_server.py, run.sh, v.v.
19
+ COPY --chown=user . /app
20
+
21
+ # Cấp quyền thực thi cho script run.sh
22
+ RUN chmod +x run.sh
23
+
24
+ # Lệnh để chạy khi Space khởi động
25
+ # Nó sẽ thực thi script của chúng ta
26
+ CMD ["bash", "run.sh"]
27
+
__pycache__/api_server.cpython-310.pyc ADDED
Binary file (4.03 kB). View file
 
api_server.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import io
2
+ import json
3
+ import uuid
4
+ import urllib.request
5
+ import urllib.parse
6
+ import websocket
7
+
8
+ from fastapi import FastAPI, File, UploadFile, HTTPException
9
+ from fastapi.responses import StreamingResponse
10
+
11
+ # --- Cấu hình ---
12
+ # Địa chỉ máy chủ ComfyUI, mặc định là localhost
13
+ COMFYUI_SERVER_ADDRESS = "127.0.0.1:8188"
14
+ # ID của client, dùng để nhận diện trong WebSocket
15
+ CLIENT_ID = str(uuid.uuid4())
16
+
17
+ # Khởi tạo ứng dụng FastAPI
18
+ app = FastAPI(title="Clarity AI Upscaler API")
19
+
20
+ def get_image(filename, subfolder, folder_type):
21
+ """Lấy file ảnh từ máy chủ ComfyUI."""
22
+ data = {"filename": filename, "subfolder": subfolder, "type": folder_type}
23
+ url_values = urllib.parse.urlencode(data)
24
+ with urllib.request.urlopen(f"http://{COMFYUI_SERVER_ADDRESS}/view?{url_values}") as response:
25
+ return response.read()
26
+
27
+ def queue_prompt(prompt_workflow):
28
+ """Gửi yêu cầu thực thi quy trình đến ComfyUI."""
29
+ p = {"prompt": prompt_workflow, "client_id": CLIENT_ID}
30
+ data = json.dumps(p).encode('utf-8')
31
+ req = urllib.request.Request(f"http://{COMFYUI_SERVER_ADDRESS}/prompt", data=data)
32
+ return json.loads(urllib.request.urlopen(req).read())
33
+
34
+ def upload_image(image_bytes: bytes, filename: str = "input_image.png"):
35
+ """Tải ảnh lên thư mục input của ComfyUI."""
36
+ import requests
37
+ files = {"image": (filename, image_bytes, 'image/png'), "overwrite": (None, 'true')}
38
+ response = requests.post(f"http://{COMFYUI_SERVER_ADDRESS}/upload/image", files=files)
39
+ if response.status_code == 200:
40
+ return response.json()
41
+ else:
42
+ raise HTTPException(status_code=500, detail=f"Failed to upload image: {response.text}")
43
+
44
+ def get_history(prompt_id):
45
+ """Lấy lịch sử thực thi của một prompt."""
46
+ with urllib.request.urlopen(f"http://{COMFYUI_SERVER_ADDRESS}/history/{prompt_id}") as response:
47
+ return json.loads(response.read())
48
+
49
+ def track_execution_and_get_output(prompt_id):
50
+ """Theo dõi tiến trình qua WebSocket và lấy ảnh kết quả."""
51
+ ws_url = f"ws://{COMFYUI_SERVER_ADDRESS}/ws?clientId={CLIENT_ID}"
52
+ ws = websocket.WebSocket()
53
+ ws.connect(ws_url)
54
+
55
+ while True:
56
+ out = ws.recv()
57
+ if isinstance(out, str):
58
+ message = json.loads(out)
59
+ if message['type'] == 'executing':
60
+ data = message['data']
61
+ if data['node'] is None and data['prompt_id'] == prompt_id:
62
+ break # Đã thực thi xong
63
+ else:
64
+ continue # Bỏ qua các tin nhắn không phải dạng text
65
+ ws.close()
66
+
67
+ history = get_history(prompt_id)[prompt_id]
68
+ for node_id, node_output in history['outputs'].items():
69
+ if 'images' in node_output:
70
+ for image in node_output['images']:
71
+ if image['type'] == 'output':
72
+ image_data = get_image(image['filename'], image['subfolder'], image['type'])
73
+ return image_data
74
+ raise HTTPException(status_code=500, detail="Không tìm thấy ảnh kết quả.")
75
+
76
+ @app.post("/upscale/",
77
+ summary="Nâng cấp và tinh chỉnh hình ảnh",
78
+ response_description="Hình ảnh đã được xử lý ở định dạng PNG")
79
+ async def upscale_image(file: UploadFile = File(..., description="File ảnh cần xử lý.")):
80
+ """
81
+ Nhận một file ảnh, xử lý nó thông qua quy trình ComfyUI, và trả về kết quả.
82
+ """
83
+ try:
84
+ # 1. Đọc file workflow từ định dạng API
85
+ with open("workflow_api.json", "r", encoding="utf-8") as f:
86
+ prompt_workflow = json.load(f)
87
+
88
+ # 2. Đọc và tải ảnh đầu vào lên ComfyUI
89
+ image_bytes = await file.read()
90
+ upload_response = upload_image(image_bytes)
91
+ input_filename = upload_response['name']
92
+
93
+ # 3. Tìm node LoadImage (ID=17) và cập nhật tên file
94
+ # LƯU Ý: ID '17' là ID của node LoadImage trong workflow của bạn.
95
+ # Nếu bạn thay đổi workflow, ID này có thể thay đổi.
96
+ prompt_workflow["17"]["inputs"]["image"] = input_filename
97
+
98
+ # 4. Gửi quy trình để thực thi
99
+ queue_response = queue_prompt(prompt_workflow)
100
+ prompt_id = queue_response['prompt_id']
101
+
102
+ # 5. Theo dõi tiến trình và lấy ảnh kết quả
103
+ result_image_bytes = track_execution_and_get_output(prompt_id)
104
+
105
+ # 6. Trả về ảnh kết quả
106
+ return StreamingResponse(io.BytesIO(result_image_bytes), media_type="image/png")
107
+
108
+ except FileNotFoundError:
109
+ raise HTTPException(status_code=500, detail="Không tìm thấy file workflow_api.json.")
110
+ except Exception as e:
111
+ raise HTTPException(status_code=500, detail=f"Đã xảy ra lỗi: {str(e)}")
112
+
113
+ # Để chạy máy chủ này, mở terminal và gõ lệnh:
114
+ # uvicorn api_server:app --reload
free-workflow.json ADDED
@@ -0,0 +1,1053 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "last_node_id": 83,
3
+ "last_link_id": 141,
4
+ "nodes": [
5
+ {
6
+ "id": 13,
7
+ "type": "CR LoRA Stack",
8
+ "pos": [-292.2227668346914, -273.56417780232823],
9
+ "size": {
10
+ "0": 315,
11
+ "1": 342
12
+ },
13
+ "flags": {},
14
+ "order": 0,
15
+ "mode": 0,
16
+ "inputs": [
17
+ {
18
+ "name": "lora_stack",
19
+ "type": "LORA_STACK",
20
+ "link": null
21
+ }
22
+ ],
23
+ "outputs": [
24
+ {
25
+ "name": "LORA_STACK",
26
+ "type": "LORA_STACK",
27
+ "links": [10],
28
+ "shape": 3,
29
+ "slot_index": 0
30
+ },
31
+ {
32
+ "name": "show_help",
33
+ "type": "STRING",
34
+ "links": null,
35
+ "shape": 3
36
+ }
37
+ ],
38
+ "properties": {
39
+ "Node name for S&R": "CR LoRA Stack"
40
+ },
41
+ "widgets_values": [
42
+ "On",
43
+ "Other\\more_details.safetensors",
44
+ 1,
45
+ 1,
46
+ "On",
47
+ "Other\\SDXLrender_v2.0.safetensors",
48
+ 1,
49
+ -0.32,
50
+ "Off",
51
+ "None",
52
+ 1,
53
+ 1
54
+ ],
55
+ "color": "#2a363b",
56
+ "bgcolor": "#3f5159"
57
+ },
58
+ {
59
+ "id": 34,
60
+ "type": "Reroute",
61
+ "pos": [950.4974792968751, -439.5025207031251],
62
+ "size": [75, 26],
63
+ "flags": {},
64
+ "order": 6,
65
+ "mode": 0,
66
+ "inputs": [
67
+ {
68
+ "name": "",
69
+ "type": "*",
70
+ "link": 140,
71
+ "label": "🧲 IMG"
72
+ }
73
+ ],
74
+ "outputs": [
75
+ {
76
+ "name": "",
77
+ "type": "IMAGE",
78
+ "links": [57],
79
+ "slot_index": 0
80
+ }
81
+ ],
82
+ "properties": {
83
+ "showOutputText": false,
84
+ "horizontal": false
85
+ },
86
+ "color": "#432",
87
+ "bgcolor": "#653"
88
+ },
89
+ {
90
+ "id": 20,
91
+ "type": "ControlNetLoader",
92
+ "pos": [1220.4974792968746, -639.5025207031249],
93
+ "size": {
94
+ "0": 344.26751708984375,
95
+ "1": 61.083885192871094
96
+ },
97
+ "flags": {},
98
+ "order": 1,
99
+ "mode": 0,
100
+ "outputs": [
101
+ {
102
+ "name": "CONTROL_NET",
103
+ "type": "CONTROL_NET",
104
+ "links": [25],
105
+ "shape": 3,
106
+ "slot_index": 0
107
+ }
108
+ ],
109
+ "properties": {
110
+ "Node name for S&R": "ControlNetLoader"
111
+ },
112
+ "widgets_values": ["control_v11f1e_sd15_tile.safetensors"],
113
+ "color": "#432",
114
+ "bgcolor": "#653"
115
+ },
116
+ {
117
+ "id": 23,
118
+ "type": "ToBasicPipe",
119
+ "pos": [1610.4974792968746, -569.5025207031249],
120
+ "size": {
121
+ "0": 241.79998779296875,
122
+ "1": 106
123
+ },
124
+ "flags": {},
125
+ "order": 15,
126
+ "mode": 0,
127
+ "inputs": [
128
+ {
129
+ "name": "model",
130
+ "type": "MODEL",
131
+ "link": 28
132
+ },
133
+ {
134
+ "name": "clip",
135
+ "type": "CLIP",
136
+ "link": 29
137
+ },
138
+ {
139
+ "name": "vae",
140
+ "type": "VAE",
141
+ "link": 30
142
+ },
143
+ {
144
+ "name": "positive",
145
+ "type": "CONDITIONING",
146
+ "link": 31
147
+ },
148
+ {
149
+ "name": "negative",
150
+ "type": "CONDITIONING",
151
+ "link": 78
152
+ }
153
+ ],
154
+ "outputs": [
155
+ {
156
+ "name": "basic_pipe",
157
+ "type": "BASIC_PIPE",
158
+ "links": [61],
159
+ "shape": 3,
160
+ "slot_index": 0
161
+ }
162
+ ],
163
+ "properties": {
164
+ "Node name for S&R": "ToBasicPipe"
165
+ },
166
+ "color": "#432",
167
+ "bgcolor": "#653"
168
+ },
169
+ {
170
+ "id": 4,
171
+ "type": "CheckpointLoaderSimple",
172
+ "pos": [-292.2227668346914, 176.43582219767177],
173
+ "size": {
174
+ "0": 315,
175
+ "1": 98
176
+ },
177
+ "flags": {},
178
+ "order": 2,
179
+ "mode": 0,
180
+ "outputs": [
181
+ {
182
+ "name": "MODEL",
183
+ "type": "MODEL",
184
+ "links": [11],
185
+ "slot_index": 0
186
+ },
187
+ {
188
+ "name": "CLIP",
189
+ "type": "CLIP",
190
+ "links": [12],
191
+ "slot_index": 1
192
+ },
193
+ {
194
+ "name": "VAE",
195
+ "type": "VAE",
196
+ "links": [52],
197
+ "slot_index": 2
198
+ }
199
+ ],
200
+ "properties": {
201
+ "Node name for S&R": "CheckpointLoaderSimple"
202
+ },
203
+ "widgets_values": ["FAVORITE--\\juggernaut_reborn.safetensors"],
204
+ "color": "#2a363b",
205
+ "bgcolor": "#3f5159"
206
+ },
207
+ {
208
+ "id": 47,
209
+ "type": "Reroute",
210
+ "pos": [1883.2182315334064, 105.55446633061717],
211
+ "size": [75, 26],
212
+ "flags": {},
213
+ "order": 7,
214
+ "mode": 0,
215
+ "inputs": [
216
+ {
217
+ "name": "",
218
+ "type": "*",
219
+ "link": 141,
220
+ "label": "🧲 IMG"
221
+ }
222
+ ],
223
+ "outputs": [
224
+ {
225
+ "name": "",
226
+ "type": "IMAGE",
227
+ "links": [88, 94],
228
+ "slot_index": 0
229
+ }
230
+ ],
231
+ "properties": {
232
+ "showOutputText": false,
233
+ "horizontal": false
234
+ },
235
+ "color": "#223",
236
+ "bgcolor": "#335"
237
+ },
238
+ {
239
+ "id": 24,
240
+ "type": "ToBasicPipe",
241
+ "pos": [606.7772331653085, -280.56417780232823],
242
+ "size": {
243
+ "0": 241.79998779296875,
244
+ "1": 106
245
+ },
246
+ "flags": {},
247
+ "order": 11,
248
+ "mode": 0,
249
+ "inputs": [
250
+ {
251
+ "name": "model",
252
+ "type": "MODEL",
253
+ "link": 33
254
+ },
255
+ {
256
+ "name": "clip",
257
+ "type": "CLIP",
258
+ "link": 51
259
+ },
260
+ {
261
+ "name": "vae",
262
+ "type": "VAE",
263
+ "link": 52
264
+ },
265
+ {
266
+ "name": "positive",
267
+ "type": "CONDITIONING",
268
+ "link": 139
269
+ },
270
+ {
271
+ "name": "negative",
272
+ "type": "CONDITIONING",
273
+ "link": 50
274
+ }
275
+ ],
276
+ "outputs": [
277
+ {
278
+ "name": "basic_pipe",
279
+ "type": "BASIC_PIPE",
280
+ "links": [53],
281
+ "shape": 3,
282
+ "slot_index": 0
283
+ }
284
+ ],
285
+ "properties": {
286
+ "Node name for S&R": "ToBasicPipe"
287
+ },
288
+ "color": "#2a363b",
289
+ "bgcolor": "#3f5159"
290
+ },
291
+ {
292
+ "id": 46,
293
+ "type": "VAEEncodeTiled",
294
+ "pos": [2183.2182315334067, -14.445533669382833],
295
+ "size": {
296
+ "0": 315,
297
+ "1": 78
298
+ },
299
+ "flags": {},
300
+ "order": 18,
301
+ "mode": 0,
302
+ "inputs": [
303
+ {
304
+ "name": "pixels",
305
+ "type": "IMAGE",
306
+ "link": 90
307
+ },
308
+ {
309
+ "name": "vae",
310
+ "type": "VAE",
311
+ "link": 77
312
+ }
313
+ ],
314
+ "outputs": [
315
+ {
316
+ "name": "LATENT",
317
+ "type": "LATENT",
318
+ "links": [82],
319
+ "shape": 3,
320
+ "slot_index": 0
321
+ }
322
+ ],
323
+ "properties": {
324
+ "Node name for S&R": "VAEEncodeTiled"
325
+ },
326
+ "widgets_values": [768],
327
+ "color": "#223",
328
+ "bgcolor": "#335"
329
+ },
330
+ {
331
+ "id": 52,
332
+ "type": "ImageUpscaleWithModel",
333
+ "pos": [2173.2182315334067, 115.55446633061717],
334
+ "size": {
335
+ "0": 312.3489685058594,
336
+ "1": 47.45939636230469
337
+ },
338
+ "flags": {},
339
+ "order": 10,
340
+ "mode": 0,
341
+ "inputs": [
342
+ {
343
+ "name": "upscale_model",
344
+ "type": "UPSCALE_MODEL",
345
+ "link": 87,
346
+ "slot_index": 0
347
+ },
348
+ {
349
+ "name": "image",
350
+ "type": "IMAGE",
351
+ "link": 88,
352
+ "slot_index": 1
353
+ }
354
+ ],
355
+ "outputs": [
356
+ {
357
+ "name": "IMAGE",
358
+ "type": "IMAGE",
359
+ "links": [91],
360
+ "shape": 3,
361
+ "slot_index": 0
362
+ }
363
+ ],
364
+ "properties": {
365
+ "Node name for S&R": "ImageUpscaleWithModel"
366
+ },
367
+ "color": "#223",
368
+ "bgcolor": "#335"
369
+ },
370
+ {
371
+ "id": 53,
372
+ "type": "UpscaleModelLoader",
373
+ "pos": [2193.2182315334067, 365.5544663306172],
374
+ "size": {
375
+ "0": 308.583251953125,
376
+ "1": 77.44984436035156
377
+ },
378
+ "flags": {},
379
+ "order": 3,
380
+ "mode": 0,
381
+ "outputs": [
382
+ {
383
+ "name": "UPSCALE_MODEL",
384
+ "type": "UPSCALE_MODEL",
385
+ "links": [87],
386
+ "shape": 3
387
+ }
388
+ ],
389
+ "properties": {
390
+ "Node name for S&R": "UpscaleModelLoader"
391
+ },
392
+ "widgets_values": ["4xNomosUniDAT_otf.pth"],
393
+ "color": "#223",
394
+ "bgcolor": "#335"
395
+ },
396
+ {
397
+ "id": 55,
398
+ "type": "FreeU_V2",
399
+ "pos": [2553.2182315334067, -234.44553366938283],
400
+ "size": {
401
+ "0": 315,
402
+ "1": 130
403
+ },
404
+ "flags": {},
405
+ "order": 19,
406
+ "mode": 0,
407
+ "inputs": [
408
+ {
409
+ "name": "model",
410
+ "type": "MODEL",
411
+ "link": 92
412
+ }
413
+ ],
414
+ "outputs": [
415
+ {
416
+ "name": "MODEL",
417
+ "type": "MODEL",
418
+ "links": [93],
419
+ "shape": 3,
420
+ "slot_index": 0
421
+ }
422
+ ],
423
+ "properties": {
424
+ "Node name for S&R": "FreeU_V2"
425
+ },
426
+ "widgets_values": [1.3, 1.4000000000000001, 0.9, 0.2],
427
+ "color": "#223",
428
+ "bgcolor": "#335"
429
+ },
430
+ {
431
+ "id": 19,
432
+ "type": "ControlNetApplyAdvanced",
433
+ "pos": [1220.4974792968746, -529.5025207031249],
434
+ "size": {
435
+ "0": 343.86712646484375,
436
+ "1": 166
437
+ },
438
+ "flags": {},
439
+ "order": 14,
440
+ "mode": 0,
441
+ "inputs": [
442
+ {
443
+ "name": "positive",
444
+ "type": "CONDITIONING",
445
+ "link": 23
446
+ },
447
+ {
448
+ "name": "negative",
449
+ "type": "CONDITIONING",
450
+ "link": 24
451
+ },
452
+ {
453
+ "name": "control_net",
454
+ "type": "CONTROL_NET",
455
+ "link": 25,
456
+ "slot_index": 2
457
+ },
458
+ {
459
+ "name": "image",
460
+ "type": "IMAGE",
461
+ "link": 57,
462
+ "slot_index": 3
463
+ }
464
+ ],
465
+ "outputs": [
466
+ {
467
+ "name": "positive",
468
+ "type": "CONDITIONING",
469
+ "links": [31],
470
+ "shape": 3,
471
+ "slot_index": 0
472
+ },
473
+ {
474
+ "name": "negative",
475
+ "type": "CONDITIONING",
476
+ "links": [],
477
+ "shape": 3,
478
+ "slot_index": 1
479
+ }
480
+ ],
481
+ "properties": {
482
+ "Node name for S&R": "ControlNetApplyAdvanced"
483
+ },
484
+ "widgets_values": [0.9, 0, 0.9],
485
+ "color": "#432",
486
+ "bgcolor": "#653"
487
+ },
488
+ {
489
+ "id": 21,
490
+ "type": "FromBasicPipe",
491
+ "pos": [950.4974792968751, -569.5025207031249],
492
+ "size": {
493
+ "0": 241.79998779296875,
494
+ "1": 106
495
+ },
496
+ "flags": {},
497
+ "order": 13,
498
+ "mode": 0,
499
+ "inputs": [
500
+ {
501
+ "name": "basic_pipe",
502
+ "type": "BASIC_PIPE",
503
+ "link": 53,
504
+ "slot_index": 0
505
+ }
506
+ ],
507
+ "outputs": [
508
+ {
509
+ "name": "model",
510
+ "type": "MODEL",
511
+ "links": [28],
512
+ "shape": 3,
513
+ "slot_index": 0
514
+ },
515
+ {
516
+ "name": "clip",
517
+ "type": "CLIP",
518
+ "links": [29],
519
+ "shape": 3,
520
+ "slot_index": 1
521
+ },
522
+ {
523
+ "name": "vae",
524
+ "type": "VAE",
525
+ "links": [30],
526
+ "shape": 3,
527
+ "slot_index": 2
528
+ },
529
+ {
530
+ "name": "positive",
531
+ "type": "CONDITIONING",
532
+ "links": [23],
533
+ "shape": 3,
534
+ "slot_index": 3
535
+ },
536
+ {
537
+ "name": "negative",
538
+ "type": "CONDITIONING",
539
+ "links": [24, 78],
540
+ "shape": 3,
541
+ "slot_index": 4
542
+ }
543
+ ],
544
+ "properties": {
545
+ "Node name for S&R": "FromBasicPipe"
546
+ },
547
+ "color": "#432",
548
+ "bgcolor": "#653"
549
+ },
550
+ {
551
+ "id": 36,
552
+ "type": "FromBasicPipe",
553
+ "pos": [1883.2182315334064, -54.445533669382826],
554
+ "size": {
555
+ "0": 241.79998779296875,
556
+ "1": 106
557
+ },
558
+ "flags": {},
559
+ "order": 16,
560
+ "mode": 0,
561
+ "inputs": [
562
+ {
563
+ "name": "basic_pipe",
564
+ "type": "BASIC_PIPE",
565
+ "link": 61
566
+ }
567
+ ],
568
+ "outputs": [
569
+ {
570
+ "name": "model",
571
+ "type": "MODEL",
572
+ "links": [73],
573
+ "shape": 3,
574
+ "slot_index": 0
575
+ },
576
+ {
577
+ "name": "clip",
578
+ "type": "CLIP",
579
+ "links": null,
580
+ "shape": 3,
581
+ "slot_index": 1
582
+ },
583
+ {
584
+ "name": "vae",
585
+ "type": "VAE",
586
+ "links": [77, 84],
587
+ "shape": 3,
588
+ "slot_index": 2
589
+ },
590
+ {
591
+ "name": "positive",
592
+ "type": "CONDITIONING",
593
+ "links": [80],
594
+ "shape": 3,
595
+ "slot_index": 3
596
+ },
597
+ {
598
+ "name": "negative",
599
+ "type": "CONDITIONING",
600
+ "links": [81],
601
+ "shape": 3,
602
+ "slot_index": 4
603
+ }
604
+ ],
605
+ "properties": {
606
+ "Node name for S&R": "FromBasicPipe"
607
+ },
608
+ "color": "#223",
609
+ "bgcolor": "#335"
610
+ },
611
+ {
612
+ "id": 44,
613
+ "type": "TiledDiffusion",
614
+ "pos": [2183.2182315334067, -234.44553366938283],
615
+ "size": {
616
+ "0": 315,
617
+ "1": 154
618
+ },
619
+ "flags": {},
620
+ "order": 17,
621
+ "mode": 0,
622
+ "inputs": [
623
+ {
624
+ "name": "model",
625
+ "type": "MODEL",
626
+ "link": 73
627
+ }
628
+ ],
629
+ "outputs": [
630
+ {
631
+ "name": "MODEL",
632
+ "type": "MODEL",
633
+ "links": [92],
634
+ "shape": 3,
635
+ "slot_index": 0
636
+ }
637
+ ],
638
+ "properties": {
639
+ "Node name for S&R": "TiledDiffusion"
640
+ },
641
+ "widgets_values": ["MultiDiffusion", 768, 768, 64, 8],
642
+ "color": "#223",
643
+ "bgcolor": "#335"
644
+ },
645
+ {
646
+ "id": 54,
647
+ "type": "ImageScaleBy",
648
+ "pos": [2183.2182315334067, 235.55446633061717],
649
+ "size": {
650
+ "0": 308.1820373535156,
651
+ "1": 82
652
+ },
653
+ "flags": {},
654
+ "order": 12,
655
+ "mode": 0,
656
+ "inputs": [
657
+ {
658
+ "name": "image",
659
+ "type": "IMAGE",
660
+ "link": 91,
661
+ "slot_index": 0
662
+ }
663
+ ],
664
+ "outputs": [
665
+ {
666
+ "name": "IMAGE",
667
+ "type": "IMAGE",
668
+ "links": [90],
669
+ "shape": 3,
670
+ "slot_index": 0
671
+ }
672
+ ],
673
+ "properties": {
674
+ "Node name for S&R": "ImageScaleBy"
675
+ },
676
+ "widgets_values": ["lanczos", 0.6],
677
+ "color": "#223",
678
+ "bgcolor": "#335"
679
+ },
680
+ {
681
+ "id": 68,
682
+ "type": "PreviewImage",
683
+ "pos": [3070, 404],
684
+ "size": {
685
+ "0": 320.48455810546875,
686
+ "1": 251.10845947265625
687
+ },
688
+ "flags": {},
689
+ "order": 23,
690
+ "mode": 0,
691
+ "inputs": [
692
+ {
693
+ "name": "images",
694
+ "type": "IMAGE",
695
+ "link": 110
696
+ }
697
+ ],
698
+ "properties": {
699
+ "Node name for S&R": "PreviewImage"
700
+ },
701
+ "color": "#223",
702
+ "bgcolor": "#335"
703
+ },
704
+ {
705
+ "id": 56,
706
+ "type": "Image Comparer (rgthree)",
707
+ "pos": {
708
+ "0": 2903,
709
+ "1": -234,
710
+ "2": 0,
711
+ "3": 0,
712
+ "4": 0,
713
+ "5": 0,
714
+ "6": 0,
715
+ "7": 0,
716
+ "8": 0,
717
+ "9": 0
718
+ },
719
+ "size": {
720
+ "0": 490.78875732421875,
721
+ "1": 578.8710327148438
722
+ },
723
+ "flags": {},
724
+ "order": 22,
725
+ "mode": 0,
726
+ "inputs": [
727
+ {
728
+ "name": "image_a",
729
+ "type": "IMAGE",
730
+ "link": 95,
731
+ "dir": 3,
732
+ "label": "Upscale"
733
+ },
734
+ {
735
+ "name": "image_b",
736
+ "type": "IMAGE",
737
+ "link": 94,
738
+ "dir": 3,
739
+ "label": "Referenc"
740
+ }
741
+ ],
742
+ "outputs": [],
743
+ "properties": {
744
+ "comparer_mode": "Slide"
745
+ },
746
+ "widgets_values": [
747
+ [
748
+ "/view?filename=rgthree.compare._temp_adlpf_00103_.png&type=temp&subfolder=&rand=0.013878588376836198",
749
+ "/view?filename=rgthree.compare._temp_adlpf_00104_.png&type=temp&subfolder=&rand=0.7922121652263727"
750
+ ]
751
+ ],
752
+ "color": "#223",
753
+ "bgcolor": "#335"
754
+ },
755
+ {
756
+ "id": 45,
757
+ "type": "KSampler",
758
+ "pos": [2543.2182315334067, -44.445533669382826],
759
+ "size": {
760
+ "0": 315,
761
+ "1": 262
762
+ },
763
+ "flags": {},
764
+ "order": 20,
765
+ "mode": 0,
766
+ "inputs": [
767
+ {
768
+ "name": "model",
769
+ "type": "MODEL",
770
+ "link": 93
771
+ },
772
+ {
773
+ "name": "positive",
774
+ "type": "CONDITIONING",
775
+ "link": 80
776
+ },
777
+ {
778
+ "name": "negative",
779
+ "type": "CONDITIONING",
780
+ "link": 81
781
+ },
782
+ {
783
+ "name": "latent_image",
784
+ "type": "LATENT",
785
+ "link": 82
786
+ }
787
+ ],
788
+ "outputs": [
789
+ {
790
+ "name": "LATENT",
791
+ "type": "LATENT",
792
+ "links": [83],
793
+ "shape": 3,
794
+ "slot_index": 0
795
+ }
796
+ ],
797
+ "properties": {
798
+ "Node name for S&R": "KSampler"
799
+ },
800
+ "widgets_values": [
801
+ 623550544877658,
802
+ "randomize",
803
+ 24,
804
+ 6,
805
+ "dpmpp_2m",
806
+ "karras",
807
+ 0.35000000000000003
808
+ ],
809
+ "color": "#223",
810
+ "bgcolor": "#335"
811
+ },
812
+ {
813
+ "id": 48,
814
+ "type": "VAEDecodeTiled",
815
+ "pos": [2553.2182315334067, 275.5544663306172],
816
+ "size": {
817
+ "0": 315,
818
+ "1": 78
819
+ },
820
+ "flags": {},
821
+ "order": 21,
822
+ "mode": 0,
823
+ "inputs": [
824
+ {
825
+ "name": "samples",
826
+ "type": "LATENT",
827
+ "link": 83
828
+ },
829
+ {
830
+ "name": "vae",
831
+ "type": "VAE",
832
+ "link": 84
833
+ }
834
+ ],
835
+ "outputs": [
836
+ {
837
+ "name": "IMAGE",
838
+ "type": "IMAGE",
839
+ "links": [95, 110],
840
+ "shape": 3,
841
+ "slot_index": 0
842
+ }
843
+ ],
844
+ "properties": {
845
+ "Node name for S&R": "VAEDecodeTiled"
846
+ },
847
+ "widgets_values": [768],
848
+ "color": "#223",
849
+ "bgcolor": "#335"
850
+ },
851
+ {
852
+ "id": 7,
853
+ "type": "CLIPTextEncode",
854
+ "pos": [76, 89],
855
+ "size": {
856
+ "0": 425.27801513671875,
857
+ "1": 180.6060791015625
858
+ },
859
+ "flags": {},
860
+ "order": 8,
861
+ "mode": 0,
862
+ "inputs": [
863
+ {
864
+ "name": "clip",
865
+ "type": "CLIP",
866
+ "link": 15
867
+ }
868
+ ],
869
+ "outputs": [
870
+ {
871
+ "name": "CONDITIONING",
872
+ "type": "CONDITIONING",
873
+ "links": [50],
874
+ "slot_index": 0
875
+ }
876
+ ],
877
+ "properties": {
878
+ "Node name for S&R": "CLIPTextEncode"
879
+ },
880
+ "widgets_values": [
881
+ "(worst quality, low quality, normal quality:2) embedding:JuggernautNegative-neg, "
882
+ ],
883
+ "color": "#322",
884
+ "bgcolor": "#533"
885
+ },
886
+ {
887
+ "id": 14,
888
+ "type": "CR Apply LoRA Stack",
889
+ "pos": [72.77723316530859, -273.56417780232823],
890
+ "size": {
891
+ "0": 254.40000915527344,
892
+ "1": 66
893
+ },
894
+ "flags": {},
895
+ "order": 5,
896
+ "mode": 0,
897
+ "inputs": [
898
+ {
899
+ "name": "model",
900
+ "type": "MODEL",
901
+ "link": 11
902
+ },
903
+ {
904
+ "name": "clip",
905
+ "type": "CLIP",
906
+ "link": 12
907
+ },
908
+ {
909
+ "name": "lora_stack",
910
+ "type": "LORA_STACK",
911
+ "link": 10
912
+ }
913
+ ],
914
+ "outputs": [
915
+ {
916
+ "name": "MODEL",
917
+ "type": "MODEL",
918
+ "links": [33],
919
+ "shape": 3,
920
+ "slot_index": 0
921
+ },
922
+ {
923
+ "name": "CLIP",
924
+ "type": "CLIP",
925
+ "links": [15, 51, 138],
926
+ "shape": 3,
927
+ "slot_index": 1
928
+ },
929
+ {
930
+ "name": "show_help",
931
+ "type": "STRING",
932
+ "links": null,
933
+ "shape": 3
934
+ }
935
+ ],
936
+ "properties": {
937
+ "Node name for S&R": "CR Apply LoRA Stack"
938
+ },
939
+ "color": "#2a363b",
940
+ "bgcolor": "#3f5159"
941
+ },
942
+ {
943
+ "id": 83,
944
+ "type": "CLIPTextEncode",
945
+ "pos": [81, -145],
946
+ "size": {
947
+ "0": 425.27801513671875,
948
+ "1": 180.6060791015625
949
+ },
950
+ "flags": {},
951
+ "order": 9,
952
+ "mode": 0,
953
+ "inputs": [
954
+ {
955
+ "name": "clip",
956
+ "type": "CLIP",
957
+ "link": 138
958
+ }
959
+ ],
960
+ "outputs": [
961
+ {
962
+ "name": "CONDITIONING",
963
+ "type": "CONDITIONING",
964
+ "links": [139],
965
+ "slot_index": 0
966
+ }
967
+ ],
968
+ "properties": {
969
+ "Node name for S&R": "CLIPTextEncode"
970
+ },
971
+ "widgets_values": ["masterpiece, best quality, highres"],
972
+ "color": "#232",
973
+ "bgcolor": "#353"
974
+ },
975
+ {
976
+ "id": 17,
977
+ "type": "LoadImage",
978
+ "pos": [536, -132],
979
+ "size": {
980
+ "0": 290.8611755371094,
981
+ "1": 314
982
+ },
983
+ "flags": {},
984
+ "order": 4,
985
+ "mode": 0,
986
+ "outputs": [
987
+ {
988
+ "name": "IMAGE",
989
+ "type": "IMAGE",
990
+ "links": [140, 141],
991
+ "shape": 3,
992
+ "slot_index": 0
993
+ },
994
+ {
995
+ "name": "MASK",
996
+ "type": "MASK",
997
+ "links": null,
998
+ "shape": 3
999
+ }
1000
+ ],
1001
+ "properties": {
1002
+ "Node name for S&R": "LoadImage"
1003
+ },
1004
+ "widgets_values": ["00026-3626113995.png", "image"],
1005
+ "color": "#2a363b",
1006
+ "bgcolor": "#3f5159"
1007
+ }
1008
+ ],
1009
+ "links": [
1010
+ [10, 13, 0, 14, 2, "LORA_STACK"],
1011
+ [11, 4, 0, 14, 0, "MODEL"],
1012
+ [12, 4, 1, 14, 1, "CLIP"],
1013
+ [15, 14, 1, 7, 0, "CLIP"],
1014
+ [23, 21, 3, 19, 0, "CONDITIONING"],
1015
+ [24, 21, 4, 19, 1, "CONDITIONING"],
1016
+ [25, 20, 0, 19, 2, "CONTROL_NET"],
1017
+ [28, 21, 0, 23, 0, "MODEL"],
1018
+ [29, 21, 1, 23, 1, "CLIP"],
1019
+ [30, 21, 2, 23, 2, "VAE"],
1020
+ [31, 19, 0, 23, 3, "CONDITIONING"],
1021
+ [33, 14, 0, 24, 0, "MODEL"],
1022
+ [50, 7, 0, 24, 4, "CONDITIONING"],
1023
+ [51, 14, 1, 24, 1, "CLIP"],
1024
+ [52, 4, 2, 24, 2, "VAE"],
1025
+ [53, 24, 0, 21, 0, "BASIC_PIPE"],
1026
+ [57, 34, 0, 19, 3, "IMAGE"],
1027
+ [61, 23, 0, 36, 0, "BASIC_PIPE"],
1028
+ [73, 36, 0, 44, 0, "MODEL"],
1029
+ [77, 36, 2, 46, 1, "VAE"],
1030
+ [78, 21, 4, 23, 4, "CONDITIONING"],
1031
+ [80, 36, 3, 45, 1, "CONDITIONING"],
1032
+ [81, 36, 4, 45, 2, "CONDITIONING"],
1033
+ [82, 46, 0, 45, 3, "LATENT"],
1034
+ [83, 45, 0, 48, 0, "LATENT"],
1035
+ [84, 36, 2, 48, 1, "VAE"],
1036
+ [87, 53, 0, 52, 0, "UPSCALE_MODEL"],
1037
+ [88, 47, 0, 52, 1, "IMAGE"],
1038
+ [90, 54, 0, 46, 0, "IMAGE"],
1039
+ [91, 52, 0, 54, 0, "IMAGE"],
1040
+ [92, 44, 0, 55, 0, "MODEL"],
1041
+ [93, 55, 0, 45, 0, "MODEL"],
1042
+ [94, 47, 0, 56, 1, "IMAGE"],
1043
+ [95, 48, 0, 56, 0, "IMAGE"],
1044
+ [110, 48, 0, 68, 0, "IMAGE"],
1045
+ [138, 14, 1, 83, 0, "CLIP"],
1046
+ [139, 83, 0, 24, 3, "CONDITIONING"],
1047
+ [140, 17, 0, 34, 0, "*"],
1048
+ [141, 17, 0, 47, 0, "*"]
1049
+ ],
1050
+ "config": {},
1051
+ "extra": {},
1052
+ "version": 0.4
1053
+ }
requirements.txt ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn[standard]
3
+ python-multipart
4
+ Pillow
5
+ requests
6
+ websocket-client
7
+
8
+ # --- THÊM CÁC THƯ VIỆN CỦA BẠN VÀO ĐÂY ---
9
+ # Các thư viện này rất quan trọng để chạy quy trình AI.
10
+ # Nếu thiếu, ứng dụng sẽ báo lỗi trên Hugging Face.
11
+ # Ví dụ:
12
+ # torch
13
+ # torchvision
14
+ # torchaudio
15
+ # diffusers
16
+ # transformers
17
+ # accelerate
run.sh ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ # Di chuyển vào thư mục ComfyUI và khởi động nó trong nền
4
+ # Giả định rằng bạn sẽ upload thư mục ComfyUI của mình vào đây
5
+ cd ComfyUI
6
+ python main.py --listen --port 8188 &
7
+
8
+ # Đợi một chút để ComfyUI khởi động hoàn toàn
9
+ sleep 15
10
+
11
+ # Quay lại thư mục gốc và khởi động máy chủ FastAPI
12
+ cd ..
13
+ uvicorn api_server:app --host 0.0.0.0 --port 7860
14
+
workflow_description.md ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Phân Tích Chi Tiết Quy Trình Hoạt Động `free-workflow.json`
2
+
3
+ Đây là bản phân tích chi tiết về quy trình xử lý ảnh được định nghĩa trong file `free-workflow.json`. Quy trình này là một luồng công việc Image-to-Image, có chức năng chính là nâng cấp chất lượng (upscale) và tinh chỉnh một hình ảnh có sẵn bằng cách sử dụng ControlNet, Tiled Diffusion và các kỹ thuật khác.
4
+
5
+ ## Tổng Quan Quy Trình
6
+
7
+ Quy trình nhận một ảnh đầu vào và hai câu lệnh (prompt dương và âm), sau đó thực hiện hai lần xử lý chính:
8
+ 1. **Lần 1 (ControlNet Pass):** Áp dụng ControlNet để đảm bảo cấu trúc của ảnh mới sẽ tuân theo ảnh gốc.
9
+ 2. **Lần 2 (Upscale Pass):** Nâng cấp độ phân giải và thêm chi tiết cho ảnh bằng KSampler với các thiết lập tinh chỉnh.
10
+
11
+ ## Các Giai Đoạn Chính
12
+
13
+ Quy trình có thể được chia thành 4 giai đoạn logic như sau:
14
+
15
+ ### Giai đoạn 1: Chuẩn bị và Tải Tài Nguyên
16
+
17
+ Giai đoạn này tập trung vào việc tải tất cả các thành phần cần thiết để bắt đầu quá trình tạo ảnh.
18
+
19
+ - **`LoadImage` (Node 17):** Tải hình ảnh đầu vào (`00026-3626113995.png`) để làm cơ sở cho việc xử lý.
20
+ - **`CheckpointLoaderSimple` (Node 4):** Tải model nền chính (`juggernaut_reborn.safetensors`). Đây là model Stable Diffusion chính của quy trình.
21
+ - **`CR LoRA Stack` (Node 13):** Tải và xếp chồng các model LoRA. Trong trường hợp này, có hai LoRA được sử dụng:
22
+ - `more_details.safetensors`: Dùng để tăng thêm chi tiết cho ảnh.
23
+ - `SDXLrender_v2.0.safetensors`: Dùng để cải thiện chất lượng kết xuất.
24
+ - **`CR Apply LoRA Stack` (Node 14):** Áp dụng các LoRA đã tải vào model chính và CLIP.
25
+ - **`CLIPTextEncode` (Node 83 & 7):** Mã hóa các câu lệnh văn bản thành dạng mà model có thể hiểu được.
26
+ - **Prompt dương (Node 83):** `masterpiece, best quality, highres` (yêu cầu chất lượng cao).
27
+ - **Prompt âm (Node 7):** `(worst quality, low quality, normal quality:2) embedding:JuggernautNegative-neg` (loại bỏ các yếu tố chất lượng thấp).
28
+ - **`ToBasicPipe` (Node 24):** Gói tất cả các thành phần đã tải (model, CLIP, VAE, prompts) vào một "đường ống" (pipe) để dễ dàng truyền đi giữa các node.
29
+
30
+ ### Giai đoạn 2: Áp dụng ControlNet
31
+
32
+ Giai đoạn này sử dụng ControlNet để điều khiển việc tạo ảnh, đảm bảo kết quả cuối cùng giữ lại được bố cục và các đặc điểm chính từ ảnh đầu vào.
33
+
34
+ - **`FromBasicPipe` (Node 21):** Giải nén "đường ống" từ Giai đoạn 1 để lấy ra các thành phần cần thiết.
35
+ - **`ControlNetLoader` (Node 20):** Tải model ControlNet (`control_v11f1e_sd15_tile.safetensors`). Model `tile` này rất hiệu quả trong việc phân tích và tái tạo chi tiết từ ảnh gốc.
36
+ - **`ControlNetApplyAdvanced` (Node 19):** Áp dụng ControlNet lên các prompt. Nó nhận ảnh đầu vào làm ảnh điều khiển, từ đó điều chỉnh các prompt để hướng dẫn KSampler tạo ra một ảnh mới có cấu trúc tương tự ảnh gốc.
37
+ - **`ToBasicPipe` (Node 23):** Sau khi áp dụng ControlNet, các thành phần lại được gói vào một "đường ống" mới để chuyển sang giai đoạn tiếp theo.
38
+
39
+ ### Giai đoạn 3: Nâng Cấp và Tinh Chỉnh (Upscale & Refine)
40
+
41
+ Đây là giai đoạn phức tạp nhất, nơi ảnh được nâng cấp độ phân giải và được tinh chỉnh bằng một KSampler thứ hai với các thiết lập đặc biệt.
42
+
43
+ - **`FromBasicPipe` (Node 36):** Giải nén "đường ống" từ Giai đoạn 2.
44
+ - **Chuỗi xử lý ảnh đầu vào:**
45
+ 1. **`UpscaleModelLoader` (Node 53):** Tải model nâng cấp (`4xNomosUniDAT_otf.pth`).
46
+ 2. **`ImageUpscaleWithModel` (Node 52):** Nâng cấp độ phân giải của ảnh đầu vào gốc bằng model vừa tải.
47
+ 3. **`ImageScaleBy` (Node 54):** Giảm nhẹ kích thước ảnh vừa được nâng cấp xuống còn 60%. Kỹ thuật này thường được dùng để làm mịn ảnh trước khi đưa vào latent space, giúp giảm nhiễu và tạo ra kết quả cuối cùng sắc nét hơn.
48
+ 4. **`VAEEncodeTiled` (Node 46):** Mã hóa hình ảnh đã qua xử lý thành không gian tiềm ẩn (latent space). Đây sẽ là latent đầu vào cho KSampler cuối cùng.
49
+ - **Chuỗi xử lý model:**
50
+ 1. **`TiledDiffusion` (Node 44):** Áp dụng kỹ thuật "MultiDiffusion" lên model. Kỹ thuật này chia ảnh thành các ô nhỏ (tiles) để xử lý, cho phép tạo ra ảnh có độ phân giải cao mà không cần quá nhiều VRAM.
51
+ 2. **`FreeU_V2` (Node 55):** Áp dụng FreeU lên model. Đây là một kỹ thuật giúp cải thiện chất lượng ảnh ở các tần số khác nhau, làm tăng độ tương phản và chi tiết mà không cần thay đổi prompt.
52
+ - **`KSampler` (Node 45):** Đây là bước tạo ảnh chính của giai đoạn này.
53
+ - Nó nhận model đã được tinh chỉnh bởi `TiledDiffusion` và `FreeU_V2`.
54
+ - Nó sử dụng latent từ ảnh đã được upscale/downscale làm điểm bắt đầu.
55
+ - **Denoise (0.35):** Chỉ số denoise thấp (0.35) cho thấy KSampler chỉ thay đổi một phần nhỏ (35%) của latent đầu vào, chủ yếu để thêm chi tiết và tinh chỉnh chứ không tạo ra một ảnh hoàn toàn mới.
56
+
57
+ ### Giai đoạn 4: Kết Xuất và So Sánh
58
+
59
+ Giai đoạn cuối cùng là giải mã latent thành ảnh và hiển thị kết quả.
60
+
61
+ - **`VAEDecodeTiled` (Node 48):** Giải mã latent cuối cùng từ KSampler để tạo ra hình ảnh pixel hoàn chỉnh.
62
+ - **`PreviewImage` (Node 68):** Hiển thị ảnh kết quả cuối cùng.
63
+ - **`Image Comparer` (Node 56):** Cung cấp một giao diện để so sánh trực quan giữa ảnh gốc và ảnh đã được nâng cấp, giúp dễ dàng đánh giá hiệu quả của quy trình.