Instructions to use hipinis/20260718 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 hipinis/20260718 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 hipinis/20260718:Q8_0 # Run inference directly in the terminal: llama cli -hf hipinis/20260718:Q8_0
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf hipinis/20260718:Q8_0 # Run inference directly in the terminal: llama cli -hf hipinis/20260718: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 hipinis/20260718:Q8_0 # Run inference directly in the terminal: ./llama-cli -hf hipinis/20260718: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 hipinis/20260718:Q8_0 # Run inference directly in the terminal: ./build/bin/llama-cli -hf hipinis/20260718:Q8_0
Use Docker
docker model run hf.co/hipinis/20260718:Q8_0
- LM Studio
- Jan
- Ollama
How to use hipinis/20260718 with Ollama:
ollama run hf.co/hipinis/20260718:Q8_0
- Unsloth Studio
How to use hipinis/20260718 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 hipinis/20260718 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 hipinis/20260718 to start chatting
Using HuggingFace Spaces for Unsloth
# No setup required # Open https://huggingface.co/spaces/unsloth/studio in your browser # Search for hipinis/20260718 to start chatting
- Pi
How to use hipinis/20260718 with Pi:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf hipinis/20260718: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": "hipinis/20260718:Q8_0" } ] } } }Run Pi
# Start Pi in your project directory: pi
- OpenClaw new
How to use hipinis/20260718 with OpenClaw:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf hipinis/20260718: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 "hipinis/20260718: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 hipinis/20260718 with Docker Model Runner:
docker model run hf.co/hipinis/20260718:Q8_0
- Lemonade
How to use hipinis/20260718 with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull hipinis/20260718:Q8_0
Run and chat with the model
lemonade run user.20260718-Q8_0
List all available models
lemonade list
- Hermes Agent
How to use hipinis/20260718 with Hermes Agent:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf hipinis/20260718: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 hipinis/20260718:Q8_0
Run Hermes
hermes
- Atomic Chat
| import base64 | |
| import hashlib | |
| import os | |
| import sys | |
| import threading | |
| from collections import OrderedDict | |
| from concurrent.futures import ThreadPoolExecutor, as_completed | |
| from io import BytesIO | |
| from typing import Callable, Dict, List, Optional, Tuple | |
| import time | |
| import numpy as np | |
| import torch | |
| from PIL import Image, ImageDraw, ImageFont | |
| import comfy.model_management | |
| MODULE_DIR = os.path.dirname(os.path.abspath(__file__)) | |
| if MODULE_DIR not in sys.path: | |
| sys.path.insert(0, MODULE_DIR) | |
| from logger import logger | |
| class ImageCodec: | |
| """负责 Tensor/Base64 转换、缓存与实时预览构建。""" | |
| def __init__( | |
| self, | |
| logger_instance=logger, | |
| ensure_not_interrupted: Optional[Callable[[], None]] = None, | |
| cache_size: int = 16, | |
| ): | |
| self.logger = logger_instance | |
| self.ensure_not_interrupted = ensure_not_interrupted | |
| self._image_cache: "OrderedDict[str, str]" = OrderedDict() | |
| self._cache_lock = threading.Lock() | |
| self._cache_size = max(1, cache_size) | |
| def _maybe_interrupt(self): | |
| if self.ensure_not_interrupted: | |
| self.ensure_not_interrupted() | |
| def _tensor_cache_key( | |
| self, | |
| tensor: Optional[torch.Tensor] = None, | |
| np_data: Optional[np.ndarray] = None, | |
| ) -> Optional[str]: | |
| if tensor is None and np_data is None: | |
| return None | |
| try: | |
| target = np_data | |
| if target is None: | |
| target = tensor.detach().cpu().numpy() | |
| return hashlib.sha1(target.tobytes()).hexdigest() | |
| except Exception: | |
| return None | |
| def _get_cached_image_b64(self, cache_key: Optional[str]) -> Optional[str]: | |
| if not cache_key: | |
| return None | |
| with self._cache_lock: | |
| value = self._image_cache.get(cache_key) | |
| if value is not None: | |
| self._image_cache.move_to_end(cache_key) | |
| return value | |
| def _set_cached_image_b64(self, cache_key: Optional[str], value: str) -> None: | |
| if not cache_key or not value: | |
| return | |
| with self._cache_lock: | |
| self._image_cache[cache_key] = value | |
| self._image_cache.move_to_end(cache_key) | |
| while len(self._image_cache) > self._cache_size: | |
| self._image_cache.popitem(last=False) | |
| def extract_numpy_images(self, tensor: torch.Tensor) -> List[np.ndarray]: | |
| images: List[np.ndarray] = [] | |
| if tensor is None: | |
| return images | |
| try: | |
| np_data = tensor.detach().cpu().numpy() | |
| except Exception as exc: | |
| self.logger.error(f"输入图像转换失败: {exc}") | |
| return images | |
| if np_data.ndim == 3: | |
| np_data = np_data[np.newaxis, ...] | |
| np_data = np.clip(np_data, 0.0, 1.0) | |
| for sample in np_data: | |
| if sample.ndim == 2: | |
| sample = np.expand_dims(sample, axis=-1) | |
| if sample.shape[-1] == 1: | |
| sample = np.repeat(sample, 3, axis=-1) | |
| images.append(np.ascontiguousarray(sample)) | |
| return images | |
| def tensor_to_base64( | |
| self, | |
| tensor: Optional[torch.Tensor] = None, | |
| np_image: Optional[np.ndarray] = None, | |
| ) -> str: | |
| if np_image is None: | |
| if tensor is None: | |
| raise ValueError("必须提供 tensor 或 numpy 图像数据用于编码") | |
| samples = self.extract_numpy_images(tensor) | |
| if not samples: | |
| raise ValueError("无法从 tensor 中提取有效图像数据") | |
| np_image = samples[0] | |
| img_array = np.clip(np_image, 0.0, 1.0) | |
| img_uint8 = (img_array * 255).astype(np.uint8) | |
| img = Image.fromarray(img_uint8) | |
| buffered = BytesIO() | |
| img.save(buffered, format="PNG") | |
| return base64.b64encode(buffered.getvalue()).decode() | |
| def prepare_input_images(self, tensors: List[torch.Tensor]) -> List[str]: | |
| if not tensors: | |
| return [] | |
| encoded_images: List[str] = [] | |
| for tensor in tensors: | |
| if tensor is None: | |
| continue | |
| for sample in self.extract_numpy_images(tensor): | |
| cache_key = self._tensor_cache_key(np_data=sample) | |
| cached_value = self._get_cached_image_b64(cache_key) | |
| if cached_value is None: | |
| base64_value = self.tensor_to_base64(np_image=sample) | |
| self._set_cached_image_b64(cache_key, base64_value) | |
| else: | |
| base64_value = cached_value | |
| encoded_images.append(base64_value) | |
| return encoded_images | |
| def base64_to_tensor_single(self, b64_str: str) -> np.ndarray: | |
| try: | |
| img_data = base64.b64decode(b64_str) | |
| img = Image.open(BytesIO(img_data)).convert('RGB') | |
| img_array = np.array(img).astype(np.float32) / 255.0 | |
| return img_array | |
| except Exception as exc: | |
| self.logger.error(f"图片解码失败: {exc}") | |
| return np.zeros((64, 64, 3), dtype=np.float32) | |
| def base64_to_tensor_parallel( | |
| self, | |
| base64_strings: List[str], | |
| log_prefix: Optional[str] = None, | |
| max_workers: Optional[int] = None, | |
| ) -> torch.Tensor: | |
| if not isinstance(base64_strings, list) or len(base64_strings) == 0: | |
| return torch.zeros((1, 64, 64, 3), dtype=torch.float32) | |
| decode_start = time.time() | |
| images = [] | |
| worker_cap = max_workers if max_workers is not None else max(4, os.cpu_count() or 1) | |
| worker_cap = max(1, worker_cap) | |
| effective_workers = min(worker_cap, len(base64_strings)) | |
| self._maybe_interrupt() | |
| executor = ThreadPoolExecutor(max_workers=effective_workers) | |
| try: | |
| future_to_index = {executor.submit(self.base64_to_tensor_single, b64): i | |
| for i, b64 in enumerate(base64_strings)} | |
| results = [None] * len(base64_strings) | |
| try: | |
| for future in as_completed(future_to_index): | |
| index = future_to_index[future] | |
| try: | |
| self._maybe_interrupt() | |
| results[index] = future.result() | |
| except comfy.model_management.InterruptProcessingException: | |
| for pending in future_to_index: | |
| pending.cancel() | |
| raise | |
| except Exception as exc: | |
| self.logger.error(f"图片{index+1}解码异常: {exc}") | |
| results[index] = np.zeros((64, 64, 3), dtype=np.float32) | |
| images = [r for r in results if r is not None] | |
| except comfy.model_management.InterruptProcessingException: | |
| executor.shutdown(wait=False, cancel_futures=True) | |
| raise | |
| finally: | |
| if not executor._shutdown: | |
| executor.shutdown(wait=False, cancel_futures=True) | |
| decode_time = time.time() - decode_start | |
| prefix = log_prefix or "" | |
| prefix = f"{prefix} " if prefix else "" | |
| self.logger.success(f"{prefix}并发解码 {len(images)} 张图片完成,耗时: {decode_time:.2f}s") | |
| return torch.from_numpy(np.stack(images)) | |
| def build_preview_tuple( | |
| self, | |
| tensor: Optional[torch.Tensor], | |
| batch_index: int, | |
| max_size: int = 512, | |
| ) -> Optional[Tuple[str, Image.Image, int]]: | |
| if tensor is None or tensor.shape[0] == 0: | |
| return None | |
| try: | |
| preview_tensor = tensor[0].detach().cpu() | |
| preview_tensor = torch.clamp(preview_tensor, 0.0, 1.0) | |
| preview_array = (preview_tensor.numpy() * 255).astype(np.uint8) | |
| if preview_array.ndim == 3 and preview_array.shape[2] == 1: | |
| preview_array = np.repeat(preview_array, 3, axis=2) | |
| elif preview_array.ndim == 2: | |
| preview_array = np.stack([preview_array] * 3, axis=2) | |
| preview_image = Image.fromarray(preview_array) | |
| return ("PNG", preview_image, max_size) | |
| except Exception as exc: | |
| self.logger.error(f"实时预览生成失败: 批次 {batch_index + 1}: {str(exc)[:80]}") | |
| return None | |
| class ErrorCanvas: | |
| """统一的错误画布与字体管理。""" | |
| def __init__(self, logger_instance=logger): | |
| self.logger = logger_instance | |
| self._font_cache: Dict[int, ImageFont.ImageFont] = {} | |
| def _get_error_font_paths(self) -> List[str]: | |
| candidates = [] | |
| windir = os.environ.get("WINDIR") | |
| if windir: | |
| for name in ("msyh.ttc", "msyh.ttf", "msjh.ttc", "simhei.ttf", "msmincho.ttc"): | |
| candidates.append(os.path.join(windir, "Fonts", name)) | |
| candidates.append(os.path.join(os.path.dirname(__file__), "msyh.ttc")) | |
| return candidates | |
| def _load_error_font(self, size: int) -> ImageFont.ImageFont: | |
| cached = self._font_cache.get(size) | |
| if cached is not None: | |
| return cached | |
| for font_path in self._get_error_font_paths(): | |
| if font_path and os.path.exists(font_path): | |
| try: | |
| font = ImageFont.truetype(font_path, size) | |
| self._font_cache[size] = font | |
| return font | |
| except Exception: | |
| continue | |
| fallback = ImageFont.load_default() | |
| self._font_cache[size] = fallback | |
| return fallback | |
| def _wrap_text_segments(draw: ImageDraw.ImageDraw, text: str, | |
| font: ImageFont.ImageFont, max_width: int) -> List[str]: | |
| if not text: | |
| return [""] | |
| segments: List[str] = [] | |
| current = "" | |
| for ch in text: | |
| tentative = current + ch | |
| if draw.textlength(tentative, font=font) <= max_width or not current: | |
| current = tentative | |
| else: | |
| segments.append(current) | |
| current = ch | |
| if current: | |
| segments.append(current) | |
| return segments | |
| def build_error_image_tensor( | |
| self, | |
| title: str, | |
| lines: List[str], | |
| size: Tuple[int, int] = (640, 640), | |
| ) -> torch.Tensor: | |
| lines = [line.strip() for line in lines if line and line.strip()] | |
| if not lines: | |
| lines = ["发生未知错误"] | |
| width, height = size | |
| background = (248, 248, 248) | |
| accent = (255, 235, 235) | |
| title_color = (180, 30, 30) | |
| text_color = (45, 45, 45) | |
| img = Image.new("RGB", (width, height), background) | |
| draw = ImageDraw.Draw(img) | |
| font_title = self._load_error_font(26) | |
| font_body = self._load_error_font(18) | |
| margin = 32 | |
| y = margin | |
| max_text_width = max(10, width - 2 * margin) | |
| max_y = height - margin | |
| draw.rectangle([margin - 6, margin - 6, width - margin + 6, y + 40], fill=accent) | |
| draw.text((margin, y), title, fill=title_color, font=font_title) | |
| y += font_title.getbbox(title)[3] - font_title.getbbox(title)[1] + 16 | |
| for line in lines: | |
| wrapped = self._wrap_text_segments(draw, line, font_body, max_text_width) | |
| for seg in wrapped: | |
| bbox = font_body.getbbox(seg) | |
| line_height = bbox[3] - bbox[1] + 6 | |
| if y + line_height > max_y: | |
| break | |
| draw.text((margin, y), seg, fill=text_color, font=font_body) | |
| y += line_height | |
| arr = np.array(img).astype(np.float32) / 255.0 | |
| return torch.from_numpy(arr).unsqueeze(0) | |
| def build_error_tensor_from_text(self, title: str, text: str) -> torch.Tensor: | |
| normalized = text.replace("\r\n", "\n").replace("\r", "\n") | |
| lines = [line.strip() for line in normalized.split("\n") if line.strip()] | |
| if not lines: | |
| lines = ["发生未知错误"] | |
| return self.build_error_image_tensor(title, lines) | |