Skip to content

Port All model furnace features to unified tooling - #128

Merged
openshift-merge-bot[bot] merged 62 commits into
openshift-psap:mainfrom
Harshith-umesh:port/model-furnace-features
Jul 29, 2026
Merged

openshift-merge-bot[bot] merged 62 commits into
openshift-psap:mainfrom
Harshith-umesh:port/model-furnace-features

Conversation

@Harshith-umesh

@Harshith-umesh Harshith-umesh commented Jul 16, 2026 •

Copy link
Copy Markdown
Member

Port model-furnace benchmarking features to forge/rhaiis

This PR ports the full RHAIIS benchmarking, analysis, and notification pipeline from the legacy model-furnace repository into the unified forge tooling, and integrates it with Caliper's postprocessing framework.

What's included

Benchmarking & execution

  • End-to-end RHAIIS test phase: KServe ISVC deployment → GuideLLM warmup → benchmark → result extraction → postprocessing → S3 sync → regression analysis → Slack notifications → cleanup
  • Parallel job isolation: each FournosJob gets a unique vLLM deployment name derived from the FJOB suffix, allowing multiple jobs on the same cluster/namespace without colliding on the same InferenceService
  • Configurable HF_TOKEN injection — secret name driven by benchmarks.guidellm.hf_token_secret config, conditionally injected into K8s job manifests
  • Configurable ISVC labels via a labels dict parameter instead of hardcoded values
  • Robust large-file extraction: oc cp with gzip fallback for benchmarks.json files >70MB that fail with unexpected EOF

Dashboard CSV generation (Caliper integration)

  • Replaced manual benchmarks.json lookup and PSAP payload generation with Caliper's plugin postprocessing pipeline: parse → KPI → CSV export
  • RhaiisParser extends GuideLLMParser with all per-benchmark extra metrics (p1/p999/mean latencies, token counts, throughput, concurrency, request counts)
  • RhaiisKpiHandler emits per-rate-point KPIs covering all 31 dashboard CSV columns
  • RhaiisPlugin.export_kpis_to_csv pivots KPI records into the dashboard CSV schema with correct units (seconds→ms conversion for latency columns)
  • Extra curves sorted by request_rate to match GuideLLM parser ordering, preventing index misalignment
  • _sync_postprocessed_dashboard_csv syncs the generated CSV to S3 and triggers regression checks after Caliper postprocessing

Regression analysis

  • Geometric mean comparison with configurable thresholds per metric
  • compare_runs and run_regression_analysis accept profile_map and metrics as parameters (no RHAIIS-specific code in caliper engine)
  • Standalone analysis mode: download CSV from S3 and run regression without re-running benchmarks

Notifications

  • Slack regression/improvement alerts with TP/DP info and pre-filtered dashboard links
  • Pipeline failure alerts with job metadata (model, TP, version, cluster, error) via topsail bot on psap-rhaiis-alerts channel
  • Non-critical warning collection with summary Slack notification
  • All RHAIIS notifications routed through topsail bot (webhook removed)

AI agent integration

  • Agent connectivity check, analysis request, and follow-up via configurable agent URL

PyTorch profiling pipeline

  • Full profiler workflow ported from model-furnace: verify prerequisites → enable profiler gate → run profiler-gated GuideLLM benchmark → disable gate → copy traces from pod → upload traces to S3
  • verify_profiler_prereqs: checks webhook pod status in vllm-profiler namespace, validates MutatingWebhookConfiguration, TLS secret, and ConfigMap before profiler runs
  • enable_profiler_gate: toggles the vLLM profiler webhook gate annotation on the InferenceService to start/stop trace collection per label
  • copy_profiler_traces: extracts PyTorch profiler trace files from the predictor pod
  • Profiler traces uploaded to S3 (psap-dashboard-data bucket, pytorch-profiles/rhaiis prefix)
  • Configurable profiler rates, max_seconds, labels, and S3 settings via rhaiis.profiler config section
  • Auto-derives profiler label from workload config when not explicitly set
  • When profiler is enabled, ISVC is deployed with vllm-profiler/enabled: "true" label (now configurable via the generic labels dict)

S3 and config

  • S3 bucket, vault, and credentials moved from hardcoded function defaults to rhaiis.s3 config section
  • Dashboard CSV S3 key in caliper.postprocess.csv_dashboard config
  • Vault definitions: psap-forge-dashboard-s3 (generic), consolidated psap-forge-notifications

