quantification-MobileNetV5-V4 / scripts /generate_scientific_graphs.py
Lohan11's picture
Initial release: technical documentation, quantization scripts, and NPU benchmarks (part 2)
2248c41 verified
Raw History Blame Contribute Delete
6.79 kB
import os
import shutil
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('seaborn-v0_8-whitegrid' if 'seaborn-v0_8-whitegrid' in plt.style.available else 'default')
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
RESULTS_DIR = os.environ.get("LITHO_RESULTS_DIR", os.path.join(BASE_DIR, "results"))
CSV_PATH = os.path.join(RESULTS_DIR, "MobileNetV5", "machine_1", "machine_1_scientific_analysis.csv")
if not os.path.exists(CSV_PATH):
CSV_PATH = os.path.join(RESULTS_DIR, "consolidated", "csv", "lithotheque_scientific_analysis.csv")
if not os.path.exists(CSV_PATH):
raise FileNotFoundError(f"Cannot find scientific analysis dataset: {CSV_PATH}")
df = pd.read_csv(CSV_PATH)
print(f"[INFO] Loaded dataset from: {CSV_PATH}")
print(df.groupby(["Format", "Backend"]).agg({"Latency_ms": ["count", "mean", "std", "min", "max"]}))
# ==============================================================================
# Graph 1: Comparative Latency Across Backends and Quantizations (Error Bar Chart)
# ==============================================================================
fig, ax = plt.subplots(figsize=(10, 6), dpi=300)
summary = df.groupby(["Format", "Backend"])["Latency_ms"].agg(["mean", "std"]).reset_index()
order = [
("INT8", "Tensor_Cores_INT8"),
("INT8", "CPU_x64"),
("W4A8", "Tensor_Cores_INT4"),
("W4A8", "CPU_x64")
]
summary["order"] = summary.apply(lambda r: order.index((r["Format"], r["Backend"])) if (r["Format"], r["Backend"]) in order else 99, axis=1)
summary = summary.sort_values("order")
labels = [
"INT8\n(Machine 1 GPU Tensor Cores)",
"INT8\n(Machine 1 CPU Intel Core i3)",
"W4A8\n(Machine 1 GPU Tensor Cores)",
"W4A8\n(Machine 1 CPU Intel Core i3)"
]
means = summary["mean"].values
stds = summary["std"].values
colors = ["#10b981", "#ef4444", "#3b82f6", "#f59e0b"]
bars = ax.bar(labels, means, yerr=stds, capsize=8, color=colors, edgecolor="black", alpha=0.88, width=0.55)
for bar, mean in zip(bars, means):
yval = bar.get_height()
ax.text(bar.get_x() + bar.get_width() / 2.0, yval + 80, f"{mean:.1f} ms", ha='center', va='bottom', fontsize=11, fontweight='bold')
ax.set_ylabel("Inference Latency (ms) - Lower is Better", fontsize=12, fontweight='bold')
ax.set_title("MobileNetV5 (512x512) - Inference Latency Across Backends\nMachine 1: Workstation RTX 5060 vs Intel Core i3-12100F", fontsize=13, fontweight='bold', pad=15)
ax.set_ylim(0, max(means) * 1.22)
ax.grid(axis='y', linestyle='--', alpha=0.6)
plt.tight_layout()
chart1_dir = os.path.join(RESULTS_DIR, "MobileNetV5", "machine_1")
os.makedirs(chart1_dir, exist_ok=True)
chart1_path = os.path.join(chart1_dir, "latency_comparison_machine_1.png")
fig.savefig(chart1_path)
plt.close(fig)
print(f"[OK] Generated Graph 1: {chart1_path}")
# ==============================================================================
# Graph 2: Empirical Latency Stability Across Iterations (Boxplot Distribution)
# ==============================================================================
fig, ax = plt.subplots(figsize=(10, 6), dpi=300)
data_groups = []
labels_box = []
for fmt, bk, lbl in [
("INT8", "Tensor_Cores_INT8", "INT8 Tensor Cores\n(Machine 1 GPU)"),
("W4A8", "Tensor_Cores_INT4", "W4A8 Tensor Cores\n(Machine 1 GPU)"),
("INT8", "CPU_x64", "INT8 CPU\n(Machine 1 CPU)"),
("W4A8", "CPU_x64", "W4A8 CPU\n(Machine 1 CPU)")
]:
sub = df[(df["Format"] == fmt) & (df["Backend"] == bk)]["Latency_ms"].values
data_groups.append(sub)
labels_box.append(lbl)
try:
bplot = ax.boxplot(data_groups, patch_artist=True, tick_labels=labels_box, medianprops=dict(color='black', linewidth=2))
except TypeError:
bplot = ax.boxplot(data_groups, patch_artist=True, labels=labels_box, medianprops=dict(color='black', linewidth=2))
for patch, color in zip(bplot['boxes'], colors):
patch.set_facecolor(color)
patch.set_alpha(0.8)
ax.set_ylabel("Inference Latency (ms)", fontsize=12, fontweight='bold')
ax.set_title("Empirical Latency Stability Across Iterations (Variance & Outliers)\nMobileNetV5 Rock Classification Pipeline", fontsize=13, fontweight='bold', pad=15)
ax.grid(axis='y', linestyle='--', alpha=0.6)
plt.tight_layout()
chart2_dir = os.path.join(RESULTS_DIR, "consolidated", "images")
os.makedirs(chart2_dir, exist_ok=True)
chart2_path = os.path.join(chart2_dir, "latency_stability_distribution.png")
fig.savefig(chart2_path)
plt.close(fig)
print(f"[OK] Generated Graph 2: {chart2_path}")
# ==============================================================================
# Graph 3: Pareto Frontier (Inference Latency vs Top-1 Accuracy)
# ==============================================================================
fig, ax = plt.subplots(figsize=(9, 6), dpi=300)
pts = [
{"label": "INT8 (Machine 1 GPU)", "lat": df[(df["Format"] == "INT8") & (df["Backend"] == "Tensor_Cores_INT8")]["Latency_ms"].mean(), "acc": 83.33, "color": "#10b981", "size": 180},
{"label": "W4A8 (Machine 1 GPU)", "lat": df[(df["Format"] == "W4A8") & (df["Backend"] == "Tensor_Cores_INT4")]["Latency_ms"].mean(), "acc": 80.33, "color": "#3b82f6", "size": 180},
{"label": "INT8 (Machine 1 CPU)", "lat": df[(df["Format"] == "INT8") & (df["Backend"] == "CPU_x64")]["Latency_ms"].mean(), "acc": 83.33, "color": "#ef4444", "size": 140},
{"label": "W4A8 (Machine 1 CPU)", "lat": df[(df["Format"] == "W4A8") & (df["Backend"] == "CPU_x64")]["Latency_ms"].mean(), "acc": 80.33, "color": "#f59e0b", "size": 140},
{"label": "Machine 2 CPU INT8 (Oryon ARM64)", "lat": 5695.84, "acc": 83.33, "color": "#8b5cf6", "size": 140},
{"label": "Machine 2 CPU W4A8 (Oryon ARM64)", "lat": 7119.80, "acc": 80.33, "color": "#ec4899", "size": 140}
]
for p in pts:
ax.scatter(p["lat"], p["acc"], color=p["color"], s=p["size"], edgecolors="black", zorder=4)
ax.annotate(p["label"], (p["lat"], p["acc"]), textcoords="offset points", xytext=(10, 8 if "INT8" in p["label"] else -16),
fontsize=9.5, fontweight='bold', bbox=dict(boxstyle="round,pad=0.3", fc="white", ec=p["color"], alpha=0.9))
ax.set_xlabel("Inference Latency (ms) - Log/Linear Scale", fontsize=12, fontweight='bold')
ax.set_ylabel("Top-1 Accuracy (%)", fontsize=12, fontweight='bold')
ax.set_title("Pareto Efficiency: Geological Accuracy vs Inference Latency\nComparison Across Machine 1 & Machine 2 Environments", fontsize=13, fontweight='bold', pad=15)
ax.set_ylim(78.5, 85.5)
ax.set_xlim(-200, 7800)
ax.grid(True, linestyle='--', alpha=0.5)
plt.tight_layout()
chart3_path = os.path.join(chart2_dir, "accuracy_vs_latency_pareto.png")
fig.savefig(chart3_path)
plt.close(fig)
print(f"[OK] Generated Graph 3: {chart3_path}")
print("[SUCCESS] All scientific figures successfully generated in English.")