feat(semdedup): bound pairwise precision and memory - #2318
feat(semdedup): bound pairwise precision and memory#2318praateekmahajan wants to merge 6 commits into
Conversation
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
|
🌿 Preview your docs: https://nvidia-preview-praateekm-nmcur-318-semdedup-pairwise-precision.docs.buildwithfern.com/nemo/curator Here are the markdown pages you've updated: |
44c3013 to
5586523
Compare
| return None | ||
|
|
||
|
|
||
| def release_cached_gpu_memory() -> None: |
There was a problem hiding this comment.
@ayushdg can you review this, to see if it's not sloppy? I'm wondering if we can then also add this in the minhash teardown part
d63a7f3 to
cd18cc1
Compare
|
/ok to test cd18cc1 |
|
/ok to test bcb544b |
| eps: Epsilon value for duplicate identification threshold (cosine_sim >= 1-eps) | ||
| which_to_keep: Strategy for ranking within clusters ("hard", "easy", "random") | ||
| pairwise_batch_size: Batch size for pairwise similarity computation | ||
| pairwise_compute_dtype: Multiplication precision used by Pairwise |
There was a problem hiding this comment.
nit: Should we rename this to precision?
There was a problem hiding this comment.
Can do it but I think it could become ambiguous.
KMeans outputs FP32 or 16 and this one can perform matmul in FP32 or 16, both of which are "precision" args.
ayushdg
left a comment
There was a problem hiding this comment.
At a high level the concept makes sense to me. Just had high level questions & few nits
| return None | ||
|
|
||
|
|
||
| def release_cached_gpu_memory(*, reset_owned_rmm_pool: bool = False) -> None: |
There was a problem hiding this comment.
Not an expert on memory stuff but I know there's a way to ask cupy and possibly torch to re-use the same rmm pool being used by cudf. Not sure if we use that or if that needs to be handled separately.
Signed-off-by: Praateek <praateekm@gmail.com>
Signed-off-by: Praateek <praateekm@gmail.com>
Signed-off-by: Praateek <praateekm@gmail.com>
Signed-off-by: Praateek <praateekm@gmail.com>
Signed-off-by: Praateek <praateekm@gmail.com>
Signed-off-by: Praateek <praateekm@gmail.com>
| """Make Torch allocate from the RMM resource already used by cuDF and CuPy.""" | ||
| torch.cuda.memory.change_current_allocator(rmm_torch_allocator) | ||
|
|
||
| def process(self, task: FileGroupTask) -> FileGroupTask: |
There was a problem hiding this comment.
Nit but do we still need process if we are doing process_batch now?
| except BaseException as exc: | ||
| # An exception's traceback otherwise keeps the unwound _process | ||
| # frame—and its large GPU objects—alive until after this finalizer. | ||
| traceback.clear_frames(exc.__traceback__) |
There was a problem hiding this comment.
Sorry what is the point of this?
| conversion_start = time.perf_counter() | ||
| resolved_compute_dtype = _resolve_compute_dtype(cluster_embeddings, self.compute_dtype) | ||
| storage_was_converted = cluster_embeddings.dtype != resolved_compute_dtype | ||
| cluster_embeddings = cluster_embeddings.to(dtype=resolved_compute_dtype) |
There was a problem hiding this comment.
So you are doing _resolve_compute_dtype and to(dtype=...) here and then again inside pairwise_cosine_similarity_batched? Are they the same thing each time?
| ``B``, ``B`` over ``C``, and so on. For example, consider these normalized | ||
| four-dimensional embeddings:: | ||
|
|
||
| X = A [1.00, 0.00, 0.00, 0.00] |
There was a problem hiding this comment.
This seems like a nice example, is it something we should consider explaining in the docs too?
Summary
Implements NMCUR-318 on current
main:N x Bworkspace with fixed positivepairwise_batch_size(default1024);id,max_id, andcosine_sim_scoreoutput contract;The ranked-neighbor sidecar remains an extension point only. This PR does not implement NMCUR-242 or NMCUR-319.
EOS benchmark
Compared PR commit
5e5b8248with the September 4 main nightly on the 329,774,475-document predict-all workload:The bounded FP32 path reduced Pairwise wall time by 42.9% with an 11-document duplicate-count difference. FP16 remains opt-in pending duplicate-ID analysis; the benchmark indicates substantial performance and storage potential.
The benchmark's original per-cluster custom metrics were under-aggregated across executor task batches. Workflow and Pairwise wall times above are valid; this PR now aggregates the granular phase timings per executor batch and removes the redundant row-count and resolved-batch metrics.
The six-entry precision matrix completed successfully for this analysis. The committed nightly YAML now retains only the two existing SemDedup baseline entries, explicitly configured for the FP32 storage/FP32 compute defaults.
An allocator-only EOS A/B is in progress for both committed SemDedup entries:
pr-2318-2026_09_04__22_24_57_UTC-5d9be38apr-2318-2026_09_04__22_37_45_UTC-fb6bbdbbA local 330,000-row × 768-dimension Pairwise workload reduced peak GPU memory from 31.83 GiB to 3.49 GiB with RMM sharing; its median compute time was about 7% slower, which is why the EOS A/B is being run before drawing a performance conclusion.
Validation
At
fb6bbdbb, usingnvcr.io/nvidian/nemo-curator:nightly-2026-09-04with GPUs 2 and 3 only: