perf(ebook-search): run phrase detection in parallel with retrieval
Move protected phrase detection into the retrieval gather so it runs concurrently with vector and BM25 candidates instead of sequentially before them. Make the search API accept real bool form fields for rerank/phrase_matching, gate phrase matching on both the request and config kill switch, and reflow log f-strings for readability.
This commit is contained in:
@@ -688,14 +688,14 @@ def extract_phrase_candidates_for_book(
|
||||
raw_started_at = perf_counter()
|
||||
raw = extract_raw_ngrams_by_chapter(chapters, config)
|
||||
logger.info(
|
||||
f"ebook_phrase_candidate_extract_raw_complete candidates={len(raw)} duration_ms={(perf_counter() - "
|
||||
f"raw_started_at) * 1000:.1f}"
|
||||
f"ebook_phrase_candidate_extract_raw_complete candidates={len(raw)} "
|
||||
f"duration_ms={(perf_counter() - raw_started_at) * 1000:.1f}"
|
||||
)
|
||||
yake_started_at = perf_counter()
|
||||
yake_candidates = extract_yake_candidates(book_text, config)
|
||||
logger.info(
|
||||
f"ebook_phrase_candidate_extract_yake_complete candidates={len(yake_candidates)} duration_ms={(perf_counter() - "
|
||||
f"yake_started_at) * 1000:.1f}"
|
||||
f"ebook_phrase_candidate_extract_yake_complete candidates={len(yake_candidates)} "
|
||||
f"duration_ms={(perf_counter() - yake_started_at) * 1000:.1f}"
|
||||
)
|
||||
capitalized_started_at = perf_counter()
|
||||
capitalized = extract_capitalized_phrases(book_text, config)
|
||||
@@ -728,7 +728,8 @@ def extract_phrase_candidates_for_book(
|
||||
f"ebook_phrase_candidate_extract_complete raw={len(raw)} yake={len(yake_candidates)} "
|
||||
f"capitalized={len(capitalized)} metadata={len(metadata_candidates)} {pre_filter_count=} {filtered_too_short=} "
|
||||
f"{filtered_too_rare=} {filtered_too_common=} {filtered_junk=} min_uses={minimum_candidate_raw_count(config)} "
|
||||
f"storable={len(candidates)} limited={len(limited)} enrich_score_ms={(perf_counter() - enriched_started_at) * "
|
||||
f"1000:.1f} duration_ms={(perf_counter() - started_at) * 1000:.1f}"
|
||||
f"storable={len(candidates)} limited={len(limited)} "
|
||||
f"enrich_score_ms={(perf_counter() - enriched_started_at) * 1000:.1f} "
|
||||
f"duration_ms={(perf_counter() - started_at) * 1000:.1f}"
|
||||
)
|
||||
return limited
|
||||
|
||||
@@ -68,8 +68,8 @@ async def generate_candidate_phrases_for_books(
|
||||
source_ids = (await session.scalars(source_query)).all()
|
||||
books_seen = len(source_ids)
|
||||
logger.info(
|
||||
f"ebook_candidate_phrase_generation_start {books_seen=} {config.phrase_min_tokens=} {config.phrase_max_tokens=} "
|
||||
f"{config.protected_phrase_max_candidates_per_book=}"
|
||||
f"ebook_candidate_phrase_generation_start {books_seen=} {config.phrase_min_tokens=} "
|
||||
f"{config.phrase_max_tokens=} {config.protected_phrase_max_candidates_per_book=}"
|
||||
)
|
||||
|
||||
pool = get_extraction_pool(config.protected_phrase_extraction_workers)
|
||||
@@ -244,8 +244,8 @@ async def generate_candidate_phrases_for_book(
|
||||
await session.rollback()
|
||||
raise
|
||||
logger.info(
|
||||
f"ebook_candidate_phrase_generation_book_duration {book_id=} {saved_count=} duration_ms={(perf_counter() - "
|
||||
f"started_at) * 1000:.1f}"
|
||||
f"ebook_candidate_phrase_generation_book_duration {book_id=} {saved_count=} "
|
||||
f"duration_ms={(perf_counter() - started_at) * 1000:.1f}"
|
||||
)
|
||||
return saved_count
|
||||
|
||||
@@ -289,7 +289,7 @@ async def store_candidate_phrases_for_book(
|
||||
)
|
||||
saved_count = await bulk_upsert_unjudged_candidates(session, book_id, series_id, limited_candidates)
|
||||
logger.info(
|
||||
f"ebook_candidate_phrase_save_complete {book_id=} {saved_count=} save_ms={(perf_counter() - save_started_at) * "
|
||||
f"1000:.1f}"
|
||||
f"ebook_candidate_phrase_save_complete {book_id=} {saved_count=} "
|
||||
f"save_ms={(perf_counter() - save_started_at) * 1000:.1f}"
|
||||
)
|
||||
return saved_count
|
||||
|
||||
Reference in New Issue
Block a user