isa-model 0.0.3__py3-none-any.whl → 0.0.8__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 (78) hide show
  1. isa_model/__init__.py +1 -1
  2. isa_model/core/model_registry.py +273 -46
  3. isa_model/core/storage/hf_storage.py +419 -0
  4. isa_model/deployment/__init__.py +52 -0
  5. isa_model/deployment/core/__init__.py +34 -0
  6. isa_model/deployment/core/deployment_config.py +356 -0
  7. isa_model/deployment/core/deployment_manager.py +549 -0
  8. isa_model/deployment/core/isa_deployment_service.py +401 -0
  9. isa_model/eval/factory.py +381 -140
  10. isa_model/inference/ai_factory.py +142 -240
  11. isa_model/inference/providers/ml_provider.py +50 -0
  12. isa_model/inference/services/audio/openai_tts_service.py +104 -3
  13. isa_model/inference/services/embedding/base_embed_service.py +112 -0
  14. isa_model/inference/services/embedding/ollama_embed_service.py +28 -2
  15. isa_model/inference/services/llm/__init__.py +2 -0
  16. isa_model/inference/services/llm/base_llm_service.py +111 -1
  17. isa_model/inference/services/llm/ollama_llm_service.py +234 -26
  18. isa_model/inference/services/llm/openai_llm_service.py +180 -26
  19. isa_model/inference/services/llm/triton_llm_service.py +481 -0
  20. isa_model/inference/services/ml/base_ml_service.py +78 -0
  21. isa_model/inference/services/ml/sklearn_ml_service.py +140 -0
  22. isa_model/inference/services/vision/__init__.py +3 -3
  23. isa_model/inference/services/vision/base_image_gen_service.py +161 -0
  24. isa_model/inference/services/vision/base_vision_service.py +177 -0
  25. isa_model/inference/services/vision/ollama_vision_service.py +143 -17
  26. isa_model/inference/services/vision/replicate_image_gen_service.py +139 -7
  27. isa_model/training/__init__.py +62 -32
  28. isa_model/training/cloud/__init__.py +22 -0
  29. isa_model/training/cloud/job_orchestrator.py +402 -0
  30. isa_model/training/cloud/runpod_trainer.py +454 -0
  31. isa_model/training/cloud/storage_manager.py +482 -0
  32. isa_model/training/core/__init__.py +23 -0
  33. isa_model/training/core/config.py +181 -0
  34. isa_model/training/core/dataset.py +222 -0
  35. isa_model/training/core/trainer.py +720 -0
  36. isa_model/training/core/utils.py +213 -0
  37. isa_model/training/factory.py +229 -198
  38. isa_model-0.0.8.dist-info/METADATA +465 -0
  39. isa_model-0.0.8.dist-info/RECORD +86 -0
  40. isa_model/core/model_router.py +0 -226
  41. isa_model/core/model_version.py +0 -0
  42. isa_model/core/resource_manager.py +0 -202
  43. isa_model/deployment/gpu_fp16_ds8/models/deepseek_r1/1/model.py +0 -120
  44. isa_model/deployment/gpu_fp16_ds8/scripts/download_model.py +0 -18
  45. isa_model/training/engine/llama_factory/__init__.py +0 -39
  46. isa_model/training/engine/llama_factory/config.py +0 -115
  47. isa_model/training/engine/llama_factory/data_adapter.py +0 -284
  48. isa_model/training/engine/llama_factory/examples/__init__.py +0 -6
  49. isa_model/training/engine/llama_factory/examples/finetune_with_tracking.py +0 -185
  50. isa_model/training/engine/llama_factory/examples/rlhf_with_tracking.py +0 -163
  51. isa_model/training/engine/llama_factory/factory.py +0 -331
  52. isa_model/training/engine/llama_factory/rl.py +0 -254
  53. isa_model/training/engine/llama_factory/trainer.py +0 -171
  54. isa_model/training/image_model/configs/create_config.py +0 -37
  55. isa_model/training/image_model/configs/create_flux_config.py +0 -26
  56. isa_model/training/image_model/configs/create_lora_config.py +0 -21
  57. isa_model/training/image_model/prepare_massed_compute.py +0 -97
  58. isa_model/training/image_model/prepare_upload.py +0 -17
  59. isa_model/training/image_model/raw_data/create_captions.py +0 -16
  60. isa_model/training/image_model/raw_data/create_lora_captions.py +0 -20
  61. isa_model/training/image_model/raw_data/pre_processing.py +0 -200
  62. isa_model/training/image_model/train/train.py +0 -42
  63. isa_model/training/image_model/train/train_flux.py +0 -41
  64. isa_model/training/image_model/train/train_lora.py +0 -57
  65. isa_model/training/image_model/train_main.py +0 -25
  66. isa_model-0.0.3.dist-info/METADATA +0 -327
  67. isa_model-0.0.3.dist-info/RECORD +0 -92
  68. isa_model-0.0.3.dist-info/licenses/LICENSE +0 -21
  69. /isa_model/training/{llm_model/annotation → annotation}/annotation_schema.py +0 -0
  70. /isa_model/training/{llm_model/annotation → annotation}/processors/annotation_processor.py +0 -0
  71. /isa_model/training/{llm_model/annotation → annotation}/storage/dataset_manager.py +0 -0
  72. /isa_model/training/{llm_model/annotation → annotation}/storage/dataset_schema.py +0 -0
  73. /isa_model/training/{llm_model/annotation → annotation}/tests/test_annotation_flow.py +0 -0
  74. /isa_model/training/{llm_model/annotation → annotation}/tests/test_minio copy.py +0 -0
  75. /isa_model/training/{llm_model/annotation → annotation}/tests/test_minio_upload.py +0 -0
  76. /isa_model/training/{llm_model/annotation → annotation}/views/annotation_controller.py +0 -0
  77. {isa_model-0.0.3.dist-info → isa_model-0.0.8.dist-info}/WHEEL +0 -0
  78. {isa_model-0.0.3.dist-info → isa_model-0.0.8.dist-info}/top_level.txt +0 -0
