| |
|
| | """
|
| | Backend Selector Module
|
| | Intelligent backend selection based on edit characteristics
|
| | """
|
| | import numpy as np
|
| | from typing import Dict, List, Optional
|
| |
|
| |
|
| | class PerformancePredictor:
|
| | """Predict backend performance for given edit"""
|
| |
|
| | def __init__(self):
|
| | """Initialize performance predictor"""
|
| |
|
| | self.profiles = {
|
| | 'russian': {
|
| | 'cyrillic_boost': 0.05,
|
| | 'base_success': 0.873,
|
| | 'base_latency': 85,
|
| | 'domain_strengths': {'scientific': 0.03, 'math': 0.02}
|
| | },
|
| | 'ibm': {
|
| | 'cyrillic_boost': 0.0,
|
| | 'base_success': 0.891,
|
| | 'base_latency': 92,
|
| | 'domain_strengths': {'code': 0.03, 'text': 0.02}
|
| | }
|
| | }
|
| |
|
| | def predict_performance(
|
| | self,
|
| | backend: str,
|
| | edit_features: Dict
|
| | ) -> Dict[str, float]:
|
| | """
|
| | Predict performance for backend on edit
|
| |
|
| | Args:
|
| | backend: Backend name
|
| | edit_features: Edit characteristics
|
| |
|
| | Returns:
|
| | Predicted performance metrics
|
| | """
|
| | profile = self.profiles.get(backend, self.profiles['ibm'])
|
| |
|
| |
|
| | success_rate = profile['base_success']
|
| |
|
| |
|
| | if edit_features.get('lang') == 'ru' and backend == 'russian':
|
| | success_rate += profile['cyrillic_boost']
|
| |
|
| |
|
| | domain = edit_features.get('domain', 'text')
|
| | if domain in profile['domain_strengths']:
|
| | success_rate += profile['domain_strengths'][domain]
|
| |
|
| |
|
| | latency = profile['base_latency']
|
| |
|
| |
|
| | success_rate += np.random.normal(0, 0.01)
|
| | latency += np.random.normal(0, 5)
|
| |
|
| | return {
|
| | 'predicted_success_rate': min(1.0, max(0.0, success_rate)),
|
| | 'predicted_latency_ms': max(10, latency),
|
| | 'confidence': 0.85
|
| | }
|
| |
|
| |
|
| | class BackendSelector:
|
| | """Select optimal backend for edit"""
|
| |
|
| | def __init__(
|
| | self,
|
| | backends: List[str] = None,
|
| | selection_strategy: str = 'performance'
|
| | ):
|
| | """
|
| | Initialize backend selector
|
| |
|
| | Args:
|
| | backends: Available backends
|
| | selection_strategy: Strategy ('performance', 'latency', 'balanced')
|
| | """
|
| | self.backends = backends or ['russian', 'ibm']
|
| | self.selection_strategy = selection_strategy
|
| | self.predictor = PerformancePredictor()
|
| |
|
| | self.selection_history = []
|
| |
|
| | def select_backend(
|
| | self,
|
| | edit: Dict,
|
| | constraints: Optional[Dict] = None
|
| | ) -> str:
|
| | """
|
| | Select optimal backend for edit
|
| |
|
| | Args:
|
| | edit: Edit to process
|
| | constraints: Optional constraints (max_latency, min_success_rate)
|
| |
|
| | Returns:
|
| | Selected backend name
|
| | """
|
| | constraints = constraints or {}
|
| |
|
| |
|
| | features = {
|
| | 'lang': edit.get('lang', 'en'),
|
| | 'domain': edit.get('domain', 'text'),
|
| | 'complexity': edit.get('complexity', 'medium')
|
| | }
|
| |
|
| |
|
| | predictions = {}
|
| | for backend in self.backends:
|
| | pred = self.predictor.predict_performance(backend, features)
|
| | predictions[backend] = pred
|
| |
|
| |
|
| | if self.selection_strategy == 'performance':
|
| | selected = max(
|
| | predictions.items(),
|
| | key=lambda x: x[1]['predicted_success_rate']
|
| | )[0]
|
| | elif self.selection_strategy == 'latency':
|
| | selected = min(
|
| | predictions.items(),
|
| | key=lambda x: x[1]['predicted_latency_ms']
|
| | )[0]
|
| | else:
|
| | selected = max(
|
| | predictions.items(),
|
| | key=lambda x: x[1]['predicted_success_rate'] / (x[1]['predicted_latency_ms'] / 100)
|
| | )[0]
|
| |
|
| |
|
| | if constraints:
|
| | max_latency = constraints.get('max_latency_ms')
|
| | min_success = constraints.get('min_success_rate')
|
| |
|
| | if max_latency and predictions[selected]['predicted_latency_ms'] > max_latency:
|
| |
|
| | for backend, pred in predictions.items():
|
| | if pred['predicted_latency_ms'] <= max_latency:
|
| | selected = backend
|
| | break
|
| |
|
| | if min_success and predictions[selected]['predicted_success_rate'] < min_success:
|
| |
|
| | for backend, pred in predictions.items():
|
| | if pred['predicted_success_rate'] >= min_success:
|
| | selected = backend
|
| | break
|
| |
|
| |
|
| | self.selection_history.append({
|
| | 'edit_id': edit.get('id', 'unknown'),
|
| | 'selected_backend': selected,
|
| | 'predictions': predictions
|
| | })
|
| |
|
| | return selected
|
| |
|
| | def batch_select(
|
| | self,
|
| | edits: List[Dict],
|
| | constraints: Optional[Dict] = None
|
| | ) -> Dict[str, List[Dict]]:
|
| | """
|
| | Select backends for batch of edits
|
| |
|
| | Args:
|
| | edits: List of edits
|
| | constraints: Optional constraints
|
| |
|
| | Returns:
|
| | Dict mapping backend names to edit lists
|
| | """
|
| | backend_assignments = {backend: [] for backend in self.backends}
|
| |
|
| | for edit in edits:
|
| | selected = self.select_backend(edit, constraints)
|
| | backend_assignments[selected].append(edit)
|
| |
|
| | return backend_assignments
|
| |
|
| | def get_selection_stats(self) -> Dict:
|
| | """Get selection statistics"""
|
| | if not self.selection_history:
|
| | return {}
|
| |
|
| | backend_counts = {backend: 0 for backend in self.backends}
|
| | for selection in self.selection_history:
|
| | backend_counts[selection['selected_backend']] += 1
|
| |
|
| | total = len(self.selection_history)
|
| | return {
|
| | 'total_selections': total,
|
| | 'backend_distribution': {
|
| | backend: count / total
|
| | for backend, count in backend_counts.items()
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| | def select_best_backend(edit: Dict, backends: List[str] = None) -> str:
|
| | """Quick backend selection"""
|
| | selector = BackendSelector(backends=backends)
|
| | return selector.select_backend(edit)
|
| |
|