Skip to content

Fix multi-turn traces merging when prefix_caching differs in runtime_args (main) - #53

Closed
aas008 wants to merge 1 commit into
openshift-psap:mainfrom
aas008:fix/prefix-caching-from-runtime-args-main
Closed

aas008 wants to merge 1 commit into
openshift-psap:mainfrom
aas008:fix/prefix-caching-from-runtime-args-main

Conversation

@aas008

@aas008 aas008 commented Jul 10, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Multi-turn benchmark data has prefix_caching = NaN even when runs differ in prefix caching config
  • The differentiating info is in runtime_args (e.g., no-enable-prefix-caching: True vs False)
  • This caused Performance Plots to merge distinct runs into a single zigzag trace

Fix

After existing prefix_caching fillna/astype preprocessing, backfill empty values from runtime_args:

  • no-enable-prefix-caching: True → prefix_caching = "no" (caching OFF)
  • no-enable-prefix-caching: False → prefix_caching = "yes" (caching ON)

Verification

Tested against staging CSV:

  • Before: All 17 multi-turn rows had prefix_caching = NaN
  • After: Rows correctly labeled "no" or "yes" based on runtime_args, producing separate trace keys

Test plan

  • Run ruff check dashboard.py — passes clean
  • Load dashboard and verify multi-turn traces no longer merge into zigzag lines
  • Verify single-turn rows (which already have prefix_caching set) are unaffected

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved dashboard data handling by filling in missing prefix-caching status from available runtime settings.
    • Correctly identifies whether prefix caching is enabled or disabled when the status is not explicitly provided.

…args

Derive prefix_caching from runtime_args when the column is empty.
Multi-turn benchmark data has prefix_caching=NaN even though
no-enable-prefix-caching differs between runs, causing Performance
Plots to merge distinct runs into a single zigzag trace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 10, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

load_data now fills empty prefix_caching values by parsing runtime_args for no-enable-prefix-caching: and mapping its boolean value to "no" or "yes".

Changes

Prefix caching data enrichment

Layer / File(s) Summary
Runtime argument backfill
dashboard.py
Adds parsing of no-enable-prefix-caching: tokens and applies the derived prefix-caching value only to rows with non-null runtime arguments and empty existing values.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main fix: preventing multi-turn trace merging by deriving prefix_caching from runtime_args.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@aas008 aas008 changed the title Fix multi-turn traces merging when prefix_caching differs in runtime_args Fix multi-turn traces merging when prefix_caching differs in runtime_args (main) Jul 10, 2026
@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 0% with 10 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@cf066be). Learn more about missing BASE report.

Files with missing lines Patch % Lines
dashboard.py 0.00% 10 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@          Coverage Diff           @@
##             main     #53   +/-   ##
======================================
  Coverage        ?   3.46%           
======================================
  Files           ?       8           
  Lines           ?    8342           
  Branches        ?       0           
======================================
  Hits            ?     289           
  Misses          ?    8053           
  Partials        ?       0           
Flag Coverage Δ
unittests 3.46% <0.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@aas008
aas008 marked this pull request as draft August 3, 2026 02:24
aas008 added a commit to aas008/performance-dashboard that referenced this pull request Oct 6, 2026
The script emits turn_index right before turns in the output dict.
The README should reflect actual output order, not the RHAIIS schema
field position (which pandas aligns by name on concat anyway).

turn_index: openshift-psap#49, turns: openshift-psap#50, prefix_tokens: openshift-psap#51, prefix_count: openshift-psap#52,
request_type: openshift-psap#53.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
aas008 added a commit to aas008/performance-dashboard that referenced this pull request Oct 6, 2026
The script emits turn_index right before turns in the output dict.
The README should reflect actual output order, not the RHAIIS schema
field position (which pandas aligns by name on concat anyway).

turn_index: openshift-psap#49, turns: openshift-psap#50, prefix_tokens: openshift-psap#51, prefix_count: openshift-psap#52,
request_type: openshift-psap#53.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Harshith-umesh pushed a commit that referenced this pull request Oct 7, 2026
#104)

* Filter out per-turn breakdown rows from multi-turn benchmarks

Forge PR #215 adds per-turn CSV rows alongside aggregate rows for
multi-turn benchmarks. The `turn` column is empty on aggregate rows
and 0/1/2/… on per-turn breakdown rows.

Without this filter, per-turn rows would be mixed into _combos()
grouping and produce duplicate concurrency points, inflated request
counts, and skewed percentiles.

Filter keeps only aggregate rows (turn is empty/NaN). CSVs without
a turn column are unaffected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Rename turn to turn_index to avoid confusion with turns column

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add Turn x-axis option to Performance Plots for multi-turn benchmarks

