zeyadcode commited on
Commit
479a2b5
·
verified ·
1 Parent(s): efff8de

Sync from GitHub via hub-sync

Browse files
Dockerfile CHANGED
@@ -6,6 +6,7 @@ RUN apt-get update && apt-get install -y \
6
  git \
7
  libgl1 \
8
  libglib2.0-0 \
 
9
  libsm6 \
10
  libxext6 \
11
  libxrender-dev \
@@ -27,9 +28,13 @@ ENV HF_HUB_ENABLE_HF_TRANSFER=1 \
27
  CELERY_RESULT_BACKEND=redis://localhost:6379/1
28
 
29
  # Step 3. Download models for caching
 
30
  RUN python -c "from huggingface_hub import snapshot_download; snapshot_download('zeyadcode/ov_owlv2_model', local_dir='./models/ov_owlv2_model')"
31
  RUN python -c "from ultralytics import SAM; import os; os.chdir('./models'); SAM('mobile_sam.pt')"
32
  RUN python -c "from transformers import AutoProcessor; AutoProcessor.from_pretrained('google/owlv2-base-patch16-ensemble')"
 
 
 
33
 
34
  # Step 4: Copy the rest of the application
35
  COPY . .
 
6
  git \
7
  libgl1 \
8
  libglib2.0-0 \
9
+ libgomp1 \
10
  libsm6 \
11
  libxext6 \
12
  libxrender-dev \
 
28
  CELERY_RESULT_BACKEND=redis://localhost:6379/1
29
 
30
  # Step 3. Download models for caching
31
+ RUN mkdir -p ./models
32
  RUN python -c "from huggingface_hub import snapshot_download; snapshot_download('zeyadcode/ov_owlv2_model', local_dir='./models/ov_owlv2_model')"
33
  RUN python -c "from ultralytics import SAM; import os; os.chdir('./models'); SAM('mobile_sam.pt')"
34
  RUN python -c "from transformers import AutoProcessor; AutoProcessor.from_pretrained('google/owlv2-base-patch16-ensemble')"
35
+ RUN python -c "from simple_lama_inpainting import SimpleLama; SimpleLama()"
36
+ RUN python -c "from optimum.intel import OVStableDiffusionXLInpaintPipeline; pipe = OVStableDiffusionXLInpaintPipeline.from_pretrained('stabilityai/sdxl-turbo', export=True, device='CPU'); pipe.reshape(batch_size=1, height=512, width=512, num_images_per_prompt=1); pipe.save_pretrained('./models/ov_sdxl_turbo_inpaint')"
37
+
38
 
39
  # Step 4: Copy the rest of the application
40
  COPY . .
config.py CHANGED
@@ -25,7 +25,10 @@ DETECTOR_OUT_PATH = "detector_boxes.json"
25
 
26
  INPAINTOR_OUT_PATH = "inpainted.png"
27
 
28
- INPAINTOR_MODEL_NAME = "stabilityai/stable-diffusion-xl-base-1.0"
 
 
 
29
 
30
  CELERY_BROKER_URL = os.getenv("CELERY_BROKER_URL", "redis://localhost:6379/0")
31
  CELERY_RESULT_BACKEND = os.getenv("CELERY_RESULT_BACKEND", "redis://localhost:6379/1")
 
25
 
26
  INPAINTOR_OUT_PATH = "inpainted.png"
27
 
28
+ INPAINTOR_MODEL_NAME = "stabilityai/sdxl-turbo"
29
+ INPAINTOR_MODEL_PATH = Path(os.getenv("INPAINTOR_MODEL_PATH", "models/ov_sdxl_turbo_inpaint"))
30
+ INPAINTOR_DEVICE = os.getenv("INPAINTOR_DEVICE", "CPU")
31
+ INPAINTOR_IMAGE_SIZE = 512
32
 
33
  CELERY_BROKER_URL = os.getenv("CELERY_BROKER_URL", "redis://localhost:6379/0")
