Text Generation
GGUF
llama.cpp
pocketpal
on-device
Mixture of Experts
multilingual
quantization
distillation
1-bit
2-bit
3-bit
conversational
Instructions to use RegalInvader/Marco-Nano-Instruct-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 RegalInvader/Marco-Nano-Instruct-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 RegalInvader/Marco-Nano-Instruct-GGUF:TQ1_0 # Run inference directly in the terminal: llama cli -hf RegalInvader/Marco-Nano-Instruct-GGUF:TQ1_0
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf RegalInvader/Marco-Nano-Instruct-GGUF:TQ1_0 # Run inference directly in the terminal: llama cli -hf RegalInvader/Marco-Nano-Instruct-GGUF:TQ1_0
Build from source code
git clone https://github.com/ggml-org/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-app # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama serve -hf RegalInvader/Marco-Nano-Instruct-GGUF:TQ1_0 # Run inference directly in the terminal: ./build/bin/llama cli -hf RegalInvader/Marco-Nano-Instruct-GGUF:TQ1_0
Use Docker
docker model run hf.co/RegalInvader/Marco-Nano-Instruct-GGUF:TQ1_0
- Llama new
- LM Studio
- Jan
- vLLM
How to use RegalInvader/Marco-Nano-Instruct-GGUF with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "RegalInvader/Marco-Nano-Instruct-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": "RegalInvader/Marco-Nano-Instruct-GGUF", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/RegalInvader/Marco-Nano-Instruct-GGUF:TQ1_0
- Ollama
How to use RegalInvader/Marco-Nano-Instruct-GGUF with Ollama:
ollama run hf.co/RegalInvader/Marco-Nano-Instruct-GGUF:TQ1_0
- Unsloth Desktop
- Pi
How to use RegalInvader/Marco-Nano-Instruct-GGUF with Pi:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf RegalInvader/Marco-Nano-Instruct-GGUF:TQ1_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": "RegalInvader/Marco-Nano-Instruct-GGUF:TQ1_0" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Docker Model Runner
How to use RegalInvader/Marco-Nano-Instruct-GGUF with Docker Model Runner:
docker model run hf.co/RegalInvader/Marco-Nano-Instruct-GGUF:TQ1_0
- Lemonade
How to use RegalInvader/Marco-Nano-Instruct-GGUF with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull RegalInvader/Marco-Nano-Instruct-GGUF:TQ1_0
Run and chat with the model
lemonade run user.Marco-Nano-Instruct-GGUF-TQ1_0
List all available models
lemonade list
- Hermes Agent
How to use RegalInvader/Marco-Nano-Instruct-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 RegalInvader/Marco-Nano-Instruct-GGUF:TQ1_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 RegalInvader/Marco-Nano-Instruct-GGUF:TQ1_0
Run Hermes
hermes
- Atomic Chat
- OpenClaw
How to use RegalInvader/Marco-Nano-Instruct-GGUF with OpenClaw:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf RegalInvader/Marco-Nano-Instruct-GGUF:TQ1_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 "RegalInvader/Marco-Nano-Instruct-GGUF:TQ1_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"
Download code/tests/test_codebook.py from RegalInvader/Marco-Nano-Instruct-GGUF: direct link, hf CLI and curl.
- Browser
- Download file 14.1 kB
-
https://huggingface.co/RegalInvader/Marco-Nano-Instruct-GGUF/resolve/main/code/tests/test_codebook.py
- Command line
-
hf download hf://RegalInvader/Marco-Nano-Instruct-GGUF/code/tests/test_codebook.py
-
curl -L -o test_codebook.py https://huggingface.co/RegalInvader/Marco-Nano-Instruct-GGUF/resolve/main/code/tests/test_codebook.py
14.1 kB
| """D-58: codebook formats against llama.cpp's own files (gguf-py's dequantisers are the reference).""" | |
| from pathlib import Path | |
| import numpy as np | |
| import pytest | |
| import torch | |
| from lowbit.export.gguf import gguf_module | |
| from lowbit.quant import codebook as cb | |
| PTQ = Path("/path/to/data/ptq/gguf") | |
| LLAMA = "/path/to/llama.cpp" | |
| SOURCES = { # format → (file, tensor) | |
| "IQ2_XXS": ("teacher-iq2_xxs-imat.gguf", "blk.5.ffn_up_exps.weight"), | |
| "IQ2_XS": ("teacher-iq2_xs-imat.gguf", "blk.5.ffn_up_exps.weight"), | |
| "IQ2_S": ("teacher-iq2_s-iq4nldown-imat.gguf", "blk.5.ffn_gate_exps.weight"), | |
| "IQ3_XXS": ("teacher-iq3_xxs-imat.gguf", "blk.5.ffn_gate_exps.weight"), | |
| "IQ3_S": ("teacher-iq3_s-iq4nldown-imat.gguf", "blk.5.ffn_gate_exps.weight"), | |
| "IQ4_XS": ("teacher-iq4_xs-imat.gguf", "blk.5.ffn_up_exps.weight"), | |
| "IQ4_NL": ("teacher-iq3_s-iq4nldown-imat.gguf", "blk.5.ffn_down_exps.weight"), | |
| } | |
| N = 4096 # blocks per test | |
| def gguf(): | |
| return gguf_module(LLAMA) | |
| def _blocks(gguf, name, n=N): | |
| path, tensor = SOURCES[name] | |
| if not (PTQ / path).exists(): | |
| pytest.skip(f"{path} not on this machine") | |
| t = next(t for t in gguf.GGUFReader(str(PTQ / path)).tensors if t.name == tensor) | |
| fmt = cb.FORMATS[name] | |
| assert t.tensor_type == getattr(gguf.GGMLQuantizationType, name) | |
| return fmt, np.asarray(t.data).reshape(-1, fmt.nbytes)[:n].copy() | |
| def test_fields_round_trip(gguf, name): | |
| fmt, b = _blocks(gguf, name) | |
| out = cb.write_blocks(fmt, b, cb.get_d(b), cb.get_s(fmt, b)) | |
| assert np.array_equal(out, b) # byte-identical | |
| def test_decode_matches_ggml(gguf, name): | |
| fmt, b = _blocks(gguf, name) | |
| ref = gguf.quants.dequantize(b, getattr(gguf.GGMLQuantizationType, name)).reshape(len(b), fmt.block) | |
| v = cb.values(fmt, b, gguf) | |
| e = cb.eff_np(fmt, cb.get_d(b), cb.get_s(fmt, b)) | |
| got = (v.astype(np.float32).reshape(len(b), -1, fmt.sub) * e[..., None]).reshape(len(b), -1) | |
| assert np.array_equal(got, ref) | |
| # the torch form at its start (dlog = 0, slat = s) is the same weights | |
| d0 = torch.from_numpy(cb.get_d(b).astype(np.float32)) | |
| s0 = torch.from_numpy(cb.get_s(fmt, b).astype(np.float32)) | |
| w = cb.weight(fmt, torch.from_numpy(v.reshape(-1)), d0, torch.zeros_like(d0), | |
| s0.reshape(-1) if fmt.name != "IQ4_NL" else None) | |
| assert torch.equal(w, torch.from_numpy(ref.reshape(-1))) | |
| def test_new_scales_dequantise_as_trained(gguf, name): | |
| fmt, b = _blocks(gguf, name) | |
| v = torch.from_numpy(cb.values(fmt, b, gguf).reshape(-1)) | |
| d0 = torch.from_numpy(cb.get_d(b).astype(np.float32)) | |
| g = torch.Generator().manual_seed(0) | |
| dlog = 0.05 * torch.randn(d0.shape, generator=g) | |
| slat = None | |
| if fmt.name != "IQ4_NL": | |
| s0 = torch.from_numpy(cb.get_s(fmt, b).astype(np.float32)).reshape(-1) | |
| slat = s0 + 1.5 * torch.randn(s0.shape, generator=g) | |
| w = cb.weight(fmt, v, d0, dlog, slat) | |
| d, s = cb.trained_fields(fmt, d0, dlog, slat) | |
| nb = cb.write_blocks(fmt, b, d, s.reshape(len(b), -1)) | |
| ref = gguf.quants.dequantize(nb, getattr(gguf.GGMLQuantizationType, name)).reshape(-1) | |
| assert torch.equal(w, torch.from_numpy(ref)) | |
| def test_ste_reaches_scales(): | |
| fmt = cb.FORMATS["IQ3_S"] | |
| v = torch.randint(-15, 16, (2, 256), dtype=torch.int8) | |
| d0 = torch.full((2, 1), 0.01) | |
| dlog = torch.zeros(2, 1, requires_grad=True) | |
| slat = torch.full((2, 8), 5.0, requires_grad=True) | |
| cb.weight(fmt, v, d0, dlog, slat).sum().backward() | |
| assert dlog.grad.abs().sum() > 0 and slat.grad.abs().sum() > 0 | |
| def _fake_init(gguf, tmp_path, cfg): | |
| """A cb_import-style directory for a tiny model, from real llama.cpp blocks (IQ3_S gate/up, IQ4_NL down).""" | |
| from safetensors.numpy import save_file | |
| import json | |
| E, I, H = cfg.num_experts, cfg.moe_intermediate_size, cfg.hidden_size | |
| f3, b3 = _blocks(gguf, "IQ3_S") | |
| fn, bn = _blocks(gguf, "IQ4_NL", 4 * N) | |
| need3, needn = E * I * (H // 256), E * H * (I // 32) | |
| assert len(b3) >= 2 * need3 and len(bn) >= needn | |
| t, formats = {}, {} | |
| for i in range(cfg.num_hidden_layers): | |
| for k, (fmt, src, rows, cols) in {"gate": (f3, b3[:need3], I, H), "up": (f3, b3[need3:2 * need3], I, H), | |
| "down": (fn, bn[:needn], H, I)}.items(): | |
| key = f"layers.{i}.{k}" | |
| formats[key] = fmt.name | |
| t[f"{key}.blocks"] = src.reshape(E, rows, cols // fmt.block, fmt.nbytes).copy() | |
| t[f"{key}.v"] = cb.values(fmt, src, gguf).reshape(E, rows, cols) | |
| t[f"{key}.d"] = cb.get_d(src).reshape(E, rows, -1) | |
| t[f"{key}.s"] = cb.get_s(fmt, src).reshape(E, rows, -1) | |
| save_file(t, str(tmp_path / "experts.safetensors")) | |
| (tmp_path / "manifest.json").write_text(json.dumps({"formats": formats})) | |
| return t | |
| def test_student_round_trip(gguf, tmp_path): | |
| """The codebook student's weights are the source blocks' dequantisation; after a training-like change the packed | |
| export dequantises to the student's weights; gate/up keep llama.cpp's order (gate first).""" | |
| from test_student import tiny | |
| from lowbit.model import student as st | |
| from lowbit.quant.ternary import QuantSpec | |
| from lowbit.export.gguf import packed_blocks, student_tensors | |
| base = tiny(hidden=256) | |
| (tmp_path / "init").mkdir() | |
| t = _fake_init(gguf, tmp_path / "init", base.config) | |
| prec = st.Precision.load(Path(__file__).resolve().parent.parent / "configs/precision/cb_iq3s.yaml") | |
| prec.codebook = str(tmp_path / "init") | |
| prec.experts = QuantSpec(method="codebook", group_size=32) | |
| m = st.build_student(base, prec, quant=True) | |
| T = gguf.GGMLQuantizationType | |
| ex = m.model.layers[1].mlp.experts | |
| deq = lambda b, q: gguf.quants.dequantize(b, q).reshape(*b.shape[:2], -1) | |
| ref_gu = np.concatenate([deq(t[f"layers.1.{k}.blocks"], T.IQ3_S) for k in ("gate", "up")], 1) | |
| assert np.array_equal(st._expert_weight(ex, "gate_up").detach().numpy(), ref_gu) | |
| ref_d = deq(t["layers.1.down.blocks"], T.IQ4_NL) | |
| assert np.array_equal(st._expert_weight(ex, "down").detach().numpy(), ref_d) | |
| # forward/backward reach the scales | |
| m.train() | |
| x = torch.randint(0, 256, (2, 32), generator=torch.Generator().manual_seed(1)) | |
| st.logits(m, st.final_hidden(m, x)).float().pow(2).mean().backward() | |
| assert ex.gate_up_dlog.grad.abs().sum() > 0 and ex.gate_up_slat.grad.abs().sum() > 0 | |
| assert ex.down_dlog.grad.abs().sum() > 0 and not hasattr(ex, "down_slat") | |
| # untrained export: the source blocks unchanged, gate first | |
| st.export_packed_student(m, tmp_path / "p0") | |
| sd, packed, man = st.read_packed(tmp_path / "p0") | |
| tens = student_tensors({}, packed, gguf) | |
| for k in ("gate", "up", "down"): | |
| assert tens[f"blk.1.ffn_{k}_exps.weight"][1].tobytes() == t[f"layers.1.{k}.blocks"].tobytes() | |
| # a training-like change: the export dequantises to the student's weights | |
| g = torch.Generator().manual_seed(2) | |
| with torch.no_grad(): | |
| for layer in m.model.layers: | |
| e = layer.mlp.experts | |
| e.gate_up_dlog.add_(0.05 * torch.randn(e.gate_up_dlog.shape, generator=g)) | |
| e.gate_up_slat.add_(1.5 * torch.randn(e.gate_up_slat.shape, generator=g)) | |
| e.down_dlog.add_(0.05 * torch.randn(e.down_dlog.shape, generator=g)) | |
| st.export_packed_student(m, tmp_path / "p1") | |
| sd, packed, man = st.read_packed(tmp_path / "p1") | |
| for name in ("gate_up", "down"): | |
| key = f"model.layers.1.mlp.experts.{name}_proj" | |
| qt, raw = packed_blocks(packed[key], gguf) | |
| got = gguf.quants.dequantize(raw, qt).reshape(packed[key]["shape"]) | |
| assert np.array_equal(got, st._expert_weight(ex, name).detach().numpy()) | |
| assert torch.equal(st.dequant_codebook(key, packed[key], torch.float32), st._expert_weight(ex, name).detach()) | |
| assert man["codebook_formats"]["model.layers.0.mlp.experts.gate_up_proj"] == "IQ3_S" | |
| FREE = ("IQ3_S", "IQ2_XXS", "IQ4_NL") | |
| def test_free_codes_start_is_the_file(gguf, name): | |
| """Latents at llama.cpp's dequantised weights find llama.cpp's own codes: the re-encoded blocks are identical.""" | |
| fmt, b = _blocks(gguf, name) | |
| ref = gguf.quants.dequantize(b, getattr(gguf.GGMLQuantizationType, name)).reshape(len(b), fmt.block) | |
| grid = cb.grid_from_gguf(fmt, gguf) | |
| d0 = torch.from_numpy(cb.get_d(b).astype(np.float32))[:, None] | |
| s0 = torch.from_numpy(cb.get_s(fmt, b).astype(np.float32)) | |
| lat = torch.from_numpy(ref.copy()) | |
| w = cb.weight_free(fmt, lat, d0, torch.zeros_like(d0), None if name == "IQ4_NL" else s0, grid) | |
| assert torch.equal(w, lat) | |
| e = cb.eff_torch(fmt, d0, s0).unsqueeze(-1) | |
| idx, vals = cb.free_codes(fmt, (lat.unflatten(-1, (-1, fmt.sub)) / e).flatten(-2), grid) | |
| out = cb.encode(fmt, idx, vals, cb.get_d(b), cb.get_s(fmt, b)) | |
| assert np.array_equal(out.reshape(b.shape), b) | |
| def test_free_codes_moved_dequantise_as_trained(gguf, name): | |
| fmt, b = _blocks(gguf, name) | |
| ref = gguf.quants.dequantize(b, getattr(gguf.GGMLQuantizationType, name)).reshape(len(b), fmt.block) | |
| grid = cb.grid_from_gguf(fmt, gguf) | |
| g = torch.Generator().manual_seed(3) | |
| lat = torch.from_numpy(ref.copy()) * (1 + 0.3 * torch.randn(ref.shape, generator=g)) | |
| d0 = torch.from_numpy(cb.get_d(b).astype(np.float32))[:, None] | |
| dlog = 0.05 * torch.randn(d0.shape, generator=g) | |
| slat = None if name == "IQ4_NL" else torch.from_numpy(cb.get_s(fmt, b).astype(np.float32)) + torch.randn(len(b), fmt.block // fmt.sub, generator=g) | |
| w = cb.weight_free(fmt, lat, d0, dlog, slat, grid) | |
| d, s = cb.trained_fields(fmt, d0, dlog, slat) | |
| e = cb.eff_torch(fmt, torch.from_numpy(d.astype(np.float32)), torch.from_numpy(s.astype(np.float32))).unsqueeze(-1) | |
| idx, vals = cb.free_codes(fmt, (lat.unflatten(-1, (-1, fmt.sub)) / e).flatten(-2), grid) | |
| out = cb.encode(fmt, idx, vals, d, s) | |
| got = gguf.quants.dequantize(out.reshape(b.shape), getattr(gguf.GGMLQuantizationType, name)).reshape(w.shape) | |
| assert torch.equal(w, torch.from_numpy(got)) | |
| assert (out.reshape(b.shape) != b).any() # codes really moved | |
| def test_student_free_round_trip(gguf, tmp_path): | |
| """Free codes: the start is the file; latents get gradients; a moved student exports to its own weights.""" | |
| from test_student import tiny | |
| from lowbit.model import student as st | |
| from lowbit.quant.ternary import QuantSpec | |
| from lowbit.export.gguf import packed_blocks | |
| from safetensors.torch import save_file | |
| base = tiny(hidden=256) | |
| (tmp_path / "init").mkdir() | |
| t = _fake_init(gguf, tmp_path / "init", base.config) | |
| save_file({n: cb.grid_from_gguf(cb.FORMATS[n], gguf) for n in ("IQ3_S", "IQ4_NL")}, str(tmp_path / "init/grids.safetensors")) | |
| prec = st.Precision.load(Path(__file__).resolve().parent.parent / "configs/precision/cb_iq3s.yaml") | |
| prec.codebook, prec.codebook_mode = str(tmp_path / "init"), "free" | |
| prec.experts = QuantSpec(method="codebook", group_size=32) | |
| m = st.build_student(base, prec, quant=True) | |
| ex = m.model.layers[1].mlp.experts | |
| T = gguf.GGMLQuantizationType | |
| deq = lambda b, q: gguf.quants.dequantize(b, q).reshape(*b.shape[:2], -1) | |
| ref = np.concatenate([deq(t[f"layers.1.{k}.blocks"], T.IQ3_S) for k in ("gate", "up")], 1) | |
| assert np.array_equal(st._expert_weight(ex, "gate_up").detach().numpy(), ref) | |
| m.train() | |
| x = torch.randint(0, 256, (2, 32), generator=torch.Generator().manual_seed(1)) | |
| st.logits(m, st.final_hidden(m, x)).float().pow(2).mean().backward() | |
| assert ex.gate_up_latent.grad.abs().sum() > 0 and ex.down_latent.grad.abs().sum() > 0 | |
| assert ex.gate_up_slat.grad.abs().sum() > 0 | |
| g = torch.Generator().manual_seed(4) | |
| with torch.no_grad(): | |
| for layer in m.model.layers: | |
| e = layer.mlp.experts | |
| for n in ("gate_up", "down"): | |
| lat = getattr(e, f"{n}_latent") | |
| lat.mul_(1 + 0.3 * torch.randn(lat.shape, generator=g)) | |
| st.export_packed_student(m, tmp_path / "p") | |
| sd, packed, man = st.read_packed(tmp_path / "p") | |
| for name in ("gate_up", "down"): | |
| key = f"model.layers.1.mlp.experts.{name}_proj" | |
| qt, raw = packed_blocks(packed[key], gguf) | |
| got = gguf.quants.dequantize(raw, qt).reshape(packed[key]["shape"]) | |
| assert np.array_equal(got, st._expert_weight(ex, name).detach().numpy()) | |
| def test_codebook_export_resume(gguf, tmp_path): | |
| """A student loaded from its own export exports the same file again (blocks and dense tensors).""" | |
| from test_student import tiny | |
| from lowbit.model import student as st | |
| from lowbit.quant.ternary import QuantSpec | |
| from safetensors.torch import load_file | |
| base = tiny(hidden=256) | |
| (tmp_path / "init").mkdir() | |
| _fake_init(gguf, tmp_path / "init", base.config) | |
| prec = st.Precision.load(Path(__file__).resolve().parent.parent / "configs/precision/cb_iq3s.yaml") | |
| prec.codebook = str(tmp_path / "init") | |
| prec.experts = QuantSpec(method="codebook", group_size=32) | |
| m = st.build_student(base, prec, quant=True) | |
| g = torch.Generator().manual_seed(5) | |
| with torch.no_grad(): | |
| for layer in m.model.layers: | |
| e = layer.mlp.experts | |
| e.gate_up_dlog.add_(0.05 * torch.randn(e.gate_up_dlog.shape, generator=g)) | |
| e.gate_up_slat.add_(1.5 * torch.randn(e.gate_up_slat.shape, generator=g)) | |
| e.down_dlog.add_(0.05 * torch.randn(e.down_dlog.shape, generator=g)) | |
| layer.self_attn.q_proj.weight.add_(0.01) | |
| st.export_packed_student(m, tmp_path / "a") | |
| m2 = st.build_student(tiny(hidden=256), prec, quant=True) | |
| st.load_codebook_export(m2, tmp_path / "a") | |
| st.export_packed_student(m2, tmp_path / "b") | |
| a, b = load_file(str(tmp_path / "a/model.safetensors")), load_file(str(tmp_path / "b/model.safetensors")) | |
| assert a.keys() == b.keys() and all(torch.equal(a[k], b[k]) for k in a) | |