Text Generation
Transformers
Safetensors
mini-beatrix
byte-level
tokenizer-free
aleph
signed-address
custom_code
Instructions to use AbstractPhil/mini-beatrix-1 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use AbstractPhil/mini-beatrix-1 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="AbstractPhil/mini-beatrix-1", trust_remote_code=True)# pip install -U transformers accelerate # Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("AbstractPhil/mini-beatrix-1", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use AbstractPhil/mini-beatrix-1 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "AbstractPhil/mini-beatrix-1" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "AbstractPhil/mini-beatrix-1", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/AbstractPhil/mini-beatrix-1
- SGLang
How to use AbstractPhil/mini-beatrix-1 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 "AbstractPhil/mini-beatrix-1" \ --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": "AbstractPhil/mini-beatrix-1", "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 "AbstractPhil/mini-beatrix-1" \ --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": "AbstractPhil/mini-beatrix-1", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use AbstractPhil/mini-beatrix-1 with Docker Model Runner:
docker model run hf.co/AbstractPhil/mini-beatrix-1
mirror alephllm 0.9.0 (same-session law): presets.py (AlephLMConfig.fusion field, default None; the v3 preset builder + registrations guarded for copies without the data stack), governor.py (raw_block), alephlm.py (the optional fusion stage imported lazily — unfused crafts load without model/fusion.py; the trunk loop factored into _trunk). Gated: strict load of model.safetensors through the vendored path, logits parity 0.0 vs geolip.
Browse files- alephlm.py +132 -9
alephlm.py
CHANGED
|
@@ -32,6 +32,8 @@ from .attention import CausalSDPA, CausalSplatHUB
|
|
| 32 |
from .bank import AnchoredBank
|
| 33 |
from .embedding import TrigramByteEmbedding, TokenEmbedding
|
| 34 |
from .head import DualHead
|
|
|
|
|
|
|
| 35 |
|
| 36 |
|
| 37 |
class Block(nn.Module):
|
|
@@ -94,6 +96,43 @@ class AlephLM(nn.Module):
|
|
| 94 |
self.nf = nn.LayerNorm(cfg.d_model)
|
| 95 |
self.head = DualHead(cfg.d_model, cfg.vocab_size, cfg.head_K,
|
| 96 |
cfg.head_D, cfg.tau, tied_weight=tied)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
|
| 98 |
def forward(self, idx=None, targets=None, disable_bank=False,
|
| 99 |
disable_hub=False, disable_head_aleph=False,
|
|
@@ -107,8 +146,7 @@ class AlephLM(nn.Module):
|
|
| 107 |
if idx is None:
|
| 108 |
idx = input_ids
|
| 109 |
x = self.embed(idx)
|
| 110 |
-
|
| 111 |
-
x = b(x, disable_bank=disable_bank, disable_hub=disable_hub)
|
| 112 |
h = self.nf(x)
|
| 113 |
logits = self.head(h, disable_aleph=disable_head_aleph)
|
| 114 |
if targets is not None: # pre-shifted (ours)
|
|
@@ -130,6 +168,8 @@ class AlephLM(nn.Module):
|
|
| 130 |
The cache carries per-layer attention state, the trigram history
|
| 131 |
bytes, and the absolute position cursor."""
|
| 132 |
self.eval()
|
|
|
|
|
|
|
| 133 |
from .embedding import PAD_ROW
|
| 134 |
caches = []
|
| 135 |
x = self.embed(idx)
|
|
@@ -143,26 +183,109 @@ class AlephLM(nn.Module):
|
|
| 143 |
return logits, {"layers": caches, "t": n,
|
| 144 |
"prev1": idx[:, -1], "prev2": prev2}
|
| 145 |
|
| 146 |
-
|
| 147 |
-
def decode_step(self, next_id, cache):
|
| 148 |
-
"""One token through the cached path. next_id: (B,) or (B,1)."""
|
| 149 |
-
next_id = next_id.reshape(-1)
|
| 150 |
-
t = cache["t"]
|
| 151 |
-
assert t < self.cfg.context, "decode exceeded the position table"
|
| 152 |
if isinstance(self.embed, TrigramByteEmbedding):
|
| 153 |
e = (self.embed.emb0(next_id) + self.embed.emb1(cache["prev1"])
|
| 154 |
+ self.embed.emb2(cache["prev2"])).unsqueeze(1) \
|
| 155 |
+ self.embed.pos[:, t:t + 1]
|
|
|
|
| 156 |
cache["prev2"] = cache["prev1"]
|
| 157 |
cache["prev1"] = next_id
|
| 158 |
else:
|
| 159 |
e = self.embed.emb(next_id).unsqueeze(1) + self.embed.pos[:, t:t + 1]
|
| 160 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
for b, c in zip(self.blocks, cache["layers"]):
|
| 162 |
x = b.step(x, c)
|
| 163 |
cache["t"] = t + 1
|
| 164 |
return self.head(self.nf(x))
|
| 165 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 166 |
@staticmethod
|
| 167 |
def _sample(logits, temperature, top_p):
|
| 168 |
logits = logits[:, -1].float()
|
|
|
|
| 32 |
from .bank import AnchoredBank
|
| 33 |
from .embedding import TrigramByteEmbedding, TokenEmbedding
|
| 34 |
from .head import DualHead
|
| 35 |
+
# model/fusion.py is imported lazily (only when a config asks for fusion),
|
| 36 |
+
# so a vendored copy of this file without it keeps loading unfused crafts.
|
| 37 |
|
| 38 |
|
| 39 |
class Block(nn.Module):
|
|
|
|
| 96 |
self.nf = nn.LayerNorm(cfg.d_model)
|
| 97 |
self.head = DualHead(cfg.d_model, cfg.vocab_size, cfg.head_K,
|
| 98 |
cfg.head_D, cfg.tau, tied_weight=tied)
|
| 99 |
+
# v3: weak-token fusion (model/fusion.py). None keeps the byte-
|
| 100 |
+
# resolution trunk verbatim; otherwise the middle blocks run over
|
| 101 |
+
# units and the front/back blocks stay at byte resolution.
|
| 102 |
+
spec = getattr(cfg, "fusion", None)
|
| 103 |
+
if spec:
|
| 104 |
+
from .fusion import Fusion
|
| 105 |
+
self.fusion = Fusion(spec, cfg.d_model)
|
| 106 |
+
else:
|
| 107 |
+
self.fusion = None
|
| 108 |
+
if self.fusion is not None:
|
| 109 |
+
assert self.fusion.k_lo + self.fusion.k_hi <= cfg.n_layers, \
|
| 110 |
+
"fusion: k_lo + k_hi must not exceed n_layers"
|
| 111 |
+
|
| 112 |
+
def _ranges(self):
|
| 113 |
+
L = len(self.blocks)
|
| 114 |
+
lo, hi = self.fusion.k_lo, L - self.fusion.k_hi
|
| 115 |
+
return self.blocks[:lo], self.blocks[lo:hi], self.blocks[hi:]
|
| 116 |
+
|
| 117 |
+
def _trunk(self, x, idx, disable_bank=False, disable_hub=False):
|
| 118 |
+
if self.fusion is None:
|
| 119 |
+
for b in self.blocks:
|
| 120 |
+
x = b(x, disable_bank=disable_bank, disable_hub=disable_hub)
|
| 121 |
+
return x
|
| 122 |
+
front, middle, back = self._ranges()
|
| 123 |
+
plan = self.fusion.plan(idx)
|
| 124 |
+
for b in front:
|
| 125 |
+
x = b(x, disable_bank=disable_bank, disable_hub=disable_hub)
|
| 126 |
+
if len(middle):
|
| 127 |
+
u = plan.pool(x)
|
| 128 |
+
for b in middle:
|
| 129 |
+
u = b(u, disable_bank=disable_bank, disable_hub=disable_hub)
|
| 130 |
+
x = x + plan.unpool(u, self.fusion.null)
|
| 131 |
+
else:
|
| 132 |
+
x = x + self.fusion.null.to(x.dtype)
|
| 133 |
+
for b in back:
|
| 134 |
+
x = b(x, disable_bank=disable_bank, disable_hub=disable_hub)
|
| 135 |
+
return x
|
| 136 |
|
| 137 |
def forward(self, idx=None, targets=None, disable_bank=False,
|
| 138 |
disable_hub=False, disable_head_aleph=False,
|
|
|
|
| 146 |
if idx is None:
|
| 147 |
idx = input_ids
|
| 148 |
x = self.embed(idx)
|
| 149 |
+
x = self._trunk(x, idx, disable_bank=disable_bank, disable_hub=disable_hub)
|
|
|
|
| 150 |
h = self.nf(x)
|
| 151 |
logits = self.head(h, disable_aleph=disable_head_aleph)
|
| 152 |
if targets is not None: # pre-shifted (ours)
|
|
|
|
| 168 |
The cache carries per-layer attention state, the trigram history
|
| 169 |
bytes, and the absolute position cursor."""
|
| 170 |
self.eval()
|
| 171 |
+
if self.fusion is not None:
|
| 172 |
+
return self._prefill_fused(idx)
|
| 173 |
from .embedding import PAD_ROW
|
| 174 |
caches = []
|
| 175 |
x = self.embed(idx)
|
|
|
|
| 183 |
return logits, {"layers": caches, "t": n,
|
| 184 |
"prev1": idx[:, -1], "prev2": prev2}
|
| 185 |
|
| 186 |
+
def _embed_step(self, next_id, cache, t):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 187 |
if isinstance(self.embed, TrigramByteEmbedding):
|
| 188 |
e = (self.embed.emb0(next_id) + self.embed.emb1(cache["prev1"])
|
| 189 |
+ self.embed.emb2(cache["prev2"])).unsqueeze(1) \
|
| 190 |
+ self.embed.pos[:, t:t + 1]
|
| 191 |
+
cache["prev3"] = cache.get("prev2")
|
| 192 |
cache["prev2"] = cache["prev1"]
|
| 193 |
cache["prev1"] = next_id
|
| 194 |
else:
|
| 195 |
e = self.embed.emb(next_id).unsqueeze(1) + self.embed.pos[:, t:t + 1]
|
| 196 |
+
return e
|
| 197 |
+
|
| 198 |
+
@torch.no_grad()
|
| 199 |
+
def decode_step(self, next_id, cache):
|
| 200 |
+
"""One token through the cached path. next_id: (B,) or (B,1)."""
|
| 201 |
+
next_id = next_id.reshape(-1)
|
| 202 |
+
t = cache["t"]
|
| 203 |
+
assert t < self.cfg.context, "decode exceeded the position table"
|
| 204 |
+
if self.fusion is not None:
|
| 205 |
+
return self._decode_step_fused(next_id, cache, t)
|
| 206 |
+
x = self._embed_step(next_id, cache, t)
|
| 207 |
for b, c in zip(self.blocks, cache["layers"]):
|
| 208 |
x = b.step(x, c)
|
| 209 |
cache["t"] = t + 1
|
| 210 |
return self.head(self.nf(x))
|
| 211 |
|
| 212 |
+
# ------------------------------------------------- fused decode path
|
| 213 |
+
@torch.no_grad()
|
| 214 |
+
def _prefill_fused(self, idx):
|
| 215 |
+
"""The prompt through the hourglass: front blocks at byte
|
| 216 |
+
resolution (batched), the middle over each row's COMPLETED units
|
| 217 |
+
(the last unit stays open until a later byte starts the next), the
|
| 218 |
+
back blocks at byte resolution. The middle's caches are merged
|
| 219 |
+
across rows (the hub's prefix state has one shape per row)."""
|
| 220 |
+
from .embedding import PAD_ROW
|
| 221 |
+
from .governor import raw_block
|
| 222 |
+
from .fusion import cat_caches, zero_cache_rows
|
| 223 |
+
front, middle, back = self._ranges()
|
| 224 |
+
for b in middle:
|
| 225 |
+
assert raw_block(b).is_hub, "fused decode needs hub blocks in the middle"
|
| 226 |
+
B, T = idx.shape
|
| 227 |
+
plan = self.fusion.plan(idx)
|
| 228 |
+
x = self.embed(idx)
|
| 229 |
+
front_c = []
|
| 230 |
+
for b in front:
|
| 231 |
+
x, c = b.prefill(x)
|
| 232 |
+
front_c.append(c)
|
| 233 |
+
x_front = x
|
| 234 |
+
u_all = plan.pool(x_front) # (B, J, d) incl. the open unit
|
| 235 |
+
n_closed = plan.n_units - 1
|
| 236 |
+
d = x.shape[-1]
|
| 237 |
+
v_pad = torch.zeros(B, plan.J, d, device=x.device, dtype=x.dtype)
|
| 238 |
+
mid_rows = []
|
| 239 |
+
for r in range(B):
|
| 240 |
+
nc = int(n_closed[r])
|
| 241 |
+
u = u_all[r:r + 1, :max(nc, 1)]
|
| 242 |
+
row_c = []
|
| 243 |
+
for b in middle:
|
| 244 |
+
u, c = b.prefill(u)
|
| 245 |
+
row_c.append(c)
|
| 246 |
+
if nc > 0:
|
| 247 |
+
v_pad[r, :nc] = u[0]
|
| 248 |
+
mid_rows.append(row_c)
|
| 249 |
+
mid_c = [cat_caches([row[i] for row in mid_rows]) for i in range(len(middle))]
|
| 250 |
+
empty = n_closed == 0
|
| 251 |
+
if bool(empty.any()):
|
| 252 |
+
mid_c = [zero_cache_rows(c, empty) for c in mid_c]
|
| 253 |
+
g = plan.unpool(v_pad, self.fusion.null) # (B, T, d)
|
| 254 |
+
x = x_front + g
|
| 255 |
+
back_c = []
|
| 256 |
+
for b in back:
|
| 257 |
+
x, c = b.prefill(x)
|
| 258 |
+
back_c.append(c)
|
| 259 |
+
logits = self.head(self.nf(x)[:, -1:])
|
| 260 |
+
pad = lambda k: idx[:, -k] if T >= k else torch.full_like(idx[:, -1], PAD_ROW) # noqa: E731
|
| 261 |
+
return logits, {"front": front_c, "mid": mid_c, "back": back_c, "t": T,
|
| 262 |
+
"prev1": idx[:, -1], "prev2": pad(2), "prev3": pad(3),
|
| 263 |
+
"front_last": x_front[:, -1], "g": g[:, -1]}
|
| 264 |
+
|
| 265 |
+
@torch.no_grad()
|
| 266 |
+
def _decode_step_fused(self, next_id, cache, t):
|
| 267 |
+
from .embedding import PAD_ROW
|
| 268 |
+
from .fusion import snapshot, restore_rows
|
| 269 |
+
front, middle, back = self._ranges()
|
| 270 |
+
prev1, prev2, prev3 = cache["prev1"], cache["prev2"], cache["prev3"]
|
| 271 |
+
st = self.fusion.starts_step(next_id, prev1, prev2, prev3, PAD_ROW) # (B,) closes the open unit
|
| 272 |
+
if bool(st.any()) and len(middle):
|
| 273 |
+
u = cache["front_last"].unsqueeze(1)
|
| 274 |
+
for b, c in zip(middle, cache["mid"]):
|
| 275 |
+
old = snapshot(c)
|
| 276 |
+
u = b.step(u, c)
|
| 277 |
+
restore_rows(c, old, st)
|
| 278 |
+
cache["g"] = torch.where(st.unsqueeze(-1), u[:, 0], cache["g"])
|
| 279 |
+
x = self._embed_step(next_id, cache, t)
|
| 280 |
+
for b, c in zip(front, cache["front"]):
|
| 281 |
+
x = b.step(x, c)
|
| 282 |
+
cache["front_last"] = x[:, 0]
|
| 283 |
+
x = x + cache["g"].unsqueeze(1)
|
| 284 |
+
for b, c in zip(back, cache["back"]):
|
| 285 |
+
x = b.step(x, c)
|
| 286 |
+
cache["t"] = t + 1
|
| 287 |
+
return self.head(self.nf(x))
|
| 288 |
+
|
| 289 |
@staticmethod
|
| 290 |
def _sample(logits, temperature, top_p):
|
| 291 |
logits = logits[:, -1].float()
|