Instructions to use Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF 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 Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF # Run inference directly in the terminal: llama cli -hf Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF # Run inference directly in the terminal: llama cli -hf Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF
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 Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF # Run inference directly in the terminal: ./llama-cli -hf Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF
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 Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF # Run inference directly in the terminal: ./build/bin/llama-cli -hf Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF
Use Docker
docker model run hf.co/Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF
- LM Studio
- Jan
- vLLM
How to use Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF
- Ollama
How to use Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF with Ollama:
ollama run hf.co/Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF
- Unsloth Desktop
- Pi
How to use Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF with Pi:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF
Configure the model in Pi
# Install Pi: npm install -g @earendil-works/pi-coding-agent # Add to ~/.pi/agent/models.json: { "providers": { "llama-cpp": { "baseUrl": "http://localhost:8080/v1", "api": "openai-completions", "apiKey": "none", "models": [ { "id": "Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Docker Model Runner
How to use Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF with Docker Model Runner:
docker model run hf.co/Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF
- Lemonade
How to use Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF
Run and chat with the model
lemonade run user.Qwen3.8-27B-5090-goldilocks-GGUF-{{QUANT_TAG}}List all available models
lemonade list
- Hermes Agent
How to use Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF with Hermes Agent:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF
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 Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF
Run Hermes
hermes
- Atomic Chat
- OpenClaw
How to use Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF with OpenClaw:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF
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 "Rabbit-Hole-Ai/Qwen3.8-27B-5090-goldilocks-GGUF" \ --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"
| #!/usr/bin/env python3 | |
| """ | |
| build_recipe.py — size-solve a thireus-style per-tensor quant recipe for | |
| Qwen3.8-27B against a hard VRAM weight budget. | |
| WHY THIS EXISTS | |
| --------------- | |
| The thireus q6_0-7bpw map for Qwen3.6-27B is a flat list of anchored regexes | |
| with hardcoded layer indices. Qwen3.8-27B has the SAME tensor shape (WATCH | |
| gate G3: 866 tensors, blk.0-63 + blk.64 MTP), so the map transfers verbatim | |
| — but "verbatim" is exactly the assumption that fails silently: a | |
| --tensor-type pattern that matches nothing is NOT an error. So this script | |
| does two jobs: | |
| 1. GATE: verify every regex in the inherited map matches exactly one real | |
| tensor in the converted GGUF, and that every weight tensor is covered. | |
| Refuses to emit a recipe if not. | |
| 2. SOLVE: the inherited map lands ~22,887 MiB (the ThinkingCap reference). | |
| We measured a larger budget than that on this rig, so spend the | |
| headroom by promoting Q6_K -> Q8_0 in a principled order until the | |
| budget is hit. This is the "Goldilocks" step. | |
| PROMOTION ORDER (and why) | |
| ------------------------- | |
| We do NOT have a fresh per-tensor sensitivity ranking for 3.8 (that needs | |
| benchmark_each_tensor.sh, hours of GPU). So the order below is derived from | |
| the structure of the inherited map itself, which already encodes thireus' | |
| sensitivity findings for this architecture: | |
| Groups the map protects COMPLETELY at Q8_0 (attn_k/v/output, ssm_alpha, | |
| ssm_beta, nextn.eh_proj) are already maxed - nothing to promote. | |
| Groups the map protects PARTIALLY are, by construction, the ones sitting | |
| right at the sensitivity boundary - thireus spent bits on some layers of | |
| these and not others. Completing them is the highest-confidence use of | |
| headroom, so they go first, most-protected group first: | |
| ssm_out (43/48 already q8_0 -> finish the last 5) | |
| attn_gate (30/48 already q8_0 -> finish 18) | |
| attn_q ( 2/17 already q8_0 -> finish 15) | |
| attn_qkv ( 4/48 already q8_0 -> finish 44) | |
| Then the FFN bulk, ffn_down first (the map itself favours it: 9 layers at | |
| q8_0 vs 6 for ffn_gate and 5 for ffn_up - same ordering llama.cpp's own | |
| quant heuristics use): | |
| ffn_down -> ffn_gate -> ffn_up | |
| Within a group we promote LOW layer index first: early layers are the | |
| conventional sensitivity hot spot and the map's own q8_0 picks cluster there. | |
| OUTPUT | |
| ------ | |
| A --tensor-type argument file for llama-quantize, plus a printed size | |
| report. Nothing is quantized here. | |
| """ | |
| import argparse | |
| import re | |
| import sys | |
| from pathlib import Path | |
| sys.path.insert(0, r"C:\path\to\llama.cpp\gguf-py") # point at your llama.cpp checkout | |
| from gguf import GGUFReader # noqa: E402 | |
| # bytes per element, by ggml type name | |
| BPE = { | |
| "F32": 4.0, | |
| "F16": 2.0, | |
| "BF16": 2.0, | |
| "Q8_0": 34.0 / 32.0, # 32 vals -> 2B scale + 32B data | |
| "Q6_K": 210.0 / 256.0, | |
| "Q5_K": 176.0 / 256.0, | |
| "Q4_K": 144.0 / 256.0, | |
| } | |
| # group -> promotion priority (lower = promoted sooner). See docstring. | |
| PROMOTION_ORDER = [ | |
| "ssm_out", | |
| "attn_gate", | |
| "attn_q", | |
| "attn_qkv", | |
| "ffn_down", | |
| "ffn_gate", | |
| "ffn_up", | |
| ] | |
| MIB = 1024.0 * 1024.0 | |
| def stem_of(name: str) -> str: | |
| """blk.12.ffn_down.weight -> ffn_down""" | |
| m = re.match(r"^blk\.(\d+)\.(.+)\.weight$", name) | |
| return m.group(2) if m else name | |
| def layer_of(name: str) -> int: | |
| m = re.match(r"^blk\.(\d+)\.", name) | |
| return int(m.group(1)) if m else -1 | |
| def main() -> int: | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--gguf", required=True, help="converted BF16 GGUF") | |
| ap.add_argument("--map", required=True, help="inherited tensortypes.txt") | |
| ap.add_argument("--budget-mib", type=float, required=True, | |
| help="hard ceiling for the quantized file, MiB") | |
| ap.add_argument("--out", required=True, help="tensor-type args file to write") | |
| args = ap.parse_args() | |
| print(f"reading {args.gguf} ...", flush=True) | |
| r = GGUFReader(args.gguf) | |
| tensors = {t.name: t for t in r.tensors} | |
| print(f" {len(tensors)} tensors") | |
| # ---- load inherited map ---- | |
| assign: dict[str, str] = {} | |
| unmatched: list[str] = [] | |
| for line in Path(args.map).read_text(encoding="utf-8").splitlines(): | |
| line = line.strip() | |
| if not line or line.startswith("#"): | |
| continue | |
| pat, _, ty = line.partition("=") | |
| # ^blk.0.ffn_down.weight$ -> literal name | |
| name = pat.strip().lstrip("^").rstrip("$").replace("\\.", ".") | |
| if name in tensors: | |
| assign[name] = ty.strip().upper() | |
| else: | |
| unmatched.append(name) | |
| # ---- GATE 1: every map entry must hit a real tensor ---- | |
| if unmatched: | |
| print(f"\nFATAL: {len(unmatched)} map entries match NO tensor in this GGUF.") | |
| print("This is the silent-failure mode - refusing to emit a recipe.") | |
| for n in unmatched[:15]: | |
| print(" ", n) | |
| return 2 | |
| # ---- GATE 2: report coverage of weight tensors ---- | |
| quantizable = { | |
| n: t for n, t in tensors.items() | |
| if len(t.shape) >= 2 and n.endswith(".weight") | |
| } | |
| uncovered = sorted(set(quantizable) - set(assign)) | |
| print(f" map covers {len(assign)}/{len(quantizable)} 2-D weight tensors") | |
| if uncovered: | |
| print(f" {len(uncovered)} NOT in map (will take llama-quantize's base type):") | |
| for n in uncovered[:10]: | |
| print(" ", n) | |
| def elems(name: str) -> int: | |
| n = 1 | |
| for d in tensors[name].shape: | |
| n *= int(d) | |
| return n | |
| # ---- pin the big tensors the inherited map does NOT cover ---- | |
| # | |
| # This is where a 310 MiB size-model error came from on the first pass, and | |
| # it matters more than it sounds: token_embd and output are 1,271,398,400 | |
| # elements EACH here (vocab 248,320 x 5,120) - together ~2.3 GiB, roughly | |
| # 10% of the whole budget, and NEITHER is in thireus' map. | |
| # | |
| # output.weight -> Q8_0. It is the LM head; llama-quantize already | |
| # promotes it by default, and reproducing the | |
| # ThinkingCap reference size requires it (assuming | |
| # Q6_K under-predicted that file by ~293 MiB). | |
| # token_embd -> Q6_K. Embeddings tolerate it; this is what the | |
| # reference quant used. Dropping it to Q5_K would buy | |
| # ~200 MiB for FFN upgrades but deviates from the | |
| # proven recipe - not worth the risk unprompted. | |
| # *ssm_conv1d -> F32. Tiny (7.5 MiB total at F32) and llama.cpp | |
| # generally refuses to quantize conv kernels anyway. | |
| # Pinned so the output size is deterministic rather | |
| # than dependent on llama-quantize's internal rules. | |
| for n, t in tensors.items(): | |
| if n in assign: | |
| continue | |
| if n == "output.weight": | |
| assign[n] = "Q8_0" | |
| elif n == "token_embd.weight": | |
| assign[n] = "Q6_K" | |
| elif "conv1d" in n: | |
| assign[n] = "F32" | |
| def total_mib(a: dict[str, str]) -> float: | |
| tot = 0.0 | |
| for n, t in tensors.items(): | |
| e = elems(n) | |
| if n in a: | |
| tot += e * BPE[a[n]] | |
| else: | |
| # remaining uncovered: 1-D/norms stay F32, others base Q6_K | |
| ty = "F32" if len(t.shape) < 2 else "Q6_K" | |
| tot += e * BPE[ty] | |
| return tot / MIB | |
| base = total_mib(assign) | |
| print(f"\ninherited map size: {base:10.1f} MiB") | |
| print(f"budget: {args.budget_mib:10.1f} MiB") | |
| print(f"headroom: {args.budget_mib - base:10.1f} MiB") | |
| if base > args.budget_mib: | |
| print("\nWARNING: inherited map ALREADY exceeds budget - would need " | |
| "demotion, not promotion. Not implemented; stopping.") | |
| return 3 | |
| # ---- SOLVE: promote Q6_K -> Q8_0 in principled order ---- | |
| # token_embd is excluded from promotion on purpose: at 1.27B elements it | |
| # would eat ~293 MiB of headroom for the least sensitivity-per-byte of any | |
| # tensor in the model. That headroom belongs to the FFN stack. | |
| candidates = [n for n, ty in assign.items() | |
| if ty == "Q6_K" and n != "token_embd.weight"] | |
| def rank(n: str): | |
| s = stem_of(n) | |
| gi = PROMOTION_ORDER.index(s) if s in PROMOTION_ORDER else len(PROMOTION_ORDER) | |
| return (gi, layer_of(n)) | |
| candidates.sort(key=rank) | |
| promoted: list[str] = [] | |
| cur = base | |
| for n in candidates: | |
| delta = elems(n) * (BPE["Q8_0"] - BPE["Q6_K"]) / MIB | |
| if cur + delta <= args.budget_mib: | |
| assign[n] = "Q8_0" | |
| promoted.append(n) | |
| cur += delta | |
| print(f"\npromoted {len(promoted)}/{len(candidates)} Q6_K tensors to Q8_0") | |
| by_stem: dict[str, int] = {} | |
| for n in promoted: | |
| by_stem[stem_of(n)] = by_stem.get(stem_of(n), 0) + 1 | |
| for s in PROMOTION_ORDER: | |
| tot = sum(1 for n in candidates if stem_of(n) == s) | |
| if tot: | |
| print(f" {s:12s} {by_stem.get(s,0):3d}/{tot:3d}") | |
| final = total_mib(assign) | |
| n_q8 = sum(1 for v in assign.values() if v == "Q8_0") | |
| n_q6 = sum(1 for v in assign.values() if v == "Q6_K") | |
| tot_elems = sum(elems(n) for n in assign) | |
| bpw = final * MIB * 8.0 / tot_elems | |
| print(f"\nfinal size: {final:10.1f} MiB ({final*MIB/1e9:.2f} GB decimal)") | |
| print(f"under budget by: {args.budget_mib - final:10.1f} MiB") | |
| print(f"mapped tensors: {n_q8} Q8_0 / {n_q6} Q6_K") | |
| print(f"effective bpw (mapped tensors): {bpw:.3f}") | |
| with open(args.out, "w", encoding="utf-8") as f: | |
| for n in sorted(assign): | |
| # anchored, dots escaped - same format as the proven thireus file. | |
| # anchors are NOT optional: an unanchored "attn_q" would also match | |
| # attn_qkv and silently mis-assign 48 tensors. | |
| f.write(f"^{re.escape(n)}$={assign[n].lower()}\n") | |
| print(f"\nwrote {args.out}") | |
| return 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |