carm5333 commited on
Commit
dbfe3bc
·
verified ·
1 Parent(s): e5d7e07

S185: stop masking killed/bad-score jobs, force Itiqan aggressive everywhere, harden deep-filter

Browse files
Files changed (3) hide show
  1. Dockerfile +4 -0
  2. app.py +15 -6
  3. engine_safaa_v4.py +6 -2
Dockerfile CHANGED
@@ -5,5 +5,9 @@ COPY requirements.txt .
5
  RUN pip install --no-cache-dir -r requirements.txt
6
  COPY . .
7
  RUN chmod +x /app/deep-filter || true
 
 
 
 
8
  EXPOSE 7860
9
  CMD ["python3", "app.py"]
 
5
  RUN pip install --no-cache-dir -r requirements.txt
6
  COPY . .
7
  RUN chmod +x /app/deep-filter || true
8
+ # S184/S185: pre-warm DF3 model into image so runtime never downloads
9
+ RUN ffmpeg -f lavfi -i "anullsrc=r=48000:cl=mono" -t 2 /tmp/df_warm.wav -y 2>/dev/null && \
10
+ /app/deep-filter -o /tmp /tmp/df_warm.wav 2>&1 || true && \
11
+ rm -f /tmp/df_warm.wav /tmp/in.wav
12
  EXPOSE 7860
13
  CMD ["python3", "app.py"]
app.py CHANGED
@@ -49,7 +49,7 @@ DEFAULT_ENGINE = "v11.0"
49
  REF_DIR = BASE / "reference_audio"
50
  CHUNK_SIZE = 4 * 1024 * 1024
51
  MAX_DOWNLOAD_CHUNK = 32 * 1024 * 1024
52
- ENGINE_TIMEOUT = 300 # S173: hard-kill engine after 5 min
53
 
54
  _REF_CACHE = None
55
  _REF_CACHE_TS = 0.0
@@ -342,19 +342,24 @@ def _run_engine(job_id):
342
  "-i", job["in_path"], "-o", _o_path,
343
  "--iterations", "3"]
344
  for rf in ref_files[:3]: cmd += ["--ref", str(rf)]
 
 
345
  proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
346
  stderr=subprocess.STDOUT, text=True)
347
  engine_log = []
348
  # S176: communicate() drains stdout AND enforces timeout atomically.
349
  # The old `for line in proc.stdout:` blocked until process exit,
350
  # making proc.wait(timeout=…) unreachable — silent hangs ate semaphores.
 
351
  try:
352
  _out, _ = proc.communicate(timeout=ENGINE_TIMEOUT)
353
  except subprocess.TimeoutExpired:
354
  proc.kill(); proc.wait()
 
355
  job["engine_error"] = (
356
  f"engine killed after {ENGINE_TIMEOUT}s — possible hang")
357
  _out = ""
 
358
  for line in _out.splitlines():
359
  line = line.strip()
360
  engine_log.append(line)
@@ -380,7 +385,7 @@ def _run_engine(job_id):
380
  if m:
381
  try:
382
  s = float(m.group(1))
383
- if 50.0 <= s <= 100.0:
384
  job["score"] = s; job["progress"] = 95
385
  job["label"] = "حساب النتيجة..."
386
  except Exception: pass
@@ -388,7 +393,8 @@ def _run_engine(job_id):
388
  job["engine_log"] = engine_log
389
  # S173 Bug2: engine wrote to _o_path (may be .wav for safaa)
390
  _out = Path(_o_path)
391
- if _out.exists() and _out.stat().st_size > 0:
 
392
  if _is_safaa and _o_path != job["out_path"]:
393
  subprocess.run(
394
  ["ffmpeg", "-y", "-i", str(_out),
@@ -397,8 +403,10 @@ def _run_engine(job_id):
397
  try: _out.unlink()
398
  except Exception: pass
399
  success = True
400
- else:
401
- job["engine_rc"] = proc.returncode
 
 
402
  except Exception as exc:
403
  job["engine_error"] = str(exc)
404
  if not success:
@@ -418,7 +426,8 @@ def _run_engine(job_id):
418
  return
419
  with JOBS_LOCK:
420
  job["status"] = "done"; job["progress"] = 100; job["label"] = "اكتملت ✓"
421
- if not job.get("score"): job["score"] = 90
 
422
  _add_history(job)
423
  try: Path(job["in_path"]).unlink(missing_ok=True)
424
  except Exception: pass
 
49
  REF_DIR = BASE / "reference_audio"
50
  CHUNK_SIZE = 4 * 1024 * 1024
51
  MAX_DOWNLOAD_CHUNK = 32 * 1024 * 1024
52
+ ENGINE_TIMEOUT = 600 # S185: 300s was killing ~7min recordings mid-pass
53
 
54
  _REF_CACHE = None
55
  _REF_CACHE_TS = 0.0
 
342
  "-i", job["in_path"], "-o", _o_path,
343
  "--iterations", "3"]
344
  for rf in ref_files[:3]: cmd += ["--ref", str(rf)]
345
+ if "itiqan" in str(script).lower():
346
+ cmd.append("--aggressive") # S185: always aggressive, all spaces
347
  proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
348
  stderr=subprocess.STDOUT, text=True)
