File size: 4,971 Bytes
13445a2
69cddef
 
13445a2
69cddef
 
 
 
13445a2
69cddef
 
 
13445a2
 
69cddef
 
 
13445a2
 
69cddef
 
 
 
 
 
 
 
 
47f7605
69cddef
 
 
 
 
 
 
 
 
 
47f7605
69cddef
 
 
47f7605
 
 
69cddef
 
 
47f7605
69cddef
 
 
 
47f7605
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
---
license: apache-2.0
base_model: unsloth/Llama-3.2-11B-Vision-Instruct-bnb-4bit
tags:
- medical
- radiology
- vqa
- vision-language
- unsloth
- lora
datasets:
- raidium/RadImageNet-VQA
language:
- en
metrics:
- loss
pipeline_tag: image-to-text
---

# RadInSight

**RadInSight**, tıbbi radyoloji görüntülerinin analizi ve bu görüntüler üzerine çok turlu (multi-turn) karmaşık diyaloglar yürütülmesi amacıyla özel olarak eğitilmiş, 11 milyar parametreli bir **Vizyon-Dil Modelidir (VLM)**. 

Model, `unsloth/Llama-3.2-11B-Vision-Instruct-bnb-4bit` temel modeli üzerine, radyoloji odaklı **RadImageNet-VQA** veriseti kullanılarak iki aşamalı bir finetuning (ince ayar) stratejisiyle Unsloth kütüphanesi yardımıyla optimize edilmiştir.

## 🚀 Öne Çıkan Özellikler
- **İki Aşamalı Eğitim (Alignment + Instruct):** Model önce görsel-metin hizalamasını öğrenmiş, ardından karmaşık tıbbi soru-cevap senaryolarında kararlı kalabilmesi için talimat (instruct) eğitimine tabi tutulmuştur.
- **Çok Turlu (Multi-turn) Diyalog Desteği:** Radyoloji görselleri üzerinde sadece tek bir soruya cevap vermekle kalmaz; bağlamı kaybetmeden hastanın/doktorun takip eden sorularını da yanıtlayabilir.
- **Deterministik ve Güvenli Çıkarım:** Medikal halüsinasyonları önlemek adına çıkarım parametreleri optimize edilmiş; çıktı akışındaki özel karakter sızıntıları (`<|eot_id|>`) tamamen engellenmiştir.

## 📊 Eğitim Detayları ve Loss Performansı

Eğitim süreci boyunca loss (kayıp) değerleri son derece kararlı ve keskin bir düşüş sergilemiştir:

- **1. Aşama (Alignment):** `4.82` seviyesinden başlayan loss değeri, görsel-metin eşleşmesinin hızla kavranmasıyla birlikte **`0.35`** seviyesine kadar gerilemiş ve başarılı bir plato yakalamıştır.
- **2. Aşama (Instruct):** Çok turlu diyalog yapısına geçildiğinde `2.81` seviyesinden başlayan loss, modelin karmaşık tıbbi senaryoları ezberlemeden (overfitting olmadan) sindirmesiyle birlikte **`0.15`** seviyesine kadar düşerek eğitimi kararlı bir şekilde tamamlamıştır.

## 🛠️ Kullanım Şekli (Inference)

Modeli kendi radyoloji projelerinizde çok turlu (multi-turn) bir sohbet döngüsüyle çalıştırmak ve en kararlı medikal sonuçları almak için aşağıdaki güncel kod bloğunu kullanabilirsiniz:

```python
import torch
from unsloth import FastVisionModel
from transformers import TextStreamer
from PIL import Image

# 1. Modeli ve Tokenizer'ı Yükleme
model, tokenizer = FastVisionModel.from_pretrained(
    model_name = "ahmet1338/RadInSight",
    load_in_4bit = True,
)
FastVisionModel.for_inference(model)

# 2. Radyoloji Görüntüsünü Yükleme
image_path = "YOUR_PIL_IMAGE_PATH" # Test edeceğiniz medikal görselin yolu
image = Image.open(image_path).convert("RGB")

# 3. Sohbet Geçmişi (Context) Yönetimi
chat_history = []

print("RadInSight Canlı Test Modu Başlatıldı. Çıkmak için 'exit' yazın.\n" + "="*50)

while True:
    user_question = input("User: ")
    if user_question.lower() == 'exit':
        break
        
    # İlk adımda görseli ve soruyu birlikte, sonraki adımlarda sadece metni ekliyoruz (Bağlam Koruma)
    if len(chat_history) == 0:
        new_message = {
            "role": "user",
            "content": [
                {"type": "image"},
                {"type": "text", "text": user_question}
            ]
        }
    else:
        new_message = {
            "role": "user",
            "content": [
                {"type": "text", "text": user_question}
            ]
        }
    
    chat_history.append(new_message)
    
    # 4. Tokenize ve Girdi Hazırlığı
    input_text = tokenizer.apply_chat_template(chat_history, add_generation_prompt=True)
    inputs = tokenizer(
        [image],
        input_text,
        add_special_tokens=False,
        return_tensors="pt",
    ).to("cuda")
    
    # 5. Deterministik Üretim Ayarları (Halüsinasyonu Önleme)
    outputs = model.generate(
        **inputs,
        max_new_tokens=512,
        use_cache=True,
        do_sample=False,   # En kararlı tıbbi yanıtlar için Greedy Decoding aktiftir
        temperature=0.0,   # Rastgeleliği sıfırlıyoruz
    )
    
    # 6. Çıktı Temizleme ve Ekrana Basma
    input_length = inputs.input_ids.shape[1]
    response_ids = outputs[0][input_length:]
    response_text = tokenizer.decode(response_ids, skip_special_tokens=True)
    
    # Özel belirteç sızıntılarını (<|eot_id|>) temizleme filtresi
    stop_tokens = ["<|eot_id|>", "<|im_end|>", "<|end_of_text|>", "</s>"]
    for token in stop_tokens:
        response_text = response_text.replace(token, "")
    response_text = response_text.strip()
    
    print(f"Assistant: {response_text}")
    
    # Cevabı geçmişe ekle
    chat_history.append({"role": "assistant", "content": [{"type": "text", "text": response_text}]})
    print("\n" + "-"*30)