@@ -1,12 +1,13 @@
1
1
  import logging
2
2
  import os
3
- from typing import Dict, Any, List, Union, AsyncGenerator, Optional
3
+ import json
4
+ from typing import Dict, Any, List, Union, AsyncGenerator, Optional, Callable
4
5
 
5
6
  # 使用官方 OpenAI 库和 dotenv
6
7
  from openai import AsyncOpenAI
7
8
  from dotenv import load_dotenv
8
9
 
9
- from isa_model.inference.services.base_service import BaseLLMService
10
+ from isa_model.inference.services.llm.base_llm_service import BaseLLMService
10
11
  from isa_model.inference.providers.base_provider import BaseProvider
11
12
 
12
13
  # 加载 .env.local 文件中的环境变量
@@ -34,8 +35,36 @@ class OpenAILLMService(BaseLLMService):
34
35
  raise ValueError("OPENAI_API_KEY 未设置。") from e
35
36
 
36
37
  self.last_token_usage = {"prompt_tokens": 0, "completion_tokens": 0, "total_tokens": 0}
38
+ self.total_token_usage = {"prompt_tokens": 0, "completion_tokens": 0, "total_tokens": 0, "requests_count": 0}
39
+
40
+ # Tool binding attributes
41
+ self._bound_tools: List[Dict[str, Any]] = []
42
+ self._tool_binding_kwargs: Dict[str, Any] = {}
43
+ self._tool_functions: Dict[str, Callable] = {}
44
+
37
45
  logger.info(f"Initialized OpenAILLMService with model {self.model_name} and endpoint {self.client.base_url}")
38
46
 
47
+ def _create_bound_copy(self) -> 'OpenAILLMService':
48
+ """Create a copy of this service for tool binding"""
49
+ bound_service = OpenAILLMService(self.provider, self.model_name)
50
+ bound_service._bound_tools = self._bound_tools.copy()
51
+ bound_service._tool_binding_kwargs = self._tool_binding_kwargs.copy()
52
+ bound_service._tool_functions = self._tool_functions.copy()
53
+ return bound_service
54
+
55
+ def bind_tools(self, tools: List[Union[Dict[str, Any], Callable]], **kwargs) -> 'OpenAILLMService':
56
+ """Bind tools to this LLM service for function calling"""
57
+ bound_service = self._create_bound_copy()
58
+ bound_service._bound_tools = self._convert_tools_to_schema(tools)
59
+ bound_service._tool_binding_kwargs = kwargs
60
+
61
+ # Store the actual functions for execution
62
+ for tool in tools:
63
+ if callable(tool):
64
+ bound_service._tool_functions[tool.__name__] = tool
65
+
66
+ return bound_service
67
+
39
68
  async def ainvoke(self, prompt: Union[str, List[Dict[str, str]], Any]) -> str:
40
69
  """Universal invocation method"""
41
70
  if isinstance(prompt, str):
