Skip to content

Commit 2c26e24

Browse files
committed
Merge branch 'release/0.5.0'
2 parents 3f66a0b + abe6641 commit 2c26e24

File tree

4 files changed

+112
-8
lines changed

4 files changed

+112
-8
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
0.5.0
2+
---
3+
4+
### Enhancement
5+
6+
1. Add VRAM Used to the ExecutionTime Node.
7+
8+
PR: https://github.com/ty0x2333/ComfyUI-Dev-Utils/pull/20
9+
10+
Thanks [drake7707](https://github.com/drake7707) .
11+
12+
2. Add a Max statistics row to the ExecutionTime Node to easily view the longest execution time of a node and the VRAM
13+
requirements of the workflow.
14+
115
0.4.3
216
---
317

nodes/execution_time.py

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import time
22

3+
import torch
4+
35
import execution
46
import server
7+
# import model_management
58

69

710
class ExecutionTime:
@@ -22,20 +25,48 @@ def process(self):
2225
CURRENT_START_EXECUTION_DATA = None
2326

2427

28+
# def get_free_vram():
29+
# dev = model_management.get_torch_device()
30+
# if hasattr(dev, 'type') and (dev.type == 'cpu' or dev.type == 'mps'):
31+
# return 0
32+
# else:
33+
# return model_management.get_free_memory(dev)
34+
35+
36+
def get_peak_memory():
37+
if not torch.cuda.is_available():
38+
return 0
39+
device = torch.device('cuda')
40+
return torch.cuda.max_memory_allocated(device)
41+
42+
43+
def reset_peak_memory_record():
44+
if not torch.cuda.is_available():
45+
return
46+
device = torch.device('cuda')
47+
torch.cuda.reset_max_memory_allocated(device)
48+
49+
2550
def handle_execute(class_type, last_node_id, prompt_id, server, unique_id):
2651
if not CURRENT_START_EXECUTION_DATA:
2752
return
2853
start_time = CURRENT_START_EXECUTION_DATA['nodes_start_perf_time'].get(unique_id)
54+
start_vram = CURRENT_START_EXECUTION_DATA['nodes_start_vram'].get(unique_id)
2955
if start_time:
3056
end_time = time.perf_counter()
3157
execution_time = end_time - start_time
58+
59+
end_vram = get_peak_memory()
60+
vram_used = end_vram - start_vram
61+
print(f"end_vram - start_vram: {end_vram} - {start_vram} = {vram_used}")
3262
if server.client_id is not None and last_node_id != server.last_node_id:
3363
server.send_sync(
3464
"TyDev-Utils.ExecutionTime.executed",
35-
{"node": unique_id, "prompt_id": prompt_id, "execution_time": int(execution_time * 1000)},
65+
{"node": unique_id, "prompt_id": prompt_id, "execution_time": int(execution_time * 1000),
66+
"vram_used": vram_used},
3667
server.client_id
3768
)
38-
print(f"#{unique_id} [{class_type}]: {execution_time:.2f}s")
69+
print(f"#{unique_id} [{class_type}]: {execution_time:.2f}s - vram {vram_used}b")
3970

4071

4172
try:
@@ -91,7 +122,8 @@ def swizzle_send_sync(self, event, data, sid=None):
91122
if event == "execution_start":
92123
CURRENT_START_EXECUTION_DATA = dict(
93124
start_perf_time=time.perf_counter(),
94-
nodes_start_perf_time={}
125+
nodes_start_perf_time={},
126+
nodes_start_vram={}
95127
)
96128

97129
origin_func(self, event=event, data=data, sid=sid)
@@ -113,6 +145,8 @@ def swizzle_send_sync(self, event, data, sid=None):
113145
else:
114146
node_id = data.get("node")
115147
CURRENT_START_EXECUTION_DATA['nodes_start_perf_time'][node_id] = time.perf_counter()
148+
reset_peak_memory_record()
149+
CURRENT_START_EXECUTION_DATA['nodes_start_vram'][node_id] = get_peak_memory()
116150

117151

118152
server.PromptServer.send_sync = swizzle_send_sync

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[project]
22
name = "comfyui-dev-utils"
33
description = "Execution Time Analysis, Reroute Enhancement, Node collection for developers."
4-
version = "0.4.3"
4+
version = "0.5.0"
55
license = { text = "MIT License" }
66
dependencies = ["aiohttp-sse"]
77

web/executionTime.js

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,19 @@ function formatExecutionTime(time) {
2727
return `${(time / 1000.0).toFixed(2)}s`
2828
}
2929

30+
// Reference: https://gist.github.com/zentala/1e6f72438796d74531803cc3833c039c
31+
function formatBytes(bytes, decimals) {
32+
if (bytes === 0) {
33+
return '0 B'
34+
}
35+
const k = 1024,
36+
dm = decimals || 2,
37+
sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
38+
i = Math.floor(Math.log(bytes) / Math.log(k));
39+
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
40+
}
41+
42+
3043
// Reference: https://github.com/ltdrdata/ComfyUI-Manager/blob/main/js/comfyui-manager.js
3144
function drawBadge(node, orig, restArgs) {
3245
let ctx = restArgs[0];
@@ -35,7 +48,7 @@ function drawBadge(node, orig, restArgs) {
3548
if (!node.flags.collapsed && node.constructor.title_mode != LiteGraph.NO_TITLE) {
3649
let text = "";
3750
if (node.ty_et_execution_time !== undefined) {
38-
text = formatExecutionTime(node.ty_et_execution_time);
51+
text = formatExecutionTime(node.ty_et_execution_time) + " - vram " + formatBytes(node.ty_et_vram_used, 2);
3952
} else if (node.ty_et_start_time !== undefined) {
4053
text = formatExecutionTime(LiteGraph.getTime() - node.ty_et_start_time);
4154
}
@@ -140,7 +153,8 @@ function buildTableHtml() {
140153
$el("th", {style: headerThStyle, "textContent": "Node Title"}),
141154
$el("th", {style: headerThStyle, "textContent": "Current Time"}),
142155
$el("th", {style: headerThStyle, "textContent": "Per Time"}),
143-
$el("th", {style: headerThStyle, "textContent": "Current / Pre Diff"})
156+
$el("th", {style: headerThStyle, "textContent": "Cur / Pre Time Diff"}),
157+
$el("th", {style: headerThStyle, "textContent": "VRAM Used"})
144158
])
145159
]),
146160
tableBody,
@@ -170,6 +184,9 @@ function buildTableHtml() {
170184
return [diffColor, diffText]
171185
}
172186

187+
let max_execution_time = null
188+
let max_vram_used = null
189+
173190
runningData.nodes_execution_time.forEach(function (item) {
174191
const nodeId = item.node;
175192
const node = app.graph.getNodeById(nodeId)
@@ -178,7 +195,16 @@ function buildTableHtml() {
178195

179196
const [diffColor, diffText] = diff(item.execution_time, preExecutionTime);
180197

198+
if (max_execution_time == null || item.execution_time > max_execution_time) {
199+
max_execution_time = item.execution_time
200+
}
201+
202+
if (max_vram_used == null || item.vram_used > max_vram_used) {
203+
max_vram_used = item.vram_used
204+
}
205+
181206
tableBody.append($el("tr", {
207+
style: {"cursor": "pointer"},
182208
onclick: () => {
183209
if (node) {
184210
app.canvas.selectNode(node, false);
@@ -199,10 +225,36 @@ function buildTableHtml() {
199225
},
200226
"textContent": diffText
201227
}),
228+
$el("td", {style: {"textAlign": "right"}, "textContent": formatBytes(item.vram_used, 2)}),
202229
]))
203230
});
204231
if (runningData.total_execution_time !== null) {
205232
const [diffColor, diffText] = diff(runningData.total_execution_time, lastRunningDate?.total_execution_time);
233+
234+
tableFooter.append($el("tr", [
235+
$el("td", {style: {"textAlign": "right"}, "textContent": 'Max'}),
236+
$el("td", {style: {"textAlign": "right"}, "textContent": ''}),
237+
$el("td", {
238+
style: {"textAlign": "right"},
239+
"textContent": max_execution_time != null ? formatExecutionTime(max_execution_time) : ''
240+
}),
241+
$el("td", {
242+
style: {"textAlign": "right"},
243+
"textContent": ''
244+
}),
245+
$el("td", {
246+
style: {
247+
"textAlign": "right",
248+
"color": diffColor
249+
},
250+
"textContent": ''
251+
}),
252+
$el("td", {
253+
style: {"textAlign": "right"},
254+
"textContent": max_vram_used != null ? formatBytes(max_vram_used, 2) : ''
255+
}),
256+
]))
257+
206258
tableFooter.append($el("tr", [
207259
$el("td", {style: {"textAlign": "right"}, "textContent": 'Total'}),
208260
$el("td", {style: {"textAlign": "right"}, "textContent": ''}),
@@ -221,6 +273,7 @@ function buildTableHtml() {
221273
},
222274
"textContent": diffText
223275
}),
276+
$el("td", {style: {"textAlign": "right"}, "textContent": ""}),
224277
]))
225278
}
226279
return table;
@@ -261,11 +314,13 @@ app.registerExtension({
261314
const node = app.graph.getNodeById(detail.node)
262315
if (node) {
263316
node.ty_et_execution_time = detail.execution_time;
317+
node.ty_et_vram_used = detail.vram_used;
264318
}
265319
const index = runningData.nodes_execution_time.findIndex(x => x.node === detail.node);
266320
const data = {
267321
node: detail.node,
268-
execution_time: detail.execution_time
322+
execution_time: detail.execution_time,
323+
vram_used: detail.vram_used
269324
};
270325
if (index > 0) {
271326
runningData.nodes_execution_time[index] = data
@@ -283,6 +338,7 @@ app.registerExtension({
283338
app.graph._nodes.forEach(function (node) {
284339
delete node.ty_et_start_time
285340
delete node.ty_et_execution_time
341+
delete node.ty_et_vram_used
286342
});
287343
runningData = {
288344
nodes_execution_time: [],
@@ -337,7 +393,7 @@ app.registerExtension({
337393
const thUnscaledHeight = 24;
338394
const tableUnscaledHeight = thUnscaledHeight * tableHeight / thHeight;
339395
const autoResizeMaxHeight = 300;
340-
return [Math.max(originSize[0], 480), originSize[1] + Math.min(tableUnscaledHeight, autoResizeMaxHeight) - LiteGraph.NODE_WIDGET_HEIGHT];
396+
return [Math.max(originSize[0], 600), originSize[1] + Math.min(tableUnscaledHeight, autoResizeMaxHeight) - LiteGraph.NODE_WIDGET_HEIGHT];
341397
}
342398

343399
const nodeCreated = nodeType.prototype.onNodeCreated;

0 commit comments

Comments
 (0)