abedgemma commited on
Commit
6de407c
·
verified ·
1 Parent(s): 63fb9e7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +25 -18
app.py CHANGED
@@ -69,11 +69,10 @@ RATE_LIMIT_RPM = int(os.getenv("RATE_LIMIT_RPM", "60"))
69
  RATE_BURST = int(os.getenv("RATE_LIMIT_BURST", "10"))
70
  RATE_VIP_IPS = set(os.getenv("RATE_VIP_IPS", "127.0.0.1").split(","))
71
  # RAM thresholds — auto-calculated as % of total RAM if not set explicitly
72
- _total_ram_gb = __import__('psutil').virtual_memory().total / (1024**3)
73
- # Thresholds: 90/95/98% of total RAM — safe on any machine size
74
- RAM_WARN_GB = float(os.getenv("RAM_WARN_GB", str(round(_total_ram_gb * 0.90, 1))))
75
- RAM_REJECT_GB = float(os.getenv("RAM_REJECT_GB", str(round(_total_ram_gb * 0.95, 1))))
76
- RAM_FLUSH_GB = float(os.getenv("RAM_FLUSH_GB", str(round(_total_ram_gb * 0.98, 1))))
77
  REQUEST_TIMEOUT = float(os.getenv("REQUEST_TIMEOUT","90.0"))
78
  QUEUE_TIMEOUT = float(os.getenv("QUEUE_TIMEOUT", "30.0"))
79
  ENRICH_TIMEOUT = float(os.getenv("ENRICH_TIMEOUT", "12.0"))
@@ -523,7 +522,12 @@ async def _flush_kv() -> bool:
523
  return False
524
 
525
  async def watchdog_task():
526
- logger.info(f"[wd] warn={RAM_WARN_GB}G reject={RAM_REJECT_GB}G flush={RAM_FLUSH_GB}G")
 
 
 
 
 
527
  while True:
528
  try:
529
  await asyncio.sleep(2.0)
@@ -531,9 +535,9 @@ async def watchdog_task():
531
  used = mem.used / (1024**3)
532
  wd.ram_gb = used
533
 
534
- if used >= RAM_FLUSH_GB:
535
  if wd.level != "flush":
536
- logger.warning(f"[wd] 🚨 FLUSH {used:.1f}GB")
537
  wd.level = "flush"; wd.flushes += 1
538
  gc.collect(2)
539
  exact_cache.cleanup()
@@ -543,13 +547,13 @@ async def watchdog_task():
543
  await _flush_kv()
544
  after = psutil.virtual_memory().used / (1024**3)
545
  logger.info(f"[wd] post-flush {after:.1f}GB (freed {used-after:.1f}GB)")
546
- if after < RAM_REJECT_GB: wd.level = "ok"
547
- elif used >= RAM_REJECT_GB:
548
  if wd.level not in ("reject", "flush"):
549
- logger.warning(f"[wd] ⚠ REJECT {used:.1f}GB")
550
  wd.level = "reject"; wd.rejects += 1; gc.collect(1)
551
- elif used >= RAM_WARN_GB:
552
- if wd.level == "ok": logger.info(f"[wd] ⚡ WARN {used:.1f}GB")
553
  wd.level = "warn"
554
  else:
555
  if wd.level != "ok": logger.info(f"[wd] ✅ OK {used:.1f}GB")
@@ -1099,6 +1103,10 @@ async def chat(request: Request) -> Response | StreamingResponse:
1099
  headers={"X-Request-ID":rid,"X-Cache":"SEMANTIC-HIT"})
1100
 
1101
  # Build payload
 
 
 
 
1102
  payload: dict = {
1103
  "messages": messages,
1104
  "cache_prompt": True,
@@ -1109,12 +1117,11 @@ async def chat(request: Request) -> Response | StreamingResponse:
1109
  "top_k": int(body.get("top_k", 20)),
1110
  "min_p": float(body.get("min_p", 0.0)),
1111
  "stream": is_stream,
 
 
1112
  }
1113
- if body.get("thinking") is True:
1114
- payload["chat_template_kwargs"] = {"enable_thinking": True}
1115
  payload["reasoning_budget"] = int(body.get("thinking_budget", 4096))
1116
- elif body.get("thinking") is False:
1117
- payload["chat_template_kwargs"] = {"enable_thinking": False}
1118
  if body.get("tools"):
1119
  payload["tools"] = body["tools"]
1120
  payload["tool_choice"] = body.get("tool_choice", "auto")
@@ -1592,4 +1599,4 @@ if __name__ == "__main__":
1592
  import uvicorn
