isa-model 0.0.2__py3-none-any.whl → 0.3.1__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.
- isa_model/__init__.py +1 -1
- isa_model/core/model_manager.py +69 -4
- isa_model/core/model_registry.py +273 -46
- isa_model/core/storage/hf_storage.py +419 -0
- isa_model/deployment/__init__.py +52 -0
- isa_model/deployment/core/__init__.py +34 -0
- isa_model/deployment/core/deployment_config.py +356 -0
- isa_model/deployment/core/deployment_manager.py +549 -0
- isa_model/deployment/core/isa_deployment_service.py +401 -0
- isa_model/eval/factory.py +381 -140
- isa_model/inference/ai_factory.py +427 -236
- isa_model/inference/billing_tracker.py +406 -0
- isa_model/inference/providers/base_provider.py +51 -4
- isa_model/inference/providers/ml_provider.py +50 -0
- isa_model/inference/providers/ollama_provider.py +37 -18
- isa_model/inference/providers/openai_provider.py +65 -36
- isa_model/inference/providers/replicate_provider.py +42 -30
- isa_model/inference/services/audio/base_stt_service.py +21 -2
- isa_model/inference/services/audio/openai_realtime_service.py +353 -0
- isa_model/inference/services/audio/openai_stt_service.py +252 -0
- isa_model/inference/services/audio/openai_tts_service.py +149 -9
- isa_model/inference/services/audio/replicate_tts_service.py +239 -0
- isa_model/inference/services/base_service.py +36 -1
- isa_model/inference/services/embedding/base_embed_service.py +112 -0
- isa_model/inference/services/embedding/ollama_embed_service.py +28 -2
- isa_model/inference/services/embedding/openai_embed_service.py +223 -0
- isa_model/inference/services/llm/__init__.py +2 -0
- isa_model/inference/services/llm/base_llm_service.py +158 -86
- isa_model/inference/services/llm/llm_adapter.py +414 -0
- isa_model/inference/services/llm/ollama_llm_service.py +252 -63
- isa_model/inference/services/llm/openai_llm_service.py +231 -93
- isa_model/inference/services/llm/triton_llm_service.py +481 -0
- isa_model/inference/services/ml/base_ml_service.py +78 -0
- isa_model/inference/services/ml/sklearn_ml_service.py +140 -0
- isa_model/inference/services/vision/__init__.py +3 -3
- isa_model/inference/services/vision/base_image_gen_service.py +161 -0
- isa_model/inference/services/vision/base_vision_service.py +177 -0
- isa_model/inference/services/vision/helpers/image_utils.py +4 -3
- isa_model/inference/services/vision/ollama_vision_service.py +151 -17
- isa_model/inference/services/vision/openai_vision_service.py +275 -41
- isa_model/inference/services/vision/replicate_image_gen_service.py +278 -118
- isa_model/training/__init__.py +62 -32
- isa_model/training/cloud/__init__.py +22 -0
- isa_model/training/cloud/job_orchestrator.py +402 -0
- isa_model/training/cloud/runpod_trainer.py +454 -0
- isa_model/training/cloud/storage_manager.py +482 -0
- isa_model/training/core/__init__.py +23 -0
- isa_model/training/core/config.py +181 -0
- isa_model/training/core/dataset.py +222 -0
- isa_model/training/core/trainer.py +720 -0
- isa_model/training/core/utils.py +213 -0
- isa_model/training/factory.py +229 -198
- isa_model-0.3.1.dist-info/METADATA +465 -0
- isa_model-0.3.1.dist-info/RECORD +91 -0
- isa_model/core/model_router.py +0 -226
- isa_model/core/model_version.py +0 -0
- isa_model/core/resource_manager.py +0 -202
- isa_model/deployment/gpu_fp16_ds8/models/deepseek_r1/1/model.py +0 -120
- isa_model/deployment/gpu_fp16_ds8/scripts/download_model.py +0 -18
- isa_model/training/engine/llama_factory/__init__.py +0 -39
- isa_model/training/engine/llama_factory/config.py +0 -115
- isa_model/training/engine/llama_factory/data_adapter.py +0 -284
- isa_model/training/engine/llama_factory/examples/__init__.py +0 -6
- isa_model/training/engine/llama_factory/examples/finetune_with_tracking.py +0 -185
- isa_model/training/engine/llama_factory/examples/rlhf_with_tracking.py +0 -163
- isa_model/training/engine/llama_factory/factory.py +0 -331
- isa_model/training/engine/llama_factory/rl.py +0 -254
- isa_model/training/engine/llama_factory/trainer.py +0 -171
- isa_model/training/image_model/configs/create_config.py +0 -37
- isa_model/training/image_model/configs/create_flux_config.py +0 -26
- isa_model/training/image_model/configs/create_lora_config.py +0 -21
- isa_model/training/image_model/prepare_massed_compute.py +0 -97
- isa_model/training/image_model/prepare_upload.py +0 -17
- isa_model/training/image_model/raw_data/create_captions.py +0 -16
- isa_model/training/image_model/raw_data/create_lora_captions.py +0 -20
- isa_model/training/image_model/raw_data/pre_processing.py +0 -200
- isa_model/training/image_model/train/train.py +0 -42
- isa_model/training/image_model/train/train_flux.py +0 -41
- isa_model/training/image_model/train/train_lora.py +0 -57
- isa_model/training/image_model/train_main.py +0 -25
- isa_model-0.0.2.dist-info/METADATA +0 -327
- isa_model-0.0.2.dist-info/RECORD +0 -92
- isa_model-0.0.2.dist-info/licenses/LICENSE +0 -21
- /isa_model/training/{llm_model/annotation → annotation}/annotation_schema.py +0 -0
- /isa_model/training/{llm_model/annotation → annotation}/processors/annotation_processor.py +0 -0
- /isa_model/training/{llm_model/annotation → annotation}/storage/dataset_manager.py +0 -0
- /isa_model/training/{llm_model/annotation → annotation}/storage/dataset_schema.py +0 -0
- /isa_model/training/{llm_model/annotation → annotation}/tests/test_annotation_flow.py +0 -0
- /isa_model/training/{llm_model/annotation → annotation}/tests/test_minio copy.py +0 -0
- /isa_model/training/{llm_model/annotation → annotation}/tests/test_minio_upload.py +0 -0
- /isa_model/training/{llm_model/annotation → annotation}/views/annotation_controller.py +0 -0
- {isa_model-0.0.2.dist-info → isa_model-0.3.1.dist-info}/WHEEL +0 -0
- {isa_model-0.0.2.dist-info → isa_model-0.3.1.dist-info}/top_level.txt +0 -0
@@ -1,134 +1,206 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
|
-
from typing import Dict, Any, List, Union, Optional, AsyncGenerator,
|
2
|
+
from typing import Dict, Any, List, Union, Optional, AsyncGenerator, Callable
|
3
3
|
from isa_model.inference.services.base_service import BaseService
|
4
|
-
|
5
|
-
T = TypeVar('T') # Generic type for responses
|
4
|
+
from isa_model.inference.services.llm.llm_adapter import AdapterManager
|
6
5
|
|
7
6
|
class BaseLLMService(BaseService):
|
8
|
-
"""Base class for Large Language Model services"""
|
7
|
+
"""Base class for Large Language Model services with unified invoke interface"""
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
def __init__(self, provider, model_name: str):
|
10
|
+
super().__init__(provider, model_name)
|
11
|
+
self._bound_tools: List[Any] = [] # 改为存储原始工具对象
|
12
|
+
self._tool_mappings: Dict[str, tuple] = {} # 工具名到(工具, 适配器)的映射
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
"""
|
21
|
-
pass
|
14
|
+
# 初始化适配器管理器
|
15
|
+
self.adapter_manager = AdapterManager()
|
16
|
+
|
17
|
+
# Get streaming config from provider config
|
18
|
+
self.streaming = self.config.get("streaming", False)
|
22
19
|
|
23
|
-
|
24
|
-
async def achat(self, messages: List[Dict[str, str]]) -> T:
|
20
|
+
def bind_tools(self, tools: List[Any], **kwargs) -> 'BaseLLMService':
|
25
21
|
"""
|
26
|
-
|
22
|
+
Bind tools to this LLM service for function calling
|
27
23
|
|
28
24
|
Args:
|
29
|
-
|
30
|
-
|
25
|
+
tools: List of tools to bind (functions, LangChain tools, etc.)
|
26
|
+
**kwargs: Additional tool binding parameters
|
31
27
|
|
32
28
|
Returns:
|
33
|
-
|
29
|
+
Self for method chaining
|
34
30
|
"""
|
35
|
-
|
31
|
+
self._bound_tools = tools
|
32
|
+
return self
|
36
33
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
async def _prepare_tools_for_request(self) -> List[Dict[str, Any]]:
|
35
|
+
"""准备工具用于请求"""
|
36
|
+
if not self._bound_tools:
|
37
|
+
return []
|
41
38
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
39
|
+
schemas, self._tool_mappings = await self.adapter_manager.convert_tools_to_schemas(self._bound_tools)
|
40
|
+
return schemas
|
41
|
+
|
42
|
+
def _prepare_messages(self, input_data: Union[str, List[Dict[str, str]], Any]) -> List[Dict[str, str]]:
|
43
|
+
"""使用适配器管理器转换消息格式"""
|
44
|
+
return self.adapter_manager.convert_messages(input_data)
|
45
|
+
|
46
|
+
def _format_response(self, response: str, original_input: Any) -> Union[str, Any]:
|
47
|
+
"""使用适配器管理器格式化响应"""
|
48
|
+
return self.adapter_manager.format_response(response, original_input)
|
49
|
+
|
50
|
+
async def _execute_tool_call(self, tool_name: str, arguments: Dict[str, Any]) -> Any:
|
51
|
+
"""使用适配器管理器执行工具调用"""
|
52
|
+
return await self.adapter_manager.execute_tool(tool_name, arguments, self._tool_mappings)
|
49
53
|
|
50
54
|
@abstractmethod
|
51
|
-
async def
|
55
|
+
async def ainvoke(self, input_data: Union[str, List[Dict[str, str]], Any]) -> Union[str, Any]:
|
52
56
|
"""
|
53
|
-
|
57
|
+
Universal async invocation method that handles different input types
|
54
58
|
|
55
59
|
Args:
|
56
|
-
|
57
|
-
|
60
|
+
input_data: Can be:
|
61
|
+
- str: Simple text prompt
|
62
|
+
- list: Message history like [{"role": "user", "content": "hello"}]
|
63
|
+
- Any: LangChain message objects or other formats
|
58
64
|
|
59
65
|
Returns:
|
60
|
-
|
66
|
+
Model response (string for simple cases, object for complex cases)
|
61
67
|
"""
|
62
68
|
pass
|
63
69
|
|
64
|
-
|
65
|
-
async def astream_chat(self, messages: List[Dict[str, str]]) -> AsyncGenerator[str, None]:
|
70
|
+
def invoke(self, input_data: Union[str, List[Dict[str, str]], Any]) -> Union[str, Any]:
|
66
71
|
"""
|
67
|
-
|
72
|
+
Synchronous wrapper for ainvoke
|
68
73
|
|
69
74
|
Args:
|
70
|
-
|
75
|
+
input_data: Same as ainvoke
|
71
76
|
|
72
|
-
|
73
|
-
|
74
|
-
"""
|
75
|
-
|
77
|
+
Returns:
|
78
|
+
Model response
|
79
|
+
"""
|
80
|
+
import asyncio
|
81
|
+
try:
|
82
|
+
# Try to get current event loop
|
83
|
+
loop = asyncio.get_running_loop()
|
84
|
+
# If we're in an event loop, create a new thread
|
85
|
+
import concurrent.futures
|
86
|
+
with concurrent.futures.ThreadPoolExecutor() as executor:
|
87
|
+
future = executor.submit(asyncio.run, self.ainvoke(input_data))
|
88
|
+
return future.result()
|
89
|
+
except RuntimeError:
|
90
|
+
# No event loop running, create a new one
|
91
|
+
return asyncio.run(self.ainvoke(input_data))
|
76
92
|
|
77
|
-
|
78
|
-
|
79
|
-
"""
|
80
|
-
|
93
|
+
# 保留旧的方法以保持向后兼容
|
94
|
+
def _convert_tools_to_schema(self, tools: List[Union[Dict[str, Any], Callable]]) -> List[Dict[str, Any]]:
|
95
|
+
"""Convert tools to OpenAI function calling schema (deprecated, use adapter manager)"""
|
96
|
+
import asyncio
|
97
|
+
try:
|
98
|
+
loop = asyncio.get_event_loop()
|
99
|
+
schemas, _ = loop.run_until_complete(self.adapter_manager.convert_tools_to_schemas(tools))
|
100
|
+
return schemas
|
101
|
+
except RuntimeError:
|
102
|
+
schemas, _ = asyncio.run(self.adapter_manager.convert_tools_to_schemas(tools))
|
103
|
+
return schemas
|
104
|
+
|
105
|
+
def _has_bound_tools(self) -> bool:
|
106
|
+
"""Check if this service has bound tools"""
|
107
|
+
return bool(self._bound_tools)
|
108
|
+
|
109
|
+
def _get_bound_tools(self) -> List[Dict[str, Any]]:
|
110
|
+
"""Get the bound tools schema"""
|
111
|
+
return self._bound_tools
|
112
|
+
|
113
|
+
def _convert_langchain_to_openai(self, messages: List[Any]) -> List[Dict[str, str]]:
|
114
|
+
"""Convert LangChain message objects to OpenAI format"""
|
115
|
+
converted_messages = []
|
81
116
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
117
|
+
for msg in messages:
|
118
|
+
# Handle different LangChain message types
|
119
|
+
if hasattr(msg, 'type') and hasattr(msg, 'content'):
|
120
|
+
# LangChain message object
|
121
|
+
msg_dict = {"content": str(msg.content)}
|
122
|
+
|
123
|
+
# Map LangChain types to OpenAI roles
|
124
|
+
if msg.type == "system":
|
125
|
+
msg_dict["role"] = "system"
|
126
|
+
elif msg.type == "human":
|
127
|
+
msg_dict["role"] = "user"
|
128
|
+
elif msg.type == "ai":
|
129
|
+
msg_dict["role"] = "assistant"
|
130
|
+
# Handle tool calls if present
|
131
|
+
if hasattr(msg, 'tool_calls') and msg.tool_calls:
|
132
|
+
# Handle tool calls - need to store as separate key since it's not a string
|
133
|
+
tool_calls = [
|
134
|
+
{
|
135
|
+
"id": tc.get("id", f"call_{i}"),
|
136
|
+
"type": "function",
|
137
|
+
"function": {
|
138
|
+
"name": tc["name"],
|
139
|
+
"arguments": tc.get("args", {}) if isinstance(tc.get("args"), dict) else tc.get("args", "{}")
|
140
|
+
}
|
141
|
+
} for i, tc in enumerate(msg.tool_calls)
|
142
|
+
]
|
143
|
+
# Store tool_calls separately to avoid type issues
|
144
|
+
msg_dict["tool_calls"] = tool_calls # type: ignore
|
145
|
+
elif msg.type == "tool":
|
146
|
+
msg_dict["role"] = "tool"
|
147
|
+
if hasattr(msg, 'tool_call_id'):
|
148
|
+
msg_dict["tool_call_id"] = msg.tool_call_id
|
149
|
+
elif msg.type == "function": # Legacy function message
|
150
|
+
msg_dict["role"] = "function"
|
151
|
+
if hasattr(msg, 'name'):
|
152
|
+
msg_dict["name"] = msg.name
|
153
|
+
else:
|
154
|
+
msg_dict["role"] = "user" # Default fallback
|
155
|
+
|
156
|
+
converted_messages.append(msg_dict)
|
157
|
+
|
158
|
+
elif isinstance(msg, dict):
|
159
|
+
# Already in OpenAI format
|
160
|
+
converted_messages.append(msg)
|
161
|
+
else:
|
162
|
+
# Fallback: treat as user message
|
163
|
+
converted_messages.append({"role": "user", "content": str(msg)})
|
164
|
+
|
165
|
+
return converted_messages
|
89
166
|
|
90
167
|
@abstractmethod
|
91
168
|
def get_token_usage(self) -> Dict[str, Any]:
|
92
|
-
"""
|
93
|
-
Get cumulative token usage statistics for this service instance
|
94
|
-
|
95
|
-
Returns:
|
96
|
-
Dict containing token usage information:
|
97
|
-
- total_tokens: Total tokens used
|
98
|
-
- prompt_tokens: Tokens used for prompts
|
99
|
-
- completion_tokens: Tokens used for completions
|
100
|
-
- requests_count: Number of requests made
|
101
|
-
"""
|
169
|
+
"""Get cumulative token usage statistics"""
|
102
170
|
pass
|
103
171
|
|
104
172
|
@abstractmethod
|
105
173
|
def get_last_token_usage(self) -> Dict[str, int]:
|
106
|
-
"""
|
107
|
-
Get token usage from the last request
|
108
|
-
|
109
|
-
Returns:
|
110
|
-
Dict containing last request token usage:
|
111
|
-
- prompt_tokens: Tokens in last prompt
|
112
|
-
- completion_tokens: Tokens in last completion
|
113
|
-
- total_tokens: Total tokens in last request
|
114
|
-
"""
|
174
|
+
"""Get token usage from the last request"""
|
115
175
|
pass
|
116
176
|
|
117
177
|
@abstractmethod
|
118
178
|
def get_model_info(self) -> Dict[str, Any]:
|
119
|
-
"""
|
120
|
-
Get information about the current model
|
121
|
-
|
122
|
-
Returns:
|
123
|
-
Dict containing model information:
|
124
|
-
- name: Model name
|
125
|
-
- max_tokens: Maximum context length
|
126
|
-
- supports_streaming: Whether streaming is supported
|
127
|
-
- supports_functions: Whether function calling is supported
|
128
|
-
"""
|
179
|
+
"""Get information about the current model"""
|
129
180
|
pass
|
130
181
|
|
131
182
|
@abstractmethod
|
132
183
|
async def close(self):
|
133
184
|
"""Cleanup resources and close connections"""
|
134
185
|
pass
|
186
|
+
|
187
|
+
def get_last_usage_with_cost(self) -> Dict[str, Any]:
|
188
|
+
"""Get last request usage with cost information"""
|
189
|
+
usage = self.get_last_token_usage()
|
190
|
+
|
191
|
+
# Calculate cost using provider
|
192
|
+
if hasattr(self.provider, 'calculate_cost'):
|
193
|
+
cost = getattr(self.provider, 'calculate_cost')(
|
194
|
+
self.model_name,
|
195
|
+
usage["prompt_tokens"],
|
196
|
+
usage["completion_tokens"]
|
197
|
+
)
|
198
|
+
else:
|
199
|
+
cost = 0.0
|
200
|
+
|
201
|
+
return {
|
202
|
+
**usage,
|
203
|
+
"cost_usd": cost,
|
204
|
+
"model": self.model_name,
|
205
|
+
"provider": getattr(self.provider, 'name', 'unknown')
|
206
|
+
}
|