MedSync AI Studio: Medical-IndoBERT Dual-Head INA-CBGs Sync
Model klasifikasi teks klinis multi-task berbasis Medical-IndoBERT (Domain-Adaptive Pretrained) yang disempurnakan melalui Supervised Fine-Tuning (SFT) dengan arsitektur Dual-Head:
1. Head 1 (ICD-10): Klasifikasi Diagnosis Klinis Primer (WHO ICD-10).
2. Head 2 (INA-CBGs): Prediksi Kelompok Tarif Casemix Klaim (Kemenkes RI / UNU-IIGH Casemix).
Detail Arsitektur & Pelatihan
- Backbone:
indobenchmark/indobert-base-p2 + Domain-Adaptive Pretraining (DAPT) pada korpus medis klinis.
- Arsitektur:
DualHeadModel (Encoder BERT + Dropout 0.2 + 2 Linear Classification Heads).
- Jumlah Kelas ICD-10: 45 kelas diagnosis.
- Jumlah Kelas INA-CBGs: 46 kelompok tarif casemix.
- Studi Kasus: RSUD Datu Sanggul (Kelas C, Regional 4).
- Kepatuhan Privasi: UU Perlindungan Data Pribadi (UU PDP) No. 27 Tahun 2022.
Cara Penggunaan Singkat (Python / Google Colab / Notebook)
Senior atau peneliti dapat langsung menguji model ini menggunakan kode berikut:
import torch
import torch.nn as nn
from transformers import AutoConfig, AutoTokenizer
from huggingface_hub import hf_hub_download
import json
REPO_ID = "Dragneva/medsync-indobert-inacbg"
# 1. Download Model Weights & Metadata dari Hugging Face Hub
model_path = hf_hub_download(repo_id=REPO_ID, filename="model.pt")
mapping_path = hf_hub_download(repo_id=REPO_ID, filename="label_mappings.json")
with open(mapping_path, "r", encoding="utf-8") as f:
meta = json.load(f)
id_to_icd10 = {int(k): v for k, v in meta["id_to_icd10"].items()}
id_to_group = {int(k): v for k, v in meta["id_to_group"].items()}
icd10_to_name = meta.get("icd10_to_name", {})
group_to_name = meta.get("group_to_name_id", {})
# 2. Inisialisasi Arsitektur DualHeadModel
class DualHeadModel(nn.Module):
def __init__(self, config, n_icd, n_grp):
super().__init__()
from transformers import AutoModel
self.encoder = AutoModel.from_config(config)
self.dropout = nn.Dropout(0.2)
self.icd10_head = nn.Linear(config.hidden_size, n_icd)
self.group_head = nn.Linear(config.hidden_size, n_grp)
def forward(self, input_ids, attention_mask):
outputs = self.encoder(input_ids=input_ids, attention_mask=attention_mask)
mask = attention_mask.unsqueeze(-1).float()
pooled = (outputs.last_hidden_state * mask).sum(dim=1) / mask.sum(dim=1).clamp(min=1e-9)
return self.icd10_head(self.dropout(pooled)), self.group_head(self.dropout(pooled))
# 3. Load Model & Tokenizer
config = AutoConfig.from_pretrained(REPO_ID)
tokenizer = AutoTokenizer.from_pretrained(REPO_ID)
model = DualHeadModel(config, n_icd=len(id_to_icd10), n_grp=len(id_to_group))
model.load_state_dict(torch.load(model_path, map_location="cpu"))
model.eval()
# 4. Inferensi Teks Klinis
teks_klinis = "Pasien datang kontrol rutin poli penyakit dalam dengan riwayat hipertensi 5 tahun. Tensi 150/90 mmHg."
inputs = tokenizer(teks_klinis, return_tensors="pt", max_length=128, truncation=True, padding=True)
with torch.no_grad():
icd_logits, grp_logits = model(inputs["input_ids"], inputs["attention_mask"])
icd_probs = torch.softmax(icd_logits, dim=-1)[0]
grp_probs = torch.softmax(grp_logits, dim=-1)[0]
top_icd = torch.argmax(icd_probs).item()
top_grp = torch.argmax(grp_probs).item()
icd_code = id_to_icd10[top_icd]
grp_code = id_to_group[top_grp]
print("=== HASIL INFERENSI MEDSYNC AI STUDIO ===")
print(f"Prediksi ICD-10 : {icd_code} - {icd10_to_name.get(icd_code, '')} ({icd_probs[top_icd]*100:.1f}%)")
print(f"Prediksi INA-CBGs: {grp_code} - {group_to_name.get(grp_code, '')} ({grp_probs[top_grp]*100:.1f}%)")
Etika & Kepatuhan Data
Dataset dan bobot dikembangkan sesuai regulasi perlindungan data medis UU PDP No. 27/2022. Rekam Medis (Nomor Rekam Medis, No. SEP, Nama Pasien) telah dideidentifikasi dan disimpan di repositori privat terpisah.