When per-turn rows are present (from Forge PR #215), a "Turn (Multi-turn)"
option appears in the Select X-Axis dropdown. Selecting it plots turn_index
on x-axis vs any Y-axis metric, with one line per concurrency level.
"Show concurrency up to" filters which lines appear, same as for Concurrency.

Replaces the earlier render_per_turn_breakdown expander with native
integration into the existing plot controls.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* Fix code-review findings in per-turn dashboard integration

Correctness:
- filtered_per_turn_df now uses a shared _apply_filters() function that
  applies all 10 sidebar filters (was missing TP, profile, spec_decoding,
  DP, dataset, prefix_caching, and multi-turn masks)
- per_turn_plot_df run_identifier now includes DP/spec_decoding/prefix_caching
  suffixes so per-turn legend labels match the main-chart labels
- errored_requests/successful_requests column access now guarded; KeyError
  no longer crashes data prep for older CSV schemas
- turn_index astype(float) replaced with pd.to_numeric(errors='coerce') to
  handle non-numeric strings like 'N/A' without crashing
- efficiency_ratio inf guard: replace [inf, -inf] with NaN for TP=0 rows
- output_tok/sec column access now guarded for latency-only schemas

Cleanup:
- Extract _is_turn_view boolean; evaluated once before all branches use it

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* bazinga: fix CI failure on PR #101

Remove orphaned mask variables (tp_mask, dp_mask, custom_mask, etc.)
left behind after refactoring to _apply_filters() — ruff F841 flagged
all 9 as assigned but unused. Run ruff format to fix formatting.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* bazinga: address PR review feedback (#101)

Add turns/prefix_tokens/prefix_count suffixes to per_turn_plot_df
run_identifier so it fully matches filtered_df's run_identifier format.
All six configuration dimensions now included: DP, spec_decoding,
prefix_caching, turns, prefix_tokens, prefix_count.

Addresses coderabbitai comment at line 3845.
The filtered_per_turn_df filter comment is already fixed by _apply_filters().

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* bazinga: address PR review feedback (#101)

Fix turn_index staying float64: filter invalid rows before astype(int)
instead of using reindex() which re-introduces NaN and forces float column.
Turn labels now show 0/1/2 instead of 0.0/1.0/2.0.

Suggested by coderabbitai (comment 4146691396).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* feat: replace Turn x-axis concurrency filter with multiselect

When Turn (Multi-turn) is selected as x-axis, col3 now shows a
Concurrency multiselect (defaulting to the highest value) instead of
the "Show concurrency up to" selectbox. This lets engineers study one
concurrency at a time while making it easy to add more for comparison.

Also fix empty-list isin() bug for mt_turns/mt_prefix_tokens/
mt_prefix_count sidebar filters — empty selection now means no filter
(pass-through) instead of filtering out all data.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* bazinga: address PR review feedback (#101)

Guard per_turn_df["turns"] against missing column using .get() with
default Series(1), matching the pattern already used for prefix_tokens,
prefix_count, spec_decoding, and prefix_caching.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix: include Turn concurrency multiselect in shared URL

Add pp_turn_conc → perf_plots_turn_concurrency to SECTION_FILTER_KEYS
and MULTISELECT_SESSION_KEYS (with NUMERIC_LIST for int parsing) so the
selected concurrency level(s) survive copy-paste URL sharing.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix: decode pp_turn_conc as int not float to match multiselect options

NUMERIC_LIST_SESSION_KEYS converts to float, but the Concurrency
multiselect options are integers. Add INT_LIST_SESSION_KEYS and move
perf_plots_turn_concurrency there so URL-restored selections correctly
match the int options in the widget.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix: push pp_turn_conc to URL directly from fragment

@st.fragment reruns dont trigger the parent encode_filters_to_url,
so the concurrency selection was never written to st.query_params.
Update it inline after the multiselect renders.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix: push all perf-plots URL params from fragment

pp_x, pp_y, pp_conc, and pp_turn_conc are all written directly to
st.query_params after the chart renders, since @st.fragment reruns
do not fire the parent from_dict call. This ensures the URL bar stays
accurate for copy-paste sharing when any of these widgets change.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* feat(manual-import): add turn_index column to manual run CSV output

Add turn_index as empty string for aggregate rows so manually-imported
CSVs are schema-compatible with the dashboard's per-turn logic (PR #101).
Per-turn rows (turn_index=0/1/2) are generated by the Forge pipeline
when request-level turn data is preserved in the benchmark JSON.

Update README: 52 → 53 columns, add turn_index to column table (#7),
clarify that manual import produces aggregate rows only.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix: correct turn_index position in README column table

Row numbering was corrupted by the previous renumber script — TP and
measured concurrency both landed at row 9. Fix: turn_index=7, TP=8,
measured concurrency=9, continuing sequentially to request_type=53.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix: move turn_index adjacent to turns in README column table

The script emits turn_index right before turns in the output dict.
The README should reflect actual output order, not the RHAIIS schema
field position (which pandas aligns by name on concat anyway).

turn_index: #49, turns: #50, prefix_tokens: #51, prefix_count: #52,
request_type: #53.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix: address code-review findings in per-turn dashboard integration

Correctness:
- Guard stale perf_plots_turn_concurrency session state: filter stored
  list to only still-valid values, fall back to max if all stale
  (previously raised StreamlitInvalidValueError when data reloads)
- Add .fillna("?") to run_identifier string concat for accelerator/
  model/version, preventing NaN color labels in plotly turn chart
- Guard else-branch when x_axis='turn_index' but per_turn_plot_df is
  empty — show info message instead of sorting aggregate df by NaN
  turn_index column
- Narrow broad contextlib.suppress(Exception) in URL push block to a
  try/except with a pass, keeping the intent but letting TypeError/
  AttributeError from bad values surface during development

Simplification:
- Factor _str_norm into a proper function shared by both per_turn_df
  and df preprocessing paths — eliminates duplicated logic
- Remove redundant reset_index(drop=True, inplace=True) in filtered
  data section (concat branch already ends with .reset_index)
- Remove double per_turn_plot_df.copy() — plot_label can be assigned
  directly (per_turn_df.copy() earlier in the block is sufficient)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
aas008 added a commit to aas008/performance-dashboard that referenced this pull request Oct 15, 2026
The script emits turn_index right before turns in the output dict.
The README should reflect actual output order, not the RHAIIS schema
field position (which pandas aligns by name on concat anyway).

turn_index: openshift-psap#49, turns: openshift-psap#50, prefix_tokens: openshift-psap#51, prefix_count: openshift-psap#52,
request_type: openshift-psap#53.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@Harshith-umesh

Copy link
Copy Markdown
Member

closing since it's not relevant anymore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants