isa-model 0.4.0__py3-none-any.whl → 0.4.3__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 (199) 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 +40 -17
  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/storage/hf_storage.py +1 -1
  26. isa_model/core/types.py +1 -0
  27. isa_model/deployment/__init__.py +5 -48
  28. isa_model/deployment/core/__init__.py +2 -31
  29. isa_model/deployment/core/deployment_manager.py +1278 -370
  30. isa_model/deployment/local/__init__.py +31 -0
  31. isa_model/deployment/local/config.py +248 -0
  32. isa_model/deployment/local/gpu_gateway.py +607 -0
  33. isa_model/deployment/local/health_checker.py +428 -0
  34. isa_model/deployment/local/provider.py +586 -0
  35. isa_model/deployment/local/tensorrt_service.py +621 -0
  36. isa_model/deployment/local/transformers_service.py +644 -0
  37. isa_model/deployment/local/vllm_service.py +527 -0
  38. isa_model/deployment/modal/__init__.py +8 -0
  39. isa_model/deployment/modal/config.py +136 -0
  40. isa_model/deployment/{services/auto_hf_modal_deployer.py → modal/deployer.py} +1 -1
  41. isa_model/deployment/modal/services/__init__.py +3 -0
  42. isa_model/deployment/modal/services/audio/__init__.py +1 -0
  43. isa_model/deployment/modal/services/embedding/__init__.py +1 -0
  44. isa_model/deployment/modal/services/llm/__init__.py +1 -0
  45. isa_model/deployment/modal/services/llm/isa_llm_service.py +424 -0
  46. isa_model/deployment/modal/services/video/__init__.py +1 -0
  47. isa_model/deployment/modal/services/vision/__init__.py +1 -0
  48. isa_model/deployment/models/org-org-acme-corp-tenant-a-service-llm-20250825-225822/tenant-a-service_modal_service.py +48 -0
  49. isa_model/deployment/models/org-test-org-123-prefix-test-service-llm-20250825-225822/prefix-test-service_modal_service.py +48 -0
  50. isa_model/deployment/models/test-llm-service-llm-20250825-204442/test-llm-service_modal_service.py +48 -0
  51. isa_model/deployment/models/test-monitoring-gpt2-llm-20250825-212906/test-monitoring-gpt2_modal_service.py +48 -0
  52. isa_model/deployment/models/test-monitoring-gpt2-llm-20250825-213009/test-monitoring-gpt2_modal_service.py +48 -0
  53. isa_model/deployment/storage/__init__.py +5 -0
  54. isa_model/deployment/storage/deployment_repository.py +824 -0
  55. isa_model/deployment/triton/__init__.py +10 -0
  56. isa_model/deployment/triton/config.py +196 -0
  57. isa_model/deployment/triton/configs/__init__.py +1 -0
  58. isa_model/deployment/triton/provider.py +512 -0
  59. isa_model/deployment/triton/scripts/__init__.py +1 -0
  60. isa_model/deployment/triton/templates/__init__.py +1 -0
  61. isa_model/inference/__init__.py +47 -1
  62. isa_model/inference/ai_factory.py +137 -10
  63. isa_model/inference/legacy_services/__init__.py +21 -0
  64. isa_model/inference/legacy_services/model_evaluation.py +637 -0
  65. isa_model/inference/legacy_services/model_service.py +573 -0
  66. isa_model/inference/legacy_services/model_serving.py +717 -0
  67. isa_model/inference/legacy_services/model_training.py +561 -0
  68. isa_model/inference/models/__init__.py +21 -0
  69. isa_model/inference/models/inference_config.py +551 -0
  70. isa_model/inference/models/inference_record.py +675 -0
  71. isa_model/inference/models/performance_models.py +714 -0
  72. isa_model/inference/repositories/__init__.py +9 -0
  73. isa_model/inference/repositories/inference_repository.py +828 -0
  74. isa_model/inference/services/audio/base_stt_service.py +184 -11
  75. isa_model/inference/services/audio/openai_stt_service.py +22 -6
  76. isa_model/inference/services/custom_model_manager.py +277 -0
  77. isa_model/inference/services/embedding/ollama_embed_service.py +15 -3
  78. isa_model/inference/services/embedding/resilient_embed_service.py +285 -0
  79. isa_model/inference/services/llm/__init__.py +10 -2
  80. isa_model/inference/services/llm/base_llm_service.py +335 -24
  81. isa_model/inference/services/llm/cerebras_llm_service.py +628 -0
  82. isa_model/inference/services/llm/helpers/llm_adapter.py +9 -4
  83. isa_model/inference/services/llm/helpers/llm_prompts.py +342 -0
  84. isa_model/inference/services/llm/helpers/llm_utils.py +321 -23
  85. isa_model/inference/services/llm/huggingface_llm_service.py +581 -0
  86. isa_model/inference/services/llm/local_llm_service.py +747 -0
  87. isa_model/inference/services/llm/ollama_llm_service.py +9 -2
  88. isa_model/inference/services/llm/openai_llm_service.py +33 -16
  89. isa_model/inference/services/llm/yyds_llm_service.py +8 -2
  90. isa_model/inference/services/vision/__init__.py +22 -1
  91. isa_model/inference/services/vision/blip_vision_service.py +359 -0
  92. isa_model/inference/services/vision/helpers/image_utils.py +8 -5
  93. isa_model/inference/services/vision/isa_vision_service.py +65 -4
  94. isa_model/inference/services/vision/openai_vision_service.py +19 -10
  95. isa_model/inference/services/vision/vgg16_vision_service.py +257 -0
  96. isa_model/serving/api/cache_manager.py +245 -0
  97. isa_model/serving/api/dependencies/__init__.py +1 -0
  98. isa_model/serving/api/dependencies/auth.py +194 -0
  99. isa_model/serving/api/dependencies/database.py +139 -0
  100. isa_model/serving/api/error_handlers.py +284 -0
  101. isa_model/serving/api/fastapi_server.py +172 -22
  102. isa_model/serving/api/middleware/auth.py +8 -2
  103. isa_model/serving/api/middleware/security.py +23 -33
  104. isa_model/serving/api/middleware/tenant_context.py +414 -0
  105. isa_model/serving/api/routes/analytics.py +4 -1
  106. isa_model/serving/api/routes/config.py +645 -0
  107. isa_model/serving/api/routes/deployment_billing.py +315 -0
  108. isa_model/serving/api/routes/deployments.py +138 -2
  109. isa_model/serving/api/routes/gpu_gateway.py +440 -0
  110. isa_model/serving/api/routes/health.py +32 -12
  111. isa_model/serving/api/routes/inference_monitoring.py +486 -0
  112. isa_model/serving/api/routes/local_deployments.py +448 -0
  113. isa_model/serving/api/routes/tenants.py +575 -0
  114. isa_model/serving/api/routes/unified.py +680 -18
  115. isa_model/serving/api/routes/webhooks.py +479 -0
  116. isa_model/serving/api/startup.py +68 -54
  117. isa_model/utils/gpu_utils.py +311 -0
  118. {isa_model-0.4.0.dist-info → isa_model-0.4.3.dist-info}/METADATA +66 -24
  119. isa_model-0.4.3.dist-info/RECORD +193 -0
  120. isa_model/core/storage/minio_storage.py +0 -0
  121. isa_model/deployment/cloud/__init__.py +0 -9
  122. isa_model/deployment/cloud/modal/__init__.py +0 -10
  123. isa_model/deployment/core/deployment_config.py +0 -356
  124. isa_model/deployment/core/isa_deployment_service.py +0 -401
  125. isa_model/deployment/gpu_int8_ds8/app/server.py +0 -66
  126. isa_model/deployment/gpu_int8_ds8/scripts/test_client.py +0 -43
  127. isa_model/deployment/gpu_int8_ds8/scripts/test_client_os.py +0 -35
  128. isa_model/deployment/runtime/deployed_service.py +0 -338
  129. isa_model/deployment/services/__init__.py +0 -9
  130. isa_model/deployment/services/auto_deploy_vision_service.py +0 -538
  131. isa_model/deployment/services/model_service.py +0 -332
  132. isa_model/deployment/services/service_monitor.py +0 -356
  133. isa_model/deployment/services/service_registry.py +0 -527
  134. isa_model/eval/__init__.py +0 -92
  135. isa_model/eval/benchmarks/__init__.py +0 -27
  136. isa_model/eval/benchmarks/multimodal_datasets.py +0 -460
  137. isa_model/eval/benchmarks.py +0 -701
  138. isa_model/eval/config/__init__.py +0 -10
  139. isa_model/eval/config/evaluation_config.py +0 -108
  140. isa_model/eval/evaluators/__init__.py +0 -24
  141. isa_model/eval/evaluators/audio_evaluator.py +0 -727
  142. isa_model/eval/evaluators/base_evaluator.py +0 -503
  143. isa_model/eval/evaluators/embedding_evaluator.py +0 -742
  144. isa_model/eval/evaluators/llm_evaluator.py +0 -472
  145. isa_model/eval/evaluators/vision_evaluator.py +0 -564
  146. isa_model/eval/example_evaluation.py +0 -395
  147. isa_model/eval/factory.py +0 -798
  148. isa_model/eval/infrastructure/__init__.py +0 -24
  149. isa_model/eval/infrastructure/experiment_tracker.py +0 -466
  150. isa_model/eval/isa_benchmarks.py +0 -700
  151. isa_model/eval/isa_integration.py +0 -582
  152. isa_model/eval/metrics.py +0 -951
  153. isa_model/eval/tests/unit/test_basic.py +0 -396
  154. isa_model/serving/api/routes/evaluations.py +0 -579
  155. isa_model/training/__init__.py +0 -168
  156. isa_model/training/annotation/annotation_schema.py +0 -47
  157. isa_model/training/annotation/processors/annotation_processor.py +0 -126
  158. isa_model/training/annotation/storage/dataset_manager.py +0 -131
  159. isa_model/training/annotation/storage/dataset_schema.py +0 -44
  160. isa_model/training/annotation/tests/test_annotation_flow.py +0 -109
  161. isa_model/training/annotation/tests/test_minio copy.py +0 -113
  162. isa_model/training/annotation/tests/test_minio_upload.py +0 -43
  163. isa_model/training/annotation/views/annotation_controller.py +0 -158
  164. isa_model/training/cloud/__init__.py +0 -22
  165. isa_model/training/cloud/job_orchestrator.py +0 -402
  166. isa_model/training/cloud/runpod_trainer.py +0 -454
  167. isa_model/training/cloud/storage_manager.py +0 -482
  168. isa_model/training/core/__init__.py +0 -26
  169. isa_model/training/core/config.py +0 -181
  170. isa_model/training/core/dataset.py +0 -222
  171. isa_model/training/core/trainer.py +0 -720
  172. isa_model/training/core/utils.py +0 -213
  173. isa_model/training/examples/intelligent_training_example.py +0 -281
  174. isa_model/training/factory.py +0 -424
  175. isa_model/training/intelligent/__init__.py +0 -25
  176. isa_model/training/intelligent/decision_engine.py +0 -643
  177. isa_model/training/intelligent/intelligent_factory.py +0 -888
  178. isa_model/training/intelligent/knowledge_base.py +0 -751
  179. isa_model/training/intelligent/resource_optimizer.py +0 -839
  180. isa_model/training/intelligent/task_classifier.py +0 -576
  181. isa_model/training/storage/__init__.py +0 -24
  182. isa_model/training/storage/core_integration.py +0 -439
  183. isa_model/training/storage/training_repository.py +0 -552
  184. isa_model/training/storage/training_storage.py +0 -628
  185. isa_model-0.4.0.dist-info/RECORD +0 -182
  186. /isa_model/deployment/{cloud/modal → modal/services/audio}/isa_audio_chatTTS_service.py +0 -0
  187. /isa_model/deployment/{cloud/modal → modal/services/audio}/isa_audio_fish_service.py +0 -0
  188. /isa_model/deployment/{cloud/modal → modal/services/audio}/isa_audio_openvoice_service.py +0 -0
  189. /isa_model/deployment/{cloud/modal → modal/services/audio}/isa_audio_service_v2.py +0 -0
  190. /isa_model/deployment/{cloud/modal → modal/services/embedding}/isa_embed_rerank_service.py +0 -0
  191. /isa_model/deployment/{cloud/modal → modal/services/video}/isa_video_hunyuan_service.py +0 -0
  192. /isa_model/deployment/{cloud/modal → modal/services/vision}/isa_vision_ocr_service.py +0 -0
  193. /isa_model/deployment/{cloud/modal → modal/services/vision}/isa_vision_qwen25_service.py +0 -0
  194. /isa_model/deployment/{cloud/modal → modal/services/vision}/isa_vision_table_service.py +0 -0
  195. /isa_model/deployment/{cloud/modal → modal/services/vision}/isa_vision_ui_service.py +0 -0
  196. /isa_model/deployment/{cloud/modal → modal/services/vision}/isa_vision_ui_service_optimized.py +0 -0
  197. /isa_model/deployment/{services → modal/services/vision}/simple_auto_deploy_vision_service.py +0 -0
  198. {isa_model-0.4.0.dist-info → isa_model-0.4.3.dist-info}/WHEEL +0 -0
  199. {isa_model-0.4.0.dist-info → isa_model-0.4.3.dist-info}/top_level.txt +0 -0
@@ -1,527 +0,0 @@
1
- """
2
- ServiceRegistry - Enhanced registry for managing deployed model services
3
-
4
- This registry extends the basic ModelRegistry to provide full service lifecycle management
5
- including service discovery, health monitoring, and deployment tracking.
6
- """
7
-
8
- from typing import Dict, List, Optional, Any, Tuple
9
- import logging
10
- from datetime import datetime, timezone
11
- import asyncio
12
- import json
13
-
14
- from .deployment_service import (
15
- DeployedService, ServiceStatus, ServiceType, DeploymentPlatform,
16
- HealthMetrics, ServiceMetrics, ResourceRequirements
17
- )
18
- # Backward compatibility
19
- ModelService = DeployedService
20
- UsageMetrics = ServiceMetrics
21
- from .model_repo import ModelRegistry, ModelType, ModelCapability
22
-
23
- logger = logging.getLogger(__name__)
24
-
25
- class ServiceRegistry:
26
- """
27
- Enhanced registry for managing deployed model services in the MaaS platform
28
-
29
- This registry provides:
30
- - Service registration and discovery
31
- - Health monitoring and status tracking
32
- - Deployment management
33
- - Usage metrics collection
34
- - Integration with existing ModelRegistry
35
- """
36
-
37
- def __init__(self, model_registry: Optional[ModelRegistry] = None):
38
- self.model_registry = model_registry or ModelRegistry()
39
- self._service_cache: Dict[str, ModelService] = {}
40
- self._last_cache_update: Optional[datetime] = None
41
- self._cache_ttl_seconds = 300 # 5 minutes cache TTL
42
-
43
- logger.info("ServiceRegistry initialized with Supabase backend")
44
-
45
- # Service Registration and Management
46
-
47
- async def register_service(self, service: DeployedService) -> bool:
48
- """
49
- Register a new service in the platform
50
-
51
- Args:
52
- service: ModelService instance to register
53
-
54
- Returns:
55
- True if registration successful, False otherwise
56
- """
57
- try:
58
- # First ensure the underlying model is registered
59
- if service.model_id:
60
- await self._ensure_model_registered(service)
61
-
62
- # Check if using Supabase backend
63
- if hasattr(self.model_registry, 'use_supabase') and self.model_registry.use_supabase:
64
- return await self._register_service_supabase(service)
65
- else:
66
- return await self._register_service_sqlite(service)
67
-
68
- except Exception as e:
69
- logger.error(f"Failed to register service {service.service_id}: {e}")
70
- return False
71
-
72
- async def _register_service_supabase(self, service: DeployedService) -> bool:
73
- """Register service using Supabase backend"""
74
- try:
75
- backend = self.model_registry.backend
76
-
77
- # Prepare service data
78
- service_data = {
79
- 'service_id': service.deployment_id, # Updated field name
80
- 'service_name': service.service_name,
81
- 'model_id': service.model_id,
82
- 'deployment_platform': service.deployment_platform.value,
83
- 'service_type': service.service_type.value,
84
- 'status': service.status.value,
85
- 'inference_endpoint': service.inference_endpoint,
86
- 'health_endpoint': service.health_endpoint,
87
- 'config': json.dumps(service.config),
88
- 'gpu_type': service.resource_requirements.gpu_type,
89
- 'memory_mb': service.resource_requirements.memory_mb,
90
- 'cpu_cores': service.resource_requirements.cpu_cores,
91
- 'metadata': json.dumps(service.metadata),
92
- }
93
-
94
- # Insert service
95
- result = backend.supabase.table('services').upsert(service_data).execute()
96
-
97
- if not result.data:
98
- logger.error(f"Failed to insert service {service.service_id}")
99
- return False
100
-
101
- # Insert service capabilities
102
- if service.capabilities:
103
- capability_data = [
104
- {
105
- 'service_id': service.service_id,
106
- 'capability': capability
107
- }
108
- for capability in service.capabilities
109
- ]
110
-
111
- # Delete existing capabilities first
112
- backend.supabase.table('service_capabilities').delete().eq('service_id', service.service_id).execute()
113
-
114
- # Insert new capabilities
115
- cap_result = backend.supabase.table('service_capabilities').insert(capability_data).execute()
116
-
117
- if not cap_result.data:
118
- logger.warning(f"Failed to insert capabilities for service {service.service_id}")
119
-
120
- # Update cache
121
- self._service_cache[service.service_id] = service
122
-
123
- logger.info(f"Successfully registered service {service.service_id} in Supabase")
124
- return True
125
-
126
- except Exception as e:
127
- logger.error(f"Supabase service registration failed: {e}")
128
- return False
129
-
130
- async def _register_service_sqlite(self, service: ModelService) -> bool:
131
- """Register service using SQLite backend (for development/testing)"""
132
- # For SQLite, we'll store services in the models table with a special marker
133
- try:
134
- success = self.model_registry.register_model(
135
- model_id=service.service_id,
136
- model_type=ModelType.VISION, # Default type
137
- capabilities=[ModelCapability(cap) for cap in service.capabilities if hasattr(ModelCapability, cap.upper())],
138
- metadata={
139
- **service.metadata,
140
- 'is_service': True,
141
- 'service_name': service.service_name,
142
- 'deployment_platform': service.deployment_platform.value,
143
- 'service_type': service.service_type.value,
144
- 'inference_endpoint': service.inference_endpoint,
145
- 'health_endpoint': service.health_endpoint,
146
- 'status': service.status.value,
147
- }
148
- )
149
-
150
- if success:
151
- self._service_cache[service.service_id] = service
152
- logger.info(f"Successfully registered service {service.service_id} in SQLite")
153
-
154
- return success
155
-
156
- except Exception as e:
157
- logger.error(f"SQLite service registration failed: {e}")
158
- return False
159
-
160
- async def unregister_service(self, service_id: str) -> bool:
161
- """
162
- Unregister a service from the platform
163
-
164
- Args:
165
- service_id: ID of the service to unregister
166
-
167
- Returns:
168
- True if unregistration successful, False otherwise
169
- """
170
- try:
171
- if hasattr(self.model_registry, 'use_supabase') and self.model_registry.use_supabase:
172
- backend = self.model_registry.backend
173
- result = backend.supabase.table('services').delete().eq('service_id', service_id).execute()
174
- success = bool(result.data)
175
- else:
176
- success = self.model_registry.unregister_model(service_id)
177
-
178
- if success and service_id in self._service_cache:
179
- del self._service_cache[service_id]
180
- logger.info(f"Unregistered service {service_id}")
181
-
182
- return success
183
-
184
- except Exception as e:
185
- logger.error(f"Failed to unregister service {service_id}: {e}")
186
- return False
187
-
188
- # Service Discovery
189
-
190
- async def get_service(self, service_id: str) -> Optional[DeployedService]:
191
- """Get a specific service by ID"""
192
- try:
193
- # Check cache first
194
- if service_id in self._service_cache:
195
- return self._service_cache[service_id]
196
-
197
- if hasattr(self.model_registry, 'use_supabase') and self.model_registry.use_supabase:
198
- return await self._get_service_supabase(service_id)
199
- else:
200
- return await self._get_service_sqlite(service_id)
201
-
202
- except Exception as e:
203
- logger.error(f"Failed to get service {service_id}: {e}")
204
- return None
205
-
206
- async def _get_service_supabase(self, service_id: str) -> Optional[ModelService]:
207
- """Get service from Supabase backend"""
208
- try:
209
- backend = self.model_registry.backend
210
-
211
- # Get service data
212
- result = backend.supabase.table('services').select('*').eq('service_id', service_id).execute()
213
-
214
- if not result.data:
215
- return None
216
-
217
- service_data = result.data[0]
218
-
219
- # Get service capabilities
220
- cap_result = backend.supabase.table('service_capabilities').select('capability').eq('service_id', service_id).execute()
221
- capabilities = [cap['capability'] for cap in cap_result.data]
222
-
223
- # Create ModelService instance
224
- service = self._create_service_from_data(service_data, capabilities)
225
-
226
- # Cache the service
227
- self._service_cache[service_id] = service
228
-
229
- return service
230
-
231
- except Exception as e:
232
- logger.error(f"Failed to get service from Supabase: {e}")
233
- return None
234
-
235
- async def _get_service_sqlite(self, service_id: str) -> Optional[ModelService]:
236
- """Get service from SQLite backend"""
237
- try:
238
- model_info = self.model_registry.get_model_info(service_id)
239
- if not model_info or not model_info.get('metadata', {}).get('is_service'):
240
- return None
241
-
242
- # Convert model info to service
243
- metadata = model_info.get('metadata', {})
244
-
245
- # Create basic service from stored metadata
246
- service = ModelService(
247
- service_id=service_id,
248
- service_name=metadata.get('service_name', service_id),
249
- model_id=metadata.get('model_id'),
250
- deployment_platform=DeploymentPlatform(metadata.get('deployment_platform', 'modal')),
251
- service_type=ServiceType(metadata.get('service_type', 'vision')),
252
- status=ServiceStatus(metadata.get('status', 'healthy')),
253
- inference_endpoint=metadata.get('inference_endpoint'),
254
- health_endpoint=metadata.get('health_endpoint'),
255
- capabilities=model_info.get('capabilities', []),
256
- metadata=metadata,
257
- )
258
-
259
- self._service_cache[service_id] = service
260
- return service
261
-
262
- except Exception as e:
263
- logger.error(f"Failed to get service from SQLite: {e}")
264
- return None
265
-
266
- async def get_services_by_name(self, service_name: str) -> List[ModelService]:
267
- """Get all services with a specific name (multiple deployments)"""
268
- try:
269
- if hasattr(self.model_registry, 'use_supabase') and self.model_registry.use_supabase:
270
- backend = self.model_registry.backend
271
- result = backend.supabase.rpc('get_healthy_services_by_name', {'name_pattern': service_name}).execute()
272
-
273
- services = []
274
- for row in result.data or []:
275
- service = ModelService(
276
- service_id=row['service_id'],
277
- service_name=row['service_name'],
278
- model_id=row['model_id'],
279
- deployment_platform=DeploymentPlatform(row['deployment_platform']),
280
- service_type=ServiceType.VISION, # Default, should be in data
281
- inference_endpoint=row['inference_endpoint'],
282
- health_endpoint=row['health_endpoint'],
283
- status=ServiceStatus.HEALTHY, # From healthy services query
284
- )
285
- services.append(service)
286
- self._service_cache[service.service_id] = service
287
-
288
- return services
289
- else:
290
- # SQLite fallback - search in model registry
291
- models = self.model_registry.search_models(service_name)
292
- services = []
293
-
294
- for model_id, model_info in models.items():
295
- metadata = model_info.get('metadata', {})
296
- if metadata.get('is_service') and metadata.get('service_name') == service_name:
297
- service = await self._get_service_sqlite(model_id)
298
- if service:
299
- services.append(service)
300
-
301
- return services
302
-
303
- except Exception as e:
304
- logger.error(f"Failed to get services by name {service_name}: {e}")
305
- return []
306
-
307
- async def get_services_by_capability(self, capability: str) -> List[ModelService]:
308
- """Get all services that provide a specific capability"""
309
- try:
310
- if hasattr(self.model_registry, 'use_supabase') and self.model_registry.use_supabase:
311
- backend = self.model_registry.backend
312
- result = backend.supabase.rpc('get_services_by_capability', {'capability_name': capability}).execute()
313
-
314
- services = []
315
- for row in result.data or []:
316
- service = self._create_service_from_supabase_row(row)
317
- services.append(service)
318
- self._service_cache[service.service_id] = service
319
-
320
- return services
321
- else:
322
- # SQLite fallback
323
- models = self.model_registry.get_models_by_capability(ModelCapability(capability))
324
- services = []
325
-
326
- for model_id, model_info in models.items():
327
- if model_info.get('metadata', {}).get('is_service'):
328
- service = await self._get_service_sqlite(model_id)
329
- if service:
330
- services.append(service)
331
-
332
- return services
333
-
334
- except Exception as e:
335
- logger.error(f"Failed to get services by capability {capability}: {e}")
336
- return []
337
-
338
- async def get_active_service(self, service_name: str) -> Optional[ModelService]:
339
- """
340
- Get the best active service for a given service name
341
-
342
- Returns the healthiest service with the most recent health check
343
- """
344
- services = await self.get_services_by_name(service_name)
345
-
346
- if not services:
347
- return None
348
-
349
- # Filter to only healthy services
350
- healthy_services = [s for s in services if s.is_healthy()]
351
-
352
- if not healthy_services:
353
- logger.warning(f"No healthy services found for {service_name}")
354
- return None
355
-
356
- # Return the first healthy service (could add more sophisticated selection logic)
357
- return healthy_services[0]
358
-
359
- # Health Monitoring
360
-
361
- async def update_service_health(
362
- self,
363
- service_id: str,
364
- health_metrics: HealthMetrics
365
- ) -> bool:
366
- """Update health metrics for a service"""
367
- try:
368
- if hasattr(self.model_registry, 'use_supabase') and self.model_registry.use_supabase:
369
- backend = self.model_registry.backend
370
-
371
- # Insert health check record
372
- health_data = {
373
- 'service_id': service_id,
374
- 'is_healthy': health_metrics.is_healthy,
375
- 'response_time_ms': health_metrics.response_time_ms,
376
- 'status_code': health_metrics.status_code,
377
- 'cpu_usage_percent': health_metrics.cpu_usage_percent,
378
- 'memory_usage_mb': health_metrics.memory_usage_mb,
379
- 'gpu_usage_percent': health_metrics.gpu_usage_percent,
380
- 'error_message': health_metrics.error_message,
381
- 'checked_at': health_metrics.checked_at.isoformat() if health_metrics.checked_at else datetime.now(timezone.utc).isoformat(),
382
- }
383
-
384
- result = backend.supabase.table('service_health').insert(health_data).execute()
385
-
386
- # Update service status
387
- new_status = ServiceStatus.HEALTHY if health_metrics.is_healthy else ServiceStatus.UNHEALTHY
388
- backend.supabase.table('services').update({'status': new_status.value}).eq('service_id', service_id).execute()
389
-
390
- # Update cached service
391
- if service_id in self._service_cache:
392
- self._service_cache[service_id].update_health_metrics(health_metrics)
393
-
394
- return bool(result.data)
395
- else:
396
- # For SQLite, just update cached service
397
- if service_id in self._service_cache:
398
- self._service_cache[service_id].update_health_metrics(health_metrics)
399
- return True
400
-
401
- except Exception as e:
402
- logger.error(f"Failed to update health for service {service_id}: {e}")
403
- return False
404
-
405
- # Statistics and Monitoring
406
-
407
- async def get_service_statistics(self) -> Dict[str, Any]:
408
- """Get platform-wide service statistics"""
409
- try:
410
- if hasattr(self.model_registry, 'use_supabase') and self.model_registry.use_supabase:
411
- backend = self.model_registry.backend
412
- result = backend.supabase.rpc('get_service_statistics').execute()
413
-
414
- if result.data:
415
- return result.data[0]
416
-
417
- return {
418
- "total_services": 0,
419
- "healthy_services": 0,
420
- "platforms": {},
421
- "service_types": {}
422
- }
423
-
424
- except Exception as e:
425
- logger.error(f"Failed to get service statistics: {e}")
426
- return {}
427
-
428
- # Helper Methods
429
-
430
- def _create_service_from_data(self, service_data: Dict[str, Any], capabilities: List[str]) -> ModelService:
431
- """Create ModelService instance from database row data"""
432
- # Parse JSON fields
433
- config = json.loads(service_data.get('config', '{}')) if service_data.get('config') else {}
434
- metadata = json.loads(service_data.get('metadata', '{}')) if service_data.get('metadata') else {}
435
-
436
- # Create resource requirements
437
- resources = ResourceRequirements(
438
- gpu_type=service_data.get('gpu_type'),
439
- memory_mb=service_data.get('memory_mb'),
440
- cpu_cores=service_data.get('cpu_cores'),
441
- )
442
-
443
- # Create service
444
- service = ModelService(
445
- service_id=service_data['service_id'],
446
- service_name=service_data['service_name'],
447
- model_id=service_data.get('model_id'),
448
- deployment_platform=DeploymentPlatform(service_data['deployment_platform']),
449
- service_type=ServiceType(service_data['service_type']),
450
- status=ServiceStatus(service_data.get('status', 'pending')),
451
- inference_endpoint=service_data.get('inference_endpoint'),
452
- health_endpoint=service_data.get('health_endpoint'),
453
- capabilities=capabilities,
454
- config=config,
455
- resource_requirements=resources,
456
- metadata=metadata,
457
- )
458
-
459
- # Set timestamps
460
- if service_data.get('created_at'):
461
- service.created_at = datetime.fromisoformat(service_data['created_at'].replace('Z', '+00:00'))
462
- if service_data.get('updated_at'):
463
- service.updated_at = datetime.fromisoformat(service_data['updated_at'].replace('Z', '+00:00'))
464
-
465
- return service
466
-
467
- def _create_service_from_supabase_row(self, row: Dict[str, Any]) -> ModelService:
468
- """Create ModelService from Supabase RPC result row"""
469
- # Parse JSON fields safely
470
- config = {}
471
- metadata = {}
472
-
473
- if row.get('config'):
474
- try:
475
- config = json.loads(row['config']) if isinstance(row['config'], str) else row['config']
476
- except json.JSONDecodeError:
477
- config = {}
478
-
479
- if row.get('metadata'):
480
- try:
481
- metadata = json.loads(row['metadata']) if isinstance(row['metadata'], str) else row['metadata']
482
- except json.JSONDecodeError:
483
- metadata = {}
484
-
485
- return ModelService(
486
- service_id=row['service_id'],
487
- service_name=row['service_name'],
488
- model_id=row.get('model_id'),
489
- deployment_platform=DeploymentPlatform(row['deployment_platform']),
490
- service_type=ServiceType(row['service_type']),
491
- status=ServiceStatus(row.get('status', 'pending')),
492
- inference_endpoint=row.get('inference_endpoint'),
493
- health_endpoint=row.get('health_endpoint'),
494
- config=config,
495
- metadata=metadata,
496
- )
497
-
498
- async def _ensure_model_registered(self, service: ModelService) -> None:
499
- """Ensure the underlying model is registered in the model registry"""
500
- if not service.model_id:
501
- return
502
-
503
- # Check if model exists
504
- model_info = self.model_registry.get_model_info(service.model_id)
505
-
506
- if not model_info:
507
- # Register the model
508
- model_type = ModelType.VISION # Default, could be inferred from service type
509
- capabilities = [ModelCapability(cap) for cap in service.capabilities if hasattr(ModelCapability, cap.upper())]
510
-
511
- self.model_registry.register_model(
512
- model_id=service.model_id,
513
- model_type=model_type,
514
- capabilities=capabilities,
515
- metadata={
516
- "description": f"Model used by service {service.service_name}",
517
- "registered_by_service": service.service_id,
518
- }
519
- )
520
-
521
- logger.info(f"Auto-registered model {service.model_id} for service {service.service_id}")
522
-
523
- def clear_cache(self) -> None:
524
- """Clear the service cache"""
525
- self._service_cache.clear()
526
- self._last_cache_update = None
527
- logger.info("Service cache cleared")
@@ -1,92 +0,0 @@
1
- """
2
- ISA Model Evaluation Framework
3
-
4
- Enterprise-grade evaluation framework implementing MLOps best practices:
5
-
6
- Key Features:
7
- - Multi-modal evaluation (LLM, Vision, Multimodal)
8
- - Async evaluation with smart concurrency management
9
- - Comprehensive experiment tracking (W&B, MLflow)
10
- - Production-ready error handling and monitoring
11
- - Distributed evaluation support
12
- - Cost tracking and optimization
13
- - Reproducible evaluation pipelines
14
-
15
- Quick Start:
16
- ```python
17
- import asyncio
18
- from isa_model.eval import EvaluationFactory
19
-
20
- async def main():
21
- # Initialize factory with experiment tracking
22
- factory = EvaluationFactory(
23
- experiment_tracking={
24
- "type": "wandb",
25
- "project": "model-evaluation"
26
- }
27
- )
28
-
29
- # Evaluate LLM
30
- result = await factory.evaluate_llm(
31
- model_name="gpt-4.1-mini",
32
- provider="openai",
33
- dataset_path="eval_data.json",
34
- save_results=True
35
- )
36
-
37
- print(f"Accuracy: {result.metrics['exact_match']:.3f}")
38
-
39
- # Cleanup
40
- await factory.cleanup()
41
-
42
- asyncio.run(main())
43
- ```
44
-
45
- Architecture:
46
- - evaluators/: Specialized evaluators by modality
47
- - infrastructure/: Experiment tracking, async runners, storage
48
- - config/: Configuration management
49
- - metrics/: Metric computation by type
50
- - benchmarks/: Standard benchmark implementations
51
- - utils/: Data processing and visualization utilities
52
- """
53
-
54
- # Main interfaces
55
- from .factory import EvaluationFactory, evaluate_llm_quick, run_benchmark_quick
56
-
57
- # Core components
58
- from .evaluators import BaseEvaluator, EvaluationResult, LLMEvaluator
59
- from .config import EvaluationConfig, ConfigManager
60
-
61
- # Infrastructure (optional imports)
62
- try:
63
- from .infrastructure import ExperimentTracker, WandBTracker, MLflowTracker
64
- INFRASTRUCTURE_AVAILABLE = True
65
- except ImportError:
66
- INFRASTRUCTURE_AVAILABLE = False
67
-
68
- __all__ = [
69
- # Main interfaces
70
- "EvaluationFactory",
71
- "evaluate_llm_quick",
72
- "run_benchmark_quick",
73
-
74
- # Core components
75
- "BaseEvaluator",
76
- "EvaluationResult",
77
- "LLMEvaluator",
78
- "EvaluationConfig",
79
- "ConfigManager"
80
- ]
81
-
82
- # Add infrastructure components if available
83
- if INFRASTRUCTURE_AVAILABLE:
84
- __all__.extend([
85
- "ExperimentTracker",
86
- "WandBTracker",
87
- "MLflowTracker"
88
- ])
89
-
90
- # Version info
91
- __version__ = "1.0.0"
92
- __author__ = "ISA Model Team"
@@ -1,27 +0,0 @@
1
- """
2
- Benchmarks module for ISA Model evaluation framework.
3
-
4
- Contains benchmark implementations and dataset loaders.
5
- """
6
-
7
- from .multimodal_datasets import (
8
- VQAv2Dataset,
9
- COCOCaptionsDataset,
10
- DocVQADataset,
11
- AudioDatasetLoader,
12
- create_vqa_dataset,
13
- create_coco_captions_dataset,
14
- create_docvqa_dataset,
15
- create_audio_dataset_loader
16
- )
17
-
18
- __all__ = [
19
- "VQAv2Dataset",
20
- "COCOCaptionsDataset",
21
- "DocVQADataset",
22
- "AudioDatasetLoader",
23
- "create_vqa_dataset",
24
- "create_coco_captions_dataset",
25
- "create_docvqa_dataset",
26
- "create_audio_dataset_loader"
27
- ]