Text Generation
Transformers
Safetensors
English
bard
feature-extraction
interactive-fiction
text-adventure
storytelling
custom_code
Instructions to use lowerkey/bard-small with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use lowerkey/bard-small with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="lowerkey/bard-small", trust_remote_code=True)# pip install -U transformers accelerate # Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("lowerkey/bard-small", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use lowerkey/bard-small with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "lowerkey/bard-small" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "lowerkey/bard-small", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/lowerkey/bard-small
- SGLang
How to use lowerkey/bard-small 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 "lowerkey/bard-small" \ --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": "lowerkey/bard-small", "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 "lowerkey/bard-small" \ --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": "lowerkey/bard-small", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use lowerkey/bard-small with Docker Model Runner:
docker model run hf.co/lowerkey/bard-small
Download bard_core.py from lowerkey/bard-small: direct link, hf CLI and curl.
- Browser
- Download file 16.6 kB
-
https://huggingface.co/lowerkey/bard-small/resolve/main/bard_core.py
- Command line
-
hf download hf://lowerkey/bard-small/bard_core.py
-
curl -L -o bard_core.py https://huggingface.co/lowerkey/bard-small/resolve/main/bard_core.py
16.6 kB
| """The network of bard-small.""" | |
| import re | |
| import math | |
| import time | |
| from functools import lru_cache | |
| import torch | |
| from torch import nn | |
| from torch.nn import functional as F | |
| try: | |
| from torch.nn.attention.flex_attention import create_block_mask, flex_attention | |
| except ImportError: # pragma: no cover | |
| create_block_mask = flex_attention = None | |
| from torch.utils.checkpoint import checkpoint | |
| def sliding_window_block_mask(T: int, window: int, device: str): | |
| def mask_mod(b, h, q_idx, kv_idx): | |
| causal = q_idx >= kv_idx | |
| in_window = (q_idx - kv_idx) < window | |
| return causal & in_window | |
| return create_block_mask(mask_mod, B=None, H=None, Q_LEN=T, KV_LEN=T, device=device) | |
| def apply_rope(x, base=10000.0, offset=0): | |
| T, D = x.shape[-2], x.shape[-1] | |
| inv_freq = base ** (-torch.arange(0, D, 2, device=x.device, dtype=torch.float32) / D) | |
| ang = torch.arange(offset, offset + T, device=x.device, dtype=torch.float32)[:, None] * inv_freq | |
| cos, sin = ang.cos().to(x.dtype), ang.sin().to(x.dtype) | |
| x1, x2 = x[..., : D // 2], x[..., D // 2:] | |
| return torch.cat([x1 * cos - x2 * sin, x1 * sin + x2 * cos], dim=-1) | |
| class LayerKV: | |
| def __init__(self, window): | |
| self.window = window | |
| self.k = self.v = None | |
| self.lo = self.hi = 0 | |
| self.start = 0 | |
| def append(self, k, v): | |
| T = k.shape[2] | |
| if self.k is None: | |
| cap = max(64, 2 * T) | |
| self.k = k.new_empty(k.shape[:2] + (cap,) + k.shape[3:]) | |
| self.v = v.new_empty(self.k.shape) | |
| elif self.hi + T > self.k.shape[2]: | |
| live = self.hi - self.lo | |
| cap = self.k.shape[2] | |
| if live + T > cap // 2: | |
| cap = 2 * (live + T) | |
| k_buf = self.k.new_empty(self.k.shape[:2] + (cap,) + self.k.shape[3:]) | |
| v_buf = self.v.new_empty(k_buf.shape) | |
| k_buf[:, :, :live] = self.k[:, :, self.lo:self.hi] | |
| v_buf[:, :, :live] = self.v[:, :, self.lo:self.hi] | |
| self.k, self.v, self.lo, self.hi = k_buf, v_buf, 0, live | |
| self.k[:, :, self.hi:self.hi + T] = k | |
| self.v[:, :, self.hi:self.hi + T] = v | |
| self.hi += T | |
| return self.k[:, :, self.lo:self.hi], self.v[:, :, self.lo:self.hi], self.start | |
| def trim(self): | |
| if self.window is not None and self.hi - self.lo > self.window - 1: | |
| drop = self.hi - self.lo - (self.window - 1) | |
| self.lo += drop | |
| self.start += drop | |
| class KVCache: | |
| def __init__(self, transformer): | |
| self.windows = [block.window for block in transformer.blocks] | |
| self.reset() | |
| def reset(self): | |
| self.layers = [LayerKV(w) for w in self.windows] | |
| self.pos = 0 | |
| def __len__(self): | |
| return self.pos | |
| def attend(q, k, v, rope, window, block_mask, cache=None, pos=0): | |
| if cache is None: | |
| if rope: | |
| q, k = apply_rope(q), apply_rope(k) | |
| if block_mask is None: | |
| return F.scaled_dot_product_attention(q, k, v, is_causal=True) | |
| return flex_attention(q, k, v, block_mask=block_mask) | |
| T = q.shape[2] | |
| if rope: | |
| q, k = apply_rope(q, offset=pos), apply_rope(k, offset=pos) | |
| k_all, v_all, k_start = cache.append(k, v) | |
| S = k_all.shape[2] | |
| if T == 1 and (window is None or S <= window): | |
| out = F.scaled_dot_product_attention(q, k_all, v_all) | |
| elif S == T and (window is None or T <= window): | |
| out = F.scaled_dot_product_attention(q, k_all, v_all, is_causal=True) | |
| else: | |
| q_pos = torch.arange(pos, pos + T, device=q.device)[:, None] | |
| k_pos = torch.arange(k_start, k_start + S, device=q.device)[None, :] | |
| mask = k_pos <= q_pos | |
| if window is not None: | |
| mask = mask & (q_pos - k_pos < window) | |
| out = F.scaled_dot_product_attention(q, k_all, v_all, attn_mask=mask) | |
| cache.trim() | |
| return out | |
| class Attention(nn.Module): | |
| def __init__(self, d_model, heads, window=None, rope=False): | |
| super().__init__() | |
| assert d_model % heads == 0 | |
| self.d_model = d_model | |
| self.heads = heads | |
| self.head_dim = d_model // heads | |
| self.window = window | |
| self.rope = rope | |
| self.qkvg = nn.Linear(d_model, 4 * d_model, bias=False) | |
| self.out = nn.Linear(d_model, d_model, bias=False) | |
| self.qnorm = nn.RMSNorm(self.head_dim) | |
| self.knorm = nn.RMSNorm(self.head_dim) | |
| def forward(self, x, block_mask=None, cache=None, pos=0): | |
| B, T, E = x.shape | |
| H, D = self.heads, self.head_dim | |
| q, k, v, g = self.qkvg(x).split(self.d_model, dim=-1) | |
| q = self.qnorm(q.view(B, T, H, D)).transpose(1, 2) | |
| k = self.knorm(k.view(B, T, H, D)).transpose(1, 2) | |
| v = v.view(B, T, H, D).transpose(1, 2) | |
| out = attend(q, k, v, self.rope, self.window, block_mask, cache, pos) | |
| out = out.transpose(1, 2).reshape(B, T, E) | |
| out = out * torch.sigmoid(g) | |
| return self.out(out) | |
| class FFN(nn.Module): | |
| def __init__(self, d_model, expansion=4, match_naive_params=True): | |
| super().__init__() | |
| hidden = d_model * expansion | |
| if match_naive_params: | |
| hidden = int(hidden * 2 / 3) | |
| hidden = max(128, (hidden // 128) * 128) | |
| self.hidden = hidden | |
| self.W_gate_up = nn.Linear(d_model, 2 * hidden, bias=False) | |
| self.W_down = nn.Linear(hidden, d_model, bias=False) | |
| def forward(self, x): | |
| gate, value = self.W_gate_up(x).chunk(2, dim=-1) | |
| return self.W_down(F.silu(gate) * value) | |
| class Block(nn.Module): | |
| def __init__(self, d_model, heads, ffn_expansion=4, window=None, rope=False): | |
| super().__init__() | |
| self.attn = Attention(d_model, heads, window, rope) | |
| self.ffn = FFN(d_model, ffn_expansion) | |
| self.norm1 = nn.RMSNorm(d_model) | |
| self.norm2 = nn.RMSNorm(d_model) | |
| def window(self): | |
| return self.attn.window | |
| def forward(self, x, block_mask=None, cache=None, pos=0): | |
| x = x + self.attn(self.norm1(x), block_mask, cache, pos) | |
| x = x + self.ffn(self.norm2(x)) | |
| return x | |
| class ParallelBlock(nn.Module): | |
| def __init__(self, d_model, heads, ffn_expansion=4, window=None, rope=False): | |
| super().__init__() | |
| assert d_model % heads == 0 | |
| self.d_model, self.heads, self.head_dim = d_model, heads, d_model // heads | |
| self.window = window | |
| self.rope = rope | |
| hidden = int(d_model * ffn_expansion * 2 / 3) | |
| self.hidden = max(128, (hidden // 128) * 128) | |
| self.norm = nn.RMSNorm(d_model) | |
| self.W_in = nn.Linear(d_model, 4 * d_model + 2 * self.hidden, bias=False) | |
| self.W_out = nn.Linear(d_model + self.hidden, d_model, bias=False) | |
| self.qnorm = nn.RMSNorm(self.head_dim) | |
| self.knorm = nn.RMSNorm(self.head_dim) | |
| def forward(self, x, block_mask=None, cache=None, pos=0): | |
| B, T, E = x.shape | |
| H, D = self.heads, self.head_dim | |
| q, k, v, g, gate, up = self.W_in(self.norm(x)).split( | |
| [E, E, E, E, self.hidden, self.hidden], dim=-1) | |
| q = self.qnorm(q.view(B, T, H, D)).transpose(1, 2) | |
| k = self.knorm(k.view(B, T, H, D)).transpose(1, 2) | |
| v = v.view(B, T, H, D).transpose(1, 2) | |
| a = attend(q, k, v, self.rope, self.window, block_mask, cache, pos) | |
| a = a.transpose(1, 2).reshape(B, T, E) * torch.sigmoid(g) | |
| f = F.silu(gate) * up | |
| return x + self.W_out(torch.cat([a, f], dim=-1)) | |
| def _init_weights(module): | |
| if isinstance(module, nn.Linear): | |
| nn.init.normal_(module.weight, mean=0.0, std=0.02) | |
| if module.bias is not None: | |
| nn.init.zeros_(module.bias) | |
| class CausalTransformer(nn.Module): | |
| def __init__( | |
| self, | |
| d_model: int, | |
| heads: int, | |
| n_blocks: int, | |
| ffn_expansion: int = 4, | |
| window: int = 1024, | |
| global_every: int = 4, | |
| grad_checkpoint: bool = True, | |
| compile_blocks: bool = True, | |
| parallel: bool = False, | |
| rope: str = "local", | |
| ): | |
| super().__init__() | |
| self.grad_checkpoint = grad_checkpoint | |
| windows = [] | |
| for i in range(n_blocks): | |
| is_global = ((i + 1) % global_every == 0) or (i == n_blocks - 1) | |
| windows.append(None if is_global else window) | |
| self.windows = windows | |
| block_cls = ParallelBlock if parallel else Block | |
| self.blocks = nn.ModuleList( | |
| [block_cls(d_model, heads, ffn_expansion, w, | |
| rope=(rope == "all" or (rope == "local" and w is not None))) | |
| for w in windows] | |
| ) | |
| self.norm = nn.RMSNorm(d_model) | |
| self.apply(_init_weights) | |
| residual_std = 0.02 / math.sqrt(2 * n_blocks) | |
| for block in self.blocks: | |
| if parallel: | |
| nn.init.normal_(block.W_out.weight, mean=0.0, std=residual_std) | |
| else: | |
| nn.init.normal_(block.attn.out.weight, mean=0.0, std=residual_std) | |
| nn.init.normal_(block.ffn.W_down.weight, mean=0.0, std=residual_std) | |
| if compile_blocks: | |
| for block in self.blocks: | |
| block.compile() | |
| def block_masks(self, T, device): | |
| return { | |
| w: sliding_window_block_mask(T, w, str(device)) | |
| for w in set(self.windows) | |
| if w is not None and w < T | |
| } | |
| cache_offset = 0 | |
| """While a cached forward runs: the absolute position of x[:, 0] (hooks that index | |
| positions, like steering, need it). 0 otherwise.""" | |
| def forward(self, x, masks=None, cache=None): | |
| if cache is not None: | |
| pos = cache.pos | |
| self.cache_offset = pos | |
| try: | |
| for block, layer_cache in zip(self.blocks, cache.layers): | |
| x = block(x, None, layer_cache, pos) | |
| finally: | |
| self.cache_offset = 0 | |
| cache.pos += x.shape[1] | |
| return self.norm(x) | |
| if masks is None: | |
| masks = self.block_masks(x.shape[1], x.device) | |
| for block in self.blocks: | |
| m = masks.get(block.window) | |
| if self.grad_checkpoint and self.training: | |
| x = checkpoint(block, x, m, use_reentrant=False) | |
| else: | |
| x = block(x, m) | |
| return self.norm(x) | |
| MAX_DIGITS = 8 | |
| LEN_SHIFT = 27 | |
| VALUE_MASK = (1 << LEN_SHIFT) - 1 | |
| NUMBER_RE = re.compile(r"( ?)([0-9]+)") | |
| def pack(digits: str) -> int: | |
| assert 0 < len(digits) <= MAX_DIGITS | |
| return int(digits) | (len(digits) << LEN_SHIFT) | |
| def unpack(packed: int) -> str: | |
| return str(packed & VALUE_MASK).zfill(packed >> LEN_SHIFT) | |
| def split_numbers(text): | |
| out, pos = [], 0 | |
| for m in NUMBER_RE.finditer(text): | |
| if m.start() > pos: | |
| out.append(text[pos:m.start()]) | |
| spaced, digits = bool(m.group(1)), m.group(2) | |
| for i in range(0, len(digits), MAX_DIGITS): | |
| out.append((spaced and i == 0, pack(digits[i:i + MAX_DIGITS]))) | |
| pos = m.end() | |
| if pos < len(text): | |
| out.append(text[pos:]) | |
| return out | |
| def _lengths_values(packed): | |
| packed = packed.long() | |
| return packed >> LEN_SHIFT, packed & VALUE_MASK | |
| def _pow10(n, device): | |
| return 10 ** torch.arange(n, device=device, dtype=torch.long) | |
| class NumberEncoder(nn.Module): | |
| def __init__(self, d_model, n_freq=4): | |
| super().__init__() | |
| self.n_freq = n_freq | |
| n_feat = MAX_DIGITS * (2 * n_freq + 1) + MAX_DIGITS + 1 | |
| self.mlp = nn.Sequential(nn.Linear(n_feat, d_model), nn.SiLU(), nn.Linear(d_model, d_model)) | |
| for m in self.mlp: | |
| if isinstance(m, nn.Linear): | |
| nn.init.normal_(m.weight, std=0.02) | |
| nn.init.zeros_(m.bias) | |
| def forward(self, packed): | |
| L, value = _lengths_values(packed) | |
| digits = value.unsqueeze(-1) // _pow10(MAX_DIGITS, packed.device) % 10 | |
| present = (torch.arange(MAX_DIGITS, device=packed.device) < L.unsqueeze(-1)).float() | |
| freqs = torch.arange(1, self.n_freq + 1, dtype=torch.float32, device=packed.device) | |
| angle = 2 * math.pi * digits.float().unsqueeze(-1) / 10 * freqs | |
| places = torch.cat([angle.sin(), angle.cos()], -1) * present.unsqueeze(-1) | |
| feats = torch.cat([ | |
| places.flatten(-2), | |
| present, | |
| F.one_hot((L - 1).clamp(min=0), MAX_DIGITS).float() * (L > 0).unsqueeze(-1), | |
| (torch.log10(value.float() + 1) / MAX_DIGITS).unsqueeze(-1), | |
| ], -1) | |
| out = self.mlp(feats.to(self.mlp[0].weight.dtype)) | |
| return out * (packed != 0).unsqueeze(-1).to(out.dtype) | |
| class NumberDecoder(nn.Module): | |
| def __init__(self, d_model, width=256, heads=4, layers=2): | |
| super().__init__() | |
| self.len_head = nn.Sequential(nn.Linear(d_model, width, bias=False), nn.SiLU(), | |
| nn.Linear(width, MAX_DIGITS, bias=False)) | |
| self.ctx = nn.Linear(d_model, width, bias=False) | |
| self.len_emb = nn.Embedding(MAX_DIGITS, width) | |
| self.place_emb = nn.Embedding(MAX_DIGITS, width) | |
| self.prev_emb = nn.Embedding(11, width) | |
| self.blocks = nn.ModuleList([Block(width, heads) for _ in range(layers)]) | |
| self.norm = nn.RMSNorm(width) | |
| self.out = nn.Linear(width, 10, bias=False) | |
| for m in self.modules(): | |
| if isinstance(m, (nn.Linear, nn.Embedding)): | |
| nn.init.normal_(m.weight, std=0.02) | |
| for b in self.blocks: | |
| nn.init.normal_(b.attn.out.weight, std=0.02 / math.sqrt(2 * layers)) | |
| nn.init.normal_(b.ffn.W_down.weight, std=0.02 / math.sqrt(2 * layers)) | |
| def _digit_logits(self, h, L, prev): | |
| j = torch.arange(MAX_DIGITS, device=h.device) | |
| power = (L.unsqueeze(-1) - 1 - j).clamp(min=0) | |
| x = (self.ctx(h) + self.len_emb(L - 1)).unsqueeze(1) + self.place_emb(power) + self.prev_emb(prev) | |
| for b in self.blocks: | |
| x = b(x) | |
| return self.out(self.norm(x)) | |
| def _msb_digits(packed): | |
| L, value = _lengths_values(packed) | |
| power = (L.unsqueeze(-1) - 1 - torch.arange(MAX_DIGITS, device=packed.device)).clamp(min=0) | |
| digits = value.unsqueeze(-1) // (10 ** power) % 10 | |
| valid = torch.arange(MAX_DIGITS, device=packed.device) < L.unsqueeze(-1) | |
| return L, digits, valid | |
| def nll(self, h, packed, weight=None): | |
| L, digits, valid = self._msb_digits(packed) | |
| prev = torch.cat([torch.full_like(digits[:, :1], 10), digits[:, :-1]], 1) | |
| len_nll = F.cross_entropy(self.len_head(h).float(), L - 1, reduction="none") | |
| logits = self._digit_logits(h, L, prev).float() | |
| dig_nll = F.cross_entropy(logits.view(-1, 10), digits.view(-1), reduction="none") | |
| per_num = len_nll + (dig_nll.view_as(digits) * valid).sum(-1) | |
| return per_num.sum() if weight is None else (per_num * weight).sum() | |
| def generate(self, h, temperature=0.0): | |
| def pick(logits): | |
| if temperature <= 0: | |
| return logits.argmax(-1) | |
| return torch.multinomial(F.softmax(logits.float() / temperature, -1), 1).squeeze(-1) | |
| L = pick(self.len_head(h)) + 1 | |
| prev = torch.full((h.shape[0], MAX_DIGITS), 10, dtype=torch.long, device=h.device) | |
| digits = torch.zeros_like(prev) | |
| for j in range(MAX_DIGITS): | |
| digits[:, j] = pick(self._digit_logits(h, L, prev)[:, j]) | |
| if j + 1 < MAX_DIGITS: | |
| prev[:, j + 1] = digits[:, j] | |
| power = (L.unsqueeze(-1) - 1 - torch.arange(MAX_DIGITS, device=h.device)).clamp(min=0) | |
| valid = torch.arange(MAX_DIGITS, device=h.device) < L.unsqueeze(-1) | |
| value = (digits * 10 ** power * valid).sum(-1) | |
| return value | (L << LEN_SHIFT) | |
| LOGIT_SOFTCAP = 30.0 | |
| def softcap(logits): | |
| return LOGIT_SOFTCAP * torch.tanh(logits.float() / LOGIT_SOFTCAP) | |
| class LM(nn.Module): | |
| def __init__(self, vocab, d_model, heads, n_blocks, window, global_every, parallel=True, rope="local"): | |
| super().__init__() | |
| self.emb = nn.Embedding(vocab, d_model) | |
| self.num_enc = NumberEncoder(d_model) | |
| self.body = CausalTransformer(d_model, heads, n_blocks, window=window, global_every=global_every, | |
| grad_checkpoint=False, parallel=parallel, rope=rope, compile_blocks=False) | |
| self.head = nn.Linear(d_model, vocab, bias=False) | |
| self.num_dec = NumberDecoder(d_model) | |
| def hidden(self, idx, vals, masks=None, cache=None): | |
| return self.body(self.emb(idx) + self.num_enc(vals), masks, cache) | |