Instructions to use TessaCoil/K3-Stuff 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 TessaCoil/K3-Stuff 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 TessaCoil/K3-Stuff:Q8_0 # Run inference directly in the terminal: llama cli -hf TessaCoil/K3-Stuff:Q8_0
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf TessaCoil/K3-Stuff:Q8_0 # Run inference directly in the terminal: llama cli -hf TessaCoil/K3-Stuff: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 TessaCoil/K3-Stuff:Q8_0 # Run inference directly in the terminal: ./llama-cli -hf TessaCoil/K3-Stuff: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 TessaCoil/K3-Stuff:Q8_0 # Run inference directly in the terminal: ./build/bin/llama-cli -hf TessaCoil/K3-Stuff:Q8_0
Use Docker
docker model run hf.co/TessaCoil/K3-Stuff:Q8_0
- LM Studio
- Jan
- Ollama
How to use TessaCoil/K3-Stuff with Ollama:
ollama run hf.co/TessaCoil/K3-Stuff:Q8_0
- Unsloth Desktop
- Pi
How to use TessaCoil/K3-Stuff with Pi:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf TessaCoil/K3-Stuff:Q8_0
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": "TessaCoil/K3-Stuff:Q8_0" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Docker Model Runner
How to use TessaCoil/K3-Stuff with Docker Model Runner:
docker model run hf.co/TessaCoil/K3-Stuff:Q8_0
- Lemonade
How to use TessaCoil/K3-Stuff with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull TessaCoil/K3-Stuff:Q8_0
Run and chat with the model
lemonade run user.K3-Stuff-Q8_0
List all available models
lemonade list
- Hermes Agent
How to use TessaCoil/K3-Stuff with Hermes Agent:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf TessaCoil/K3-Stuff: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 TessaCoil/K3-Stuff:Q8_0
Run Hermes
hermes
- Atomic Chat
- OpenClaw
How to use TessaCoil/K3-Stuff with OpenClaw:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf TessaCoil/K3-Stuff: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 "TessaCoil/K3-Stuff: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"
| #!/usr/bin/env python3 | |
| """Add tokenizer.ggml.mask_token_id to the DSpark draft GGUF. | |
| llama.cpp's DSpark spec reads the draft's mask token via | |
| llama_vocab_mask(vocab) -> tokenizer.ggml.mask_token_id. Our rewritten draft | |
| copied K3's tokenizer, which has no mask token, so it returns -1 and the draft | |
| batch gets fed token -1 -> 'invalid token[1] = -1' -> draft decode fails every step. | |
| The draft's *trained* mask id lives in dflash.mask_token_id (163824). We copy it | |
| into tokenizer.ggml.mask_token_id so llama_vocab_mask() returns the right id. | |
| """ | |
| import struct, sys | |
| SRC = "/root/models/k3-draft/draft_final.gguf" | |
| DST = "/root/models/k3-draft/draft_masked.gguf" | |
| MASK_KEY = b"tokenizer.ggml.mask_token_id" | |
| DFLASH_MASK_KEY = b"dflash.mask_token_id" | |
| def read_kv(data, pos): | |
| klen = struct.unpack_from("<Q", data, pos)[0]; pos += 8 | |
| key = data[pos:pos+klen]; pos += klen | |
| vtype = struct.unpack_from("<I", data, pos)[0]; pos += 4 | |
| if vtype == 8: | |
| vlen = struct.unpack_from("<Q", data, pos)[0]; pos += 8 | |
| val = data[pos:pos+vlen]; pos += vlen | |
| elif vtype in (0, 1, 7): | |
| val = data[pos:pos+1]; pos += 1 | |
| elif vtype in (2, 3): | |
| val = data[pos:pos+2]; pos += 2 | |
| elif vtype in (4, 5, 6): | |
| val = data[pos:pos+4]; pos += 4 | |
| elif vtype in (10, 11, 12): | |
| val = data[pos:pos+8]; pos += 8 | |
| elif vtype == 9: | |
| atype = struct.unpack_from("<I", data, pos)[0]; pos += 4 | |
| alen = struct.unpack_from("<Q", data, pos)[0]; pos += 8 | |
| if atype == 8: | |
| vals = [] | |
| for _ in range(alen): | |
| slen = struct.unpack_from("<Q", data, pos)[0]; pos += 8 | |
| vals.append(data[pos:pos+slen]); pos += slen | |
| val = (atype, vals) | |
| elif atype in (0, 1, 7): | |
| val = (atype, data[pos:pos+alen]); pos += alen | |
| elif atype in (2, 3): | |
| val = (atype, data[pos:pos+alen*2]); pos += alen*2 | |
| elif atype in (4, 5, 6): | |
| val = (atype, data[pos:pos+alen*4]); pos += alen*4 | |
| elif atype in (10, 11, 12): | |
| val = (atype, data[pos:pos+alen*8]); pos += alen*8 | |
| else: | |
| raise ValueError(f"array atype {atype}") | |
| else: | |
| raise ValueError(f"vtype {vtype} key {key}") | |
| return key, vtype, val, pos | |
| def write_kv(out, key, vtype, val): | |
| out += struct.pack("<Q", len(key)) + key + struct.pack("<I", vtype) | |
| if vtype == 8: | |
| out += struct.pack("<Q", len(val)) + val | |
| elif vtype in (0, 1, 7, 2, 3, 4, 5, 6, 10, 11, 12): | |
| out += val | |
| elif vtype == 9: | |
| atype, d = val | |
| out += struct.pack("<I", atype) | |
| if atype == 8: | |
| out += struct.pack("<Q", len(d)) | |
| for s in d: | |
| out += struct.pack("<Q", len(s)) + s | |
| else: | |
| sz = {0:1,1:1,7:1,2:2,3:2,4:4,5:4,6:4,10:8,11:8,12:8}[atype] | |
| out += struct.pack("<Q", len(d)//sz) + d | |
| def main(): | |
| data = open(SRC, "rb").read() | |
| pos = 0 | |
| magic = data[0:4]; pos = 4 | |
| version = struct.unpack_from("<I", data, pos)[0]; pos += 4 | |
| n_tensors = struct.unpack_from("<Q", data, pos)[0]; pos += 8 | |
| n_kv = struct.unpack_from("<Q", data, pos)[0]; pos += 8 | |
| kvs = [] | |
| mask_val = None | |
| have_tok_mask = False | |
| for _ in range(n_kv): | |
| key, vtype, val, pos = read_kv(data, pos) | |
| if key == DFLASH_MASK_KEY: | |
| mask_val = struct.unpack("<I", val)[0] if vtype in (4,5) else None | |
| print(f"found {DFLASH_MASK_KEY.decode()} vtype={vtype} val={mask_val}") | |
| if key == MASK_KEY: | |
| have_tok_mask = True | |
| print(f"WARNING: {MASK_KEY.decode()} already present") | |
| kvs.append((key, vtype, val)) | |
| if have_tok_mask: | |
| print("mask token already present, nothing to do"); return | |
| if mask_val is None: | |
| print("ERROR: dflash.mask_token_id not found"); sys.exit(1) | |
| # Append the new key | |
| kvs.append((MASK_KEY, 4, struct.pack("<I", mask_val))) # uint32 | |
| print(f"adding {MASK_KEY.decode()} = {mask_val} (uint32)") | |
| # Rebuild header + KV | |
| out = bytearray() | |
| out += magic + struct.pack("<I", version) + struct.pack("<Q", n_tensors) + struct.pack("<Q", len(kvs)) | |
| for key, vtype, val in kvs: | |
| write_kv(out, key, vtype, val) | |
| kv_end_new = len(out) | |
| # tensor infos + data follow unchanged from original pos | |
| rest = data[pos:] | |
| # The tensor data section is aligned; tensor info offsets are relative to data start. | |
| # We must recompute alignment: original data start vs new data start. | |
| alignment = 32 | |
| # original tensor-data start | |
| orig_data_start = (pos + 0) # pos == end of KV in original | |
| # tensor infos occupy from pos; find their end by walking n_tensors | |
| ti_pos = pos | |
| for _ in range(n_tensors): | |
| nl = struct.unpack_from("<Q", data, ti_pos)[0]; ti_pos += 8 + nl | |
| nd = struct.unpack_from("<I", data, ti_pos)[0]; ti_pos += 4 + nd*8 | |
| ti_pos += 4 # dtype | |
| ti_pos += 8 # offset | |
| orig_tensor_data_start = (ti_pos + alignment - 1)//alignment*alignment | |
| # new tensor-data start | |
| new_kv_and_ti_len = len(out) + (ti_pos - pos) | |
| new_tensor_data_start = (new_kv_and_ti_len + alignment - 1)//alignment*alignment | |
| # append tensor infos verbatim | |
| out += data[pos:ti_pos] | |
| while len(out) < new_tensor_data_start: | |
| out += b"\x00" | |
| out += data[orig_tensor_data_start:] | |
| open(DST, "wb").write(out) | |
| print(f"wrote {DST}: {len(out)} bytes (src {len(data)})") | |
| print("verify: tokenizer.ggml.mask_token_id should now read", mask_val) | |
| if __name__ == "__main__": | |
| main() | |