hbatali2020 commited on
Commit
44d28de
ยท
verified ยท
1 Parent(s): f0b6e84

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +80 -41
app.py CHANGED
@@ -1,6 +1,16 @@
 
1
  import sys
2
  import types
3
  import importlib.util
 
 
 
 
 
 
 
 
 
4
  import io
5
  import time
6
  import torch
@@ -10,77 +20,106 @@ from fastapi import FastAPI, HTTPException, UploadFile, File
10
  from fastapi.responses import JSONResponse
11
  from contextlib import asynccontextmanager
12
 
13
- # --- Mock flash_attn (ู†ูุณ ุฎุฏุนุชูƒ ู„ู„ู€ CPU) ---
14
- flash_mock = types.ModuleType("flash_attn")
15
- flash_mock.__version__ = "2.0.0"
16
- flash_mock.__spec__ = importlib.util.spec_from_loader("flash_attn", loader=None)
17
- sys.modules["flash_attn"] = flash_mock
18
- sys.modules["flash_attn.flash_attn_interface"] = types.ModuleType("flash_attn.flash_attn_interface")
19
- sys.modules["flash_attn.bert_padding"] = types.ModuleType("flash_attn.bert_padding")
20
-
21
- # --- ุงู„ู‚ุงุฆู…ุฉ ุงู„ู…ุฎุตุตุฉ ู„ู„ุฌู†ุฏุฑ (ุชุฌู†ุจ ุญุฌุจ ุงู„ุฑุฌุงู„) ---
22
- # ุฃุถูู†ุง ูˆุตู "female" ูˆ "woman" ู„ุชู‚ูŠูŠุฏ ุงู„ุจุญุซ
23
- FORBIDDEN_LABELS = "woman, girl, lady, female hair, female skin, female arm, female hand, female leg, female chest"
24
 
 
25
  MODEL_DATA = {}
26
 
27
  @asynccontextmanager
28
  async def lifespan(app: FastAPI):
29
- print("๐Ÿ“ฅ Loading Florence-2-large for Female Detection...")
30
- MODEL_DATA["processor"] = AutoProcessor.from_pretrained("microsoft/Florence-2-large", trust_remote_code=True)
 
 
 
 
 
31
  MODEL_DATA["model"] = AutoModelForCausalLM.from_pretrained(
32
- "microsoft/Florence-2-large", trust_remote_code=True, attn_implementation="eager"
 
 
 
33
  ).eval()
 
 
34
  yield
 
35
 
36
- app = FastAPI(lifespan=lifespan)
 
 
 
 
 
 
 
 
 
 
37
 
38
  @app.post("/analyze")
39
  async def analyze_image(file: UploadFile = File(...)):
 
 
 
 
40
  try:
41
  image_bytes = await file.read()
42
  image = Image.open(io.BytesIO(image_bytes)).convert("RGB")
43
-
 
 
 
 
 
 
44
  task = "<OPEN_VOCABULARY_DETECTION>"
45
  prompt = f"{task}{FORBIDDEN_LABELS}"
46
-
47
- inputs = MODEL_DATA["processor"](text=prompt, images=image, return_tensors="pt")
48
-
49
  start_time = time.time()
50
  with torch.no_grad():
51
- generated_ids = MODEL_DATA["model"].generate(
52
  input_ids=inputs["input_ids"],
53
  pixel_values=inputs["pixel_values"],
54
  max_new_tokens=512,
55
- num_beams=1
 
56
  )
57
-
58
- generated_text = MODEL_DATA["processor"].batch_decode(generated_ids, skip_special_tokens=False)[0]
59
- parsed_result = MODEL_DATA["processor"].post_process_generation(
60
- generated_text,
61
- task=task,
62
  image_size=(image.width, image.height)
63
  )
64
-
65
- # ุงุณุชุฎุฑุงุฌ ุงู„ู†ุชุงุฆุฌ
66
  results = parsed_result.get(task, {})
67
- detected_objects = results.get('bboxes', [])
68
- detected_labels = results.get('labels', []) # ุงู„ู…ุณู…ูŠุงุช ุงู„ุชูŠ ูˆุฌุฏู‡ุง ุงู„ู†ู…ูˆุฐุฌ
69
-
70
- # ู…ู†ุทู‚ ุงู„ู‚ุฑุงุฑ: ู†ุญุฌุจ ูู‚ุท ุฅุฐุง ูˆุฌุฏ ุดูŠุฆุงู‹ ู…ู† ุงู„ู‚ุงุฆู…ุฉ ุงู„ุฃู†ุซูˆูŠุฉ
71
- decision = "allow"
72
- if len(detected_objects) > 0:
73
- decision = "block"
74
-
75
  return {
76
- "decision": decision,
77
- "detected_count": len(detected_objects),
78
- "found": detected_labels,
79
- "execution_time": round(time.time() - start_time, 2),
 
80
  "status": "success"
81
  }
 
82
  except Exception as e:
83
- return JSONResponse(status_code=500, content={"error": str(e)})
 
84
 
85
  if __name__ == "__main__":
86
  import uvicorn
 
1
+ # โ”€โ”€โ”€ flash_attn Mock ูŠุฌุจ ุฃู† ูŠูƒูˆู† ุฃูˆู„ ุดูŠุก โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
2
  import sys
3
  import types
4
  import importlib.util
