Token Classification
Transformers
Safetensors
Portuguese
modernbert
legal
brazilian-portuguese
citation-extraction
ner
Instructions to use vinimlo/gama with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use vinimlo/gama with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("token-classification", model="vinimlo/gama")# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForTokenClassification tokenizer = AutoTokenizer.from_pretrained("vinimlo/gama") model = AutoModelForTokenClassification.from_pretrained("vinimlo/gama", device_map="auto") - Notebooks
- Google Colab
- Kaggle
treino jhu-clsp/mmBERT-base semente 13 dados vinimlo/caca-goldenset@ea6ae7e087be018bdcf7652ee1b09fe35d0577fe
Browse files- .gitattributes +1 -0
- bio.py +108 -0
- config.json +97 -0
- metricas.json +30 -0
- model.safetensors +3 -0
- tokenizer.json +3 -0
- tokenizer_config.json +25 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
tokenizer.json filter=lfs diff=lfs merge=lfs -text
|
bio.py
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# -*- coding: utf-8 -*-
|
| 2 |
+
"""Rótulos BIO por token <-> spans por caractere. Mesmo código no treino e na inferência.
|
| 3 |
+
|
| 4 |
+
Duas funções puras sobre o `offset_mapping` do tokenizador (fast):
|
| 5 |
+
|
| 6 |
+
rotular(offsets, spans) spans de caractere -> um rótulo por token
|
| 7 |
+
decodificar(offsets, rotulos) rótulos por token -> spans de caractere
|
| 8 |
+
|
| 9 |
+
O portão do plano (D1): rotular -> decodificar tem que devolver EXATAMENTE os
|
| 10 |
+
spans do gabarito (IoU 1,0) em 100% do dev set e do goldenset. É aqui que acento,
|
| 11 |
+
NBSP e quebra de linha causam bug silencioso: o token SentencePiece "▁SP" pode
|
| 12 |
+
começar no espaço, o token "RS," pode engolir a vírgula. A decodificação apara
|
| 13 |
+
espaço nas bordas e pontuação final — nenhum span do gabarito termina em .,;:
|
| 14 |
+
(192/192, docs/convencoes-de-borda.md).
|
| 15 |
+
|
| 16 |
+
Documento longo: janelas de `max_len` tokens com sobreposição; cada token herda o
|
| 17 |
+
rótulo da janela em que está mais ao centro (menos perda de contexto na borda).
|
| 18 |
+
"""
|
| 19 |
+
from __future__ import annotations
|
| 20 |
+
|
| 21 |
+
TIPOS = ("JURIS", "LEI", "VAGA")
|
| 22 |
+
ROTULOS = ["O"] + [f"{p}-{t}" for t in TIPOS for p in ("B", "I")]
|
| 23 |
+
ID = {r: i for i, r in enumerate(ROTULOS)}
|
| 24 |
+
IGNORAR = -100 # token especial: fora da perda
|
| 25 |
+
|
| 26 |
+
_APARA_FIM = " \t\n\r .,;:"
|
| 27 |
+
_APARA_INI = " \t\n\r "
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def rotular(offsets: list, spans: list) -> list[int]:
|
| 31 |
+
"""offsets: [(ini, fim)] por token ((0, 0) = especial). spans: [(ini, fim, tipo)].
|
| 32 |
+
|
| 33 |
+
B no primeiro token que cruza o span, I nos seguintes. Token que cruza a borda
|
| 34 |
+
(ex.: "▁SP" começando no espaço, "RS," levando a vírgula) conta como dentro — a
|
| 35 |
+
decodificação apara o excesso.
|
| 36 |
+
"""
|
| 37 |
+
rot = []
|
| 38 |
+
ordenados = sorted(spans)
|
| 39 |
+
iniciados: set = set()
|
| 40 |
+
for s, e in offsets:
|
| 41 |
+
if s == e:
|
| 42 |
+
rot.append(IGNORAR)
|
| 43 |
+
continue
|
| 44 |
+
r = ID["O"]
|
| 45 |
+
for k, (a, b, tipo) in enumerate(ordenados):
|
| 46 |
+
if max(s, a) < min(e, b):
|
| 47 |
+
r = ID[f"I-{tipo}"] if k in iniciados else ID[f"B-{tipo}"]
|
| 48 |
+
iniciados.add(k)
|
| 49 |
+
break
|
| 50 |
+
rot.append(r)
|
| 51 |
+
return rot
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
def decodificar(offsets: list, rotulos: list, texto: str) -> list[tuple[int, int, str]]:
|
| 55 |
+
"""Rótulos por token -> spans (ini, fim, tipo), aparados pela convenção de borda."""
|
| 56 |
+
spans = []
|
| 57 |
+
atual = None # [ini, fim, tipo]
|
| 58 |
+
for (s, e), r in zip(offsets, rotulos):
|
| 59 |
+
if s == e or r == IGNORAR:
|
| 60 |
+
continue
|
| 61 |
+
nome = ROTULOS[r]
|
| 62 |
+
if nome == "O":
|
| 63 |
+
if atual:
|
| 64 |
+
spans.append(atual)
|
| 65 |
+
atual = None
|
| 66 |
+
continue
|
| 67 |
+
prefixo, tipo = nome.split("-", 1)
|
| 68 |
+
if prefixo == "B" or atual is None or atual[2] != tipo:
|
| 69 |
+
if atual:
|
| 70 |
+
spans.append(atual)
|
| 71 |
+
atual = [s, e, tipo]
|
| 72 |
+
else:
|
| 73 |
+
atual[1] = e
|
| 74 |
+
if atual:
|
| 75 |
+
spans.append(atual)
|
| 76 |
+
out = []
|
| 77 |
+
for a, b, tipo in spans:
|
| 78 |
+
while a < b and texto[a] in _APARA_INI:
|
| 79 |
+
a += 1
|
| 80 |
+
while b > a and texto[b - 1] in _APARA_FIM:
|
| 81 |
+
b -= 1
|
| 82 |
+
if b > a:
|
| 83 |
+
out.append((a, b, tipo))
|
| 84 |
+
return out
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
def janelas(n_tokens: int, max_len: int, passo: int) -> list[tuple[int, int]]:
|
| 88 |
+
"""Cobertura de [0, n) por janelas [i, j) de até max_len, avançando `passo`."""
|
| 89 |
+
if n_tokens <= max_len:
|
| 90 |
+
return [(0, n_tokens)]
|
| 91 |
+
out, i = [], 0
|
| 92 |
+
while True:
|
| 93 |
+
j = min(i + max_len, n_tokens)
|
| 94 |
+
out.append((i, j))
|
| 95 |
+
if j == n_tokens:
|
| 96 |
+
return out
|
| 97 |
+
i += passo
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
def janela_dona(i: int, cobertura: list[tuple[int, int]]) -> int:
|
| 101 |
+
"""Índice da janela em que o token i está mais longe da borda."""
|
| 102 |
+
melhor, dist = 0, -1
|
| 103 |
+
for k, (a, b) in enumerate(cobertura):
|
| 104 |
+
if a <= i < b:
|
| 105 |
+
d = min(i - a, b - 1 - i)
|
| 106 |
+
if d > dist:
|
| 107 |
+
melhor, dist = k, d
|
| 108 |
+
return melhor
|
config.json
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"architectures": [
|
| 3 |
+
"ModernBertForTokenClassification"
|
| 4 |
+
],
|
| 5 |
+
"attention_bias": false,
|
| 6 |
+
"attention_dropout": 0.0,
|
| 7 |
+
"bos_token_id": 2,
|
| 8 |
+
"classifier_activation": "gelu",
|
| 9 |
+
"classifier_bias": false,
|
| 10 |
+
"classifier_dropout": 0.0,
|
| 11 |
+
"classifier_pooling": "mean",
|
| 12 |
+
"cls_token_id": 1,
|
| 13 |
+
"decoder_bias": true,
|
| 14 |
+
"deterministic_flash_attn": false,
|
| 15 |
+
"dtype": "float32",
|
| 16 |
+
"embedding_dropout": 0.0,
|
| 17 |
+
"eos_token_id": 1,
|
| 18 |
+
"global_attn_every_n_layers": 3,
|
| 19 |
+
"gradient_checkpointing": false,
|
| 20 |
+
"hidden_activation": "gelu",
|
| 21 |
+
"hidden_size": 768,
|
| 22 |
+
"id2label": {
|
| 23 |
+
"0": "O",
|
| 24 |
+
"1": "B-JURIS",
|
| 25 |
+
"2": "I-JURIS",
|
| 26 |
+
"3": "B-LEI",
|
| 27 |
+
"4": "I-LEI",
|
| 28 |
+
"5": "B-VAGA",
|
| 29 |
+
"6": "I-VAGA"
|
| 30 |
+
},
|
| 31 |
+
"initializer_cutoff_factor": 2.0,
|
| 32 |
+
"initializer_range": 0.02,
|
| 33 |
+
"intermediate_size": 1152,
|
| 34 |
+
"label2id": {
|
| 35 |
+
"B-JURIS": 1,
|
| 36 |
+
"B-LEI": 3,
|
| 37 |
+
"B-VAGA": 5,
|
| 38 |
+
"I-JURIS": 2,
|
| 39 |
+
"I-LEI": 4,
|
| 40 |
+
"I-VAGA": 6,
|
| 41 |
+
"O": 0
|
| 42 |
+
},
|
| 43 |
+
"layer_norm_eps": 1e-05,
|
| 44 |
+
"layer_types": [
|
| 45 |
+
"full_attention",
|
| 46 |
+
"sliding_attention",
|
| 47 |
+
"sliding_attention",
|
| 48 |
+
"full_attention",
|
| 49 |
+
"sliding_attention",
|
| 50 |
+
"sliding_attention",
|
| 51 |
+
"full_attention",
|
| 52 |
+
"sliding_attention",
|
| 53 |
+
"sliding_attention",
|
| 54 |
+
"full_attention",
|
| 55 |
+
"sliding_attention",
|
| 56 |
+
"sliding_attention",
|
| 57 |
+
"full_attention",
|
| 58 |
+
"sliding_attention",
|
| 59 |
+
"sliding_attention",
|
| 60 |
+
"full_attention",
|
| 61 |
+
"sliding_attention",
|
| 62 |
+
"sliding_attention",
|
| 63 |
+
"full_attention",
|
| 64 |
+
"sliding_attention",
|
| 65 |
+
"sliding_attention",
|
| 66 |
+
"full_attention"
|
| 67 |
+
],
|
| 68 |
+
"local_attention": 128,
|
| 69 |
+
"mask_token_id": 4,
|
| 70 |
+
"max_position_embeddings": 8192,
|
| 71 |
+
"mlp_bias": false,
|
| 72 |
+
"mlp_dropout": 0.0,
|
| 73 |
+
"model_type": "modernbert",
|
| 74 |
+
"norm_bias": false,
|
| 75 |
+
"norm_eps": 1e-05,
|
| 76 |
+
"num_attention_heads": 12,
|
| 77 |
+
"num_hidden_layers": 22,
|
| 78 |
+
"pad_token_id": 0,
|
| 79 |
+
"position_embedding_type": "sans_pos",
|
| 80 |
+
"rope_parameters": {
|
| 81 |
+
"full_attention": {
|
| 82 |
+
"rope_theta": 160000,
|
| 83 |
+
"rope_type": "default"
|
| 84 |
+
},
|
| 85 |
+
"sliding_attention": {
|
| 86 |
+
"rope_theta": 160000,
|
| 87 |
+
"rope_type": "default"
|
| 88 |
+
}
|
| 89 |
+
},
|
| 90 |
+
"sep_token_id": 1,
|
| 91 |
+
"sparse_pred_ignore_index": -100,
|
| 92 |
+
"sparse_prediction": false,
|
| 93 |
+
"tie_word_embeddings": true,
|
| 94 |
+
"transformers_version": "5.17.0",
|
| 95 |
+
"use_cache": false,
|
| 96 |
+
"vocab_size": 256000
|
| 97 |
+
}
|
metricas.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"estresse": {
|
| 3 |
+
"exato": {
|
| 4 |
+
"JURIS": 1.0,
|
| 5 |
+
"LEI": 1.0,
|
| 6 |
+
"VAGA": 1.0
|
| 7 |
+
},
|
| 8 |
+
"iou50": {
|
| 9 |
+
"JURIS": 1.0,
|
| 10 |
+
"LEI": 1.0,
|
| 11 |
+
"VAGA": 1.0
|
| 12 |
+
}
|
| 13 |
+
},
|
| 14 |
+
"n_estresse": 402,
|
| 15 |
+
"n_treino": 3598,
|
| 16 |
+
"janelas": 6458,
|
| 17 |
+
"args": {
|
| 18 |
+
"dados": "vinimlo/caca-goldenset",
|
| 19 |
+
"revisao": "ea6ae7e087be018bdcf7652ee1b09fe35d0577fe",
|
| 20 |
+
"subpasta": "final_v1",
|
| 21 |
+
"modelo_base": "jhu-clsp/mmBERT-base",
|
| 22 |
+
"saida": "vinimlo/caca-extrator-mmbert",
|
| 23 |
+
"max_len": 1024,
|
| 24 |
+
"epocas": 3.0,
|
| 25 |
+
"lr": 5e-05,
|
| 26 |
+
"lote": 8,
|
| 27 |
+
"semente": 13
|
| 28 |
+
},
|
| 29 |
+
"minutos": 17.8
|
| 30 |
+
}
|
model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:65ecbe552da448f69ec5c330f64be15fe9ebc80d3d0f4f11d0404bb814f8647f
|
| 3 |
+
size 1230156812
|
tokenizer.json
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:609d8f4c067cd3950f88594c5a802616cea245823836ef5848ee4fc40aab5b6f
|
| 3 |
+
size 34363188
|
tokenizer_config.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"backend": "tokenizers",
|
| 3 |
+
"bos_token": "<bos>",
|
| 4 |
+
"clean_up_tokenization_spaces": false,
|
| 5 |
+
"cls_token": "<bos>",
|
| 6 |
+
"eos_token": "<eos>",
|
| 7 |
+
"extra_special_tokens": [
|
| 8 |
+
"<start_of_turn>",
|
| 9 |
+
"<end_of_turn>"
|
| 10 |
+
],
|
| 11 |
+
"is_local": false,
|
| 12 |
+
"local_files_only": false,
|
| 13 |
+
"mask_token": "<mask>",
|
| 14 |
+
"model_input_names": [
|
| 15 |
+
"input_ids",
|
| 16 |
+
"attention_mask"
|
| 17 |
+
],
|
| 18 |
+
"model_max_length": 8192,
|
| 19 |
+
"pad_token": "<pad>",
|
| 20 |
+
"padding_side": "right",
|
| 21 |
+
"sep_token": "<eos>",
|
| 22 |
+
"spaces_between_special_tokens": false,
|
| 23 |
+
"tokenizer_class": "TokenizersBackend",
|
| 24 |
+
"unk_token": "<unk>"
|
| 25 |
+
}
|