Spaces:
Sleeping
Sleeping
File size: 5,260 Bytes
ca9fd09 ad74c90 ca9fd09 ad74c90 ca9fd09 ad74c90 ca9fd09 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | 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()
|