Cleanup and parallel safety

  • Post-cleanup scoped to current job's FJOB suffix (deletes ISVC, ServingRuntime, Job, Pod, PVC only for the current job)
  • Removed unused webhook functions from core notifications

Review comments addressed

  • Moved RHAIIS-specific code out of caliper/engine and core/notifications into rhaiis/postprocess
  • Extracted analysis functions to orchestration/analysis.py and failure alerts to orchestration/notifications.py
  • Made vault descriptions project-generic
  • Documented enable_profiler_gate script arguments
  • Removed hardcoded DEFAULT_AGENT_URL
  • Removed redundant mode="w+b" from NamedTemporaryFile calls
  • Made ISVC labels configurable via labels dict
  • Moved S3 config from hardcoded Python defaults to config file

Files changed (30 files, +3095 / -400)

Area Key files
Orchestration test_phase.py, analysis.py, notifications.py, ci.py, prepare_rhaiis.py
Postprocessing parser.py, kpis.py, plugin.py, csv_export.py, s3_dashboard.py, regression.py, agent.py
GuideLLM run_guidellm_benchmark/main.py, utils.py, guidellm_job.yaml.j2
KServe deploy_kserve_isvc/main.py, inferenceservice.yaml.j2, servingruntime.yaml.j2
Profiler enable_profiler_gate/main.py, copy_profiler_traces/main.py, verify_profiler_prereqs/main.py
Config config.yaml, config.d/rhaiis.yaml, config.d/workloads.yaml
Caliper engine kpi/analyze.py
Vaults psap-forge-dashboard-s3.yaml

Summary by CodeRabbit

  • New Features
    • Added multi-workload benchmarking with warmup and profiler phases.
    • Added dashboard CSV export plus S3 syncing, including performance-curve KPI support.
    • Added CSV-based regression analysis with optional AI follow-up reports.
    • Added pipeline failure and warning notifications, including Slack alert helpers.
    • Added optional Hugging Face token injection for benchmark jobs.
    • Improved labeling and expanded resource cleanup for generated workloads.
  • Bug Fixes
    • Improved benchmark results retrieval (more resilient file copy/transfer) and relaxed copy-pod readiness timing.

@openshift-ci

openshift-ci Bot commented Jul 16, 2026

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 16, 2026
@coderabbitai

coderabbitai Bot commented Jul 16, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Harshith-umesh, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 58 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 608c4960-5ce0-47cf-b088-500019992cb0

📥 Commits

Reviewing files that changed from the base of the PR and between 5668caf and 3f2ecca.

📒 Files selected for processing (6)
  • projects/rhaiis/orchestration/analysis.py
  • projects/rhaiis/orchestration/ci.py
  • projects/rhaiis/orchestration/notifications.py
  • projects/rhaiis/orchestration/prepare_rhaiis.py
  • projects/rhaiis/orchestration/test_phase.py
  • projects/rhaiis/toolbox/copy_profiler_traces/main.py
📝 Walkthrough

Walkthrough

Adds multi-workload RHAIIS benchmarking with profiler workflows, curve-based KPI exports, S3 dashboard synchronization, regression and AI-agent analysis, pipeline notifications, and improved GuideLLM credential and result handling.

Changes

RHAIIS benchmarking and regression pipeline

Layer / File(s) Summary
Benchmark credentials and result transfer
projects/guidellm/toolbox/run_guidellm_benchmark/...
Adds optional Hugging Face token injection, expands copy-pod readiness, and retrieves result files through direct copy with compressed fallback handling.
Performance data and regression outputs
projects/rhaiis/postprocess/..., projects/caliper/engine/kpi/analyze.py
Parses performance curves, emits curve-based KPIs, exports and synchronizes dashboard CSVs, compares baseline runs, and formats regression notifications.
Multi-workload and profiler orchestration
projects/rhaiis/orchestration/..., projects/rhaiis/toolbox/..., vaults/psap-forge-dashboard-s3.yaml
Adds multi-workload execution, warmup and profiler phases, prerequisite and gate tools, trace copying, deployment labels, cleanup, configuration, and S3 support.
Analysis agent and pipeline notifications
projects/rhaiis/orchestration/analysis.py, projects/rhaiis/postprocess/agent.py, projects/rhaiis/orchestration/ci.py, projects/rhaiis/orchestration/notifications.py
Adds regression orchestration, streamed agent analysis, HTML reports, and failure or warning notifications.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant test_phase
  participant run_guidellm_benchmark
  participant RhaiisParser
  participant RhaiisPlugin
  participant run_regression_check
  participant run_agent_analysis
  test_phase->>run_guidellm_benchmark: run workload benchmark
  run_guidellm_benchmark-->>test_phase: return benchmark artifacts
  test_phase->>RhaiisParser: parse benchmark metrics and curves
  RhaiisParser->>RhaiisPlugin: emit KPI records
  RhaiisPlugin->>run_regression_check: provide dashboard CSV
  run_regression_check->>run_agent_analysis: analyze severe regressions
