Spaces:
Sleeping
Sleeping
| import time | |
| import gradio as gr | |
| from gliner import GLiNER | |
| model = GLiNER.from_pretrained("Ihor/gliner-biomed-base-v1.0") | |
| MAX_LABELS = 12 | |
| PALETTE = [ | |
| "#FF6B6B", "#4ECDC4", "#45B7D1", "#FFA07A", "#98D8C8", "#F7DC6F", | |
| "#BB8FCE", "#85C1E9", "#F0B27A", "#76D7C4", "#F1948A", "#82E0AA", | |
| ] | |
| DEFAULT_LABELS = ["patient_name", "age", "sex", "symptom", "diagnosis", "medication", "vital_sign", "procedure"] | |
| def filter_choices(selected): | |
| return gr.Dropdown(choices=[l for l in DEFAULT_LABELS if l not in selected]) | |
| def extract(text, labels_list, threshold): | |
| labels = [l for l in labels_list if l][:MAX_LABELS] | |
| if not labels or not text.strip(): | |
| return None, [], "" | |
| color_map = {l: PALETTE[i % len(PALETTE)] for i, l in enumerate(labels)} | |
| start = time.perf_counter() | |
| entities = model.predict_entities(text, labels, threshold=threshold) | |
| latency_ms = (time.perf_counter() - start) * 1000 | |
| entities = sorted(entities, key=lambda e: e["start"]) | |
| hl_entities = [{"entity": e["label"], "start": e["start"], "end": e["end"]} for e in entities] | |
| table = [[e["label"], e["text"], f"{e['score']:.2f}"] for e in entities] | |
| return ( | |
| gr.HighlightedText(value={"text": text, "entities": hl_entities}, color_map=color_map), | |
| table, | |
| f"{latency_ms:.1f} ms | {len(entities)} entities", | |
| ) | |
| EXAMPLES = [ | |
| [ | |
| """Patient: Jane Doe, 58-year-old female. | |
| Chief Complaint: Chest pain and shortness of breath for 2 days. | |
| History of Present Illness: | |
| Patient presents with substernal chest pain radiating to the left arm, | |
| rated 7/10, worsening with exertion. She reports associated dyspnea and | |
| diaphoresis. She has a history of Type 2 Diabetes Mellitus diagnosed in | |
| 2015 and Hypertension diagnosed in 2018. | |
| Current Medications: | |
| - Metformin 1000mg PO BID for diabetes | |
| - Lisinopril 20mg PO daily for hypertension | |
| - Aspirin 81mg PO daily for cardiac prophylaxis | |
| Vitals: BP 158/92, HR 96, SpO2 94%, Temp 98.6F | |
| Assessment: | |
| 1. Acute coronary syndrome - rule out myocardial infarction | |
| 2. Uncontrolled hypertension | |
| 3. Type 2 Diabetes Mellitus - stable on current regimen | |
| Plan: | |
| - Stat ECG and troponin levels | |
| - Start Heparin drip 18 units/kg/hr IV | |
| - Nitroglycerin 0.4mg sublingual PRN chest pain | |
| - Cardiology consult | |
| - Continue home medications""", | |
| DEFAULT_LABELS, | |
| 0.4, | |
| ], | |
| [ | |
| """DISCHARGE SUMMARY | |
| Patient: Robert Chen, 72-year-old male. | |
| Admission Date: 2024-01-15. Discharge Date: 2024-01-19. | |
| Principal Diagnosis: Community-acquired pneumonia, right lower lobe. | |
| Secondary Diagnoses: COPD, Atrial fibrillation. | |
| Hospital Course: | |
| Patient admitted with fever 101.8F, productive cough with purulent sputum, | |
| and oxygen saturation of 88% on room air. Chest X-ray confirmed right lower | |
| lobe consolidation. Started on Ceftriaxone 1g IV daily and Azithromycin | |
| 500mg PO daily. Supplemental O2 via nasal cannula at 3L/min. | |
| Discharge Medications: | |
| - Amoxicillin-Clavulanate 875mg PO BID x 5 days | |
| - Albuterol inhaler 2 puffs q4-6h PRN | |
| - Warfarin 5mg PO daily | |
| - Metoprolol 50mg PO BID | |
| Follow-up: Pulmonology clinic in 2 weeks. Repeat chest X-ray in 6 weeks.""", | |
| DEFAULT_LABELS, | |
| 0.4, | |
| ], | |
| [ | |
| """ED Note - 03/10/2024 22:45 | |
| Chief Complaint: Laceration to right hand. | |
| HPI: 34-year-old male presents after cutting his right palm on broken glass | |
| approximately 1 hour ago. Reports moderate bleeding controlled with direct | |
| pressure. Denies numbness or weakness in fingers. No foreign body sensation. | |
| Tetanus up to date. | |
| Exam: 3cm linear laceration to right thenar eminence, clean edges, no tendon | |
| involvement, neurovascular intact distally. | |
| Procedure: Wound irrigated with normal saline. Repaired with 4-0 nylon, | |
| 5 interrupted sutures. Sterile dressing applied. | |
| Disposition: Home with wound care instructions. Suture removal in 10 days.""", | |
| DEFAULT_LABELS + ["body_part", "wound"], | |
| 0.4, | |
| ], | |
| ] | |
| with gr.Blocks(title="GLiNER Biomedical NER") as demo: | |
| gr.Markdown("# GLiNER Biomedical NER\nZero-shot named entity recognition with `gliner-biomed-base-v1.0`") | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| text_input = gr.Textbox(label="Clinical Text", lines=12) | |
| labels_input = gr.Dropdown( | |
| label="Entity Labels", | |
| choices=DEFAULT_LABELS, | |
| value=DEFAULT_LABELS, | |
| multiselect=True, | |
| allow_custom_value=True, | |
| max_choices=MAX_LABELS, | |
| ) | |
| threshold = gr.Slider(0.0, 1.0, value=0.4, step=0.05, label="Confidence Threshold") | |
| run_btn = gr.Button("Extract", variant="primary") | |
| with gr.Column(scale=3): | |
| latency_output = gr.Textbox(label="Latency") | |
| highlight_output = gr.HighlightedText(label="Entities", combine_adjacent=False, show_legend=True) | |
| table_output = gr.Dataframe(headers=["Label", "Text", "Score"], label="Extracted Entities") | |
| labels_input.change(filter_choices, inputs=[labels_input], outputs=[labels_input]) | |
| run_btn.click(extract, inputs=[text_input, labels_input, threshold], outputs=[highlight_output, table_output, latency_output]) | |
| gr.Examples(EXAMPLES, inputs=[text_input, labels_input, threshold]) | |
| demo.launch() | |