Refactor Gradio app to support Turkish localization, enhance UI with modern design elements, and improve data management with comprehensive error handling. Update configuration settings for better clarity and usability.
Browse files- README.md +199 -50
- api_service.py +255 -0
- app.py +26 -444
- config.py +17 -17
- data_manager.py +78 -74
- test_submission.py +1 -0
- ui_analytics.py +8 -0
- ui_evaluation_requests.py +147 -0
- ui_leaderboard.py +43 -0
- ui_main.py +47 -0
- ui_model_responses.py +9 -0
- ui_submit_model.py +91 -0
- ui_utils.py +64 -0
- utils.py +270 -250
README.md
CHANGED
@@ -10,90 +10,239 @@ license: cc-by-nc-4.0
|
|
10 |
short_description: Leaderboard showcasing Turkish MMLU dataset results.
|
11 |
---
|
12 |
|
13 |
-
# 🏆
|
14 |
|
15 |
-
|
16 |
|
17 |
-
## ✨
|
18 |
|
19 |
-
|
20 |
-
- 🔍 **Model Responses Browser**: Browse through all 6,200 questions and model answers with pagination
|
21 |
-
- 📈 **Performance Analytics**: Visualize section-wise performance with interactive charts
|
22 |
-
- ➕ **Model Submission**: Submit new models for evaluation
|
23 |
-
- 🎨 **Clean UI**: Modern, responsive design with beautiful styling
|
24 |
|
25 |
-
|
|
|
|
|
|
|
26 |
|
27 |
-
###
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
- Python 3.8+
|
30 |
-
-
|
31 |
|
32 |
-
###
|
33 |
|
34 |
-
1.
|
35 |
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
|
41 |
-
2.
|
42 |
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
|
47 |
-
3.
|
48 |
|
49 |
-
|
50 |
-
|
51 |
-
|
|
|
|
|
52 |
|
53 |
-
|
|
|
|
|
54 |
|
55 |
-
## 📁
|
56 |
|
57 |
```
|
58 |
turkish_mmlu_leaderboard/
|
59 |
-
├── app.py
|
60 |
-
├── config.py
|
61 |
-
├── data_manager.py
|
62 |
-
├── utils.py
|
63 |
-
├── requirements.txt
|
64 |
-
├── Dockerfile
|
65 |
-
└── README.md
|
66 |
```
|
67 |
|
68 |
-
##
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
|
70 |
-
|
71 |
|
72 |
-
- **
|
73 |
-
- **
|
74 |
-
- **
|
|
|
75 |
|
76 |
-
|
77 |
|
78 |
-
|
|
|
|
|
|
|
79 |
|
80 |
-
|
81 |
-
- **Model Responses**: Individual model answers to questions
|
82 |
-
- **Section Results**: Performance breakdown by subject areas
|
83 |
|
84 |
-
|
85 |
|
86 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
|
88 |
```bash
|
|
|
89 |
docker build -t turkish-mmlu-leaderboard .
|
|
|
|
|
90 |
docker run -p 7860:7860 turkish-mmlu-leaderboard
|
91 |
```
|
92 |
|
93 |
-
##
|
94 |
|
95 |
-
|
96 |
|
97 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
|
99 |
-
|
|
|
10 |
short_description: Leaderboard showcasing Turkish MMLU dataset results.
|
11 |
---
|
12 |
|
13 |
+
# 🏆 Türkçe MMLU Liderlik Tablosu
|
14 |
|
15 |
+
Yapay zeka modellerinin Türkçe dil görevlerindeki kapsamlı değerlendirmesi ve performans karşılaştırması için modern bir web uygulaması.
|
16 |
|
17 |
+
## ✨ Özellikler
|
18 |
|
19 |
+
### 📊 Liderlik Tablosu
|
|
|
|
|
|
|
|
|
20 |
|
21 |
+
- Model performanslarının kapsamlı sıralaması
|
22 |
+
- Aile ve kuantalama seviyesine göre filtreleme
|
23 |
+
- Gerçek zamanlı skor güncellemeleri
|
24 |
+
- Etkileşimli ve responsive tablo görünümü
|
25 |
|
26 |
+
### 🔍 Model Cevapları
|
27 |
+
|
28 |
+
- 6.200+ soru ve model cevabını göz atma
|
29 |
+
- Gelişmiş arama ve filtreleme seçenekleri
|
30 |
+
- Sayfalama ile hızlı navigasyon
|
31 |
+
- Çoklu model karşılaştırması
|
32 |
+
|
33 |
+
### 📈 Performans Analitikleri
|
34 |
+
|
35 |
+
- Bölüm bazında detaylı performans grafikleri
|
36 |
+
- Etkileşimli Plotly görselleştirmeleri
|
37 |
+
- Model karşılaştırmaları
|
38 |
+
- İstatistiksel özetler
|
39 |
+
|
40 |
+
### ➕ Model Gönderimi
|
41 |
+
|
42 |
+
- Yeni model kayıt formu
|
43 |
+
- Detaylı doğrulama kontrolü
|
44 |
+
- Model türü ve hassasiyet seçenekleri
|
45 |
+
- Otomatik değerlendirme kuyruğu entegrasyonu
|
46 |
+
|
47 |
+
## 🚀 Kurulum
|
48 |
+
|
49 |
+
### Gereksinimler
|
50 |
|
51 |
- Python 3.8+
|
52 |
+
- Pip paket yöneticisi
|
53 |
|
54 |
+
### Hızlı Başlangıç
|
55 |
|
56 |
+
1. **Repoyu klonlayın**
|
57 |
|
58 |
+
```bash
|
59 |
+
git clone <repository-url>
|
60 |
+
cd turkish_mmlu_leaderboard
|
61 |
+
```
|
62 |
|
63 |
+
2. **Bağımlılıkları yükleyin**
|
64 |
|
65 |
+
```bash
|
66 |
+
pip install -r requirements.txt
|
67 |
+
```
|
68 |
|
69 |
+
3. **Uygulamayı çalıştırın**
|
70 |
|
71 |
+
```bash
|
72 |
+
python app.py
|
73 |
+
```
|
74 |
+
|
75 |
+
4. **Tarayıcınızda açın**
|
76 |
|
77 |
+
```
|
78 |
+
http://localhost:7860
|
79 |
+
```
|
80 |
|
81 |
+
## 📁 Proje Yapısı
|
82 |
|
83 |
```
|
84 |
turkish_mmlu_leaderboard/
|
85 |
+
├── app.py # Ana uygulama dosyası (Türkçe arayüz)
|
86 |
+
├── config.py # Yapılandırma ayarları (Türkçe etiketler)
|
87 |
+
├── data_manager.py # Veri yönetimi ve önbellekleme
|
88 |
+
├── utils.py # Yardımcı fonksiyonlar (Türkçe mesajlar)
|
89 |
+
├── requirements.txt # Python bağımlılıkları
|
90 |
+
├── Dockerfile # Docker yapılandırması
|
91 |
+
└── README.md # Bu dosya
|
92 |
```
|
93 |
|
94 |
+
## 🎨 Arayüz Özellikleri
|
95 |
+
|
96 |
+
### Modern Tasarım
|
97 |
+
|
98 |
+
- **Temiz ve minimal görünüm**: Kullanıcı dostu arayüz tasarımı
|
99 |
+
- **Responsive design**: Tüm cihazlarda uyumlu görüntüleme
|
100 |
+
- **Gradient efektler**: Modern görsel öğeler
|
101 |
+
- **Hover animasyonları**: Etkileşimli buton ve tablo efektleri
|
102 |
|
103 |
+
### Türkçe Yerelleştirme
|
104 |
|
105 |
+
- **Tam Türkçe arayüz**: Tüm menüler, butonlar ve mesajlar Türkçe
|
106 |
+
- **Türkçe hata mesajları**: Anlaşılır hata açıklamaları
|
107 |
+
- **Türkçe veri etiketleri**: Tablo başlıkları ve sütun adları
|
108 |
+
- **Türkçe durum mesajları**: Sistem bilgilendirmeleri
|
109 |
|
110 |
+
### Gelişmiş Özellikler
|
111 |
|
112 |
+
- **Gerçek zamanlı veri güncellemesi**: Otomatik yenileme
|
113 |
+
- **Önbellekleme sistemi**: Hızlı veri erişimi
|
114 |
+
- **Thread-safe işlemler**: Güvenilir veri yönetimi
|
115 |
+
- **Hata toleransı**: Robust hata işleme
|
116 |
|
117 |
+
## 📊 Veri Kaynakları
|
|
|
|
|
118 |
|
119 |
+
Uygulama aşağıdaki Hugging Face veri kümelerini kullanır:
|
120 |
|
121 |
+
1. **Liderlik Tablosu**: `alibayram/yapay_zeka_turkce_mmlu_liderlik_tablosu`
|
122 |
+
2. **Model Cevapları**: `alibayram/yapay_zeka_turkce_mmlu_model_cevaplari`
|
123 |
+
3. **Bölüm Sonuçları**: `alibayram/yapay_zeka_turkce_mmlu_bolum_sonuclari`
|
124 |
+
|
125 |
+
## 🔧 Yapılandırma
|
126 |
+
|
127 |
+
### Temel Ayarlar
|
128 |
+
|
129 |
+
```python
|
130 |
+
# config.py içinde
|
131 |
+
SERVER_PORT = 7860
|
132 |
+
REFRESH_INTERVAL = 1800 # 30 dakika
|
133 |
+
CACHE_TIMEOUT = 3600 # 1 saat
|
134 |
+
```
|
135 |
+
|
136 |
+
### UI Özelleştirme
|
137 |
+
|
138 |
+
- CSS stilleri `config.py` dosyasında tanımlanmıştır
|
139 |
+
- Renk şemaları ve gradient efektler özelleştirilebilir
|
140 |
+
- Responsif breakpoint'ler mobil uyumluluk için ayarlanmıştır
|
141 |
+
|
142 |
+
## 🚀 Docker ile Çalıştırma
|
143 |
|
144 |
```bash
|
145 |
+
# Docker image oluştur
|
146 |
docker build -t turkish-mmlu-leaderboard .
|
147 |
+
|
148 |
+
# Konteyner çalıştır
|
149 |
docker run -p 7860:7860 turkish-mmlu-leaderboard
|
150 |
```
|
151 |
|
152 |
+
## 🔄 Güncellemeler ve Yenilemeye
|
153 |
|
154 |
+
### Otomatik Yenileme
|
155 |
|
156 |
+
- Veriler her 30 dakikada bir otomatik güncellenir
|
157 |
+
- Arkaplan görevleri scheduler ile yönetilir
|
158 |
+
- Hata durumunda fallback verileri kullanılır
|
159 |
+
|
160 |
+
### Manuel Yenileme
|
161 |
+
|
162 |
+
- "Yenile" butonları ile anlık güncelleme
|
163 |
+
- Cache temizleme seçenekleri
|
164 |
+
- Veri durumu görüntüleme
|
165 |
+
|
166 |
+
## 🛠️ Geliştirme
|
167 |
+
|
168 |
+
### Kod Yapısı
|
169 |
+
|
170 |
+
- **Modüler tasarım**: Her bileşen ayrı dosyada
|
171 |
+
- **Type hints**: Python 3.8+ tip belirteçleri
|
172 |
+
- **Logging**: Kapsamlı hata takibi
|
173 |
+
- **Error handling**: Graceful hata yönetimi
|
174 |
+
|
175 |
+
### Katkıda Bulunma
|
176 |
+
|
177 |
+
1. Fork yapın
|
178 |
+
2. Feature branch oluşturun (`git checkout -b feature/yeni-ozellik`)
|
179 |
+
3. Değişikliklerinizi commit edin (`git commit -am 'Yeni özellik eklendi'`)
|
180 |
+
4. Branch'i push edin (`git push origin feature/yeni-ozellik`)
|
181 |
+
5. Pull Request açın
|
182 |
+
|
183 |
+
## 📝 Çeviri Notları
|
184 |
+
|
185 |
+
Bu uygulama tamamen Türkçe'ye çevrilmiştir:
|
186 |
+
|
187 |
+
### Çevrilen Bileşenler
|
188 |
+
|
189 |
+
- ✅ Tüm UI etiketleri ve butonlar
|
190 |
+
- ✅ Hata mesajları ve uyarılar
|
191 |
+
- ✅ Tablo başlıkları ve sütun adları
|
192 |
+
- ✅ Form alanları ve placeholder metinleri
|
193 |
+
- ✅ Durum mesajları ve bildirimler
|
194 |
+
- ✅ Tooltip'ler ve yardım metinleri
|
195 |
+
- ✅ Log mesajları ve debugging bilgileri
|
196 |
+
|
197 |
+
### Korunun Öğeler
|
198 |
+
|
199 |
+
- Model isimleri (orijinal haliyle)
|
200 |
+
- Teknik parametreler (precision, quantization)
|
201 |
+
- Dataset path'leri ve URL'ler
|
202 |
+
- CSS class isimleri ve JS fonksiyonları
|
203 |
+
|
204 |
+
## 🐛 Sorun Giderme
|
205 |
+
|
206 |
+
### Yaygın Sorunlar
|
207 |
+
|
208 |
+
1. **Uygulama başlatılamıyor**
|
209 |
+
|
210 |
+
```bash
|
211 |
+
# Bağımlılıkları kontrol edin
|
212 |
+
pip install -r requirements.txt
|
213 |
+
|
214 |
+
# Port çakışması kontrolü
|
215 |
+
lsof -i :7860
|
216 |
+
```
|
217 |
+
|
218 |
+
2. **Veri yüklenmiyor**
|
219 |
+
|
220 |
+
- İnternet bağlantınızı kontrol edin
|
221 |
+
- Hugging Face erişiminizi doğrulayın
|
222 |
+
- Cache klasörü izinlerini kontrol edin
|
223 |
+
|
224 |
+
3. **Yavaş performans**
|
225 |
+
- Cache ayarlarını kontrol edin
|
226 |
+
- Page size değerlerini azaltın
|
227 |
+
- Browser cache'ini temizleyin
|
228 |
+
|
229 |
+
## 📄 Lisans
|
230 |
+
|
231 |
+
Bu proje MIT lisansı altında lisanslanmıştır. Detaylar için LICENSE dosyasına bakın.
|
232 |
+
|
233 |
+
## 👨💻 Geliştirici
|
234 |
+
|
235 |
+
**Ali Bayram**
|
236 |
+
|
237 |
+
- GitHub: [@alibayram](https://github.com/alibayram)
|
238 |
+
- Hugging Face: [@alibayram](https://huggingface.co/alibayram)
|
239 |
+
|
240 |
+
## 🙏 Teşekkürler
|
241 |
+
|
242 |
+
- Hugging Face ekibine veri hosting için
|
243 |
+
- Gradio ekibine harika UI framework için
|
244 |
+
- Türkçe NLP topluluğuna katkıları için
|
245 |
+
|
246 |
+
---
|
247 |
|
248 |
+
**Not**: Bu uygulama sürekli geliştirme altındadır. Geri bildirimleriniz ve katkılarınız çok değerlidir!
|
api_service.py
ADDED
@@ -0,0 +1,255 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import logging
|
2 |
+
from datetime import datetime
|
3 |
+
from typing import Dict, List, Optional
|
4 |
+
|
5 |
+
import requests
|
6 |
+
|
7 |
+
logger = logging.getLogger(__name__)
|
8 |
+
|
9 |
+
class APIService:
|
10 |
+
"""API servisi - model değerlendirme verilerini API'den alır."""
|
11 |
+
|
12 |
+
def __init__(self, api_url: str = None):
|
13 |
+
self.api_url = api_url or "https://getmodeldetails-tf2nev5rqa-uc.a.run.app" # Updated API URL
|
14 |
+
self.session = requests.Session()
|
15 |
+
self.session.timeout = 30 # 30 saniye timeout
|
16 |
+
|
17 |
+
def check_api_connection(self) -> bool:
|
18 |
+
"""API bağlantısını test et."""
|
19 |
+
try:
|
20 |
+
response = self.session.get(self.api_url, timeout=10)
|
21 |
+
if response.status_code == 200:
|
22 |
+
logger.info("API bağlantısı başarılı")
|
23 |
+
return True
|
24 |
+
else:
|
25 |
+
logger.warning(f"API bağlantısı başarısız: HTTP {response.status_code}")
|
26 |
+
return False
|
27 |
+
except Exception as e:
|
28 |
+
logger.error(f"API bağlantı testi başarısız: {e}")
|
29 |
+
return False
|
30 |
+
|
31 |
+
def get_evaluation_models(self, limit: int = 100) -> List[Dict]:
|
32 |
+
"""Değerlendirme modellerini API'den getir."""
|
33 |
+
try:
|
34 |
+
response = self.session.get(self.api_url, timeout=30)
|
35 |
+
|
36 |
+
if response.status_code == 200:
|
37 |
+
data = response.json()
|
38 |
+
|
39 |
+
# API yanıt yapısını kontrol et
|
40 |
+
if isinstance(data, dict) and 'models' in data:
|
41 |
+
models = data['models']
|
42 |
+
elif isinstance(data, list):
|
43 |
+
models = data
|
44 |
+
else:
|
45 |
+
logger.error(f"Beklenmeyen API yanıt formatı: {type(data)}")
|
46 |
+
return []
|
47 |
+
|
48 |
+
# Limit uygula
|
49 |
+
if limit and len(models) > limit:
|
50 |
+
models = models[:limit]
|
51 |
+
|
52 |
+
# Her modeli formatla
|
53 |
+
formatted_models = []
|
54 |
+
for model in models:
|
55 |
+
if isinstance(model, dict):
|
56 |
+
formatted_models.append(self._format_model_data(model))
|
57 |
+
else:
|
58 |
+
logger.warning(f"Model verisi dict değil: {type(model)}")
|
59 |
+
|
60 |
+
logger.info(f"{len(formatted_models)} model başarıyla alındı")
|
61 |
+
return formatted_models
|
62 |
+
else:
|
63 |
+
logger.error(f"API'den veri alma hatası: HTTP {response.status_code}")
|
64 |
+
return []
|
65 |
+
|
66 |
+
except Exception as e:
|
67 |
+
logger.error(f"Model listesi alma hatası: {e}")
|
68 |
+
return []
|
69 |
+
|
70 |
+
def get_model_details(self, model_name: str) -> Optional[Dict]:
|
71 |
+
"""Belirli bir modelin detaylarını API'den getir (model adına göre)."""
|
72 |
+
try:
|
73 |
+
# Önce tüm modelleri al
|
74 |
+
models = self.get_evaluation_models()
|
75 |
+
|
76 |
+
# Model adına göre ara
|
77 |
+
for model in models:
|
78 |
+
if model.get('model') == model_name:
|
79 |
+
logger.info(f"Model bulundu: {model_name}")
|
80 |
+
return model
|
81 |
+
|
82 |
+
logger.warning(f"Model bulunamadı: {model_name}")
|
83 |
+
return None
|
84 |
+
|
85 |
+
except Exception as e:
|
86 |
+
logger.error(f"Model detayları alma hatası: {e}")
|
87 |
+
return None
|
88 |
+
|
89 |
+
def add_evaluation_request(self, model_data: Dict) -> bool:
|
90 |
+
"""Yeni değerlendirme isteği ekle (API destekliyorsa)."""
|
91 |
+
try:
|
92 |
+
# POST isteği ile yeni model ekle
|
93 |
+
response = self.session.post(self.api_url, json=model_data, timeout=30)
|
94 |
+
|
95 |
+
if response.status_code in [200, 201]:
|
96 |
+
logger.info("Yeni değerlendirme isteği başarıyla eklendi")
|
97 |
+
return True
|
98 |
+
else:
|
99 |
+
logger.error(f"Değerlendirme isteği ekleme hatası: HTTP {response.status_code}")
|
100 |
+
return False
|
101 |
+
|
102 |
+
except Exception as e:
|
103 |
+
logger.error(f"Değerlendirme isteği ekleme hatası: {e}")
|
104 |
+
return False
|
105 |
+
|
106 |
+
def update_model_status(self, model_id: str, status: str, progress: float = None, basari: float = None) -> bool:
|
107 |
+
"""Model durumunu güncelle (API destekliyorsa)."""
|
108 |
+
try:
|
109 |
+
# PUT/PATCH isteği ile model güncelle
|
110 |
+
update_data = {
|
111 |
+
'status': status
|
112 |
+
}
|
113 |
+
|
114 |
+
if progress is not None:
|
115 |
+
update_data['progress'] = progress
|
116 |
+
|
117 |
+
if basari is not None:
|
118 |
+
update_data['basari'] = basari
|
119 |
+
|
120 |
+
update_url = f"{self.api_url}/{model_id}"
|
121 |
+
response = self.session.patch(update_url, json=update_data, timeout=30)
|
122 |
+
|
123 |
+
if response.status_code in [200, 204]:
|
124 |
+
logger.info(f"Model durumu güncellendi: {model_id} - {status}")
|
125 |
+
return True
|
126 |
+
else:
|
127 |
+
logger.error(f"Model durumu güncelleme hatası: HTTP {response.status_code}")
|
128 |
+
return False
|
129 |
+
|
130 |
+
except Exception as e:
|
131 |
+
logger.error(f"Model durumu güncelleme hatası: {e}")
|
132 |
+
return False
|
133 |
+
|
134 |
+
def _format_model_data(self, model_data: Dict) -> Dict:
|
135 |
+
"""Model verilerini görüntüleme için formatla."""
|
136 |
+
try:
|
137 |
+
formatted_data = model_data.copy()
|
138 |
+
|
139 |
+
# Timestamp'leri formatla (ISO string formatından)
|
140 |
+
if 'updated_at' in formatted_data:
|
141 |
+
try:
|
142 |
+
# ISO string formatını parse et
|
143 |
+
updated_at = datetime.fromisoformat(formatted_data['updated_at'].replace('Z', '+00:00'))
|
144 |
+
formatted_data['updated_at_formatted'] = updated_at.strftime('%d/%m/%Y %H:%M:%S')
|
145 |
+
except:
|
146 |
+
formatted_data['updated_at_formatted'] = formatted_data['updated_at']
|
147 |
+
|
148 |
+
if 'created_at' in formatted_data:
|
149 |
+
try:
|
150 |
+
created_at = datetime.fromisoformat(formatted_data['created_at'].replace('Z', '+00:00'))
|
151 |
+
formatted_data['created_at_formatted'] = created_at.strftime('%d/%m/%Y %H:%M:%S')
|
152 |
+
except:
|
153 |
+
formatted_data['created_at_formatted'] = formatted_data['created_at']
|
154 |
+
|
155 |
+
# Progress'i yüzde olarak formatla
|
156 |
+
if 'progress' in formatted_data:
|
157 |
+
progress = formatted_data['progress']
|
158 |
+
if isinstance(progress, (int, float)):
|
159 |
+
formatted_data['progress_percent'] = f"{progress * 100:.2f}%"
|
160 |
+
else:
|
161 |
+
formatted_data['progress_percent'] = "0.00%"
|
162 |
+
|
163 |
+
# Başarı oranını formatla
|
164 |
+
if 'basari' in formatted_data:
|
165 |
+
basari = formatted_data['basari']
|
166 |
+
if isinstance(basari, (int, float)):
|
167 |
+
formatted_data['basari_percent'] = f"{basari:.2f}%"
|
168 |
+
else:
|
169 |
+
formatted_data['basari_percent'] = "0.00%"
|
170 |
+
|
171 |
+
# Status'u Türkçe'ye çevir
|
172 |
+
status_mapping = {
|
173 |
+
'pending': 'Beklemede',
|
174 |
+
'processing': 'İşleniyor',
|
175 |
+
'completed': 'Tamamlandı',
|
176 |
+
'failed': 'Başarısız',
|
177 |
+
'cancelled': 'İptal Edildi'
|
178 |
+
}
|
179 |
+
|
180 |
+
if 'status' in formatted_data:
|
181 |
+
status = formatted_data['status']
|
182 |
+
formatted_data['status_turkish'] = status_mapping.get(status, status)
|
183 |
+
|
184 |
+
# Ek alanları ekle
|
185 |
+
if 'user_email' not in formatted_data:
|
186 |
+
formatted_data['user_email'] = 'API'
|
187 |
+
|
188 |
+
if 'model_type' not in formatted_data:
|
189 |
+
formatted_data['model_type'] = formatted_data.get('family', 'Unknown')
|
190 |
+
|
191 |
+
if 'parameters' not in formatted_data:
|
192 |
+
formatted_data['parameters'] = formatted_data.get('parameter_size', 'Unknown')
|
193 |
+
|
194 |
+
return formatted_data
|
195 |
+
|
196 |
+
except Exception as e:
|
197 |
+
logger.error(f"Model verisi formatlama hatası: {e}")
|
198 |
+
return model_data
|
199 |
+
|
200 |
+
def submit_model(self, model_name: str, version: str) -> Dict:
|
201 |
+
"""Yeni model gönderimi yap."""
|
202 |
+
try:
|
203 |
+
submit_url = "https://submitmodel-tf2nev5rqa-uc.a.run.app"
|
204 |
+
|
205 |
+
# Request payload
|
206 |
+
payload = {
|
207 |
+
"model_name": model_name,
|
208 |
+
"version": version
|
209 |
+
}
|
210 |
+
|
211 |
+
# POST isteği ile model gönder
|
212 |
+
response = self.session.post(submit_url, json=payload, timeout=30)
|
213 |
+
|
214 |
+
if response.status_code == 201:
|
215 |
+
result = response.json()
|
216 |
+
if result.get('success'):
|
217 |
+
logger.info(f"Model başarıyla gönderildi: {model_name} v{version}")
|
218 |
+
return {
|
219 |
+
'success': True,
|
220 |
+
'message': result.get('message', 'Model başarıyla gönderildi'),
|
221 |
+
'data': result.get('data', {})
|
222 |
+
}
|
223 |
+
else:
|
224 |
+
logger.error(f"Model gönderimi başarısız: {result.get('error')}")
|
225 |
+
return {
|
226 |
+
'success': False,
|
227 |
+
'message': result.get('message', 'Model gönderimi başarısız'),
|
228 |
+
'error': result.get('error')
|
229 |
+
}
|
230 |
+
elif response.status_code == 400:
|
231 |
+
result = response.json()
|
232 |
+
logger.error(f"Model gönderimi hatası (400): {result.get('message')}")
|
233 |
+
return {
|
234 |
+
'success': False,
|
235 |
+
'message': result.get('message', 'Geçersiz veri'),
|
236 |
+
'error': result.get('error')
|
237 |
+
}
|
238 |
+
else:
|
239 |
+
logger.error(f"Model gönderimi hatası: HTTP {response.status_code}")
|
240 |
+
return {
|
241 |
+
'success': False,
|
242 |
+
'message': f'Server hatası: HTTP {response.status_code}',
|
243 |
+
'error': 'Server error'
|
244 |
+
}
|
245 |
+
|
246 |
+
except Exception as e:
|
247 |
+
logger.error(f"Model gönderimi hatası: {e}")
|
248 |
+
return {
|
249 |
+
'success': False,
|
250 |
+
'message': f'Bağlantı hatası: {str(e)}',
|
251 |
+
'error': str(e)
|
252 |
+
}
|
253 |
+
|
254 |
+
# Global API servisi örneği
|
255 |
+
api_service = APIService()
|
app.py
CHANGED
@@ -1,468 +1,50 @@
|
|
1 |
import logging
|
2 |
import sys
|
3 |
-
import time
|
4 |
-
from typing import Optional
|
5 |
|
6 |
-
import gradio as gr
|
7 |
-
import plotly.express as px
|
8 |
-
import plotly.graph_objects as go
|
9 |
from apscheduler.schedulers.background import BackgroundScheduler
|
10 |
|
11 |
from config import CONFIG
|
12 |
from data_manager import data_manager
|
13 |
-
from
|
14 |
|
15 |
logging.basicConfig(level=logging.INFO)
|
16 |
logger = logging.getLogger(__name__)
|
17 |
|
18 |
-
# Clean, minimal CSS
|
19 |
-
CLEAN_CSS = """
|
20 |
-
.gradio-container {
|
21 |
-
max-width: 1200px !important;
|
22 |
-
margin: 0 auto !important;
|
23 |
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
|
24 |
-
}
|
25 |
-
|
26 |
-
.main-header {
|
27 |
-
text-align: center;
|
28 |
-
background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);
|
29 |
-
color: white;
|
30 |
-
padding: 2rem;
|
31 |
-
border-radius: 12px;
|
32 |
-
margin-bottom: 2rem;
|
33 |
-
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
34 |
-
}
|
35 |
-
|
36 |
-
.main-header h1 {
|
37 |
-
font-size: 2.5rem !important;
|
38 |
-
font-weight: 700 !important;
|
39 |
-
margin-bottom: 0.5rem !important;
|
40 |
-
}
|
41 |
-
|
42 |
-
.main-header p {
|
43 |
-
font-size: 1.1rem !important;
|
44 |
-
opacity: 0.9;
|
45 |
-
}
|
46 |
-
|
47 |
-
.status-info {
|
48 |
-
background: #f8fafc;
|
49 |
-
border: 1px solid #e2e8f0;
|
50 |
-
border-radius: 8px;
|
51 |
-
padding: 1rem;
|
52 |
-
margin: 1rem 0;
|
53 |
-
font-size: 0.9rem;
|
54 |
-
color: #475569;
|
55 |
-
}
|
56 |
-
|
57 |
-
.gr-button {
|
58 |
-
border-radius: 8px !important;
|
59 |
-
font-weight: 500 !important;
|
60 |
-
}
|
61 |
-
|
62 |
-
.gr-dataframe {
|
63 |
-
border-radius: 8px !important;
|
64 |
-
border: 1px solid #e2e8f0 !important;
|
65 |
-
}
|
66 |
-
"""
|
67 |
-
|
68 |
-
def create_simple_plot():
|
69 |
-
"""Create a simple, clean plot."""
|
70 |
-
try:
|
71 |
-
df = data_manager.section_results_data
|
72 |
-
|
73 |
-
if df.empty:
|
74 |
-
fig = go.Figure()
|
75 |
-
fig.add_annotation(
|
76 |
-
text="No data available",
|
77 |
-
xref="paper", yref="paper",
|
78 |
-
x=0.5, y=0.5, xanchor='center', yanchor='middle',
|
79 |
-
showarrow=False,
|
80 |
-
font=dict(size=16, color="gray")
|
81 |
-
)
|
82 |
-
fig.update_layout(
|
83 |
-
title="Section Performance",
|
84 |
-
height=400,
|
85 |
-
plot_bgcolor='white'
|
86 |
-
)
|
87 |
-
return fig
|
88 |
-
|
89 |
-
# Simple bar chart
|
90 |
-
numeric_cols = df.select_dtypes(include=['number']).columns
|
91 |
-
if len(numeric_cols) > 0:
|
92 |
-
avg_scores = df[numeric_cols].mean()
|
93 |
-
|
94 |
-
fig = go.Figure(data=[
|
95 |
-
go.Bar(
|
96 |
-
x=avg_scores.index,
|
97 |
-
y=avg_scores.values,
|
98 |
-
marker_color='#4f46e5',
|
99 |
-
text=[f'{v:.1f}%' for v in avg_scores.values],
|
100 |
-
textposition='auto',
|
101 |
-
)
|
102 |
-
])
|
103 |
-
|
104 |
-
fig.update_layout(
|
105 |
-
title="Average Section Performance",
|
106 |
-
xaxis_title="Sections",
|
107 |
-
yaxis_title="Accuracy (%)",
|
108 |
-
height=400,
|
109 |
-
plot_bgcolor='white',
|
110 |
-
paper_bgcolor='white'
|
111 |
-
)
|
112 |
-
|
113 |
-
return fig
|
114 |
-
|
115 |
-
except Exception as e:
|
116 |
-
logger.error(f"Error creating plot: {e}")
|
117 |
-
fig = go.Figure()
|
118 |
-
fig.add_annotation(
|
119 |
-
text=f"Error: {str(e)}",
|
120 |
-
xref="paper", yref="paper",
|
121 |
-
x=0.5, y=0.5, xanchor='center', yanchor='middle',
|
122 |
-
showarrow=False,
|
123 |
-
font=dict(size=14, color="red")
|
124 |
-
)
|
125 |
-
fig.update_layout(title="Section Performance", height=400)
|
126 |
-
return fig
|
127 |
-
|
128 |
-
def create_clean_app():
|
129 |
-
"""Create a clean, simple Gradio app."""
|
130 |
-
|
131 |
-
# Get basic data info
|
132 |
-
try:
|
133 |
-
leaderboard_data = data_manager.leaderboard_data
|
134 |
-
responses_data = data_manager.responses_data
|
135 |
-
|
136 |
-
# Get available models for responses
|
137 |
-
available_models = []
|
138 |
-
if not responses_data.empty:
|
139 |
-
available_models = [col.replace("_cevap", "") for col in responses_data.columns if col.endswith("_cevap")]
|
140 |
-
|
141 |
-
data_status = f"✅ Loaded: {len(leaderboard_data)} leaderboard entries, {len(responses_data)} responses, {len(available_models)} models"
|
142 |
-
except Exception as e:
|
143 |
-
data_status = f"⚠️ Data loading issue: {str(e)}"
|
144 |
-
available_models = []
|
145 |
-
|
146 |
-
with gr.Blocks(css=CLEAN_CSS, title="Turkish MMLU Leaderboard") as app:
|
147 |
-
|
148 |
-
# Header
|
149 |
-
gr.HTML(f"""
|
150 |
-
<div class="main-header">
|
151 |
-
<h1>🏆 Turkish MMLU Leaderboard</h1>
|
152 |
-
<p>Comprehensive evaluation of AI models on Turkish language tasks</p>
|
153 |
-
</div>
|
154 |
-
""")
|
155 |
-
|
156 |
-
# Status
|
157 |
-
gr.HTML(f'<div class="status-info">{data_status}</div>')
|
158 |
-
|
159 |
-
with gr.Tabs():
|
160 |
-
|
161 |
-
# Leaderboard Tab
|
162 |
-
with gr.TabItem("📊 Leaderboard"):
|
163 |
-
gr.Markdown("### Model Performance Rankings")
|
164 |
-
|
165 |
-
with gr.Row():
|
166 |
-
family_filter = gr.Dropdown(
|
167 |
-
choices=["All"] + (leaderboard_data["family"].unique().tolist() if not leaderboard_data.empty else []),
|
168 |
-
label="Filter by Family",
|
169 |
-
value="All"
|
170 |
-
)
|
171 |
-
quantization_filter = gr.Dropdown(
|
172 |
-
choices=["All"] + (leaderboard_data["quantization_level"].unique().tolist() if not leaderboard_data.empty else []),
|
173 |
-
label="Filter by Quantization",
|
174 |
-
value="All"
|
175 |
-
)
|
176 |
-
filter_btn = gr.Button("Apply Filters", variant="primary")
|
177 |
-
|
178 |
-
leaderboard_table = gr.DataFrame(
|
179 |
-
value=leaderboard_data,
|
180 |
-
interactive=False,
|
181 |
-
wrap=True
|
182 |
-
)
|
183 |
-
|
184 |
-
def simple_filter(family, quantization):
|
185 |
-
try:
|
186 |
-
df = data_manager.leaderboard_data.copy()
|
187 |
-
if df.empty:
|
188 |
-
return df
|
189 |
-
|
190 |
-
if family and family != "All":
|
191 |
-
df = df[df["family"] == family]
|
192 |
-
if quantization and quantization != "All":
|
193 |
-
df = df[df["quantization_level"] == quantization]
|
194 |
-
|
195 |
-
if "score" in df.columns:
|
196 |
-
df = df.sort_values("score", ascending=False)
|
197 |
-
|
198 |
-
return df
|
199 |
-
except Exception as e:
|
200 |
-
logger.error(f"Filter error: {e}")
|
201 |
-
return data_manager.leaderboard_data
|
202 |
-
|
203 |
-
filter_btn.click(
|
204 |
-
simple_filter,
|
205 |
-
inputs=[family_filter, quantization_filter],
|
206 |
-
outputs=leaderboard_table
|
207 |
-
)
|
208 |
-
|
209 |
-
# Model Responses Tab
|
210 |
-
with gr.TabItem("🔍 Model Responses"):
|
211 |
-
gr.Markdown("### Browse Model Responses")
|
212 |
-
gr.Markdown("**Browse all 6,200 questions and model answers, or search for specific content.**")
|
213 |
-
|
214 |
-
with gr.Row():
|
215 |
-
model_dropdown = gr.Dropdown(
|
216 |
-
choices=available_models,
|
217 |
-
label="Select Model (Optional - leave empty to see all models)",
|
218 |
-
scale=2
|
219 |
-
)
|
220 |
-
query_input = gr.Textbox(
|
221 |
-
label="Search Query (Optional - leave empty to see all questions)",
|
222 |
-
placeholder="Enter keywords to search, or leave empty to browse all...",
|
223 |
-
scale=2
|
224 |
-
)
|
225 |
-
search_btn = gr.Button("Search/Browse", variant="primary", scale=1)
|
226 |
-
|
227 |
-
with gr.Row():
|
228 |
-
show_all_btn = gr.Button("📋 Show All Questions", variant="secondary")
|
229 |
-
refresh_btn = gr.Button("🔄 Refresh Models", variant="secondary")
|
230 |
-
page_size_dropdown = gr.Dropdown(
|
231 |
-
choices=[25, 50, 100, 200],
|
232 |
-
value=50,
|
233 |
-
label="Items per page",
|
234 |
-
scale=1
|
235 |
-
)
|
236 |
-
|
237 |
-
# Pagination controls
|
238 |
-
with gr.Row():
|
239 |
-
prev_btn = gr.Button("⬅️ Previous", variant="secondary", scale=1)
|
240 |
-
page_info = gr.HTML("<div style='text-align: center; padding: 10px;'>Page 1 of 124 (6,200 questions)</div>")
|
241 |
-
next_btn = gr.Button("Next ➡️", variant="secondary", scale=1)
|
242 |
-
|
243 |
-
with gr.Row():
|
244 |
-
page_input = gr.Number(
|
245 |
-
label="Go to page",
|
246 |
-
value=1,
|
247 |
-
minimum=1,
|
248 |
-
step=1,
|
249 |
-
scale=1
|
250 |
-
)
|
251 |
-
go_page_btn = gr.Button("Go", variant="secondary", scale=1)
|
252 |
-
|
253 |
-
gr.Markdown("💡 **Tip**: Use pagination to browse through all 6,200 questions! Leave both fields empty to see all model responses.")
|
254 |
-
|
255 |
-
# Initialize with some responses data
|
256 |
-
try:
|
257 |
-
from utils import get_all_responses, get_pagination_info
|
258 |
-
initial_responses = get_all_responses(model=None, page=1, page_size=50)
|
259 |
-
initial_page_info = get_pagination_info(page=1, page_size=50)
|
260 |
-
initial_page_html = f"<div style='text-align: center; padding: 12px; background: linear-gradient(135deg, #e0f2fe 0%, #f3e5f5 100%); border: 1px solid #b3e5fc; border-radius: 10px; color: #1565c0; font-weight: 500; box-shadow: 0 2px 4px rgba(0,0,0,0.1);'>📄 Page {initial_page_info['current_page']} of {initial_page_info['total_pages']} • Showing {initial_page_info['start_idx']}-{initial_page_info['end_idx']} of {initial_page_info['total_rows']} questions</div>"
|
261 |
-
except Exception as e:
|
262 |
-
logger.error(f"Error loading initial responses: {e}")
|
263 |
-
initial_responses = pd.DataFrame({"ℹ️ Info": ["Click 'Show All Questions' to load responses"]})
|
264 |
-
initial_page_html = "<div style='text-align: center; padding: 10px;'>Page 1 of 1 (0 items)</div>"
|
265 |
-
|
266 |
-
responses_table = gr.DataFrame(value=initial_responses, wrap=True)
|
267 |
-
|
268 |
-
# State variables for pagination
|
269 |
-
current_page = gr.State(1)
|
270 |
-
current_query = gr.State("")
|
271 |
-
current_model = gr.State("")
|
272 |
-
current_page_size = gr.State(50)
|
273 |
-
|
274 |
-
# Update page info display with improved styling
|
275 |
-
page_info.value = initial_page_html
|
276 |
-
|
277 |
-
def refresh_models():
|
278 |
-
try:
|
279 |
-
responses_data = data_manager.responses_data
|
280 |
-
if not responses_data.empty:
|
281 |
-
models = [col.replace("_cevap", "") for col in responses_data.columns if col.endswith("_cevap")]
|
282 |
-
return gr.Dropdown(choices=models, value=None)
|
283 |
-
return gr.Dropdown(choices=[], value=None)
|
284 |
-
except Exception as e:
|
285 |
-
logger.error(f"Refresh error: {e}")
|
286 |
-
return gr.Dropdown(choices=[], value=None)
|
287 |
-
|
288 |
-
def show_all_responses(page_size):
|
289 |
-
"""Show all responses without any filters"""
|
290 |
-
from utils import get_all_responses, get_pagination_info
|
291 |
-
responses = get_all_responses(model=None, page=1, page_size=page_size)
|
292 |
-
page_info_data = get_pagination_info(page=1, page_size=page_size)
|
293 |
-
page_html = f"<div style='text-align: center; padding: 12px; background: linear-gradient(135deg, #e0f2fe 0%, #f3e5f5 100%); border: 1px solid #b3e5fc; border-radius: 10px; color: #1565c0; font-weight: 500; box-shadow: 0 2px 4px rgba(0,0,0,0.1);'>📄 Page {page_info_data['current_page']} of {page_info_data['total_pages']} • Showing {page_info_data['start_idx']}-{page_info_data['end_idx']} of {page_info_data['total_rows']} questions</div>"
|
294 |
-
return responses, page_html, 1, "", "", page_size
|
295 |
-
|
296 |
-
def search_with_pagination(query, model, page, page_size):
|
297 |
-
"""Search with pagination support"""
|
298 |
-
from utils import get_pagination_info, search_responses
|
299 |
-
responses = search_responses(query, model, page, page_size)
|
300 |
-
|
301 |
-
# Get pagination info
|
302 |
-
if query and query.strip():
|
303 |
-
# For search results, we need to calculate based on search results
|
304 |
-
page_html = f"<div style='text-align: center; padding: 12px; background: linear-gradient(135deg, #fff3cd 0%, #ffeaa7 100%); border: 1px solid #fdcb6e; border-radius: 10px; color: #d63031; font-weight: 500; box-shadow: 0 2px 4px rgba(0,0,0,0.1);'>🔍 Search results for '{query}' • Page {page}</div>"
|
305 |
-
else:
|
306 |
-
page_info_data = get_pagination_info(page, page_size)
|
307 |
-
page_html = f"<div style='text-align: center; padding: 12px; background: linear-gradient(135deg, #e0f2fe 0%, #f3e5f5 100%); border: 1px solid #b3e5fc; border-radius: 10px; color: #1565c0; font-weight: 500; box-shadow: 0 2px 4px rgba(0,0,0,0.1);'>📄 Page {page_info_data['current_page']} of {page_info_data['total_pages']} • Showing {page_info_data['start_idx']}-{page_info_data['end_idx']} of {page_info_data['total_rows']} questions</div>"
|
308 |
-
|
309 |
-
return responses, page_html, page, query, model, page_size
|
310 |
-
|
311 |
-
def go_to_page(page_num, query, model, page_size):
|
312 |
-
"""Go to specific page"""
|
313 |
-
page_num = max(1, int(page_num)) if page_num else 1
|
314 |
-
return search_with_pagination(query, model, page_num, page_size)
|
315 |
-
|
316 |
-
def next_page(current_page_val, query, model, page_size):
|
317 |
-
"""Go to next page"""
|
318 |
-
from utils import get_pagination_info
|
319 |
-
page_info_data = get_pagination_info(current_page_val, page_size)
|
320 |
-
if page_info_data['has_next']:
|
321 |
-
return search_with_pagination(query, model, current_page_val + 1, page_size)
|
322 |
-
return search_with_pagination(query, model, current_page_val, page_size)
|
323 |
-
|
324 |
-
def prev_page(current_page_val, query, model, page_size):
|
325 |
-
"""Go to previous page"""
|
326 |
-
if current_page_val > 1:
|
327 |
-
return search_with_pagination(query, model, current_page_val - 1, page_size)
|
328 |
-
return search_with_pagination(query, model, current_page_val, page_size)
|
329 |
-
|
330 |
-
def change_page_size(new_page_size, query, model):
|
331 |
-
"""Change page size and reset to page 1"""
|
332 |
-
return search_with_pagination(query, model, 1, new_page_size)
|
333 |
-
|
334 |
-
# Event handlers
|
335 |
-
search_btn.click(
|
336 |
-
search_with_pagination,
|
337 |
-
inputs=[query_input, model_dropdown, current_page, current_page_size],
|
338 |
-
outputs=[responses_table, page_info, current_page, current_query, current_model, current_page_size]
|
339 |
-
)
|
340 |
-
|
341 |
-
show_all_btn.click(
|
342 |
-
show_all_responses,
|
343 |
-
inputs=[current_page_size],
|
344 |
-
outputs=[responses_table, page_info, current_page, current_query, current_model, current_page_size]
|
345 |
-
)
|
346 |
-
|
347 |
-
next_btn.click(
|
348 |
-
next_page,
|
349 |
-
inputs=[current_page, current_query, current_model, current_page_size],
|
350 |
-
outputs=[responses_table, page_info, current_page, current_query, current_model, current_page_size]
|
351 |
-
)
|
352 |
-
|
353 |
-
prev_btn.click(
|
354 |
-
prev_page,
|
355 |
-
inputs=[current_page, current_query, current_model, current_page_size],
|
356 |
-
outputs=[responses_table, page_info, current_page, current_query, current_model, current_page_size]
|
357 |
-
)
|
358 |
-
|
359 |
-
go_page_btn.click(
|
360 |
-
go_to_page,
|
361 |
-
inputs=[page_input, current_query, current_model, current_page_size],
|
362 |
-
outputs=[responses_table, page_info, current_page, current_query, current_model, current_page_size]
|
363 |
-
)
|
364 |
-
|
365 |
-
page_size_dropdown.change(
|
366 |
-
change_page_size,
|
367 |
-
inputs=[page_size_dropdown, current_query, current_model],
|
368 |
-
outputs=[responses_table, page_info, current_page, current_query, current_model, current_page_size]
|
369 |
-
)
|
370 |
-
|
371 |
-
refresh_btn.click(
|
372 |
-
refresh_models,
|
373 |
-
outputs=model_dropdown
|
374 |
-
)
|
375 |
-
|
376 |
-
# Analytics Tab
|
377 |
-
with gr.TabItem("📈 Analytics"):
|
378 |
-
gr.Markdown("### Performance Analytics")
|
379 |
-
|
380 |
-
plot_output = gr.Plot(value=create_simple_plot())
|
381 |
-
|
382 |
-
gr.Markdown("### Section Results")
|
383 |
-
section_table = gr.DataFrame(
|
384 |
-
value=data_manager.section_results_data,
|
385 |
-
wrap=True
|
386 |
-
)
|
387 |
-
|
388 |
-
# Submit Model Tab
|
389 |
-
with gr.TabItem("➕ Submit Model"):
|
390 |
-
gr.Markdown("### Submit Your Model")
|
391 |
-
gr.Markdown("Add your model to the leaderboard for evaluation.")
|
392 |
-
|
393 |
-
with gr.Row():
|
394 |
-
with gr.Column():
|
395 |
-
model_name = gr.Textbox(label="Model Name", placeholder="Enter model name")
|
396 |
-
base_model = gr.Textbox(label="Base Model", placeholder="Enter base model")
|
397 |
-
revision = gr.Textbox(label="Revision", value="main")
|
398 |
-
|
399 |
-
with gr.Column():
|
400 |
-
precision = gr.Dropdown(
|
401 |
-
choices=CONFIG["model"].precision_options,
|
402 |
-
label="Precision",
|
403 |
-
value="float16"
|
404 |
-
)
|
405 |
-
weight_type = gr.Dropdown(
|
406 |
-
choices=CONFIG["model"].weight_types,
|
407 |
-
label="Weight Type",
|
408 |
-
value="Original"
|
409 |
-
)
|
410 |
-
model_type = gr.Dropdown(
|
411 |
-
choices=CONFIG["model"].model_types,
|
412 |
-
label="Model Type",
|
413 |
-
value="Transformer"
|
414 |
-
)
|
415 |
-
|
416 |
-
submit_btn = gr.Button("Submit Model", variant="primary")
|
417 |
-
submission_output = gr.HTML()
|
418 |
-
|
419 |
-
def handle_submission(*args):
|
420 |
-
try:
|
421 |
-
is_valid, message = validate_model_submission(*args)
|
422 |
-
if is_valid:
|
423 |
-
return f'<div style="color: green; padding: 10px; border: 1px solid green; border-radius: 5px;">✅ {message}</div>'
|
424 |
-
else:
|
425 |
-
return f'<div style="color: red; padding: 10px; border: 1px solid red; border-radius: 5px;">❌ {message}</div>'
|
426 |
-
except Exception as e:
|
427 |
-
return f'<div style="color: red; padding: 10px; border: 1px solid red; border-radius: 5px;">❌ Error: {str(e)}</div>'
|
428 |
-
|
429 |
-
submit_btn.click(
|
430 |
-
handle_submission,
|
431 |
-
inputs=[model_name, base_model, revision, precision, weight_type, model_type],
|
432 |
-
outputs=submission_output
|
433 |
-
)
|
434 |
-
|
435 |
-
# Footer
|
436 |
-
gr.HTML("""
|
437 |
-
<div style="text-align: center; padding: 20px; color: #64748b; border-top: 1px solid #e2e8f0; margin-top: 40px;">
|
438 |
-
<p>🏆 Turkish MMLU Leaderboard • Built with Gradio</p>
|
439 |
-
</div>
|
440 |
-
""")
|
441 |
-
|
442 |
-
return app
|
443 |
-
|
444 |
def main():
|
445 |
try:
|
446 |
-
#
|
447 |
scheduler = BackgroundScheduler()
|
448 |
scheduler.add_job(
|
449 |
data_manager.refresh_datasets,
|
450 |
-
|
451 |
-
|
|
|
|
|
452 |
)
|
453 |
scheduler.start()
|
454 |
-
|
455 |
-
|
|
|
456 |
app = create_clean_app()
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
|
|
|
|
|
|
462 |
)
|
|
|
|
|
|
|
463 |
except Exception as e:
|
464 |
-
logger.error(f"
|
465 |
sys.exit(1)
|
|
|
|
|
|
|
|
|
466 |
|
467 |
if __name__ == "__main__":
|
468 |
-
main()
|
|
|
1 |
import logging
|
2 |
import sys
|
|
|
|
|
3 |
|
|
|
|
|
|
|
4 |
from apscheduler.schedulers.background import BackgroundScheduler
|
5 |
|
6 |
from config import CONFIG
|
7 |
from data_manager import data_manager
|
8 |
+
from ui_main import create_clean_app
|
9 |
|
10 |
logging.basicConfig(level=logging.INFO)
|
11 |
logger = logging.getLogger(__name__)
|
12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
def main():
|
14 |
try:
|
15 |
+
# Zamanlayıcıyı başlat
|
16 |
scheduler = BackgroundScheduler()
|
17 |
scheduler.add_job(
|
18 |
data_manager.refresh_datasets,
|
19 |
+
'interval',
|
20 |
+
minutes=CONFIG["dataset"].refresh_interval // 60,
|
21 |
+
id='dataset_refresh',
|
22 |
+
replace_existing=True
|
23 |
)
|
24 |
scheduler.start()
|
25 |
+
logger.info("Zamanlayıcı başlatıldı")
|
26 |
+
|
27 |
+
# Uygulamayı oluştur ve başlat
|
28 |
app = create_clean_app()
|
29 |
+
|
30 |
+
logger.info("Uygulama başlatılıyor...")
|
31 |
+
app.launch(
|
32 |
+
server_name=CONFIG["app"].server_name,
|
33 |
+
server_port=CONFIG["app"].server_port,
|
34 |
+
share=CONFIG["app"].share,
|
35 |
+
debug=CONFIG["app"].debug,
|
36 |
+
show_error=CONFIG["app"].show_error
|
37 |
)
|
38 |
+
|
39 |
+
except KeyboardInterrupt:
|
40 |
+
logger.info("Kullanıcı tarafından durduruldu")
|
41 |
except Exception as e:
|
42 |
+
logger.error(f"Uygulama başlatma hatası: {e}")
|
43 |
sys.exit(1)
|
44 |
+
finally:
|
45 |
+
if 'scheduler' in locals():
|
46 |
+
scheduler.shutdown()
|
47 |
+
logger.info("Zamanlayıcı durduruldu")
|
48 |
|
49 |
if __name__ == "__main__":
|
50 |
+
main()
|
config.py
CHANGED
@@ -8,18 +8,18 @@ class DatasetConfig:
|
|
8 |
responses_path: str = "hf://datasets/alibayram/yapay_zeka_turkce_mmlu_model_cevaplari/data/train-00000-of-00001.parquet"
|
9 |
section_results_path: str = "hf://datasets/alibayram/yapay_zeka_turkce_mmlu_bolum_sonuclari/data/train-00000-of-00001.parquet"
|
10 |
cache_dir: str = "cache"
|
11 |
-
refresh_interval: int = 1800 # 30
|
12 |
-
request_timeout: int = 60 #
|
13 |
max_retries: int = 5
|
14 |
-
retry_delay: int = 2 #
|
15 |
|
16 |
@dataclass
|
17 |
class UIConfig:
|
18 |
-
title: str = "🏆
|
19 |
-
description: str = "
|
20 |
theme: str = "soft"
|
21 |
css: str = """
|
22 |
-
/*
|
23 |
.gradio-container {
|
24 |
max-width: 1400px !important;
|
25 |
margin: 0 auto !important;
|
@@ -27,7 +27,7 @@ class UIConfig:
|
|
27 |
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
|
28 |
}
|
29 |
|
30 |
-
/*
|
31 |
.main-header {
|
32 |
text-align: center;
|
33 |
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
@@ -38,7 +38,7 @@ class UIConfig:
|
|
38 |
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
|
39 |
}
|
40 |
|
41 |
-
/*
|
42 |
.gr-button {
|
43 |
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
|
44 |
border: none !important;
|
@@ -55,7 +55,7 @@ class UIConfig:
|
|
55 |
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4) !important;
|
56 |
}
|
57 |
|
58 |
-
/*
|
59 |
.gr-dataframe {
|
60 |
border-radius: 15px !important;
|
61 |
overflow: hidden !important;
|
@@ -74,7 +74,7 @@ class UIConfig:
|
|
74 |
background-color: #f8f9ff !important;
|
75 |
}
|
76 |
|
77 |
-
/*
|
78 |
.card {
|
79 |
background: white;
|
80 |
border-radius: 15px;
|
@@ -84,7 +84,7 @@ class UIConfig:
|
|
84 |
margin-bottom: 20px;
|
85 |
}
|
86 |
|
87 |
-
/*
|
88 |
.success-message {
|
89 |
background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
|
90 |
color: white;
|
@@ -103,7 +103,7 @@ class UIConfig:
|
|
103 |
font-weight: 500;
|
104 |
}
|
105 |
|
106 |
-
/*
|
107 |
@media (max-width: 768px) {
|
108 |
.gradio-container {
|
109 |
padding: 10px !important;
|
@@ -122,12 +122,12 @@ class UIConfig:
|
|
122 |
@dataclass
|
123 |
class ModelConfig:
|
124 |
precision_options: List[str] = ("float16", "int8", "bfloat16", "float32", "int4")
|
125 |
-
weight_types: List[str] = ("
|
126 |
-
model_types: List[str] = ("Transformer", "RNN", "GPT", "BERT", "T5", "
|
127 |
|
128 |
@dataclass
|
129 |
class AppConfig:
|
130 |
-
"""
|
131 |
server_name: str = "0.0.0.0"
|
132 |
server_port: int = 7860
|
133 |
share: bool = False
|
@@ -139,9 +139,9 @@ class AppConfig:
|
|
139 |
|
140 |
@dataclass
|
141 |
class PerformanceConfig:
|
142 |
-
"""
|
143 |
enable_caching: bool = True
|
144 |
-
cache_timeout: int = 3600 # 1
|
145 |
max_cache_size: int = 100 # MB
|
146 |
enable_compression: bool = True
|
147 |
|
|
|
8 |
responses_path: str = "hf://datasets/alibayram/yapay_zeka_turkce_mmlu_model_cevaplari/data/train-00000-of-00001.parquet"
|
9 |
section_results_path: str = "hf://datasets/alibayram/yapay_zeka_turkce_mmlu_bolum_sonuclari/data/train-00000-of-00001.parquet"
|
10 |
cache_dir: str = "cache"
|
11 |
+
refresh_interval: int = 1800 # 30 dakika
|
12 |
+
request_timeout: int = 60 # saniye
|
13 |
max_retries: int = 5
|
14 |
+
retry_delay: int = 2 # saniye
|
15 |
|
16 |
@dataclass
|
17 |
class UIConfig:
|
18 |
+
title: str = "🏆 Türkçe MMLU Liderlik Tablosu"
|
19 |
+
description: str = "Yapay zeka modellerinin Türkçe dil görevlerindeki performansını keşfedin, değerlendirin ve karşılaştırın."
|
20 |
theme: str = "soft"
|
21 |
css: str = """
|
22 |
+
/* Geliştirilmiş Modern UI Stilleri */
|
23 |
.gradio-container {
|
24 |
max-width: 1400px !important;
|
25 |
margin: 0 auto !important;
|
|
|
27 |
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
|
28 |
}
|
29 |
|
30 |
+
/* Başlık Geliştirmeleri */
|
31 |
.main-header {
|
32 |
text-align: center;
|
33 |
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
38 |
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
|
39 |
}
|
40 |
|
41 |
+
/* Buton Geliştirmeleri */
|
42 |
.gr-button {
|
43 |
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
|
44 |
border: none !important;
|
|
|
55 |
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4) !important;
|
56 |
}
|
57 |
|
58 |
+
/* Tablo Geliştirmeleri */
|
59 |
.gr-dataframe {
|
60 |
border-radius: 15px !important;
|
61 |
overflow: hidden !important;
|
|
|
74 |
background-color: #f8f9ff !important;
|
75 |
}
|
76 |
|
77 |
+
/* Kart Stilleri */
|
78 |
.card {
|
79 |
background: white;
|
80 |
border-radius: 15px;
|
|
|
84 |
margin-bottom: 20px;
|
85 |
}
|
86 |
|
87 |
+
/* Durum Mesajları */
|
88 |
.success-message {
|
89 |
background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
|
90 |
color: white;
|
|
|
103 |
font-weight: 500;
|
104 |
}
|
105 |
|
106 |
+
/* Duyarlı Tasarım */
|
107 |
@media (max-width: 768px) {
|
108 |
.gradio-container {
|
109 |
padding: 10px !important;
|
|
|
122 |
@dataclass
|
123 |
class ModelConfig:
|
124 |
precision_options: List[str] = ("float16", "int8", "bfloat16", "float32", "int4")
|
125 |
+
weight_types: List[str] = ("Orijinal", "Delta", "Adaptör", "LoRA", "QLoRA")
|
126 |
+
model_types: List[str] = ("Transformer", "RNN", "GPT", "BERT", "T5", "Diğer")
|
127 |
|
128 |
@dataclass
|
129 |
class AppConfig:
|
130 |
+
"""Geliştirilmiş uygulama yapılandırması"""
|
131 |
server_name: str = "0.0.0.0"
|
132 |
server_port: int = 7860
|
133 |
share: bool = False
|
|
|
139 |
|
140 |
@dataclass
|
141 |
class PerformanceConfig:
|
142 |
+
"""Performans ve önbellekleme yapılandırması"""
|
143 |
enable_caching: bool = True
|
144 |
+
cache_timeout: int = 3600 # 1 saat
|
145 |
max_cache_size: int = 100 # MB
|
146 |
enable_compression: bool = True
|
147 |
|
data_manager.py
CHANGED
@@ -17,14 +17,14 @@ from config import CONFIG
|
|
17 |
logging.basicConfig(level=logging.INFO)
|
18 |
logger = logging.getLogger(__name__)
|
19 |
|
20 |
-
#
|
21 |
def create_retry_session(
|
22 |
retries=5,
|
23 |
backoff_factor=0.5,
|
24 |
status_forcelist=(500, 502, 503, 504),
|
25 |
timeout=30
|
26 |
):
|
27 |
-
"""
|
28 |
session = requests.Session()
|
29 |
retry = Retry(
|
30 |
total=retries,
|
@@ -53,7 +53,7 @@ class DataManager:
|
|
53 |
self._refresh_in_progress = False
|
54 |
|
55 |
def _is_cache_valid(self, data_type: str) -> bool:
|
56 |
-
"""
|
57 |
if data_type not in self._cache_timestamps:
|
58 |
return False
|
59 |
|
@@ -62,15 +62,15 @@ class DataManager:
|
|
62 |
return (datetime.now() - cache_time).seconds < cache_timeout
|
63 |
|
64 |
def _update_cache_timestamp(self, data_type: str):
|
65 |
-
"""
|
66 |
self._cache_timestamps[data_type] = datetime.now()
|
67 |
|
68 |
-
def _load_dataset(self, path: str, data_type: str = "
|
69 |
-
"""
|
70 |
|
71 |
-
#
|
72 |
if self._is_cache_valid(data_type):
|
73 |
-
logger.info(f"
|
74 |
return getattr(self, f"_{data_type}_data", pd.DataFrame())
|
75 |
|
76 |
attempts = 0
|
@@ -78,15 +78,15 @@ class DataManager:
|
|
78 |
|
79 |
while attempts < self._max_retries:
|
80 |
try:
|
81 |
-
logger.info(f"
|
82 |
|
83 |
-
#
|
84 |
df = pd.read_parquet(path, engine='pyarrow')
|
85 |
|
86 |
if df.empty:
|
87 |
-
logger.warning(f"
|
88 |
else:
|
89 |
-
logger.info(f"
|
90 |
self._update_cache_timestamp(data_type)
|
91 |
|
92 |
return df
|
@@ -94,22 +94,22 @@ class DataManager:
|
|
94 |
except Exception as e:
|
95 |
last_error = e
|
96 |
attempts += 1
|
97 |
-
logger.warning(f"
|
98 |
|
99 |
if attempts < self._max_retries:
|
100 |
-
wait_time = self._retry_delay * (2 ** (attempts - 1)) #
|
101 |
-
logger.info(f"
|
102 |
time.sleep(wait_time)
|
103 |
|
104 |
-
#
|
105 |
-
logger.error(f"
|
106 |
|
107 |
-
#
|
108 |
return self._create_fallback_data(data_type, path)
|
109 |
|
110 |
def _create_fallback_data(self, data_type: str, path: str) -> pd.DataFrame:
|
111 |
-
"""
|
112 |
-
logger.info(f"
|
113 |
|
114 |
if "leaderboard" in path.lower() or data_type == "leaderboard":
|
115 |
return self._create_fallback_leaderboard()
|
@@ -118,24 +118,24 @@ class DataManager:
|
|
118 |
elif "section" in path.lower() or data_type == "section_results":
|
119 |
return self._create_fallback_section_results()
|
120 |
else:
|
121 |
-
return pd.DataFrame({"
|
122 |
|
123 |
def _create_fallback_leaderboard(self) -> pd.DataFrame:
|
124 |
-
"""
|
125 |
-
logger.info("
|
126 |
return pd.DataFrame({
|
127 |
"model": ["GPT-4-Turbo", "Claude-3-Opus", "Gemini-Pro", "Llama-2-70B", "Mistral-7B"],
|
128 |
"family": ["OpenAI", "Anthropic", "Google", "Meta", "Mistral"],
|
129 |
-
"quantization_level": ["
|
130 |
"score": [85.2, 83.7, 81.4, 78.9, 75.3],
|
131 |
"timestamp": [pd.Timestamp.now()] * 5,
|
132 |
-
"parameters": ["1.76T", "
|
133 |
-
"license": ["
|
134 |
})
|
135 |
|
136 |
def _create_fallback_responses(self) -> pd.DataFrame:
|
137 |
-
"""
|
138 |
-
logger.info("
|
139 |
return pd.DataFrame({
|
140 |
"bolum": ["Matematik", "Tarih", "Coğrafya", "Edebiyat", "Fen"],
|
141 |
"soru": [
|
@@ -152,8 +152,8 @@ class DataManager:
|
|
152 |
})
|
153 |
|
154 |
def _create_fallback_section_results(self) -> pd.DataFrame:
|
155 |
-
"""
|
156 |
-
logger.info("
|
157 |
return pd.DataFrame({
|
158 |
"section": ["Matematik", "Tarih", "Coğrafya", "Edebiyat", "Fen", "Felsefe", "Sosyoloji"],
|
159 |
"GPT-4-Turbo": [88.5, 85.2, 82.7, 89.1, 86.3, 83.8, 81.4],
|
@@ -164,9 +164,9 @@ class DataManager:
|
|
164 |
})
|
165 |
|
166 |
def refresh_datasets(self) -> None:
|
167 |
-
"""
|
168 |
if self._refresh_in_progress:
|
169 |
-
logger.info("
|
170 |
return
|
171 |
|
172 |
with self._data_lock:
|
@@ -174,12 +174,12 @@ class DataManager:
|
|
174 |
self._refresh_in_progress = True
|
175 |
self._last_refresh_attempt = datetime.now()
|
176 |
|
177 |
-
logger.info("
|
178 |
|
179 |
-
#
|
180 |
os.makedirs(CONFIG["dataset"].cache_dir, exist_ok=True)
|
181 |
|
182 |
-
#
|
183 |
snapshot_download(
|
184 |
repo_id="alibayram",
|
185 |
repo_type="dataset",
|
@@ -188,98 +188,102 @@ class DataManager:
|
|
188 |
retry_delay_seconds=CONFIG["dataset"].retry_delay
|
189 |
)
|
190 |
|
191 |
-
#
|
192 |
self._leaderboard_data = None
|
193 |
self._responses_data = None
|
194 |
self._section_results_data = None
|
195 |
self._cache_timestamps.clear()
|
196 |
|
197 |
-
logger.info("
|
198 |
|
199 |
except Exception as e:
|
200 |
-
logger.error(f"
|
201 |
-
# Don't clear cache on error, keep existing data
|
202 |
-
|
203 |
finally:
|
204 |
self._refresh_in_progress = False
|
205 |
|
206 |
def get_refresh_status(self) -> Dict[str, any]:
|
207 |
-
"""
|
208 |
return {
|
209 |
-
"
|
210 |
-
"
|
211 |
-
"
|
212 |
}
|
213 |
|
214 |
@property
|
215 |
def leaderboard_data(self) -> pd.DataFrame:
|
216 |
-
"""
|
217 |
with self._data_lock:
|
218 |
-
if self._leaderboard_data is None
|
|
|
219 |
self._leaderboard_data = self._load_dataset(
|
220 |
CONFIG["dataset"].leaderboard_path,
|
221 |
"leaderboard"
|
222 |
)
|
223 |
-
return self._leaderboard_data.copy()
|
224 |
|
225 |
@property
|
226 |
def responses_data(self) -> pd.DataFrame:
|
227 |
-
"""
|
228 |
with self._data_lock:
|
229 |
-
if self._responses_data is None
|
|
|
230 |
self._responses_data = self._load_dataset(
|
231 |
CONFIG["dataset"].responses_path,
|
232 |
"responses"
|
233 |
)
|
234 |
-
return self._responses_data.copy()
|
235 |
|
236 |
@property
|
237 |
def section_results_data(self) -> pd.DataFrame:
|
238 |
-
"""
|
239 |
with self._data_lock:
|
240 |
-
if self._section_results_data is None
|
|
|
241 |
self._section_results_data = self._load_dataset(
|
242 |
CONFIG["dataset"].section_results_path,
|
243 |
"section_results"
|
244 |
)
|
245 |
-
return self._section_results_data.copy()
|
246 |
|
247 |
def get_data_summary(self) -> Dict[str, any]:
|
248 |
-
"""
|
249 |
try:
|
250 |
summary = {
|
251 |
-
"
|
252 |
-
"
|
253 |
-
"
|
254 |
-
"
|
255 |
-
"models": self.leaderboard_data["model"].nunique() if "model" in self.leaderboard_data.columns else 0
|
256 |
},
|
257 |
-
"
|
258 |
-
"
|
259 |
-
"
|
260 |
-
"
|
261 |
},
|
262 |
-
"
|
263 |
-
"
|
264 |
-
"
|
265 |
-
"
|
266 |
},
|
267 |
-
"
|
268 |
-
|
|
|
|
|
269 |
}
|
|
|
270 |
return summary
|
|
|
271 |
except Exception as e:
|
272 |
-
logger.error(f"
|
273 |
-
return {"
|
274 |
|
275 |
def clear_cache(self):
|
276 |
-
"""
|
277 |
with self._data_lock:
|
278 |
self._leaderboard_data = None
|
279 |
self._responses_data = None
|
280 |
self._section_results_data = None
|
281 |
self._cache_timestamps.clear()
|
282 |
-
logger.info("
|
283 |
|
284 |
-
# Global
|
285 |
data_manager = DataManager()
|
|
|
17 |
logging.basicConfig(level=logging.INFO)
|
18 |
logger = logging.getLogger(__name__)
|
19 |
|
20 |
+
# Yeniden deneme özellikli istekler yapılandır
|
21 |
def create_retry_session(
|
22 |
retries=5,
|
23 |
backoff_factor=0.5,
|
24 |
status_forcelist=(500, 502, 503, 504),
|
25 |
timeout=30
|
26 |
):
|
27 |
+
"""Yeniden deneme yetenekli requests oturumu oluştur"""
|
28 |
session = requests.Session()
|
29 |
retry = Retry(
|
30 |
total=retries,
|
|
|
53 |
self._refresh_in_progress = False
|
54 |
|
55 |
def _is_cache_valid(self, data_type: str) -> bool:
|
56 |
+
"""Zaman damgasına göre önbelleğe alınan verinin hala geçerli olup olmadığını kontrol et."""
|
57 |
if data_type not in self._cache_timestamps:
|
58 |
return False
|
59 |
|
|
|
62 |
return (datetime.now() - cache_time).seconds < cache_timeout
|
63 |
|
64 |
def _update_cache_timestamp(self, data_type: str):
|
65 |
+
"""Bir veri türü için önbellek zaman damgasını güncelle."""
|
66 |
self._cache_timestamps[data_type] = datetime.now()
|
67 |
|
68 |
+
def _load_dataset(self, path: str, data_type: str = "bilinmeyen") -> pd.DataFrame:
|
69 |
+
"""Geliştirilmiş hata işleme ve önbellekleme ile veri kümesi yükle."""
|
70 |
|
71 |
+
# Önce önbellek geçerliliğini kontrol et
|
72 |
if self._is_cache_valid(data_type):
|
73 |
+
logger.info(f"{data_type} için önbelleğe alınan veri kullanılıyor")
|
74 |
return getattr(self, f"_{data_type}_data", pd.DataFrame())
|
75 |
|
76 |
attempts = 0
|
|
|
78 |
|
79 |
while attempts < self._max_retries:
|
80 |
try:
|
81 |
+
logger.info(f"{path} yolundan veri kümesi yükleniyor (deneme {attempts+1}/{self._max_retries})")
|
82 |
|
83 |
+
# Zaman aşımı ve daha iyi hata işleme ekle
|
84 |
df = pd.read_parquet(path, engine='pyarrow')
|
85 |
|
86 |
if df.empty:
|
87 |
+
logger.warning(f"{path} yolundaki veri kümesi boş")
|
88 |
else:
|
89 |
+
logger.info(f"{path} yolundan {len(df)} satır başarıyla yüklendi")
|
90 |
self._update_cache_timestamp(data_type)
|
91 |
|
92 |
return df
|
|
|
94 |
except Exception as e:
|
95 |
last_error = e
|
96 |
attempts += 1
|
97 |
+
logger.warning(f"{path} yolundan veri kümesi yükleme hatası: {e}")
|
98 |
|
99 |
if attempts < self._max_retries:
|
100 |
+
wait_time = self._retry_delay * (2 ** (attempts - 1)) # Üstel geri çekilme
|
101 |
+
logger.info(f"{wait_time} saniye sonra tekrar denenecek...")
|
102 |
time.sleep(wait_time)
|
103 |
|
104 |
+
# Buraya geldiysek, tüm denemeler başarısız oldu
|
105 |
+
logger.error(f"{self._max_retries} deneme sonrası veri kümesi yüklenemedi: {last_error}")
|
106 |
|
107 |
+
# Uygun yedek dataframe döndür
|
108 |
return self._create_fallback_data(data_type, path)
|
109 |
|
110 |
def _create_fallback_data(self, data_type: str, path: str) -> pd.DataFrame:
|
111 |
+
"""Veri türüne göre yedek veri oluştur."""
|
112 |
+
logger.info(f"{data_type} için yedek veri oluşturuluyor")
|
113 |
|
114 |
if "leaderboard" in path.lower() or data_type == "leaderboard":
|
115 |
return self._create_fallback_leaderboard()
|
|
|
118 |
elif "section" in path.lower() or data_type == "section_results":
|
119 |
return self._create_fallback_section_results()
|
120 |
else:
|
121 |
+
return pd.DataFrame({"hata": ["Bilinmeyen veri türü"], "mesaj": [f"{path} yüklenemedi"]})
|
122 |
|
123 |
def _create_fallback_leaderboard(self) -> pd.DataFrame:
|
124 |
+
"""Kapsamlı yedek liderlik tablosu dataframe'i oluştur."""
|
125 |
+
logger.info("Yedek liderlik tablosu verisi oluşturuluyor")
|
126 |
return pd.DataFrame({
|
127 |
"model": ["GPT-4-Turbo", "Claude-3-Opus", "Gemini-Pro", "Llama-2-70B", "Mistral-7B"],
|
128 |
"family": ["OpenAI", "Anthropic", "Google", "Meta", "Mistral"],
|
129 |
+
"quantization_level": ["Yok", "Yok", "Yok", "float16", "int8"],
|
130 |
"score": [85.2, 83.7, 81.4, 78.9, 75.3],
|
131 |
"timestamp": [pd.Timestamp.now()] * 5,
|
132 |
+
"parameters": ["1.76T", "Bilinmiyor", "Bilinmiyor", "70B", "7B"],
|
133 |
+
"license": ["Mülkiyet", "Mülkiyet", "Mülkiyet", "Özel", "Apache 2.0"]
|
134 |
})
|
135 |
|
136 |
def _create_fallback_responses(self) -> pd.DataFrame:
|
137 |
+
"""Kapsamlı yedek cevaplar dataframe'i oluştur."""
|
138 |
+
logger.info("Yedek cevaplar verisi oluşturuluyor")
|
139 |
return pd.DataFrame({
|
140 |
"bolum": ["Matematik", "Tarih", "Coğrafya", "Edebiyat", "Fen"],
|
141 |
"soru": [
|
|
|
152 |
})
|
153 |
|
154 |
def _create_fallback_section_results(self) -> pd.DataFrame:
|
155 |
+
"""Kapsamlı yedek bölüm sonuçları dataframe'i oluştur."""
|
156 |
+
logger.info("Yedek bölüm sonuçları verisi oluşturuluyor")
|
157 |
return pd.DataFrame({
|
158 |
"section": ["Matematik", "Tarih", "Coğrafya", "Edebiyat", "Fen", "Felsefe", "Sosyoloji"],
|
159 |
"GPT-4-Turbo": [88.5, 85.2, 82.7, 89.1, 86.3, 83.8, 81.4],
|
|
|
164 |
})
|
165 |
|
166 |
def refresh_datasets(self) -> None:
|
167 |
+
"""Thread güvenliği ile tüm veri kümelerini kaynaktan yenile."""
|
168 |
if self._refresh_in_progress:
|
169 |
+
logger.info("Yenileme zaten devam ediyor, atlanıyor...")
|
170 |
return
|
171 |
|
172 |
with self._data_lock:
|
|
|
174 |
self._refresh_in_progress = True
|
175 |
self._last_refresh_attempt = datetime.now()
|
176 |
|
177 |
+
logger.info("Kapsamlı veri kümesi yenileme başlatılıyor...")
|
178 |
|
179 |
+
# Önbellek dizinini oluştur
|
180 |
os.makedirs(CONFIG["dataset"].cache_dir, exist_ok=True)
|
181 |
|
182 |
+
# En son verileri indir
|
183 |
snapshot_download(
|
184 |
repo_id="alibayram",
|
185 |
repo_type="dataset",
|
|
|
188 |
retry_delay_seconds=CONFIG["dataset"].retry_delay
|
189 |
)
|
190 |
|
191 |
+
# Önbelleğe alınan verileri yeniden yüklemek için temizle
|
192 |
self._leaderboard_data = None
|
193 |
self._responses_data = None
|
194 |
self._section_results_data = None
|
195 |
self._cache_timestamps.clear()
|
196 |
|
197 |
+
logger.info("Veri kümeleri başarıyla yenilendi")
|
198 |
|
199 |
except Exception as e:
|
200 |
+
logger.error(f"Veri kümeleri yenileme hatası: {e}")
|
|
|
|
|
201 |
finally:
|
202 |
self._refresh_in_progress = False
|
203 |
|
204 |
def get_refresh_status(self) -> Dict[str, any]:
|
205 |
+
"""Veri yenileme durumu hakkında bilgi al."""
|
206 |
return {
|
207 |
+
"yenileme_devam_ediyor": self._refresh_in_progress,
|
208 |
+
"son_yenileme_denemesi": self._last_refresh_attempt.isoformat() if self._last_refresh_attempt else None,
|
209 |
+
"onbellek_zaman_damgalari": {k: v.isoformat() for k, v in self._cache_timestamps.items()}
|
210 |
}
|
211 |
|
212 |
@property
|
213 |
def leaderboard_data(self) -> pd.DataFrame:
|
214 |
+
"""Thread-safe liderlik tablosu verisi alımı."""
|
215 |
with self._data_lock:
|
216 |
+
if self._leaderboard_data is None:
|
217 |
+
logger.info("Liderlik tablosu verileri yükleniyor...")
|
218 |
self._leaderboard_data = self._load_dataset(
|
219 |
CONFIG["dataset"].leaderboard_path,
|
220 |
"leaderboard"
|
221 |
)
|
222 |
+
return self._leaderboard_data.copy()
|
223 |
|
224 |
@property
|
225 |
def responses_data(self) -> pd.DataFrame:
|
226 |
+
"""Thread-safe cevaplar verisi alımı."""
|
227 |
with self._data_lock:
|
228 |
+
if self._responses_data is None:
|
229 |
+
logger.info("Cevaplar verileri yükleniyor...")
|
230 |
self._responses_data = self._load_dataset(
|
231 |
CONFIG["dataset"].responses_path,
|
232 |
"responses"
|
233 |
)
|
234 |
+
return self._responses_data.copy()
|
235 |
|
236 |
@property
|
237 |
def section_results_data(self) -> pd.DataFrame:
|
238 |
+
"""Thread-safe bölüm sonuçları verisi alımı."""
|
239 |
with self._data_lock:
|
240 |
+
if self._section_results_data is None:
|
241 |
+
logger.info("Bölüm sonuçları verileri yükleniyor...")
|
242 |
self._section_results_data = self._load_dataset(
|
243 |
CONFIG["dataset"].section_results_path,
|
244 |
"section_results"
|
245 |
)
|
246 |
+
return self._section_results_data.copy()
|
247 |
|
248 |
def get_data_summary(self) -> Dict[str, any]:
|
249 |
+
"""Tüm yüklenen verilerin özet bilgilerini al."""
|
250 |
try:
|
251 |
summary = {
|
252 |
+
"liderlik_tablosu": {
|
253 |
+
"satir_sayisi": len(self.leaderboard_data),
|
254 |
+
"sutun_sayisi": len(self.leaderboard_data.columns),
|
255 |
+
"sutunlar": list(self.leaderboard_data.columns) if not self.leaderboard_data.empty else []
|
|
|
256 |
},
|
257 |
+
"cevaplar": {
|
258 |
+
"satir_sayisi": len(self.responses_data),
|
259 |
+
"sutun_sayisi": len(self.responses_data.columns),
|
260 |
+
"sutunlar": list(self.responses_data.columns) if not self.responses_data.empty else []
|
261 |
},
|
262 |
+
"bolum_sonuclari": {
|
263 |
+
"satir_sayisi": len(self.section_results_data),
|
264 |
+
"sutun_sayisi": len(self.section_results_data.columns),
|
265 |
+
"sutunlar": list(self.section_results_data.columns) if not self.section_results_data.empty else []
|
266 |
},
|
267 |
+
"durum": {
|
268 |
+
"son_guncelleme": datetime.now().isoformat(),
|
269 |
+
"yenileme_devam_ediyor": self._refresh_in_progress
|
270 |
+
}
|
271 |
}
|
272 |
+
|
273 |
return summary
|
274 |
+
|
275 |
except Exception as e:
|
276 |
+
logger.error(f"Veri özeti alma hatası: {e}")
|
277 |
+
return {"hata": str(e), "mesaj": "Veri özeti alınamadı"}
|
278 |
|
279 |
def clear_cache(self):
|
280 |
+
"""Tüm önbelleğe alınan verileri ve zaman damgalarını temizle."""
|
281 |
with self._data_lock:
|
282 |
self._leaderboard_data = None
|
283 |
self._responses_data = None
|
284 |
self._section_results_data = None
|
285 |
self._cache_timestamps.clear()
|
286 |
+
logger.info("Tüm veri önbellekleri temizlendi")
|
287 |
|
288 |
+
# Global veri yöneticisi örneği
|
289 |
data_manager = DataManager()
|
test_submission.py
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
|
ui_analytics.py
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import pandas as pd
|
3 |
+
|
4 |
+
|
5 |
+
def add_analytics_tab(block, data_manager):
|
6 |
+
with gr.Tab("📈 Analitik"):
|
7 |
+
gr.Markdown("### Performans Analitikleri")
|
8 |
+
# (Move the rest of the tab code here, including plot and section table)
|
ui_evaluation_requests.py
ADDED
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import logging
|
2 |
+
|
3 |
+
import gradio as gr
|
4 |
+
import pandas as pd
|
5 |
+
|
6 |
+
logger = logging.getLogger(__name__)
|
7 |
+
|
8 |
+
def create_evaluation_models_table(api_service):
|
9 |
+
"""API'den değerlendirme modellerini al ve tablo oluştur."""
|
10 |
+
try:
|
11 |
+
models = api_service.get_evaluation_models(limit=20)
|
12 |
+
|
13 |
+
if not models:
|
14 |
+
return pd.DataFrame({
|
15 |
+
"ℹ️ Bilgi": ["Henüz değerlendirme isteği bulunmuyor"],
|
16 |
+
"💡 İpucu": ["İlk modelinizi göndermek için 'Model Gönder' sekmesini kullanın"]
|
17 |
+
})
|
18 |
+
|
19 |
+
# DataFrame oluştur (ID olmadan)
|
20 |
+
df_data = []
|
21 |
+
for model in models:
|
22 |
+
df_data.append({
|
23 |
+
"🤖 Model Adı": model.get('model', 'N/A'),
|
24 |
+
"📊 Durum": model.get('status_turkish', model.get('status', 'N/A')),
|
25 |
+
"📈 İlerleme": model.get('progress_percent', '0.00%'),
|
26 |
+
"🎯 Başarı": model.get('basari_percent', '0.00%'),
|
27 |
+
"📅 Son Güncelleme": model.get('updated_at_formatted', 'N/A'),
|
28 |
+
"👤 Kullanıcı": model.get('user_email', 'N/A'),
|
29 |
+
"🔧 Model Türü": model.get('model_type', 'N/A'),
|
30 |
+
"📏 Parametreler": model.get('parameters', 'N/A')
|
31 |
+
})
|
32 |
+
|
33 |
+
return pd.DataFrame(df_data)
|
34 |
+
|
35 |
+
except Exception as e:
|
36 |
+
logger.error(f"Değerlendirme modelleri tablosu oluşturma hatası: {e}")
|
37 |
+
return pd.DataFrame({
|
38 |
+
"❌ Hata": [f"Veri yükleme hatası: {str(e)}"],
|
39 |
+
"🔧 Durum": ["API bağlantısını kontrol edin"]
|
40 |
+
})
|
41 |
+
|
42 |
+
def get_model_details_html(model_name: str, api_service) -> str:
|
43 |
+
"""Model detaylarını HTML formatında getir."""
|
44 |
+
try:
|
45 |
+
# Model adına göre detayları al
|
46 |
+
models = api_service.get_evaluation_models()
|
47 |
+
model = None
|
48 |
+
|
49 |
+
for m in models:
|
50 |
+
if m.get('model') == model_name:
|
51 |
+
model = m
|
52 |
+
break
|
53 |
+
|
54 |
+
if not model:
|
55 |
+
return f'<div style="color: red; padding: 10px;">❌ Model bulunamadı: {model_name}</div>'
|
56 |
+
|
57 |
+
# HTML formatında detayları oluştur
|
58 |
+
html = f"""
|
59 |
+
<div style="background: #f8fafc; border-radius: 10px; padding: 20px; margin: 10px 0;">
|
60 |
+
<h3 style="color: #1e40af; margin-bottom: 15px;">🤖 Model Detayları</h3>
|
61 |
+
|
62 |
+
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px;">
|
63 |
+
<div>
|
64 |
+
<strong>Model Adı:</strong> {model.get('model', 'N/A')}<br>
|
65 |
+
<strong>Durum:</strong> <span style="color: #059669;">{model.get('status_turkish', 'N/A')}</span><br>
|
66 |
+
<strong>İlerleme:</strong> {model.get('progress_percent', '0.00%')}<br>
|
67 |
+
<strong>Başarı Oranı:</strong> {model.get('basari_percent', '0.00%')}<br>
|
68 |
+
</div>
|
69 |
+
<div>
|
70 |
+
<strong>Kullanıcı:</strong> {model.get('user_email', 'N/A')}<br>
|
71 |
+
<strong>Model Türü:</strong> {model.get('model_type', 'N/A')}<br>
|
72 |
+
<strong>Parametreler:</strong> {model.get('parameters', 'N/A')}<br>
|
73 |
+
<strong>Oluşturulma:</strong> {model.get('created_at_formatted', 'N/A')}<br>
|
74 |
+
</div>
|
75 |
+
</div>
|
76 |
+
|
77 |
+
<div style="margin-top: 15px; padding-top: 15px; border-top: 1px solid #e2e8f0;">
|
78 |
+
<strong>Son Güncelleme:</strong> {model.get('updated_at_formatted', 'N/A')}<br>
|
79 |
+
<strong>Model Adı:</strong> <code>{model.get('model', 'N/A')}</code>
|
80 |
+
</div>
|
81 |
+
</div>
|
82 |
+
"""
|
83 |
+
|
84 |
+
return html
|
85 |
+
|
86 |
+
except Exception as e:
|
87 |
+
logger.error(f"Model detayları alma hatası: {e}")
|
88 |
+
return f'<div style="color: red; padding: 10px;">❌ Detay alma hatası: {str(e)}</div>'
|
89 |
+
|
90 |
+
def add_evaluation_requests_tab(block, api_service):
|
91 |
+
with gr.Tab("📋 Değerlendirme İstekleri"):
|
92 |
+
gr.Markdown("### API Model Değerlendirme İstekleri")
|
93 |
+
gr.Markdown("**Kullanıcıların değerlendirme için gönderdiği modellerin durumunu takip edin.**")
|
94 |
+
|
95 |
+
with gr.Row():
|
96 |
+
refresh_eval_btn = gr.Button("🔄 Listeyi Yenile", variant="primary")
|
97 |
+
status_filter = gr.Dropdown(
|
98 |
+
choices=["Tümü", "Beklemede", "İşleniyor", "Tamamlandı", "Başarısız"],
|
99 |
+
label="Duruma Göre Filtrele",
|
100 |
+
value="Tümü"
|
101 |
+
)
|
102 |
+
|
103 |
+
# Model detayları için alan
|
104 |
+
model_details_output = gr.HTML()
|
105 |
+
|
106 |
+
# Değerlendirme modelleri tablosu
|
107 |
+
evaluation_table = gr.DataFrame(
|
108 |
+
value=create_evaluation_models_table(api_service),
|
109 |
+
wrap=True,
|
110 |
+
interactive=False
|
111 |
+
)
|
112 |
+
|
113 |
+
def refresh_evaluation_models():
|
114 |
+
"""Değerlendirme modellerini yenile"""
|
115 |
+
try:
|
116 |
+
return create_evaluation_models_table(api_service)
|
117 |
+
except Exception as e:
|
118 |
+
logger.error(f"Değerlendirme modelleri yenileme hatası: {e}")
|
119 |
+
return pd.DataFrame({
|
120 |
+
"❌ Hata": [f"Yenileme hatası: {str(e)}"],
|
121 |
+
"🔧 Durum": ["API bağlantısını kontrol edin"]
|
122 |
+
})
|
123 |
+
|
124 |
+
def show_model_details(evt: gr.SelectData):
|
125 |
+
"""Seçilen modelin detaylarını göster"""
|
126 |
+
try:
|
127 |
+
if evt.index[0] is not None:
|
128 |
+
# Tablodan model adını al
|
129 |
+
df = create_evaluation_models_table(api_service)
|
130 |
+
if not df.empty and evt.index[0] < len(df):
|
131 |
+
model_name = df.iloc[evt.index[0]]["🤖 Model Adı"]
|
132 |
+
return get_model_details_html(model_name, api_service)
|
133 |
+
return "<div style='color: gray; padding: 10px;'>Model seçin</div>"
|
134 |
+
except Exception as e:
|
135 |
+
logger.error(f"Model detayları gösterme hatası: {e}")
|
136 |
+
return f"<div style='color: red; padding: 10px;'>Hata: {str(e)}</div>"
|
137 |
+
|
138 |
+
# Event handlers
|
139 |
+
refresh_eval_btn.click(
|
140 |
+
refresh_evaluation_models,
|
141 |
+
outputs=evaluation_table
|
142 |
+
)
|
143 |
+
|
144 |
+
evaluation_table.select(
|
145 |
+
show_model_details,
|
146 |
+
outputs=model_details_output
|
147 |
+
)
|
ui_leaderboard.py
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import pandas as pd
|
3 |
+
|
4 |
+
|
5 |
+
def add_leaderboard_tab(block, leaderboard_data, data_manager, available_models):
|
6 |
+
with gr.Tab("📊 Liderlik Tablosu"):
|
7 |
+
gr.Markdown("### Model Performans Sıralaması")
|
8 |
+
with gr.Row():
|
9 |
+
family_filter = gr.Dropdown(
|
10 |
+
choices=["Tümü"] + (leaderboard_data["family"].unique().tolist() if not leaderboard_data.empty else []),
|
11 |
+
label="Aileye Göre Filtrele",
|
12 |
+
value="Tümü"
|
13 |
+
)
|
14 |
+
quantization_filter = gr.Dropdown(
|
15 |
+
choices=["Tümü"] + (leaderboard_data["quantization_level"].unique().tolist() if not leaderboard_data.empty else []),
|
16 |
+
label="Kuantalamaya Göre Filtrele",
|
17 |
+
value="Tümü"
|
18 |
+
)
|
19 |
+
filter_btn = gr.Button("Filtreleri Uygula", variant="primary")
|
20 |
+
leaderboard_table = gr.DataFrame(
|
21 |
+
value=leaderboard_data,
|
22 |
+
interactive=False,
|
23 |
+
wrap=True
|
24 |
+
)
|
25 |
+
def simple_filter(family, quantization):
|
26 |
+
try:
|
27 |
+
df = data_manager.leaderboard_data.copy()
|
28 |
+
if df.empty:
|
29 |
+
return df
|
30 |
+
if family and family != "Tümü":
|
31 |
+
df = df[df["family"] == family]
|
32 |
+
if quantization and quantization != "Tümü":
|
33 |
+
df = df[df["quantization_level"] == quantization]
|
34 |
+
if "score" in df.columns:
|
35 |
+
df = df.sort_values("score", ascending=False)
|
36 |
+
return df
|
37 |
+
except Exception as e:
|
38 |
+
return data_manager.leaderboard_data
|
39 |
+
filter_btn.click(
|
40 |
+
simple_filter,
|
41 |
+
inputs=[family_filter, quantization_filter],
|
42 |
+
outputs=leaderboard_table
|
43 |
+
)
|
ui_main.py
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
|
3 |
+
from api_service import api_service
|
4 |
+
from config import CONFIG
|
5 |
+
from data_manager import data_manager
|
6 |
+
from ui_analytics import add_analytics_tab
|
7 |
+
from ui_evaluation_requests import add_evaluation_requests_tab
|
8 |
+
from ui_leaderboard import add_leaderboard_tab
|
9 |
+
from ui_model_responses import add_model_responses_tab
|
10 |
+
from ui_submit_model import add_submit_model_tab
|
11 |
+
from ui_utils import CLEAN_CSS
|
12 |
+
|
13 |
+
|
14 |
+
def create_clean_app():
|
15 |
+
# Prepare data
|
16 |
+
leaderboard_data = data_manager.leaderboard_data
|
17 |
+
responses_data = data_manager.responses_data
|
18 |
+
available_models = []
|
19 |
+
try:
|
20 |
+
if not responses_data.empty:
|
21 |
+
available_models = [col.replace("_cevap", "") for col in responses_data.columns if col.endswith("_cevap")]
|
22 |
+
except Exception:
|
23 |
+
available_models = []
|
24 |
+
data_status = f"✅ Yüklendi: {len(leaderboard_data)} liderlik tablosu girişi, {len(responses_data)} cevap, {len(available_models)} model"
|
25 |
+
|
26 |
+
with gr.Blocks(css=CLEAN_CSS, title="Türkçe MMLU Liderlik Tablosu") as app:
|
27 |
+
gr.HTML(f"""
|
28 |
+
<div class=\"main-header\">
|
29 |
+
<h1>🏆 Türkçe MMLU Liderlik Tablosu</h1>
|
30 |
+
<p>Yapay zeka modellerinin Türkçe dil görevlerindeki kapsamlı değerlendirmesi</p>
|
31 |
+
</div>
|
32 |
+
""")
|
33 |
+
gr.HTML(f'<div class="status-info">{data_status}</div>')
|
34 |
+
|
35 |
+
with gr.Tabs() as tabs:
|
36 |
+
add_leaderboard_tab(tabs, leaderboard_data, data_manager, available_models)
|
37 |
+
add_model_responses_tab(tabs, data_manager, available_models)
|
38 |
+
add_evaluation_requests_tab(tabs, api_service)
|
39 |
+
add_analytics_tab(tabs, data_manager)
|
40 |
+
add_submit_model_tab(tabs, api_service)
|
41 |
+
|
42 |
+
gr.HTML("""
|
43 |
+
<div style=\"text-align: center; padding: 20px; color: #64748b; border-top: 1px solid #e2e8f0; margin-top: 40px;\">
|
44 |
+
<p>🏆 Türkçe MMLU Liderlik Tablosu • Gradio ile Geliştirildi</p>
|
45 |
+
</div>
|
46 |
+
""")
|
47 |
+
return app
|
ui_model_responses.py
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import pandas as pd
|
3 |
+
|
4 |
+
|
5 |
+
def add_model_responses_tab(block, data_manager, available_models):
|
6 |
+
with gr.Tab("🔍 Model Cevapları"):
|
7 |
+
gr.Markdown("### Model Cevaplarını Göz At")
|
8 |
+
gr.Markdown("**6.200 soruyu ve model cevaplarını göz atın veya belirli içerik arayın.**")
|
9 |
+
# (Move the rest of the tab code here, including search, pagination, and event handlers)
|
ui_submit_model.py
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import logging
|
2 |
+
|
3 |
+
import gradio as gr
|
4 |
+
|
5 |
+
logger = logging.getLogger(__name__)
|
6 |
+
|
7 |
+
def add_submit_model_tab(block, api_service):
|
8 |
+
with gr.Tab("➕ Model Gönder"):
|
9 |
+
gr.Markdown("### Modelinizi Gönderin")
|
10 |
+
gr.Markdown("**Değerlendirme için modelinizi API'ye gönderin.**")
|
11 |
+
|
12 |
+
with gr.Row():
|
13 |
+
with gr.Column():
|
14 |
+
model_name = gr.Textbox(
|
15 |
+
label="Model Adı",
|
16 |
+
placeholder="Örnek: llama2, qwen2, gemma2",
|
17 |
+
info="Model adını girin (örn: llama2)"
|
18 |
+
)
|
19 |
+
version = gr.Textbox(
|
20 |
+
label="Versiyon",
|
21 |
+
placeholder="Örnek: 7b, 13b, 70b",
|
22 |
+
info="Model versiyonunu girin (örn: 7b)"
|
23 |
+
)
|
24 |
+
|
25 |
+
with gr.Column():
|
26 |
+
gr.Markdown("""
|
27 |
+
### 📋 Gönderim Bilgileri
|
28 |
+
|
29 |
+
**Gerekli Alanlar:**
|
30 |
+
- ✅ Model Adı (zorunlu)
|
31 |
+
- ✅ Versiyon (zorunlu)
|
32 |
+
|
33 |
+
**Örnekler:**
|
34 |
+
- Model: `llama2`, Versiyon: `7b`
|
35 |
+
- Model: `qwen2`, Versiyon: `14b`
|
36 |
+
- Model: `gemma2`, Versiyon: `9b`
|
37 |
+
|
38 |
+
**Not:** Model gönderildikten sonra değerlendirme süreci başlayacaktır.
|
39 |
+
""")
|
40 |
+
|
41 |
+
submit_btn = gr.Button("🚀 Model Gönder", variant="primary", size="lg")
|
42 |
+
submission_output = gr.HTML()
|
43 |
+
|
44 |
+
def handle_submission(model_name, version):
|
45 |
+
"""Model gönderimi işle"""
|
46 |
+
try:
|
47 |
+
# Validation
|
48 |
+
if not model_name or not model_name.strip():
|
49 |
+
return f'<div style="color: red; padding: 15px; border: 1px solid red; border-radius: 8px; background: #fef2f2;">❌ Hata: Model adı gereklidir</div>'
|
50 |
+
|
51 |
+
if not version or not version.strip():
|
52 |
+
return f'<div style="color: red; padding: 15px; border: 1px solid red; border-radius: 8px; background: #fef2f2;">❌ Hata: Versiyon gereklidir</div>'
|
53 |
+
|
54 |
+
# API'ye gönder
|
55 |
+
result = api_service.submit_model(model_name.strip(), version.strip())
|
56 |
+
|
57 |
+
if result.get('success'):
|
58 |
+
data = result.get('data', {})
|
59 |
+
return f'''
|
60 |
+
<div style="color: green; padding: 15px; border: 1px solid green; border-radius: 8px; background: #f0fdf4;">
|
61 |
+
✅ <strong>Başarılı!</strong><br>
|
62 |
+
<strong>Mesaj:</strong> {result.get('message')}<br>
|
63 |
+
<strong>Model:</strong> {data.get('model', model_name)}<br>
|
64 |
+
<strong>Versiyon:</strong> {data.get('version', version)}<br>
|
65 |
+
<strong>Durum:</strong> {data.get('status', 'Beklemede')}<br>
|
66 |
+
<strong>Oluşturulma:</strong> {data.get('created_at', 'Şimdi')}
|
67 |
+
</div>
|
68 |
+
'''
|
69 |
+
else:
|
70 |
+
return f'''
|
71 |
+
<div style="color: red; padding: 15px; border: 1px solid red; border-radius: 8px; background: #fef2f2;">
|
72 |
+
❌ <strong>Hata!</strong><br>
|
73 |
+
<strong>Mesaj:</strong> {result.get('message')}<br>
|
74 |
+
<strong>Detay:</strong> {result.get('error', 'Bilinmeyen hata')}
|
75 |
+
</div>
|
76 |
+
'''
|
77 |
+
|
78 |
+
except Exception as e:
|
79 |
+
logger.error(f"Model gönderimi hatası: {e}")
|
80 |
+
return f'''
|
81 |
+
<div style="color: red; padding: 15px; border: 1px solid red; border-radius: 8px; background: #fef2f2;">
|
82 |
+
❌ <strong>Sistem Hatası!</strong><br>
|
83 |
+
<strong>Hata:</strong> {str(e)}
|
84 |
+
</div>
|
85 |
+
'''
|
86 |
+
|
87 |
+
submit_btn.click(
|
88 |
+
handle_submission,
|
89 |
+
inputs=[model_name, version],
|
90 |
+
outputs=submission_output
|
91 |
+
)
|
ui_utils.py
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# ui_utils.py
|
2 |
+
|
3 |
+
CLEAN_CSS = """
|
4 |
+
.gradio-container {
|
5 |
+
max-width: 1200px !important;
|
6 |
+
margin: 0 auto !important;
|
7 |
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
|
8 |
+
}
|
9 |
+
|
10 |
+
.main-header {
|
11 |
+
text-align: center;
|
12 |
+
background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);
|
13 |
+
color: white;
|
14 |
+
padding: 2rem;
|
15 |
+
border-radius: 12px;
|
16 |
+
margin-bottom: 2rem;
|
17 |
+
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
18 |
+
}
|
19 |
+
|
20 |
+
.main-header h1 {
|
21 |
+
font-size: 2.5rem !important;
|
22 |
+
font-weight: 700 !important;
|
23 |
+
margin-bottom: 0.5rem !important;
|
24 |
+
}
|
25 |
+
|
26 |
+
.main-header p {
|
27 |
+
font-size: 1.1rem !important;
|
28 |
+
opacity: 0.9;
|
29 |
+
}
|
30 |
+
|
31 |
+
.status-info {
|
32 |
+
background: #f8fafc;
|
33 |
+
border: 1px solid #e2e8f0;
|
34 |
+
border-radius: 8px;
|
35 |
+
padding: 1rem;
|
36 |
+
margin: 1rem 0;
|
37 |
+
font-size: 0.9rem;
|
38 |
+
color: #475569;
|
39 |
+
}
|
40 |
+
|
41 |
+
.gr-button {
|
42 |
+
border-radius: 8px !important;
|
43 |
+
font-weight: 500 !important;
|
44 |
+
}
|
45 |
+
|
46 |
+
.gr-dataframe {
|
47 |
+
border-radius: 8px !important;
|
48 |
+
border: 1px solid #e2e8f0 !important;
|
49 |
+
}
|
50 |
+
|
51 |
+
.evaluation-card {
|
52 |
+
background: white;
|
53 |
+
border-radius: 12px;
|
54 |
+
padding: 20px;
|
55 |
+
margin: 10px 0;
|
56 |
+
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
57 |
+
border-left: 4px solid #4f46e5;
|
58 |
+
}
|
59 |
+
|
60 |
+
.status-pending { border-left-color: #f59e0b; }
|
61 |
+
.status-processing { border-left-color: #3b82f6; }
|
62 |
+
.status-completed { border-left-color: #10b981; }
|
63 |
+
.status-failed { border-left-color: #ef4444; }
|
64 |
+
"""
|
utils.py
CHANGED
@@ -16,89 +16,89 @@ def filter_leaderboard(
|
|
16 |
family: Optional[str] = None,
|
17 |
quantization_level: Optional[str] = None
|
18 |
) -> pd.DataFrame:
|
19 |
-
"""
|
20 |
try:
|
21 |
df = data_manager.leaderboard_data.copy()
|
22 |
|
23 |
if df.empty:
|
24 |
-
logger.warning("
|
25 |
return pd.DataFrame()
|
26 |
|
27 |
-
#
|
28 |
-
if family and family != "
|
29 |
df = df[df["family"] == family]
|
30 |
-
if quantization_level and quantization_level != "
|
31 |
df = df[df["quantization_level"] == quantization_level]
|
32 |
|
33 |
-
#
|
34 |
if "score" in df.columns:
|
35 |
df = df.sort_values("score", ascending=False)
|
36 |
|
37 |
-
#
|
38 |
if not df.empty and "score" in df.columns:
|
39 |
df = df.reset_index(drop=True)
|
40 |
-
df.insert(0, "
|
41 |
|
42 |
return df
|
43 |
except Exception as e:
|
44 |
-
logger.error(f"
|
45 |
return pd.DataFrame()
|
46 |
|
47 |
def get_all_responses(model: str = None, page: int = 1, page_size: int = 50) -> pd.DataFrame:
|
48 |
-
"""
|
49 |
try:
|
50 |
df = data_manager.responses_data
|
51 |
|
52 |
if df.empty:
|
53 |
-
logger.warning("
|
54 |
-
return pd.DataFrame({"ℹ️
|
55 |
|
56 |
-
#
|
57 |
-
logger.info(f"
|
58 |
|
59 |
-
#
|
60 |
required_columns = ["bolum", "soru", "cevap"]
|
61 |
missing_columns = [col for col in required_columns if col not in df.columns]
|
62 |
if missing_columns:
|
63 |
return pd.DataFrame({
|
64 |
-
"❌
|
65 |
-
"
|
66 |
})
|
67 |
|
68 |
-
#
|
69 |
available_models = [col.replace("_cevap", "") for col in df.columns if col.endswith("_cevap")]
|
70 |
|
71 |
if not available_models:
|
72 |
return pd.DataFrame({
|
73 |
-
"ℹ️
|
74 |
-
"
|
75 |
})
|
76 |
|
77 |
-
#
|
78 |
total_rows = len(df)
|
79 |
start_idx = (page - 1) * page_size
|
80 |
end_idx = start_idx + page_size
|
81 |
|
82 |
-
#
|
83 |
if start_idx >= total_rows:
|
84 |
return pd.DataFrame({
|
85 |
-
"ℹ️
|
86 |
})
|
87 |
|
88 |
-
#
|
89 |
df_page = df.iloc[start_idx:end_idx].copy()
|
90 |
|
91 |
-
#
|
92 |
if not model or model.strip() == "":
|
93 |
-
#
|
94 |
display_columns = ["bolum", "soru", "cevap"] + [f"{m}_cevap" for m in available_models if f"{m}_cevap" in df_page.columns]
|
95 |
result_df = df_page[display_columns]
|
96 |
|
97 |
-
#
|
98 |
column_mapping = {
|
99 |
-
"bolum": "📚
|
100 |
-
"soru": "❓
|
101 |
-
"cevap": "✅
|
102 |
}
|
103 |
|
104 |
for model_name in available_models:
|
@@ -109,45 +109,45 @@ def get_all_responses(model: str = None, page: int = 1, page_size: int = 50) ->
|
|
109 |
result_df = result_df.rename(columns=column_mapping)
|
110 |
|
111 |
else:
|
112 |
-
#
|
113 |
model_column = f"{model}_cevap"
|
114 |
if model_column not in df.columns:
|
115 |
return pd.DataFrame({
|
116 |
-
"❌
|
117 |
-
"🤖
|
118 |
-
"💡
|
119 |
})
|
120 |
|
121 |
-
#
|
122 |
selected_columns = ["bolum", "soru", "cevap", model_column]
|
123 |
result_df = df_page[selected_columns]
|
124 |
|
125 |
-
#
|
126 |
result_df = result_df.rename(columns={
|
127 |
-
"bolum": "📚
|
128 |
-
"soru": "❓
|
129 |
-
"cevap": "✅
|
130 |
-
model_column: f"🤖 {model}
|
131 |
})
|
132 |
|
133 |
-
#
|
134 |
result_df = result_df.fillna("N/A")
|
135 |
|
136 |
-
#
|
137 |
global_question_numbers = range(start_idx + 1, start_idx + len(result_df) + 1)
|
138 |
-
result_df.insert(0, "📝
|
139 |
|
140 |
return result_df
|
141 |
|
142 |
except Exception as e:
|
143 |
-
logger.error(f"
|
144 |
return pd.DataFrame({
|
145 |
-
"❌
|
146 |
-
"🔧
|
147 |
})
|
148 |
|
149 |
def get_pagination_info(page: int = 1, page_size: int = 50) -> dict:
|
150 |
-
"""
|
151 |
try:
|
152 |
df = data_manager.responses_data
|
153 |
total_rows = len(df)
|
@@ -167,7 +167,7 @@ def get_pagination_info(page: int = 1, page_size: int = 50) -> dict:
|
|
167 |
"has_next": page < total_pages
|
168 |
}
|
169 |
except Exception as e:
|
170 |
-
logger.error(f"
|
171 |
return {
|
172 |
"current_page": 1,
|
173 |
"total_pages": 1,
|
@@ -180,14 +180,14 @@ def get_pagination_info(page: int = 1, page_size: int = 50) -> dict:
|
|
180 |
}
|
181 |
|
182 |
def search_responses(query: str, model: str, page: int = 1, page_size: int = 50) -> pd.DataFrame:
|
183 |
-
"""
|
184 |
try:
|
185 |
-
#
|
186 |
if not query or not query.strip():
|
187 |
return get_all_responses(model, page, page_size)
|
188 |
|
189 |
if not model or not model.strip():
|
190 |
-
return pd.DataFrame({"ℹ️
|
191 |
|
192 |
query = query.strip()
|
193 |
model = model.strip()
|
@@ -195,203 +195,201 @@ def search_responses(query: str, model: str, page: int = 1, page_size: int = 50)
|
|
195 |
df = data_manager.responses_data
|
196 |
|
197 |
if df.empty:
|
198 |
-
logger.warning("
|
199 |
-
return pd.DataFrame({"ℹ️
|
200 |
|
201 |
-
#
|
202 |
-
logger.info(f"Available columns in responses data: {list(df.columns)}")
|
203 |
-
|
204 |
-
# Check if required columns exist
|
205 |
required_columns = ["bolum", "soru", "cevap"]
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
|
213 |
-
#
|
214 |
model_column = f"{model}_cevap"
|
215 |
if model_column not in df.columns:
|
216 |
available_models = [col.replace("_cevap", "") for col in df.columns if col.endswith("_cevap")]
|
217 |
-
logger.warning(f"Model column '{model_column}' not found in responses data")
|
218 |
return pd.DataFrame({
|
219 |
-
"❌
|
220 |
-
"🤖
|
221 |
-
"💡
|
|
|
|
|
|
|
|
|
222 |
})
|
223 |
|
224 |
-
#
|
225 |
-
|
226 |
-
search_mask = pd.Series([False] * len(df))
|
227 |
-
|
228 |
-
# Search in each column separately to handle potential issues
|
229 |
-
if "bolum" in df.columns:
|
230 |
-
search_mask |= df["bolum"].astype(str).str.contains(query, case=False, na=False)
|
231 |
-
|
232 |
-
if "soru" in df.columns:
|
233 |
-
search_mask |= df["soru"].astype(str).str.contains(query, case=False, na=False)
|
234 |
-
|
235 |
-
if "cevap" in df.columns:
|
236 |
-
search_mask |= df["cevap"].astype(str).str.contains(query, case=False, na=False)
|
237 |
-
|
238 |
-
if model_column in df.columns:
|
239 |
-
search_mask |= df[model_column].astype(str).str.contains(query, case=False, na=False)
|
240 |
-
|
241 |
-
except Exception as search_error:
|
242 |
-
logger.error(f"Error in search operation: {search_error}")
|
243 |
-
return pd.DataFrame({"❌ Error": [f"Search operation failed: {str(search_error)}"]})
|
244 |
|
245 |
-
|
|
|
|
|
246 |
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
|
253 |
-
#
|
254 |
-
|
255 |
-
start_idx = (page - 1) * page_size
|
256 |
-
end_idx = start_idx + page_size
|
257 |
|
258 |
-
|
259 |
-
if start_idx >= total_results:
|
260 |
-
total_pages = (total_results + page_size - 1) // page_size
|
261 |
return pd.DataFrame({
|
262 |
-
"
|
263 |
-
"
|
|
|
|
|
|
|
|
|
|
|
264 |
})
|
265 |
|
266 |
-
#
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
"
|
281 |
-
|
|
|
|
|
282 |
})
|
283 |
|
284 |
-
#
|
285 |
-
|
286 |
-
result.insert(0, "🔍 Match #", global_match_numbers)
|
287 |
|
288 |
-
|
|
|
|
|
289 |
|
290 |
-
return
|
291 |
|
292 |
except Exception as e:
|
293 |
-
logger.error(f"
|
|
|
294 |
return pd.DataFrame({
|
295 |
-
"❌
|
296 |
-
"🔧
|
|
|
|
|
|
|
|
|
|
|
297 |
})
|
298 |
|
299 |
-
|
300 |
-
|
301 |
def create_plotly_section_results() -> go.Figure:
|
302 |
-
"""
|
303 |
try:
|
304 |
df = data_manager.section_results_data
|
305 |
|
306 |
if df.empty:
|
307 |
fig = go.Figure()
|
308 |
fig.add_annotation(
|
309 |
-
text="
|
310 |
xref="paper", yref="paper",
|
311 |
x=0.5, y=0.5, xanchor='center', yanchor='middle',
|
312 |
showarrow=False,
|
313 |
-
font=dict(size=
|
314 |
)
|
315 |
fig.update_layout(
|
316 |
-
title="
|
317 |
height=500,
|
318 |
-
plot_bgcolor='white'
|
|
|
319 |
)
|
320 |
return fig
|
321 |
|
322 |
-
#
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
marker=dict(
|
332 |
-
color=avg_scores.values,
|
333 |
-
colorscale='Viridis',
|
334 |
-
showscale=True,
|
335 |
-
colorbar=dict(title="Score (%)", titleside="right")
|
336 |
-
),
|
337 |
-
text=[f'{v:.1f}%' for v in avg_scores.values],
|
338 |
-
textposition='auto',
|
339 |
-
textfont=dict(size=12, color='white'),
|
340 |
-
hovertemplate='<b>%{x}</b><br>Score: %{y:.1f}%<br><extra></extra>',
|
341 |
-
name="Section Scores"
|
342 |
)
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
354 |
|
355 |
fig.update_layout(
|
356 |
-
title=
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
),
|
361 |
-
xaxis=dict(
|
362 |
-
title="Sections",
|
363 |
-
titlefont=dict(size=16),
|
364 |
-
tickangle=45,
|
365 |
-
gridcolor='#f0f0f0'
|
366 |
-
),
|
367 |
-
yaxis=dict(
|
368 |
-
title="Accuracy (%)",
|
369 |
-
titlefont=dict(size=16),
|
370 |
-
gridcolor='#f0f0f0'
|
371 |
-
),
|
372 |
plot_bgcolor='white',
|
373 |
paper_bgcolor='white',
|
374 |
-
|
375 |
-
|
376 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
377 |
)
|
378 |
|
|
|
|
|
|
|
|
|
379 |
return fig
|
380 |
|
381 |
except Exception as e:
|
382 |
-
logger.error(f"
|
383 |
fig = go.Figure()
|
384 |
fig.add_annotation(
|
385 |
-
text=f"
|
386 |
xref="paper", yref="paper",
|
387 |
x=0.5, y=0.5, xanchor='center', yanchor='middle',
|
388 |
showarrow=False,
|
389 |
font=dict(size=14, color="red")
|
390 |
)
|
391 |
fig.update_layout(
|
392 |
-
title="
|
393 |
height=500,
|
394 |
-
plot_bgcolor='white'
|
|
|
395 |
)
|
396 |
return fig
|
397 |
|
@@ -403,120 +401,142 @@ def validate_model_submission(
|
|
403 |
weight_type: str,
|
404 |
model_type: str
|
405 |
) -> Tuple[bool, str]:
|
406 |
-
"""
|
407 |
try:
|
408 |
-
#
|
409 |
if not model_name or not model_name.strip():
|
410 |
-
return False, "Model
|
411 |
|
412 |
if not base_model or not base_model.strip():
|
413 |
-
return False, "
|
414 |
|
415 |
-
#
|
416 |
model_name = model_name.strip()
|
417 |
if len(model_name) < 3:
|
418 |
-
return False, "Model
|
419 |
|
420 |
if len(model_name) > 100:
|
421 |
-
return False, "Model
|
422 |
|
423 |
-
#
|
424 |
-
|
425 |
-
|
426 |
-
return False, f"Model name contains invalid characters: {', '.join(invalid_chars)}"
|
427 |
|
428 |
-
#
|
429 |
-
|
430 |
-
|
431 |
-
if model_name in
|
432 |
-
return False, f"
|
433 |
|
434 |
-
#
|
435 |
base_model = base_model.strip()
|
436 |
-
if
|
437 |
-
return False, "
|
438 |
|
439 |
-
#
|
440 |
-
if revision and len(revision.strip())
|
441 |
-
return False, "
|
442 |
|
443 |
-
#
|
444 |
from config import CONFIG
|
445 |
|
446 |
if precision not in CONFIG["model"].precision_options:
|
447 |
-
return False, f"
|
448 |
|
449 |
if weight_type not in CONFIG["model"].weight_types:
|
450 |
-
return False, f"
|
451 |
|
452 |
if model_type not in CONFIG["model"].model_types:
|
453 |
-
return False, f"
|
454 |
|
455 |
-
|
|
|
|
|
|
|
|
|
456 |
|
457 |
except Exception as e:
|
458 |
-
logger.error(f"
|
459 |
-
return False, f"
|
460 |
|
461 |
def get_leaderboard_stats() -> Dict[str, any]:
|
462 |
-
"""
|
463 |
try:
|
464 |
df = data_manager.leaderboard_data
|
465 |
|
466 |
if df.empty:
|
467 |
return {
|
468 |
-
"
|
469 |
-
"
|
470 |
-
"
|
471 |
-
"
|
472 |
-
"
|
473 |
}
|
474 |
|
475 |
stats = {
|
476 |
-
"
|
477 |
-
"
|
478 |
-
"
|
479 |
-
"
|
480 |
-
"
|
481 |
}
|
482 |
|
483 |
return stats
|
484 |
|
485 |
except Exception as e:
|
486 |
-
logger.error(f"
|
487 |
return {
|
488 |
-
"
|
489 |
-
"
|
490 |
-
"
|
491 |
-
"
|
492 |
-
"
|
493 |
}
|
494 |
|
495 |
def format_dataframe_for_display(df: pd.DataFrame, max_rows: int = 100) -> pd.DataFrame:
|
496 |
-
"""
|
497 |
try:
|
498 |
if df.empty:
|
499 |
-
return
|
500 |
|
501 |
-
#
|
502 |
if len(df) > max_rows:
|
503 |
df = df.head(max_rows)
|
|
|
504 |
|
505 |
-
#
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
|
510 |
-
#
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
lambda x: x[:100] + "..." if len(str(x)) > 100 else x
|
516 |
-
)
|
517 |
|
518 |
return df
|
519 |
|
520 |
except Exception as e:
|
521 |
-
logger.error(f"
|
522 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
family: Optional[str] = None,
|
17 |
quantization_level: Optional[str] = None
|
18 |
) -> pd.DataFrame:
|
19 |
+
"""Önbellekleme ile kriterlere göre liderlik tablosu verilerini filtrele."""
|
20 |
try:
|
21 |
df = data_manager.leaderboard_data.copy()
|
22 |
|
23 |
if df.empty:
|
24 |
+
logger.warning("Liderlik tablosu verileri boş, boş DataFrame döndürülüyor")
|
25 |
return pd.DataFrame()
|
26 |
|
27 |
+
# Filtreleri uygula
|
28 |
+
if family and family != "Tümü":
|
29 |
df = df[df["family"] == family]
|
30 |
+
if quantization_level and quantization_level != "Tümü":
|
31 |
df = df[df["quantization_level"] == quantization_level]
|
32 |
|
33 |
+
# Puan varsa sırala
|
34 |
if "score" in df.columns:
|
35 |
df = df.sort_values("score", ascending=False)
|
36 |
|
37 |
+
# Sıralama ekle
|
38 |
if not df.empty and "score" in df.columns:
|
39 |
df = df.reset_index(drop=True)
|
40 |
+
df.insert(0, "Sıra", range(1, len(df) + 1))
|
41 |
|
42 |
return df
|
43 |
except Exception as e:
|
44 |
+
logger.error(f"Liderlik tablosu filtreleme hatası: {e}")
|
45 |
return pd.DataFrame()
|
46 |
|
47 |
def get_all_responses(model: str = None, page: int = 1, page_size: int = 50) -> pd.DataFrame:
|
48 |
+
"""Sayfalama ile arama sorgusu olmadan göz atmak için tüm model cevaplarını al."""
|
49 |
try:
|
50 |
df = data_manager.responses_data
|
51 |
|
52 |
if df.empty:
|
53 |
+
logger.warning("Cevap verileri boş, boş DataFrame döndürülüyor")
|
54 |
+
return pd.DataFrame({"ℹ️ Bilgi": ["Cevap verisi mevcut değil. Lütfen veri yüklemeyi kontrol edin."]})
|
55 |
|
56 |
+
# Hata ayıklama: Mevcut sütunları göster
|
57 |
+
logger.info(f"Cevap verilerindeki mevcut sütunlar: {list(df.columns)}")
|
58 |
|
59 |
+
# Gerekli sütunların var olup olmadığını kontrol et
|
60 |
required_columns = ["bolum", "soru", "cevap"]
|
61 |
missing_columns = [col for col in required_columns if col not in df.columns]
|
62 |
if missing_columns:
|
63 |
return pd.DataFrame({
|
64 |
+
"❌ Hata": [f"Eksik gerekli sütunlar: {', '.join(missing_columns)}"],
|
65 |
+
"Mevcut Sütunlar": [", ".join(df.columns.tolist())]
|
66 |
})
|
67 |
|
68 |
+
# Tüm mevcut modelleri al
|
69 |
available_models = [col.replace("_cevap", "") for col in df.columns if col.endswith("_cevap")]
|
70 |
|
71 |
if not available_models:
|
72 |
return pd.DataFrame({
|
73 |
+
"ℹ️ Bilgi": ["Model cevap sütunları bulunamadı."],
|
74 |
+
"Mevcut Sütunlar": [", ".join(df.columns.tolist())]
|
75 |
})
|
76 |
|
77 |
+
# Sayfalamayı hesapla
|
78 |
total_rows = len(df)
|
79 |
start_idx = (page - 1) * page_size
|
80 |
end_idx = start_idx + page_size
|
81 |
|
82 |
+
# Sayfa numarasını doğrula
|
83 |
if start_idx >= total_rows:
|
84 |
return pd.DataFrame({
|
85 |
+
"ℹ️ Bilgi": [f"Sayfa {page} aralığın dışında. Toplam sayfa: {(total_rows + page_size - 1) // page_size}"]
|
86 |
})
|
87 |
|
88 |
+
# Mevcut sayfa için veri dilimini al
|
89 |
df_page = df.iloc[start_idx:end_idx].copy()
|
90 |
|
91 |
+
# Belirli bir model seçilmemişse, tüm modeller için cevapları göster
|
92 |
if not model or model.strip() == "":
|
93 |
+
# İlgili sütunları seç
|
94 |
display_columns = ["bolum", "soru", "cevap"] + [f"{m}_cevap" for m in available_models if f"{m}_cevap" in df_page.columns]
|
95 |
result_df = df_page[display_columns]
|
96 |
|
97 |
+
# Daha iyi görünüm için sütunları yeniden adlandır
|
98 |
column_mapping = {
|
99 |
+
"bolum": "📚 Bölüm",
|
100 |
+
"soru": "❓ Soru",
|
101 |
+
"cevap": "✅ Doğru Cevap"
|
102 |
}
|
103 |
|
104 |
for model_name in available_models:
|
|
|
109 |
result_df = result_df.rename(columns=column_mapping)
|
110 |
|
111 |
else:
|
112 |
+
# Belirli model için cevapları göster
|
113 |
model_column = f"{model}_cevap"
|
114 |
if model_column not in df.columns:
|
115 |
return pd.DataFrame({
|
116 |
+
"❌ Hata": [f"'{model}' modeli cevapları bulunamadı."],
|
117 |
+
"🤖 Mevcut Modeller": [", ".join(available_models[:10]) + ("..." if len(available_models) > 10 else "")],
|
118 |
+
"💡 İpucu": ["Lütfen cevap verisi olan açılır menüden bir model seçin."]
|
119 |
})
|
120 |
|
121 |
+
# Görüntülenecek sütunları seç ve hazırla
|
122 |
selected_columns = ["bolum", "soru", "cevap", model_column]
|
123 |
result_df = df_page[selected_columns]
|
124 |
|
125 |
+
# Daha iyi görünüm için sütunları yeniden adlandır
|
126 |
result_df = result_df.rename(columns={
|
127 |
+
"bolum": "📚 Bölüm",
|
128 |
+
"soru": "❓ Soru",
|
129 |
+
"cevap": "✅ Doğru Cevap",
|
130 |
+
model_column: f"🤖 {model} Cevabı"
|
131 |
})
|
132 |
|
133 |
+
# Eksik değerleri işle
|
134 |
result_df = result_df.fillna("N/A")
|
135 |
|
136 |
+
# Genel soru numaralarını ekle (sadece sayfa numaraları değil)
|
137 |
global_question_numbers = range(start_idx + 1, start_idx + len(result_df) + 1)
|
138 |
+
result_df.insert(0, "📝 Soru #", global_question_numbers)
|
139 |
|
140 |
return result_df
|
141 |
|
142 |
except Exception as e:
|
143 |
+
logger.error(f"Tüm cevapları alma hatası: {e}")
|
144 |
return pd.DataFrame({
|
145 |
+
"❌ Hata": [f"Cevapları yükleme hatası: {str(e)}"],
|
146 |
+
"🔧 Hata Ayıklama Bilgisi": [f"Model: '{model}', Sayfa: {page}"]
|
147 |
})
|
148 |
|
149 |
def get_pagination_info(page: int = 1, page_size: int = 50) -> dict:
|
150 |
+
"""Cevap verileri için sayfalama bilgilerini al."""
|
151 |
try:
|
152 |
df = data_manager.responses_data
|
153 |
total_rows = len(df)
|
|
|
167 |
"has_next": page < total_pages
|
168 |
}
|
169 |
except Exception as e:
|
170 |
+
logger.error(f"Sayfalama bilgisi alma hatası: {e}")
|
171 |
return {
|
172 |
"current_page": 1,
|
173 |
"total_pages": 1,
|
|
|
180 |
}
|
181 |
|
182 |
def search_responses(query: str, model: str, page: int = 1, page_size: int = 50) -> pd.DataFrame:
|
183 |
+
"""Geliştirilmiş işlevsellik ile sorguya göre model cevaplarını ara."""
|
184 |
try:
|
185 |
+
# Sorgu sağlanmazsa, tüm cevapları göster
|
186 |
if not query or not query.strip():
|
187 |
return get_all_responses(model, page, page_size)
|
188 |
|
189 |
if not model or not model.strip():
|
190 |
+
return pd.DataFrame({"ℹ️ Bilgi": ["Lütfen açılır menüden bir model seçin."]})
|
191 |
|
192 |
query = query.strip()
|
193 |
model = model.strip()
|
|
|
195 |
df = data_manager.responses_data
|
196 |
|
197 |
if df.empty:
|
198 |
+
logger.warning("Cevap verileri boş, boş DataFrame döndürülüyor")
|
199 |
+
return pd.DataFrame({"ℹ️ Bilgi": ["Cevap verisi mevcut değil. Lütfen veri yüklemeyi kontrol edin."]})
|
200 |
|
201 |
+
# Gerekli sütunların varlığını kontrol et
|
|
|
|
|
|
|
202 |
required_columns = ["bolum", "soru", "cevap"]
|
203 |
+
for col in required_columns:
|
204 |
+
if col not in df.columns:
|
205 |
+
return pd.DataFrame({
|
206 |
+
"❌ Hata": [f"Gerekli sütun '{col}' bulunamadı"],
|
207 |
+
"Mevcut Sütunlar": [", ".join(df.columns.tolist())]
|
208 |
+
})
|
209 |
|
210 |
+
# Model sütununun varlığını kontrol et
|
211 |
model_column = f"{model}_cevap"
|
212 |
if model_column not in df.columns:
|
213 |
available_models = [col.replace("_cevap", "") for col in df.columns if col.endswith("_cevap")]
|
|
|
214 |
return pd.DataFrame({
|
215 |
+
"❌ Hata": [f"'{model}' modeli cevapları bulunamadı"],
|
216 |
+
"🤖 Mevcut Modeller": [", ".join(available_models[:10]) + ("..." if len(available_models) > 10 else "")],
|
217 |
+
"💡 Öneriler": [
|
218 |
+
"1. Açılır menüden geçerli bir model seçin",
|
219 |
+
"2. Model verilerinin yüklendiğinden emin olun",
|
220 |
+
"3. Modelleri yenilemek için 'Yenile' butonuna tıklayın"
|
221 |
+
]
|
222 |
})
|
223 |
|
224 |
+
# Sorguyu güvenli hale getir (büyük/küçük harf duyarsız)
|
225 |
+
query_lower = query.lower()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
226 |
|
227 |
+
# Birden fazla sütunda arama yap
|
228 |
+
search_columns = ["bolum", "soru", "cevap", model_column]
|
229 |
+
search_mask = pd.Series([False] * len(df))
|
230 |
|
231 |
+
for col in search_columns:
|
232 |
+
if col in df.columns:
|
233 |
+
# Güvenli string dönüştürme ve büyük/küçük harf duyarsız arama
|
234 |
+
col_mask = df[col].astype(str).str.lower().str.contains(query_lower, case=False, na=False, regex=False)
|
235 |
+
search_mask = search_mask | col_mask
|
236 |
|
237 |
+
# Arama sonuçlarını filtrele
|
238 |
+
search_results = df[search_mask]
|
|
|
|
|
239 |
|
240 |
+
if search_results.empty:
|
|
|
|
|
241 |
return pd.DataFrame({
|
242 |
+
"🔍 Arama Sonucu": [f"'{query}' için sonuç bulunamadı"],
|
243 |
+
"💡 İpucu": [
|
244 |
+
"Daha genel terimler deneyin",
|
245 |
+
"Yazım hatalarını kontrol edin",
|
246 |
+
"Farklı anahtar kelimeler kullanın"
|
247 |
+
],
|
248 |
+
"📊 Aranan Sütunlar": [", ".join(search_columns)]
|
249 |
})
|
250 |
|
251 |
+
# Sonuçları sayıyla sınırla (performans için)
|
252 |
+
max_results = 50
|
253 |
+
if len(search_results) > max_results:
|
254 |
+
search_results = search_results.head(max_results)
|
255 |
+
truncated_message = f" (İlk {max_results} sonuç gösteriliyor)"
|
256 |
+
else:
|
257 |
+
truncated_message = ""
|
258 |
+
|
259 |
+
# Görüntülenecek sütunları seç
|
260 |
+
display_columns = ["bolum", "soru", "cevap", model_column]
|
261 |
+
result_df = search_results[display_columns].copy()
|
262 |
+
|
263 |
+
# Sütunları yeniden adlandır
|
264 |
+
result_df = result_df.rename(columns={
|
265 |
+
"bolum": "📚 Bölüm",
|
266 |
+
"soru": "❓ Soru",
|
267 |
+
"cevap": "✅ Doğru Cevap",
|
268 |
+
model_column: f"🤖 {model} Cevabı"
|
269 |
})
|
270 |
|
271 |
+
# Eksik değerleri işle
|
272 |
+
result_df = result_df.fillna("N/A")
|
|
|
273 |
|
274 |
+
# Başlık satırı ekle
|
275 |
+
summary_info = f"'{query}' için {len(search_results)} sonuç{truncated_message}"
|
276 |
+
result_df.insert(0, "🔍 Arama Özeti", [summary_info] + [""] * (len(result_df) - 1))
|
277 |
|
278 |
+
return result_df
|
279 |
|
280 |
except Exception as e:
|
281 |
+
logger.error(f"Cevap arama hatası: {e}")
|
282 |
+
error_details = f"Sorgu: '{query}', Model: '{model}', Hata: {str(e)}"
|
283 |
return pd.DataFrame({
|
284 |
+
"❌ Arama Hatası": ["Arama sırasında bir hata oluştu"],
|
285 |
+
"🔧 Hata Detayları": [error_details],
|
286 |
+
"💡 Öneriler": [
|
287 |
+
"Basit sorgu terimleri deneyin",
|
288 |
+
"Özel karakterleri kaldırın",
|
289 |
+
"Sayfayı yenileyin ve tekrar deneyin"
|
290 |
+
]
|
291 |
})
|
292 |
|
|
|
|
|
293 |
def create_plotly_section_results() -> go.Figure:
|
294 |
+
"""Bölüm sonuçları için etkileşimli Plotly grafiği oluştur."""
|
295 |
try:
|
296 |
df = data_manager.section_results_data
|
297 |
|
298 |
if df.empty:
|
299 |
fig = go.Figure()
|
300 |
fig.add_annotation(
|
301 |
+
text="Bölüm verisi mevcut değil",
|
302 |
xref="paper", yref="paper",
|
303 |
x=0.5, y=0.5, xanchor='center', yanchor='middle',
|
304 |
showarrow=False,
|
305 |
+
font=dict(size=16, color="gray")
|
306 |
)
|
307 |
fig.update_layout(
|
308 |
+
title="Bölüm Performans Analizi",
|
309 |
height=500,
|
310 |
+
plot_bgcolor='white',
|
311 |
+
paper_bgcolor='white'
|
312 |
)
|
313 |
return fig
|
314 |
|
315 |
+
# İlk sütunun bölüm adları olduğunu varsay
|
316 |
+
if len(df.columns) < 2:
|
317 |
+
fig = go.Figure()
|
318 |
+
fig.add_annotation(
|
319 |
+
text="Yeterli veri yok",
|
320 |
+
xref="paper", yref="paper",
|
321 |
+
x=0.5, y=0.5, xanchor='center', yanchor='middle',
|
322 |
+
showarrow=False,
|
323 |
+
font=dict(size=16, color="gray")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
324 |
)
|
325 |
+
fig.update_layout(title="Bölüm Performans Analizi", height=500)
|
326 |
+
return fig
|
327 |
+
|
328 |
+
# Sayısal sütunları (model performansları) al
|
329 |
+
numeric_columns = df.select_dtypes(include=['number']).columns.tolist()
|
330 |
+
section_column = df.columns[0] if df.columns[0] not in numeric_columns else 'section'
|
331 |
+
|
332 |
+
if not numeric_columns:
|
333 |
+
# Sayısal sütun yoksa ilk sütunu bölüm olarak al ve diğerlerini sayısala çevirmeye çalış
|
334 |
+
numeric_columns = df.columns[1:].tolist()
|
335 |
+
for col in numeric_columns:
|
336 |
+
df[col] = pd.to_numeric(df[col], errors='coerce')
|
337 |
+
|
338 |
+
# Etkileşimli bar chart oluştur
|
339 |
+
fig = go.Figure()
|
340 |
+
|
341 |
+
# Her model için ayrı çubuk ekle
|
342 |
+
colors = px.colors.qualitative.Set3
|
343 |
+
for i, model in enumerate(numeric_columns):
|
344 |
+
fig.add_trace(go.Bar(
|
345 |
+
name=model,
|
346 |
+
x=df[section_column] if section_column in df.columns else df.index,
|
347 |
+
y=df[model],
|
348 |
+
marker_color=colors[i % len(colors)],
|
349 |
+
text=[f'{v:.1f}%' if pd.notna(v) else 'N/A' for v in df[model]],
|
350 |
+
textposition='auto',
|
351 |
+
hovertemplate=f'<b>{model}</b><br>Bölüm: %{{x}}<br>Puan: %{{y:.1f}}%<extra></extra>'
|
352 |
+
))
|
353 |
|
354 |
fig.update_layout(
|
355 |
+
title="Model Performanslarının Bölümlere Göre Karşılaştırması",
|
356 |
+
xaxis_title="Bölümler",
|
357 |
+
yaxis_title="Doğruluk Puanı (%)",
|
358 |
+
height=500,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
359 |
plot_bgcolor='white',
|
360 |
paper_bgcolor='white',
|
361 |
+
barmode='group',
|
362 |
+
hovermode='x unified',
|
363 |
+
legend=dict(
|
364 |
+
orientation="h",
|
365 |
+
yanchor="bottom",
|
366 |
+
y=1.02,
|
367 |
+
xanchor="right",
|
368 |
+
x=1
|
369 |
+
)
|
370 |
)
|
371 |
|
372 |
+
# Grid ekle
|
373 |
+
fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor='lightgray')
|
374 |
+
fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor='lightgray')
|
375 |
+
|
376 |
return fig
|
377 |
|
378 |
except Exception as e:
|
379 |
+
logger.error(f"Bölüm sonuçları grafiği oluşturma hatası: {e}")
|
380 |
fig = go.Figure()
|
381 |
fig.add_annotation(
|
382 |
+
text=f"Grafik oluşturma hatası: {str(e)}",
|
383 |
xref="paper", yref="paper",
|
384 |
x=0.5, y=0.5, xanchor='center', yanchor='middle',
|
385 |
showarrow=False,
|
386 |
font=dict(size=14, color="red")
|
387 |
)
|
388 |
fig.update_layout(
|
389 |
+
title="Bölüm Performans Analizi",
|
390 |
height=500,
|
391 |
+
plot_bgcolor='white',
|
392 |
+
paper_bgcolor='white'
|
393 |
)
|
394 |
return fig
|
395 |
|
|
|
401 |
weight_type: str,
|
402 |
model_type: str
|
403 |
) -> Tuple[bool, str]:
|
404 |
+
"""Model gönderimini detaylı kontrollerle doğrula."""
|
405 |
try:
|
406 |
+
# Temel validasyon
|
407 |
if not model_name or not model_name.strip():
|
408 |
+
return False, "Model adı gereklidir"
|
409 |
|
410 |
if not base_model or not base_model.strip():
|
411 |
+
return False, "Temel model gereklidir"
|
412 |
|
413 |
+
# İsim formatını kontrol et
|
414 |
model_name = model_name.strip()
|
415 |
if len(model_name) < 3:
|
416 |
+
return False, "Model adı en az 3 karakter olmalıdır"
|
417 |
|
418 |
if len(model_name) > 100:
|
419 |
+
return False, "Model adı 100 karakterden fazla olamaz"
|
420 |
|
421 |
+
# Özel karakterleri kontrol et
|
422 |
+
if not model_name.replace('-', '').replace('_', '').replace('.', '').replace('/', '').isalnum():
|
423 |
+
return False, "Model adında sadece harf, rakam, tire, alt çizgi, nokta ve eğik çizgi kullanılabilir"
|
|
|
424 |
|
425 |
+
# Mevcut modellerde çakışma kontrolü
|
426 |
+
existing_data = data_manager.leaderboard_data
|
427 |
+
if not existing_data.empty and 'model' in existing_data.columns:
|
428 |
+
if model_name.lower() in existing_data['model'].str.lower().values:
|
429 |
+
return False, f"'{model_name}' adında bir model zaten mevcut"
|
430 |
|
431 |
+
# Temel model formatını kontrol et
|
432 |
base_model = base_model.strip()
|
433 |
+
if '/' not in base_model and not base_model.startswith('http'):
|
434 |
+
return False, "Temel model formatı 'organization/model' şeklinde olmalıdır"
|
435 |
|
436 |
+
# Revizyon kontrolü
|
437 |
+
if revision and len(revision.strip()) > 50:
|
438 |
+
return False, "Revizyon 50 karakterden fazla olamaz"
|
439 |
|
440 |
+
# Yapılandırma seçeneklerini kontrol et
|
441 |
from config import CONFIG
|
442 |
|
443 |
if precision not in CONFIG["model"].precision_options:
|
444 |
+
return False, f"Geçersiz hassasiyet seçimi. Geçerli seçenekler: {', '.join(CONFIG['model'].precision_options)}"
|
445 |
|
446 |
if weight_type not in CONFIG["model"].weight_types:
|
447 |
+
return False, f"Geçersiz ağırlık türü seçimi. Geçerli seçenekler: {', '.join(CONFIG['model'].weight_types)}"
|
448 |
|
449 |
if model_type not in CONFIG["model"].model_types:
|
450 |
+
return False, f"Geçersiz model türü seçimi. Geçerli seçenekler: {', '.join(CONFIG['model'].model_types)}"
|
451 |
|
452 |
+
# Başarılı validasyon
|
453 |
+
success_message = f"Model '{model_name}' başarıyla doğrulandı ve değerlendirme kuyruğuna eklendi"
|
454 |
+
logger.info(f"Model gönderimi doğrulandı: {model_name}")
|
455 |
+
|
456 |
+
return True, success_message
|
457 |
|
458 |
except Exception as e:
|
459 |
+
logger.error(f"Model doğrulama hatası: {e}")
|
460 |
+
return False, f"Doğrulama sırasında hata oluştu: {str(e)}"
|
461 |
|
462 |
def get_leaderboard_stats() -> Dict[str, any]:
|
463 |
+
"""Liderlik tablosu istatistiklerini al."""
|
464 |
try:
|
465 |
df = data_manager.leaderboard_data
|
466 |
|
467 |
if df.empty:
|
468 |
return {
|
469 |
+
"toplam_model": 0,
|
470 |
+
"ortalama_puan": 0,
|
471 |
+
"en_yuksek_puan": 0,
|
472 |
+
"aileler": [],
|
473 |
+
"kuantizasyon_seviyeleri": []
|
474 |
}
|
475 |
|
476 |
stats = {
|
477 |
+
"toplam_model": len(df),
|
478 |
+
"ortalama_puan": df["score"].mean() if "score" in df.columns else 0,
|
479 |
+
"en_yuksek_puan": df["score"].max() if "score" in df.columns else 0,
|
480 |
+
"aileler": df["family"].unique().tolist() if "family" in df.columns else [],
|
481 |
+
"kuantizasyon_seviyeleri": df["quantization_level"].unique().tolist() if "quantization_level" in df.columns else []
|
482 |
}
|
483 |
|
484 |
return stats
|
485 |
|
486 |
except Exception as e:
|
487 |
+
logger.error(f"İstatistik alma hatası: {e}")
|
488 |
return {
|
489 |
+
"toplam_model": 0,
|
490 |
+
"ortalama_puan": 0,
|
491 |
+
"en_yuksek_puan": 0,
|
492 |
+
"aileler": [],
|
493 |
+
"kuantizasyon_seviyeleri": []
|
494 |
}
|
495 |
|
496 |
def format_dataframe_for_display(df: pd.DataFrame, max_rows: int = 100) -> pd.DataFrame:
|
497 |
+
"""DataFrame'i görüntüleme için formatla."""
|
498 |
try:
|
499 |
if df.empty:
|
500 |
+
return pd.DataFrame({"ℹ️ Bilgi": ["Görüntülenecek veri yok"]})
|
501 |
|
502 |
+
# Satır sayısını sınırla
|
503 |
if len(df) > max_rows:
|
504 |
df = df.head(max_rows)
|
505 |
+
logger.info(f"DataFrame {max_rows} satırla sınırlandırıldı")
|
506 |
|
507 |
+
# Sayısal sütunları formatla
|
508 |
+
for col in df.select_dtypes(include=['float']).columns:
|
509 |
+
if 'score' in col.lower() or 'puan' in col.lower():
|
510 |
+
df[col] = df[col].round(2)
|
511 |
|
512 |
+
# Uzun string'leri kısalt
|
513 |
+
for col in df.select_dtypes(include=['object']).columns:
|
514 |
+
df[col] = df[col].astype(str).apply(
|
515 |
+
lambda x: x[:100] + "..." if len(x) > 100 else x
|
516 |
+
)
|
|
|
|
|
517 |
|
518 |
return df
|
519 |
|
520 |
except Exception as e:
|
521 |
+
logger.error(f"DataFrame formatlama hatası: {e}")
|
522 |
+
return pd.DataFrame({"❌ Hata": [f"Formatlama hatası: {str(e)}"]})
|
523 |
+
|
524 |
+
# Önbellekleme temizleme işlevi
|
525 |
+
def clear_cache():
|
526 |
+
"""Tüm LRU önbelleklerini temizle."""
|
527 |
+
try:
|
528 |
+
filter_leaderboard.cache_clear()
|
529 |
+
logger.info("Önbellekler temizlendi")
|
530 |
+
except Exception as e:
|
531 |
+
logger.error(f"Önbellek temizleme hatası: {e}")
|
532 |
+
|
533 |
+
# Veri yenileme sonrası önbellekleri temizle
|
534 |
+
def refresh_all_caches():
|
535 |
+
"""Veri yenileme sonrası tüm önbellekleri yenile."""
|
536 |
+
try:
|
537 |
+
clear_cache()
|
538 |
+
# Veri yöneticisinden yeni verileri zorla yükle
|
539 |
+
data_manager.refresh_datasets()
|
540 |
+
logger.info("Tüm önbellekler ve veriler yenilendi")
|
541 |
+
except Exception as e:
|
542 |
+
logger.error(f"Önbellek yenileme hatası: {e}")
|