Repository navigation
Conversation
|
nice. the (id, epoch) primitive is the right shape and the 27s/20s -> 0.11s win on the K=200/N=50k subset is convincing - that's the O(K) vs O(K*N) central-directory cost showing up clearly. three minor things:
the "partial |
|
Thanks, this is a great review. 2 (string-id): added a test — 3 (concurrency): added a docstring note. One small correction to the premise while I was in there — 1 (validate=False): agreed — that's the composition that makes partial And yes — summaries → find incomplete → |
…amples_by_id Addresses review feedback on UKGovernmentBEIS#4183: cover the custom string sample.id path (previously only int ids were tested) and document the concurrency model (shared AsyncZipReader, central directory parsed once, independent byte-range reads per sample; concurrency bounds in-flight reads).
2f4a0eb to
e240ce7
Compare
…amples_by_id Addresses review feedback on UKGovernmentBEIS#4183: cover the custom string sample.id path (previously only int ids were tested) and document the concurrency model (shared AsyncZipReader, central directory parsed once, independent byte-range reads per sample; concurrency bounds in-flight reads).
Reading a subset of samples from a large .eval log currently requires either read_eval_log (parses every sample) or a loop of read_eval_log_sample (which rebuilds the AsyncZipReader and re-parses the zip central directory on every call -> O(K*N)). Add read_eval_log_samples_by_id / _async to fetch only the requested (id, epoch) samples concurrently over a single shared reader. Composes with exclude_fields; preserves request order. For a 50k-sample log, fetching 200 samples drops from ~20s (sequential loop) / ~27s (full read) to ~0.11s. Refs UKGovernmentBEIS#2873
…amples_by_id Addresses review feedback on UKGovernmentBEIS#4183: cover the custom string sample.id path (previously only int ids were tested) and document the concurrency model (shared AsyncZipReader, central directory parsed once, independent byte-range reads per sample; concurrency bounds in-flight reads).
e240ce7 to
ccea589
Compare
WatchTree-19
left a comment
There was a problem hiding this comment.
the rebase + expanded test coverage looks good, and deferring validate=False until the per-sample-cost PR lands is the right call - keeps the two shapes from cross-contaminating. lgtm.
WatchTree-19
left a comment
There was a problem hiding this comment.
the two adds look right: the string-id test confirms _sample_filename consistency across id types, and the docstring note correctly flags that concurrency bounds the fetch + parse, not parse-only. and yes, deferring the validate=False kwarg until Option 1 lands keeps the two PRs from racing on the same signature.
can wire the partial-eval-retry consumer (summaries to incomplete sample ids to read_eval_log_samples_by_id) as a follow-up once both this and Option 1 merge. ping on either thread if useful.
LGTM, ready to merge from my side.
Added functions to read evaluation log samples concurrently by ID and epoch.
* Add read_eval_log_samples_by_id for concurrent subset reads (#4183) * Add read_eval_log_samples_by_id for concurrent subset reads Reading a subset of samples from a large .eval log currently requires either read_eval_log (parses every sample) or a loop of read_eval_log_sample (which rebuilds the AsyncZipReader and re-parses the zip central directory on every call -> O(K*N)). Add read_eval_log_samples_by_id / _async to fetch only the requested (id, epoch) samples concurrently over a single shared reader. Composes with exclude_fields; preserves request order. For a 50k-sample log, fetching 200 samples drops from ~20s (sequential loop) / ~27s (full read) to ~0.11s. Refs #2873 * Add string-id test and concurrency docstring note for read_eval_log_samples_by_id Addresses review feedback on #4183: cover the custom string sample.id path (previously only int ids were tested) and document the concurrency model (shared AsyncZipReader, central directory parsed once, independent byte-range reads per sample; concurrency bounds in-flight reads). * Add concurrent sample reading functions to Eval Logs Added functions to read evaluation log samples concurrently by ID and epoch. --------- Co-authored-by: jjallaire <jj.allaire@gmail.com> * fix ruff and mypy issues * don't export async version of read_eval_log_samples_by_id * Update CHANGELOG to remove duplicate log entry Fix duplicate entry for read_eval_log_samples_by_id() in CHANGELOG. --------- Co-authored-by: FugoP <264910004+AgentGymLeader@users.noreply.github.com>
This PR contains:
What is the current behavior? (You can also link to an open issue here)
Reading a subset of samples from a large
.evallog currently has only two options, bothO(N)or worse:read_eval_log(...)parses every sample, and loopingread_eval_log_sample(...)rebuilds theAsyncZipReaderand re-parses the zip central directory on every call (O(K·N)). See #2873.What is the new behavior?
Adds
read_eval_log_samples_by_id(log, samples, *, concurrency=...)(sync) andread_eval_log_samples_by_id_async(...): fetch only the requested(id, epoch)samples, concurrently, over a single sharedAsyncZipReader(central directory parsed once). Reuses the existingread_eval_log_sample_async(reader=...)path; preserves request order; bounds fan-out with a semaphore; composes withexclude_fields; raisesIndexErrorfor a missing(id, epoch).Benchmark (50k-sample
.eval, fetching K=200, concurrency=8, median of 3):read_eval_log+ pick K = 27.3s; sequentialread_eval_log_sampleloop = 20.2s;read_eval_log_samples_by_id= 0.11s (~176x / ~238x).Does this PR introduce a breaking change? (What changes might users need to make in their application due to this PR?)
No — purely additive (two new public functions). No existing API or behavior changes.
Other information:
This is the "read fewer samples" (slicing) piece from #2873, distinct from the per-sample-cost work (
validate=False/orjson, andexclude_fieldsin #3816 / #3990). It does not by itself speed upeval-retryor a fullsamples_df(those touch ~all samples), but it's the building block for a faster partialeval-retry(read summaries → load only the incomplete samples). Opened per @WatchTree-19's suggestion on #2873. Tests intests/log/test_read_samples_by_id.py;make check(ruff + mypy) and thetests/logsuite are clean.