@@ -51,12 +80,19 @@ class OpenAILLMService(BaseLLMService):
51
80
  temperature = self.config.get("temperature", 0.7)
52
81
  max_tokens = self.config.get("max_tokens", 1024)
53
82
 
54
- response = await self.client.chat.completions.create(
55
- model=self.model_name,
56
- messages=messages,
57
- temperature=temperature,
58
- max_tokens=max_tokens
59
- )
83
+ kwargs = {
84
+ "model": self.model_name,
85
+ "messages": messages,
86
+ "temperature": temperature,
87
+ "max_tokens": max_tokens
88
+ }
89
+
90
+ # Add tools if bound
91
+ if self._has_bound_tools():
92
+ kwargs["tools"] = self._get_bound_tools()
93
+ kwargs["tool_choice"] = "auto"
94
+
95
+ response = await self.client.chat.completions.create(**kwargs)
60
96
 
61
97
  if response.usage:
62
98
  self.last_token_usage = {
@@ -64,13 +100,87 @@ class OpenAILLMService(BaseLLMService):
64
100
  "completion_tokens": response.usage.completion_tokens,
65
101
  "total_tokens": response.usage.total_tokens
66
102
  }
103
+
104
+ # Update total usage
105
+ self.total_token_usage["prompt_tokens"] += self.last_token_usage["prompt_tokens"]
106
+ self.total_token_usage["completion_tokens"] += self.last_token_usage["completion_tokens"]
107
+ self.total_token_usage["total_tokens"] += self.last_token_usage["total_tokens"]
108
+ self.total_token_usage["requests_count"] += 1
67
109
 
68
- return response.choices[0].message.content or ""
110
+ # Handle tool calls if present
111
+ message = response.choices[0].message
112
+ if message.tool_calls:
113
+ return await self._handle_tool_calls(message, messages)
114
+
115
+ return message.content or ""
69
116
 
70
117
  except Exception as e:
71
118
  logger.error(f"Error in chat completion: {e}")
72
119
  raise
73
120
 
121
+ async def _handle_tool_calls(self, assistant_message, original_messages: List[Dict[str, str]]) -> str:
122
+ """Handle tool calls from the assistant"""
123
+ # Add assistant message with tool calls to conversation
124
+ messages = original_messages + [{
125
+ "role": "assistant",
126
+ "content": assistant_message.content or "",
127
+ "tool_calls": [
128
+ {
129
+ "id": tc.id,
130
+ "type": tc.type,
131
+ "function": {
132
+ "name": tc.function.name,
133
+ "arguments": tc.function.arguments
134
+ }
135
+ } for tc in assistant_message.tool_calls
136
+ ]
137
+ }]
138
+
139
+ # Execute each tool call
140
+ for tool_call in assistant_message.tool_calls:
141
+ function_name = tool_call.function.name
142
+ arguments = json.loads(tool_call.function.arguments)
143
+
144
+ try:
145
+ # Execute the tool
146
+ if function_name in self._tool_functions:
147
+ result = self._tool_functions[function_name](**arguments)
148
+ if hasattr(result, '__await__'): # Handle async functions
149
+ result = await result
150
+ else:
151
+ result = f"Error: Function {function_name} not found"
152
+
153
+ # Add tool result to messages
154
+ messages.append({
155
+ "role": "tool",
156
+ "content": str(result),
157
+ "tool_call_id": tool_call.id
158
+ })
159
+
160
+ except Exception as e:
161
+ logger.error(f"Error executing tool {function_name}: {e}")
162
+ messages.append({
163
+ "role": "tool",
164
+ "content": f"Error executing {function_name}: {str(e)}",
165
+ "tool_call_id": tool_call.id
166
+ })
167
+
168
+ # Get final response from the model with all context
169
+ try:
170
+ kwargs = {
171
+ "model": self.model_name,
172
+ "messages": messages,
173
+ "temperature": self.config.get("temperature", 0.7),
174
+ "max_tokens": self.config.get("max_tokens", 1024)
175
+ }
176
+
177
+ response = await self.client.chat.completions.create(**kwargs)
178
+ return response.choices[0].message.content or ""
179
+
180
+ except Exception as e:
181
+ logger.error(f"Error getting final response after tool calls: {e}")
182
+ raise
183
+
74
184
  async def acompletion(self, prompt: str) -> str:
75
185
  """Text completion method (using chat API)"""
76
186
  messages = [{"role": "user", "content": prompt}]
