isa-model 0.4.0__py3-none-any.whl → 0.4.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. isa_model/client.py +466 -43
  2. isa_model/core/cache/redis_cache.py +12 -3
  3. isa_model/core/config/config_manager.py +230 -3
  4. isa_model/core/config.py +90 -0
  5. isa_model/core/database/direct_db_client.py +114 -0
  6. isa_model/core/database/migration_manager.py +563 -0
  7. isa_model/core/database/migrations.py +21 -1
  8. isa_model/core/database/supabase_client.py +154 -19
  9. isa_model/core/dependencies.py +316 -0
  10. isa_model/core/discovery/__init__.py +19 -0
  11. isa_model/core/discovery/consul_discovery.py +190 -0
  12. isa_model/core/logging/__init__.py +54 -0
  13. isa_model/core/logging/influx_logger.py +523 -0
  14. isa_model/core/logging/loki_logger.py +160 -0
  15. isa_model/core/models/__init__.py +27 -18
  16. isa_model/core/models/config_models.py +625 -0
  17. isa_model/core/models/deployment_billing_tracker.py +430 -0
  18. isa_model/core/models/model_manager.py +35 -80
  19. isa_model/core/models/model_metadata.py +690 -0
  20. isa_model/core/models/model_repo.py +174 -18
  21. isa_model/core/models/system_models.py +857 -0
  22. isa_model/core/repositories/__init__.py +9 -0
  23. isa_model/core/repositories/config_repository.py +912 -0
  24. isa_model/core/services/intelligent_model_selector.py +399 -21
  25. isa_model/core/types.py +1 -0
  26. isa_model/deployment/__init__.py +5 -48
  27. isa_model/deployment/core/__init__.py +2 -31
  28. isa_model/deployment/core/deployment_manager.py +1278 -370
  29. isa_model/deployment/modal/__init__.py +8 -0
  30. isa_model/deployment/modal/config.py +136 -0
  31. isa_model/deployment/{services/auto_hf_modal_deployer.py → modal/deployer.py} +1 -1
  32. isa_model/deployment/modal/services/__init__.py +3 -0
  33. isa_model/deployment/modal/services/audio/__init__.py +1 -0
  34. isa_model/deployment/modal/services/embedding/__init__.py +1 -0
  35. isa_model/deployment/modal/services/llm/__init__.py +1 -0
  36. isa_model/deployment/modal/services/llm/isa_llm_service.py +424 -0
  37. isa_model/deployment/modal/services/video/__init__.py +1 -0
  38. isa_model/deployment/modal/services/vision/__init__.py +1 -0
  39. isa_model/deployment/models/org-org-acme-corp-tenant-a-service-llm-20250825-225822/tenant-a-service_modal_service.py +48 -0
  40. isa_model/deployment/models/org-test-org-123-prefix-test-service-llm-20250825-225822/prefix-test-service_modal_service.py +48 -0
  41. isa_model/deployment/models/test-llm-service-llm-20250825-204442/test-llm-service_modal_service.py +48 -0
  42. isa_model/deployment/models/test-monitoring-gpt2-llm-20250825-212906/test-monitoring-gpt2_modal_service.py +48 -0
  43. isa_model/deployment/models/test-monitoring-gpt2-llm-20250825-213009/test-monitoring-gpt2_modal_service.py +48 -0
  44. isa_model/deployment/storage/__init__.py +5 -0
  45. isa_model/deployment/storage/deployment_repository.py +824 -0
  46. isa_model/deployment/triton/__init__.py +10 -0
  47. isa_model/deployment/triton/config.py +196 -0
  48. isa_model/deployment/triton/configs/__init__.py +1 -0
  49. isa_model/deployment/triton/provider.py +512 -0
  50. isa_model/deployment/triton/scripts/__init__.py +1 -0
  51. isa_model/deployment/triton/templates/__init__.py +1 -0
  52. isa_model/inference/__init__.py +47 -1
  53. isa_model/inference/ai_factory.py +137 -10
  54. isa_model/inference/legacy_services/__init__.py +21 -0
  55. isa_model/inference/legacy_services/model_evaluation.py +637 -0
  56. isa_model/inference/legacy_services/model_service.py +573 -0
  57. isa_model/inference/legacy_services/model_serving.py +717 -0
  58. isa_model/inference/legacy_services/model_training.py +561 -0
  59. isa_model/inference/models/__init__.py +21 -0
  60. isa_model/inference/models/inference_config.py +551 -0
  61. isa_model/inference/models/inference_record.py +675 -0
  62. isa_model/inference/models/performance_models.py +714 -0
  63. isa_model/inference/repositories/__init__.py +9 -0
  64. isa_model/inference/repositories/inference_repository.py +828 -0
  65. isa_model/inference/services/audio/base_stt_service.py +184 -11
  66. isa_model/inference/services/audio/openai_stt_service.py +22 -6
  67. isa_model/inference/services/embedding/ollama_embed_service.py +15 -3
  68. isa_model/inference/services/embedding/resilient_embed_service.py +285 -0
  69. isa_model/inference/services/llm/__init__.py +10 -2
  70. isa_model/inference/services/llm/base_llm_service.py +335 -24
  71. isa_model/inference/services/llm/cerebras_llm_service.py +628 -0
  72. isa_model/inference/services/llm/helpers/llm_adapter.py +9 -4
  73. isa_model/inference/services/llm/helpers/llm_prompts.py +342 -0
  74. isa_model/inference/services/llm/helpers/llm_utils.py +321 -23
  75. isa_model/inference/services/llm/huggingface_llm_service.py +581 -0
  76. isa_model/inference/services/llm/ollama_llm_service.py +9 -2
  77. isa_model/inference/services/llm/openai_llm_service.py +33 -16
  78. isa_model/inference/services/llm/yyds_llm_service.py +8 -2
  79. isa_model/inference/services/vision/__init__.py +22 -1
  80. isa_model/inference/services/vision/helpers/image_utils.py +8 -5
  81. isa_model/inference/services/vision/isa_vision_service.py +65 -4
  82. isa_model/inference/services/vision/openai_vision_service.py +19 -10
  83. isa_model/inference/services/vision/vgg16_vision_service.py +257 -0
  84. isa_model/serving/api/cache_manager.py +245 -0
  85. isa_model/serving/api/dependencies/__init__.py +1 -0
  86. isa_model/serving/api/dependencies/auth.py +194 -0
  87. isa_model/serving/api/dependencies/database.py +139 -0
  88. isa_model/serving/api/error_handlers.py +284 -0
  89. isa_model/serving/api/fastapi_server.py +172 -22
  90. isa_model/serving/api/middleware/auth.py +8 -2
  91. isa_model/serving/api/middleware/security.py +23 -33
  92. isa_model/serving/api/middleware/tenant_context.py +414 -0
  93. isa_model/serving/api/routes/analytics.py +4 -1
  94. isa_model/serving/api/routes/config.py +645 -0
  95. isa_model/serving/api/routes/deployment_billing.py +315 -0
  96. isa_model/serving/api/routes/deployments.py +138 -2
  97. isa_model/serving/api/routes/gpu_gateway.py +440 -0
  98. isa_model/serving/api/routes/health.py +32 -12
  99. isa_model/serving/api/routes/inference_monitoring.py +486 -0
  100. isa_model/serving/api/routes/local_deployments.py +448 -0
  101. isa_model/serving/api/routes/tenants.py +575 -0
  102. isa_model/serving/api/routes/unified.py +680 -18
  103. isa_model/serving/api/routes/webhooks.py +479 -0
  104. isa_model/serving/api/startup.py +68 -54
  105. isa_model/utils/gpu_utils.py +311 -0
  106. {isa_model-0.4.0.dist-info → isa_model-0.4.4.dist-info}/METADATA +71 -24
  107. isa_model-0.4.4.dist-info/RECORD +180 -0
  108. isa_model/core/security/secrets.py +0 -358
  109. isa_model/core/storage/hf_storage.py +0 -419
  110. isa_model/core/storage/minio_storage.py +0 -0
  111. isa_model/deployment/cloud/__init__.py +0 -9
  112. isa_model/deployment/cloud/modal/__init__.py +0 -10
  113. isa_model/deployment/core/deployment_config.py +0 -356
  114. isa_model/deployment/core/isa_deployment_service.py +0 -401
  115. isa_model/deployment/gpu_int8_ds8/app/server.py +0 -66
  116. isa_model/deployment/gpu_int8_ds8/scripts/test_client.py +0 -43
  117. isa_model/deployment/gpu_int8_ds8/scripts/test_client_os.py +0 -35
  118. isa_model/deployment/runtime/deployed_service.py +0 -338
  119. isa_model/deployment/services/__init__.py +0 -9
  120. isa_model/deployment/services/auto_deploy_vision_service.py +0 -538
  121. isa_model/deployment/services/model_service.py +0 -332
  122. isa_model/deployment/services/service_monitor.py +0 -356
  123. isa_model/deployment/services/service_registry.py +0 -527
  124. isa_model/eval/__init__.py +0 -92
  125. isa_model/eval/benchmarks/__init__.py +0 -27
  126. isa_model/eval/benchmarks/multimodal_datasets.py +0 -460
  127. isa_model/eval/benchmarks.py +0 -701
  128. isa_model/eval/config/__init__.py +0 -10
  129. isa_model/eval/config/evaluation_config.py +0 -108
  130. isa_model/eval/evaluators/__init__.py +0 -24
  131. isa_model/eval/evaluators/audio_evaluator.py +0 -727
  132. isa_model/eval/evaluators/base_evaluator.py +0 -503
  133. isa_model/eval/evaluators/embedding_evaluator.py +0 -742
  134. isa_model/eval/evaluators/llm_evaluator.py +0 -472
  135. isa_model/eval/evaluators/vision_evaluator.py +0 -564
  136. isa_model/eval/example_evaluation.py +0 -395
  137. isa_model/eval/factory.py +0 -798
  138. isa_model/eval/infrastructure/__init__.py +0 -24
  139. isa_model/eval/infrastructure/experiment_tracker.py +0 -466
  140. isa_model/eval/isa_benchmarks.py +0 -700
  141. isa_model/eval/isa_integration.py +0 -582
  142. isa_model/eval/metrics.py +0 -951
  143. isa_model/eval/tests/unit/test_basic.py +0 -396
  144. isa_model/serving/api/routes/evaluations.py +0 -579
  145. isa_model/training/__init__.py +0 -168
  146. isa_model/training/annotation/annotation_schema.py +0 -47
  147. isa_model/training/annotation/processors/annotation_processor.py +0 -126
  148. isa_model/training/annotation/storage/dataset_manager.py +0 -131
  149. isa_model/training/annotation/storage/dataset_schema.py +0 -44
  150. isa_model/training/annotation/tests/test_annotation_flow.py +0 -109
  151. isa_model/training/annotation/tests/test_minio copy.py +0 -113
  152. isa_model/training/annotation/tests/test_minio_upload.py +0 -43
  153. isa_model/training/annotation/views/annotation_controller.py +0 -158
  154. isa_model/training/cloud/__init__.py +0 -22
  155. isa_model/training/cloud/job_orchestrator.py +0 -402
  156. isa_model/training/cloud/runpod_trainer.py +0 -454
  157. isa_model/training/cloud/storage_manager.py +0 -482
  158. isa_model/training/core/__init__.py +0 -26
  159. isa_model/training/core/config.py +0 -181
  160. isa_model/training/core/dataset.py +0 -222
  161. isa_model/training/core/trainer.py +0 -720
  162. isa_model/training/core/utils.py +0 -213
  163. isa_model/training/examples/intelligent_training_example.py +0 -281
  164. isa_model/training/factory.py +0 -424
  165. isa_model/training/intelligent/__init__.py +0 -25
  166. isa_model/training/intelligent/decision_engine.py +0 -643
  167. isa_model/training/intelligent/intelligent_factory.py +0 -888
  168. isa_model/training/intelligent/knowledge_base.py +0 -751
  169. isa_model/training/intelligent/resource_optimizer.py +0 -839
  170. isa_model/training/intelligent/task_classifier.py +0 -576
  171. isa_model/training/storage/__init__.py +0 -24
  172. isa_model/training/storage/core_integration.py +0 -439
  173. isa_model/training/storage/training_repository.py +0 -552
  174. isa_model/training/storage/training_storage.py +0 -628
  175. isa_model-0.4.0.dist-info/RECORD +0 -182
  176. /isa_model/deployment/{cloud/modal → modal/services/audio}/isa_audio_chatTTS_service.py +0 -0
  177. /isa_model/deployment/{cloud/modal → modal/services/audio}/isa_audio_fish_service.py +0 -0
  178. /isa_model/deployment/{cloud/modal → modal/services/audio}/isa_audio_openvoice_service.py +0 -0
  179. /isa_model/deployment/{cloud/modal → modal/services/audio}/isa_audio_service_v2.py +0 -0
  180. /isa_model/deployment/{cloud/modal → modal/services/embedding}/isa_embed_rerank_service.py +0 -0
  181. /isa_model/deployment/{cloud/modal → modal/services/video}/isa_video_hunyuan_service.py +0 -0
  182. /isa_model/deployment/{cloud/modal → modal/services/vision}/isa_vision_ocr_service.py +0 -0
  183. /isa_model/deployment/{cloud/modal → modal/services/vision}/isa_vision_qwen25_service.py +0 -0
  184. /isa_model/deployment/{cloud/modal → modal/services/vision}/isa_vision_table_service.py +0 -0
  185. /isa_model/deployment/{cloud/modal → modal/services/vision}/isa_vision_ui_service.py +0 -0
  186. /isa_model/deployment/{cloud/modal → modal/services/vision}/isa_vision_ui_service_optimized.py +0 -0
  187. /isa_model/deployment/{services → modal/services/vision}/simple_auto_deploy_vision_service.py +0 -0
  188. {isa_model-0.4.0.dist-info → isa_model-0.4.4.dist-info}/WHEEL +0 -0
  189. {isa_model-0.4.0.dist-info → isa_model-0.4.4.dist-info}/top_level.txt +0 -0