Loading

Possibly related PRs

Suggested labels: lgtm

Suggested reviewers: mml-coder

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 47.66% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the PR’s main goal: porting model-furnace/RHAIIS workflows into unified Forge tooling.
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.
✨ 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.

Comment thread projects/llm_d_legacy/testing/config.yaml
Comment thread projects/mcp_gateway/orchestration/config.yaml
Comment thread projects/rhaiis/orchestration/config.d/rhaiis.yaml Outdated
Comment thread projects/rhaiis/orchestration/config.d/workloads.yaml
Comment thread projects/rhaiis/orchestration/config.yaml Outdated
Comment thread projects/rhaiis/orchestration/test_phase.py Outdated
Comment thread projects/rhaiis/orchestration/test_phase.py Outdated
Comment thread projects/rhaiis/postprocess/agent.py Outdated
Comment thread projects/rhaiis/postprocess/s3_dashboard.py Outdated
Comment thread projects/rhaiis/toolbox/deploy_kserve_isvc/templates/inferenceservice.yaml.j2 Outdated
Comment thread projects/rhaiis/toolbox/enable_profiler_gate/main.py
Comment thread vaults/psap-forge-dashboard-s3.yaml Outdated
Comment thread vaults/psap-forge-rhaiis-slack.yaml Outdated
Comment thread projects/caliper/engine/kpi/analyze.py Outdated
Comment thread projects/core/notifications/send.py Outdated
Harshith-umesh and others added 11 commits July 16, 2026 13:27
- CSV dashboard export (csv_export.py): generates consolidated_dashboard.csv
  from PSAP JSON files matching model-furnace's exact column schema
- S3 sync (s3_dashboard.py): download/append/re-upload consolidated CSV and
  upload profiler traces, using new psap-forge-dashboard-s3 vault
- Regression detection (analyze.py): geometric mean comparison with configurable
  thresholds per metric, ported from model-furnace's compare_results.py
- Slack webhook notifications (send.py): regression/improvement alerts via
  Incoming Webhook (psap-forge-rhaiis-slack vault), with Bot Token fallback
- Profiler toolbox tasks: enable/disable gate, copy traces from pod, and
  verify_profiler_prereqs (webhook pod, TLS, ConfigMap checks)
- Test phase wiring: profiler prereq check → gate toggle → benchmark → trace
  copy → PSAP payload → CSV export → S3 sync → regression analysis → Slack →
  profiler trace upload → MLflow metadata
- Config: new vault definitions, profiler section, csv_dashboard and analyze
  sections in rhaiis config

Co-authored-by: Cursor <cursoragent@cursor.com>
- Fix CSV export to match model-furnace field extraction exactly:
  accelerator parsing, runtime_args formatting, metric key paths,
  raw ms values (no /1000), median/p01 instead of p50/p1, and
  add missing columns (DP, dataset, spec_decoding, etc.)
- Generate a single UUID4 per run and thread it through PSAP payload
  (experiment_id), dashboard CSV (uuid column), predictor log upload
  (logs/{uuid}.log on S3), and regression notifications (job_id)
- Add predictor pod log upload to s3://psap-model-furnace/logs/

Co-authored-by: Cursor <cursoragent@cursor.com>
The openshift-client tarball includes both oc and kubectl, but the
Containerfile was deleting kubectl after extraction. Pipeline tasks
that reference kubectl (e.g. 00-pre-cleanup) fail with exit code 127.

Co-authored-by: Cursor <cursoragent@cursor.com>
- Use gpu_type (e.g. H200) instead of platform name (nvidia) for
  PSAP payload, CSV, and S3 artifact paths
- Exclude warmup benchmarks.json from PSAP payload generation to
  prevent warmup results contaminating the dashboard CSV

Co-authored-by: Cursor <cursoragent@cursor.com>
Track the main benchmark artifact directory explicitly by index
instead of globbing for all benchmarks.json files. Warmup and
profiler benchmark results are no longer included in the PSAP
payload or dashboard CSV.

