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.
- isa_model/__init__.py +1 -1
- 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 +142 -240
- isa_model/inference/providers/ml_provider.py +50 -0
- isa_model/inference/services/audio/openai_tts_service.py +104 -3
- 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/llm/__init__.py +2 -0
- isa_model/inference/services/llm/base_llm_service.py +111 -1
- isa_model/inference/services/llm/ollama_llm_service.py +234 -26
- isa_model/inference/services/llm/openai_llm_service.py +180 -26
- 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/ollama_vision_service.py +143 -17
- isa_model/inference/services/vision/replicate_image_gen_service.py +139 -7
- 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.0.8.dist-info/METADATA +465 -0
- isa_model-0.0.8.dist-info/RECORD +86 -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.3.dist-info/METADATA +0 -327
- isa_model-0.0.3.dist-info/RECORD +0 -92
- isa_model-0.0.3.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.3.dist-info → isa_model-0.0.8.dist-info}/WHEEL +0 -0
- {isa_model-0.0.3.dist-info → isa_model-0.0.8.dist-info}/top_level.txt +0 -0
@@ -1,200 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import cv2
|
3
|
-
import logging
|
4
|
-
from PIL import Image
|
5
|
-
from pathlib import Path
|
6
|
-
from tqdm import tqdm
|
7
|
-
from concurrent.futures import ProcessPoolExecutor
|
8
|
-
import shutil
|
9
|
-
from ultralytics import YOLO
|
10
|
-
import numpy
|
11
|
-
from pillow_heif import register_heif_opener
|
12
|
-
|
13
|
-
# Configure logging and PIL settings
|
14
|
-
logging.basicConfig(level=logging.INFO)
|
15
|
-
Image.MAX_IMAGE_PIXELS = None
|
16
|
-
register_heif_opener() # This enables HEIC support in PIL
|
17
|
-
|
18
|
-
COCO_CLASSES = {
|
19
|
-
'person': 0, 'bicycle': 1, 'car': 2, 'motorcycle': 3, 'airplane': 4, 'bus': 5, 'train': 6,
|
20
|
-
'truck': 7, 'boat': 8, 'traffic light': 9, 'fire hydrant': 10, 'stop sign': 11,
|
21
|
-
'parking meter': 12, 'bench': 13, 'bird': 14, 'cat': 15, 'dog': 16, 'horse': 17,
|
22
|
-
'sheep': 18, 'cow': 19, 'elephant': 20, 'bear': 21, 'zebra': 22, 'giraffe': 23,
|
23
|
-
'backpack': 24, 'umbrella': 25, 'handbag': 26, 'tie': 27, 'suitcase': 28, 'frisbee': 29,
|
24
|
-
'skis': 30, 'snowboard': 31, 'sports ball': 32, 'kite': 33, 'baseball bat': 34,
|
25
|
-
'baseball glove': 35, 'skateboard': 36, 'surfboard': 37, 'tennis racket': 38,
|
26
|
-
'bottle': 39, 'wine glass': 40, 'cup': 41, 'fork': 42, 'knife': 43, 'spoon': 44,
|
27
|
-
'bowl': 45, 'banana': 46, 'apple': 47, 'sandwich': 48, 'orange': 49, 'broccoli': 50,
|
28
|
-
'carrot': 51, 'hot dog': 52, 'pizza': 53, 'donut': 54, 'cake': 55, 'chair': 56,
|
29
|
-
'couch': 57, 'potted plant': 58, 'bed': 59, 'dining table': 60, 'toilet': 61,
|
30
|
-
'tv': 62, 'laptop': 63, 'mouse': 64, 'remote': 65, 'keyboard': 66, 'cell phone': 67,
|
31
|
-
'microwave': 68, 'oven': 69, 'toaster': 70, 'sink': 71, 'refrigerator': 72,
|
32
|
-
'book': 73, 'clock': 74, 'vase': 75, 'scissors': 76, 'teddy bear': 77,
|
33
|
-
'hair drier': 78, 'toothbrush': 79
|
34
|
-
}
|
35
|
-
|
36
|
-
class ImagePreProcessor:
|
37
|
-
def __init__(self, input_dir: str, output_dir: str, target_size: tuple = (512, 512),
|
38
|
-
padding: float = 0.3):
|
39
|
-
"""
|
40
|
-
Initialize the image preprocessor
|
41
|
-
"""
|
42
|
-
self.input_dir = Path(input_dir)
|
43
|
-
self.output_dir = Path(output_dir)
|
44
|
-
self.target_size = target_size
|
45
|
-
self.padding = padding
|
46
|
-
self.supported_formats = {'.jpg', '.jpeg', '.heic', '.png'}
|
47
|
-
|
48
|
-
# Load YOLO face detection model
|
49
|
-
try:
|
50
|
-
logging.info("Loading YOLO face detection model...")
|
51
|
-
current_dir = Path(__file__).parent # Get the directory where this script is located
|
52
|
-
model_path = current_dir / "models" / "yolov8n-face.pt"
|
53
|
-
|
54
|
-
if not os.path.exists(model_path):
|
55
|
-
raise FileNotFoundError(f"Model file not found at {model_path}")
|
56
|
-
self.model = YOLO(str(model_path)) # Convert Path to string for YOLO
|
57
|
-
logging.info("Successfully loaded YOLO face detection model")
|
58
|
-
except Exception as e:
|
59
|
-
logging.error(f"Failed to load YOLO model: {str(e)}")
|
60
|
-
raise
|
61
|
-
|
62
|
-
self.output_dir.mkdir(parents=True, exist_ok=True)
|
63
|
-
|
64
|
-
def detect_and_crop_face(self, img) -> tuple:
|
65
|
-
"""
|
66
|
-
Detect face in image and return cropped region
|
67
|
-
"""
|
68
|
-
cv2_img = cv2.cvtColor(numpy.array(img), cv2.COLOR_RGB2BGR)
|
69
|
-
results = self.model(cv2_img)
|
70
|
-
|
71
|
-
# Get all face detections
|
72
|
-
detections = results[0].boxes
|
73
|
-
|
74
|
-
if len(detections) == 0:
|
75
|
-
return False, None
|
76
|
-
|
77
|
-
# Get coordinates of the first detected face
|
78
|
-
box = detections[0]
|
79
|
-
x1, y1, x2, y2 = map(int, box.xyxy[0].tolist())
|
80
|
-
|
81
|
-
# Add padding
|
82
|
-
width = x2 - x1
|
83
|
-
height = y2 - y1
|
84
|
-
padding_x = int(width * self.padding)
|
85
|
-
padding_y = int(height * self.padding)
|
86
|
-
|
87
|
-
x1 = max(0, x1 - padding_x)
|
88
|
-
y1 = max(0, y1 - padding_y)
|
89
|
-
x2 = min(img.width, x2 + padding_x)
|
90
|
-
y2 = min(img.height, y2 + padding_y)
|
91
|
-
|
92
|
-
cropped_img = img.crop((x1, y1, x2, y2))
|
93
|
-
return True, cropped_img
|
94
|
-
|
95
|
-
def process_image(self, image_path: Path) -> tuple:
|
96
|
-
"""
|
97
|
-
Process a single image
|
98
|
-
|
99
|
-
Args:
|
100
|
-
image_path (Path): Path to input image
|
101
|
-
|
102
|
-
Returns:
|
103
|
-
tuple: (success, message)
|
104
|
-
"""
|
105
|
-
try:
|
106
|
-
# Handle HEIC/HEIF files
|
107
|
-
if image_path.suffix.lower() in {'.heic', '.heif'}:
|
108
|
-
try:
|
109
|
-
with Image.open(image_path) as img:
|
110
|
-
# Convert HEIC to RGB mode
|
111
|
-
img = img.convert('RGB')
|
112
|
-
detected, cropped_img = self.detect_and_crop_face(img)
|
113
|
-
if not detected:
|
114
|
-
return False, f"No face detected in {image_path.name}"
|
115
|
-
except Exception as e:
|
116
|
-
return False, f"Error processing HEIC file {image_path.name}: {str(e)}"
|
117
|
-
else:
|
118
|
-
# Handle other image formats
|
119
|
-
with Image.open(image_path) as img:
|
120
|
-
if img.mode != 'RGB':
|
121
|
-
img = img.convert('RGB')
|
122
|
-
detected, cropped_img = self.detect_and_crop_face(img)
|
123
|
-
if not detected:
|
124
|
-
return False, f"No face detected in {image_path.name}"
|
125
|
-
|
126
|
-
# Process the cropped image
|
127
|
-
aspect_ratio = cropped_img.width / cropped_img.height
|
128
|
-
if aspect_ratio > 1:
|
129
|
-
new_width = self.target_size[0]
|
130
|
-
new_height = int(self.target_size[0] / aspect_ratio)
|
131
|
-
else:
|
132
|
-
new_height = self.target_size[1]
|
133
|
-
new_width = int(self.target_size[1] * aspect_ratio)
|
134
|
-
|
135
|
-
cropped_img = cropped_img.resize((new_width, new_height), Image.LANCZOS)
|
136
|
-
|
137
|
-
new_img = Image.new('RGB', self.target_size, (0, 0, 0))
|
138
|
-
paste_x = (self.target_size[0] - new_width) // 2
|
139
|
-
paste_y = (self.target_size[1] - new_height) // 2
|
140
|
-
new_img.paste(cropped_img, (paste_x, paste_y))
|
141
|
-
|
142
|
-
output_path = self.output_dir / f"{image_path.stem}.jpg"
|
143
|
-
new_img.save(output_path, 'JPEG', quality=95)
|
144
|
-
|
145
|
-
return True, f"Successfully processed {image_path.name}"
|
146
|
-
|
147
|
-
except Exception as e:
|
148
|
-
return False, f"Error processing {image_path.name}: {str(e)}"
|
149
|
-
|
150
|
-
def process_directory(self, num_workers: int = 4):
|
151
|
-
"""
|
152
|
-
Process all images in the input directory
|
153
|
-
|
154
|
-
Args:
|
155
|
-
num_workers (int): Number of worker processes to use
|
156
|
-
"""
|
157
|
-
# Get list of all images
|
158
|
-
image_files = [
|
159
|
-
f for f in self.input_dir.iterdir()
|
160
|
-
if f.is_file() and f.suffix.lower() in self.supported_formats
|
161
|
-
]
|
162
|
-
|
163
|
-
if not image_files:
|
164
|
-
logging.warning("No supported image files found in input directory")
|
165
|
-
return
|
166
|
-
|
167
|
-
logging.info(f"Found {len(image_files)} images to process")
|
168
|
-
|
169
|
-
# Process images using multiple workers
|
170
|
-
with ProcessPoolExecutor(max_workers=num_workers) as executor:
|
171
|
-
with tqdm(total=len(image_files), desc="Processing images") as pbar:
|
172
|
-
futures = []
|
173
|
-
for image_path in image_files:
|
174
|
-
future = executor.submit(self.process_image, image_path)
|
175
|
-
future.add_done_callback(lambda p: pbar.update(1))
|
176
|
-
futures.append(future)
|
177
|
-
|
178
|
-
# Process results
|
179
|
-
for future in futures:
|
180
|
-
success, message = future.result()
|
181
|
-
if not success:
|
182
|
-
logging.error(message)
|
183
|
-
|
184
|
-
def main():
|
185
|
-
# Update paths to use project-relative directories
|
186
|
-
current_dir = Path(__file__).parent # Get the directory where this script is located
|
187
|
-
input_dir = current_dir / "data" / "training_images"
|
188
|
-
output_dir = current_dir / "data" / "training_images_processed"
|
189
|
-
|
190
|
-
processor = ImagePreProcessor(
|
191
|
-
input_dir=input_dir,
|
192
|
-
output_dir=output_dir,
|
193
|
-
target_size=(512, 512), # Good size for Kohya training
|
194
|
-
padding=0.3, # 30% padding around faces
|
195
|
-
)
|
196
|
-
|
197
|
-
processor.process_directory(num_workers=4)
|
198
|
-
|
199
|
-
if __name__ == "__main__":
|
200
|
-
main()
|
@@ -1,42 +0,0 @@
|
|
1
|
-
import json
|
2
|
-
import subprocess
|
3
|
-
from pathlib import Path
|
4
|
-
|
5
|
-
def train_lora():
|
6
|
-
# Load your config
|
7
|
-
with open('training_config.json', 'r') as f:
|
8
|
-
config = json.load(f)
|
9
|
-
|
10
|
-
# Construct the training command
|
11
|
-
cmd = [
|
12
|
-
"accelerate", "launch",
|
13
|
-
"--num_cpu_threads_per_process", str(config["num_cpu_threads_per_process"]),
|
14
|
-
"train_network.py",
|
15
|
-
"--pretrained_model_name_or_path", config["pretrained_model_name_or_path"],
|
16
|
-
"--train_data_dir", config["train_data_dir"],
|
17
|
-
"--output_dir", config["output_dir"],
|
18
|
-
"--output_name", config["output_name"],
|
19
|
-
"--save_model_as", config["save_model_as"],
|
20
|
-
"--learning_rate", str(config["learning_rate"]),
|
21
|
-
"--train_batch_size", str(config["train_batch_size"]),
|
22
|
-
"--epoch", str(config["epoch"]),
|
23
|
-
"--save_every_n_epochs", str(config["save_every_n_epochs"]),
|
24
|
-
"--mixed_precision", config["mixed_precision"],
|
25
|
-
"--cache_latents",
|
26
|
-
"--gradient_checkpointing"
|
27
|
-
]
|
28
|
-
|
29
|
-
# Add FLUX specific parameters
|
30
|
-
if config.get("flux1_checkbox"):
|
31
|
-
cmd.extend([
|
32
|
-
"--flux1_t5xxl", config["flux1_t5xxl"],
|
33
|
-
"--flux1_clip_l", config["flux1_clip_l"],
|
34
|
-
"--flux1_cache_text_encoder_outputs",
|
35
|
-
"--flux1_cache_text_encoder_outputs_to_disk"
|
36
|
-
])
|
37
|
-
|
38
|
-
# Execute the training
|
39
|
-
subprocess.run(cmd, check=True)
|
40
|
-
|
41
|
-
if __name__ == "__main__":
|
42
|
-
train_lora()
|
@@ -1,41 +0,0 @@
|
|
1
|
-
import json
|
2
|
-
import subprocess
|
3
|
-
from pathlib import Path
|
4
|
-
|
5
|
-
def train_flux():
|
6
|
-
# Load your config
|
7
|
-
with open('flux_config.json', 'r') as f:
|
8
|
-
config = json.load(f)
|
9
|
-
|
10
|
-
# Construct the training command for Flux finetuning
|
11
|
-
cmd = [
|
12
|
-
"accelerate", "launch",
|
13
|
-
"--num_cpu_threads_per_process", str(config["num_cpu_threads_per_process"]),
|
14
|
-
"train_db.py",
|
15
|
-
"--pretrained_model_name_or_path", config["pretrained_model_name_or_path"],
|
16
|
-
"--train_data_dir", config["train_data_dir"],
|
17
|
-
"--output_dir", config["output_dir"],
|
18
|
-
"--output_name", config["output_name"],
|
19
|
-
"--train_batch_size", str(config["train_batch_size"]),
|
20
|
-
"--save_every_n_epochs", str(config["save_every_n_epochs"]),
|
21
|
-
"--learning_rate", str(config["learning_rate"]),
|
22
|
-
"--max_train_epochs", str(config["epoch"]),
|
23
|
-
"--mixed_precision", config["mixed_precision"],
|
24
|
-
"--save_model_as", config["save_model_as"],
|
25
|
-
"--cache_latents",
|
26
|
-
"--cache_latents_to_disk",
|
27
|
-
"--gradient_checkpointing",
|
28
|
-
"--optimizer_type", "Adafactor",
|
29
|
-
"--optimizer_args", "scale_parameter=False relative_step=False warmup_init=False weight_decay=0.01",
|
30
|
-
"--max_resolution", "1024,1024",
|
31
|
-
"--full_bf16",
|
32
|
-
"--flux1_checkbox",
|
33
|
-
"--flux1_t5xxl", config["flux1_t5xxl"],
|
34
|
-
"--flux1_clip_l", config["flux1_clip_l"],
|
35
|
-
"--flux1_cache_text_encoder_outputs",
|
36
|
-
"--flux1_cache_text_encoder_outputs_to_disk",
|
37
|
-
"--flux_fused_backward_pass"
|
38
|
-
]
|
39
|
-
|
40
|
-
# Execute the training
|
41
|
-
subprocess.run(cmd, check=True)
|
@@ -1,57 +0,0 @@
|
|
1
|
-
import json
|
2
|
-
import subprocess
|
3
|
-
from pathlib import Path
|
4
|
-
|
5
|
-
def train_lora():
|
6
|
-
# Load your config
|
7
|
-
with open('training_config.json', 'r') as f:
|
8
|
-
config = json.load(f)
|
9
|
-
|
10
|
-
# Construct the training command for LoRA
|
11
|
-
cmd = [
|
12
|
-
"accelerate", "launch",
|
13
|
-
"--num_cpu_threads_per_process", str(config["num_cpu_threads_per_process"]),
|
14
|
-
"sdxl_train_network.py", # Use the SDXL LoRA training script
|
15
|
-
"--network_module", "networks.lora", # Specify LoRA network
|
16
|
-
"--pretrained_model_name_or_path", config["pretrained_model_name_or_path"],
|
17
|
-
"--train_data_dir", config["train_data_dir"],
|
18
|
-
"--output_dir", config["output_dir"],
|
19
|
-
"--output_name", config["output_name"],
|
20
|
-
"--save_model_as", config["save_model_as"],
|
21
|
-
"--network_alpha", "1", # LoRA alpha parameter
|
22
|
-
"--network_dim", "32", # LoRA dimension
|
23
|
-
"--learning_rate", str(config["learning_rate"]),
|
24
|
-
"--train_batch_size", str(config["train_batch_size"]),
|
25
|
-
"--max_train_epochs", str(config["epoch"]),
|
26
|
-
"--save_every_n_epochs", str(config["save_every_n_epochs"]),
|
27
|
-
"--mixed_precision", config["mixed_precision"],
|
28
|
-
"--cache_latents",
|
29
|
-
"--gradient_checkpointing",
|
30
|
-
"--network_args", "conv_dim=32", "conv_alpha=1", # LoRA network arguments
|
31
|
-
"--noise_offset", "0.1",
|
32
|
-
"--adaptive_noise_scale", "0.01",
|
33
|
-
"--max_resolution", "1024,1024",
|
34
|
-
"--min_bucket_reso", "256",
|
35
|
-
"--max_bucket_reso", "1024",
|
36
|
-
"--xformers",
|
37
|
-
"--bucket_reso_steps", "64",
|
38
|
-
"--caption_extension", ".txt",
|
39
|
-
"--optimizer_type", "AdaFactor",
|
40
|
-
"--optimizer_args", "scale_parameter=False", "relative_step=False", "warmup_init=False",
|
41
|
-
"--lr_scheduler", "constant"
|
42
|
-
]
|
43
|
-
|
44
|
-
# Add FLUX specific parameters for LoRA
|
45
|
-
if config.get("flux1_checkbox"):
|
46
|
-
cmd.extend([
|
47
|
-
"--flux1_t5xxl", config["flux1_t5xxl"],
|
48
|
-
"--flux1_clip_l", config["flux1_clip_l"],
|
49
|
-
"--flux1_cache_text_encoder_outputs",
|
50
|
-
"--flux1_cache_text_encoder_outputs_to_disk"
|
51
|
-
])
|
52
|
-
|
53
|
-
# Execute the training
|
54
|
-
subprocess.run(cmd, check=True)
|
55
|
-
|
56
|
-
if __name__ == "__main__":
|
57
|
-
train_lora()
|
@@ -1,25 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
from pathlib import Path
|
3
|
-
import shutil
|
4
|
-
from app.services.training.image_model.raw_data.create_lora_captions import create_lora_captions
|
5
|
-
from app.services.training.image_model.train.train_flux import train_flux
|
6
|
-
|
7
|
-
def main():
|
8
|
-
# Setup paths
|
9
|
-
project_root = Path(__file__).parent
|
10
|
-
processed_images_dir = project_root / "raw_data/training_images_processed"
|
11
|
-
|
12
|
-
# 1. Generate captions for all processed images
|
13
|
-
print("Creating captions for processed images...")
|
14
|
-
create_lora_captions(processed_images_dir)
|
15
|
-
|
16
|
-
# 2. Create Flux config
|
17
|
-
print("Creating Flux configuration...")
|
18
|
-
os.system(f"python {project_root}/configs/create_flux_config.py")
|
19
|
-
|
20
|
-
# 3. Run Flux training
|
21
|
-
print("Starting Flux training...")
|
22
|
-
train_flux()
|
23
|
-
|
24
|
-
if __name__ == "__main__":
|
25
|
-
main()
|
@@ -1,327 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: isa-model
|
3
|
-
Version: 0.0.3
|
4
|
-
Summary: Unified AI model serving framework
|
5
|
-
Author-email: isA_Model Contributors <your.email@example.com>
|
6
|
-
License-Expression: MIT
|
7
|
-
Classifier: Development Status :: 3 - Alpha
|
8
|
-
Classifier: Intended Audience :: Developers
|
9
|
-
Classifier: Operating System :: OS Independent
|
10
|
-
Classifier: Programming Language :: Python :: 3
|
11
|
-
Requires-Python: >=3.8
|
12
|
-
Description-Content-Type: text/markdown
|
13
|
-
License-File: LICENSE
|
14
|
-
Requires-Dist: fastapi>=0.95.0
|
15
|
-
Requires-Dist: numpy>=1.20.0
|
16
|
-
Requires-Dist: httpx>=0.23.0
|
17
|
-
Requires-Dist: pydantic>=2.0.0
|
18
|
-
Requires-Dist: uvicorn>=0.22.0
|
19
|
-
Requires-Dist: requests>=2.28.0
|
20
|
-
Requires-Dist: aiohttp>=3.8.0
|
21
|
-
Requires-Dist: transformers>=4.30.0
|
22
|
-
Requires-Dist: langchain-core>=0.1.0
|
23
|
-
Requires-Dist: huggingface-hub>=0.16.0
|
24
|
-
Requires-Dist: kubernetes>=25.3.0
|
25
|
-
Requires-Dist: mlflow>=2.4.0
|
26
|
-
Requires-Dist: torch>=2.0.0
|
27
|
-
Requires-Dist: openai>=1.10.0
|
28
|
-
Requires-Dist: replicate>=0.23.0
|
29
|
-
Requires-Dist: python-dotenv>=1.0.0
|
30
|
-
Dynamic: license-file
|
31
|
-
|
32
|
-
# isA Model - Unified AI Model Serving Framework
|
33
|
-
|
34
|
-
A comprehensive Python framework for working with multiple AI providers and models through a unified interface. Support for OpenAI, Replicate, Ollama, and more.
|
35
|
-
|
36
|
-
## Installation
|
37
|
-
|
38
|
-
```bash
|
39
|
-
pip install isa-model
|
40
|
-
```
|
41
|
-
|
42
|
-
## Quick Start
|
43
|
-
|
44
|
-
The isa-model package supports three main usage patterns:
|
45
|
-
|
46
|
-
### 1. Pass API Keys Directly (Recommended)
|
47
|
-
|
48
|
-
This is the most flexible approach - no environment variables needed:
|
49
|
-
|
50
|
-
```python
|
51
|
-
from isa_model.inference.ai_factory import AIFactory
|
52
|
-
|
53
|
-
# Create factory instance
|
54
|
-
factory = AIFactory.get_instance()
|
55
|
-
|
56
|
-
# Use OpenAI with API key
|
57
|
-
llm = factory.get_llm(
|
58
|
-
model_name="gpt-4o-mini",
|
59
|
-
provider="openai",
|
60
|
-
api_key="your-openai-api-key-here"
|
61
|
-
)
|
62
|
-
|
63
|
-
# Use Replicate for image generation
|
64
|
-
image_gen = factory.get_vision_model(
|
65
|
-
model_name="stability-ai/sdxl",
|
66
|
-
provider="replicate",
|
67
|
-
api_key="your-replicate-token-here"
|
68
|
-
)
|
69
|
-
```
|
70
|
-
|
71
|
-
### 2. Use Environment Variables
|
72
|
-
|
73
|
-
Set your API keys as environment variables:
|
74
|
-
|
75
|
-
```bash
|
76
|
-
export OPENAI_API_KEY="your-openai-api-key"
|
77
|
-
export REPLICATE_API_TOKEN="your-replicate-token"
|
78
|
-
```
|
79
|
-
|
80
|
-
Then use without passing keys:
|
81
|
-
|
82
|
-
```python
|
83
|
-
from isa_model.inference.ai_factory import AIFactory
|
84
|
-
|
85
|
-
factory = AIFactory.get_instance()
|
86
|
-
|
87
|
-
# Will automatically use OPENAI_API_KEY from environment
|
88
|
-
llm = factory.get_llm(model_name="gpt-4o-mini", provider="openai")
|
89
|
-
|
90
|
-
# Will automatically use REPLICATE_API_TOKEN from environment
|
91
|
-
image_gen = factory.get_vision_model(model_name="stability-ai/sdxl", provider="replicate")
|
92
|
-
```
|
93
|
-
|
94
|
-
### 3. Use Local Models (No API Key Needed)
|
95
|
-
|
96
|
-
For local models like Ollama, no API keys are required:
|
97
|
-
|
98
|
-
```python
|
99
|
-
from isa_model.inference.ai_factory import AIFactory
|
100
|
-
|
101
|
-
factory = AIFactory.get_instance()
|
102
|
-
|
103
|
-
# Use local Ollama model (no API key needed)
|
104
|
-
llm = factory.get_llm(model_name="llama3.1", provider="ollama")
|
105
|
-
```
|
106
|
-
|
107
|
-
## Supported Services
|
108
|
-
|
109
|
-
### Language Models (LLM)
|
110
|
-
|
111
|
-
```python
|
112
|
-
# OpenAI models
|
113
|
-
llm = factory.get_llm("gpt-4o-mini", "openai", api_key="your-key")
|
114
|
-
llm = factory.get_llm("gpt-4o", "openai", api_key="your-key")
|
115
|
-
|
116
|
-
# Ollama models (local)
|
117
|
-
llm = factory.get_llm("llama3.1", "ollama")
|
118
|
-
llm = factory.get_llm("codellama", "ollama")
|
119
|
-
|
120
|
-
# Replicate models
|
121
|
-
llm = factory.get_llm("meta/llama-3-70b-instruct", "replicate", api_key="your-token")
|
122
|
-
```
|
123
|
-
|
124
|
-
### Vision Models
|
125
|
-
|
126
|
-
```python
|
127
|
-
# OpenAI vision
|
128
|
-
vision = factory.get_vision_model("gpt-4o", "openai", api_key="your-key")
|
129
|
-
|
130
|
-
# Replicate image generation
|
131
|
-
image_gen = factory.get_vision_model("stability-ai/sdxl", "replicate", api_key="your-token")
|
132
|
-
|
133
|
-
# Ollama vision (local)
|
134
|
-
vision = factory.get_vision_model("llava", "ollama")
|
135
|
-
```
|
136
|
-
|
137
|
-
### Embedding Models
|
138
|
-
|
139
|
-
```python
|
140
|
-
# OpenAI embeddings
|
141
|
-
embedder = factory.get_embedding("text-embedding-3-small", "openai", {"api_key": "your-key"})
|
142
|
-
|
143
|
-
# Ollama embeddings (local)
|
144
|
-
embedder = factory.get_embedding("bge-m3", "ollama")
|
145
|
-
```
|
146
|
-
|
147
|
-
## Base Service Classes
|
148
|
-
|
149
|
-
The framework provides comprehensive base classes for implementing new AI services:
|
150
|
-
|
151
|
-
### BaseLLMService
|
152
|
-
- `ainvoke()` - Universal invocation method
|
153
|
-
- `achat()` - Chat completion with messages
|
154
|
-
- `acompletion()` - Simple text completion
|
155
|
-
- `agenerate()` - Generate multiple completions
|
156
|
-
- `astream_chat()` - Streaming chat responses
|
157
|
-
- `get_token_usage()` - Token usage statistics
|
158
|
-
|
159
|
-
### BaseVisionService
|
160
|
-
- `analyze_image()` - Analyze and describe images
|
161
|
-
- `describe_image()` - Generate detailed descriptions
|
162
|
-
- `extract_text()` - OCR text extraction
|
163
|
-
- `detect_objects()` - Object detection
|
164
|
-
- `classify_image()` - Image classification
|
165
|
-
- `compare_images()` - Image similarity comparison
|
166
|
-
|
167
|
-
### BaseImageGenService
|
168
|
-
- `generate_image()` - Generate single image from text
|
169
|
-
- `generate_images()` - Generate multiple images
|
170
|
-
- `image_to_image()` - Transform existing images
|
171
|
-
- `get_supported_sizes()` - Get supported dimensions
|
172
|
-
|
173
|
-
### BaseEmbedService
|
174
|
-
- `create_text_embedding()` - Single text embedding
|
175
|
-
- `create_text_embeddings()` - Batch text embeddings
|
176
|
-
- `compute_similarity()` - Similarity calculation
|
177
|
-
- `find_similar_texts()` - Semantic search
|
178
|
-
|
179
|
-
### BaseSTTService (Speech-to-Text)
|
180
|
-
- `transcribe_audio()` - Audio transcription
|
181
|
-
- `transcribe_audio_batch()` - Batch transcription
|
182
|
-
- `detect_language()` - Language detection
|
183
|
-
|
184
|
-
### BaseTTSService (Text-to-Speech)
|
185
|
-
- `synthesize_speech()` - Text to speech conversion
|
186
|
-
- `synthesize_speech_to_file()` - Save speech to file
|
187
|
-
- `get_available_voices()` - List available voices
|
188
|
-
|
189
|
-
## Usage Examples
|
190
|
-
|
191
|
-
### Chat Completion
|
192
|
-
|
193
|
-
```python
|
194
|
-
import asyncio
|
195
|
-
from isa_model.inference.ai_factory import AIFactory
|
196
|
-
|
197
|
-
async def chat_example():
|
198
|
-
factory = AIFactory.get_instance()
|
199
|
-
llm = factory.get_llm("gpt-4o-mini", "openai", api_key="your-key")
|
200
|
-
|
201
|
-
messages = [
|
202
|
-
{"role": "user", "content": "Hello, how are you?"}
|
203
|
-
]
|
204
|
-
|
205
|
-
response = await llm.achat(messages)
|
206
|
-
print(response)
|
207
|
-
|
208
|
-
# Run the async function
|
209
|
-
asyncio.run(chat_example())
|
210
|
-
```
|
211
|
-
|
212
|
-
### Image Analysis
|
213
|
-
|
214
|
-
```python
|
215
|
-
import asyncio
|
216
|
-
from isa_model.inference.ai_factory import AIFactory
|
217
|
-
|
218
|
-
async def vision_example():
|
219
|
-
factory = AIFactory.get_instance()
|
220
|
-
vision = factory.get_vision_model("gpt-4o", "openai", api_key="your-key")
|
221
|
-
|
222
|
-
result = await vision.analyze_image(
|
223
|
-
image="path/to/your/image.jpg",
|
224
|
-
prompt="What do you see in this image?"
|
225
|
-
)
|
226
|
-
|
227
|
-
print(result["text"])
|
228
|
-
|
229
|
-
asyncio.run(vision_example())
|
230
|
-
```
|
231
|
-
|
232
|
-
### Image Generation
|
233
|
-
|
234
|
-
```python
|
235
|
-
import asyncio
|
236
|
-
from isa_model.inference.ai_factory import AIFactory
|
237
|
-
|
238
|
-
async def image_gen_example():
|
239
|
-
factory = AIFactory.get_instance()
|
240
|
-
image_gen = factory.get_vision_model(
|
241
|
-
"stability-ai/sdxl",
|
242
|
-
"replicate",
|
243
|
-
api_key="your-replicate-token"
|
244
|
-
)
|
245
|
-
|
246
|
-
result = await image_gen.generate_image(
|
247
|
-
prompt="A beautiful sunset over mountains",
|
248
|
-
width=1024,
|
249
|
-
height=1024
|
250
|
-
)
|
251
|
-
|
252
|
-
# Save the generated image
|
253
|
-
with open("generated_image.png", "wb") as f:
|
254
|
-
f.write(result["image_data"])
|
255
|
-
|
256
|
-
asyncio.run(image_gen_example())
|
257
|
-
```
|
258
|
-
|
259
|
-
## Configuration Options
|
260
|
-
|
261
|
-
You can pass additional configuration options:
|
262
|
-
|
263
|
-
```python
|
264
|
-
# Custom configuration
|
265
|
-
config = {
|
266
|
-
"temperature": 0.7,
|
267
|
-
"max_tokens": 1000,
|
268
|
-
"top_p": 0.9
|
269
|
-
}
|
270
|
-
|
271
|
-
llm = factory.get_llm(
|
272
|
-
model_name="gpt-4o-mini",
|
273
|
-
provider="openai",
|
274
|
-
config=config,
|
275
|
-
api_key="your-key"
|
276
|
-
)
|
277
|
-
```
|
278
|
-
|
279
|
-
## Error Handling
|
280
|
-
|
281
|
-
The framework provides informative error messages and graceful fallbacks:
|
282
|
-
|
283
|
-
```python
|
284
|
-
try:
|
285
|
-
llm = factory.get_llm("gpt-4o-mini", "openai", api_key="invalid-key")
|
286
|
-
response = await llm.achat([{"role": "user", "content": "Hello"}])
|
287
|
-
except Exception as e:
|
288
|
-
print(f"Error: {e}")
|
289
|
-
```
|
290
|
-
|
291
|
-
## Development
|
292
|
-
|
293
|
-
### Installing for Development
|
294
|
-
|
295
|
-
```bash
|
296
|
-
git clone <repository-url>
|
297
|
-
cd isA_Model
|
298
|
-
pip install -e .
|
299
|
-
```
|
300
|
-
|
301
|
-
### Running Tests
|
302
|
-
|
303
|
-
```bash
|
304
|
-
pytest tests/
|
305
|
-
```
|
306
|
-
|
307
|
-
### Building and Publishing
|
308
|
-
|
309
|
-
```bash
|
310
|
-
# Build the package
|
311
|
-
python -m build
|
312
|
-
|
313
|
-
# Upload to PyPI (requires PYPI_API_TOKEN in .env.local)
|
314
|
-
bash scripts/normal_update.sh
|
315
|
-
```
|
316
|
-
|
317
|
-
## License
|
318
|
-
|
319
|
-
MIT License - see LICENSE file for details.
|
320
|
-
|
321
|
-
## Contributing
|
322
|
-
|
323
|
-
Contributions are welcome! Please read our contributing guidelines and submit pull requests to our GitHub repository.
|
324
|
-
|
325
|
-
## Support
|
326
|
-
|
327
|
-
For questions and support, please open an issue on our GitHub repository.
|