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="models/text_encoders/Qwen3VL-8B-Uncensored-HauhauCS-Aggressive-Q8_0.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:Q8_0 # Run inference directly in the terminal: llama cli -hf saik0s/comfy_backup:Q8_0
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf saik0s/comfy_backup:Q8_0 # Run inference directly in the terminal: llama cli -hf saik0s/comfy_backup:Q8_0
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:Q8_0 # Run inference directly in the terminal: ./llama-cli -hf saik0s/comfy_backup:Q8_0
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:Q8_0 # Run inference directly in the terminal: ./build/bin/llama-cli -hf saik0s/comfy_backup:Q8_0
Use Docker
docker model run hf.co/saik0s/comfy_backup:Q8_0
- LM Studio
- Jan
- Ollama
How to use saik0s/comfy_backup with Ollama:
ollama run hf.co/saik0s/comfy_backup:Q8_0
- 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:Q8_0
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:Q8_0" } ] } } }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:Q8_0
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:Q8_0
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:Q8_0
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:Q8_0" \ --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:Q8_0
- Lemonade
How to use saik0s/comfy_backup with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull saik0s/comfy_backup:Q8_0
Run and chat with the model
lemonade run user.comfy_backup-Q8_0
List all available models
lemonade list
| import type { | |
| IContextMenuValue, | |
| IFoundSlot, | |
| INodeInputSlot, | |
| INodeOutputSlot, | |
| ISlotType, | |
| LGraphNode, | |
| LLink, | |
| } from "@comfyorg/frontend"; | |
| import type {ComfyNodeDef} from "typings/comfy.js"; | |
| import {app} from "scripts/app.js"; | |
| import { | |
| IoDirection, | |
| followConnectionUntilType, | |
| getConnectedInputInfosAndFilterPassThroughs, | |
| } from "./utils.js"; | |
| import {rgthree} from "./rgthree.js"; | |
| import { | |
| SERVICE as CONTEXT_SERVICE, | |
| InputMutation, | |
| InputMutationOperation, | |
| } from "./services/context_service.js"; | |
| import {NodeTypesString} from "./constants.js"; | |
| import {removeUnusedInputsFromEnd} from "./utils_inputs_outputs.js"; | |
| import {DynamicContextNodeBase} from "./dynamic_context_base.js"; | |
| import {SERVICE as CONFIG_SERVICE} from "./services/config_service.js"; | |
| const OWNED_PREFIX = "+"; | |
| const REGEX_OWNED_PREFIX = /^\+\s*/; | |
| const REGEX_EMPTY_INPUT = /^\+\s*$/; | |
| /** | |
| * The Dynamic Context node. | |
| */ | |
| export class DynamicContextNode extends DynamicContextNodeBase { | |
| static override title = NodeTypesString.DYNAMIC_CONTEXT; | |
| static override type = NodeTypesString.DYNAMIC_CONTEXT; | |
| static comfyClass = NodeTypesString.DYNAMIC_CONTEXT; | |
| constructor(title = DynamicContextNode.title) { | |
| super(title); | |
| } | |
| override onNodeCreated() { | |
| this.addInput("base_ctx", "RGTHREE_DYNAMIC_CONTEXT"); | |
| this.ensureOneRemainingNewInputSlot(); | |
| super.onNodeCreated(); | |
| } | |
| override onConnectionsChange( | |
| type: ISlotType, | |
| slotIndex: number, | |
| isConnected: boolean, | |
| link: LLink | null | undefined, | |
| ioSlot: INodeInputSlot | INodeOutputSlot, | |
| ): void { | |
| super.onConnectionsChange?.call(this, type, slotIndex, isConnected, link, ioSlot); | |
| if (this.configuring) { | |
| return; | |
| } | |
| if (type === LiteGraph.INPUT) { | |
| if (isConnected) { | |
| this.handleInputConnected(slotIndex); | |
| } else { | |
| this.handleInputDisconnected(slotIndex); | |
| } | |
| } | |
| } | |
| override onConnectInput( | |
| inputIndex: number, | |
| outputType: INodeOutputSlot["type"], | |
| outputSlot: INodeOutputSlot, | |
| outputNode: LGraphNode, | |
| outputIndex: number, | |
| ): boolean { | |
| let canConnect = true; | |
| if (super.onConnectInput) { | |
| canConnect = super.onConnectInput.apply(this, [...arguments] as any); | |
| } | |
| if ( | |
| canConnect && | |
| outputNode instanceof DynamicContextNode && | |
| outputIndex === 0 && | |
| inputIndex !== 0 | |
| ) { | |
| const [n, v] = rgthree.logger.warnParts( | |
| "Currently, you can only connect a context node in the first slot.", | |
| ); | |
| console[n]?.call(console, ...v); | |
| canConnect = false; | |
| } | |
| return canConnect; | |
| } | |
| handleInputConnected(slotIndex: number) { | |
| const ioSlot = this.inputs[slotIndex]; | |
| const connectedIndexes = []; | |
| if (slotIndex === 0) { | |
| let baseNodeInfos = getConnectedInputInfosAndFilterPassThroughs(this, this, 0); | |
| const baseNodes = baseNodeInfos.map((n) => n.node)!; | |
| const baseNodesDynamicCtx = baseNodes[0] as DynamicContextNodeBase; | |
| if (baseNodesDynamicCtx?.provideInputsData) { | |
| const inputsData = CONTEXT_SERVICE.getDynamicContextInputsData(baseNodesDynamicCtx); | |
| console.log("inputsData", inputsData); | |
| for (const input of baseNodesDynamicCtx.provideInputsData()) { | |
| if (input.name === "base_ctx" || input.name === "+") { | |
| continue; | |
| } | |
| this.addContextInput(input.name, input.type, input.index); | |
| this.stabilizeNames(); | |
| } | |
| } | |
| } else if (this.isInputSlotForNewInput(slotIndex)) { | |
| this.handleNewInputConnected(slotIndex); | |
| } | |
| } | |
| isInputSlotForNewInput(slotIndex: number) { | |
| const ioSlot = this.inputs[slotIndex]; | |
| return ioSlot && ioSlot.name === "+" && ioSlot.type === "*"; | |
| } | |
| handleNewInputConnected(slotIndex: number) { | |
| if (!this.isInputSlotForNewInput(slotIndex)) { | |
| throw new Error('Expected the incoming slot index to be the "new input" input.'); | |
| } | |
| const ioSlot = this.inputs[slotIndex]!; | |
| let cxn = null; | |
| if (ioSlot.link != null) { | |
| cxn = followConnectionUntilType(this, IoDirection.INPUT, slotIndex, true); | |
| } | |
| if (cxn?.type && cxn?.name) { | |
| let name = this.addOwnedPrefix(this.getNextUniqueNameForThisNode(cxn.name)); | |
| if (name.match(/^\+\s*[A-Z_]+(\.\d+)?$/)) { | |
| name = name.toLowerCase(); | |
| } | |
| ioSlot.name = name; | |
| ioSlot.type = cxn.type as string; | |
| ioSlot.removable = true; | |
| while (!this.outputs[slotIndex]) { | |
| this.addOutput("*", "*"); | |
| } | |
| this.outputs[slotIndex]!.type = cxn.type as string; | |
| this.outputs[slotIndex]!.name = this.stripOwnedPrefix(name).toLocaleUpperCase(); | |
| // This is a dumb override for ComfyUI's widgetinputs issues. | |
| if (cxn.type === "COMBO" || cxn.type.includes(",") || Array.isArray(cxn.type)) { | |
| (this.outputs[slotIndex] as any).widget = true; | |
| } | |
| this.inputsMutated({ | |
| operation: InputMutationOperation.ADDED, | |
| node: this, | |
| slotIndex, | |
| slot: ioSlot, | |
| }); | |
| this.stabilizeNames(); | |
| this.ensureOneRemainingNewInputSlot(); | |
| } | |
| } | |
| handleInputDisconnected(slotIndex: number) { | |
| const inputs = this.getContextInputsList(); | |
| if (slotIndex === 0) { | |
| for (let index = inputs.length - 1; index > 0; index--) { | |
| if (index === 0 || index === inputs.length - 1) { | |
| continue; | |
| } | |
| const input = inputs[index]!; | |
| if (!this.isOwnedInput(input.name)) { | |
| if (input.link || this.outputs[index]?.links?.length) { | |
| this.renameContextInput(index, input.name, true); | |
| } else { | |
| this.removeContextInput(index); | |
| } | |
| } | |
| } | |
| this.setSize(this.computeSize()); | |
| this.setDirtyCanvas(true, true); | |
| } | |
| } | |
| ensureOneRemainingNewInputSlot() { | |
| removeUnusedInputsFromEnd(this, 1, REGEX_EMPTY_INPUT); | |
| this.addInput(OWNED_PREFIX, "*"); | |
| } | |
| getNextUniqueNameForThisNode(desiredName: string) { | |
| const inputs = this.getContextInputsList(); | |
| const allExistingKeys = inputs.map((i) => this.stripOwnedPrefix(i.name).toLocaleUpperCase()); | |
| desiredName = this.stripOwnedPrefix(desiredName); | |
| let newName = desiredName; | |
| let n = 0; | |
| while (allExistingKeys.includes(newName.toLocaleUpperCase())) { | |
| newName = `${desiredName}.${++n}`; | |
| } | |
| return newName; | |
| } | |
| override removeInput(slotIndex: number) { | |
| const slot = this.inputs[slotIndex]!; | |
| super.removeInput(slotIndex); | |
| if (this.outputs[slotIndex]) { | |
| this.removeOutput(slotIndex); | |
| } | |
| this.inputsMutated({operation: InputMutationOperation.REMOVED, node: this, slotIndex, slot}); | |
| this.stabilizeNames(); | |
| } | |
| stabilizeNames() { | |
| const inputs = this.getContextInputsList(); | |
| const names: string[] = []; | |
| for (const [index, input] of inputs.entries()) { | |
| if (index === 0 || index === inputs.length - 1) { | |
| continue; | |
| } | |
| input.label = undefined; | |
| this.outputs[index]!.label = undefined; | |
| let origName = this.stripOwnedPrefix(input.name).replace(/\.\d+$/, ""); | |
| let name = input.name; | |
| if (!this.isOwnedInput(name)) { | |
| names.push(name.toLocaleUpperCase()); | |
| } else { | |
| let n = 0; | |
| name = this.addOwnedPrefix(origName); | |
| while (names.includes(this.stripOwnedPrefix(name).toLocaleUpperCase())) { | |
| name = `${this.addOwnedPrefix(origName)}.${++n}`; | |
| } | |
| names.push(this.stripOwnedPrefix(name).toLocaleUpperCase()); | |
| if (input.name !== name) { | |
| this.renameContextInput(index, name); | |
| } | |
| } | |
| } | |
| } | |
| override getSlotMenuOptions(slot: IFoundSlot): IContextMenuValue[] { | |
| const editable = this.isOwnedInput(slot.input!.name) && this.type !== "*"; | |
| return [ | |
| { | |
| content: "✏️ Rename Input", | |
| disabled: !editable, | |
| callback: () => { | |
| var dialog = app.canvas.createDialog( | |
| "<span class='name'>Name</span><input autofocus type='text'/><button>OK</button>", | |
| {}, | |
| ); | |
| var dialogInput = dialog.querySelector("input")!; | |
| if (dialogInput) { | |
| dialogInput.value = this.stripOwnedPrefix(slot.input!.name || ""); | |
| } | |
| var inner = () => { | |
| this.handleContextMenuRenameInputDialog(slot.slot, dialogInput.value); | |
| dialog.close(); | |
| }; | |
| dialog.querySelector("button")!.addEventListener("click", inner); | |
| dialogInput.addEventListener("keydown", (e) => { | |
| dialog.is_modified = true; | |
| if (e.keyCode == 27) { | |
| dialog.close(); | |
| } else if (e.keyCode == 13) { | |
| inner(); | |
| } else if (e.keyCode != 13 && (e.target as HTMLElement)?.localName != "textarea") { | |
| return; | |
| } | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| }); | |
| dialogInput.focus(); | |
| }, | |
| }, | |
| { | |
| content: "🗑️ Delete Input", | |
| disabled: !editable, | |
| callback: () => { | |
| this.removeInput(slot.slot); | |
| }, | |
| }, | |
| ]; | |
| } | |
| handleContextMenuRenameInputDialog(slotIndex: number, value: string) { | |
| app.graph.beforeChange(); | |
| this.renameContextInput(slotIndex, value); | |
| this.stabilizeNames(); | |
| this.setDirtyCanvas(true, true); | |
| app.graph.afterChange(); | |
| } | |
| } | |
| const contextDynamicNodes = [DynamicContextNode]; | |
| app.registerExtension({ | |
| name: "rgthree.DynamicContext", | |
| async beforeRegisterNodeDef(nodeType: typeof LGraphNode, nodeData: ComfyNodeDef) { | |
| if (!CONFIG_SERVICE.getConfigValue("unreleased.dynamic_context.enabled")) { | |
| return; | |
| } | |
| if (nodeData.name === DynamicContextNode.type) { | |
| DynamicContextNode.setUp(nodeType, nodeData); | |
| } | |
| }, | |
| }); | |