@@ -82,13 +192,20 @@ class OpenAILLMService(BaseLLMService):
82
192
  temperature = self.config.get("temperature", 0.7)
83
193
  max_tokens = self.config.get("max_tokens", 1024)
84
194
 
85
- response = await self.client.chat.completions.create(
86
- model=self.model_name,
87
- messages=messages,
88
- temperature=temperature,
89
- max_tokens=max_tokens,
90
- n=n
91
- )
195
+ kwargs = {
196
+ "model": self.model_name,
197
+ "messages": messages,
198
+ "temperature": temperature,
199
+ "max_tokens": max_tokens,
200
+ "n": n
201
+ }
202
+
203
+ # Add tools if bound
204
+ if self._has_bound_tools():
205
+ kwargs["tools"] = self._get_bound_tools()
206
+ kwargs["tool_choice"] = "auto"
207
+
208
+ response = await self.client.chat.completions.create(**kwargs)
92
209
 
93
210
  if response.usage:
94
211
  self.last_token_usage = {
@@ -96,6 +213,12 @@ class OpenAILLMService(BaseLLMService):
96
213
  "completion_tokens": response.usage.completion_tokens,
97
214
  "total_tokens": response.usage.total_tokens
98
215
  }
216
+
217
+ # Update total usage
218
+ self.total_token_usage["prompt_tokens"] += self.last_token_usage["prompt_tokens"]
219
+ self.total_token_usage["completion_tokens"] += self.last_token_usage["completion_tokens"]
220
+ self.total_token_usage["total_tokens"] += self.last_token_usage["total_tokens"]
221
+ self.total_token_usage["requests_count"] += 1
99
222
 
100
223
  return [choice.message.content or "" for choice in response.choices]
101
224
  except Exception as e:
@@ -108,13 +231,20 @@ class OpenAILLMService(BaseLLMService):
108
231
  temperature = self.config.get("temperature", 0.7)
109
232
  max_tokens = self.config.get("max_tokens", 1024)
110
233
 
111
- stream = await self.client.chat.completions.create(
112
- model=self.model_name,
113
- messages=messages,
114
- temperature=temperature,
115
- max_tokens=max_tokens,
116
- stream=True
117
- )
234
+ kwargs = {
235
+ "model": self.model_name,
236
+ "messages": messages,
237
+ "temperature": temperature,
238
+ "max_tokens": max_tokens,
239
+ "stream": True
240
+ }
241
+
242
+ # Add tools if bound
243
+ if self._has_bound_tools():
244
+ kwargs["tools"] = self._get_bound_tools()
245
+ kwargs["tool_choice"] = "auto"
246
+
247
+ stream = await self.client.chat.completions.create(**kwargs)
118
248
 
119
249
  async for chunk in stream:
120
250
  content = chunk.choices[0].delta.content
@@ -125,14 +255,38 @@ class OpenAILLMService(BaseLLMService):
125
255
  logger.error(f"Error in stream chat: {e}")
126
256
  raise
127
257
 
128
- def get_token_usage(self) -> Dict[str, int]:
258
+ async def astream_completion(self, prompt: str) -> AsyncGenerator[str, None]:
259
+ """Stream completion responses"""
260
+ messages = [{"role": "user", "content": prompt}]
261
+ async for chunk in self.astream_chat(messages):
262
+ yield chunk
263
+
264
+ def get_token_usage(self) -> Dict[str, Any]:
129
265
  """Get total token usage statistics"""
130
- return self.last_token_usage
266
+ return self.total_token_usage
131
267
 
132
268
  def get_last_token_usage(self) -> Dict[str, int]:
133
269
  """Get token usage from last request"""
134
270
  return self.last_token_usage
271
+
272
+ def get_model_info(self) -> Dict[str, Any]:
273
+ """Get information about the current model"""
274
+ return {
275
+ "name": self.model_name,
276
+ "max_tokens": self.config.get("max_tokens", 1024),
277
+ "supports_streaming": True,
278
+ "supports_functions": True,
279
+ "provider": "openai"
280
+ }
281
+
282
+ def _has_bound_tools(self) -> bool:
283
+ """Check if this service has bound tools"""
284
+ return bool(self._bound_tools)
285
+
286
+ def _get_bound_tools(self) -> List[Dict[str, Any]]:
287
+ """Get the bound tools schema"""
288
+ return self._bound_tools
135
289
 
136
290
  async def close(self):
137
291
  """Close the backend client"""
138
- await self.client.aclose()
292
+ await self.client.close()