Co-authored-by: Cursor <cursoragent@cursor.com>
When rhaiis.cluster_tag is set (e.g. "hera2"), the PSAP payload
accelerator_type becomes "H200_HERA2", which csv_export splits
into accelerator=H200 and run=H200-hera2-model-TP.

Co-authored-by: Cursor <cursoragent@cursor.com>
- merge_vllm_args now applies rhaiis.vllm_args last so configOverrides
  like tensor-parallel-size take precedence over model defaults
- Remove tensor-parallel-size from rhaiis.yaml defaults (models define it)
- Move namespace and image_pull_secret into rhaiis.yaml defaults
- Fix predictor log upload bucket to psap-dashboard-data

Co-authored-by: Cursor <cursoragent@cursor.com>
The capture_isvc_state toolbox task writes logs under its own
sub-directory (NNN__capture_isvc_state/artifacts/), not the
top-level ARTIFACT_DIR.

Co-authored-by: Cursor <cursoragent@cursor.com>
- Add rhaiis.warmup config section (rate: 200, max_seconds: 60)
- Add profiler rates/max_seconds to config (200/200, matching model-furnace)
- Read warmup params from config instead of hardcoding

Co-authored-by: Cursor <cursoragent@cursor.com>
Derives labels like isl1000_osl1000 from the workload's data field
instead of requiring manual rhaiis.profiler.labels config, matching
model-furnace's get_profile_label() behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
…plugin

Move compare_runs, run_regression_analysis, RegressionResult, and
geometric_mean out of the generic caliper/engine/kpi/analyze.py into
rhaiis/postprocess/regression.py. The caliper engine should contain
no project-specific code (no references to model, accelerator, TP,
tokens, etc.).

This is a temporary transition — these CSV-based comparison functions
will be replaced by generic Caliper KPI-based analysis once the
framework lands.

Co-authored-by: Cursor <cursoragent@cursor.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
projects/rhaiis/postprocess/csv_export.py (1)

137-146: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Preserve all report.args.data entries when extracting token counts.

generate_dashboard_csv() applies the same token metadata to every CSV row, but report.args.data can contain repeated --data entries; dropping all rows after the first can assign the wrong prompt_toks/output_toks to benchmarks that used a later data source. Aggregate or fail explicitly when multiple data configurations are present instead of silently using only the first string.

🤖 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 `@projects/rhaiis/postprocess/csv_export.py` around lines 137 - 146, Update the
token extraction in generate_dashboard_csv() so every report.args.data entry is
preserved and considered, rather than selecting only data_list[0]. Aggregate
token metadata across entries or explicitly reject multiple configurations; do
not silently discard later entries or assign token counts from only the first
data source.
projects/rhaiis/orchestration/test_phase.py (2)

158-181: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Module-global _warnings state still unresolved, including the standalone-analysis early return.

_warnings remains process-global mutable state accumulated across _run_test/_run_workload_benchmark. The standalone-analysis early return at Line 180 (return 1 if _warnings else 0) still doesn't clear _warnings before returning, exactly the gap called out in a prior review ("never cleared in the standalone-analysis early return"). If two test invocations share a process, warnings from a previous run leak into the next run's return code and Slack notification.

Also applies to: 312-326

🤖 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 `@projects/rhaiis/orchestration/test_phase.py` around lines 158 - 181, Remove
the process-global `_warnings` dependency from `_run_test` and
`_run_workload_benchmark` by creating and using per-invocation warning state.
Ensure the standalone-analysis early return and the corresponding flow around
lines 312–326 evaluate only the current invocation’s warnings, so prior runs
cannot affect return codes or Slack notifications.

709-734: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Name copied trace files by workload before merging.

Traces are copied from different *__copy_profiler_traces directories and merged into the same traces_combined directory using f.name only. Names like trace_rank*.json can collide across workloads, causing files to silently overwrite each other instead of preserving one trace per workload/profile. Prefix the target paths with the parent directory name or a workload/profile token, and apply the same namespace when inferred labels are used.

🤖 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 `@projects/rhaiis/orchestration/test_phase.py` around lines 709 - 734, Update
the merge logic in _upload_profiler_traces so copied trace filenames include a
workload/profile namespace derived from each source parent directory, preventing
collisions in traces_combined. Use the same prefixed naming when selecting or
inferring labels from merged traces, while preserving direct uploads when all
traces share one directory.
projects/rhaiis/postprocess/regression.py (1)

380-418: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

status == "failed" is silently swallowed with zero logging.