34
  CELERY_RESULT_BACKEND = os.getenv("CELERY_RESULT_BACKEND", "redis://localhost:6379/1")
main.py CHANGED
@@ -10,7 +10,7 @@ import shutil
10
  import tasks as tasks
11
  from celery.result import AsyncResult
12
  import config as config
13
- from schemas import SegmentRequest
14
  from services import job_lifecycle
15
 
16
  job_lifecycle.ensure_upload_dir()
@@ -85,9 +85,19 @@ async def segment_objects(job_id: str, data: SegmentRequest):
85
 
86
 
87
  @app.post("/process/inpaint/{job_id}")
88
- async def inapint(job_id, prompt: str = Form(...)):
89
  tasks.celery_app.backend.delete(f"celery-task-meta-{job_id}")
90
- tasks.inpaint.apply_async(args=[job_id, prompt], task_id=job_id)
 
 
 
 
 
 
 
 
 
 
91
 
92
 
93
  if __name__ == "__main__":
 
10
  import tasks as tasks
11
  from celery.result import AsyncResult
12
  import config as config
13
+ from schemas import InpaintRequest, SegmentRequest
14
  from services import job_lifecycle
15
 
16
  job_lifecycle.ensure_upload_dir()
 
85
 
86
 
87
  @app.post("/process/inpaint/{job_id}")
88
+ async def inpaint(job_id: str, data: InpaintRequest):
89
  tasks.celery_app.backend.delete(f"celery-task-meta-{job_id}")
90
+ tasks.inpaint.apply_async(
91
+ args=[
92
+ job_id,
93
+ data.mode,
94
+ data.positive_prompt,
95
+ data.negative_prompt,
96
+ data.num_inference_steps,
97
+ ],
98
+ task_id=job_id,
99
+ )
100
+ return job_id
101
 
102
 
103
  if __name__ == "__main__":
requirements.txt CHANGED
@@ -10,13 +10,17 @@ opencv-python-headless
10
  Pillow
11
 
12
  # Hugging Face & Model Hub
 
13
  huggingface-hub
14
  hf-transfer
 
15
  transformers
16
 
17
  # Model Execution Frameworks
18
  openvino
19
  optimum
20
  optimum-intel
 
 
21
  ultralytics
22
- simple-lama-inpainting
 
10
  Pillow
11
 
12
  # Hugging Face & Model Hub
13
+ diffusers
14
  huggingface-hub
15
  hf-transfer
16
+ safetensors
17
  transformers
18
 
19
  # Model Execution Frameworks
20
  openvino
21
  optimum
22
  optimum-intel
23
+ torch
24
+ torchvision
25
  ultralytics
26
+ simple-lama-inpainting
schemas/__init__.py CHANGED
@@ -1 +1,2 @@
1
- from .segment_request import SegmentRequest
 
 
1
+ from .segment_request import SegmentRequest
2
+ from .inpaint_request import InpaintRequest
schemas/inpaint_request.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Literal
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+
6
+ class InpaintRequest(BaseModel):
7
+ mode: Literal["blur", "remove", "diffusion"] = "blur"
8
+ positive_prompt: str = ""
9
+ negative_prompt: str = ""
10
+ num_inference_steps: int = Field(default=4, ge=4, le=15)
services/model_manager.py CHANGED
@@ -3,6 +3,7 @@ from ultralytics import SAM
3
  import openvino as ov
4
  import config as config
5
  from optimum.intel import OVStableDiffusionXLInpaintPipeline
 
6
 
7
 
8
  def get_detector_model(MODELS: dict):
@@ -29,16 +30,30 @@ def get_segmentor_model(MODELS: dict):
29
 
30
  def get_inpaintor_model(MODELS: dict):
31
  if MODELS['inpaintor'] is None:
