Instructions to use saik0s/comfy_backup with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- llama-cpp-python
How to use saik0s/comfy_backup with llama-cpp-python:
# !pip install llama-cpp-python from llama_cpp import Llama llm = Llama.from_pretrained( repo_id="saik0s/comfy_backup", filename="ComfyUI/models/text_encoders/gemma-3-12b-it-q2_k.gguf", )
llm.create_chat_completion( messages = "No input example has been defined for this model task." )
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use saik0s/comfy_backup with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf saik0s/comfy_backup:Q4_K_S # Run inference directly in the terminal: llama cli -hf saik0s/comfy_backup:Q4_K_S
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf saik0s/comfy_backup:Q4_K_S # Run inference directly in the terminal: llama cli -hf saik0s/comfy_backup:Q4_K_S
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf saik0s/comfy_backup:Q4_K_S # Run inference directly in the terminal: ./llama-cli -hf saik0s/comfy_backup:Q4_K_S
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf saik0s/comfy_backup:Q4_K_S # Run inference directly in the terminal: ./build/bin/llama-cli -hf saik0s/comfy_backup:Q4_K_S
Use Docker
docker model run hf.co/saik0s/comfy_backup:Q4_K_S
- LM Studio
- Jan
- Ollama
How to use saik0s/comfy_backup with Ollama:
ollama run hf.co/saik0s/comfy_backup:Q4_K_S
- Unsloth Studio
How to use saik0s/comfy_backup with Unsloth Studio:
Install Unsloth Studio (macOS, Linux, WSL)
curl -fsSL https://unsloth.ai/install.sh | sh # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for saik0s/comfy_backup to start chatting
Install Unsloth Studio (Windows)
irm https://unsloth.ai/install.ps1 | iex # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for saik0s/comfy_backup to start chatting
Using HuggingFace Spaces for Unsloth
# No setup required # Open https://huggingface.co/spaces/unsloth/studio in your browser # Search for saik0s/comfy_backup to start chatting
- Pi
How to use saik0s/comfy_backup with Pi:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf saik0s/comfy_backup:Q4_K_S
Configure the model in Pi
# Install Pi: npm install -g @mariozechner/pi-coding-agent # Add to ~/.pi/agent/models.json: { "providers": { "llama-cpp": { "baseUrl": "http://localhost:8080/v1", "api": "openai-completions", "apiKey": "none", "models": [ { "id": "saik0s/comfy_backup:Q4_K_S" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Hermes Agent new
How to use saik0s/comfy_backup with Hermes Agent:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf saik0s/comfy_backup:Q4_K_S
Configure Hermes
# Install Hermes: curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash hermes setup # Point Hermes at the local server: hermes config set model.provider custom hermes config set model.base_url http://127.0.0.1:8080/v1 hermes config set model.default saik0s/comfy_backup:Q4_K_S
Run Hermes
hermes
- Atomic Chat new
- OpenClaw new
How to use saik0s/comfy_backup with OpenClaw:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf saik0s/comfy_backup:Q4_K_S
Configure OpenClaw
# Install OpenClaw: npm install -g openclaw@latest # Register the local server and set it as the default model: openclaw onboard --non-interactive --mode local \ --auth-choice custom-api-key \ --custom-base-url http://127.0.0.1:8080/v1 \ --custom-model-id "saik0s/comfy_backup:Q4_K_S" \ --custom-provider-id llama-cpp \ --custom-compatibility openai \ --custom-text-input \ --accept-risk \ --skip-health
Run OpenClaw
openclaw agent --local --agent main --message "Hello from Hugging Face"
- Docker Model Runner
How to use saik0s/comfy_backup with Docker Model Runner:
docker model run hf.co/saik0s/comfy_backup:Q4_K_S
- Lemonade
How to use saik0s/comfy_backup with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull saik0s/comfy_backup:Q4_K_S
Run and chat with the model
lemonade run user.comfy_backup-Q4_K_S
List all available models
lemonade list
| import { app } from "../../../scripts/app.js"; | |
| import { api } from "../../../scripts/api.js"; | |
| import { $el } from "../../../scripts/ui.js"; | |
| // Adds workflow management | |
| // Original implementation by https://github.com/i-h4x | |
| // Thanks for permission to reimplement as an extension | |
| const style = ` | |
| #comfy-save-button, #comfy-load-button { | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .pysssss-workflow-arrow { | |
| position: absolute; | |
| top: 0; | |
| bottom: 0; | |
| right: 0; | |
| font-size: 12px; | |
| display: flex; | |
| align-items: center; | |
| width: 24px; | |
| justify-content: center; | |
| background: rgba(255,255,255,0.1); | |
| } | |
| .pysssss-workflow-arrow:after { | |
| content: "▼"; | |
| } | |
| .pysssss-workflow-arrow:hover { | |
| filter: brightness(1.6); | |
| background-color: var(--comfy-menu-bg); | |
| } | |
| .pysssss-workflow-load .litemenu-entry:not(.has_submenu):before, | |
| .pysssss-workflow-load ~ .litecontextmenu .litemenu-entry:not(.has_submenu):before { | |
| content: "🎛️"; | |
| padding-right: 5px; | |
| } | |
| .pysssss-workflow-load .litemenu-entry.has_submenu:before, | |
| .pysssss-workflow-load ~ .litecontextmenu .litemenu-entry.has_submenu:before { | |
| content: "📂"; | |
| padding-right: 5px; | |
| position: relative; | |
| top: -1px; | |
| } | |
| .pysssss-workflow-popup ~ .litecontextmenu { | |
| transform: scale(1.3); | |
| } | |
| `; | |
| async function getWorkflows() { | |
| const response = await api.fetchApi("/pysssss/workflows", { cache: "no-store" }); | |
| return await response.json(); | |
| } | |
| async function getWorkflow(name) { | |
| const response = await api.fetchApi(`/pysssss/workflows/${encodeURIComponent(name)}`, { cache: "no-store" }); | |
| return await response.json(); | |
| } | |
| async function saveWorkflow(name, workflow, overwrite) { | |
| try { | |
| const response = await api.fetchApi("/pysssss/workflows", { | |
| method: "POST", | |
| headers: { | |
| "Content-Type": "application/json", | |
| }, | |
| body: JSON.stringify({ name, workflow, overwrite }), | |
| }); | |
| if (response.status === 201) { | |
| return true; | |
| } | |
| if (response.status === 409) { | |
| return false; | |
| } | |
| throw new Error(response.statusText); | |
| } catch (error) { | |
| console.error(error); | |
| } | |
| } | |
| class PysssssWorkflows { | |
| async load() { | |
| this.workflows = await getWorkflows(); | |
| if(this.workflows.length) { | |
| this.workflows.sort(); | |
| } | |
| this.loadMenu.style.display = this.workflows.length ? "flex" : "none"; | |
| } | |
| getMenuOptions(callback) { | |
| const menu = []; | |
| const directories = new Map(); | |
| for (const workflow of this.workflows || []) { | |
| const path = workflow.split("/"); | |
| let parent = menu; | |
| let currentPath = ""; | |
| for (let i = 0; i < path.length - 1; i++) { | |
| currentPath += "/" + path[i]; | |
| let newParent = directories.get(currentPath); | |
| if (!newParent) { | |
| newParent = { | |
| title: path[i], | |
| has_submenu: true, | |
| submenu: { | |
| options: [], | |
| }, | |
| }; | |
| parent.push(newParent); | |
| newParent = newParent.submenu.options; | |
| directories.set(currentPath, newParent); | |
| } | |
| parent = newParent; | |
| } | |
| parent.push({ | |
| title: path[path.length - 1], | |
| callback: () => callback(workflow), | |
| }); | |
| } | |
| return menu; | |
| } | |
| constructor() { | |
| function addWorkflowMenu(type, getOptions) { | |
| return $el("div.pysssss-workflow-arrow", { | |
| parent: document.getElementById(`comfy-${type}-button`), | |
| onclick: (e) => { | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| LiteGraph.closeAllContextMenus(); | |
| const menu = new LiteGraph.ContextMenu( | |
| getOptions(), | |
| { | |
| event: e, | |
| scale: 1.3, | |
| }, | |
| window | |
| ); | |
| menu.root.classList.add("pysssss-workflow-popup"); | |
| menu.root.classList.add(`pysssss-workflow-${type}`); | |
| }, | |
| }); | |
| } | |
| this.loadMenu = addWorkflowMenu("load", () => | |
| this.getMenuOptions(async (workflow) => { | |
| const json = await getWorkflow(workflow); | |
| app.loadGraphData(json); | |
| }) | |
| ); | |
| addWorkflowMenu("save", () => { | |
| return [ | |
| { | |
| title: "Save as", | |
| callback: () => { | |
| let filename = prompt("Enter filename", this.workflowName || "workflow"); | |
| if (filename) { | |
| if (!filename.toLowerCase().endsWith(".json")) { | |
| filename += ".json"; | |
| } | |
| this.workflowName = filename; | |
| const json = JSON.stringify(app.graph.serialize(), null, 2); // convert the data to a JSON string | |
| const blob = new Blob([json], { type: "application/json" }); | |
| const url = URL.createObjectURL(blob); | |
| const a = $el("a", { | |
| href: url, | |
| download: filename, | |
| style: { display: "none" }, | |
| parent: document.body, | |
| }); | |
| a.click(); | |
| setTimeout(function () { | |
| a.remove(); | |
| window.URL.revokeObjectURL(url); | |
| }, 0); | |
| } | |
| }, | |
| }, | |
| { | |
| title: "Save to workflows", | |
| callback: async () => { | |
| const name = prompt("Enter filename", this.workflowName || "workflow"); | |
| if (name) { | |
| this.workflowName = name; | |
| const data = app.graph.serialize(); | |
| if (!(await saveWorkflow(name, data))) { | |
| if (confirm("A workspace with this name already exists, do you want to overwrite it?")) { | |
| await saveWorkflow(name, app.graph.serialize(), true); | |
| } else { | |
| return; | |
| } | |
| } | |
| await this.load(); | |
| } | |
| }, | |
| }, | |
| ]; | |
| }); | |
| this.load(); | |
| const handleFile = app.handleFile; | |
| const self = this; | |
| app.handleFile = function (file) { | |
| if (file?.name?.endsWith(".json")) { | |
| self.workflowName = file.name; | |
| } else { | |
| self.workflowName = null; | |
| } | |
| return handleFile.apply(this, arguments); | |
| }; | |
| } | |
| } | |
| const refreshComboInNodes = app.refreshComboInNodes; | |
| let workflows; | |
| async function sendToWorkflow(img, workflow) { | |
| const graph = !workflow ? app.graph.serialize() : await getWorkflow(workflow); | |
| const nodes = graph.nodes.filter((n) => n.type === "LoadImage"); | |
| let targetNode; | |
| if (nodes.length === 0) { | |
| alert("To send the image to another workflow, that workflow must have a LoadImage node."); | |
| return; | |
| } else if (nodes.length > 1) { | |
| targetNode = nodes.find((n) => n.title?.toLowerCase().includes("input")); | |
| if (!targetNode) { | |
| targetNode = nodes[0]; | |
| alert( | |
| "The target workflow has multiple LoadImage nodes, include 'input' in the name of the one you want to use. The first one will be used here." | |
| ); | |
| } | |
| } else { | |
| targetNode = nodes[0]; | |
| } | |
| const blob = await (await fetch(img.src)).blob(); | |
| const name = | |
| (workflow || "sendtoworkflow").replace(/\//g, "_") + | |
| "-" + | |
| +new Date() + | |
| new URLSearchParams(img.src.split("?")[1]).get("filename"); | |
| const body = new FormData(); | |
| body.append("image", new File([blob], name)); | |
| const resp = await api.fetchApi("/upload/image", { | |
| method: "POST", | |
| body, | |
| }); | |
| if (resp.status === 200) { | |
| await refreshComboInNodes.call(app); | |
| targetNode.widgets_values[0] = name; | |
| app.loadGraphData(graph); | |
| app.graph.getNodeById(targetNode.id); | |
| } else { | |
| alert(resp.status + " - " + resp.statusText); | |
| } | |
| } | |
| app.registerExtension({ | |
| name: "pysssss.Workflows", | |
| init() { | |
| $el("style", { | |
| textContent: style, | |
| parent: document.head, | |
| }); | |
| }, | |
| async refreshComboInNodes() { | |
| workflows.load() | |
| }, | |
| async setup() { | |
| workflows = new PysssssWorkflows(); | |
| const comfyDefault = "[ComfyUI Default]"; | |
| const defaultWorkflow = app.ui.settings.addSetting({ | |
| id: "pysssss.Workflows.Default", | |
| name: "🐍 Default Workflow", | |
| defaultValue: comfyDefault, | |
| type: "combo", | |
| options: (value) => | |
| [comfyDefault, ...workflows.workflows].map((m) => ({ | |
| value: m, | |
| text: m, | |
| selected: m === value, | |
| })), | |
| }); | |
| document.getElementById("comfy-load-default-button").onclick = async function () { | |
| if ( | |
| localStorage["Comfy.Settings.Comfy.ConfirmClear"] === "false" || | |
| confirm(`Load default workflow (${defaultWorkflow.value})?`) | |
| ) { | |
| if (defaultWorkflow.value === comfyDefault) { | |
| app.loadGraphData(); | |
| } else { | |
| const json = await getWorkflow(defaultWorkflow.value); | |
| app.loadGraphData(json); | |
| } | |
| } | |
| }; | |
| }, | |
| async beforeRegisterNodeDef(nodeType, nodeData, app) { | |
| const getExtraMenuOptions = nodeType.prototype.getExtraMenuOptions; | |
| nodeType.prototype.getExtraMenuOptions = function (_, options) { | |
| const r = getExtraMenuOptions?.apply?.(this, arguments); | |
| let img; | |
| if (this.imageIndex != null) { | |
| // An image is selected so select that | |
| img = this.imgs[this.imageIndex]; | |
| } else if (this.overIndex != null) { | |
| // No image is selected but one is hovered | |
| img = this.imgs[this.overIndex]; | |
| } | |
| if (img) { | |
| let pos = options.findIndex((o) => o.content === "Save Image"); | |
| if (pos === -1) { | |
| pos = 0; | |
| } else { | |
| pos++; | |
| } | |
| options.splice(pos, 0, { | |
| content: "Send to workflow", | |
| has_submenu: true, | |
| submenu: { | |
| options: [ | |
| { callback: () => sendToWorkflow(img), title: "[Current workflow]" }, | |
| ...workflows.getMenuOptions(sendToWorkflow.bind(null, img)), | |
| ], | |
| }, | |
| }); | |
| } | |
| return r; | |
| }; | |
| }, | |
| }); | |