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
| /** | |
| * Various dom manipulation utils that have followed me around. | |
| */ | |
| const DIRECT_ATTRIBUTE_MAP: {[name: string]: string} = { | |
| cellpadding: "cellPadding", | |
| cellspacing: "cellSpacing", | |
| colspan: "colSpan", | |
| frameborder: "frameBorder", | |
| height: "height", | |
| maxlength: "maxLength", | |
| nonce: "nonce", | |
| role: "role", | |
| rowspan: "rowSpan", | |
| type: "type", | |
| usemap: "useMap", | |
| valign: "vAlign", | |
| width: "width", | |
| }; | |
| const RGX_NUMERIC_STYLE_UNIT = "px"; | |
| const RGX_NUMERIC_STYLE = | |
| /^((max|min)?(width|height)|margin|padding|(margin|padding)?(left|top|bottom|right)|fontsize|borderwidth)$/i; | |
| const RGX_DEFAULT_VALUE_PROP = /input|textarea|select/i; | |
| function localAssertNotFalsy<T>(input?: T | null, errorMsg = `Input is not of type.`): T { | |
| if (input == null) { | |
| throw new Error(errorMsg); | |
| } | |
| return input; | |
| } | |
| const RGX_STRING_VALID = "[a-z0-9_-]"; | |
| const RGX_TAG = new RegExp(`^([a-z]${RGX_STRING_VALID}*)(\\.|\\[|\\#|$)`, "i"); | |
| const RGX_ATTR_ID = new RegExp(`#(${RGX_STRING_VALID}+)`, "gi"); | |
| const RGX_ATTR_CLASS = new RegExp(`(^|\\S)\\.([a-z0-9_\\-\\.]+)`, "gi"); | |
| const RGX_STRING_CONTENT_TO_SQUARES = "(.*?)(\\[|\\])"; | |
| const RGX_ATTRS_MAYBE_OPEN = new RegExp(`\\[${RGX_STRING_CONTENT_TO_SQUARES}`, "gi"); | |
| const RGX_ATTRS_FOLLOW_OPEN = new RegExp(`^${RGX_STRING_CONTENT_TO_SQUARES}`, "gi"); | |
| type QueryParent = HTMLElement | Document | DocumentFragment; | |
| export function queryAll<K extends keyof HTMLElementTagNameMap>( | |
| selectors: K, | |
| parent?: QueryParent, | |
| ): Array<HTMLElementTagNameMap[K]>; | |
| export function queryAll<K extends keyof SVGElementTagNameMap>( | |
| selectors: K, | |
| parent?: QueryParent, | |
| ): Array<SVGElementTagNameMap[K]>; | |
| export function queryAll<K extends keyof MathMLElementTagNameMap>( | |
| selectors: K, | |
| parent?: QueryParent, | |
| ): Array<MathMLElementTagNameMap[K]>; | |
| export function queryAll<T extends HTMLElement>(selectors: string, parent?: QueryParent): Array<T>; | |
| export function queryAll(selectors: string, parent: QueryParent = document) { | |
| return Array.from(parent.querySelectorAll(selectors)).filter((n) => !!n); | |
| } | |
| export function query<K extends keyof HTMLElementTagNameMap>( | |
| selectors: K, | |
| parent?: QueryParent, | |
| ): HTMLElementTagNameMap[K] | null; | |
| export function query<K extends keyof SVGElementTagNameMap>( | |
| selectors: K, | |
| parent?: QueryParent, | |
| ): SVGElementTagNameMap[K] | null; | |
| export function query<K extends keyof MathMLElementTagNameMap>( | |
| selectors: K, | |
| parent?: QueryParent, | |
| ): MathMLElementTagNameMap[K] | null; | |
| export function query<T extends HTMLElement>(selectors: string, parent?: QueryParent): T | null; | |
| export function query(selectors: string, parent: QueryParent = document) { | |
| return parent.querySelector(selectors) ?? null; | |
| } | |
| export function createText(text: string) { | |
| return document.createTextNode(text); | |
| } | |
| export function getClosestOrSelf( | |
| element: EventTarget | HTMLElement | null, | |
| query: string, | |
| ): HTMLElement | null { | |
| const el = element as HTMLElement; | |
| return (el?.closest && (((el.matches(query) && el) || el.closest(query)) as HTMLElement)) || null; | |
| } | |
| export function containsOrSelf( | |
| parent: EventTarget | HTMLElement | null, | |
| contained: EventTarget | HTMLElement | null, | |
| ): boolean { | |
| return ( | |
| parent === contained || (parent as HTMLElement)?.contains?.(contained as HTMLElement) || false | |
| ); | |
| } | |
| type Attrs = { | |
| [name: string]: any; | |
| }; | |
| export function createElement<T extends HTMLElement>(selectorOrMarkup: string, attrs?: Attrs) { | |
| const frag = getHtmlFragment(selectorOrMarkup); | |
| let element = frag?.firstElementChild as HTMLElement; | |
| let selector = ""; | |
| if (!element) { | |
| selector = selectorOrMarkup.replace(/[\r\n]\s*/g, ""); | |
| const tag = getSelectorTag(selector) || "div"; | |
| element = document.createElement(tag); | |
| selector = selector.replace(RGX_TAG, "$2"); | |
| const brackets = selector.match(/(\[[^\]]+\])/g) || []; | |
| for (const bracket of brackets) { | |
| selector = selector.replace(bracket, ""); | |
| } | |
| // Turn id and classname into [attr]s that can be nested | |
| selector = selector.replace(RGX_ATTR_ID, '[id="$1"]'); | |
| selector = selector.replace( | |
| RGX_ATTR_CLASS, | |
| (match, p1, p2) => `${p1}[class="${p2.replace(/\./g, " ")}"]`, | |
| ); | |
| selector += brackets.join(""); | |
| } | |
| const selectorAttrs = getSelectorAttributes(selector); | |
| if (selectorAttrs) { | |
| for (const attr of selectorAttrs) { | |
| let matches = attr.substring(1, attr.length - 1).split("="); | |
| let key = localAssertNotFalsy(matches.shift()); | |
| let value: string = matches.join("="); | |
| if (value === undefined) { | |
| setAttribute(element, key, true); | |
| } else { | |
| value = value.replace(/^['"](.*)['"]$/, "$1"); | |
| setAttribute(element, key, value); | |
| } | |
| } | |
| } | |
| if (attrs) { | |
| setAttributes(element, attrs); | |
| } | |
| return element as T; | |
| } | |
| export const $el = createElement; | |
| function getSelectorTag(str: string) { | |
| return tryMatch(str, RGX_TAG); | |
| } | |
| function getSelectorAttributes(selector: string) { | |
| RGX_ATTRS_MAYBE_OPEN.lastIndex = 0; | |
| let attrs: string[] = []; | |
| let result; | |
| while ((result = RGX_ATTRS_MAYBE_OPEN.exec(selector))) { | |
| let attr = result[0]; | |
| if (attr.endsWith("]")) { | |
| attrs.push(attr); | |
| } else { | |
| attr = | |
| result[0] + getOpenAttributesRecursive(selector.substr(RGX_ATTRS_MAYBE_OPEN.lastIndex), 2); | |
| RGX_ATTRS_MAYBE_OPEN.lastIndex += attr.length - result[0].length; | |
| attrs.push(attr); | |
| } | |
| } | |
| return attrs; | |
| } | |
| function getOpenAttributesRecursive(selectorSubstring: string, openCount: number) { | |
| let matches = selectorSubstring.match(RGX_ATTRS_FOLLOW_OPEN); | |
| let result = ""; | |
| if (matches && matches.length) { | |
| result = matches[0]; | |
| openCount += result.endsWith("]") ? -1 : 1; | |
| if (openCount > 0) { | |
| result += getOpenAttributesRecursive(selectorSubstring.substr(result.length), openCount); | |
| } | |
| } | |
| return result; | |
| } | |
| function tryMatch(str: string, rgx: RegExp, index = 1) { | |
| let found = ""; | |
| try { | |
| found = str.match(rgx)?.[index] || ""; | |
| } catch (e) { | |
| found = ""; | |
| } | |
| return found; | |
| } | |
| export function setAttributes(element: HTMLElement, data: {[name: string]: any}) { | |
| let attr; | |
| for (attr in data) { | |
| if (data.hasOwnProperty(attr)) { | |
| setAttribute(element, attr, data[attr]); | |
| } | |
| } | |
| } | |
| function getHtmlFragment(value: string) { | |
| if (value.match(/^\s*<.*?>[\s\S]*<\/[a-z0-9]+>\s*$/)) { | |
| return document.createRange().createContextualFragment(value.trim()); | |
| } | |
| return null; | |
| } | |
| function getChild(value: any): HTMLElement | DocumentFragment | Text | null { | |
| if (value instanceof Node) { | |
| return value as HTMLElement; | |
| } | |
| if (typeof value === "string") { | |
| let child = getHtmlFragment(value); | |
| if (child) { | |
| return child; | |
| } | |
| if (getSelectorTag(value)) { | |
| return createElement(value); | |
| } | |
| return createText(value); | |
| } | |
| if (value && typeof value.toElement === "function") { | |
| return value.toElement() as HTMLElement; | |
| } | |
| return null; | |
| } | |
| export function setAttribute(element: HTMLElement, attribute: string, value: any) { | |
| let isRemoving = value == null; | |
| if (attribute === "default") { | |
| attribute = RGX_DEFAULT_VALUE_PROP.test(element.nodeName) ? "value" : "text"; | |
| } | |
| if (attribute === "text") { | |
| empty(element).appendChild(createText(value != null ? String(value) : "")); | |
| } else if (attribute === "html") { | |
| empty(element).innerHTML += value != null ? String(value) : ""; | |
| } else if (attribute == "style") { | |
| if (typeof value === "string") { | |
| element.style.cssText = isRemoving ? "" : value != null ? String(value) : ""; | |
| } else { | |
| for (const [styleKey, styleValue] of Object.entries(value as {[key: string]: any})) { | |
| element.style[styleKey as "display"] = styleValue; | |
| } | |
| } | |
| } else if (attribute == "events") { | |
| for (const [key, fn] of Object.entries(value as {[key: string]: (e: Event) => void})) { | |
| addEvent(element, key, fn); | |
| } | |
| } else if (attribute === "parent") { | |
| value.appendChild(element); | |
| } else if (attribute === "child" || attribute === "children") { | |
| // Try to handle an array, like [li,li,li]. Not nested brackets, though | |
| if (typeof value === "string" && /^\[[^\[\]]+\]$/.test(value)) { | |
| const parseable = value.replace(/^\[([^\[\]]+)\]$/, '["$1"]').replace(/,/g, '","'); | |
| try { | |
| const parsed = JSON.parse(parseable); | |
| value = parsed; | |
| } catch (e) { | |
| console.error(e); | |
| } | |
| } | |
| // "children" is a replace of the children, while "child" appends a new child if others exist. | |
| if (attribute === "children") { | |
| empty(element); | |
| } | |
| let children = value instanceof Array ? value : [value]; | |
| for (let child of children) { | |
| child = getChild(child); | |
| if (child instanceof Node) { | |
| if (element instanceof HTMLTemplateElement) { | |
| element.content.appendChild(child); | |
| } else { | |
| element.appendChild(child); | |
| } | |
| } | |
| } | |
| } else if (attribute == "for") { | |
| (element as HTMLLabelElement).htmlFor = value != null ? String(value) : ""; | |
| if (isRemoving) { | |
| // delete (element as HTMLLabelElement).htmlFor; | |
| element.removeAttribute("for"); | |
| } | |
| } else if (attribute === "class" || attribute === "className" || attribute === "classes") { | |
| element.className = isRemoving ? "" : Array.isArray(value) ? value.join(" ") : String(value); | |
| } else if (attribute === "dataset") { | |
| if (typeof value !== "object") { | |
| console.error("Expecting an object for dataset"); | |
| return; | |
| } | |
| for (const [key, val] of Object.entries(value)) { | |
| element.dataset[key] = String(val); | |
| } | |
| } else if (attribute.startsWith("on") && typeof value === "function") { | |
| element.addEventListener(attribute.substring(2), value); | |
| } else if (["checked", "disabled", "readonly", "required", "selected"].includes(attribute)) { | |
| // Could be input, button, etc. We are not discriminate. | |
| (element as HTMLInputElement)[attribute as "checked"] = !!value; | |
| if (!value) { | |
| (element as HTMLInputElement).removeAttribute(attribute); | |
| } else { | |
| (element as HTMLInputElement).setAttribute(attribute, attribute); | |
| } | |
| } else if (DIRECT_ATTRIBUTE_MAP.hasOwnProperty(attribute)) { | |
| if (isRemoving) { | |
| element.removeAttribute(DIRECT_ATTRIBUTE_MAP[attribute]!); | |
| } else { | |
| element.setAttribute(DIRECT_ATTRIBUTE_MAP[attribute]!, String(value)); | |
| } | |
| } else if (isRemoving) { | |
| element.removeAttribute(attribute); | |
| } else { | |
| let oldVal = element.getAttribute(attribute); | |
| if (oldVal !== value) { | |
| element.setAttribute(attribute, String(value)); | |
| } | |
| } | |
| } | |
| function addEvent(element: HTMLElement, key: string, fn: (e: Event) => void) { | |
| element.addEventListener(key, fn); | |
| } | |
| function setStyles(element: HTMLElement, styles: {[name: string]: string | number} | null = null) { | |
| if (styles) { | |
| for (let name in styles) { | |
| setStyle(element, name, styles[name]!); | |
| } | |
| } | |
| return element; | |
| } | |
| export function setStyle(element: HTMLElement, name: string, value: string | number | null) { | |
| // Note: Old IE uses 'styleFloat' | |
| name = name.indexOf("float") > -1 ? "cssFloat" : name; | |
| // Camelcase | |
| if (name.indexOf("-") != -1) { | |
| name = name.replace(/-\D/g, (match) => { | |
| return match.charAt(1).toUpperCase(); | |
| }); | |
| } | |
| if (value == String(Number(value)) && RGX_NUMERIC_STYLE.test(name)) { | |
| value = value + RGX_NUMERIC_STYLE_UNIT; | |
| } | |
| if (name === "display" && typeof value !== "string") { | |
| value = !!value ? null : "none"; | |
| } | |
| (element.style as any)[name] = value === null ? null : String(value); | |
| return element; | |
| } | |
| export function empty(element: HTMLElement) { | |
| while (element.firstChild) { | |
| element.removeChild(element.firstChild); | |
| } | |
| return element; | |
| } | |
| export function remove(element: HTMLElement) { | |
| while (element.parentElement) { | |
| element.parentElement.removeChild(element); | |
| } | |
| return element; | |
| } | |
| export function replaceChild(oldChildNode: Node, newNode: Node) { | |
| oldChildNode.parentNode!.replaceChild(newNode, oldChildNode); | |
| return newNode; | |
| } | |
| type ChildType = HTMLElement | DocumentFragment | Text | string | null; | |
| export function appendChildren(el: HTMLElement, children: ChildType | ChildType[]) { | |
| children = !Array.isArray(children) ? [children] : children; | |
| for (let child of children) { | |
| child = getChild(child); | |
| if (child instanceof Node) { | |
| if (el instanceof HTMLTemplateElement) { | |
| el.content.appendChild(child); | |
| } else { | |
| el.appendChild(child); | |
| } | |
| } | |
| } | |
| } | |
| /** | |
| * Returns elements and their actions. | |
| * | |
| * data-action="click:action-signal" | |
| */ | |
| export function getActionEls(parent: Element | Document = document) { | |
| const els = Array.from(parent.querySelectorAll("[data-action],[on-action],[on]")); | |
| if (parent instanceof Element) { | |
| els.unshift(parent); | |
| } | |
| return els | |
| .map((actionEl) => { | |
| const actions: {[action: string]: string} = {}; | |
| const actionSegments = ( | |
| actionEl.getAttribute("data-action") || | |
| actionEl.getAttribute("on-action") || | |
| actionEl.getAttribute("on") || | |
| "" | |
| ).split(";"); | |
| for (let segment of actionSegments) { | |
| let actionsData = segment | |
| .trim() | |
| .split(/\s*:\s*/g) | |
| .filter((i) => !!i.trim()) as [string, string?]; | |
| if (!actionsData.length) continue; | |
| if (actionsData.length === 1) { | |
| if (actionEl instanceof HTMLInputElement) { | |
| actionsData.unshift("input"); | |
| } else { | |
| actionsData.unshift("click"); | |
| } | |
| } | |
| if (actionsData[0] && actionsData[1]) { | |
| actions[actionsData[0]] = actionsData[1]; | |
| // actionEl.addEventListener(actionsData[0], (e) => {this.handleAction(actionsData[1]!, actionEl, e);}); | |
| } | |
| } | |
| return { | |
| el: actionEl, | |
| actions, | |
| }; | |
| }) | |
| .filter((el) => !!el); | |
| } | |