Download QWENVL-PRIVATE/analysis/analysis_auto.py from TerryPei/GroundFlow: direct link, hf CLI and curl.
- Browser
- Download file 22.6 kB
-
https://huggingface.co/TerryPei/GroundFlow/resolve/main/QWENVL-PRIVATE/analysis/analysis_auto.py
- Command line
-
hf download hf://TerryPei/GroundFlow/QWENVL-PRIVATE/analysis/analysis_auto.py
-
curl -L -o analysis_auto.py https://huggingface.co/TerryPei/GroundFlow/resolve/main/QWENVL-PRIVATE/analysis/analysis_auto.py
22.6 kB
| import os | |
| import glob | |
| import pickle | |
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| import seaborn as sns | |
| # ========================================== | |
| # 1. DATA LOADING & PROCESSING | |
| # ========================================== | |
| def load_data_for_task(base_dir, task_name, model_pattern): | |
| """ | |
| Loads pickle files matching the model_pattern for a specific task. | |
| Returns: | |
| - samples_data: dict of sample-level data (scores, visual tokens) | |
| - metadata: dict containing 'e2e_latency', 'total_tokens', etc. | |
| """ | |
| # Construct search pattern. logic handles wildcards if passed in model_pattern | |
| search_pattern = os.path.join(base_dir, f"{task_name}_analysis_rank*_{model_pattern}*.pkl") | |
| files = glob.glob(search_pattern) | |
| if not files: | |
| print(f" [Warning] No files found for task '{task_name}' with pattern '*{model_pattern}*'") | |
| return {}, {} | |
| merged_samples = {} | |
| aggregated_metadata = {"e2e_latency": 0, "total_tokens": 0} | |
| found_metadata = False | |
| for file_path in files: | |
| try: | |
| with open(file_path, "rb") as f: | |
| data_chunk = pickle.load(f) | |
| # Separate metric_dict from sample data | |
| if 'metric_dict' in data_chunk: | |
| m_dict = data_chunk.pop('metric_dict') | |
| # Sum latencies/tokens if split across multiple files (rare but safe) | |
| aggregated_metadata['e2e_latency'] += m_dict.get('e2e_latency', 0) | |
| aggregated_metadata['total_tokens'] += m_dict.get('total_tokens', 0) | |
| found_metadata = True | |
| merged_samples.update(data_chunk) | |
| except Exception as e: | |
| print(f" [Error] Failed to load {file_path}: {e}") | |
| if not found_metadata: | |
| print(f" [Info] No 'metric_dict' found in files for {task_name}.") | |
| return merged_samples, aggregated_metadata | |
| def extract_metrics(task_data_map, task_meta_map): | |
| """ | |
| Calculates average metrics (Throughput, Avg Visual Tokens) from raw data. | |
| """ | |
| visual_tokens = [] | |
| # 1. Extract Visual Token Counts | |
| for doc_id, content in task_data_map.items(): | |
| if "visual_token_num" in content: | |
| val = content["visual_token_num"] | |
| # Handle if it's a tensor/array or scalar | |
| if hasattr(val, 'item'): | |
| val = val.item() | |
| visual_tokens.append(float(val)) | |
| avg_vis_tokens = np.mean(visual_tokens) if visual_tokens else 0 | |
| # 2. Calculate Throughput (Samples / Second) | |
| # Total samples in this dataset | |
| n_samples = len(task_data_map) | |
| # Total time (e2e_latency is usually in seconds, ensure your logger units match) | |
| total_time = task_meta_map.get('e2e_latency', 0) | |
| if total_time > 0: | |
| throughput = n_samples / total_time | |
| else: | |
| throughput = 0 | |
| return { | |
| "avg_visual_tokens": avg_vis_tokens, | |
| "throughput": throughput, | |
| "n_samples": n_samples | |
| } | |
| # ========================================== | |
| # 2. PLOTTING FUNCTIONS | |
| # ========================================== | |
| def plot_tradeoff_curves(results, save_dir): | |
| """ | |
| Plots Accuracy vs. Efficiency (Throughput) and Accuracy vs. Visual Tokens. | |
| Handles Baseline, Ours, and RoI curves with distinct styles. | |
| """ | |
| labels = list(results.keys()) | |
| # Calculate Macro Averages (across all tasks for each config) | |
| avg_accs = [] | |
| avg_throughputs = [] | |
| avg_tokens = [] | |
| for label in labels: | |
| metrics = results[label] | |
| # Calculate mean of values; ensure we handle potential empty lists safely | |
| acc_values = [m['acc'] for m in metrics.values()] | |
| th_values = [m['throughput'] for m in metrics.values()] | |
| tok_values = [m['avg_visual_tokens'] for m in metrics.values()] | |
| avg_accs.append(np.mean(acc_values) if acc_values else 0) | |
| avg_throughputs.append(np.mean(th_values) if th_values else 0) | |
| avg_tokens.append(np.mean(tok_values) if tok_values else 0) | |
| # --- STYLE DEFINITIONS --- | |
| # Customize colors and markers here | |
| styles = { | |
| 'Baseline': {'marker': 'o', 'linestyle': '--', 'color': '#7f8c8d'}, # Grey, Dashed, Circle | |
| 'Ours': {'marker': '*', 'linestyle': '-', 'color': '#e74c3c'}, # Red, Solid, Star | |
| 'RoI': {'marker': 's', 'linestyle': '-', 'color': '#3498db'} # Blue, Solid, Square | |
| } | |
| # Helper function to generate both plots without code duplication | |
| def create_plot(x_data, x_label, file_name, title): | |
| plt.figure(figsize=(10, 7)) | |
| sns.set_theme(style="whitegrid") # Optional: makes grid look nice | |
| # Identify unique prefixes (Baseline, Ours, RoI) from the config keys | |
| prefixes = sorted(list(set([l.split('\n')[0] for l in labels]))) | |
| # Sort prefixes to ensure Legend order (e.g. Baseline -> Ours -> RoI) if desired | |
| # You can manually force order: prefixes = ['Baseline', 'Ours', 'RoI'] | |
| for prefix in prefixes: | |
| # Get style, default to black if unknown prefix | |
| style = styles.get(prefix, {'marker': 'D', 'linestyle': '-.', 'color': 'black'}) | |
| # Filter data for this group | |
| group_indices = [i for i, l in enumerate(labels) if l.startswith(prefix)] | |
| if not group_indices: continue | |
| g_x = [x_data[i] for i in group_indices] | |
| g_y = [avg_accs[i] for i in group_indices] | |
| g_labels = [labels[i] for i in group_indices] | |
| # Sort points by X-axis (efficiency or tokens) to draw correct line | |
| sorted_pairs = sorted(zip(g_x, g_y, g_labels), key=lambda x: x[0]) | |
| s_x, s_y, s_l = zip(*sorted_pairs) | |
| # Plot Line | |
| plt.plot(s_x, s_y, | |
| marker=style['marker'], | |
| linestyle=style['linestyle'], | |
| color=style['color'], | |
| label=prefix, | |
| linewidth=2, | |
| markersize=10 if style['marker'] != '*' else 14) # Stars need to be larger | |
| # Annotate Points (Labels like "Max-256") | |
| for x, y, lbl in zip(s_x, s_y, s_l): | |
| clean_lbl = lbl.split('\n')[-1] | |
| # Dynamic offsets to prevent overlapping labels | |
| offset = (0, 10) | |
| if prefix == 'RoI': | |
| offset = (0, -15) | |
| elif prefix == 'Ours': | |
| offset = (-10, 10) | |
| plt.annotate(clean_lbl, (x, y), xytext=offset, textcoords='offset points', | |
| ha='center', fontsize=8, fontweight='bold', | |
| bbox=dict(boxstyle="round,pad=0.2", fc="white", alpha=0.6, ec="none")) | |
| plt.title(title, fontsize=14) | |
| plt.xlabel(x_label, fontweight='bold') | |
| plt.ylabel('Average Accuracy (%)', fontweight='bold') | |
| plt.grid(True, linestyle=':', alpha=0.6) | |
| plt.legend(fontsize=10) | |
| plt.tight_layout() | |
| save_path = os.path.join(save_dir, file_name) | |
| plt.savefig(save_path, dpi=300) | |
| plt.close() | |
| print(f"Saved plot: {save_path}") | |
| # 1. Plot Efficiency | |
| create_plot(avg_throughputs, | |
| 'Average Throughput (Samples / Second) \n← Slower | Faster →', | |
| "acc_vs_efficiency.png", | |
| "Accuracy vs. Efficiency Trade-off") | |
| # 2. Plot Visual Tokens | |
| create_plot(avg_tokens, | |
| 'Average Visual Tokens per Image \n← Cheaper | More Detailed →', | |
| "acc_vs_visual_tokens.png", | |
| "Accuracy vs. Visual Cost") | |
| # ========================================== | |
| # 3. EXISTING UTILS (Preserved) | |
| # ========================================== | |
| def print_threshold_ratios(task_data_map, threshold): | |
| print(f"\n{'=' * 20} Threshold Analysis (Score > {threshold}) {'=' * 20}") | |
| print(f"{'Dataset Name':<20} | {'Total Samples':<15} | {'Above Thr':<10} | {'Ratio':<10}") | |
| print("-" * 65) | |
| for task_name, content in task_data_map.items(): | |
| scores = content['scores'] | |
| if len(scores) == 0: continue | |
| above_mask = scores > threshold | |
| count_above = np.sum(above_mask) | |
| ratio = count_above / len(scores) | |
| print(f"{task_name:<20} | {len(scores):<15} | {count_above:<10} | {ratio:.2%}") | |
| print("-" * 65 + "\n") | |
| def extract_scores_list(data_dict): | |
| scores = [] | |
| for doc_id, content in data_dict.items(): | |
| if "high_res_pred_score" in content: | |
| val = content["high_res_pred_score"] | |
| if isinstance(val, np.ndarray): val = val.flatten()[0] | |
| scores.append(float(val)) | |
| return np.array(scores) | |
| def plot_cost_benefit_combo(results, task_name, save_dir): | |
| """ | |
| Better Idea: Combines Relative Efficiency (Bars) with Accuracy Gain (Points/Lines) | |
| on a dual-axis chart. | |
| """ | |
| # 1. Parse Data (Similar to above, but also gets Accuracy) | |
| data_map = {} | |
| for label, metrics in results.items(): | |
| method, resolution = label.split('\n') | |
| if resolution not in data_map: data_map[resolution] = {} | |
| task_data = metrics.get(task_name, {'throughput': 0, 'acc': 0}) | |
| data_map[resolution][method] = { | |
| 'speed': task_data['throughput'], | |
| 'acc': task_data['acc'] | |
| } | |
| resolutions = sorted(data_map.keys(), key=lambda x: int(x.split('-')[-1])) | |
| methods = ['Baseline', 'Ours', 'RoI'] | |
| colors = {'Baseline': '#95a5a6', 'Ours': '#e74c3c', 'RoI': '#3498db'} | |
| x = np.arange(len(resolutions)) | |
| width = 0.25 | |
| fig, ax1 = plt.subplots(figsize=(11, 7)) | |
| ax2 = ax1.twinx() # Create secondary y-axis for Accuracy Gain | |
| # Loop for Bars (Efficiency) AND Points (Accuracy) | |
| for i, method in enumerate(methods): | |
| eff_ratios = [] | |
| acc_gains = [] | |
| for res in resolutions: | |
| base_speed = data_map[res].get('Baseline', {}).get('speed', 1.0) | |
| base_acc = data_map[res].get('Baseline', {}).get('acc', 0.0) | |
| curr = data_map[res].get(method, {'speed': 0, 'acc': 0}) | |
| # Efficiency Ratio | |
| ratio = (curr['speed'] / base_speed) * 100 if base_speed > 0 else 0 | |
| eff_ratios.append(ratio) | |
| # Accuracy Delta (Gain over Baseline of SAME resolution) | |
| delta = curr['acc'] - base_acc | |
| acc_gains.append(delta) | |
| offset = (i - 1) * width | |
| # PLOT 1: Efficiency Bars (Left Axis) | |
| ax1.bar(x + offset, eff_ratios, width, color=colors[method], alpha=0.3, label=f"{method} (Speed)") | |
| # PLOT 2: Accuracy Gain Markers (Right Axis) | |
| # We plot these slightly offset to align with bars, or connected with lines | |
| if method == 'Baseline': | |
| # Plot baseline as flat line at 0 | |
| ax2.plot(x + offset, acc_gains, color=colors[method], marker='_', markersize=20, linestyle='None') | |
| else: | |
| # Plot gains as distinct markers | |
| ax2.plot(x + offset, acc_gains, color=colors[method], marker='D', markersize=8, | |
| linestyle='-', linewidth=2, label=f"{method} (Acc Gain)") | |
| # Annotate specific gains | |
| for j, gain in enumerate(acc_gains): | |
| ax2.annotate(f"+{gain:.1f}", (x[j] + offset, gain), xytext=(0, 8), | |
| textcoords='offset points', ha='center', color=colors[method], fontweight='bold') | |
| # Formatting | |
| ax1.set_ylabel("Relative Efficiency (%)", fontsize=12, fontweight='bold') | |
| ax1.set_ylim(0, 120) | |
| ax1.set_xlabel("Resolution", fontsize=12) | |
| ax1.set_xticks(x) | |
| ax1.set_xticklabels(resolutions) | |
| ax2.set_ylabel("Accuracy Gain over Baseline (Points)", fontsize=12, fontweight='bold') | |
| # Set symmetric limits or auto limits for acc gain | |
| ax2.axhline(0, color='gray', linestyle=':', linewidth=1) | |
| plt.title(f"Cost-Benefit Analysis: {task_name}\n(Bars = Speed %, Points = Acc Gain)", fontsize=14) | |
| # Custom Legend | |
| lines, labels = ax1.get_legend_handles_labels() | |
| lines2, labels2 = ax2.get_legend_handles_labels() | |
| ax1.legend(lines + lines2, labels + labels2, loc='upper left') | |
| plt.tight_layout() | |
| save_path = os.path.join(save_dir, f"{task_name}_cost_benefit.png") | |
| plt.savefig(save_path, dpi=300) | |
| plt.close() | |
| print(f"Saved Cost-Benefit plot: {save_path}") | |
| # ========================================== | |
| # 4. MAIN EXECUTION | |
| # ========================================== | |
| if __name__ == "__main__": | |
| BASE_DIR = "../archive_data/" | |
| SAVE_DIR = "./analysis_plots/" | |
| os.makedirs(SAVE_DIR, exist_ok=True) | |
| # --- CONFIGURATION: Define Models and Manual Accuracies --- | |
| # Keys: Display Label (First line is Group, second is variant) | |
| # Values: 'pattern': filename part to match, 'accs': dict of {task: accuracy} | |
| TARGET_TASKS = [ | |
| "docvqa_val", | |
| "infovqa_val", | |
| "textvqa_val", | |
| "chartqa", # Added from table | |
| "ocrbench" # Added from table | |
| # "vstar_bench", | |
| # "mmerealworld_lite", | |
| ] | |
| # --- CONFIGURATION: Define Models and Manual Accuracies --- | |
| # Patterns are derived from: Visual_Tokens * 28 * 28 | |
| # 128 tokens = 100352 pixels | |
| # 256 tokens = 200704 pixels | |
| # 576 tokens = 451584 pixels | |
| # 1024 tokens = 802816 pixels | |
| # 2048 tokens = 1605632 pixels | |
| MODEL_CONFIGS = { | |
| # --- BASELINE CONFIGURATIONS --- | |
| # 'Baseline\nMax-256': { | |
| # 'pattern': 'Qwen2.5-VL-7B-Instruct_min100352_max200704', | |
| # 'accs': { | |
| # 'docvqa_val': 81.2, | |
| # 'chartqa': 76.8, | |
| # 'ocrbench': 77.8, | |
| # 'infovqa_val': 54.0, | |
| # 'textvqa_val': 75.5, | |
| # 'vstar_bench': 53.4, | |
| # 'mmerealworld_lite': 27.6 | |
| # } | |
| # }, | |
| 'Baseline\nMax-576': { | |
| 'pattern': 'Qwen2.5-VL-7B-Instruct_min200704_max451584', | |
| 'accs': { | |
| 'docvqa_val': 92.0, | |
| 'chartqa': 83.0, | |
| 'ocrbench': 82.8, | |
| 'infovqa_val': 70.1, | |
| 'textvqa_val': 81.1, | |
| 'vstar_bench': 64.4, | |
| 'mmerealworld_lite': 35.4 | |
| } | |
| }, | |
| 'Baseline\nMax-1024': { | |
| 'pattern': 'Qwen2.5-VL-7B-Instruct_min200704_max802816', | |
| 'accs': { | |
| 'docvqa_val': 93.9, | |
| 'chartqa': 84.6, | |
| 'ocrbench': 84.4, | |
| 'infovqa_val': 76.5, | |
| 'textvqa_val': 82.8, | |
| 'vstar_bench': 70.2, | |
| 'mmerealworld_lite': 37.5 | |
| } | |
| }, | |
| 'Baseline\nMax-2048': { | |
| 'pattern': 'Qwen2.5-VL-7B-Instruct_min200704_max1605632', | |
| 'accs': { | |
| 'docvqa_val': 94.7, | |
| 'chartqa': 84.5, | |
| 'ocrbench': 84.8, | |
| 'infovqa_val': 80.4, | |
| 'textvqa_val': 82.9, | |
| 'vstar_bench': 72.3, | |
| 'mmerealworld_lite': 39.3 | |
| } | |
| }, | |
| # | |
| # # # # --- YOUR "OURS" CONFIGURATIONS (Update these patterns as needed) --- | |
| # 'Ours\nMax-256': { | |
| # 'pattern': 'qwen2_5vl-7b-roi-K18T3-134k-gatedv2PB-wGTwRoI-twiginit-filled_min100352_max200704', | |
| # 'accs': { | |
| # 'docvqa_val': 89.1, | |
| # 'chartqa': 82.5, | |
| # 'ocrbench': 83.8, | |
| # 'infovqa_val': 69.6, | |
| # 'textvqa_val': 81.8, | |
| # 'vstar_bench': 67.5, | |
| # 'mmerealworld_lite': 37.3 | |
| # } | |
| # }, | |
| # 'Ours\nMax-576': { | |
| # 'pattern': 'qwen2_5vl-7b-roi-K18T3-134k-gatedv2PB-wGTwRoI-twiginit-filled_min200704_max451584', | |
| # 'accs': { | |
| # 'docvqa_val': 93.9, | |
| # 'chartqa': 84.2, | |
| # 'ocrbench': 84.8, | |
| # 'infovqa_val': 78.5, | |
| # 'textvqa_val': 82.8, | |
| # 'vstar_bench': 80.1, | |
| # 'mmerealworld_lite': 43.4 | |
| # } | |
| # }, | |
| # 'Ours\nMax-1024': { | |
| # 'pattern': 'qwen2_5vl-7b-roi-K18T3-134k-gatedv2PB-wGTwRoI-twiginit-filled_min200704_max802816', | |
| # 'accs': { | |
| # 'docvqa_val': 94.6, | |
| # 'chartqa': 85.4, | |
| # 'ocrbench': 84.8, | |
| # 'infovqa_val': 81.5, | |
| # 'textvqa_val': 83.7, | |
| # 'vstar_bench': 83.3, | |
| # 'mmerealworld_lite': 46.5 | |
| # } | |
| # }, | |
| # 'Ours\nMax-1536': { | |
| # 'pattern': 'qwen2_5vl-7b-roi-K18T3-134k-gatedv2PB-wGTwRoI-twiginit-filled_min200704_max1204224', | |
| # 'accs': { | |
| # 'docvqa_val': 94.8, | |
| # 'chartqa': 85.4, | |
| # 'ocrbench': 85.4, | |
| # 'infovqa_val': 82.4, | |
| # 'textvqa_val': 83.6, | |
| # 'vstar_bench': 88.0, | |
| # 'mmerealworld_lite': 47.2 | |
| # } | |
| # }, | |
| ###--- "OURS-RoI" CONFIGURATIONS --- | |
| 'RoI\nMax-256': { | |
| 'pattern': 'qwen2_5vl-7b-roi-K18T3-185k-v1bf16-denoisedv2-twiginit-filled_min100352_max200704', | |
| 'accs': { | |
| 'docvqa_val': 89.2, 'chartqa': 83.0, 'ocrbench': 83.6, 'infovqa_val': 69.9, | |
| 'textvqa_val': 81.4, 'vstar_bench': 67.5, 'mmerealworld_lite': 37.6 | |
| } | |
| }, | |
| 'RoI\nMax-576': { | |
| 'pattern': 'qwen2_5vl-7b-roi-K18T3-185k-v1bf16-denoisedv2-twiginit-filled_min200704_max451584', | |
| 'accs': { | |
| 'docvqa_val': 94.1, 'chartqa': 85.8, 'ocrbench': 84.9, 'infovqa_val': 79.6, | |
| 'textvqa_val': 82.9, 'vstar_bench': 80.6, 'mmerealworld_lite': 44.6 | |
| } | |
| }, | |
| 'RoI\nMax-1024': { | |
| 'pattern': 'qwen2_5vl-7b-roi-K18T3-185k-v1bf16-denoisedv2-twiginit-filled_min200704_max802816', | |
| 'accs': { | |
| 'docvqa_val': 94.7, 'chartqa': 86.3, 'ocrbench': 84.8, 'infovqa_val': 82.0, | |
| 'textvqa_val': 83.9, 'vstar_bench': 82.2, 'mmerealworld_lite': 46.7 | |
| } | |
| }, | |
| # 'RoI\nMax-1536': { | |
| # 'pattern': 'qwen2_5vl-7b-roi-K18T3-185k-v1bf16-denoisedv2-twiginit-filled_min200704_max1204224', | |
| # 'accs': { | |
| # 'docvqa_val': 94.9, 'chartqa': 85.8, 'ocrbench': 84.8, 'infovqa_val': 83.2, | |
| # 'textvqa_val': 83.9, 'vstar_bench': 88.0, 'mmerealworld_lite': 47.0 | |
| # } | |
| # }, | |
| # # # --- YOUR "OURS" CONFIGURATIONS (Update these patterns as needed) --- | |
| 'Ours\nMax-1024': { | |
| 'pattern': 'qwen2_5vl-7b-roi-K18T3-134k-gatedv2PB-stage3_min200704_max802816', | |
| 'accs': { | |
| 'docvqa_val': 94.8, | |
| 'chartqa': 86.4, | |
| 'ocrbench': 85.4, | |
| 'infovqa_val': 81.2, | |
| 'textvqa_val': 84.1, | |
| 'vstar_bench': 83.8, | |
| 'mmerealworld_lite': 47.3 | |
| } | |
| }, | |
| 'Ours\nMax-576': { | |
| 'pattern': 'qwen2_5vl-7b-roi-K18T3-134k-gatedv2PB-stage3_min200704_max451584', | |
| 'accs': { | |
| 'docvqa_val': 94.0, | |
| 'chartqa': 85.4, | |
| 'ocrbench': 85.4, | |
| 'infovqa_val': 79.4, | |
| 'textvqa_val': 83.5, | |
| 'vstar_bench': 79.6, | |
| 'mmerealworld_lite': 45.7 | |
| } | |
| }, | |
| 'Ours\nMax-384': { | |
| 'pattern': 'qwen2_5vl-7b-roi-K18T3-134k-gatedv2PB-stage3_min100352_max301056', | |
| 'accs': { | |
| 'docvqa_val': 93.4, | |
| 'chartqa': 84.2, | |
| 'ocrbench': 85.3, | |
| 'infovqa_val': 75.7, | |
| 'textvqa_val': 82.7, | |
| 'vstar_bench': 73.8, | |
| 'mmerealworld_lite': 41.2 | |
| } | |
| }, | |
| 'Ours\nMax-256': { | |
| 'pattern': 'qwen2_5vl-7b-roi-K18T3-134k-gatedv2PB-stage3_min100352_max200704', | |
| 'accs': { | |
| 'docvqa_val': 90.4, | |
| 'chartqa': 82.7, | |
| 'ocrbench': 83.5, | |
| 'infovqa_val': 71.7, | |
| 'textvqa_val': 81.8, | |
| 'vstar_bench': 68.6, | |
| 'mmerealworld_lite': 37.9 | |
| } | |
| }, | |
| # 'Ours\nMax-1536': { | |
| # 'pattern': 'qwen2_5vl-7b-roi-K18T3-post7k-repos-full2_min200704_max1204224', | |
| # 'accs': { | |
| # 'docvqa_val': 95.0, | |
| # 'chartqa': 86.4, | |
| # 'ocrbench': 84.8, | |
| # 'infovqa_val': 82.6, | |
| # 'textvqa_val': 84.3, | |
| # 'vstar_bench': 86.9, | |
| # 'mmerealworld_lite': 48.2 | |
| # } | |
| # }, | |
| } | |
| print("--- Loading Data for Comparison ---") | |
| # Store all results here: { "Baseline\nMax-256": { "textvqa": {throughput, tokens, acc}, ... } } | |
| overall_results = {} | |
| for label, config in MODEL_CONFIGS.items(): | |
| print(f"Processing config: {label.replace(chr(10), ' ')}") # chr(10) is newline | |
| overall_results[label] = {} | |
| # Load data for each task for this specific config | |
| for task in TARGET_TASKS: | |
| # 1. Load Raw Data | |
| raw_data, metadata = load_data_for_task(BASE_DIR, task, config['pattern']) | |
| if not raw_data: | |
| # Fill dummy if missing to avoid crash, or skip | |
| overall_results[label][task] = {'throughput': 0, 'avg_visual_tokens': 0, 'acc': 0} | |
| continue | |
| # 2. Extract Metrics (Speed, Tokens) | |
| metrics = extract_metrics(raw_data, metadata) | |
| # 3. Add Manual Accuracy | |
| acc = config['accs'].get(task, 0.0) # Default 0 if task missing in config | |
| # 4. Store Scores for Histograms (Optional, if you want detailed score plots per config) | |
| # scores = extract_scores_list(raw_data) | |
| # Save combined | |
| overall_results[label][task] = { | |
| 'throughput': metrics['throughput'], | |
| 'avg_visual_tokens': metrics['avg_visual_tokens'], | |
| 'acc': acc, | |
| # 'scores': scores # Uncomment if you want to pass this to the histogram plotter | |
| } | |
| print( | |
| f" > {task}: {metrics['throughput']:.1f} samp/s, {metrics['avg_visual_tokens']:.0f} tokens, Acc: {acc}") | |
| # --- PLOT COMPARISONS --- | |
| if overall_results: | |
| print("\n--- Generating Comparison Plots ---") | |
| plot_tradeoff_curves(overall_results, SAVE_DIR) | |
| print("\nDone! Plots saved to:", SAVE_DIR) | |
| for i in range(len(TARGET_TASKS)): | |
| plot_cost_benefit_combo(overall_results, TARGET_TASKS[i], SAVE_DIR) | |