5
+
6
+ flash_mock = types.ModuleType("flash_attn")
7
+ flash_mock.__version__ = "2.0.0"
8
+ flash_mock.__spec__ = importlib.util.spec_from_loader("flash_attn", loader=None)
9
+ sys.modules["flash_attn"] = flash_mock
10
+ sys.modules["flash_attn.flash_attn_interface"] = types.ModuleType("flash_attn.flash_attn_interface")
11
+ sys.modules["flash_attn.bert_padding"] = types.ModuleType("flash_attn.bert_padding")
12
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
13
+
14
  import io
15
  import time
16
  import torch
 
20
  from fastapi.responses import JSONResponse
21
  from contextlib import asynccontextmanager
22
 
23
+ # โ”€โ”€โ”€ ุงู„ู‚ุงุฆู…ุฉ ุงู„ุฃู†ุซูˆูŠุฉ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
24
+ FORBIDDEN_LABELS = (
25
+ "woman, girl, lady, female, female hair, female skin, "
26
+ "female arm, female hand, female leg, female chest, "
27
+ "woman face, girl face"
28
+ )
 
 
 
 
 
29
 
30
+ # โ”€โ”€โ”€ ุชุญู…ูŠู„ ุงู„ู†ู…ูˆุฐุฌ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
31
  MODEL_DATA = {}
32
 
33
  @asynccontextmanager
34
  async def lifespan(app: FastAPI):
35
+ print("๐Ÿ“ฅ Loading Florence-2-large...")
36
+ start = time.time()
37
+
38
+ MODEL_DATA["processor"] = AutoProcessor.from_pretrained(
39
+ "microsoft/Florence-2-large",
40
+ trust_remote_code=True
41
+ )
42
  MODEL_DATA["model"] = AutoModelForCausalLM.from_pretrained(
43
+ "microsoft/Florence-2-large",
44
+ torch_dtype=torch.float32, # โ† ุถุฑูˆุฑูŠ ุนู„ู‰ CPU
45
+ trust_remote_code=True,
46
+ attn_implementation="eager"
47
  ).eval()
48
+
49
+ print(f"โœ… Model ready in {time.time()-start:.1f}s")
50
  yield
51
+ MODEL_DATA.clear()
52
 
53
+ # โ”€โ”€โ”€ FastAPI โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
54
+ app = FastAPI(
55
+ title="Female Detection API",
56
+ description="Detects female content in images using Florence-2-large",
57
+ version="1.0.0",
58
+ lifespan=lifespan
59
+ )
60
+
61
+ @app.get("/health")
62
+ def health():
63
+ return {"status": "ok", "model_loaded": "model" in MODEL_DATA}
64
 
65
  @app.post("/analyze")
66
  async def analyze_image(file: UploadFile = File(...)):
67
+ # ุงู„ุชุญู‚ู‚ ู…ู† ู†ูˆุน ุงู„ู…ู„ู
68
+ if not file.content_type.startswith("image/"):
69
+ raise HTTPException(status_code=400, detail="ุงู„ู…ู„ู ู„ูŠุณ ุตูˆุฑุฉ")
70
+
71
  try:
72
  image_bytes = await file.read()
73
  image = Image.open(io.BytesIO(image_bytes)).convert("RGB")
74
+ except Exception as e:
75
+ raise HTTPException(status_code=400, detail=f"ุฎุทุฃ ููŠ ู‚ุฑุงุกุฉ ุงู„ุตูˆุฑุฉ: {str(e)}")
76
+
77
+ try:
78
+ processor = MODEL_DATA["processor"]
79
+ model = MODEL_DATA["model"]
80
+
81
  task = "<OPEN_VOCABULARY_DETECTION>"
82
  prompt = f"{task}{FORBIDDEN_LABELS}"
83
+
84
+ inputs = processor(text=prompt, images=image, return_tensors="pt")
85
+
86
  start_time = time.time()
87
  with torch.no_grad():
88
+ generated_ids = model.generate(
89
  input_ids=inputs["input_ids"],
90
  pixel_values=inputs["pixel_values"],
91
  max_new_tokens=512,
92
+ num_beams=1,
93
+ do_sample=False
94
  )
95
+
96
+ generated_text = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
97
+ parsed_result = processor.post_process_generation(
98
+ generated_text,
99
+ task=task,
100
  image_size=(image.width, image.height)
101
  )
102
+
 
103
  results = parsed_result.get(task, {})
104
+ bboxes = results.get("bboxes", [])
105
+ labels = results.get("labels", [])
106
+ elapsed = round(time.time() - start_time, 2)
107
+
108
+ # โ”€โ”€โ”€ ู…ู†ุทู‚ ุงู„ู‚ุฑุงุฑ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
109
+ decision = "block" if len(bboxes) > 0 else "allow"
110
+
 
111
  return {
112
+ "decision": decision, # allow | block
113
+ "detected_count": len(bboxes),
114
+ "found": labels, # ู…ุง ูˆุฌุฏู‡ ุงู„ู†ู…ูˆุฐุฌ ูุนู„ุงู‹
115
+ "bboxes": bboxes, # ุฅุญุฏุงุซูŠุงุช ุงู„ู…ู†ุงุทู‚ ุงู„ู…ูƒุชุดูุฉ
116
+ "execution_time": elapsed,
117
  "status": "success"
118
  }
119
+
120
  except Exception as e:
121
+ raise HTTPException(status_code=500, detail=f"ุฎุทุฃ ููŠ ุงู„ุงุณุชุฏู„ุงู„: {str(e)}")
122
+
123
 
124
  if __name__ == "__main__":
125
  import uvicorn