File size: 1,983 Bytes
72c62ed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""Plot the dynamic-batching sweep from the benchmark matrix JSONs.

Reads benchmarks/{config}-batch{N}-c32.json for the three sweep configs and writes
benchmarks/batching-sweep.png (p50 latency and throughput vs batch size).

Run:
    uv run --extra plot python scripts/plot_results.py
"""

from __future__ import annotations

import json
from pathlib import Path

import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt


BENCHMARKS_DIR = Path(__file__).resolve().parent.parent / "benchmarks"
OUTPUT = BENCHMARKS_DIR / "batching-sweep.png"
BATCH_SIZES = [1, 8, 16, 32]
SERIES = {
    "PyTorch / CPU": "pytorch-cpu",
    "PyTorch / MPS": "pytorch-mps",
    "ONNX / CPU": "onnx-cpu",
}


def load(prefix: str) -> tuple[list[float], list[float]]:
    p50, tput = [], []
    for n in BATCH_SIZES:
        data = json.loads((BENCHMARKS_DIR / f"{prefix}-batch{n}-c32.json").read_text())
        summary = data["summary"]
        p50.append(summary["p50_latency_ms"])
        tput.append(summary["throughput_rps"])
    return p50, tput


def main() -> None:
    fig, (ax_latency, ax_tput) = plt.subplots(1, 2, figsize=(11, 4.5))

    for label, prefix in SERIES.items():
        p50, tput = load(prefix)
        ax_latency.plot(BATCH_SIZES, p50, marker="o", label=label)
        ax_tput.plot(BATCH_SIZES, tput, marker="o", label=label)

    ax_latency.set_title("p50 latency vs batch size")
    ax_latency.set_xlabel("max batch size")
    ax_latency.set_ylabel("p50 latency (ms)")

    ax_tput.set_title("Throughput vs batch size")
    ax_tput.set_xlabel("max batch size")
    ax_tput.set_ylabel("throughput (req/s)")

    for ax in (ax_latency, ax_tput):
        ax.set_xticks(BATCH_SIZES)
        ax.grid(True, alpha=0.3)
        ax.legend()

    fig.suptitle("Dynamic batching sweep — all-MiniLM-L6-v2, concurrency 32, 500 req, 1 text/req")
    fig.tight_layout()
    fig.savefig(OUTPUT, dpi=120)
    print(f"Wrote {OUTPUT}")


if __name__ == "__main__":
    main()