@@ -1,643 +0,0 @@
1
- """
2
- Intelligent Decision Engine for Training Configuration
3
-
4
- This module provides AI-powered decision making for training configurations,
5
- automatically selecting optimal models, parameters, and resources based on
6
- user requirements, dataset characteristics, and historical performance data.
7
- """
8
-
9
- import logging
10
- from typing import Dict, List, Optional, Any, Tuple
11
- from dataclasses import dataclass, field
12
- from datetime import datetime
13
- import json
14
- import os
15
-
16
- from .task_classifier import TaskClassifier
17
- from .knowledge_base import KnowledgeBase
18
- from .resource_optimizer import ResourceOptimizer
19
- from ..core.config import TrainingConfig, LoRAConfig, DatasetConfig
20
-
21
- logger = logging.getLogger(__name__)
22
-
23
-
24
- @dataclass
25
- class TrainingRequest:
26
- """User training request with requirements and constraints."""
27
-
28
- # Core requirements
29
- description: str # Natural language description
30
- dataset_source: str # Dataset path or HuggingFace name
31
-
32
- # Quality and performance targets
33
- quality_target: str = "balanced" # "fast", "balanced", "high"
34
- budget_limit: Optional[float] = None # USD budget limit
35
- time_limit: Optional[int] = None # Hours time limit
36
-
37
- # Optional constraints
38
- model_preferences: Optional[List[str]] = None # Preferred models
39
- gpu_preferences: Optional[List[str]] = None # Preferred GPU types
40
- cloud_preferences: Optional[List[str]] = None # Preferred cloud providers
41
-
42
- # Advanced options
43
- use_lora: Optional[bool] = None # Force LoRA usage
44
- batch_size: Optional[int] = None # Force batch size
45
- learning_rate: Optional[float] = None # Force learning rate
46
-
47
- # Metadata
48
- user_id: Optional[str] = None
49
- project_name: Optional[str] = None
50
- tags: Dict[str, str] = field(default_factory=dict)
51
-
52
-
53
- @dataclass
54
- class TrainingRecommendation:
55
- """Intelligent training configuration recommendation."""
56
-
57
- # Model selection
58
- model_name: str
59
- trainer_type: str # "llm", "sd", "ml"
60
-
61
- # Training configuration
62
- training_config: TrainingConfig
63
-
64
- # Resource selection
65
- recommended_gpu: str
66
- cloud_provider: str
67
- estimated_cost: float
68
- estimated_time: int # hours
69
-
70
- # Performance predictions
71
- predicted_quality: str # "excellent", "good", "fair"
72
- confidence_score: float # 0.0 to 1.0
73
-
74
- # Rationale
75
- decision_reasons: List[str]
76
- alternatives: List[Dict[str, Any]]
77
-
78
- # Metadata
79
- created_at: datetime = field(default_factory=datetime.now)
80
- version: str = "1.0"
81
-
82
-
83
- class IntelligentDecisionEngine:
84
- """
85
- Core intelligent decision engine for training configuration.
86
-
87
- This engine analyzes training requests and generates optimal configuration
88
- recommendations based on:
89
- - Task type and complexity analysis
90
- - Dataset characteristics
91
- - Historical performance data
92
- - Resource availability and pricing
93
- - User preferences and constraints
94
-
95
- Example:
96
- ```python
97
- engine = IntelligentDecisionEngine()
98
-
99
- request = TrainingRequest(
100
- description="Fine-tune a Chinese dialogue model for customer service",
101
- dataset_source="my-chinese-dialogues.json",
102
- quality_target="high",
103
- budget_limit=500.0,
104
- time_limit=12
105
- )
106
-
107
- recommendation = engine.analyze_and_recommend(request)
108
- print(f"Recommended: {recommendation.model_name}")
109
- print(f"Cost: ${recommendation.estimated_cost}")
110
- ```
111
- """
112
-
113
- def __init__(self, knowledge_base: Optional[KnowledgeBase] = None):
114
- """
115
- Initialize the intelligent decision engine.
116
-
117
- Args:
118
- knowledge_base: Optional knowledge base instance
119
- """
120
- self.task_classifier = TaskClassifier()
121
- self.knowledge_base = knowledge_base or KnowledgeBase()
122
- self.resource_optimizer = ResourceOptimizer()
123
-
124
- # Decision history for learning
125
- self.decision_history: List[Dict[str, Any]] = []
126
-
127
- logger.info("Intelligent Decision Engine initialized")
128
-
129
- def analyze_and_recommend(self, request: TrainingRequest) -> TrainingRecommendation:
130
- """
131
- Analyze training request and generate intelligent recommendation.
132
-
133
- Args:
134
- request: Training request with requirements
135
-
136
- Returns:
137
- Complete training recommendation
138
- """
139
- logger.info(f"Analyzing training request: {request.description[:100]}...")
140
-
141
- try:
142
- # Step 1: Classify task type and extract requirements
143
- task_analysis = self.task_classifier.analyze_request(
144
- request.description,
145
- request.dataset_source
146
- )
147
-
148
- # Step 2: Analyze dataset characteristics
149
- dataset_analysis = self._analyze_dataset(request.dataset_source)
150
-
151
- # Step 3: Generate model recommendations
152
- model_candidates = self.knowledge_base.recommend_models(
153
- task_type=task_analysis.task_type,
154
- domain=task_analysis.domain,
155
- dataset_size=dataset_analysis.get("size", 0),
156
- quality_target=request.quality_target,
157
- constraints={
158
- "budget": request.budget_limit,
159
- "time": request.time_limit,
160
- "preferences": request.model_preferences
161
- }
162
- )
163
-
164
- # Step 4: Select optimal model
165
- selected_model = self._select_optimal_model(
166
- model_candidates,
167
- task_analysis,
168
- dataset_analysis,
169
- request
170
- )
171
-
172
- # Step 5: Generate training configuration
173
- training_config = self._generate_training_config(
174
- selected_model,
175
- task_analysis,
176
- dataset_analysis,
177
- request
178
- )
179
-
180
- # Step 6: Optimize resources
181
- resource_recommendation = self.resource_optimizer.optimize_resources(
182
- model_name=selected_model["name"],
183
- training_config=training_config,
184
- budget_limit=request.budget_limit,
185
- time_limit=request.time_limit,
186
- preferences={
187
- "gpu": request.gpu_preferences,
188
- "cloud": request.cloud_preferences
189
- }
190
- )
191
-
192
- # Step 7: Generate alternatives
193
- alternatives = self._generate_alternatives(
194
- model_candidates[:3], # Top 3 alternatives
195
- task_analysis,
196
- dataset_analysis,
197
- request
198
- )
199
-
200
- # Step 8: Create recommendation
201
- recommendation = TrainingRecommendation(
202
- model_name=selected_model["name"],
203
- trainer_type=selected_model["trainer_type"],
204
- training_config=training_config,
205
- recommended_gpu=resource_recommendation.gpu,
206
- cloud_provider=resource_recommendation.cloud_provider,
207
- estimated_cost=resource_recommendation.estimated_cost,
208
- estimated_time=resource_recommendation.estimated_time,
209
- predicted_quality=self._predict_quality(
210
- selected_model, training_config, dataset_analysis
211
- ),
212
- confidence_score=self._calculate_confidence(
213
- selected_model, task_analysis, dataset_analysis
214
- ),
215
- decision_reasons=self._generate_decision_reasons(
216
- selected_model, resource_recommendation, task_analysis
217
- ),
218
- alternatives=alternatives
219
- )
220
-
221
- # Store for learning
222
- self._store_decision(request, recommendation, task_analysis)
223
-
224
- logger.info(f"Generated recommendation: {recommendation.model_name} "
225
- f"(${recommendation.estimated_cost:.2f}, {recommendation.estimated_time}h)")
226
-
227
- return recommendation
228
-
229
- except Exception as e:
230
- logger.error(f"Failed to analyze training request: {e}")
231
- raise
232
-
233
- def _analyze_dataset(self, dataset_source: str) -> Dict[str, Any]:
234
- """Analyze dataset characteristics."""
235
- analysis = {
236
- "size": 0,
237
- "format": "unknown",
238
- "language": "unknown",
239
- "complexity": "medium",
240
- "quality": "unknown"
241
- }
242
-
243
- try:
244
- if os.path.exists(dataset_source):
245
- # Local dataset analysis
246
- with open(dataset_source, 'r', encoding='utf-8') as f:
247
- if dataset_source.endswith('.json'):
248
- data = json.load(f)
249
- if isinstance(data, list):
250
- analysis["size"] = len(data)
251
- analysis["format"] = "json"
252
-
253
- # Analyze first few samples
254
- if data:
255
- sample = data[0]
256
- if isinstance(sample, dict):
257
- if "instruction" in sample and "output" in sample:
258
- analysis["format"] = "alpaca"
259
- elif "messages" in sample:
260
- analysis["format"] = "sharegpt"
261
-
262
- # Estimate complexity based on text length
263
- text_content = str(sample)
264
- if len(text_content) > 1000:
265
- analysis["complexity"] = "high"
266
- elif len(text_content) < 200:
267
- analysis["complexity"] = "low"
268
- else:
269
- # HuggingFace dataset - get from knowledge base
270
- dataset_info = self.knowledge_base.get_dataset_info(dataset_source)
271
- if dataset_info:
272
- analysis.update(dataset_info)
273
- else:
274
- # Default estimates for unknown HF datasets
275
- analysis["size"] = 10000 # Conservative estimate
276
- analysis["format"] = "hf_dataset"
277
-
278
- except Exception as e:
279
- logger.warning(f"Failed to analyze dataset {dataset_source}: {e}")
280
-
281
- return analysis
282
-
283
- def _select_optimal_model(
284
- self,
285
- candidates: List[Dict[str, Any]],
286
- task_analysis: Any,
287
- dataset_analysis: Dict[str, Any],
288
- request: TrainingRequest
289
- ) -> Dict[str, Any]:
290
- """Select the optimal model from candidates."""
291
- if not candidates:
292
- raise ValueError("No suitable models found for the task")
293
-
294
- # Score each candidate
295
- scored_candidates = []
296
- for candidate in candidates:
297
- score = self._score_model_candidate(
298
- candidate, task_analysis, dataset_analysis, request
299
- )
300
- scored_candidates.append((candidate, score))
301
-
302
- # Sort by score (highest first)
303
- scored_candidates.sort(key=lambda x: x[1], reverse=True)
304
-
305
- return scored_candidates[0][0]
306
-
307
- def _score_model_candidate(
308
- self,
309
- candidate: Dict[str, Any],
310
- task_analysis: Any,
311
- dataset_analysis: Dict[str, Any],
312
- request: TrainingRequest
313
- ) -> float:
314
- """Score a model candidate based on suitability."""
315
- score = 0.0
316
-
317
- # Base suitability score
318
- score += candidate.get("task_suitability", 0.5) * 30
319
-
320
- # Quality vs speed tradeoff
321
- if request.quality_target == "fast":
322
- score += (1.0 - candidate.get("complexity", 0.5)) * 20
323
- elif request.quality_target == "high":
324
- score += candidate.get("quality_score", 0.5) * 20
325
- else: # balanced
326
- score += (candidate.get("quality_score", 0.5) +
327
- (1.0 - candidate.get("complexity", 0.5))) * 10
328
-
329
- # Budget considerations
330
- if request.budget_limit:
331
- estimated_cost = candidate.get("estimated_cost", float('inf'))
332
- if estimated_cost <= request.budget_limit:
333
- score += 15
334
- else:
335
- score -= 10
336
-
337
- # Time considerations
338
- if request.time_limit:
339
- estimated_time = candidate.get("estimated_time", float('inf'))
340
- if estimated_time <= request.time_limit:
341
- score += 10
342
- else:
343
- score -= 5
344
-
345
- # User preferences
346
- if request.model_preferences:
347
- for pref in request.model_preferences:
348
- if pref.lower() in candidate["name"].lower():
349
- score += 5
350
-
351
- # Dataset size compatibility
352
- dataset_size = dataset_analysis.get("size", 0)
353
- if dataset_size > 0:
354
- optimal_size = candidate.get("optimal_dataset_size", 10000)
355
- size_ratio = min(dataset_size / optimal_size, optimal_size / dataset_size)
356
- score += size_ratio * 10
357
-
358
- return max(0.0, score)
359
-
360
- def _generate_training_config(
361
- self,
362
- selected_model: Dict[str, Any],
363
- task_analysis: Any,
364
- dataset_analysis: Dict[str, Any],
365
- request: TrainingRequest
366
- ) -> TrainingConfig:
367
- """Generate intelligent training configuration."""
368
-
369
- # Base configuration from model defaults
370
- base_config = selected_model.get("default_config", {})
371
-
372
- # Override with intelligent selections
373
- config_params = {
374
- "model_name": selected_model["name"],
375
- "output_dir": f"./training_outputs/{selected_model['name'].replace('/', '_')}_{datetime.now().strftime('%Y%m%d_%H%M%S')}",
376
- "training_type": task_analysis.training_type,
377
-
378
- # Intelligent parameter selection
379
- "num_epochs": self._select_num_epochs(dataset_analysis, request),
380
- "batch_size": self._select_batch_size(selected_model, request),
381
- "learning_rate": self._select_learning_rate(selected_model, dataset_analysis, request),
382
-
383
- # Advanced parameters
384
- "gradient_accumulation_steps": self._select_gradient_accumulation(selected_model, request),
385
- "warmup_steps": self._select_warmup_steps(dataset_analysis),
386
- "weight_decay": base_config.get("weight_decay", 0.01),
387
- "max_grad_norm": base_config.get("max_grad_norm", 1.0),
388
- }
389
-
390
- # Apply user overrides
391
- if request.batch_size:
392
- config_params["batch_size"] = request.batch_size
393
- if request.learning_rate:
394
- config_params["learning_rate"] = request.learning_rate
395
-
396
- # LoRA configuration
397
- lora_config = None
398
- if request.use_lora is not False: # Default to True unless explicitly False
399
- lora_config = LoRAConfig(
400
- use_lora=True,
401
- lora_rank=self._select_lora_rank(selected_model, request),
402
- lora_alpha=self._select_lora_alpha(selected_model, request),
403
- lora_dropout=base_config.get("lora_dropout", 0.05),
404
- lora_target_modules=selected_model.get("lora_targets", ["q_proj", "v_proj"])
405
- )
406
-
407
- # Dataset configuration
408
- dataset_config = DatasetConfig(
409
- dataset_path=request.dataset_source,
410
- dataset_format=dataset_analysis.get("format", "alpaca"),
411
- max_length=self._select_max_length(selected_model, task_analysis),
412
- validation_split=0.1,
413
- preprocessing_num_workers=4
414
- )
415
-
416
- return TrainingConfig(
417
- **config_params,
418
- lora_config=lora_config,
419
- dataset_config=dataset_config
420
- )
421
-
422
- def _select_num_epochs(self, dataset_analysis: Dict[str, Any], request: TrainingRequest) -> int:
423
- """Intelligently select number of epochs."""
424
- dataset_size = dataset_analysis.get("size", 10000)
425
-
426
- if request.quality_target == "fast":
427
- return 1
428
- elif request.quality_target == "high":
429
- if dataset_size < 1000:
430
- return 5
431
- elif dataset_size < 10000:
432
- return 3
433
- else:
434
- return 2
435
- else: # balanced
436
- if dataset_size < 1000:
437
- return 3
438
- elif dataset_size < 10000:
439
- return 2
440
- else:
441
- return 1
442
-
443
- def _select_batch_size(self, selected_model: Dict[str, Any], request: TrainingRequest) -> int:
444
- """Intelligently select batch size."""
445
- model_size = selected_model.get("parameters", 7_000_000_000)
446
-
447
- if model_size > 13_000_000_000: # 13B+
448
- return 1
449
- elif model_size > 7_000_000_000: # 7B+
450
- return 2
451
- else: # < 7B
452
- return 4
453
-
454
- def _select_learning_rate(
455
- self,
456
- selected_model: Dict[str, Any],
457
- dataset_analysis: Dict[str, Any],
458
- request: TrainingRequest
459
- ) -> float:
460
- """Intelligently select learning rate."""
461
- base_lr = selected_model.get("default_lr", 2e-5)
462
-
463
- # Adjust based on dataset size
464
- dataset_size = dataset_analysis.get("size", 10000)
465
- if dataset_size < 1000:
466
- return base_lr * 0.5 # Lower LR for small datasets
467
- elif dataset_size > 100000:
468
- return base_lr * 1.5 # Higher LR for large datasets
469
-
470
- return base_lr
471
-
472
- def _select_gradient_accumulation(self, selected_model: Dict[str, Any], request: TrainingRequest) -> int:
473
- """Select gradient accumulation steps."""
474
- model_size = selected_model.get("parameters", 7_000_000_000)
475
-
476
- if model_size > 13_000_000_000: # 13B+
477
- return 8
478
- elif model_size > 7_000_000_000: # 7B+
479
- return 4
480
- else:
481
- return 2
482
-
483
- def _select_warmup_steps(self, dataset_analysis: Dict[str, Any]) -> int:
484
- """Select warmup steps."""
485
- dataset_size = dataset_analysis.get("size", 10000)
486
- return max(10, min(500, dataset_size // 100))
487
-
488
- def _select_lora_rank(self, selected_model: Dict[str, Any], request: TrainingRequest) -> int:
489
- """Select LoRA rank."""
490
- if request.quality_target == "fast":
491
- return 4
492
- elif request.quality_target == "high":
493
- return 16
494
- else: # balanced
495
- return 8
496
-
497
- def _select_lora_alpha(self, selected_model: Dict[str, Any], request: TrainingRequest) -> int:
498
- """Select LoRA alpha."""
499
- rank = self._select_lora_rank(selected_model, request)
500
- return rank * 2 # Common practice: alpha = 2 * rank
501
-
502
- def _select_max_length(self, selected_model: Dict[str, Any], task_analysis: Any) -> int:
503
- """Select maximum sequence length."""
504
- if task_analysis.task_type == "chat":
505
- return 2048
506
- elif task_analysis.task_type == "summarization":
507
- return 1024
508
- else:
509
- return 512
510
-
511
- def _predict_quality(
512
- self,
513
- selected_model: Dict[str, Any],
514
- training_config: TrainingConfig,
515
- dataset_analysis: Dict[str, Any]
516
- ) -> str:
517
- """Predict training quality."""
518
- # Simplified quality prediction
519
- quality_score = selected_model.get("quality_score", 0.5)
520
-
521
- if quality_score > 0.8:
522
- return "excellent"
523
- elif quality_score > 0.6:
524
- return "good"
525
- else:
526
- return "fair"
527
-
528
- def _calculate_confidence(
529
- self,
530
- selected_model: Dict[str, Any],
531
- task_analysis: Any,
532
- dataset_analysis: Dict[str, Any]
533
- ) -> float:
534
- """Calculate confidence score for recommendation."""
535
- confidence = 0.7 # Base confidence
536
-
537
- # Increase confidence for well-known models
538
- if selected_model.get("is_popular", False):
539
- confidence += 0.1
540
-
541
- # Increase confidence for good task match
542
- if selected_model.get("task_suitability", 0.5) > 0.8:
543
- confidence += 0.1
544
-
545
- # Decrease confidence for very small datasets
546
- if dataset_analysis.get("size", 0) < 100:
547
- confidence -= 0.2
548
-
549
- return max(0.1, min(1.0, confidence))
550
-
551
- def _generate_decision_reasons(
552
- self,
553
- selected_model: Dict[str, Any],
554
- resource_recommendation: Any,
555
- task_analysis: Any
556
- ) -> List[str]:
557
- """Generate human-readable reasons for the decision."""
558
- reasons = []
559
-
560
- reasons.append(f"Selected {selected_model['name']} for {task_analysis.task_type} task")
561
-
562
- if selected_model.get("is_popular"):
563
- reasons.append("This model is widely used and well-tested")
564
-
565
- if selected_model.get("task_suitability", 0.5) > 0.8:
566
- reasons.append("Excellent match for your task requirements")
567
-
568
- reasons.append(f"Recommended {resource_recommendation.gpu} for optimal performance")
569
-
570
- if resource_recommendation.estimated_cost < 100:
571
- reasons.append("Cost-effective option within budget")
572
-
573
- return reasons
574
-
575
- def _generate_alternatives(
576
- self,
577
- alternative_models: List[Dict[str, Any]],
578
- task_analysis: Any,
579
- dataset_analysis: Dict[str, Any],
580
- request: TrainingRequest
581
- ) -> List[Dict[str, Any]]:
582
- """Generate alternative recommendations."""
583
- alternatives = []
584
-
585
- for model in alternative_models:
586
- # Generate simplified config for alternative
587
- alt_config = {
588
- "model_name": model["name"],
589
- "estimated_cost": model.get("estimated_cost", 0.0),
590
- "estimated_time": model.get("estimated_time", 0),
591
- "quality_score": model.get("quality_score", 0.5),
592
- "reason": f"Alternative {model.get('category', 'model')} option"
593
- }
594
- alternatives.append(alt_config)
595
-
596
- return alternatives
597
-
598
- def _store_decision(
599
- self,
600
- request: TrainingRequest,
601
- recommendation: TrainingRecommendation,
602
- task_analysis: Any
603
- ) -> None:
604
- """Store decision for learning and improvement."""
605
- decision_record = {
606
- "timestamp": datetime.now().isoformat(),
607
- "request": {
608
- "description": request.description,
609
- "dataset_source": request.dataset_source,
610
- "quality_target": request.quality_target,
611
- "budget_limit": request.budget_limit,
612
- "time_limit": request.time_limit
613
- },
614
- "recommendation": {
615
- "model_name": recommendation.model_name,
616
- "trainer_type": recommendation.trainer_type,
617
- "estimated_cost": recommendation.estimated_cost,
618
- "estimated_time": recommendation.estimated_time,
619
- "confidence_score": recommendation.confidence_score
620
- },
621
- "task_analysis": {
622
- "task_type": getattr(task_analysis, 'task_type', 'unknown'),
623
- "domain": getattr(task_analysis, 'domain', 'unknown'),
624
- "complexity": getattr(task_analysis, 'complexity', 'unknown')
625
- }
626
- }
627
-
628
- self.decision_history.append(decision_record)
629
-
630
- # Keep only last 1000 decisions
631
- if len(self.decision_history) > 1000:
632
- self.decision_history = self.decision_history[-1000:]
633
-
634
- def get_decision_history(self) -> List[Dict[str, Any]]:
635
- """Get decision history for analysis."""
636
- return self.decision_history.copy()
637
-
638
- def learn_from_feedback(self, recommendation_id: str, feedback: Dict[str, Any]) -> None:
639
- """Learn from user feedback to improve future recommendations."""
640
- # This would implement learning from user feedback
641
- # For now, just log the feedback
642
- logger.info(f"Received feedback for recommendation {recommendation_id}: {feedback}")
643
- # TODO: Implement actual learning mechanism