raySD 0.1.0__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.
raySD/__init__.py ADDED
@@ -0,0 +1,6 @@
1
+ from .pipeline import *
2
+ from .prompt import *
3
+ from .pydantic_model import *
4
+ from .utils import *
5
+
6
+ __version__ = "0.0.1"
@@ -0,0 +1,28 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ class AbstractPipeline(ABC):
4
+ def __init__(self, **kwargs):
5
+ ## Hook model
6
+ self.module_pre_hook = []
7
+ self.module_post_hook = []
8
+
9
+ def __call__(self, *args, **kwargs):
10
+ for hook in self.module_pre_hook:
11
+ x = hook(*args, **kwargs)
12
+ x = self.forward(*args, **kwargs)
13
+ for hook in self.module_post_hook:
14
+ x = hook(*args, **kwargs)
15
+ return x
16
+
17
+ def register_pre_hook(self, hook):
18
+ self.module_pre_hook.append(hook)
19
+
20
+ def register_post_hook(self, hook):
21
+ self.module_post_hook.append(hook)
22
+
23
+ def forward(self, *args, **kwargs):
24
+ pass
25
+
26
+ @abstractmethod
27
+ def load_weights(self):
28
+ pass
@@ -0,0 +1,115 @@
1
+ import numpy as np
2
+ import torch
3
+ from raySD.utils.Enable_xFormers import *
4
+ from raySD.pipeline.Abstract_Pipeline import *
5
+ from raySD.prompt.chibi_prompt import *
6
+ from raySD.pydantic_model.Stable_Diffusion_IP_Adapter_Model import *
7
+ import time
8
+ import cv2
9
+ from PIL import Image
10
+ import importlib
11
+
12
+ class StableDiffusionIPAdapterPipeline(AbstractPipeline):
13
+ def __init__(self, **kwargs):
14
+ super().__init__()
15
+ ## Config
16
+ self.config = SD_IP_Config(**kwargs)
17
+
18
+ def update_params_infer(self, **kwargs):
19
+ self.config.inference_steps = kwargs.get("inference_steps", 20)
20
+ self.config.guidance_scale = kwargs.get("guidance_scale", 7)
21
+ self.config.ip_adapter_scale = kwargs.get("ip_adapter_scale", 1)
22
+ self.config.clip_skip=kwargs.get("clip_skip", 2)
23
+ self.config.num_images_per_prompt=kwargs.get("num_images_per_prompt", 1)
24
+
25
+ def load_weights(self):
26
+ from diffusers import DPMSolverMultistepScheduler
27
+ from diffusers import StableDiffusionPipeline
28
+
29
+ ## Device
30
+ self.device = "cuda" if torch.cuda.is_available() else "cpu"
31
+ print(f"DEVICE: {self.device}")
32
+ ## Load Stable Diffusion model
33
+ pipeline = StableDiffusionPipeline.from_single_file(
34
+ self.config.checkpoint_path,
35
+ torch_dtype=torch.float16,
36
+ safety_checker=None
37
+ ).to(self.device)
38
+
39
+ ### Scheduler
40
+ pipeline.scheduler = DPMSolverMultistepScheduler.from_config(
41
+ pipeline.scheduler.config,
42
+ algorithm_type="dpmsolver++", # <-- DPM++
43
+ use_karras_sigmas=True, # <-- Karras
44
+ solver_order=2 # <-- 2M (2nd order multistep)
45
+ )
46
+
47
+ if self.config.lora_style_path:
48
+ print("Load LoRA done")
49
+ pipeline.load_lora_weights(self.config.lora_style_path)
50
+
51
+ enable_xformers_if_available(pipeline)
52
+
53
+ ### Load pipeline to IPAdapter
54
+ if self.config.ip_adapter_plus:
55
+ from ip_adapter.ip_adapter_faceid import IPAdapterFaceIDPlus
56
+ self.ip_adapter = IPAdapterFaceIDPlus(
57
+ pipeline,
58
+ image_encoder_path=self.config.image_encoder_path,
59
+ ip_ckpt=self.config.ip_adapter_checkpoint_path,
60
+ device=self.device
61
+ )
62
+ else:
63
+ from ip_adapter.ip_adapter_faceid import IPAdapterFaceID
64
+ self.ip_adapter = IPAdapterFaceID(
65
+ pipeline,
66
+ ip_ckpt=self.config.ip_adapter_checkpoint_path,
67
+ device=self.device
68
+ )
69
+
70
+ module = importlib.import_module("insightface.app")
71
+ # Load Face Analysis
72
+ self.face_app = module.FaceAnalysis(name=self.config.insightface_app_name, providers=self.config.insightface_providers)
73
+ self.face_app.prepare(ctx_id=0, det_size=self.config.det_size_face)
74
+
75
+ module_util = importlib.import_module("insightface.utils")
76
+ self.face_align = getattr(module_util, "face_align")
77
+
78
+ print("LOAD SD PIPELINE DONE")
79
+
80
+ def forward(self, x: Image.Image, **kwargs)->Image.Image:
81
+ img = cv2.cvtColor(np.array(x), cv2.COLOR_RGB2BGR)
82
+ faces = self.face_app.get(img)
83
+ face_emb = torch.from_numpy(faces[0].normed_embedding).unsqueeze(0).to(self.device)
84
+ aligned_face = self.face_align.norm_crop(img, landmark=faces[0].kps, image_size=self.config.target_size)
85
+
86
+ print(face_emb.shape)
87
+ print(aligned_face.shape)
88
+
89
+ gender = kwargs["gender"]
90
+ age = kwargs["age"]
91
+
92
+ if self.config.style_name == "chibi_style":
93
+ chibi_prompt = ChibiPrompt2(gender=gender)
94
+ self.prompt, self.negative_prompt = chibi_prompt.get_prompt()
95
+
96
+ start_time = time.time()
97
+ image = self.ip_adapter.generate(
98
+ face_image=aligned_face,
99
+ faceid_embeds=face_emb,
100
+ prompt=self.prompt,
101
+ negative_prompt=self.negative_prompt,
102
+ guidance_scale=self.config.guidance_scale,
103
+ num_inference_steps=self.config.inference_steps,
104
+ scale=self.config.ip_adapter_scale,
105
+ num_samples=self.config.num_images_per_prompt,
106
+ width=self.config.width,
107
+ height=self.config.height,
108
+ )[0]
109
+ end_time = time.time()
110
+ print(f"Inference time: {end_time - start_time:.2f} seconds")
111
+ return image
112
+
113
+
114
+
115
+
@@ -0,0 +1,42 @@
1
+ from raySD.pipeline.Abstract_Pipeline import *
2
+ from PIL import Image
3
+ import importlib
4
+ import time
5
+ import numpy as np
6
+ import cv2
7
+
8
+ class SuperResolutionPipeline(AbstractPipeline):
9
+ def __init__(self, model_path: str, device="CPU", output_size=(768, 768)):
10
+ super().__init__()
11
+ self.model_path = model_path
12
+ self.device = device
13
+ self.output_size = output_size
14
+
15
+ def load_weights(self):
16
+ module = importlib.import_module("openvino")
17
+ Core = getattr(module, "Core")
18
+ core = Core()
19
+ model_ov = core.read_model(self.model_path)
20
+ self.model = core.compile_model(model_ov, device_name=self.device)
21
+ print("LOAD SUPER RESOLUTION MODEL DONE")
22
+
23
+
24
+ def forward(self, x: Image.Image, **kwargs)->Image.Image:
25
+ st = time.time()
26
+ x = np.array(x)
27
+ x = x / 255.0
28
+ x = np.expand_dims(x, axis=0)
29
+ x = np.transpose(x, (0, 3, 1, 2))
30
+ y = self.model([x])
31
+ start_time = time.time()
32
+ y = y[next(iter(y))]
33
+ end_time = time.time()
34
+ print(f"Inference ESRGAN: {end_time - start_time}s")
35
+ y = np.transpose(y, (0, 2, 3, 1))
36
+ y = np.squeeze(y)
37
+ y = cv2.resize(y, self.output_size, interpolation=cv2.INTER_AREA)
38
+ y = cv2.convertScaleAbs(y*255)
39
+ image_out = Image.fromarray(y)
40
+ ed = time.time()
41
+ print(f"All time IF: {ed - st}s")
42
+ return image_out
@@ -0,0 +1,2 @@
1
+ from .Stable_Diffusion_IP_Adapter import *
2
+ from .Super_Resolution_Pipeline import *
@@ -0,0 +1 @@
1
+ from .chibi_prompt import *
@@ -0,0 +1,56 @@
1
+ from pydantic import BaseModel, model_validator
2
+ from typing import List, Dict, Any, Optional
3
+
4
+ class ChibiPrompt():
5
+ def __init__(self, gender: int):
6
+ self.gender = gender
7
+ if gender == 1:
8
+ self.key1 = "boy"
9
+ self.key2 = "male"
10
+ else:
11
+ self.key1 = "girl"
12
+ self.key2 = "female"
13
+
14
+ # self.prompt = f"chibi style, solo, looking at viewer, simple background, brown hair, blue shirt, 1{self.key1}, {self.key2} focus, brown hair, warm and friendly expression, natural smile, well-aligned teeth, realistic lips, smooth facial features, expressive eyes, soft lighting, high-quality shading, professional rendering, best quality, high resolution, portrait, blue background, natural proportions, detailed face, gentle grin"
15
+ # self.negative_prompt = f"worst quality, low quality, normal quaworst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry, bad smile, bad anatomylity, jpeg artifacts, signature, watermark, username, blurry, bad anatomy, blurry teeth, deformed teeth, extra teeth, missing teeth"
16
+
17
+ self.prompt = f"chibi style, solo, looking at viewer, simple background, brown hair, blue shirt, 1{self.key1}, {self.key2} (20-30 years old), {self.key2} focus, brown hair, warm and friendly expression, natural smile, well-aligned teeth, realistic lips, smooth facial features, expressive eyes, soft lighting, high-quality shading, professional rendering, best quality, high resolution, portrait, blue background, natural proportions, detailed face, gentle grin"
18
+ self.negative_prompt = f"worst quality, low quality, normal quaworst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry, bad smile, bad anatomylity, jpeg artifacts, signature, watermark, username, blurry, bad anatomy, blurry teeth, deformed teeth, extra teeth, missing teeth"
19
+
20
+ def get_prompt(self):
21
+ return self.prompt, self.negative_prompt
22
+
23
+
24
+ class ChibiPrompt1():
25
+ def __init__(self, gender: int):
26
+ self.gender = gender
27
+ if gender == 1:
28
+ self.key1 = "boy"
29
+ self.key2 = "male"
30
+ else:
31
+ self.key1 = "girl"
32
+ self.key2 = "female"
33
+
34
+ self.prompt = f"chibi style, solo, 1{self.key1}, blue shirt, brown hair, looking at viewer, warm and friendly expression, natural smile, realistic lips, well-aligned teeth, smooth facial features, expressive eyes, soft lighting, detailed face, gentle grin, portrait, blue background, simple background, professional rendering, high-quality shading, bright face, soft glow, best quality, high resolution"
35
+ self.negative_prompt = f"worst quality, low quality, normal quaworst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry, bad smile, bad anatomylity, jpeg artifacts, signature, watermark, username, blurry, bad anatomy, blurry teeth, deformed teeth, extra teeth, missing teeth"
36
+
37
+ def get_prompt(self):
38
+ return self.prompt, self.negative_prompt
39
+
40
+
41
+ class ChibiPrompt2():
42
+ def __init__(self, gender: int):
43
+ self.gender = gender
44
+ if gender == 1:
45
+ self.key1 = "boy"
46
+ self.key2 = "male"
47
+ else:
48
+ self.key1 = "girl"
49
+ self.key2 = "female"
50
+
51
+ self.prompt = f"chibi style, solo, 1{self.key1}, looking at viewer, blue shirt, friendly expression, natural smile, smooth fair skin, realistic lips, big round eyes, bright eyes, evenly lit bright face, soft glow, ambient diffuse light, high quality shading, detailed soft face, professional render, best quality, high resolution, blue background"
52
+
53
+ self.negative_prompt = f"worst quality, low quality, jpeg artifacts, signature, watermark, username, blurry, bad smile, bad anatomy, blurry teeth, deformed teeth, extra teeth, missing teeth, uneven lighting, harsh shadow, flat shading, discolored skin, dark chin, underexposed face, unnatural skin tone, narrow eyes, slit eyes, squinting eyes, closed eyes, color bleeding, blue tint on face"
54
+
55
+ def get_prompt(self):
56
+ return self.prompt, self.negative_prompt
@@ -0,0 +1,7 @@
1
+ from pydantic import BaseModel, model_validator
2
+ from typing import List, Dict, Any, Optional
3
+
4
+ class ImageGenerateModel(BaseModel):
5
+ image: str = ""
6
+ gender: int = -1
7
+ age: int = 0
@@ -0,0 +1,4 @@
1
+ from pydantic import BaseModel, Field
2
+
3
+ class ImageResponseModel(BaseModel):
4
+ image: str = ""
@@ -0,0 +1,4 @@
1
+ from pydantic import BaseModel, Field
2
+
3
+ class MessageModel(BaseModel):
4
+ message: str = ""
@@ -0,0 +1,24 @@
1
+ from pydantic import BaseModel, model_validator
2
+ from typing import List, Dict, Any, Optional
3
+
4
+ class SD_IP_Config(BaseModel):
5
+ pretrain_model_path: str = ""
6
+ checkpoint_path: str = ""
7
+ lora_style_path: str = ""
8
+ style_name: str = ""
9
+ height: int = 512
10
+ width: int = 512
11
+ ip_adapter_plus: bool = False
12
+ version: float = 1.0
13
+ image_encoder_path: str = ""
14
+ ip_adapter_checkpoint_path: str = ""
15
+ insightface_app_name: str = ""
16
+ insightface_providers: List = []
17
+
18
+ det_size_face: tuple = (640, 640)
19
+ target_size: int = 224
20
+ inference_steps: int = 20
21
+ guidance_scale: float = 7
22
+ ip_adapter_scale: float = 0.6
23
+ clip_skip: int = 2
24
+ num_images_per_prompt: int = 1
@@ -0,0 +1,4 @@
1
+ from .Image_Generate_Model import *
2
+ from .Image_Response_Model import *
3
+ from .Message_Model import *
4
+ from .Stable_Diffusion_IP_Adapter_Model import *
@@ -0,0 +1,9 @@
1
+ def enable_xformers_if_available(pipe):
2
+ try:
3
+ import xformers
4
+ pipe.enable_xformers_memory_efficient_attention()
5
+ print("xformers is available and has been enabled.")
6
+ except ImportError:
7
+ print("xformers is NOT installed. Running without xformers.")
8
+ except Exception as e:
9
+ print(f"xformers is installed but could not be enabled: {e}")
@@ -0,0 +1 @@
1
+ from .Enable_xFormers import *
@@ -0,0 +1,21 @@
1
+ Metadata-Version: 2.4
2
+ Name: raySD
3
+ Version: 0.1.0
4
+ Summary: Stable diffusion pipeline for ray
5
+ Author: Nguyen Hong Ky
6
+ Requires-Dist: numpy==1.26.4
7
+ Requires-Dist: opencv-python>=4.10.0.84
8
+ Requires-Dist: pillow>=9.5.0
9
+ Requires-Dist: torch==2.3.1
10
+ Requires-Dist: torchvision==0.18.1
11
+ Requires-Dist: diffusers==0.33.0
12
+ Requires-Dist: transformers==4.49.0
13
+ Requires-Dist: peft==0.15.2
14
+ Requires-Dist: openvino==2025.1.0
15
+ Requires-Dist: ip-adapterv
16
+ Requires-Dist: pydantic
17
+ Requires-Dist: onnx==1.17.0
18
+ Requires-Dist: onnxruntime==1.17.1
19
+ Dynamic: author
20
+ Dynamic: requires-dist
21
+ Dynamic: summary
@@ -0,0 +1,18 @@
1
+ raySD/__init__.py,sha256=4ETmeXZJi5Myr8boHVhNqejNmMNHjG8oraKokGJw1ko,124
2
+ raySD/pipeline/Abstract_Pipeline.py,sha256=0M0H7j0b7OrJpm-FD0ZCUqiv65DjxVn9YCd38TScbZg,768
3
+ raySD/pipeline/Stable_Diffusion_IP_Adapter.py,sha256=0ViMt8X64TFIX9rZQT2ARFoExxN_FOfD5wUEJvoBQcQ,4564
4
+ raySD/pipeline/Super_Resolution_Pipeline.py,sha256=5q2L5En7zMYdnKd-yUnkQyvQ4p3wyc1tu5laZaLAUkM,1470
5
+ raySD/pipeline/__init__.py,sha256=3SohaavHvlq6mt5F5rpbReoU2pggZTH8T7BNE7GPPqo,84
6
+ raySD/prompt/__init__.py,sha256=fVssgWdHZT0v98vMT328Cx_ayYSJh_RFmIhbts_0s8c,27
7
+ raySD/prompt/chibi_prompt.py,sha256=u1v-1SSkdfM1QmSso99a1FcGdKW426eH3cRaGEbb_kE,4203
8
+ raySD/pydantic_model/Image_Generate_Model.py,sha256=RlfMwF5GhWm6sQvxVN16HVv-nLth_B7yyrFvIvyX_WA,194
9
+ raySD/pydantic_model/Image_Response_Model.py,sha256=tgZo2P-klG0TX_DRaReKHrH2ZUF-g53N1vnIMZLGNsw,98
10
+ raySD/pydantic_model/Message_Model.py,sha256=D0DNP1F8kkwwB2X8QOTLtaLleVdf_INyIwjdypuVafM,94
11
+ raySD/pydantic_model/Stable_Diffusion_IP_Adapter_Model.py,sha256=vpQM1To4K-amIKrFy0dxXxeLSMr5mWuAHJWWgdKGhO4,734
12
+ raySD/pydantic_model/__init__.py,sha256=woiNl2YsEnyRvkFFRQuDIVLm-pMiJo27xgoRrHw0mOs,152
13
+ raySD/utils/Enable_xFormers.py,sha256=2gZf3Shxth4jDkAtDFZa27wDFNavZa3BRn4nizgaiyw,392
14
+ raySD/utils/__init__.py,sha256=KavMKUtooaiUDJOsNzdEUjOxTWxZ9sn8sUPWaJ2Mkgs,30
15
+ raysd-0.1.0.dist-info/METADATA,sha256=YL59OSkrZJb-UxNft9_PTddMZGKH2LkmHiQeFBEs7Kg,598
16
+ raysd-0.1.0.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
17
+ raysd-0.1.0.dist-info/top_level.txt,sha256=1yKh5zJFazWtmZ-WR7v930Nl7KkrjpodCSBFU76K7SU,6
18
+ raysd-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.4.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ raySD