Add ray to each benchmarking entry and make sure no benchmarking/script has RayClient - #1593
Conversation
…ent in it Signed-off-by: Praateek <praateekm@gmail.com>
| @@ -187,16 +194,6 @@ def main() -> int: | |||
| rmm_pool_size=args.rmm_pool_size, | |||
| spill_memory_limit=args.spill_memory_limit, | |||
| ) | |||
|
|
|||
| except Exception as e: | |||
| print(f"Benchmark failed: {e}") | |||
| results = { | |||
| "params": vars(args), | |||
| "metrics": { | |||
| "is_success": False, | |||
| }, | |||
| "tasks": [], | |||
| } | |||
| finally: | |||
| write_benchmark_results(results, args.benchmark_results_path) | |||
There was a problem hiding this comment.
Unhandled NameError can propagate past finally
run_exact_duplicate_identification_benchmark() has an internal except Exception block that sets success = False, but it does not define workflow_result when the exception occurs before line 77 (workflow_result = workflow.run(...)). The return at line 118 then references workflow_result, causing a NameError that escapes the inner function.
Previously, the outer except Exception in main() would have caught this and written clean fallback results. With the new try/finally-only pattern, the NameError propagates past finally (fallback results are still written correctly), but main() never returns — it exits via an unhandled Python exception traceback instead of a clean exit code.
If an unambiguous exit code is desired even in this edge case, consider adding a narrow guard in the inner function:
return {
...
"tasks": workflow_result if success else [],
}| ray: | ||
| num_cpus: 64 | ||
| num_gpus: 4 | ||
| enable_object_spilling: false |
There was a problem hiding this comment.
num_gpus: 4 vs actual GPU usage — worth verifying
domain_classification_xenna and embedding_generation_xenna (line 220-223) now both reserve 4 GPUs on the Ray cluster. Neither entry passes a --gpus or similar argument to their scripts, so it isn't immediately obvious how many GPUs the workloads actually consume at runtime.
If these benchmarks only use 1 GPU internally (similar to the audio_fleurs case), 3 GPUs per run are reserved but idle for the entire benchmark duration, potentially blocking other concurrent jobs. It may be worth confirming the per-script GPU allocation before landing this so the reservation matches actual utilisation.
This same concern applies to the embedding_generation_xenna entry at line 220.
There was a problem hiding this comment.
Currently it anyway uses 4 gpus we are just now being explicit it.
| io_percentage = round( | ||
| (task_metrics["jsonl_reader"] + task_metrics["parquet_writer"]) * 100 / sum(task_metrics.values()), 2 | ||
| ) | ||
| reader_key = f"{input_filetype}_reader" |
| requirements: | ||
| # Observed throughput of 2900 docs/sec so we allow a 5% buffer to account for variability | ||
| - metric: throughput_docs_per_sec | ||
| min_value: 2755 |
There was a problem hiding this comment.
One nice thing about throughput requirements is that we don't need to update with numbers GPUs.
| @@ -44,6 +43,7 @@ def run_audio_fleurs_benchmark( # noqa: PLR0913 | |||
| split: str, | |||
| wer_threshold: float, | |||
| gpus: int, | |||
There was a problem hiding this comment.
unrelated to the PR but this arg is confusing IMO. The Cli claims its the number of GPUs to use but actually its the resource requirement for the inference stage
ray: config (num_cpus: 64, num_gpus: 4)to:domain_classification_xennaembedding_generation_xennaaudio_fleursimage_pipeline_benchmark.pymultimodal_mint1t_benchmark.pysuccess_code = 0(should be 1) inarxiv_e2e_pipeline_benchmark.pywhich masked benchmark failures as successesXennaExecutor()inaudio_fleurs_benchmark.pywithsetup_executor()+ --executor CLI arg, consistent with all other benchmark scriptsUnboundLocalErrorcrashes across multiple scripts (exact_dedup_identification,score_filter,modifier,video_pipeline,image_pipeline,fasttext_filter,semdedup_identification,dedup_removal) by initializing variables before conditional/try blocksDescription
Usage
# Add snippet demonstrating usageChecklist