-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplot_quantization.py
More file actions
135 lines (112 loc) · 5.02 KB
/
Copy pathplot_quantization.py
File metadata and controls
135 lines (112 loc) · 5.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import os
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
os.makedirs("plots", exist_ok=True)
df = pd.read_csv("results/quantization_results.csv")
ok = df[df["status"] == "ok"].copy()
# Order
quant_order = ["FP32", "FP16", "INT8", "INT4"]
ok["quantization"] = pd.Categorical(ok["quantization"], categories=quant_order, ordered=True)
# ── Plot 1: throughput vs batch size ──────────────────────────────────────
for model in sorted(ok["model"].unique()):
fig, axes = plt.subplots(1, 2, figsize=(14, 5), sharey=False)
model_df = ok[ok["model"] == model]
for ax, seq_len in zip(axes, sorted(model_df["seq_len"].unique())):
sub = model_df[model_df["seq_len"] == seq_len]
for q in quant_order:
s = sub[sub["quantization"] == q].sort_values("batch_size")
if len(s) == 0:
continue
ax.plot(
s["batch_size"],
s["total_throughput_tok_s"],
marker="o",
linewidth=2,
label=q,
)
ax.set_title(f"{model} — seq_len={seq_len}")
ax.set_xlabel("Batch size")
ax.set_ylabel("Total throughput (tok/s)")
ax.grid(True, alpha=0.3)
ax.legend()
plt.suptitle(f"{model} — throughput vs batch size", y=1.02)
plt.tight_layout()
plt.savefig(f"plots/{model}_throughput_vs_batch.png", dpi=180, bbox_inches="tight")
plt.close()
print(f"plot: plots/{model}_throughput_vs_batch.png")
# ── Plot 2: memory vs quantization ────────────────────────────────────────
summary = (
ok.groupby(["model", "quantization"], as_index=False)
.agg({
"model_memory_gb": "first",
"perplexity": "first",
"total_throughput_tok_s": "max",
"peak_memory_gb": "max",
})
)
fig, axes = plt.subplots(1, 3, figsize=(18, 5))
for model in sorted(summary["model"].unique()):
sub = summary[summary["model"] == model].sort_values("quantization")
axes[0].plot(sub["quantization"], sub["model_memory_gb"], marker="o", linewidth=2, label=model)
axes[1].plot(sub["quantization"], sub["total_throughput_tok_s"], marker="o", linewidth=2, label=model)
axes[2].plot(sub["quantization"], sub["perplexity"], marker="o", linewidth=2, label=model)
axes[0].set_title("Model memory by quantization")
axes[0].set_ylabel("Model memory (GB)")
axes[0].grid(True, alpha=0.3)
axes[0].legend()
axes[1].set_title("Peak throughput by quantization")
axes[1].set_ylabel("Peak throughput (tok/s)")
axes[1].grid(True, alpha=0.3)
axes[1].legend()
axes[2].set_title("Perplexity by quantization")
axes[2].set_ylabel("Perplexity")
axes[2].grid(True, alpha=0.3)
axes[2].legend()
plt.tight_layout()
plt.savefig("plots/quantization_summary.png", dpi=180, bbox_inches="tight")
plt.close()
print("plot: plots/quantization_summary.png")
# ── Plot 3: speedup and memory savings vs FP32 ────────────────────────────
rows = []
for model in sorted(summary["model"].unique()):
sub = summary[summary["model"] == model].copy()
fp32 = sub[sub["quantization"] == "FP32"].iloc[0]
for _, r in sub.iterrows():
rows.append({
"model": model,
"quantization": r["quantization"],
"throughput_speedup_vs_fp32": r["total_throughput_tok_s"] / fp32["total_throughput_tok_s"],
"memory_savings_vs_fp32_pct": (1 - r["model_memory_gb"] / fp32["model_memory_gb"]) * 100,
"ppl_delta_vs_fp32": r["perplexity"] - fp32["perplexity"],
})
comp = pd.DataFrame(rows)
comp.to_csv("results/quantization_summary.csv", index=False)
fig, axes = plt.subplots(1, 3, figsize=(18, 5))
for model in sorted(comp["model"].unique()):
sub = comp[comp["model"] == model].sort_values("quantization")
axes[0].plot(sub["quantization"], sub["throughput_speedup_vs_fp32"], marker="o", linewidth=2, label=model)
axes[1].plot(sub["quantization"], sub["memory_savings_vs_fp32_pct"], marker="o", linewidth=2, label=model)
axes[2].plot(sub["quantization"], sub["ppl_delta_vs_fp32"], marker="o", linewidth=2, label=model)
axes[0].axhline(1.0, color="gray", linestyle="--", alpha=0.5)
axes[0].set_title("Throughput speedup vs FP32")
axes[0].set_ylabel("Speedup (×)")
axes[0].grid(True, alpha=0.3)
axes[0].legend()
axes[1].set_title("Memory savings vs FP32")
axes[1].set_ylabel("Savings (%)")
axes[1].grid(True, alpha=0.3)
axes[1].legend()
axes[2].axhline(0.0, color="gray", linestyle="--", alpha=0.5)
axes[2].set_title("Perplexity delta vs FP32")
axes[2].set_ylabel("Δ Perplexity")
axes[2].grid(True, alpha=0.3)
axes[2].legend()
plt.tight_layout()
plt.savefig("plots/quantization_tradeoffs.png", dpi=180, bbox_inches="tight")
plt.close()
print("plot: plots/quantization_tradeoffs.png")
print("\n=== Summary table ===")
print(summary.to_string(index=False))
print("\n=== Comparison vs FP32 ===")
print(comp.to_string(index=False))