--- 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|>", ""] 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)