349
  engine_log = []
350
  # S176: communicate() drains stdout AND enforces timeout atomically.
351
  # The old `for line in proc.stdout:` blocked until process exit,
352
  # making proc.wait(timeout=…) unreachable — silent hangs ate semaphores.
353
+ _timed_out = False
354
  try:
355
  _out, _ = proc.communicate(timeout=ENGINE_TIMEOUT)
356
  except subprocess.TimeoutExpired:
357
  proc.kill(); proc.wait()
358
+ _timed_out = True
359
  job["engine_error"] = (
360
  f"engine killed after {ENGINE_TIMEOUT}s — possible hang")
361
  _out = ""
362
+ job["engine_rc"] = proc.returncode # S185: always recorded
363
  for line in _out.splitlines():
364
  line = line.strip()
365
  engine_log.append(line)
 
385
  if m:
386
  try:
387
  s = float(m.group(1))
388
+ if 0.0 <= s <= 100.0: # S185: was 50-100, hid real bad scores
389
  job["score"] = s; job["progress"] = 95
390
  job["label"] = "حساب النتيجة..."
391
  except Exception: pass
 
393
  job["engine_log"] = engine_log
394
  # S173 Bug2: engine wrote to _o_path (may be .wav for safaa)
395
  _out = Path(_o_path)
396
+ _clean = (not _timed_out) and proc.returncode == 0 # S185
397
+ if _clean and _out.exists() and _out.stat().st_size > 0:
398
  if _is_safaa and _o_path != job["out_path"]:
399
  subprocess.run(
400
  ["ffmpeg", "-y", "-i", str(_out),
 
403
  try: _out.unlink()
404
  except Exception: pass
405
  success = True
406
+ elif not _clean:
407
+ # S185: killed or non-zero rc — don't trust a partial file,
408
+ # force the real ffmpeg fallback instead of faking success
409
+ job["engine_error"] = job.get("engine_error") or f"engine exited rc={proc.returncode}"
410
  except Exception as exc:
411
  job["engine_error"] = str(exc)
412
  if not success:
 
426
  return
427
  with JOBS_LOCK:
428
  job["status"] = "done"; job["progress"] = 100; job["label"] = "اكتملت ✓"
429
+ if job.get("score") is None and not job.get("used_fallback"):
430
+ job["score"] = 90 # S185: only on a clean, non-fallback run
431
  _add_history(job)
432
  try: Path(job["in_path"]).unlink(missing_ok=True)
433
  except Exception: pass
engine_safaa_v4.py CHANGED
@@ -573,8 +573,12 @@ def _df3(wav, samples, rt60, st):
573
  r2 = subprocess.run(cmd, capture_output=True, timeout=600)
574
  wp = os.path.join(od, 'in.wav')
575
  if r2.returncode or not os.path.exists(wp):
576
- _L(st, f' [S4-ADF] {cls} pass failed — using source')
577
- return cls, mono.copy()
 
 
 
 
578
  arr = _df3_pipe_decode(wp, SR)
579
  if arr is None:
580
  _L(st, f' [S4-ADF] {cls} decode failed — using source')
 
573
  r2 = subprocess.run(cmd, capture_output=True, timeout=600)
574
  wp = os.path.join(od, 'in.wav')
575
  if r2.returncode or not os.path.exists(wp):
576
+ _stderr = r2.stderr.decode('utf-8', errors='replace')[:400] if r2.stderr else ''
577
+ _stdout = r2.stdout.decode('utf-8', errors='replace')[:200] if r2.stdout else ''
578
+ _L(st, f' [S4-ADF] {cls} pass failed rc={r2.returncode} cmd={cmd}')
579
+ _L(st, f' [S4-ADF] stderr: {_stderr!r}')
580
+ if _stdout: _L(st, f' [S4-ADF] stdout: {_stdout!r}')
581
+ return cls, mono.copy() # S183/S185: was silent
582
  arr = _df3_pipe_decode(wp, SR)
583
  if arr is None:
584
  _L(st, f' [S4-ADF] {cls} decode failed — using source')