alibayram commited on
Commit
9b0ae85
·
1 Parent(s): eb5ebe6

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
Files changed (14) hide show
  1. README.md +199 -50
  2. api_service.py +255 -0
  3. app.py +26 -444
  4. config.py +17 -17
  5. data_manager.py +78 -74
  6. test_submission.py +1 -0
  7. ui_analytics.py +8 -0
  8. ui_evaluation_requests.py +147 -0
  9. ui_leaderboard.py +43 -0
  10. ui_main.py +47 -0
  11. ui_model_responses.py +9 -0
  12. ui_submit_model.py +91 -0
  13. ui_utils.py +64 -0
  14. 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
- # 🏆 Turkish MMLU Leaderboard
14
 
15
- A clean, modern web application for exploring and comparing AI model performance on the Turkish Massive Multitask Language Understanding (MMLU) benchmark.
16
 
17
- ## ✨ Features
18
 
19
- - 📊 **Interactive Leaderboard**: Filter and sort models by family, quantization, and performance
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
- ## 🚀 Quick Start
 
 
 
26
 
27
- ### Prerequisites
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
  - Python 3.8+
30
- - pip
31
 
32
- ### Installation
33
 
34
- 1. Clone the repository:
35
 
36
- ```bash
37
- git clone https://github.com/yourusername/turkish_mmlu_leaderboard.git
38
- cd turkish_mmlu_leaderboard
39
- ```
40
 
41
- 2. Install dependencies:
42
 
43
- ```bash
44
- pip install -r requirements.txt
45
- ```
46
 
47
- 3. Run the application:
48
 
49
- ```bash
50
- python app.py
51
- ```
 
 
52
 
53
- 4. Open your browser and navigate to `http://localhost:7860`
 
 
54
 
55
- ## 📁 Project Structure
56
 
57
  ```
58
  turkish_mmlu_leaderboard/
59
- ├── app.py # Main Gradio application
60
- ├── config.py # Configuration settings
61
- ├── data_manager.py # Data loading and caching
62
- ├── utils.py # Utility functions for search and validation
63
- ├── requirements.txt # Python dependencies
64
- ├── Dockerfile # Docker configuration
65
- └── README.md # This file
66
  ```
67
 
68
- ## 🔧 Configuration
 
 
 
 
 
 
 
69
 
70
- The application can be configured by modifying `config.py`:
71
 
72
- - **DatasetConfig**: Dataset paths, cache settings, refresh intervals
73
- - **UIConfig**: UI appearance and styling
74
- - **ModelConfig**: Model-related options and validation
 
75
 
76
- ## 📊 Data Sources
77
 
78
- The leaderboard loads data from three Hugging Face datasets:
 
 
 
79
 
80
- - **Leaderboard Data**: Model rankings and scores
81
- - **Model Responses**: Individual model answers to questions
82
- - **Section Results**: Performance breakdown by subject areas
83
 
84
- ## 🐳 Docker Deployment
85
 
86
- Build and run with Docker:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
 
88
  ```bash
 
89
  docker build -t turkish-mmlu-leaderboard .
 
 
90
  docker run -p 7860:7860 turkish-mmlu-leaderboard
91
  ```
92
 
93
- ## 🤝 Contributing
94
 
95
- Contributions are welcome! Please feel free to submit a Pull Request.
96
 
97
- ## 📄 License
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
 
99
- This project is licensed under the CC-BY-NC-4.0 License.
 
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 utils import search_responses, validate_model_submission
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
- # Initialize scheduler
447
  scheduler = BackgroundScheduler()
448
  scheduler.add_job(
449
  data_manager.refresh_datasets,
450
- "interval",
451
- seconds=CONFIG["dataset"].refresh_interval
 
 
452
  )
453
  scheduler.start()
454
-
455
- # Create and launch app
 
456
  app = create_clean_app()
457
- app.queue().launch(
458
- server_name="0.0.0.0",
459
- server_port=7860,
460
- share=False,
461
- show_error=True
 
 
 
462
  )
 
 
 
463
  except Exception as e:
464
- logger.error(f"Error starting application: {e}")
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 minutes
12
- request_timeout: int = 60 # seconds
13
  max_retries: int = 5
14
- retry_delay: int = 2 # seconds
15
 
16
  @dataclass
17
  class UIConfig:
