plot: extend batch-scaling curves with saturated-throughput ceiling
Beyond a mapping's SIP capacity (16/C) the throughput plateaus: extra users run in waves at the saturated rate, they are not un-runnable. Draw a dashed horizontal extension at the ceiling so 1-kv-per-cube (cap 2) reads as saturating, not stopping, at B=2. Caption updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 72 KiB |
@@ -271,10 +271,13 @@ long-context batch sweep is 2H work (\S\ref{sec:future}).
|
|||||||
\si{\micro\second}) versus the number of concurrent decode users on one SIP,
|
\si{\micro\second}) versus the number of concurrent decode users on one SIP,
|
||||||
each user on a disjoint CUBE group. Each mapping scales almost linearly with
|
each user on a disjoint CUBE group. Each mapping scales almost linearly with
|
||||||
$B$ up to its SIP capacity $16/C$---\textsf{1-kv-per-cube} saturates at two
|
$B$ up to its SIP capacity $16/C$---\textsf{1-kv-per-cube} saturates at two
|
||||||
users, \textsf{8-kv-per-cube} at sixteen. The dense mapping reaches the
|
users, \textsf{8-kv-per-cube} at sixteen. Solid segments are measured
|
||||||
highest throughput; the spread mapping is latency-optimal but
|
concurrent runs; the dashed extensions are the saturated-throughput ceiling
|
||||||
capacity-limited. Concurrent users overlap to within
|
beyond capacity, where further users run in waves at that sustained rate
|
||||||
\SI{3}{}--\SI{5}{\percent} of the single-user latency.}
|
(so the SIP is full, not idle). The dense mapping reaches the highest
|
||||||
|
ceiling; the spread mapping is latency-optimal but capacity-limited.
|
||||||
|
Concurrent users overlap to within \SI{3}{}--\SI{5}{\percent} of the
|
||||||
|
single-user latency.}
|
||||||
\label{fig:gqa-batch}
|
\label{fig:gqa-batch}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ def main():
|
|||||||
contexts = sorted({int(r["S_kv"]) for r in rows})
|
contexts = sorted({int(r["S_kv"]) for r in rows})
|
||||||
fig, axes = plt.subplots(1, len(contexts), figsize=(6.5 * len(contexts), 4.5),
|
fig, axes = plt.subplots(1, len(contexts), figsize=(6.5 * len(contexts), 4.5),
|
||||||
squeeze=False)
|
squeeze=False)
|
||||||
|
xmax = max(int(r["B"]) for r in rows) # largest SIP capacity (= 16)
|
||||||
for col, S in enumerate(contexts):
|
for col, S in enumerate(contexts):
|
||||||
ax = axes[0][col]
|
ax = axes[0][col]
|
||||||
for m in MODES:
|
for m in MODES:
|
||||||
@@ -40,8 +41,15 @@ def main():
|
|||||||
if not pts:
|
if not pts:
|
||||||
continue
|
continue
|
||||||
xs, ys = zip(*pts)
|
xs, ys = zip(*pts)
|
||||||
|
# Measured: concurrent users up to the SIP capacity 16/C.
|
||||||
ax.plot(xs, ys, marker="o", color=MODE_COLOR[m],
|
ax.plot(xs, ys, marker="o", color=MODE_COLOR[m],
|
||||||
label=MODE_LABEL[m])
|
label=MODE_LABEL[m])
|
||||||
|
# Beyond capacity the SIP is full: extra users run in waves at
|
||||||
|
# the saturated rate, so throughput plateaus. Draw that ceiling
|
||||||
|
# as a dashed extension (projected, not concurrently measured).
|
||||||
|
if xs[-1] < xmax:
|
||||||
|
ax.plot([xs[-1], xmax], [ys[-1], ys[-1]],
|
||||||
|
linestyle="--", color=MODE_COLOR[m], alpha=0.55)
|
||||||
ax.annotate(f"{ys[-1]:.2f}", (xs[-1], ys[-1]),
|
ax.annotate(f"{ys[-1]:.2f}", (xs[-1], ys[-1]),
|
||||||
textcoords="offset points", xytext=(4, 4), fontsize=8)
|
textcoords="offset points", xytext=(4, 4), fontsize=8)
|
||||||
ax.set_title(f"S_kv = {S // 1024}K")
|
ax.set_title(f"S_kv = {S // 1024}K")
|
||||||
|
|||||||
Reference in New Issue
Block a user