fix: Salt failure is a hard error - #406
Conversation
Signed-off-by: Rashid Kaleem <230885705+arekay-nv@users.noreply.github.com>
|
MLCommons CLA bot All contributors have signed the MLCommons CLA ✍️ ✅ |
There was a problem hiding this comment.
Code Review
This pull request introduces early validation for dataset salting during the benchmark setup phase. It adds a validate_saltable method to ensure that all dataset samples are compatible with salting (i.e., they are dictionaries containing a string prompt and no input_tokens) before any subprocesses are spawned. The review feedback highlights a critical bug in validate_saltable where iterating over self.data directly will fail if it is a pandas.DataFrame (as it would iterate over column names instead of rows), and provides a code suggestion to handle this case.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| "salt cannot be applied; KV-cache reuse may not be prevented" | ||
| ) | ||
| return data # unsupported prompt type — skip salting | ||
| return {**data, "prompt": f"[{salt}] {data['prompt']}"} |
There was a problem hiding this comment.
I have 2 questions:
- Have we studied whether or not injecting these query-irrelevant random strings at the beginning affects accuracy in a format-sensitive workload like GPT-OSS that uses harmonize?
- Is it possible to salt a token_ids list by injecting a random list of ints sampled from a set of known tokens that do not represent special markers?
There was a problem hiding this comment.
-
- not yet, we can do that but the goal is to eliminate kv-cache reuse between the warmup and performance by changing the prefix of the user prompt. For something like gpt-oss, we need a haromize aware salting mechanism.
- That is the long term plan - to have each adapter add sensible salt. For now, with the text "prompt" column datasets, we can inject salt, but others require understanding the structure and picking valid tokens.
| for i, sample in enumerate(self.data): | ||
| reason = _salt_violation(sample) | ||
| if reason is not None: | ||
| raise DatasetValidationError( |
There was a problem hiding this comment.
Should have been caught earlier, but that is something to address -
exceptions.py is very poorly designed and only contains bare name aliases for particular failure states.
This construction of error message and _salt_violation should be part of the DatasetValidationError class:
class DatasetValidationError:
ERR_MSG_TEMPLATE = "salt=True requires ... but sample {index} {reason} ..."
def __init__(self, dataset_idx: int, sample: Sample):
self.reason = self._violation_reason(sample)
err_msg = DatasetValidationError.ERR_MSG_TEMPLATE.format(index=dataset_idx, reason=self.reason)
super().__init__(err_msg)
def _violation_reason(self, sample: Sample):
# Body of `_salt_violation` here.
Ideally, reason should be some enum or object rather than a raw string, smth like
class DatasetValidationError:
...
class Reason(Enum):
TypeMismatch = ...
InputTokensShadowing = ...
PromptMissing = ...
PromptTypeMismatch = ...
Other = ...
def fmt_str(self, sample):
<handle conversion to full error reason string>
...
Review Council — PR #406 (3× Claude, depth: thorough)Three independent Claude reviewers (bugs/correctness, design/edge, testing/docs) plus a code-quality pass, deduped and severity-recalibrated. "R" marks issues flagged independently by multiple reviewers. All line numbers verified against HEAD ( Verdict: Solid, focused bug-fix. Fail-fast placement is correct — validation at 🟡 Should fix
🔵 Consider
🧹 Code quality
Convergence: all three reviewers independently landed on the salt-default- |
- Default warmup.salt to False so pre-tokenized (input_tokens) workloads no longer hard-fail on a plain --warmup; the hard error now fires only when salt is explicitly enabled. - Replace raw-string salt-violation reasons with a typed DatasetValidationError.Reason enum plus optional detail; _salt_violation becomes _can_salt returning the enum. UNSPECIFIED covers not-yet-mapped --dataset parse errors. - validate_saltable: assert on unloaded data (no silent skip); clarify the error index is into the loaded post-transform order; document the intentional whole-dataset (fail-on-any-invalid) strictness and the deliberate pre-spawn check. - Tests: unpatched integration coverage (offline/online raise, accuracy-only skip), agentic messages sample, typed-reason assertions; drop brittle index regex. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
What does this PR do?
Makes salt failures a hard error instead of a silent skip. Previously, when
--warmup-saltwas on (the default) but a sample couldn't be salted,Dataset._apply_saltlogged a warning (or silently passed the sample through) and the warmup ran with no cache-busting — the exact condition salt exists to prevent, failing quietly.Now
salt=Truerequires every sample to be adictwith a text (str)promptand noinput_tokens; anything else raisesDatasetValidationErrorat dataset-load time, before any load is issued.Key changes:
Dataset.validate_saltable()— rejects non-dictsamples,input_tokens(pre-tokenized; adapters send these verbatim so a saltedpromptnever reaches the server), missingprompt, and non-strprompt. Error names the offending sample index + remediation._load_datasetswhenwarmup.enabled and warmup.salt, so an unsaltable dataset fails before worker/aggregator subprocesses spawn. Also called fromwith_salt()so the salting mechanism stays self-protecting._apply_saltcollapses to a single dict-merge ({**data, "prompt": f"[{salt}] {data['prompt']}"}) — the multimodal-list handling,input_tokenswarnings, and silent passthroughs are deleted; the contract is guaranteed upstream.promptthat is a list (image/video workloads) or a dataset withinput_tokens(e.g. gpt-oss-120b, DeepSeek-R1 via/v1/completions) will fail warmup instead of silently skipping salt. Fix: set--warmup-salt=false/warmup.salt: false.n_requestssubset would never issue. Stricter than the old per-sample skip; intended by the hard-error design.Type of change
Related issues
Testing
Checklist