send_regression_notification explicitly logs and returns for "skipped", but any other non-"completed" status — including "failed", which run_regression_analysis's exception handler produces — falls through the generic if status != "completed": return True with no log line at all. A regression-analysis crash is thus reported as a successful notification and leaves no trace, which contradicts the PR stack's repeated goal of not swallowing errors silently.

🛠️ Proposed fix
     if status == "skipped":
         reason = analysis_result.get("reason", "unknown")
         logger.info("Regression analysis skipped: %s", reason)
         return True
 
-    if status != "completed":
+    if status == "failed":
+        logger.warning(
+            "Regression analysis failed, no notification sent: %s",
+            analysis_result.get("error", "unknown"),
+        )
+        return False
+
+    if status != "completed":
         return True
🤖 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 `@projects/rhaiis/postprocess/regression.py` around lines 380 - 418, Update
send_regression_notification so status == "failed" is logged with its available
error or failure details before returning. Preserve the existing skipped
handling, and ensure all non-completed statuses are not silently swallowed while
retaining the current return behavior unless the surrounding contract requires
otherwise.
♻️ Duplicate comments (1)
projects/rhaiis/orchestration/test_phase.py (1)

100-103: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Multi-workload runs still deploy/profile using only workload_keys[0]'s vllm_args.

vllm_args is derived once from first_workload (Line 102-103) and reused for the single deployment and for every workload's profiler/warmup step in the Phase 1 loop (Lines 232-261). Any additional workload with different vllm_args is silently ignored, matching a previously raised major concern that is still unaddressed here.

Also applies to: 232-261

🤖 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 `@projects/rhaiis/orchestration/test_phase.py` around lines 100 - 103, Update
the Phase 1 deployment and profiling flow to derive merged vLLM arguments
separately for each workload instead of reusing arguments built from
workload_keys[0]. Use each workload’s configuration when invoking deployment,
profiler, and warmup steps, while preserving shared defaults and image
selection.
🧹 Nitpick comments (1)
projects/rhaiis/postprocess/regression.py (1)

517-595: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Consider guarding against secret leakage before forwarding raw error text to Slack.

error_text (and equivalents in send_regression_notification) is forwarded verbatim (only length-truncated) into an outbound Slack message. If an upstream failure ever embeds credential-like content (e.g. a raw exception from an S3/vault call), it would be posted externally. As per coding guidelines, "Never print, log, or include secret values in error messages," consider a lightweight redaction pass (e.g. common token/key patterns) before composing the message.

🤖 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 `@projects/rhaiis/postprocess/regression.py` around lines 517 - 595, Update
send_failure_notification and the equivalent error-text handling in
send_regression_notification to redact common credential and token patterns
before truncation and Slack message composition. Preserve the existing length
limit and notification flow, applying the redaction to all raw upstream error
text forwarded externally.

Source: Coding guidelines

🤖 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 `@projects/rhaiis/postprocess/csv_export.py`:
- Around line 91-102: Update _format_runtime_args to prevent sensitive
inference_server_args and trtllm_config entries from being written to
runtime_args in consolidated_dashboard.csv. Mask or skip credential, API-key,
and token-bearing keys before appending formatted values, or apply an existing
dashboard-safe allowlist while preserving non-sensitive arguments.

In `@projects/rhaiis/postprocess/regression.py`:
- Around line 100-105: Update the object-column normalization loops in the
postprocessing function to strip whitespace only from values that are actual
strings, preserving numeric and other non-string values unchanged. Apply the
same guarded normalization to both current_df and baseline_df before the later
TP, version, and accelerator filtering.

---

Outside diff comments:
In `@projects/rhaiis/orchestration/test_phase.py`:
- Around line 158-181: Remove the process-global `_warnings` dependency from
`_run_test` and `_run_workload_benchmark` by creating and using per-invocation
warning state. Ensure the standalone-analysis early return and the corresponding
flow around lines 312–326 evaluate only the current invocation’s warnings, so
prior runs cannot affect return codes or Slack notifications.
- Around line 709-734: Update the merge logic in _upload_profiler_traces so
copied trace filenames include a workload/profile namespace derived from each
source parent directory, preventing collisions in traces_combined. Use the same
prefixed naming when selecting or inferring labels from merged traces, while
preserving direct uploads when all traces share one directory.

In `@projects/rhaiis/postprocess/csv_export.py`:
- Around line 137-146: Update the token extraction in generate_dashboard_csv()
so every report.args.data entry is preserved and considered, rather than
selecting only data_list[0]. Aggregate token metadata across entries or
explicitly reject multiple configurations; do not silently discard later entries
or assign token counts from only the first data source.

