Files
pollockjj-ComfyUI-MultiGPU/memory-bank/code-references.md
T

147 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Code References (Definitive): ComfyUI Manager “Free model and node cache”
Purpose
- Provide an end-to-end, fully verified lineage of the ComfyUI Manager “Free model and node cache” button through to the exact consumption of flags in ComfyUI core, with exact file paths and code excerpts captured from the current snapshot in this workspace.
End‑to‑End Flow (Current Snapshot)
1) UI Button (Manager) → 2) JS helper free_models(...) → 3) POST /free (Comfy core) → 4) main.py prompt_worker thread polls flags and performs:
- unload_models: comfy.model_management.unload_all_models()
- free_memory: PromptExecutor.reset()
- Additionally triggers GC and comfy.model_management.soft_empty_cache()
A) Frontend UI trigger (ComfyUI Manager)
- File: ../ComfyUI-Manager/js/comfyui-manager.js
- Location: app.registerExtension({ name: "Comfy.ManagerMenu", ... }) → setup() → ComfyButtonGroup
```js
new(await import("../../scripts/ui/components/button.js")).ComfyButton({
icon: "vacuum-outline",
action: () => {
free_models();
},
tooltip: "Unload Models"
}).element,
new(await import("../../scripts/ui/components/button.js")).ComfyButton({
icon: "vacuum",
action: () => {
free_models(true);
},
tooltip: "Free model and node cache"
}).element,
```
Semantics:
- “Unload Models” → free_models() (models only)
- “Free model and node cache” → free_models(true) (models + execution cache)
B) Frontend request construction (ComfyUI Manager)
- File: ../ComfyUI-Manager/js/common.js
- Function: export async function free_models(free_execution_cache)
```js
export async function free_models(free_execution_cache) {
try {
let mode = "";
if (free_execution_cache) {
mode = '{"unload_models": true, "free_memory": true}';
} else {
mode = '{"unload_models": true}';
}
console.log(`[ManagerFreePath] POST /free payload: ${mode}`);
let res = await api.fetchApi(`/free`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: mode
});
console.log(`[ManagerFreePath] /free status: ${res.status}`);
if (res.status == 200) {
if (free_execution_cache) {
showToast("'Models' and 'Execution Cache' have been cleared.", 3000);
} else {
showToast("Models' have been unloaded.", 3000);
}
} else {
showToast('Unloading of models failed. Installed ComfyUI may be an outdated version.', 5000);
}
} catch (error) {
console.error('[ManagerFreePath] /free error:', error);
showToast('An error occurred while trying to unload models.', 5000);
}
}
```
Semantics:
- free_models(true) → POST /free with {"unload_models": true, "free_memory": true}
- free_models() → POST /free with {"unload_models": true}
C) Core server endpoint (flags are set on the queue)
- File: ../../server.py
- Route: @routes.post("/free")
```py
@routes.post("/free")
async def post_free(request):
json_data = await request.json()
unload_models = json_data.get("unload_models", False)
free_memory = json_data.get("free_memory", False)
if unload_models:
self.prompt_queue.set_flag("unload_models", unload_models)
if free_memory:
self.prompt_queue.set_flag("free_memory", free_memory)
return web.Response(status=200)
```
Semantics:
- The HTTP endpoint itself does not unload/reset; instead it sets flags on PromptServer.prompt_queue for the background worker to consume.
D) Flag consumption and execution (definitive mechanism)
- File: ../../main.py
- Function: prompt_worker(q, server_instance)
- Excerpt (poll and handle flags, then clean up):
```py
flags = q.get_flags()
free_memory = flags.get("free_memory", False)
if flags.get("unload_models", free_memory):
comfy.model_management.unload_all_models()
need_gc = True
last_gc_collect = 0
if free_memory:
e.reset()
need_gc = True
last_gc_collect = 0
if need_gc:
current_time = time.perf_counter()
if (current_time - last_gc_collect) > gc_collect_interval:
gc.collect()
comfy.model_management.soft_empty_cache()
last_gc_collect = current_time
need_gc = False
hook_breaker_ac10a0.restore_functions()
```
Context:
- e is a PromptExecutor (created earlier in prompt_worker): `e = execution.PromptExecutor(server_instance, ...)`
- The worker thread is started in start_comfyui():
```py
threading.Thread(target=prompt_worker, daemon=True, args=(prompt_server.prompt_queue, prompt_server,)).start()
```
Interpretation (What the Manager button actually does)
- “Free model and node cache” sets unload_models: true and free_memory: true via POST /free.
- The background prompt_worker then:
- Calls comfy.model_management.unload_all_models()
- Calls e.reset() on the PromptExecutor to drop execution caches
- Performs gc.collect() and comfy.model_management.soft_empty_cache()
- This matches the “benchmark button” behavior required for CPU memory reclamation (models fully unloaded + executor reset + allocator/cache cleanup).
Implications for MultiGPU P1 (force_full_system_cleanup)
- To 100% replicate the benchmark button behavior from within MultiGPU code paths:
- Call comfy.model_management.unload_all_models()
- Trigger PromptExecutor.reset() on the active executor
- Follow up with gc.collect() and comfy.model_management.soft_empty_cache()
- Or, trigger the core behavior indirectly by POST /free with both flags set, relying on ComfyUI’s running prompt worker.
Verification Status
- All file paths and snippets above were extracted from this workspace:
- Manager JS files under ../ComfyUI-Manager/js/
- ComfyUI server and main under ../../server.py and ../../main.py
- Consumption site conclusively identified in ../../main.py prompt_worker via q.get_flags → unload_all_models + PromptExecutor.reset