Instructions to use BernaLabs/berna-r8 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use BernaLabs/berna-r8 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="BernaLabs/berna-r8")# pip install -U transformers accelerate # Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("BernaLabs/berna-r8", device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use BernaLabs/berna-r8 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "BernaLabs/berna-r8" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "BernaLabs/berna-r8", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/BernaLabs/berna-r8
- SGLang
How to use BernaLabs/berna-r8 with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "BernaLabs/berna-r8" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "BernaLabs/berna-r8", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "BernaLabs/berna-r8" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "BernaLabs/berna-r8", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use BernaLabs/berna-r8 with Docker Model Runner:
docker model run hf.co/BernaLabs/berna-r8
Download code/cells/saturation.py from BernaLabs/berna-r8: direct link, hf CLI and curl.
- Browser
- Download file 8.3 kB
-
https://huggingface.co/BernaLabs/berna-r8/resolve/main/code/cells/saturation.py
- Command line
-
hf download hf://BernaLabs/berna-r8/code/cells/saturation.py
-
curl -L -o saturation.py https://huggingface.co/BernaLabs/berna-r8/resolve/main/code/cells/saturation.py
8.3 kB
| #!/usr/bin/env python3 | |
| """ | |
| R5-compliant saturation module. | |
| Cell = group of neurons in an MLP layer. | |
| 6D knowledge vector K = [L, W, H, D, T, E] | |
| Dimensions (per R5 paper, Section 3.4): | |
| K1 (L) - sequential coverage (long-range reach) | |
| K2 (W) - domain breadth (number of domains activated) [needs domain labels] | |
| K3 (H) - abstraction level (low entropy = focused) | |
| K4 (D) - reasoning depth (effective path length) [needs plexus graph] | |
| K5 (T) - temporal freshness (exponential decay by age) | |
| K6 (E) - encompassment (full facet coverage) [needs facets.json] | |
| S = ||K||_omega (weighted L2, omega in simplex) | |
| S* = 0.85 (split threshold), T_cons = 3 (consecutive steps) | |
| """ | |
| import json | |
| import math | |
| from dataclasses import dataclass, field, asdict | |
| from pathlib import Path | |
| from typing import Optional | |
| import numpy as np | |
| N_CELLS_PER_LAYER = 4 | |
| # R8 anti-explosion cap | |
| MAX_CELLS_TOTAL = 5000 | |
| S_STAR = 0.70 # R5 paper value; K6 now contributes 20% to S | |
| T_CONSECUTIVE = 3 | |
| DECAY_LAMBDA = 0.001 # for K5 (temporal freshness) | |
| class Cell: | |
| cell_id: str | |
| layer_idx: int | |
| neuron_start: int | |
| neuron_end: int | |
| K: list = field(default_factory=lambda: [0.0] * 6) | |
| omega: list = field(default_factory=lambda: [1/6] * 6) | |
| S: float = 0.0 | |
| S_history: list = field(default_factory=list) | |
| K_history: list = field(default_factory=list) # R8: K per measurement | |
| state: str = "active" | |
| splits: int = 0 | |
| parent_id: Optional[str] = None | |
| created_at: str = "" | |
| last_updated_step: int = 0 | |
| fp_history: list = field(default_factory=list) # recent pattern fingerprints | |
| pattern_sig: str = "" # dominant pattern signature | |
| last_split_step: int = 0 # cooldown tracking | |
| def num_neurons(self) -> int: | |
| return self.neuron_end - self.neuron_start | |
| def compute_K1_sequential_coverage(activations: np.ndarray) -> float: | |
| """ | |
| K1 (L): sequential coverage / long-range reach. | |
| activations: shape [seq_len, num_neurons] for ONE sample/cell. | |
| Returns: average normalized range of positions where neurons are active. | |
| High K1 = cell responds to tokens spread across long range. | |
| Low K1 = cell responds only to nearby tokens. | |
| """ | |
| if activations.size == 0: | |
| return 0.0 | |
| a = np.abs(np.asarray(activations, dtype=np.float32)) | |
| seq_len = a.shape[0] | |
| if seq_len < 2: | |
| return 0.0 | |
| # per-neuron: measure span between first and last activation | |
| active = a > a.mean(axis=0, keepdims=True) | |
| spans = [] | |
| for j in range(a.shape[1]): | |
| idx = np.where(active[:, j])[0] | |
| if len(idx) >= 2: | |
| spans.append((idx[-1] - idx[0]) / (seq_len - 1)) | |
| if not spans: | |
| return 0.0 | |
| return float(np.clip(np.mean(spans), 0.0, 1.0)) | |
| def compute_K3_abstraction(activations: np.ndarray) -> float: | |
| """ | |
| K3 (H): abstraction level — activation sparsity. | |
| FIX (2026-10-02): Entropy-based formula gives ~0 with dense swish activations. | |
| New formula: Gini-style sparsity = fraction of "concentration" in top neurons. | |
| A cell that fires on few neurons strongly = high K3 (abstraction). | |
| A cell that fires uniformly = low K3 (diffuse). | |
| """ | |
| if activations.size == 0: | |
| return 0.0 | |
| a = np.abs(np.asarray(activations, dtype=np.float32)) | |
| # mean activation per neuron | |
| p = a.mean(axis=0) | |
| n = len(p) | |
| if n < 2: | |
| return 1.0 | |
| total = p.sum() | |
| if total < 1e-9: | |
| return 0.0 | |
| # Gini coefficient: 0 = uniform, 1 = all concentrated in one | |
| p_sorted = np.sort(p) | |
| idx = np.arange(1, n + 1) | |
| gini = (2 * np.sum(idx * p_sorted)) / (n * total) - (n + 1) / n | |
| gini = float(np.clip(gini, 0.0, 1.0)) | |
| return gini | |
| def compute_K5_temporal_freshness( | |
| last_updated_step: int, | |
| current_step: int, | |
| decay_lambda: float = DECAY_LAMBDA, | |
| ) -> float: | |
| """ | |
| K5 (T): temporal freshness. | |
| Exponential decay by age. | |
| Recently-updated cells: K5 near 1. | |
| Old cells: K5 near 0. | |
| """ | |
| # FIX: if never measured (last_updated_step=0), treat as fresh (age=0) | |
| if last_updated_step == 0: | |
| return 1.0 | |
| age = max(0, current_step - last_updated_step) | |
| # FIX: cap age to avoid catastrophic decay (e.g. max 500 steps) | |
| age = min(age, 500) | |
| return float(math.exp(-decay_lambda * age)) | |
| def compute_K2_domain_breadth(activations: np.ndarray, domains=None) -> float: | |
| """K2 (W): domain breadth. TODO: needs domain labels per sample.""" | |
| return 0.0 | |
| def compute_K4_reasoning_depth(activations: np.ndarray, plexus=None) -> float: | |
| """K4 (D): reasoning depth. TODO: needs plexus graph.""" | |
| return 0.0 | |
| def compute_K6_encompassment(activations: np.ndarray, facets=None) -> float: | |
| """K6 (E): encompassment. TODO: needs facets.json taxonomy.""" | |
| return 0.0 | |
| def compute_S(K: list, omega: list) -> float: | |
| """ | |
| Weighted L2 norm of K over ACTIVE dimensions only. | |
| FIX (2026-10-02): With K2=K4=K6=0 (stubs), max possible S was 0.707 < S*=0.85. | |
| Renormalizing omega over non-zero K dims makes S in [0,1] again. | |
| When all 6 dims are implemented, this reduces to the original formula. | |
| """ | |
| k = np.asarray(K, dtype=np.float32) | |
| w_final = np.array([0.375, 0.0, 0.10, 0.0, 0.375, 0.15], dtype=np.float32) | |
| w_final = w_final / (w_final.sum() + 1e-9) | |
| return float(np.sqrt(np.sum(w_final * k * k))) | |
| def save_cells(cells: list, path: Path): | |
| path = Path(path) | |
| path.parent.mkdir(parents=True, exist_ok=True) | |
| path.write_text(json.dumps([asdict(c) for c in cells], indent=2)) | |
| return path | |
| def load_cells(path: Path) -> list: | |
| data = json.loads(Path(path).read_text()) | |
| cells = [] | |
| for d in data: | |
| # tolerate unknown fields | |
| try: | |
| cells.append(Cell(**d)) | |
| except TypeError: | |
| # strip unknown keys | |
| from dataclasses import fields | |
| valid = {f.name for f in fields(Cell)} | |
| filtered = {k: v for k, v in d.items() if k in valid} | |
| cells.append(Cell(**filtered)) | |
| return cells | |
| if __name__ == "__main__": | |
| a = np.random.randn(128, 1536).astype(np.float32) | |
| K1 = compute_K1_sequential_coverage(a) | |
| K3 = compute_K3_abstraction(a) | |
| K5 = compute_K5_temporal_freshness(0, 1000) | |
| print(f"K1 = {K1:.3f}") | |
| print(f"K3 = {K3:.3f}") | |
| print(f"K5 = {K5:.3f}") | |
| K = [K1, 0.0, K3, 0.0, K5, 0.0] | |
| print(f"S = {compute_S(K, [1/6]*6):.3f}") | |
| def load_facets(path=None) -> dict: | |
| """Load facets taxonomy from facets.json.""" | |
| if path is None: | |
| path = Path(__file__).parent / "facets.json" | |
| data = json.loads(Path(path).read_text()) | |
| return data.get("domains", {}) | |
| def compute_K6_encompassment_real( | |
| activated_facets=None, | |
| domain=None, | |
| facets_map=None, | |
| fp_history=None, | |
| similarity_threshold=0.7, | |
| ) -> float: | |
| """ | |
| K6 (E): encompassment — coverage of distinct knowledge patterns. | |
| Bottom-up design (2026-10-02): K6 grows when a cell responds to | |
| multiple distinct activation patterns over time. | |
| Logic: | |
| - Each pattern is a binary fingerprint of top-K neurons. | |
| - Count distinct patterns (by Hamming similarity < threshold). | |
| - K6 = min(1.0, distinct_patterns / TARGET_PATTERNS) | |
| - TARGET_PATTERNS = 5 (empirical; adjust if needed) | |
| """ | |
| if fp_history is None or len(fp_history) < 3: | |
| return 0.0 | |
| try: | |
| from cognitive_log import hamming_similarity | |
| except ImportError: | |
| import sys | |
| sys.path.insert(0, "/data/berna-r7/core/code") | |
| from cognitive_log import hamming_similarity | |
| TARGET = 5 | |
| unique = [] | |
| for fp in fp_history: | |
| is_new = True | |
| for u in unique: | |
| if hamming_similarity(fp, u) > similarity_threshold: | |
| is_new = False | |
| break | |
| if is_new: | |
| unique.append(fp) | |
| if len(unique) >= TARGET: | |
| return 1.0 | |
| return float(len(unique) / TARGET) | |
| def compute_K4_from_plexus(cell_id: str, plexus) -> float: | |
| """K4 (D) via plexus graph. Wrapper for plexus.compute_K4.""" | |
| if plexus is None: | |
| return 0.0 | |
| try: | |
| from .plexus import compute_K4 as _k4 | |
| return _k4(plexus, cell_id) | |
| except Exception: | |
| return 0.0 | |