BADRzs commited on
Commit
152acf8
·
verified ·
1 Parent(s): 8cd0fb1

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. app.py +16 -49
  2. detectors/itsnotai.py +10 -2
  3. requirements.txt +0 -5
app.py CHANGED
@@ -201,8 +201,13 @@ def analyze_forensics(
201
  verdict_html += "</div>"
202
 
203
  # Overlay Image (Original + Heatmap)
204
- overlay_img = explainability.get("overlay")
205
- if overlay_img is None:
 
 
 
 
 
206
  overlay_img = image
207
 
208
  # Consensus Table
@@ -252,15 +257,18 @@ def analyze_forensics(
252
  # ─────────────────────────────────────────────────────────────────────────────
253
  # Interactive Forensic Investigator Chat (Multi-turn)
254
  # ─────────────────────────────────────────────────────────────────────────────
255
- async def chat_investigator_fn(message: str, history: List[Dict[str, str]], context: Dict[str, Any]):
256
- if not message.strip():
257
- return history, ""
258
 
259
  messages = []
260
  if history:
261
  for msg in history:
262
  if isinstance(msg, dict):
263
  messages.append({"role": msg.get("role", "user"), "content": msg.get("content", "")})
 
 
 
264
  messages.append({"role": "user", "content": message})
265
 
266
  result = await chat_with_forensic_context(
@@ -366,7 +374,7 @@ with gr.Blocks(title="DeepGuard — Forensic Detection") as demo:
366
  gr.Markdown("### 🕵️ Interactive Forensic Investigator Chat")
367
  gr.Markdown("Inquire deeper into model decision boundaries, specific attention zones, or contradictory detector signals.")
368
 
369
- chatbot = gr.Chatbot(height=320, label="DeepGuard Forensic Investigator")
370
  with gr.Row():
371
  chat_input = gr.Textbox(
372
  placeholder="Ask about this image's verdict, Grad-CAM peaks, or provenance flags...",
@@ -395,47 +403,6 @@ with gr.Blocks(title="DeepGuard — Forensic Detection") as demo:
395
 
396
 
397
  # ─────────────────────────────────────────────────────────────────────────────
398
- # FastAPI REST API mounting (Allows direct HTTP /predict & /chat requests)
399
  # ─────────────────────────────────────────────────────────────────────────────
400
- api_app = FastAPI(title="DeepGuard REST API", version="1.0.0")
401
- api_app.add_middleware(
402
- CORSMiddleware,
403
- allow_origins=["*"],
404
- allow_credentials=True,
405
- allow_methods=["*"],
406
- allow_headers=["*"],
407
- )
408
-
409
-
410
- @api_app.get("/health")
411
- async def health():
412
- return {
413
- "status": "ok",
414
- "service": "DeepGuard HF Space (ZeroGPU)",
415
- "device": str(DEVICE),
416
- "zerogpu": has_spaces,
417
- }
418
-
419
-
420
- class ChatRequest(BaseModel):
421
- message: str
422
- history: Optional[List[Dict[str, str]]] = []
423
- forensic_context: Dict[str, Any]
424
-
425
-
426
- @api_app.post("/chat")
427
- async def api_chat(req: ChatRequest):
428
- messages = list(req.history or [])
429
- messages.append({"role": "user", "content": req.message})
430
- result = await chat_with_forensic_context(
431
- messages=messages,
432
- forensic_context=req.forensic_context,
433
- )
434
- return {"reply": result.get("reply", "")}
435
-
436
-
437
- # Mount Gradio onto FastAPI
438
- app = gr.mount_gradio_app(api_app, demo, path="/")
439
-
440
- if __name__ == "__main__":
441
- demo.launch()
 
201
  verdict_html += "</div>"
202
 
203
  # Overlay Image (Original + Heatmap)
204
+ heatmap_bytes = explainability.get("heatmap_bytes")
205
+ if heatmap_bytes:
206
+ try:
207
+ overlay_img = Image.open(io.BytesIO(heatmap_bytes))
208
+ except Exception:
209
+ overlay_img = image
210
+ else:
211
  overlay_img = image
212
 
213
  # Consensus Table
 
257
  # ─────────────────────────────────────────────────────────────────────────────
258
  # Interactive Forensic Investigator Chat (Multi-turn)
259
  # ─────────────────────────────────────────────────────────────────────────────
260
+ async def chat_investigator_fn(message: str, history: Optional[List[Any]], context: Dict[str, Any]):
261
+ if not message or not message.strip():
262
+ return history or [], ""
263
 
264
  messages = []
265
  if history:
266
  for msg in history:
267
  if isinstance(msg, dict):
268
  messages.append({"role": msg.get("role", "user"), "content": msg.get("content", "")})
269
+ elif isinstance(msg, (list, tuple)) and len(msg) >= 2:
270
+ messages.append({"role": "user", "content": str(msg[0])})
271
+ messages.append({"role": "assistant", "content": str(msg[1])})
272
  messages.append({"role": "user", "content": message})
273
 
274
  result = await chat_with_forensic_context(
 
374
  gr.Markdown("### 🕵️ Interactive Forensic Investigator Chat")
375
  gr.Markdown("Inquire deeper into model decision boundaries, specific attention zones, or contradictory detector signals.")
376
 
377
+ chatbot = gr.Chatbot(height=320, label="DeepGuard Forensic Investigator", type="messages")
378
  with gr.Row():
379
  chat_input = gr.Textbox(
380
  placeholder="Ask about this image's verdict, Grad-CAM peaks, or provenance flags...",
 
403
 
404
 
405
  # ─────────────────────────────────────────────────────────────────────────────
406
+ # Launch ZeroGPU Space
407
  # ─────────────────────────────────────────────────────────────────────────────
408
+ demo.queue(default_concurrency_limit=5).launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
detectors/itsnotai.py CHANGED
@@ -160,5 +160,13 @@ class ItsNotAIDetector(BaseDetector):
160
 
161
  def get_gradcam_target_layer(self) -> torch.nn.Module:
162
  self._ensure_loaded()
163
- # In HuggingFace BeitModel, transformer blocks are stored in beit.layers
164
- return self._model.beit.layers[-1].mlp
 
 
 
 
 
 
 
 
 
160
 
161
  def get_gradcam_target_layer(self) -> torch.nn.Module:
162
  self._ensure_loaded()
163
+ if hasattr(self._model, "beit"):
164
+ beit = self._model.beit
165
+ if hasattr(beit, "encoder") and hasattr(beit.encoder, "layer") and len(beit.encoder.layer) > 0:
166
+ layer = beit.encoder.layer[-1]
167
+ return getattr(layer, "output", layer)
168
+ if hasattr(beit, "layers") and len(beit.layers) > 0:
169
+ layer = beit.layers[-1]
170
+ return getattr(layer, "mlp", layer)
171
+ children = list(self._model.children())
172
+ return children[-2] if len(children) >= 2 else children[-1]
requirements.txt CHANGED
@@ -1,7 +1,5 @@
1
  gradio>=5.0.0
2
  transformers
3
- torch
4
- torchvision
5
  Pillow
6
  numpy
7
  matplotlib
@@ -13,6 +11,3 @@ scikit-learn
13
  grad-cam
14
  scipy
15
  peft
16
- fastapi
17
- python-multipart
18
- uvicorn
 
1
  gradio>=5.0.0
2
  transformers
 
 
3
  Pillow
4
  numpy
5
  matplotlib
 
11
  grad-cam
12
  scipy
13
  peft