Instructions to use masahiroid/bert-base-ner-mlx with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use masahiroid/bert-base-ner-mlx with MLX:
# Download the model from the Hub pip install huggingface_hub[hf_xet] hf download masahiroid/bert-base-ner-mlx --local-dir bert-base-ner-mlx
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- Atomic Chat
Download bert_ner_mlx.py from masahiroid/bert-base-ner-mlx: direct link, hf CLI and curl.
- Browser
- Download file 3.47 kB
-
https://huggingface.co/masahiroid/bert-base-ner-mlx/resolve/main/bert_ner_mlx.py
- Command line
-
hf download hf://masahiroid/bert-base-ner-mlx/bert_ner_mlx.py
-
curl -L -o bert_ner_mlx.py https://huggingface.co/masahiroid/bert-base-ner-mlx/resolve/main/bert_ner_mlx.py
3.47 kB
| """MLX reimplementation of dslim/bert-base-NER (standard BERT-base encoder + | |
| a per-token linear classifier head for named-entity recognition). | |
| Standard post-norm BERT, not covered by `mlx-embeddings` (which targets | |
| embedding/reranker pooling outputs, not token classification), so | |
| reimplemented directly against the HF `transformers` BERT source. | |
| """ | |
| import math | |
| import mlx.core as mx | |
| import mlx.nn as nn | |
| HIDDEN_SIZE = 768 | |
| NUM_HEADS = 12 | |
| HEAD_DIM = HIDDEN_SIZE // NUM_HEADS | |
| INTERMEDIATE_SIZE = 3072 | |
| NUM_LAYERS = 12 | |
| NUM_LABELS = 9 | |
| VOCAB_SIZE = 28996 | |
| MAX_POSITION_EMBEDDINGS = 512 | |
| TYPE_VOCAB_SIZE = 2 | |
| LN_EPS = 1e-12 | |
| class BertLayer(nn.Module): | |
| def __init__(self): | |
| super().__init__() | |
| self.q = nn.Linear(HIDDEN_SIZE, HIDDEN_SIZE) | |
| self.k = nn.Linear(HIDDEN_SIZE, HIDDEN_SIZE) | |
| self.v = nn.Linear(HIDDEN_SIZE, HIDDEN_SIZE) | |
| self.attn_out = nn.Linear(HIDDEN_SIZE, HIDDEN_SIZE) | |
| self.attn_layernorm = nn.LayerNorm(HIDDEN_SIZE, eps=LN_EPS) | |
| self.intermediate = nn.Linear(HIDDEN_SIZE, INTERMEDIATE_SIZE) | |
| self.output = nn.Linear(INTERMEDIATE_SIZE, HIDDEN_SIZE) | |
| self.output_layernorm = nn.LayerNorm(HIDDEN_SIZE, eps=LN_EPS) | |
| def __call__(self, x, attn_bias=None): | |
| b, n, c = x.shape | |
| q = self.q(x).reshape(b, n, NUM_HEADS, HEAD_DIM).transpose(0, 2, 1, 3) | |
| k = self.k(x).reshape(b, n, NUM_HEADS, HEAD_DIM).transpose(0, 2, 1, 3) | |
| v = self.v(x).reshape(b, n, NUM_HEADS, HEAD_DIM).transpose(0, 2, 1, 3) | |
| attn = mx.fast.scaled_dot_product_attention( | |
| q, k, v, scale=1.0 / math.sqrt(HEAD_DIM), mask=attn_bias | |
| ) | |
| attn = attn.transpose(0, 2, 1, 3).reshape(b, n, c) | |
| attn = self.attn_out(attn) | |
| x = self.attn_layernorm(x + attn) | |
| h = self.output(nn.gelu(self.intermediate(x))) | |
| x = self.output_layernorm(x + h) | |
| return x | |
| class BertNerMLX(nn.Module): | |
| def __init__(self): | |
| super().__init__() | |
| self.word_embeddings = mx.zeros((VOCAB_SIZE, HIDDEN_SIZE)) | |
| self.position_embeddings = mx.zeros((MAX_POSITION_EMBEDDINGS, HIDDEN_SIZE)) | |
| self.token_type_embeddings = mx.zeros((TYPE_VOCAB_SIZE, HIDDEN_SIZE)) | |
| self.embeddings_layernorm = nn.LayerNorm(HIDDEN_SIZE, eps=LN_EPS) | |
| self.layers = [BertLayer() for _ in range(NUM_LAYERS)] | |
| self.classifier = nn.Linear(HIDDEN_SIZE, NUM_LABELS) | |
| def __call__(self, input_ids, attention_mask=None, token_type_ids=None): | |
| b, n = input_ids.shape | |
| word_emb = self.word_embeddings[input_ids] | |
| pos_ids = mx.arange(n) | |
| pos_emb = self.position_embeddings[pos_ids] | |
| if token_type_ids is None: | |
| token_type_ids = mx.zeros((b, n), dtype=mx.int32) | |
| type_emb = self.token_type_embeddings[token_type_ids] | |
| x = word_emb + pos_emb[None] + type_emb | |
| x = self.embeddings_layernorm(x) | |
| attn_bias = None | |
| if attention_mask is not None: | |
| # Use a large-but-finite negative value that fits in fp16 (max ~65504). | |
| # A literal like -1e9 overflows fp16 to -inf, and 0 * -inf = NaN for | |
| # the unmasked (mask=1) positions where this term should be exactly 0. | |
| neg = mx.array(-1e4, dtype=x.dtype) | |
| attn_bias = (1 - attention_mask[:, None, None, :].astype(x.dtype)) * neg | |
| for layer in self.layers: | |
| x = layer(x, attn_bias=attn_bias) | |
| logits = self.classifier(x) | |
| return logits | |