Stop conflate_synonyms computing output it then discards - #985
Draft
gaurav wants to merge 3 commits into
Draft
Conversation
conflate_synonyms() drives two of Babel's most expensive rules --
geneprotein_conflated_synonyms (15,719 s, 98 GB max RSS) and
drugchemical_conflated_synonyms (9,949 s), together about 8.5% of the
pipeline's summed rule wall time, both ~99% CPU-bound on one core.
get_logger() defaults to logging.INFO, so logger.debug() output is suppressed
-- but an f-string argument is still evaluated in full before the call. Four
sites were paying for results nobody reads:
- The whole accumulated synonyms_to_conflate structure was serialised with
json.dumps() to feed one suppressed debug line. That structure is what the
98 GB of resident memory is.
- Every output record was serialised twice more for suppressed debug lines,
once with indent=2, on top of the json.dumps() that actually writes it.
- Every input line recomputed a bl_types set over every synonym accumulated
so far for its preferred ID -- quadratic in clique size -- and used it only
in a suppressed debug line. It also rebound `synonym` inside the read loop,
shadowing the loop variable.
- The innermost step 3 loops logged at INFO, one of them formatting an entire
synonym list per synonym.
The remaining logs take lazy %s arguments so nothing is formatted unless the
level is enabled. Measured over the local anatomy build's synonyms and
compendia (bench script not committed; it needs a build tree), with conflation
groups of 2, 8 and 32 members: 1.33x, 3.11x and 1.39x faster, output identical
every time. Those inputs are three orders of magnitude smaller than the real
gene/protein ones, so they do not predict the production figure -- the site
that should dominate there is the whole-structure json.dumps, which scales with
a structure this data barely populates.
Also adds the first tests this function has had. The third one pins a data-loss
bug found while writing them and deliberately left unfixed here, since this
commit is meant to be behaviour-preserving: `ids` (synonymconflation.py:87) is a
one-shot map object, so the outer loop searching for a conflated identifier
consumes it and the inner loop that registers the clique sees only what came
after the match. The matching identifier -- the one the conflation file names
and the one step 3 looks up -- is never registered, so a synonym record keyed on
a non-leader identifier of a conflated clique is silently dropped rather than
merged. Verified identical on origin/main, so it is pre-existing.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The test asserting that conflate_synonyms drops synonyms keyed on a non-leader identifier said the tracking issue was not filed yet. It is now #989, so the invert-when-fixed instruction has something to point at. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
get_logger() defaults to INFO, so debug output is suppressed -- but the f-string argument is evaluated in full before the call. In a per-record loop that makes a suppressed debug line a real cost, and json.dumps() inside one is unbounded. This cost conflate_synonyms a serialisation of the entire accumulated structure behind its 98 GB peak, plus two more per output record, all discarded. It is not obvious from reading the call site, it recurs, and it is cheap to grep for once you know to look -- so it belongs in AGENTS.md next to the logging rule rather than only in this branch's commit message. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
conflate_synonyms()drives two of Babel's most expensive rules —geneprotein_conflated_synonyms(15,719 s, 98 GB max RSS) anddrugchemical_conflated_synonyms(9,949 s) — together about 8.5% of the pipeline's summed rule wall time, both ~99% CPU-bound on one core.get_logger()defaults tologging.INFO, sologger.debug()output is suppressed — but an f-string argument is still evaluated in full before the call. Four sites were paying for results nobody reads.The four sites
:143— the whole accumulatedsynonyms_to_conflatestructure serialised withjson.dumps()to feed one suppressed debug line. That structure is the 98 GB of resident memory.:260-261— every output record serialised twice more for suppressed debug lines, once withindent=2, on top of thejson.dumps()that actually writes it.:135-140— every input line recomputed abl_typesset over every synonym accumulated so far for its preferred ID — quadratic in clique size — and used it only in a suppressed debug line. It also reboundsynonyminside the read loop, shadowing the loop variable.:168,:170,:172-174— the innermost step-3 loops logged at INFO, one of them formatting an entire synonym list per synonym.Remaining logs take lazy
%sarguments so nothing is formatted unless the level is enabled.Measured
Over the local anatomy build's synonyms and compendia, with conflation groups of 2, 8 and 32 members: 1.33×, 3.11× and 1.39× faster, output identical every time.
Those inputs are three orders of magnitude smaller than the real gene/protein ones, so they do not predict the production figure — the site that should dominate there is the whole-structure
json.dumps, which scales with a structure this data barely populates. Worth re-measuring on a real run.Tests, and a pre-existing bug left unfixed
This adds the first tests this function has had. Records are copied verbatim from a local anatomy build; only the conflation file is authored, since a conflation pairing anatomy cliques does not occur in a real build (it stands in for
GeneProtein.txt, same JSONL shape).The third test pins a data-loss bug found while writing them, deliberately left unfixed here because this commit is meant to be behaviour-preserving:
Verified identical on
origin/main, so it is pre-existing. The test asserts the wrong-but-current behaviour with an invert-when-fixed comment, pertests/CLAUDE.md. It needs a tracking issue — I did not file one, and the test comment says so rather than pointing at a number that does not exist.🤖 Generated with Claude Code