Skip to content

Commit eaa98a7

Browse files
anandhu-engclaude
andauthored
fix: skip truncation for endpoints submissions instead of targeting stale results.json (#2631)
The endpoints accuracy artifact was renamed from results.json (with a responses field) to accuracy/accuracy_results.json in mlcommons/endpoints#400, which also dropped the responses field entirely (per-sample text now lives in events.jsonl, not part of the submission). truncate_accuracy_log.py still looked for the old results.json/responses shape and would only log "missing" for every endpoints submission. Detect the endpoints layout via the scenario-root config.yaml and skip truncation, and remove the now-dead PERFORMANCE_ENDPOINTS_DIR/ACCURACY_ENDPOINTS_DIR constants left over from the loader.py refactor to ENDPOINTS_SCENARIO_DIR. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
1 parent 5ae81f7 commit eaa98a7

2 files changed

Lines changed: 14 additions & 102 deletions

File tree

tools/submission/submission_checker/constants.py

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2036,14 +2036,6 @@
20362036
"deepseek-r1"
20372037
]
20382038

2039-
PERFORMANCE_ENDPOINTS_DIR = {
2040-
"v5.0": "{division}/{submitter}/results/{system}/{benchmark}/{scenario}/performance/run_1/",
2041-
"v5.1": "{division}/{submitter}/results/{system}/{benchmark}/{scenario}/performance/run_1/",
2042-
"v6.0": "{division}/{submitter}/results/{system}/{benchmark}/{scenario}/performance/run_1/",
2043-
"v6.1": "{division}/{submitter}/results/{system}/{benchmark}/{scenario}/performance/run_1/",
2044-
"default": "{division}/{submitter}/results/{system}/{benchmark}/{scenario}/performance/run_1/",
2045-
}
2046-
20472039
ENDPOINTS_SCENARIO_DIR = {
20482040
"v5.0": "{division}/{submitter}/results/{system}/{benchmark}/{scenario}/",
20492041
"v5.1": "{division}/{submitter}/results/{system}/{benchmark}/{scenario}/",
@@ -2076,15 +2068,6 @@
20762068
"default": "{division}/{submitter}/results/{system}/{benchmark}/{scenario}/accuracy/mlperf_log_accuracy.json",
20772069
}
20782070