In `@projects/rhaiis/postprocess/regression.py`:
- Around line 380-418: Update send_regression_notification so status == "failed"
is logged with its available error or failure details before returning. Preserve
the existing skipped handling, and ensure all non-completed statuses are not
silently swallowed while retaining the current return behavior unless the
surrounding contract requires otherwise.

---

Duplicate comments:
In `@projects/rhaiis/orchestration/test_phase.py`:
- Around line 100-103: Update the Phase 1 deployment and profiling flow to
derive merged vLLM arguments separately for each workload instead of reusing
arguments built from workload_keys[0]. Use each workload’s configuration when
invoking deployment, profiler, and warmup steps, while preserving shared
defaults and image selection.

---

Nitpick comments:
In `@projects/rhaiis/postprocess/regression.py`:
- Around line 517-595: Update send_failure_notification and the equivalent
error-text handling in send_regression_notification to redact common credential
and token patterns before truncation and Slack message composition. Preserve the
existing length limit and notification flow, applying the redaction to all raw
upstream error text forwarded externally.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 757d23c1-6548-4301-b338-2e9765d29770

📥 Commits

Reviewing files that changed from the base of the PR and between f4e51eb and 61fdcd1.

📒 Files selected for processing (14)
  • projects/caliper/engine/kpi/analyze.py
  • projects/guidellm/toolbox/run_guidellm_benchmark/main.py
  • projects/rhaiis/orchestration/analysis.py
  • projects/rhaiis/orchestration/ci.py
  • projects/rhaiis/orchestration/test_phase.py
  • projects/rhaiis/postprocess/agent.py
  • projects/rhaiis/postprocess/csv_export.py
  • projects/rhaiis/postprocess/kpis.py
  • projects/rhaiis/postprocess/parser.py
  • projects/rhaiis/postprocess/plugin.py
  • projects/rhaiis/postprocess/regression.py
  • projects/rhaiis/postprocess/s3_dashboard.py
  • projects/rhaiis/toolbox/enable_profiler_gate/main.py
  • projects/rhaiis/toolbox/verify_profiler_prereqs/main.py
🚧 Files skipped from review as they are similar to previous changes (10)
  • projects/rhaiis/orchestration/ci.py
  • projects/rhaiis/toolbox/enable_profiler_gate/main.py
  • projects/rhaiis/toolbox/verify_profiler_prereqs/main.py
  • projects/rhaiis/postprocess/plugin.py
  • projects/rhaiis/postprocess/kpis.py
  • projects/rhaiis/postprocess/parser.py
  • projects/guidellm/toolbox/run_guidellm_benchmark/main.py
  • projects/rhaiis/postprocess/s3_dashboard.py
  • projects/rhaiis/postprocess/agent.py
  • projects/rhaiis/orchestration/analysis.py

Comment thread projects/rhaiis/postprocess/csv_export.py
Comment thread projects/rhaiis/postprocess/regression.py
…rofile data

Previously, all workload benchmarks ran under a single NextArtifactDir
("testing") with one set of test labels (workload_key=profile1). The
Caliper parser merged all benchmarks.json files into one record, causing:
- Dashboard showing only "profile1" regardless of which profiles ran
- Multiple data points on the same chart from different profiles

Now each workload's benchmark phase runs in its own NextArtifactDir
(e.g., "benchmark_profile1", "benchmark_profile2") with per-workload
test labels. The parser creates separate records per profile, producing
correct per-profile CSV rows and dashboard entries.

Co-authored-by: Cursor <cursoragent@cursor.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
projects/rhaiis/orchestration/test_phase.py (1)

219-244: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Multi-workload phase loops have no per-workload failure isolation.

Neither the phase-1 (warmup/profiler) loop nor the phase-2 (_run_workload_benchmark) loop wraps each workload iteration in its own try/except. If workload N raises (e.g. guidellm benchmark error, profiler step failure), the exception propagates straight to the outer finally: _capture_and_cleanup(...) and then to do_test()'s pipeline-failure handling, aborting all subsequent workloads in workload_keys. For a multi-workload benchmark run, this means one workload's failure discards results for every workload that hasn't run yet, rather than collecting per-workload results/warnings and continuing.

Consider catching per-workload exceptions inside each loop iteration, recording them into the warnings list, and continuing to the next wl_key so partial results are preserved and reported.

Also applies to: 253-271

