Qwen-GroundingDINO-Visual-MCP
by tilikumotp
README.md
# qwen-groundingdino-visual-mcp
> **LM Studio + Qwen VL + GroundingDINO** — üretim kalitesinde açık-kelime dağarcıklı nesne tespiti ve zekice yerleştirme öneri motoru, MCP protokolü üzerinden.
---
## Mimari Özet
```
┌──────────────────────┐ stdio ┌──────────────────────────────────────┐
│ LM Studio │◄───────────►│ annotator_mcp.py │
│ Qwen VL (orkestratör)│ │ GroundingDINO (tespit motoru) │
│ function-calling UI │ │ Kural motoru (yerleştirme) │
└──────────────────────┘ │ Oturum belleği (session_memory.json) │
└──────────────────────────────────────┘
```
| Bileşen | Teknoloji | Notlar |
|---|---|---|
| Orkestratör LLM | Qwen VL (LM Studio'da) | Multimodal; ne zaman hangi tool'u çağıracağına kendisi karar verir |
| Tespit motoru | `IDEA-Research/grounding-dino-base` | `transformers` üzerinden, **trust_remote_code=False** |
| Transport | stdio | HTTP/ağ bağlantısı **yoktur** |
| Model format | safetensors | GGUF/llama.cpp ile **hiçbir ilgisi yoktur** |
---
## Kurulum
### 1. Python sanal ortamı oluştur
```bash
python -m venv .venv
# Windows
.venv\Scripts\activate
# Linux/macOS
source .venv/bin/activate
```
### 2. Bağımlılıkları yükle
**CPU-only (varsayılan):**
```bash
pip install -r requirements.txt
```
**CUDA 12.1 (GPU hızlandırma):**
```bash
pip install torch==2.4.1+cu121 torchvision==0.19.1+cu121 \
--index-url https://download.pytorch.org/whl/cu121
# Geri kalanı (torch'u tekrar yüklememek için --no-deps kullanma, sadece requirements'i yükle)
pip install transformers==4.44.2 accelerate==0.34.2 huggingface_hub==0.25.1 \
Pillow==10.4.0 numpy==1.26.4 mcp==1.3.0 tokenizers==0.19.1
```
**CUDA 11.8:**
```bash
pip install torch==2.4.1+cu118 torchvision==0.19.1+cu118 \
--index-url https://download.pytorch.org/whl/cu118
# ardından yukarıdaki diğer paketleri yükle
```
### 3. Sözdizimi doğrulaması
```bash
python -m py_compile annotator_mcp.py && echo "OK — sözdizimi hatası yok"
```
### 4. Model ön-indirme (isteğe bağlı)
İlk tool çağrısında model otomatik indirilir. İnternetsiz ortamlar için önden indirebilirsiniz:
```bash
python -c "
from transformers import AutoProcessor, AutoModelForZeroShotObjectDetection
AutoProcessor.from_pretrained('IDEA-Research/grounding-dino-base')
AutoModelForZeroShotObjectDetection.from_pretrained('IDEA-Research/grounding-dino-base')
print('Model önbelleğe alındı.')
"
```
---
## LM Studio Yapılandırması — `mcp.json`
LM Studio'nun MCP ayarlar dosyasına aşağıdaki bloğu ekleyin:
```json
{
"mcpServers": {
"groundingdino-annotator": {
"command": "python",
"args": [
"C:/Users/ASUS/Projects/qwen-groundingdino-visual-mcp/annotator_mcp.py"
],
"env": {
"GROUNDING_DINO_MODEL_ID": "IDEA-Research/grounding-dino-base",
"BOX_THRESHOLD": "0.35",
"TEXT_THRESHOLD": "0.25"
}
}
}
}
```
> **Not:** `command` için sanal ortamdaki Python yolunu kullanmak daha güvenlidir:
> `"C:/Users/ASUS/Projects/qwen-groundingdino-visual-mcp/.venv/Scripts/python.exe"`
### Hafif model (daha az bellek):
```json
"GROUNDING_DINO_MODEL_ID": "IDEA-Research/grounding-dino-tiny"
```
---
## Örnek Sohbet Akışı
### Senaryo: "Masadaki vazoyu bul, ardından yanına bir kupa öner"
```
Kullanıcı:
C:/sahne/mutfak.jpg görüntüsündeki masayı ve vazoyu bul.
Qwen → detect_objects({
"image_path": "C:/sahne/mutfak.jpg",
"query": "masa, vazo",
"session_id": "mutfak_sahnesi"
})
Sunucu yanıtı:
{
"session_id": "mutfak_sahnesi",
"count": 2,
"detections": [
{ "label": "masa", "score": 0.82, "bbox": [120, 450, 880, 950] },
{ "label": "vazo", "score": 0.74, "bbox": [400, 200, 600, 450] }
]
}
---
Kullanıcı:
Vazonun sağına ideal kupa yerleştirme noktasını öner.
Qwen → suggest_ideal_placements({
"session_id": "mutfak_sahnesi",
"target_object": "kupa",
"reference_object": "vazo",
"relation": "right_of"
})
Sunucu yanıtı:
{
"suggested_bbox": [610, 250, 760, 440],
"score": 0.8712,
"rule_breakdown": {
"overlap_penalty": 1.0,
"edge_margin": 0.82,
"spacing_from_objects": 0.61,
"prefer_center": 0.73
}
}
---
Kullanıcı:
Bu koordinatları görüntüye çiz ve kaydet.
Qwen → annotate_image({
"image_path": "C:/sahne/mutfak.jpg",
"output_path": "C:/sahne/mutfak_annotated.jpg",
"session_id": "mutfak_sahnesi",
"annotations": [
{ "label": "masa", "bbox": [120, 450, 880, 950] },
{ "label": "vazo", "bbox": [400, 200, 600, 450] },
{ "label": "kupa", "bbox": [610, 250, 760, 440] }
]
})
Sonuç: 3 nesne kırmızı çerçeve + etiketle işaretlenmiş görüntü kaydedildi.
```
---
## Koordinat Sistemi
Tüm bbox koordinatları **0-1000 normalize skalasında** `[x1, y1, x2, y2]` formatındadır:
```
(0,0) ─────────────── (1000,0)
│ │
│ görüntü alanı │
│ │
(0,1000) ───────────(1000,1000)
```
Bu skala Qwen VL'nin koordinat çıktısıyla tutarlıdır.
---
## Tool Referansı
| Tool | Amaç | Zorunlu Parametreler |
|------|-------|----------------------|
| `detect_objects` | GroundingDINO tespiti | `image_path`, `query` |
| `register_detected_objects` | Manuel nesne kaydı | `session_id`, `objects` |
| `annotate_image` | Görüntü üzerine çizim | `image_path`, `output_path`, `annotations` |
| `suggest_ideal_placements` | Yerleştirme önerisi | `session_id`, `target_object` |
| `list_session_objects` | Oturum durumu | `session_id` |
| `reset_session` | Bellek temizleme | `session_id` |
---
## Doğrulama Testi
Aşağıdaki Python betiği, MCP olmadan doğrudan sunucunun tespit fonksiyonunu test eder:
```python
# test_detect.py
import sys
sys.path.insert(0, ".")
from annotator_mcp import format_groundingdino_query, _run_detection_sync
# 1. Sorgu formatlama testi
q = format_groundingdino_query("Masa, VAZO, Kapı")
assert q == "masa . vazo . kapı .", f"Beklenen 'masa . vazo . kapı .' ama '{q}' geldi"
print(f"✓ format_groundingdino_query: '{q}'")
# 2. Gerçek tespit testi (bir görüntü gerektirir)
TEST_IMAGE = "test.jpg" # Var olan bir .jpg yolu girin
import os
if os.path.isfile(TEST_IMAGE):
results = _run_detection_sync(
image_path=TEST_IMAGE,
query="insan, masa, sandalye",
box_threshold=0.35,
text_threshold=0.25,
session_id="test_session",
)
print(f"✓ Tespit tamamlandı: {len(results)} nesne bulundu")
for r in results:
print(f" [{r['label']:15s}] skor={r['score']:.3f} bbox={r['bbox']}")
else:
print(f"⚠ {TEST_IMAGE} bulunamadı — tespit adımı atlandı")
print("\n✓ Tüm birim testler geçti.")
```
Çalıştırma:
```bash
python test_detect.py
```
Beklenen çıktı formatı:
```json
{
"session_id": "test_session",
"count": 2,
"detections": [
{ "label": "masa", "score": 0.7812, "bbox": [45, 380, 955, 920] },
{ "label": "sandalye","score": 0.6531, "bbox": [20, 420, 300, 890] }
]
}
```
---
## ⚠️ Bilinen Tuzaklar
> Bu bölüm, proje geliştirme sırasında gerçekten yaşanan sorunları belgeler.
> Gelecekteki geliştiriciler ve AI sistemleri için rehber niteliğindedir.
### 1. GGUF vs safetensors karışıklığı
**Sorun:** GroundingDINO'yu LM Studio'nun GGUF/llama.cpp arayüzüyle yüklemeye çalışmak.
**Belirti:** `gguf_init_from_reader: tensor name too long` veya benzeri anlamsız hatalar.
**Neden:** GroundingDINO (ve genel olarak tüm `trust_remote_code`/özel mimari modeller) llama.cpp ekosistemiyle **uyumlu değildir**. Bu model safetensors formatındadır ve GGUF'a dönüştürülemez.
**Çözüm:** Model **yalnızca** bu Python süreci içinde `transformers.from_pretrained()` ile, orijinal safetensors formatında yönetilmelidir. LM Studio'nun model arayüzüne **hiç dokunmayın**.
---
### 2. transformers sürüm uyumsuzluğu
**Sorun:** `requirements.txt`'te `transformers` sürümü pinlenmemişse en güncel sürüm kurulabilir ve API kırılabilir.
**Belirti:** `TypeError: post_process_grounded_object_detection() got unexpected keyword argument 'input_ids'` veya tam tersi.
**Neden:** `post_process_grounded_object_detection`'ın fonksiyon imzası transformers sürümleri arasında değişmiştir.
**Çözüm (bu projede uygulanmıştır):** `requirements.txt`'te `transformers==4.44.2` olarak pinlendi. Ek olarak kod, yeni imzayı dener; `TypeError` alırsa eski imzaya otomatik düşer (try/except cascade). Yine de sürümü değiştirmeden önce mutlaka test edin.
---
### 3. Event loop bloklanması
**Sorun:** `_run_detection_sync()` veya `_find_best_placement_sync()` async `call_tool` handler'ından `asyncio.to_thread` olmadan doğrudan çağrılırsa.
**Belirti:** Inference süresince (1-5 saniye) MCP sunucusu tüm diğer isteklere (ping, iptal) kilitlenir.
**Çözüm (bu projede uygulanmıştır):** Tüm CPU/GPU-bound fonksiyonlar `await asyncio.to_thread(...)` ile sarılmıştır. Hiçbir zaman bu sarımı kaldırmayın.
---
### 4. Hayali dosya yolu (Hallucinated image_path)
**Sorun:** LLM, sohbete sürükle-bırak yapılan bir görseli "gördüğü" için (base64 olarak) bazen bu görselin disk yolunu uydurabilir.
**Belirti:** `FileNotFoundError: 'C:/imagined/path.jpg'`
**Neden:** Model görseli base64 olarak görüyor; gerçek disk yolunu bilmiyor.
**Çözüm:**
- Tool description'larında açıkça belirtilmiştir: `image_path` gerçek bir disk yolu olmalıdır.
- Kod, `Image.open()` başarısız olursa net hata döndürür: *"Dosya bulunamadı: ... Lütfen diskte gerçekten var olan bir dosya yolu belirtin."*
- Kullanıcıların her zaman gerçek dosya yolunu metin olarak yazması gerekir.
---
### 5. MCP handshake timeout
**Sorun:** Model `import` anında veya `annotator_mcp.py` başlangıcında yüklenirse.
**Belirti:** LM Studio, MCP sunucusunu başlatır ama ~3 saniye içinde handshake yanıtı alamaz ve bağlantıyı düşürür. Log: `MCP server connection timed out` veya benzeri.
**Neden:** Model yükleme (1-2 GB safetensors, birkaç saniye) handshake penceresini aşıyor.
**Çözüm (bu projede uygulanmıştır):** Lazy loading zorunludur. `_model = None` ile başlar; `load_model()` yalnızca **ilk tool çağrısında** tetiklenir. `torch` ve `transformers` import'ları da `load_model()` içinde yapılır (yavaş import'ları geciktirmek için).
---
### 6. Florence-2 ile karıştırma
**Sorun:** Florence-2 gibi `trust_remote_code=True` gerektiren modellerin kurulum mantığını GroundingDINO'ya uygulamak.
**Fark:** GroundingDINO, transformers 4.38+ sürümünde resmi olarak entegre edilmiştir ve `trust_remote_code` gerektirmez. Bu, Florence-2'ye göre önemli bir **kararlılık avantajıdır** — remote code her güncellemede kırılabilir, resmi entegre kod kırılmaz.
**Çözüm:** `from_pretrained()` çağrılarında `trust_remote_code` parametresi hiç kullanmayın.
---
## Proje Yapısı
```
qwen-groundingdino-visual-mcp/
├── annotator_mcp.py # Ana MCP sunucusu (tek dosya, tüm mantık burada)
├── requirements.txt # Sabit sürümlü bağımlılıklar
├── README.md # Bu dosya
└── session_memory.json # Çalışma zamanında oluşturulur (otomatik)
```
---
## Lisans
MIT — Dilediğiniz gibi kullanın, değiştirin ve dağıtın.
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues