marquesafonso commited on
Commit
ff4b155
·
verified ·
1 Parent(s): 6ff3bc4

Add BERTimbau NER Gradio app for pt-ner

Browse files
Files changed (3) hide show
  1. README.md +50 -13
  2. app.py +68 -0
  3. requirements.txt +3 -0
README.md CHANGED
@@ -1,13 +1,50 @@
1
- ---
2
- title: Pt Ner Bertimbau
3
- emoji: 🐢
4
- colorFrom: blue
5
- colorTo: green
6
- sdk: gradio
7
- sdk_version: 6.24.0
8
- python_version: '3.12'
9
- app_file: app.py
10
- pinned: false
11
- ---
12
-
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: pt-ner BERTimbau NER
3
+ emoji: 🚀
4
+ colorFrom: blue
5
+ colorTo: green
6
+ sdk: gradio
7
+ sdk_version: 5.50.0
8
+ app_file: app.py
9
+ short_description: Portuguese NER API for the pt-ner application
10
+ python_version: "3.12"
11
+ startup_duration_timeout: 30m
12
+ ---
13
+
14
+ # pt-ner BERTimbau NER Space
15
+
16
+ Public HTTP API backing [pt-ner](https://github.com/sillohq/starter): Portuguese named-entity recognition with [`marquesafonso/bertimbau-large-ner-total`](https://huggingface.co/marquesafonso/bertimbau-large-ner-total).
17
+
18
+ ## Deploy
19
+
20
+ Create the Space (ZeroGPU, public):
21
+
22
+ ```bash
23
+ hf repos create YOUR_USER/pt-ner-bertimbau --type space --space-sdk gradio \
24
+ --flavor zero-a10g --public --exist-ok
25
+ ```
26
+
27
+ Upload this directory:
28
+
29
+ ```bash
30
+ hf upload space/. --repo-type space --repo YOUR_USER/pt-ner-bertimbau \
31
+ --exclude "**/__pycache__/**"
32
+ ```
33
+
34
+ When the Space is running, set in the pt-ner app (Docker `.env`):
35
+
36
+ ```bash
37
+ NER_BACKEND=space
38
+ NER_SPACE_URL=https://YOUR_USER-pt-ner-bertimbau.hf.space
39
+ ```
40
+
41
+ ## API
42
+
43
+ Gradio exposes `predict(text) -> list[entity]`. Each entity has:
44
+
45
+ - `label` — entity type
46
+ - `text` — surface form
47
+ - `start` / `end` — character offsets in the input text
48
+ - `score` — model confidence
49
+
50
+ The pt-ner application calls this endpoint over HTTP; it does not load transformers locally.
app.py ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Gradio ZeroGPU Space — Portuguese NER API for pt-ner."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import spaces
6
+ import gradio as gr
7
+ import torch
8
+ from transformers import pipeline
9
+
10
+ MODEL_ID = "marquesafonso/bertimbau-large-ner-total"
11
+
12
+ ner = pipeline(
13
+ "ner",
14
+ model=MODEL_ID,
15
+ aggregation_strategy="simple",
16
+ device=0,
17
+ torch_dtype=torch.bfloat16,
18
+ )
19
+ ner.model.to("cuda")
20
+
21
+
22
+ def _serialize(raw: list[dict]) -> list[dict]:
23
+ entities: list[dict] = []
24
+ for item in raw:
25
+ start = int(item["start"])
26
+ end = int(item["end"])
27
+ entities.append(
28
+ {
29
+ "label": str(item.get("entity_group") or item.get("entity") or "MISC"),
30
+ "text": str(item.get("word") or ""),
31
+ "start": start,
32
+ "end": end,
33
+ "score": float(item["score"]) if item.get("score") is not None else None,
34
+ }
35
+ )
36
+ return entities
37
+
38
+
39
+ @spaces.GPU(duration=120)
40
+ def predict(text: str) -> list[dict]:
41
+ """Extract named entities from Portuguese text with character offsets."""
42
+ cleaned = (text or "").strip()
43
+ if not cleaned:
44
+ return []
45
+ return _serialize(ner(cleaned))
46
+
47
+
48
+ EXAMPLES = [
49
+ ["João Silva mora em Lisboa."],
50
+ ["Maria Santos trabalha no Banco de Portugal, no Porto."],
51
+ ]
52
+
53
+ demo = gr.Interface(
54
+ fn=predict,
55
+ inputs=gr.Textbox(label="Texto", lines=6, placeholder="Cole texto em português…"),
56
+ outputs=gr.JSON(label="Entidades"),
57
+ title="BERTimbau NER — pt-ner",
58
+ description=(
59
+ "API Space for the pt-ner application. "
60
+ f"Model: [{MODEL_ID}](https://huggingface.co/{MODEL_ID})."
61
+ ),
62
+ examples=EXAMPLES,
63
+ cache_examples=True,
64
+ cache_mode="lazy",
65
+ )
66
+
67
+ if __name__ == "__main__":
68
+ demo.launch(mcp_server=True)
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ transformers
2
+ accelerate
3
+ sentencepiece