🤖 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 `@projects/rhaiis/orchestration/test_phase.py` around lines 219 - 244, Update
both workload loops around the phase-1 profiler/warmup calls and phase-2
_run_workload_benchmark invocation to catch exceptions per wl_key iteration,
append each failure to the existing warnings collection, and continue processing
subsequent workloads. Keep successful workload result handling unchanged and
ensure the captured warnings remain included in the final partial-results
reporting and cleanup flow.
🤖 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 `@projects/rhaiis/orchestration/test_phase.py`:
- Around line 370-378: Update the run_standalone_analysis call in the
not-run_benchmark branch to pass restrict_profiles scoped to the current
workload_key. Preserve the existing model_cfg, accelerator_key, vllm_args, and
run_uuid arguments while ensuring standalone analysis processes only that
workload.

---

Outside diff comments:
In `@projects/rhaiis/orchestration/test_phase.py`:
- Around line 219-244: Update both workload loops around the phase-1
profiler/warmup calls and phase-2 _run_workload_benchmark invocation to catch
exceptions per wl_key iteration, append each failure to the existing warnings
collection, and continue processing subsequent workloads. Keep successful
workload result handling unchanged and ensure the captured warnings remain
included in the final partial-results reporting and cleanup flow.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9c609093-5b03-4ad1-8716-b01392c90326

📥 Commits

Reviewing files that changed from the base of the PR and between 61fdcd1 and 5668caf.

📒 Files selected for processing (1)
  • projects/rhaiis/orchestration/test_phase.py

Comment thread projects/rhaiis/orchestration/test_phase.py
@ci_lib.safe_ci_entrypoint
def post_cleanup(ctx):
"""Post-cleanup phase - Clean up resources after test."""
_check_pipeline_failure_and_notify()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this belongs to the test step, no? 🤔

@Harshith-umesh Harshith-umesh Jul 28, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is to catch errors before the test step in the tekton pipeline, eg: image pull timeout or prepare step crashes. I would want to get slack notifications

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the post-cleanup 🤔
to catch things before the test step, you need to implement the preflight check, that's exactly the point of this function

