From 681dfa10ec68d2197d4dbe5098b4306dec4559bb Mon Sep 17 00:00:00 2001 From: Ryhs Date: Thu, 24 Jul 2025 21:11:14 +0800 Subject: [PATCH 1/2] Fix: Resolve plots directory path inconsistency in GenAI-perf When using model names with special characters (e.g., paths with slashes), GenAI-perf creates sanitized artifact directory names but the plots generation fails due to path mismatches between profile() and create_plots() methods. - Fixed create_plots() to use the same PerfAnalyzerConfig path logic as profile() - Ensured plots directory is created under the correct sanitized artifact directory - Added proper path resolution for profile_export_file in plots configuration This resolves the "No such file or directory: 'artifacts/plots/config.yaml'" error fundamentally. --- genai-perf/genai_perf/subcommand/profile.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/genai-perf/genai_perf/subcommand/profile.py b/genai-perf/genai_perf/subcommand/profile.py index 745ab43f..757a2490 100644 --- a/genai-perf/genai_perf/subcommand/profile.py +++ b/genai-perf/genai_perf/subcommand/profile.py @@ -90,9 +90,12 @@ def profile(self) -> None: def create_plots(self) -> None: # TMA-1911: support plots CLI option - plot_dir = self._config.output.artifact_directory / "plots" + # Create the same config objects as in profile() to get consistent paths + objectives = self._create_objectives_based_on_stimulus() + perf_analyzer_config = self._create_perf_analyzer_config(objectives) + plot_dir = perf_analyzer_config.get_artifact_directory() / "plots" PlotConfigParser.create_init_yaml_config( - filenames=[self._config.output.profile_export_file], # single run + filenames=[perf_analyzer_config.get_profile_export_file()], output_dir=plot_dir, ) config_parser = PlotConfigParser(plot_dir / "config.yaml") From 40dd643144436a7663e4b5f0f704bfef824ecea9 Mon Sep 17 00:00:00 2001 From: Rythsman Date: Wed, 13 Aug 2025 12:47:08 +0800 Subject: [PATCH 2/2] fix(profile): generate plots using run-scoped PA config to preserve single-run behavior - Cache objectives, GenAIPerfConfig, and PerfAnalyzerConfig in Profile.__init__ to keep a consistent run context across profiling and plotting - Update profile() to reuse cached configs instead of reconstructing them - Use PerfAnalyzerConfig.get_artifact_directory() and get_profile_export_file() in create_plots() to avoid global output paths that caused repeated handling across runs - Improves determinism and prevents unintended multi-run plot generation - Refs TMA-1911 Signed-off-by: Rythsman --- genai-perf/genai_perf/subcommand/profile.py | 31 ++++++++++----------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/genai-perf/genai_perf/subcommand/profile.py b/genai-perf/genai_perf/subcommand/profile.py index 757a2490..d53e30d8 100644 --- a/genai-perf/genai_perf/subcommand/profile.py +++ b/genai-perf/genai_perf/subcommand/profile.py @@ -58,44 +58,41 @@ class Profile(Subcommand): def __init__(self, config: ConfigCommand, extra_args: Optional[List[str]]) -> None: super().__init__(config, extra_args) + self._objectives = self._create_objectives_based_on_stimulus() + self._genai_perf_config = self._create_genai_perf_config(self._objectives) + self._perf_analyzer_config = self._create_perf_analyzer_config(self._objectives) def profile(self) -> None: """ Profiles the model based on the user's stimulus """ - objectives = self._create_objectives_based_on_stimulus() - genai_perf_config = self._create_genai_perf_config(objectives) - perf_analyzer_config = self._create_perf_analyzer_config(objectives) - if self._is_config_present_in_results(genai_perf_config, perf_analyzer_config): + if self._is_config_present_in_results(self._genai_perf_config, self._perf_analyzer_config): self._found_config_in_checkpoint( - genai_perf_config, perf_analyzer_config, objectives + self._genai_perf_config, self._perf_analyzer_config, self._objectives ) else: # Pre-amble self._create_tokenizer() - self._create_artifact_directory(perf_analyzer_config) - self._create_plot_directory(perf_analyzer_config) - self._generate_inputs(perf_analyzer_config) + self._create_artifact_directory(self._perf_analyzer_config) + self._create_plot_directory(self._perf_analyzer_config) + self._generate_inputs(self._perf_analyzer_config) # Profile using Perf Analyzer - self._run_perf_analyzer(perf_analyzer_config) + self._run_perf_analyzer(self._perf_analyzer_config) # Post-amble - self._set_data_parser(perf_analyzer_config) + self._set_data_parser(self._perf_analyzer_config) self._add_results_to_checkpoint( - genai_perf_config, perf_analyzer_config, objectives + self._genai_perf_config, self._perf_analyzer_config, self._objectives ) - self._add_output_to_artifact_directory(perf_analyzer_config, objectives) + self._add_output_to_artifact_directory(self._perf_analyzer_config, self._objectives) def create_plots(self) -> None: # TMA-1911: support plots CLI option - # Create the same config objects as in profile() to get consistent paths - objectives = self._create_objectives_based_on_stimulus() - perf_analyzer_config = self._create_perf_analyzer_config(objectives) - plot_dir = perf_analyzer_config.get_artifact_directory() / "plots" + plot_dir = self._perf_analyzer_config.get_artifact_directory() / "plots" PlotConfigParser.create_init_yaml_config( - filenames=[perf_analyzer_config.get_profile_export_file()], + filenames=[self._perf_analyzer_config.get_profile_export_file()], # single run output_dir=plot_dir, ) config_parser = PlotConfigParser(plot_dir / "config.yaml")