32
- MODELS['inpaintor'] = OVStableDiffusionXLInpaintPipeline.from_pretrained(
33
- config.INPAINTOR_MODEL_NAME,
34
- device="CPU" # or "GPU"
 
35
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  return MODELS['inpaintor']
37
 
38
  def get_removing_model(MODELS: dict):
39
- if MODELS['obj_remove'] is None:
40
- MODELS['obj_remove'] = OVStableDiffusionXLInpaintPipeline.from_pretrained(
41
- config.INPAINTOR_MODEL_NAME,
42
- device="CPU" # or "GPU"
43
- )
44
- return MODELS['obj_remove']
 
3
  import openvino as ov
4
  import config as config
5
  from optimum.intel import OVStableDiffusionXLInpaintPipeline
6
+ from simple_lama_inpainting import SimpleLama
7
 
8
 
9
  def get_detector_model(MODELS: dict):
 
30
 
31
  def get_inpaintor_model(MODELS: dict):
32
  if MODELS['inpaintor'] is None:
33
+ model_source = (
34
+ config.INPAINTOR_MODEL_PATH
35
+ if config.INPAINTOR_MODEL_PATH.exists()
36
+ else config.INPAINTOR_MODEL_NAME
37
  )
38
+ kwargs = {"device": config.INPAINTOR_DEVICE}
39
+ if model_source == config.INPAINTOR_MODEL_NAME:
40
+ kwargs["export"] = True
41
+
42
+ pipe = OVStableDiffusionXLInpaintPipeline.from_pretrained(
43
+ str(model_source),
44
+ **kwargs,
45
+ )
46
+ pipe.reshape(
47
+ batch_size=1,
48
+ height=config.INPAINTOR_IMAGE_SIZE,
49
+ width=config.INPAINTOR_IMAGE_SIZE,
50
+ num_images_per_prompt=1,
51
+ )
52
+ pipe.compile()
53
+ MODELS['inpaintor'] = pipe
54
  return MODELS['inpaintor']
55
 
56
  def get_removing_model(MODELS: dict):
57
+ if MODELS['remover'] is None:
58
+ MODELS['remover'] = SimpleLama()
59
+ return MODELS['remover']
 
 
 
tasks.py CHANGED
@@ -15,6 +15,7 @@ MODELS: dict[str, Any] = {
15
  "detector_processor": None,
16
  "segmentor": None,
17
  "inpaintor": None,
 
18
  }
19
 
20
  celery_app = Celery(
@@ -96,30 +97,46 @@ def segment_objects(self, job_id: str, bboxes=None, points=None, point_labels=No
96
 
97
 
98
  @celery_app.task(bind=True)
99
- def inpaint(self, job_id: str, prompt: str, negative_prompt: str = "", num_inference_steps: int = 6, guidance_scale: float = 0.0) -> bool:
 
 
 
 
 
 
 
100
  job_path = config.UPLOAD_DIR / job_id
 
 
 
 
101
  orig_img = Image.open(job_path / config.INPUT_IMG_NAME).convert("RGB")
102
  mask_img = Image.open(job_path / config.SEGMENTOR_OUT_BIN_PATH).convert("L")
103
 
104
- mode = "blur"
105
-
106
- if mode == "inpaint":
107
  model = model_manager.get_inpaintor_model(MODELS)
108
- inpainted_img = model(
109
- prompt=prompt,
 
110
  negative_prompt=negative_prompt,
111
- image=orig_img,
112
- mask_image=mask_img,
113
- num_inference_steps=6,
114
  guidance_scale=0.0,
115
  ).images[0]
 
116
 
117
  elif mode == "remove":
118
  model = model_manager.get_removing_model(MODELS)
 
119
 
120
  elif mode == "blur":
121
  result = blur_img_with_mask(orig_img, mask_img)
122
- result.save(job_path / config.INPAINTOR_OUT_PATH)
 
 
 
 
123
 
124
  if self.request.id is None:
125
  return result
@@ -131,18 +148,24 @@ def inpaint(self, job_id: str, prompt: str, negative_prompt: str = "", num_infer
131
  if __name__ == "__main__":
132
  import matplotlib.pyplot as plt
133
 
134
- prompt = "hat"
135
- img = Image.open(config.UPLOAD_DIR / config.DEBUG_JOB_ID / config.INPUT_IMG_NAME)
136
 
137
  # %%
138
- detection_res = detect_objects(job_id=config.DEBUG_JOB_ID, prompt=prompt)
139
- plot_groundingdino_boxes(img, detection_res)
140
 
141
  # %%
142
- segment_res = segment_objects.run(job_id=config.DEBUG_JOB_ID, bboxes=detection_res["boxes"])
143
 
144
  # %%
145
- inpainted_res = inpaint(job_id=config.DEBUG_JOB_ID, prompt="red hat high quality", negative_prompt="blurry, messy, bad looking", num_inference_steps=4, guidance_scale=0)
 
 
 
 
 
 
146
 
147
  # %%
148
  img = segment_res.plot()
 
15
  "detector_processor": None,
16
  "segmentor": None,
17
  "inpaintor": None,
18
+ "remover": None,
19
  }
20
 
21
  celery_app = Celery(
 
97
 
98
 
99
  @celery_app.task(bind=True)
100
+ def inpaint(
101
+ self,
102
+ job_id: str,
103
+ mode: str = "blur",
104
+ positive_prompt: str = "",
105
+ negative_prompt: str = "",
106
+ num_inference_steps: int = 4,
107
+ ) -> bool:
108
  job_path = config.UPLOAD_DIR / job_id
109
+ save_path = job_path / config.INPAINTOR_OUT_PATH
110
+ if save_path.exists():
111
+ save_path.unlink()
112
+
113
  orig_img = Image.open(job_path / config.INPUT_IMG_NAME).convert("RGB")
114
  mask_img = Image.open(job_path / config.SEGMENTOR_OUT_BIN_PATH).convert("L")
115
 
116
+ if mode == "diffusion":
 
 
117
  model = model_manager.get_inpaintor_model(MODELS)
118
+ model_size = (config.INPAINTOR_IMAGE_SIZE, config.INPAINTOR_IMAGE_SIZE)
119
+ generated = model(
120
+ prompt=positive_prompt,
121
  negative_prompt=negative_prompt,
122
+ image=orig_img.resize(model_size),
123
+ mask_image=mask_img.resize(model_size, Image.Resampling.NEAREST),
124
+ num_inference_steps=num_inference_steps,
125
  guidance_scale=0.0,
126
  ).images[0]
127
+ result = generated.resize(orig_img.size)
128
 
129
  elif mode == "remove":
130
  model = model_manager.get_removing_model(MODELS)
131
+ result = model(orig_img, mask_img)
132
 
133
  elif mode == "blur":
134
  result = blur_img_with_mask(orig_img, mask_img)
135
+
136
+ else:
137
+ raise ValueError(f"Unsupported inpaint mode: {mode}")
138
+
139
+ result.convert("RGB").save(save_path)
140
 
141
  if self.request.id is None:
142
  return result
 
148
  if __name__ == "__main__":
149
  import matplotlib.pyplot as plt
150
 
151
+ # prompt = "hat"
152
+ # img = Image.open(config.UPLOAD_DIR / config.DEBUG_JOB_ID / config.INPUT_IMG_NAME)
153
 
154
  # %%
155
+ # detection_res = detect_objects(job_id=config.DEBUG_JOB_ID, prompt=prompt)
156
+ # plot_groundingdino_boxes(img, detection_res)
157
 
158
  # %%
159
+ # segment_res = segment_objects.run(job_id=config.DEBUG_JOB_ID, bboxes=detection_res["boxes"])
160
 
161
  # %%
162
+ inpainted_res = inpaint(
163
+ job_id=config.DEBUG_JOB_ID,
164
+ mode="diffusion",
165
+ positive_prompt="red hat high quality",
166
+ negative_prompt="blurry, messy, bad looking",
167
+ num_inference_steps=4,
168
+ )
169
 
170
  # %%
171
  img = segment_res.plot()