Comment thread projects/rhaiis/orchestration/notifications.py Outdated
Comment thread projects/rhaiis/orchestration/prepare_rhaiis.py
Comment thread projects/rhaiis/orchestration/prepare_rhaiis.py
Comment thread projects/rhaiis/orchestration/test_phase.py Outdated
Comment thread projects/rhaiis/orchestration/test_phase.py Outdated
Comment on lines +124 to +140
mgmt_env = {k: v for k, v in os.environ.items() if k != "KUBECONFIG"}
subprocess.run(
[
"oc",
"annotate",
"fournosjob",
fjob_name,
"-n",
fjob_ns,
f"rhaiis.run-uuid={run_uuid}",
"--overwrite",
],
check=False,
capture_output=True,
timeout=10,
env=mgmt_env,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: use the run.run library file for clean log tracking

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good suggestion, but run.run doesn't support env overrides or timeout.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

include it!

Comment thread projects/rhaiis/orchestration/test_phase.py Outdated
Comment thread projects/rhaiis/orchestration/test_phase.py Outdated
Comment thread projects/rhaiis/orchestration/test_phase.py Outdated
Harshith-umesh and others added 2 commits July 28, 2026 14:18
- Use pd.to_numeric for TP filtering in analysis.py to handle non-numeric values
- Guard against empty ARTIFACT_BASE_DIR in ci.py pipeline failure detection
- Anchor resource cleanup suffix match with endswith in prepare_rhaiis.py
- Clear _warnings at start of _run_test to prevent cross-invocation leaks
- Add pipefail and post-extraction verification to profiler trace copy
- Pass restrict_profiles=[workload_key] in per-workload standalone analysis
- Deduplicate notification functions into shared _send_alert helper
- Stop swallowing exceptions: surface CSV sync, profiler upload failures
- Use descriptive artifact dir name with model_key and workload_keys
- Factor shared warmup/profiler step args into step_kwargs dict

Co-authored-by: Cursor <cursoragent@cursor.com>
@Harshith-umesh

Copy link
Copy Markdown
Member Author

/test fournos rhaiis nvidia
/pipeline forge-full
/exclusive false
/cluster zeus
/var tests.rhaiis.version vLLM-0.24.0-delete-gh
/var tests.rhaiis.workload_keys ["profile1","profile2","profile4"]
/var rhaiis.vllm_args.tensor-parallel-size 2
/var rhaiis.cluster_tag zeus2
/var rhaiis.deploy.image_pull_secret npalaska-image-pull
/var rhaiis.profiler.enabled true
/var caliper.postprocess.csv_dashboard.enabled true
/var workloads.profile1.rates [1,50,100,200,300]
/var workloads.profile1.max_seconds 10
/var workloads.profile2.rates [1,50,100,200,300]
/var workloads.profile2.max_seconds 10
/var workloads.profile4.rates [1,50,100,200,300]
/var workloads.profile4.max_seconds 10

@Harshith-umesh

Copy link
Copy Markdown
Member Author

/test fournos rhaiis nvidia
/pipeline forge-full
/exclusive false
/cluster zeus
/var tests.rhaiis.version: vLLM-0.24.0-delete-gh
/var tests.rhaiis.workload_keys: ["profile1","profile2","profile4"]
/var rhaiis.vllm_args.tensor-parallel-size: 2
/var rhaiis.cluster_tag: zeus2
/var rhaiis.deploy.image_pull_secret: npalaska-image-pull
/var rhaiis.profiler.enabled: true
/var caliper.postprocess.csv_dashboard.enabled: true
/var workloads.profile1.rates: [1,50,100,200,300]
/var workloads.profile1.max_seconds: 10
/var workloads.profile2.rates: [1,50,100,200,300]
/var workloads.profile2.max_seconds: 10
/var workloads.profile4.rates: [1,50,100,200,300]
/var workloads.profile4.max_seconds: 10

@psap-forge-bot

Copy link
Copy Markdown

🟢 Execution of rhaiis nvidia 🟢

Execution Engine Configuration

forge:
  args:
  - nvidia
  configOverrides:
    caliper.postprocess.csv_dashboard.enabled: true
    rhaiis.cluster_tag: zeus2
    rhaiis.deploy.image_pull_secret: npalaska-image-pull
    rhaiis.profiler.enabled: true
    rhaiis.vllm_args.tensor-parallel-size: 2
    tests.rhaiis.version: vLLM-0.24.0-delete-gh
    tests.rhaiis.workload_keys:
    - profile1
    - profile2
    - profile4
    workloads.profile1.max_seconds: 10
    workloads.profile1.rates:
    - 1
    - 50
    - 100
    - 200
    - 300
    workloads.profile2.max_seconds: 10
    workloads.profile2.rates:
    - 1
    - 50
    - 100
    - 200
    - 300
    workloads.profile4.max_seconds: 10
    workloads.profile4.rates:
    - 1
    - 50
    - 100
    - 200
    - 300
  project: rhaiis

Artifact Links

Test Logs

✅ 00 Pre-Cleanup 1 second

✅ 01 Prepare 6 seconds

✅ 02 Preflight 2 seconds

✅ 03 Test 47 minutes, 8 seconds

✅ 04 Post-Cleanup 6 seconds

🔄 05 Export-Artifacts

Post-processing Status ✅

  • ✅ parse: success
  • ✅ artifacts_to_kpis: success
  • ✅ kpis_to_csv: success
  • ⏭️ artifacts_to_ai_data: disabled

    kpi.artifacts_to_ai_data disabled

  • ⏭️ s3_import: disabled

    s3_import disabled

  • ⏭️ analyse_kpis: disabled

    analyze disabled

  • ⏭️ s3_export: disabled

    s3_export disabled

@psap-forge-bot

Copy link
Copy Markdown
🟢 Submission of rhaiis nvidia succeeded after 50 minutes, 34 seconds 🟢
/test fournos rhaiis nvidia
/var tests.rhaiis.version: vLLM-0.24.0-delete-gh
/var tests.rhaiis.workload_keys: ["profile1","profile2","profile4"]
/var rhaiis.vllm_args.tensor-parallel-size: 2
/var rhaiis.cluster_tag: zeus2
/var rhaiis.deploy.image_pull_secret: npalaska-image-pull
/var rhaiis.profiler.enabled: true
/var caliper.postprocess.csv_dashboard.enabled: true
/var workloads.profile1.rates: [1,50,100,200,300]
/var workloads.profile1.max_seconds: 10
/var workloads.profile2.rates: [1,50,100,200,300]
/var workloads.profile2.max_seconds: 10
/var workloads.profile4.rates: [1,50,100,200,300]
/var workloads.profile4.max_seconds: 10
/pipeline forge-full
/exclusive false
/cluster zeus

@kpouget

kpouget commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

/approve
/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jul 29, 2026
@openshift-ci

openshift-ci Bot commented Jul 29, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: kpouget

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 29, 2026
@openshift-merge-bot
openshift-merge-bot Bot merged commit ce6a8f8 into openshift-psap:main Jul 29, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants