multimodalart HF Staff commited on
Commit
bff799d
·
verified ·
1 Parent(s): 0ec2540

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. README.md +13 -7
  2. app.py +122 -0
  3. requirements.txt +2 -0
README.md CHANGED
@@ -1,13 +1,19 @@
1
  ---
2
- title: Doctobert Fr Base
3
- emoji: 👁
4
- colorFrom: gray
5
- colorTo: blue
6
  sdk: gradio
7
  sdk_version: 6.19.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: DoctoBERT-fr-base
3
+ emoji: 🏥
4
+ colorFrom: yellow
5
+ colorTo: purple
6
  sdk: gradio
7
  sdk_version: 6.19.0
 
8
  app_file: app.py
9
+ short_description: Fill-mask demo for French medical RoBERTa
10
+ python_version: "3.12"
11
+ startup_duration_timeout: 30m
12
  ---
13
 
14
+ # DoctoBERT-fr-base
15
+
16
+ French medical RoBERTa (111M parameters) fill-mask demo. Enter a French medical sentence
17
+ containing a `<mask>` token and the model predicts the most likely completions.
18
+
19
+ Model: [doctolib-lab/doctobert-fr-base](https://huggingface.co/doctolib-lab/doctobert-fr-base)
app.py ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import spaces # MUST come before torch / any CUDA-touching import
2
+ import torch
3
+ import gradio as gr
4
+ from transformers import AutoTokenizer, AutoModelForMaskedLM, top_k_top_p_filtering
5
+ import torch.nn.functional as F
6
+
7
+ MODEL_ID = "doctolib-lab/doctobert-fr-base"
8
+
9
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
10
+ model = AutoModelForMaskedLM.from_pretrained(MODEL_ID).to("cuda")
11
+ model.eval()
12
+
13
+ MASK_TOKEN = tokenizer.mask_token # "<mask>"
14
+
15
+
16
+ @spaces.GPU(duration=15)
17
+ def predict_mask(text: str, top_k: int = 5):
18
+ """Predict the most likely tokens to fill the <mask> in a French medical sentence.
19
+
20
+ Args:
21
+ text: A French medical sentence containing one <mask> token.
22
+ top_k: Number of top predictions to return.
23
+ """
24
+ if MASK_TOKEN not in text:
25
+ return {"error": f"Le texte doit contenir le jeton {MASK_TOKEN}."}
26
+
27
+ inputs = tokenizer(text, return_tensors="pt")
28
+ input_ids = inputs["input_ids"]
29
+
30
+ mask_index = (input_ids[0] == tokenizer.mask_token_id).nonzero(as_tuple=True)[0]
31
+ if len(mask_index) == 0:
32
+ return {"error": "Aucun jeton <mask> trouvé dans le texte."}
33
+ mask_pos = mask_index[0].item()
34
+
35
+ with torch.no_grad():
36
+ logits = model(**inputs).logits
37
+
38
+ mask_logits = logits[0, mask_pos, :]
39
+ probs = F.softmax(mask_logits, dim=-1)
40
+ topk_probs, topk_indices = torch.topk(probs, top_k)
41
+
42
+ results = []
43
+ for i in range(top_k):
44
+ token_id = topk_indices[i].item()
45
+ token = tokenizer.convert_ids_to_tokens(token_id)
46
+ # Clean up the SentencePiece prefix
47
+ clean_token = token.replace("▁", "").strip()
48
+ prob = topk_probs[i].item()
49
+ results.append({"token": clean_token, "score": round(prob, 4)})
50
+
51
+ # Also build a filled-in sentence with the top prediction
52
+ top_token_id = topk_indices[0].unsqueeze(0)
53
+ filled_ids = input_ids[0].clone()
54
+ filled_ids[mask_pos] = top_token_id
55
+ filled_text = tokenizer.decode(filled_ids, skip_special_tokens=True)
56
+
57
+ return {
58
+ "predictions": results,
59
+ "best_prediction": filled_text,
60
+ }
61
+
62
+
63
+ CSS = """
64
+ #col-container { max-width: 900px; margin: 0 auto; }
65
+ .dark .gradio-container { color: var(--body-text-color); }
66
+ """
67
+
68
+ with gr.Blocks(theme=gr.themes.Citrus(), css=CSS) as demo:
69
+ with gr.Column(elem_id="col-container"):
70
+ gr.Markdown(
71
+ """
72
+ # 🏥 DoctoBERT-fr-base
73
+ **DoctoBERT-fr-base** est un encodeur médical français (RoBERTa, 111M de paramètres)
74
+ pré-entraîné sur des données biomédicales et cliniques françaises.
75
+ Démo de **fill-mask** : donnez une phrase médicale contenant `<mask>`
76
+ et le modèle prédit les jetons les plus probables.
77
+
78
+ 🔗 [Modèle sur le Hub](https://huggingface.co/doctolib-lab/doctobert-fr-base)
79
+ """
80
+ )
81
+
82
+ with gr.Row():
83
+ text_input = gr.Textbox(
84
+ label="Phrase médicale (avec <mask>)",
85
+ placeholder=f"Le patient souffre d'une {MASK_TOKEN} aiguë.",
86
+ scale=4,
87
+ )
88
+ run_btn = gr.Button("Prédire", variant="primary", scale=1)
89
+
90
+ with gr.Accordion("Paramètres avancés", open=False):
91
+ top_k_input = gr.Slider(
92
+ minimum=1, maximum=20, value=5, step=1,
93
+ label="Nombre de prédictions (top-k)",
94
+ )
95
+
96
+ best_pred_output = gr.Textbox(label="Meilleure prédiction", interactive=False)
97
+ predictions_output = gr.JSON(label="Top-k prédictions")
98
+
99
+ run_btn.click(
100
+ fn=predict_mask,
101
+ inputs=[text_input, top_k_input],
102
+ outputs=[predictions_output, best_pred_output],
103
+ api_name="predict",
104
+ )
105
+
106
+ gr.Examples(
107
+ examples=[
108
+ [f"Le patient souffre d'une {MASK_TOKEN} aiguë.", 5],
109
+ [f"Le médecin prescrit un traitement pour l'{MASK_TOKEN}.", 5],
110
+ [f"La dose recommandée est de {MASK_TOKEN} mg par jour.", 5],
111
+ [f"Le patient présente des symptômes de {MASK_TOKEN} chronique.", 5],
112
+ [f"L'examen clinique révèle une {MASK_TOKEN} au niveau du thorax.", 5],
113
+ ],
114
+ inputs=[text_input, top_k_input],
115
+ outputs=[predictions_output, best_pred_output],
116
+ fn=predict_mask,
117
+ cache_examples=True,
118
+ cache_mode="lazy",
119
+ )
120
+
121
+ if __name__ == "__main__":
122
+ demo.launch(mcp_server=True)
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ transformers
2
+ torch