2079-
ACCURACY_ENDPOINTS_DIR = {
2080-
"v5.0": "{division}/{submitter}/results/{system}/{benchmark}/{scenario}/accuracy/",
2081-
"v5.1": "{division}/{submitter}/results/{system}/{benchmark}/{scenario}/accuracy/",
2082-
"v6.0": "{division}/{submitter}/results/{system}/{benchmark}/{scenario}/accuracy/",
2083-
"v6.1": "{division}/{submitter}/results/{system}/{benchmark}/{scenario}/accuracy/",
2084-
"default": "{division}/{submitter}/results/{system}/{benchmark}/{scenario}/accuracy/",
2085-
}
2086-
2087-
20882071
POWER_DIR_PATH = {
20892072
"v5.0": "{division}/{submitter}/results/{system}/{benchmark}/{scenario}/performance/power",
20902073
"v5.1": "{division}/{submitter}/results/{system}/{benchmark}/{scenario}/performance/power",

tools/submission/truncate_accuracy_log.py

Lines changed: 14 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
MAX_ACCURACY_LOG_SIZE = 10 * 1024
2020
VIEWABLE_SIZE = 4096
21-
RESPONSES_LIMIT = 10 * 1024 # cap on truncated responses bytes
2221

2322
HELP_TEXT = """
2423
You can run this tool in 2 ways:
@@ -124,84 +123,18 @@ def copy_submission_dir(src, dst, filter_submitter):
124123
)
125124

126125

127-
def _truncate_endpoints_results(results_path, acc_path, backup):
128-
"""Truncate the ``responses`` field in an endpoints accuracy results.json.
126+
def _is_endpoints_submission(scenario_dir):
127+
"""Detect the endpoints submission layout via its scenario-root config.yaml.
129128
130-
Mirrors the behaviour of truncate_accuracy_log.py for traditional
131-
submissions: backs up the original file (when --backup is given),
132-
computes a SHA-256 hash of the original, appends ``hash=<hex>`` to
133-
accuracy.txt, then writes back a copy with responses capped at
134-
RESPONSES_LIMIT bytes.
129+
Endpoints submissions have no mlperf_log_accuracy.json; the accuracy
130+
artifact they produce (accuracy/accuracy_results.json) carries no large
131+
per-sample payload to truncate, so callers should skip truncation
132+
entirely rather than look for a file to shrink.
135133
"""
136-
try:
137-
with open(results_path, "r", encoding="utf-8") as f:
138-
original_bytes = f.read().encode()
139-
data = json.loads(original_bytes)
140-
except Exception as exc:
141-
log.error("Could not read %s: %s", results_path, exc)
142-
return
143-
144-
# Back up before any modification.
145-
if backup:
146-
backup_dir = os.path.join(backup, acc_path)
147-
os.makedirs(backup_dir, exist_ok=True)
148-
dst = os.path.join(backup_dir, "results.json")
149-
if os.path.exists(dst):
150-
log.error(
151-
"not processing %s because %s already exists",
152-
results_path,
153-
dst,
154-
)
155-
return
156-
shutil.copy(results_path, dst)
157-
158-
# Hash the original file for audit purposes (mirrors accuracy.txt hash
159-
# written for traditional mlperf_log_accuracy.json truncation).
160-
hash_val = hashlib.sha256(original_bytes).hexdigest()
161-
acc_txt = os.path.join(acc_path, "accuracy.txt")
162-
with open(acc_txt, "a", encoding="utf-8") as f:
163-
f.write("\nhash={0}\n".format(hash_val))
164-
165-
# Truncate the responses collection so the file stays small.
166-
responses = data.get("responses")
167-
if responses is None or (isinstance(
168-
responses, (list, dict)) and not responses):
169-
log.info("%s has no responses to truncate", results_path)
170-
return
171-
172-
if isinstance(responses, list):
173-
total = 2 # "[]"
174-
idx = 0
175-
for i, r in enumerate(responses):
176-
total += len(json.dumps(r).encode()) + (2 if i > 0 else 0)
177-
if total > RESPONSES_LIMIT:
178-
break
179-
idx = i + 1
180-
data["responses"] = responses[:idx]
181-
elif isinstance(responses, dict):
182-
total = 2 # "{}"
183-
kept = {}
184-
for i, (k, v) in enumerate(responses.items()):
185-
entry = len(json.dumps(k).encode()) + \
186-
len(json.dumps(v).encode()) + 2
187-
if i > 0:
188-
entry += 2
189-
if total + entry > RESPONSES_LIMIT:
190-
break
191-
total += entry
192-
kept[k] = v
193-
data["responses"] = kept
194-
else:
195-
log.error(
196-
"%s: responses has unexpected type %s; skipping truncation",
197-
results_path,
198-
type(responses).__name__,
199-
)
200-
return
201-
202-
with open(results_path, "w", encoding="utf-8") as f:
203-
json.dump(data, f, indent=2)
204-
log.info("%s responses truncated", results_path)
134+
return any(
135+
os.path.exists(os.path.join(scenario_dir, name))
136+
for name in ("config.yaml", "config.yml")
137+
)
205138

206139

207140
def truncate_results_dir(filter_submitter, backup, scenarios_to_skip):
@@ -264,14 +197,10 @@ def truncate_results_dir(filter_submitter, backup, scenarios_to_skip):
264197
acc_txt = os.path.join(
265198
acc_path, "accuracy.txt")
266199
if not os.path.exists(acc_log):
267-
# Endpoints submissions have results.json
268-
# instead of mlperf_log_accuracy.json
269-
endpoints_results = os.path.join(
270-
acc_path, "results.json"
271-
)
272-
if os.path.exists(endpoints_results):
273-
_truncate_endpoints_results(
274-
endpoints_results, acc_path, backup
200+
if _is_endpoints_submission(name):
201+
log.info(
202+
"%s is an endpoints submission; nothing to truncate",
203+
name,
275204
)
276205
else:
277206
log.error("%s missing", acc_log)

0 commit comments

Comments
 (0)