Text Generation
PyTorch
Safetensors
GGUF
qwen3_5_text
deltanet
qwen3.8
cpu
efficient
low-memory
ternary
bitnet
jirack
web-ui
routing
tool-call
robotics
ollama
ternary-weights
ternary-transformer
quantization
1.58-bit
conversational
Instructions to use CMSManhattan/JiRackDeltaNet_70b 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 CMSManhattan/JiRackDeltaNet_70b 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 CMSManhattan/JiRackDeltaNet_70b:Q4_K_M # Run inference directly in the terminal: llama cli -hf CMSManhattan/JiRackDeltaNet_70b:Q4_K_M
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf CMSManhattan/JiRackDeltaNet_70b:Q4_K_M # Run inference directly in the terminal: llama cli -hf CMSManhattan/JiRackDeltaNet_70b:Q4_K_M
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 CMSManhattan/JiRackDeltaNet_70b:Q4_K_M # Run inference directly in the terminal: ./build/bin/llama cli -hf CMSManhattan/JiRackDeltaNet_70b:Q4_K_M
Use Docker
docker model run hf.co/CMSManhattan/JiRackDeltaNet_70b:Q4_K_M
- Llama new
- LM Studio
- Jan
- vLLM
How to use CMSManhattan/JiRackDeltaNet_70b with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "CMSManhattan/JiRackDeltaNet_70b" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "CMSManhattan/JiRackDeltaNet_70b", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/CMSManhattan/JiRackDeltaNet_70b:Q4_K_M
- Ollama
How to use CMSManhattan/JiRackDeltaNet_70b with Ollama:
ollama run hf.co/CMSManhattan/JiRackDeltaNet_70b:Q4_K_M
- Unsloth Desktop
- Pi
How to use CMSManhattan/JiRackDeltaNet_70b with Pi:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf CMSManhattan/JiRackDeltaNet_70b:Q4_K_M
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": "CMSManhattan/JiRackDeltaNet_70b:Q4_K_M" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Docker Model Runner
How to use CMSManhattan/JiRackDeltaNet_70b with Docker Model Runner:
docker model run hf.co/CMSManhattan/JiRackDeltaNet_70b:Q4_K_M
- Lemonade
How to use CMSManhattan/JiRackDeltaNet_70b with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull CMSManhattan/JiRackDeltaNet_70b:Q4_K_M
Run and chat with the model
lemonade run user.JiRackDeltaNet_70b-Q4_K_M
List all available models
lemonade list
- Hermes Agent
How to use CMSManhattan/JiRackDeltaNet_70b with Hermes Agent:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf CMSManhattan/JiRackDeltaNet_70b:Q4_K_M
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 CMSManhattan/JiRackDeltaNet_70b:Q4_K_M
Run Hermes
hermes
- Atomic Chat
- OpenClaw
How to use CMSManhattan/JiRackDeltaNet_70b with OpenClaw:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf CMSManhattan/JiRackDeltaNet_70b:Q4_K_M
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 "CMSManhattan/JiRackDeltaNet_70b:Q4_K_M" \ --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 chat_jirack.py from CMSManhattan/JiRackDeltaNet_70b: direct link, hf CLI and curl.
- Browser
- Download file 12.9 kB
-
https://huggingface.co/CMSManhattan/JiRackDeltaNet_70b/resolve/main/chat_jirack.py
- Command line
-
hf download hf://CMSManhattan/JiRackDeltaNet_70b/chat_jirack.py
-
curl -L -o chat_jirack.py https://huggingface.co/CMSManhattan/JiRackDeltaNet_70b/resolve/main/chat_jirack.py
12.9 kB
| #!/usr/bin/env python3 | |
| # ============================================================================= | |
| # chat_jirack.py - chat with JiRackDeltaNet 70B from a safetensors folder. | |
| # | |
| # python3 chat_jirack.py --model-dir /mnt/nfs_share/JiRackDeltaNet_70b/expanded | |
| # | |
| # - model code: JiRackDeltaNet_*.py from the same folder (or --model-file) | |
| # - several GPUs: the TransformerBlocks are split across them evenly (70B bf16 = 140 GB, | |
| # so at least 2x80 GB); 1 GPU if it fits; CPU works but is VERY slow for 70B | |
| # - answer streams token by token, stops on <|im_end|> / <|endoftext|> | |
| # - commands: /reset (clear history), /think (thinking on/off), exit | |
| # ============================================================================= | |
| import argparse | |
| import glob | |
| import importlib.util | |
| import itertools | |
| import json | |
| import os | |
| import sys | |
| import time | |
| import torch | |
| import torch.nn as nn | |
| INIT_FNS = ("uniform_", "normal_", "trunc_normal_", "kaiming_uniform_", "kaiming_normal_", | |
| "xavier_uniform_", "xavier_normal_", "orthogonal_") | |
| def find_model_file(d): | |
| files = sorted(glob.glob(os.path.join(d, "JiRackDeltaNet_*.py"))) | |
| if not files: | |
| sys.exit(f"❌ no JiRackDeltaNet_*.py in {d}; pass --model-file") | |
| return files[-1] | |
| def load_module(path): | |
| spec = importlib.util.spec_from_file_location("jirack_chat_model", path) | |
| mod = importlib.util.module_from_spec(spec) | |
| sys.modules["jirack_chat_model"] = mod | |
| spec.loader.exec_module(mod) | |
| return mod | |
| def build(mod): | |
| """bf16 skeleton without random init (all weights are loaded afterwards) - as in deltanet_gate.py.""" | |
| saved = {n: getattr(nn.init, n) for n in INIT_FNS if hasattr(nn.init, n)} | |
| for n in saved: | |
| setattr(nn.init, n, lambda t, *a, **k: t) | |
| torch.set_default_dtype(torch.bfloat16) | |
| try: | |
| model = mod.JiRackQwen38ForCausalLM() | |
| finally: | |
| torch.set_default_dtype(torch.float32) | |
| for n, f in saved.items(): | |
| setattr(nn.init, n, f) | |
| return model.eval() | |
| def load_weights(model, d): | |
| from safetensors import safe_open | |
| idx = os.path.join(d, "model.safetensors.index.json") | |
| files = sorted(set(json.load(open(idx))["weight_map"].values())) if os.path.exists(idx) else \ | |
| sorted(os.path.basename(p) for p in glob.glob(os.path.join(d, "*.safetensors"))) | |
| sd = model.state_dict() | |
| params = {n for n, _ in model.named_parameters()} | |
| loaded = set() | |
| t0 = time.time() | |
| with torch.no_grad(): | |
| for i, f in enumerate(files): | |
| with safe_open(os.path.join(d, f), framework="pt", device="cpu") as h: | |
| for k in h.keys(): | |
| if k in sd: | |
| sd[k].copy_(h.get_tensor(k)) | |
| loaded.add(k) | |
| print(f" {i + 1}/{len(files)} {f} {time.time() - t0:.0f} s", flush=True) | |
| missing = sorted(params - loaded) | |
| if missing: | |
| sys.exit(f"❌ {len(missing)} parameters not in {d}: {missing[:5]}") | |
| class ChatTokenizer: | |
| """tokenizer.json (tokenizers) + chat template (jinja2) - no transformers needed, so the | |
| tokenizer_config.json format (e.g. extra_special_tokens as a list) does not matter.""" | |
| def __init__(self, d): | |
| import jinja2 | |
| from jinja2.sandbox import ImmutableSandboxedEnvironment | |
| from tokenizers import Tokenizer | |
| self.tk = Tokenizer.from_file(os.path.join(d, "tokenizer.json")) | |
| cfg = {} | |
| if os.path.exists(os.path.join(d, "tokenizer_config.json")): | |
| cfg = json.load(open(os.path.join(d, "tokenizer_config.json"), encoding="utf-8")) | |
| path = os.path.join(d, "chat_template.jinja") | |
| text = open(path, encoding="utf-8").read() if os.path.exists(path) else cfg.get("chat_template") | |
| if isinstance(text, list): | |
| text = next(t["template"] for t in text if t.get("name") == "default") | |
| if not text: | |
| sys.exit(f"❌ no chat template in {d}") | |
| def raise_exception(msg): | |
| raise jinja2.exceptions.TemplateError(msg) | |
| def tojson(x, ensure_ascii=False, indent=None, separators=None, sort_keys=False): | |
| return json.dumps(x, ensure_ascii=ensure_ascii, indent=indent, separators=separators, | |
| sort_keys=sort_keys) | |
| env = ImmutableSandboxedEnvironment(trim_blocks=True, lstrip_blocks=True) | |
| env.filters["tojson"] = tojson | |
| env.globals["raise_exception"] = raise_exception | |
| self.tmpl = env.from_string(text) | |
| s = lambda v: v.get("content") if isinstance(v, dict) else v | |
| self.bos, self.eos = s(cfg.get("bos_token")) or "", s(cfg.get("eos_token")) or "" | |
| self.special = [t.content for t in self.tk.get_added_tokens_decoder().values() if t.special] | |
| self.stop_ids = {i for i in (self.tk.token_to_id("<|im_end|>"), self.tk.token_to_id("<|endoftext|>"), | |
| self.tk.token_to_id(self.eos) if self.eos else None) if i is not None} | |
| def prompt_ids(self, msgs, think): | |
| text = self.tmpl.render(messages=msgs, add_generation_prompt=True, enable_thinking=think, | |
| bos_token=self.bos, eos_token=self.eos) | |
| return self.tk.encode(text, add_special_tokens=False).ids | |
| def decode(self, ids): | |
| return self.tk.decode(ids, skip_special_tokens=False) | |
| def _to(x, dev): | |
| if torch.is_tensor(x): | |
| return x.to(dev) | |
| if isinstance(x, (tuple, list)): | |
| return type(x)(_to(v, dev) for v in x) | |
| if isinstance(x, dict): | |
| return {k: _to(v, dev) for k, v in x.items()} | |
| return x | |
| def place(model, devices): | |
| """Blocks split evenly over the GPUs (moved there directly - the whole model never sits on one | |
| GPU); everything else on the first GPU. Pre-hooks move each module's inputs to its device, | |
| so the model code needs no changes.""" | |
| blocks = [m for m in model.modules() if type(m).__name__ == "TransformerBlock"] | |
| in_block = {id(x) for b in blocks for x in b.modules()} | |
| for i, b in enumerate(blocks): | |
| dev = devices[i * len(devices) // len(blocks)] | |
| b.to(dev) | |
| if len(devices) > 1: | |
| b.register_forward_pre_hook(lambda m, a, k, dev=dev: (_to(a, dev), _to(k, dev)), with_kwargs=True) | |
| for m in model.modules(): # embeddings / norms / lm_head / mtp / rotary | |
| if id(m) in in_block: | |
| continue | |
| m._apply(lambda t: t.to(devices[0]), recurse=False) | |
| if len(devices) > 1 and not list(m.children()): | |
| m.register_forward_pre_hook(lambda mm, a, k: (_to(a, devices[0]), _to(k, devices[0])), | |
| with_kwargs=True) | |
| return devices[0] | |
| def _cast(x, dtype): | |
| if torch.is_tensor(x): | |
| return x.to(dtype) if x.is_floating_point() and x.dtype != dtype else x | |
| if isinstance(x, (tuple, list)): | |
| return type(x)(_cast(v, dtype) for v in x) | |
| if isinstance(x, dict): | |
| return {k: _cast(v, dtype) for k, v in x.items()} | |
| return x | |
| def fp32_blocks(model): | |
| """CPU (AVX-only Xeon has no fast bf16 matmul): every TransformerBlock and lm_head runs with | |
| fp32 weights/inputs, converted on entry and back on exit - stored weights stay bf16 (RAM), | |
| same as the 'fp32blocks' compute of deltanet_gate.py.""" | |
| def pre(mod, args, kwargs): | |
| saved = [] | |
| for t in itertools.chain(mod.parameters(), mod.buffers()): | |
| if t.is_floating_point() and t.dtype != torch.float32: | |
| saved.append((t, t.data)) | |
| t.data = t.data.float() | |
| mod._jr_saved = saved | |
| return _cast(args, torch.float32), _cast(kwargs, torch.float32) | |
| def post(mod, args, out, back=torch.bfloat16): | |
| for t, d in mod._jr_saved: | |
| t.data = d | |
| mod._jr_saved = [] | |
| return _cast(out, back) if back is not None else out | |
| for m in model.modules(): | |
| if type(m).__name__ == "TransformerBlock": | |
| m.register_forward_pre_hook(pre, with_kwargs=True) | |
| m.register_forward_hook(post) | |
| head = getattr(model, "lm_head", None) | |
| if isinstance(head, nn.Module): | |
| head.register_forward_pre_hook(pre, with_kwargs=True) | |
| head.register_forward_hook(lambda m, a, o: post(m, a, o, None)) | |
| def logits_of(out): | |
| if isinstance(out, (tuple, list)): | |
| return out[0] | |
| return out.logits if hasattr(out, "logits") else out | |
| def sample(logits, temperature, top_p): | |
| if temperature <= 0: | |
| return int(logits.argmax()) | |
| probs = torch.softmax(logits.float() / temperature, dim=-1) | |
| sp, si = probs.sort(descending=True) | |
| cut = (sp.cumsum(-1) - sp) > top_p | |
| sp[cut] = 0 | |
| return int(si[torch.multinomial(sp / sp.sum(), 1)]) | |
| def main(): | |
| p = argparse.ArgumentParser() | |
| p.add_argument("--model-dir", default="/mnt/nfs_share/JiRackDeltaNet_70b/expanded") | |
| p.add_argument("--model-file", default=None) | |
| p.add_argument("--tokenizer-dir", default=None, help="default: --model-dir") | |
| p.add_argument("--max-new", type=int, default=2048) | |
| p.add_argument("--temperature", type=float, default=0.6, help="0 = greedy") | |
| p.add_argument("--top-p", type=float, default=0.95) | |
| p.add_argument("--system", default=None, help="file with a system prompt") | |
| p.add_argument("--no-think", action="store_true", help="start with thinking off") | |
| p.add_argument("--cpu", action="store_true") | |
| p.add_argument("--cpu-bf16", action="store_true", help="CPU: plain bf16 instead of fp32 blocks") | |
| a = p.parse_args() | |
| tok = ChatTokenizer(a.tokenizer_dir or a.model_dir) | |
| stop = tok.stop_ids | |
| print(f"stop tokens {sorted(stop)}", flush=True) | |
| mf = a.model_file or find_model_file(a.model_dir) | |
| print(f"model file {mf}\nweights {a.model_dir}", flush=True) | |
| model = build(load_module(mf)) | |
| load_weights(model, a.model_dir) | |
| n = sum(q.numel() for q in model.parameters()) | |
| if a.cpu or not torch.cuda.is_available(): | |
| dev = torch.device("cpu") | |
| try: | |
| torch.backends.nnpack.set_flags(False) # silences "Could not initialize NNPACK" | |
| except Exception: | |
| pass | |
| if not a.cpu_bf16: | |
| fp32_blocks(model) | |
| print(f"⚠️ CPU: {n / 1e9:.1f}B params, compute {'bf16' if a.cpu_bf16 else 'fp32 blocks'} - " | |
| f"every token is a full forward pass, expect minutes per token. Ctrl+C stops the answer.") | |
| else: | |
| devs = [torch.device("cuda", i) for i in range(torch.cuda.device_count())] | |
| dev = place(model, devs) | |
| print(f"on {len(devs)} GPU(s): {n / 1e9:.1f}B params, " | |
| f"{[round(torch.cuda.memory_allocated(d) / 2 ** 30) for d in devs]} GB") | |
| system = open(a.system, encoding="utf-8").read().strip() if a.system else None | |
| think = not a.no_think | |
| history = [] | |
| print("\nReady. /reset - clear history, /think - thinking on/off, exit - quit") | |
| while True: | |
| try: | |
| user = input("\nYou: ").strip() | |
| except (EOFError, KeyboardInterrupt): | |
| break | |
| if not user: | |
| continue | |
| if user.lower() in ("exit", "quit"): | |
| break | |
| if user == "/reset": | |
| history = [] | |
| print("(history cleared)") | |
| continue | |
| if user == "/think": | |
| think = not think | |
| print(f"(thinking {'on' if think else 'off'})") | |
| continue | |
| history.append({"role": "user", "content": user}) | |
| msgs = ([{"role": "system", "content": system}] if system else []) + history | |
| ids = torch.tensor([tok.prompt_ids(msgs, think)], dtype=torch.long, device=dev) | |
| start = ids.shape[1] | |
| print("\nAssistant: ", end="", flush=True) | |
| printed, t0 = "", time.time() | |
| try: | |
| with torch.no_grad(): | |
| for _ in range(a.max_new): | |
| nxt = sample(logits_of(model(ids))[0, -1], a.temperature, a.top_p) | |
| if nxt in stop: | |
| break | |
| ids = torch.cat([ids, torch.tensor([[nxt]], device=ids.device)], dim=1) | |
| text = tok.decode(ids[0, start:].tolist()) | |
| if not text.endswith("�"): # wait for a complete UTF-8 character | |
| print(text[len(printed):], end="", flush=True) | |
| printed = text | |
| except KeyboardInterrupt: | |
| print(" [stopped]", end="") | |
| gen = ids.shape[1] - start | |
| raw = tok.decode(ids[0, start:].tolist()) | |
| print(f"\n [{gen} tokens, {gen / max(time.time() - t0, 1e-6):.2f} tok/s]") | |
| # Qwen: earlier turns go back into the history without the thinking part | |
| reply = raw.split("</think>")[-1] | |
| for t in tok.special: | |
| reply = reply.replace(t, "") | |
| history.append({"role": "assistant", "content": reply.strip()}) | |
| if __name__ == "__main__": | |
| main() | |