1593
  uvicorn.run("app:app", host="0.0.0.0",
1594
  port=int(os.getenv("API_PORT","7860")),
1595
- loop="uvloop", http="h11", workers=1)
 
69
  RATE_BURST = int(os.getenv("RATE_LIMIT_BURST", "10"))
70
  RATE_VIP_IPS = set(os.getenv("RATE_VIP_IPS", "127.0.0.1").split(","))
71
  # RAM thresholds — auto-calculated as % of total RAM if not set explicitly
72
+ # RAM thresholds computed dynamically in watchdog_task() based on actual machine RAM
73
+ RAM_WARN_GB = float(os.getenv("RAM_WARN_GB", "0")) # 0 = auto 82% of total RAM
74
+ RAM_REJECT_GB = float(os.getenv("RAM_REJECT_GB", "0")) # 0 = auto 90% of total RAM
75
+ RAM_FLUSH_GB = float(os.getenv("RAM_FLUSH_GB", "0")) # 0 = auto 95% of total RAM
 
76
  REQUEST_TIMEOUT = float(os.getenv("REQUEST_TIMEOUT","90.0"))
77
  QUEUE_TIMEOUT = float(os.getenv("QUEUE_TIMEOUT", "30.0"))
78
  ENRICH_TIMEOUT = float(os.getenv("ENRICH_TIMEOUT", "12.0"))
 
522
  return False
523
 
524
  async def watchdog_task():
525
+ # Compute dynamic thresholds based on actual machine RAM
526
+ _total = psutil.virtual_memory().total / (1024**3)
527
+ _warn = RAM_WARN_GB if RAM_WARN_GB > 0 else round(_total * 0.82, 1)
528
+ _reject = RAM_REJECT_GB if RAM_REJECT_GB > 0 else round(_total * 0.90, 1)
529
+ _flush = RAM_FLUSH_GB if RAM_FLUSH_GB > 0 else round(_total * 0.95, 1)
530
+ logger.info(f"[wd] total={_total:.1f}G warn={_warn}G reject={_reject}G flush={_flush}G")
531
  while True:
532
  try:
533
  await asyncio.sleep(2.0)
 
535
  used = mem.used / (1024**3)
536
  wd.ram_gb = used
537
 
538
+ if used >= _flush:
539
  if wd.level != "flush":
540
+ logger.warning(f"[wd] 🚨 FLUSH {used:.1f}/{_total:.0f}GB")
541
  wd.level = "flush"; wd.flushes += 1
542
  gc.collect(2)
543
  exact_cache.cleanup()
 
547
  await _flush_kv()
548
  after = psutil.virtual_memory().used / (1024**3)
549
  logger.info(f"[wd] post-flush {after:.1f}GB (freed {used-after:.1f}GB)")
550
+ if after < _reject: wd.level = "ok"
551
+ elif used >= _reject:
552
  if wd.level not in ("reject", "flush"):
553
+ logger.warning(f"[wd] ⚠ REJECT {used:.1f}/{_total:.0f}GB")
554
  wd.level = "reject"; wd.rejects += 1; gc.collect(1)
555
+ elif used >= _warn:
556
+ if wd.level == "ok": logger.info(f"[wd] ⚡ WARN {used:.1f}/{_total:.0f}GB")
557
  wd.level = "warn"
558
  else:
559
  if wd.level != "ok": logger.info(f"[wd] ✅ OK {used:.1f}GB")
 
1103
  headers={"X-Request-ID":rid,"X-Cache":"SEMANTIC-HIT"})
1104
 
1105
  # Build payload
1106
+ # Thinking mode OFF by default — Qwen3 thinks for EVERY request otherwise
1107
+ # User must explicitly pass "thinking": true to enable reasoning
1108
+ thinking_requested = body.get("thinking", False)
1109
+
1110
  payload: dict = {
1111
  "messages": messages,
1112
  "cache_prompt": True,
 
1117
  "top_k": int(body.get("top_k", 20)),
1118
  "min_p": float(body.get("min_p", 0.0)),
1119
  "stream": is_stream,
1120
+ # Always set thinking explicitly to avoid Qwen3 auto-enabling it
1121
+ "chat_template_kwargs": {"enable_thinking": bool(thinking_requested)},
1122
  }
1123
+ if thinking_requested:
 
1124
  payload["reasoning_budget"] = int(body.get("thinking_budget", 4096))
 
 
1125
  if body.get("tools"):
1126
  payload["tools"] = body["tools"]
1127
  payload["tool_choice"] = body.get("tool_choice", "auto")
 
1599
  import uvicorn
1600
  uvicorn.run("app:app", host="0.0.0.0",
1601
  port=int(os.getenv("API_PORT","7860")),
1602
+ loop="uvloop", http="h11", workers=1)