feat(contextual): pipeline part 2 — accumulator, streaming, finalize, orchestrator - #36
Draft
scheuclu wants to merge 1 commit into
Draft
Conversation
Part 2/3 of the contextual word-drift pipeline (issue #34). The data path: re-stream FineWeb -> frozen-encoder forward -> on-the-fly per-word contextual centroids -> per-year finalized embeddings. Never stores per-token vectors. - contextual_aggregate.py: ContextualAccumulator holds GPU sum/sumsq/count (fp32, [V,768]). add_batch() finds first-subword positions via word_ids, resolves each word to its shared-vocab id (skipping stopwords/OOV/short/ digits, never folding into <UNK>), and folds the batch in with vectorized index_add_. Atomic npz save/load for resume. - contextual_stream.py: text_to_windows + iter_snapshot_windows re-stream FineWeb (language_score>=0.65, raw text, non-overlapping 128-word windows); run_year batches windows through the encoder into the accumulator, checkpointing after each completed snapshot (config-hash guarded). - contextual_finalize.py: centroid=sum/count, dispersion=Sum(sumsq/count - centroid^2), per-year mean-centering (anisotropy fix) + optional all-but-top-k PCA removal. Writes {year}.npy/_centered/_count/_dispersion. - scripts/contextual_drift.py: orchestrator with --stage {stream,finalize,all}, --smoke/--years/--model/--target-tokens. Resumable; on year completion drops the checkpoint but keeps the partial so finalize can be re-tuned cheaply. Verified via --smoke (2 snapshots/year): - artifacts shape (119466, 768) fp32; stopwords skipped (the=0); OOV skipped. - anisotropy fix works: raw random-pair cosine 0.47 -> centered ~0.000. - resume works: killed after snapshot 1, relaunch resumed at 300k and continued to 600k words; checkpoint deleted + partial kept on completion; --stage finalize re-derives from the partial without re-streaming. The drift stage + local eval land in Part 3 (analysis/contextual_drift.py). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This was referenced Jun 6, 2026
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.
Contextual word-drift pipeline — Part 2/3: accumulation + streaming + finalize + orchestrator
Second slice of the contextual word-drift pipeline (#34). Builds the actual data path: re-stream FineWeb → frozen-encoder forward → on-the-fly per-word contextual centroids → per-year finalized embeddings. Never stores per-token vectors (storage collapses to ~9 GB of partials + ~9 GB of artifacts).
What's here
pipeline/contextual_aggregate.pyContextualAccumulator: preallocated GPUsum[V,H],sumsq[V,H],count[V](fp32).add_batch()finds first-subword positions, resolves each word → shared vocab id (skipping stopwords / OOV / short / digits), and folds the batch in with three vectorizedindex_add_s. Atomicsave_state/load_state(npz).pipeline/contextual_stream.pytext_to_windows+iter_snapshot_windows(re-stream FineWeb,language_score >= 0.65, raw text, non-overlapping 128-word windows) andrun_year()which batches windows → encoder → accumulator, checkpointing after each completed snapshot (atomic npz + json, config-hash guarded).pipeline/contextual_finalize.pyfinalize_year(): centroid = sum/count, dispersion = Σ(sumsq/count − centroid²) (polysemy signal), per-year mean-centering (BERT anisotropy fix) + optional all-but-top-k PCA removal. Writes{year}.npy,_centered.npy,_count.npy,_dispersion.npy.scripts/contextual_drift.py--stage {stream,finalize,all},--smoke,--years,--model,--target-tokens. Resumable (skips finalized{year}.npy, resumes partials). On year completion finalizes + drops the checkpoint but keeps the partial so--stage finalizecan re-tune centering/PCA without re-streaming.The
driftstage (parquet + summary) + local eval land in Part 3 alongsideanalysis/contextual_drift.py.Design notes
word_ids()(vectorized;"mean"is a deferred knob).config_hashover{model, layer, pooling, max_len, min_word_length, use_stopwords}is stored in the checkpoint; resume refuses on mismatch rather than mixing incompatible accumulations.Verification (smoke)
uv run python scripts/contextual_drift.py --smoke --years 2018(2 snapshots, 600k words):Artifact checks (
models/contextual_smoke/2018*):Resume check (kill after snapshot 1, relaunch):
🤖 Generated with Claude Code