18
- title: str = "🏆 Turkish MMLU Leaderboard"
19
- description: str = "Explore, evaluate, and compare AI model performance on Turkish language tasks."
20
  theme: str = "soft"
21
  css: str = """
22
- /* Enhanced Modern UI Styles */
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
- /* Header Enhancement */
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
- /* Button Enhancements */
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
- /* Table Enhancements */
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
- /* Card Styles */
78
  .card {
79
  background: white;
80
  border-radius: 15px;
@@ -84,7 +84,7 @@ class UIConfig:
84
  margin-bottom: 20px;
85
  }
86
 
87
- /* Status Messages */
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
- /* Responsive Design */
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] = ("Original", "Delta", "Adapter", "LoRA", "QLoRA")
126
- model_types: List[str] = ("Transformer", "RNN", "GPT", "BERT", "T5", "Other")
127
 
128
  @dataclass
129
  class AppConfig:
130
- """Enhanced app configuration"""
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
- """Performance and caching configuration"""
143
  enable_caching: bool = True
144
- cache_timeout: int = 3600 # 1 hour
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
- # Configure requests with retries
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
- """Create a requests session with retry capabilities"""
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
- """Check if cached data is still valid based on timestamp."""
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
- """Update the cache timestamp for a data type."""
66
  self._cache_timestamps[data_type] = datetime.now()
67
 
68
- def _load_dataset(self, path: str, data_type: str = "unknown") -> pd.DataFrame:
69
- """Load dataset with enhanced error handling and caching."""
70
 
71
- # Check cache validity first
72
  if self._is_cache_valid(data_type):
73
- logger.info(f"Using cached data for {data_type}")
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"Loading dataset from {path} (attempt {attempts+1}/{self._max_retries})")
82
 
83
- # Add timeout and better error handling
84
  df = pd.read_parquet(path, engine='pyarrow')
85
 
86
  if df.empty:
87
- logger.warning(f"Dataset from {path} is empty")
88
  else:
89
- logger.info(f"Successfully loaded {len(df)} rows from {path}")
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"Error loading dataset from {path}: {e}")
98
 
99
  if attempts < self._max_retries:
100
- wait_time = self._retry_delay * (2 ** (attempts - 1)) # Exponential backoff
101
- logger.info(f"Retrying in {wait_time} seconds...")
102
  time.sleep(wait_time)
103
 
104
- # If we get here, all attempts failed
105
- logger.error(f"Failed to load dataset after {self._max_retries} attempts: {last_error}")
106
 
107
- # Return appropriate fallback dataframe
108
  return self._create_fallback_data(data_type, path)
109
 
110
  def _create_fallback_data(self, data_type: str, path: str) -> pd.DataFrame:
111
- """Create fallback data based on the data type."""
112
- logger.info(f"Creating fallback data for {data_type}")
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({"error": ["Unknown data type"], "message": [f"Failed to load {path}"]})
122
 
123
  def _create_fallback_leaderboard(self) -> pd.DataFrame:
124
- """Create a comprehensive fallback leaderboard dataframe."""
125
- logger.info("Creating fallback leaderboard data")
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": ["None", "None", "None", "float16", "int8"],
130
  "score": [85.2, 83.7, 81.4, 78.9, 75.3],
131
  "timestamp": [pd.Timestamp.now()] * 5,
132
- "parameters": ["1.76T", "Unknown", "Unknown", "70B", "7B"],
133
- "license": ["Proprietary", "Proprietary", "Proprietary", "Custom", "Apache 2.0"]
134
  })
135
 
136
  def _create_fallback_responses(self) -> pd.DataFrame:
137
- """Create a comprehensive fallback responses dataframe."""
138
- logger.info("Creating fallback responses data")
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
- """Create a comprehensive fallback section results dataframe."""
156
- logger.info("Creating fallback section results data")
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
- """Refresh all datasets from source with thread safety."""
168
  if self._refresh_in_progress:
169
- logger.info("Refresh already in progress, skipping...")
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("Starting comprehensive dataset refresh...")
178
 
179
- # Create cache directory if it doesn't exist
180
  os.makedirs(CONFIG["dataset"].cache_dir, exist_ok=True)
181
 
182
- # Download latest data
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
- # Clear cached data to force reload
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("Datasets refreshed successfully")
198
 
199
  except Exception as e:
200
- logger.error(f"Error refreshing datasets: {e}")
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
- """Get the status of the last refresh attempt."""
208
  return {
209
- "last_attempt": self._last_refresh_attempt.isoformat() if self._last_refresh_attempt else None,
210
- "in_progress": self._refresh_in_progress,
211
- "cache_timestamps": {k: v.isoformat() for k, v in self._cache_timestamps.items()}
212
  }
213
 
214
  @property
215
  def leaderboard_data(self) -> pd.DataFrame:
216
- """Get leaderboard data with thread safety and caching."""
217
  with self._data_lock:
218
- if self._leaderboard_data is None or not self._is_cache_valid("leaderboard"):
 
219
  self._leaderboard_data = self._load_dataset(
220
  CONFIG["dataset"].leaderboard_path,
221
  "leaderboard"
222
  )
223
- return self._leaderboard_data.copy() if self._leaderboard_data is not None else pd.DataFrame()
224
 
225
  @property
226
  def responses_data(self) -> pd.DataFrame:
227
- """Get responses data with thread safety and caching."""
228
  with self._data_lock:
229
- if self._responses_data is None or not self._is_cache_valid("responses"):
 
230
  self._responses_data = self._load_dataset(
231
  CONFIG["dataset"].responses_path,
232
  "responses"
233
  )
234
- return self._responses_data.copy() if self._responses_data is not None else pd.DataFrame()
235
 
236
  @property
237
  def section_results_data(self) -> pd.DataFrame:
238
- """Get section results data with thread safety and caching."""
239
  with self._data_lock:
240
- if self._section_results_data is None or not self._is_cache_valid("section_results"):
 
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() if self._section_results_data is not None else pd.DataFrame()
246
 
247
  def get_data_summary(self) -> Dict[str, any]:
248
- """Get a comprehensive summary of all loaded data."""
249
  try:
250
  summary = {
251
- "leaderboard": {
252
- "rows": len(self.leaderboard_data),
253
- "columns": list(self.leaderboard_data.columns) if not self.leaderboard_data.empty else [],
254
- "families": self.leaderboard_data["family"].nunique() if "family" in self.leaderboard_data.columns else 0,
255
- "models": self.leaderboard_data["model"].nunique() if "model" in self.leaderboard_data.columns else 0
256
  },
257
- "responses": {
258
- "rows": len(self.responses_data),
259
- "columns": list(self.responses_data.columns) if not self.responses_data.empty else [],
260
- "sections": self.responses_data["bolum"].nunique() if "bolum" in self.responses_data.columns else 0
261
  },
262
- "section_results": {
263
- "rows": len(self.section_results_data),
264
- "columns": list(self.section_results_data.columns) if not self.section_results_data.empty else [],
265
- "sections": len([col for col in self.section_results_data.columns if col != "section"]) if not self.section_results_data.empty else 0
266
  },
267
- "cache_status": self.get_refresh_status(),
268
- "last_updated": datetime.now().isoformat()
 
 
269
  }
 
270
  return summary
 
271
  except Exception as e:
272
- logger.error(f"Error generating data summary: {e}")
273
- return {"error": str(e)}
274
 
275
  def clear_cache(self):
276
- """Clear all cached data and force reload on next access."""
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("All cached data cleared")
283
 
284
- # Global instance
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
- """Filter leaderboard data based on criteria with caching."""
20
  try:
21
  df = data_manager.leaderboard_data.copy()
22
 
23
  if df.empty:
24
- logger.warning("Leaderboard data is empty, returning empty DataFrame")
25
  return pd.DataFrame()
26
 
27
- # Apply filters
28
- if family and family != "All":
29
  df = df[df["family"] == family]
30
- if quantization_level and quantization_level != "All":
31
  df = df[df["quantization_level"] == quantization_level]
32
 
33
- # Sort by score if available
34
  if "score" in df.columns:
35
  df = df.sort_values("score", ascending=False)
36
 
37
- # Add ranking
38
  if not df.empty and "score" in df.columns:
39
  df = df.reset_index(drop=True)
40
- df.insert(0, "Rank", range(1, len(df) + 1))
41
 
42
  return df
43
  except Exception as e:
44
- logger.error(f"Error filtering leaderboard: {e}")
45
  return pd.DataFrame()
46
 
47
  def get_all_responses(model: str = None, page: int = 1, page_size: int = 50) -> pd.DataFrame:
48
- """Get all model responses for browsing without search query with pagination."""
49
  try:
50
  df = data_manager.responses_data
51
 
52
  if df.empty:
53
- logger.warning("Responses data is empty, returning empty DataFrame")
54
- return pd.DataFrame({"ℹ️ Info": ["No response data available. Please check data loading."]})
55
 
56
- # Debug: Show available columns
57
- logger.info(f"Available columns in responses data: {list(df.columns)}")
58
 
59
- # Check if required columns exist
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
- "❌ Error": [f"Missing required columns: {', '.join(missing_columns)}"],
65
- "Available Columns": [", ".join(df.columns.tolist())]
66
  })
67
 
68
- # Get all available models
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
- "ℹ️ Info": ["No model response columns found."],
74
- "Available Columns": [", ".join(df.columns.tolist())]
75
  })
76
 
77
- # Calculate pagination
78
  total_rows = len(df)
79
  start_idx = (page - 1) * page_size
80
  end_idx = start_idx + page_size
81
 
82
- # Validate page number
83
  if start_idx >= total_rows:
84
  return pd.DataFrame({
85
- "ℹ️ Info": [f"Page {page} is out of range. Total pages: {(total_rows + page_size - 1) // page_size}"]
86
  })
87
 
88
- # Get the data slice for current page
89
  df_page = df.iloc[start_idx:end_idx].copy()
90
 
91
- # If no specific model selected, show responses for all models
92
  if not model or model.strip() == "":
93
- # Select relevant columns
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
- # Rename columns for better display
98
  column_mapping = {
99
- "bolum": "📚 Section",
100
- "soru": "❓ Question",
101
- "cevap": "✅ Correct Answer"
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
- # Show responses for specific model
113
  model_column = f"{model}_cevap"
114
  if model_column not in df.columns:
115
  return pd.DataFrame({
116
- "❌ Error": [f"Model '{model}' responses not found."],
117
- "🤖 Available Models": [", ".join(available_models[:10]) + ("..." if len(available_models) > 10 else "")],
118
- "💡 Tip": ["Please select a model from the dropdown that has response data."]
119
  })
120
 
121
- # Select and prepare columns for display
122
  selected_columns = ["bolum", "soru", "cevap", model_column]
123
  result_df = df_page[selected_columns]
124
 
125
- # Rename columns for better display
126
  result_df = result_df.rename(columns={
127
- "bolum": "📚 Section",
128
- "soru": "❓ Question",
129
- "cevap": "✅ Correct Answer",
130
- model_column: f"🤖 {model} Response"
131
  })
132
 
133
- # Handle missing values
134
  result_df = result_df.fillna("N/A")
135
 
136
- # Add global question numbers (not just page numbers)
137
  global_question_numbers = range(start_idx + 1, start_idx + len(result_df) + 1)
138
- result_df.insert(0, "📝 Question #", global_question_numbers)
139
 
140
  return result_df
141
 
142
  except Exception as e:
143
- logger.error(f"Error getting all responses: {e}")
144
  return pd.DataFrame({
145
- "❌ Error": [f"Error loading responses: {str(e)}"],
146
- "🔧 Debug Info": [f"Model: '{model}', Page: {page}"]
147
  })
148
 
149
  def get_pagination_info(page: int = 1, page_size: int = 50) -> dict:
150
- """Get pagination information for the responses data."""
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"Error getting pagination info: {e}")
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
- """Search model responses based on query with enhanced functionality."""
184
  try:
185
- # If no query provided, show all responses
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({"ℹ️ Info": ["Please select a model from the dropdown."]})
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("Responses data is empty, returning empty DataFrame")
199
- return pd.DataFrame({"ℹ️ Info": ["No response data available. Please check data loading."]})
200
 
201
- # Debug: Show available columns
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
- missing_columns = [col for col in required_columns if col not in df.columns]
207
- if missing_columns:
208
- return pd.DataFrame({
209
- "❌ Error": [f"Missing required columns: {', '.join(missing_columns)}"],
210
- "Available Columns": [", ".join(df.columns.tolist())]
211
- })
212
 
213
- # Check if model column exists
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
- "❌ Error": [f"Model '{model}' responses not found."],
220
- "🤖 Available Models": [", ".join(available_models[:10]) + ("..." if len(available_models) > 10 else "")],
221
- "💡 Tip": ["Please select a model from the dropdown that has response data."]
 
 
 
 
222
  })
223
 
224
- # Enhanced search - search in multiple columns with better error handling
225
- try:
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
- filtered = df[search_mask]
 
 
246
 
247
- if filtered.empty:
248
- return pd.DataFrame({
249
- "ℹ️ Info": [f"No results found for '{query}' in model '{model}' responses."],
250
- "💡 Suggestion": ["Try different search terms or check if the model has response data."]
251
- })
252
 
253
- # Apply pagination to search results
254
- total_results = len(filtered)
255
- start_idx = (page - 1) * page_size
256
- end_idx = start_idx + page_size
257
 
258
- # Validate page number for search results
259
- if start_idx >= total_results:
260
- total_pages = (total_results + page_size - 1) // page_size
261
  return pd.DataFrame({
262
- "ℹ️ Info": [f"Search page {page} is out of range. Total search pages: {total_pages}"],
263
- "🔍 Search Results": [f"Found {total_results} matches for '{query}'"]
 
 
 
 
 
264
  })
265
 
266
- # Get the search results slice for current page
267
- filtered_page = filtered.iloc[start_idx:end_idx].copy()
268
-
269
- # Select and prepare columns for display
270
- selected_columns = ["bolum", "soru", "cevap", model_column]
271
- result = filtered_page[selected_columns].copy()
272
-
273
- # Handle missing values
274
- result = result.fillna("N/A")
275
-
276
- # Rename columns for better display
277
- result = result.rename(columns={
278
- "bolum": "📚 Section",
279
- "soru": "❓ Question",
280
- "cevap": " Correct Answer",
281
- model_column: f"🤖 {model} Response"
 
 
282
  })
283
 
284
- # Add global match numbers (not just page numbers)
285
- global_match_numbers = range(start_idx + 1, start_idx + len(result) + 1)
286
- result.insert(0, "🔍 Match #", global_match_numbers)
287
 
288
- logger.info(f"Showing search results {start_idx + 1}-{start_idx + len(result)} out of {total_results} total matches")
 
 
289
 
290
- return result
291
 
292
  except Exception as e:
293
- logger.error(f"Error searching responses: {e}")
 
294
  return pd.DataFrame({
295
- "❌ Error": [f"Search error: {str(e)}"],
296
- "🔧 Debug Info": [f"Query: '{query}', Model: '{model}'"]
 
 
 
 
 
297
  })
298
 
299
-
300
-
301
  def create_plotly_section_results() -> go.Figure:
302
- """Create an interactive Plotly chart for section results."""
303
  try:
304
  df = data_manager.section_results_data
305
 
306
  if df.empty:
307
  fig = go.Figure()
308
  fig.add_annotation(
309
- text="📊 No data available",
310
  xref="paper", yref="paper",
311
  x=0.5, y=0.5, xanchor='center', yanchor='middle',
312
  showarrow=False,
313
- font=dict(size=18, color="gray")
314
  )
315
  fig.update_layout(
316
- title="Section-Wise Performance",
317
  height=500,
318
- plot_bgcolor='white'
 
319
  )
320
  return fig
321
 
322
- # Calculate average scores
323
- numeric_cols = df.select_dtypes(include=['number']).columns
324
- avg_scores = df[numeric_cols].mean()
325
-
326
- # Create interactive bar chart
327
- fig = go.Figure(data=[
328
- go.Bar(
329
- x=avg_scores.index,
330
- y=avg_scores.values,
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
- # Add average line
346
- mean_score = avg_scores.mean()
347
- fig.add_hline(
348
- y=mean_score,
349
- line_dash="dash",
350
- line_color="red",
351
- annotation_text=f"Average: {mean_score:.1f}%",
352
- annotation_position="top right"
353
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
354
 
355
  fig.update_layout(
356
- title=dict(
357
- text="📊 Average Section-Wise Performance",
358
- x=0.5,
359
- font=dict(size=24, color='#2c3e50')
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
- height=600,
375
- margin=dict(t=100, b=120, l=80, r=80),
376
- showlegend=False
 
 
 
 
 
 
377
  )
378
 
 
 
 
 
379
  return fig
380
 
381
  except Exception as e:
382
- logger.error(f"Error creating Plotly section results: {e}")
383
  fig = go.Figure()
384
  fig.add_annotation(
385
- text=f" Error generating plot: {str(e)}",
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="Section-Wise Performance",
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
- """Enhanced model submission validation with detailed checks."""
407
  try:
408
- # Basic required field validation
409
  if not model_name or not model_name.strip():
410
- return False, "Model name is required and cannot be empty."
411
 
412
  if not base_model or not base_model.strip():
413
- return False, "Base model is required and cannot be empty."
414
 
415
- # Model name validation
416
  model_name = model_name.strip()
417
  if len(model_name) < 3:
418
- return False, "Model name must be at least 3 characters long."
419
 
420
  if len(model_name) > 100:
421
- return False, "Model name must be less than 100 characters."
422
 
423
- # Check for invalid characters
424
- invalid_chars = ['<', '>', ':', '"', '|', '?', '*', '\\', '/']
425
- if any(char in model_name for char in invalid_chars):
426
- return False, f"Model name contains invalid characters: {', '.join(invalid_chars)}"
427
 
428
- # Check if model already exists
429
- if not data_manager.leaderboard_data.empty:
430
- existing_models = data_manager.leaderboard_data["model"].values
431
- if model_name in existing_models:
432
- return False, f"Model name '{model_name}' already exists. Please choose a unique name."
433
 
434
- # Base model validation
435
  base_model = base_model.strip()
436
- if len(base_model) < 3:
437
- return False, "Base model name must be at least 3 characters long."
438
 
439
- # Revision validation
440
- if revision and len(revision.strip()) == 0:
441
- return False, "Revision cannot be empty if provided."
442
 
443
- # Validate precision, weight_type, and model_type are from allowed options
444
  from config import CONFIG
445
 
446
  if precision not in CONFIG["model"].precision_options:
447
- return False, f"Invalid precision. Must be one of: {', '.join(CONFIG['model'].precision_options)}"
448
 
449
  if weight_type not in CONFIG["model"].weight_types:
450
- return False, f"Invalid weight type. Must be one of: {', '.join(CONFIG['model'].weight_types)}"
451
 
452
  if model_type not in CONFIG["model"].model_types:
453
- return False, f"Invalid model type. Must be one of: {', '.join(CONFIG['model'].model_types)}"
454
 
455
- return True, "✅ All validation checks passed! Your model submission looks good."
 
 
 
 
456
 
457
  except Exception as e:
458
- logger.error(f"Error validating model submission: {e}")
459
- return False, f"Validation error: {str(e)}"
460
 
461
  def get_leaderboard_stats() -> Dict[str, any]:
462
- """Get comprehensive statistics about the leaderboard."""
463
  try:
464
  df = data_manager.leaderboard_data
465
 
466
  if df.empty:
467
  return {
468
- "total_models": 0,
469
- "total_families": 0,
470
- "avg_score": 0,
471
- "top_score": 0,
472
- "last_updated": "No data"
473
  }
474
 
475
  stats = {
476
- "total_models": len(df),
477
- "total_families": df["family"].nunique() if "family" in df.columns else 0,
478
- "avg_score": df["score"].mean() if "score" in df.columns else 0,
479
- "top_score": df["score"].max() if "score" in df.columns else 0,
480
- "last_updated": time.strftime("%Y-%m-%d %H:%M:%S")
481
  }
482
 
483
  return stats
484
 
485
  except Exception as e:
486
- logger.error(f"Error getting leaderboard stats: {e}")
487
  return {
488
- "total_models": 0,
489
- "total_families": 0,
490
- "avg_score": 0,
491
- "top_score": 0,
492
- "last_updated": "Error"
493
  }
494
 
495
  def format_dataframe_for_display(df: pd.DataFrame, max_rows: int = 100) -> pd.DataFrame:
496
- """Format DataFrame for better display in Gradio."""
497
  try:
498
  if df.empty:
499
- return df
500
 
501
- # Limit rows for performance
502
  if len(df) > max_rows:
503
  df = df.head(max_rows)
 
504
 
505
- # Round numeric columns
506
- numeric_columns = df.select_dtypes(include=['float64', 'float32']).columns
507
- for col in numeric_columns:
508
- df[col] = df[col].round(2)
509
 
510
- # Truncate long text fields
511
- text_columns = df.select_dtypes(include=['object']).columns
512
- for col in text_columns:
513
- if col in df.columns:
514
- df[col] = df[col].astype(str).apply(
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"Error formatting DataFrame: {e}")
522
- return df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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}")