Fix avg_llm_latency ATIF evaluator always reporting 0.0 - #2140
Fix avg_llm_latency ATIF evaluator always reporting 0.0#2140AnishPatel526 wants to merge 4 commits into
Conversation
…writes (NVIDIA#2116) Signed-off-by: Anish Patel <abpatel1@unc.edu>
WalkthroughThe ATIF average LLM latency evaluator now prioritizes invocation epoch timestamps, falls back to legacy timestamps, skips invalid timing data, and includes regression tests for invocation timing and non-finite values. ChangesATIF latency evaluation
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@packages/nvidia_nat_profiler/src/nat/plugins/profiler/runtime_evaluator/atif_evaluate.py`:
- Around line 37-48: Update the docstring of _step_llm_latency to remove the
rejected “NAT” term, replacing it with “the ATOF-to-ATIF converter” or the
approved full product name while preserving the existing meaning.
- Around line 80-82: Update the evaluator class docstring near the latency
aggregation logic to document the new timing precedence: use extra["invocation"]
when available, fall back to span_event_timestamp, and skip steps only when
neither timing source exists.
- Around line 52-55: Update the timestamp validation in the invocation duration
evaluation to reject non-finite values and integers that cannot be safely
converted to float before calling float(start) or float(end). Skip such
invocations rather than computing a score, while preserving the existing
non-negative duration behavior for valid finite timestamps.
In `@packages/nvidia_nat_profiler/tests/profiler/test_runtime_evaluator_atif.py`:
- Around line 122-126: Update the docstring of
test_evaluate_atif_item_uses_invocation_timing so its opening sentence is
concise and ends with a period, and format the avg_llm_latency identifier with
backticks. Preserve the test’s existing meaning and regression context.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: fa37b017-cb84-4eb4-bf28-ed48528318d4
📒 Files selected for processing (2)
packages/nvidia_nat_profiler/src/nat/plugins/profiler/runtime_evaluator/atif_evaluate.pypackages/nvidia_nat_profiler/tests/profiler/test_runtime_evaluator_atif.py
Signed-off-by: Anish Patel <abpatel1@unc.edu>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/nvidia_nat_profiler/tests/profiler/test_runtime_evaluator_atif.py (1)
122-146: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winTest invocation-timing precedence explicitly.
This verifies that invocation timestamps work, but not that they take precedence over legacy timing. Add a conflicting
extra["span_event_timestamp"]value and keep the expected latency at3.5; otherwise a fallback-first implementation could still pass this regression test.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/nvidia_nat_profiler/tests/profiler/test_runtime_evaluator_atif.py` around lines 122 - 146, Update test_evaluate_atif_item_uses_invocation_timing to include a conflicting extra["span_event_timestamp"] value alongside extra["invocation"], while keeping the expected latency and reasoning assertions at 3.5 and one call. This must verify that invocation timing takes precedence over legacy span-event timing.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/nvidia_nat_profiler/tests/profiler/test_runtime_evaluator_atif.py`:
- Around line 149-154: Update the docstring of
test_evaluate_atif_item_skips_non_finite_invocation_timing to match the cases
actually exercised: either add a large-integer overflow scenario to the test or
remove the “and overflowing” claim, while preserving the existing NaN and inf
coverage.
---
Nitpick comments:
In `@packages/nvidia_nat_profiler/tests/profiler/test_runtime_evaluator_atif.py`:
- Around line 122-146: Update test_evaluate_atif_item_uses_invocation_timing to
include a conflicting extra["span_event_timestamp"] value alongside
extra["invocation"], while keeping the expected latency and reasoning assertions
at 3.5 and one call. This must verify that invocation timing takes precedence
over legacy span-event timing.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 9a1fe0de-be7e-4470-b5fa-7feb22d0e167
📒 Files selected for processing (2)
packages/nvidia_nat_profiler/src/nat/plugins/profiler/runtime_evaluator/atif_evaluate.pypackages/nvidia_nat_profiler/tests/profiler/test_runtime_evaluator_atif.py
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/nvidia_nat_profiler/src/nat/plugins/profiler/runtime_evaluator/atif_evaluate.py
…DIA#2116) Signed-off-by: Anish Patel <abpatel1@unc.edu>
|
This is a non-breaking bug fix ( |
|
Hi! Just wanted to follow up on this contribution! |
|
I checked this independently against The key the evaluator reads cannot legally exist. Both converters emit the
That second one is the crisp statement of the bug: The open question — which producer does this actually unblock? The loop skips steps before it ever looks at timing: if step.source != "agent" or not step.metrics:
continue
None of that argues against merging — the timing lookup is wrong either way and the fallback keeps the legacy shape working. It does suggest the description would be more accurate pointing at One small note on the fallback: it's keyed on AI-assisted review. The contract, converter and evaluator code above were read on |
|
Updated the description to point at nat/utils/atif_converter.py as the path this fixes, and added a note that the ATOF-script producer (atof_to_atif_converter.py) emits no metrics so its steps stay at 0.0, worth a separate follow-up. Thanks again for the diagnosis! |
Fix avg_llm_latency ATIF evaluator always reporting 0.0
Reference Issues/PRs
Closes #2116.
What does this implement/fix? Explain your changes.
AverageLLMLatencyAtifEvaluatorcomputed per-step LLM latency fromstep.extra["span_event_timestamp"](an ISO start paired withstep.timestampas the end). That key never exists on a converted ATIF step:
Step.extraisbuilt through
AtifStepExtra, which isConfigDict(extra="forbid")and definesonly
ancestry/invocation/ tool fields.span_event_timestampis a fieldon the pre-conversion
IntermediateStep.payload, not on the post-conversionStep.extra. So the evaluator was reading a pre-conversion field name off apost-conversion object and always found nothing, leaving
latenciesempty andthe score
0.0.The converter folds that pre-conversion field into the invocation timing:
nat/utils/atif_converter.py::_atif_invocation_from_istsetsinvocation.start_timestamp = ist.payload.span_event_timestamp(epoch seconds),and the emitted step carries
metrics=pending.metrics, so it clears theevaluator's
if step.source != "agent" or not step.metrics: continueguard.That is the path this PR fixes.
Fix
Read the timing the converter actually writes. A new helper
_step_llm_latencyprefers
step.extra["invocation"](end_timestamp - start_timestamp), rejectsnon-finite / overflowing values, and falls back to the legacy
span_event_timestamp+step.timestamppair so any producer emitting thatshape (and the existing tests for it) keeps working. Steps with neither source
are skipped rather than scored as a spurious zero.
Before / after
For a real converted ATIF agent step:
span_event_timestampabsent (and forbidden by the schema) ->latencies == []->score == 0.0.invocationused ->score == 3.5.The legacy
span_event_timestamppath is unchanged (still5.0for theexisting 5-second fixture).
Known follow-up (out of scope here)
The ATOF-script converter
atof_to_atif_converter.pyemitsinvocationtimingbut sets no
metrics, so its steps are dropped by the evaluator'snot step.metricsguard and would still score0.0after this change, for aseparate reason. Worth a follow-up issue; this PR does not attempt to change
that producer.
Testing
Added tests in
packages/nvidia_nat_profiler/tests/profiler/test_runtime_evaluator_atif.py:test_evaluate_atif_item_uses_invocation_timinguses the converter's realextra["invocation"]shape (with a conflictingspan_event_timestamppresentto prove
invocationtakes precedence) and asserts a non-zero average. Itfails on
develop(score0.0) and passes with this change.test_evaluate_atif_item_skips_non_finite_invocation_timingcovers NaN, inf,and an integer too large to convert to float.
The existing
span_event_timestamptests continue to pass via the fallback.ruff checkandruff formatare clean on both changed files.Checklist