lsdf commited on
Commit
6859d9b
·
1 Parent(s): 74af0ae

fix(optimizer): require bert target for each phrase

Browse files

Prevent early BERT stage completion when only one phrase reaches the threshold. The stage now completes only when all tracked phrase scores meet bert_stage_target, and docs reflect the new per-phrase rule.

Made-with: Cursor

docs/FULL_FUNCTIONAL_DOCUMENTATION.md CHANGED
@@ -469,6 +469,9 @@ HTML extraction pipeline:
469
  - hard constraints (не ухудшать критичные метрики сверх допустимого);
470
  - режимы `conservative/balanced/aggressive` задают пороги регрессии;
471
  - решение учитывает и `goal_improved`, и общий `delta_score`.
 
 
 
472
  - `_validate_candidate_text`:
473
  - отклоняет некачественные/спамные кандидаты (дубли слов/сущностей, подозрительные склейки токенов);
474
  - добавляет anti-stuffing фильтр для цели BERT (повторы exact phrase и чрезмерные повторы focus-термов).
 
469
  - hard constraints (не ухудшать критичные метрики сверх допустимого);
470
  - режимы `conservative/balanced/aggressive` задают пороги регрессии;
471
  - решение учитывает и `goal_improved`, и общий `delta_score`.
472
+ - `_is_stage_complete` для `bert`:
473
+ - этап считается завершённым только когда **каждая** отслеживаемая ключевая фраза достигает `bert_stage_target` (проверка по `min(bert_phrase_scores)`);
474
+ - достижение порога одной «сильной» фразой больше не завершает BERT-этап.
475
  - `_validate_candidate_text`:
476
  - отклоняет некачественные/спамные кандидаты (дубли слов/сущностей, подозрительные склейки токенов);
477
  - добавляет anti-stuffing фильтр для цели BERT (повторы exact phrase и чрезмерные повторы focus-термов).
optimizer.py CHANGED
@@ -1328,9 +1328,12 @@ def _stage_primary_progress(stage: str, prev_metrics: Dict[str, Any], next_metri
1328
 
1329
  def _is_stage_complete(stage: str, metrics: Dict[str, Any], bert_stage_target: float = BERT_TARGET_THRESHOLD) -> bool:
1330
  if stage == "bert":
 
 
1331
  scores = [float(v) for v in (metrics.get("bert_phrase_scores") or {}).values()]
1332
- max_phrase = max([0.0] + scores)
1333
- return max_phrase >= float(bert_stage_target)
 
1334
  if stage == "bm25":
1335
  return int(metrics.get("bm25_remove_count", 0)) <= 3
1336
  if stage == "semantic":
 
1328
 
1329
  def _is_stage_complete(stage: str, metrics: Dict[str, Any], bert_stage_target: float = BERT_TARGET_THRESHOLD) -> bool:
1330
  if stage == "bert":
1331
+ # Complete only when all tracked BERT phrase scores meet the threshold.
1332
+ # This enforces per-phrase target behavior (no early exit on one strong phrase).
1333
  scores = [float(v) for v in (metrics.get("bert_phrase_scores") or {}).values()]
1334
+ if not scores:
1335
+ return True
1336
+ return min(scores) >= float(bert_stage_target)
1337
  if stage == "bm25":
1338
  return int(metrics.get("bm25_remove_count", 0)) <= 3
1339
  if stage == "semantic":