Download docs/benchmarks/plot-mimo2.py from staccs/ds4-winhip: direct link, hf CLI and curl.
- Browser
- Download file 6.26 kB
-
https://huggingface.co/staccs/ds4-winhip/resolve/main/docs/benchmarks/plot-mimo2.py
- Command line
-
hf download hf://staccs/ds4-winhip/docs/benchmarks/plot-mimo2.py
-
curl -L -o plot-mimo2.py https://huggingface.co/staccs/ds4-winhip/resolve/main/docs/benchmarks/plot-mimo2.py
6.26 kB
| #!/usr/bin/env python3 | |
| """Plot three-run MiMo card sweeps; requires matplotlib. | |
| Example: --series baseline='09ce6e6 (#56)' --series final='COMMIT' | |
| Each prefix resolves to PREFIX-{1,2,3}.csv in --data. | |
| """ | |
| import argparse | |
| import csv | |
| import hashlib | |
| import json | |
| import math | |
| from pathlib import Path | |
| from statistics import median | |
| FRONTIERS = list(range(2048, 65537, 2048)) | |
| METRICS = (("prefill_tps", "Incremental prefill"), ("gen_tps", "Greedy decode")) | |
| COLORS = ("#687789", "#087f8c", "#b4532a", "#7657a8") | |
| def load_runs(data, prefix): | |
| runs, sources = [], [] | |
| for repeat in range(1, 4): | |
| path = data / f"{prefix}-{repeat}.csv" | |
| with path.open() as source: | |
| rows = list(csv.DictReader(source)) | |
| if [int(row["ctx_tokens"]) for row in rows] != FRONTIERS: | |
| raise ValueError(f"{path}: expected all 32 frontiers from 2K to 64K") | |
| if any(int(row["prefill_tokens"]) != 2048 or int(row["gen_tokens"]) != 128 | |
| for row in rows): | |
| raise ValueError(f"{path}: expected 2048 incremental + 128 generated tokens") | |
| for metric, _ in METRICS: | |
| if any(not math.isfinite(float(row[metric])) or float(row[metric]) <= 0 | |
| for row in rows): | |
| raise ValueError(f"{path}: invalid {metric}") | |
| runs.append(rows) | |
| sources.append({"file": path.name, "sha256": hashlib.sha256(path.read_bytes()).hexdigest()}) | |
| return runs, sources | |
| def summarize(runs): | |
| result = {} | |
| for metric, _ in METRICS: | |
| columns = list(zip(*[[float(row[metric]) for row in run] for run in runs])) | |
| center = [median(column) for column in columns] | |
| result[metric] = { | |
| "median": center, | |
| "min": [min(column) for column in columns], | |
| "max": [max(column) for column in columns], | |
| "retention_64k_over_2k": center[-1] / center[0], | |
| } | |
| return result | |
| def plot(series, out, note, metrics=METRICS): | |
| import matplotlib | |
| matplotlib.use("Agg") | |
| import matplotlib.pyplot as plt | |
| plt.rcParams.update({"font.size": 11, "axes.spines.top": False, | |
| "axes.spines.right": False, "savefig.facecolor": "white"}) | |
| single_panel = len(metrics) == 1 | |
| fig, axes = plt.subplots(len(metrics), 1, | |
| figsize=(11, 6.5 if single_panel else 8), | |
| sharex=True, squeeze=False) | |
| axes = axes[:, 0] | |
| fig.suptitle("MiMo-V2.6-Flash-RL · MQ-IQ2-XXS-XS-Q8", fontsize=17, | |
| fontweight="bold", y=0.98) | |
| fig.text(0.5, 0.91 if single_panel else 0.935, | |
| "One DGX Spark / GB10 · 2K–64K", ha="center", color="#4b5563") | |
| x = [frontier // 1024 for frontier in FRONTIERS] | |
| for ax, (metric, heading) in zip(axes, metrics): | |
| for index, entry in enumerate(series): | |
| values = entry["metrics"][metric] | |
| color = COLORS[index % len(COLORS)] | |
| if "min" in values and "max" in values: | |
| ax.fill_between(x, values["min"], values["max"], color=color, alpha=0.16, | |
| linewidth=0) | |
| ax.plot(x, values["median"], color=color, linewidth=2, | |
| label=f'{entry["label"]} · 64K: {values["median"][-1]:,.2f} tok/s') | |
| ax.set_title(heading, loc="left", fontsize=13) | |
| ax.set_ylabel("Tokens / second") | |
| ax.grid(alpha=0.2) | |
| ax.legend(loc="best", framealpha=0.92) | |
| ax.margins(y=0.16) | |
| ax.set_ylim(bottom=0) | |
| axes[-1].set_xlabel("Context tokens (K = 1,024)") | |
| axes[-1].set_xticks([2, 8, 16, 24, 32, 40, 48, 56, 64]) | |
| axes[-1].set_xlim(2, 64) | |
| fig.text(0.5, 0.075 if single_panel else 0.06, | |
| "Curves: per-frontier medians; bands, where recorded: observed min–max of three processes.\n" | |
| "2,048-token incremental prefill + 128 greedy tokens per frontier; one warm session per process.\n" | |
| + note, ha="center", va="center", fontsize=9, color="#4b5563", linespacing=1.6) | |
| fig.subplots_adjust(top=0.82 if single_panel else 0.88, | |
| bottom=0.25 if single_panel else 0.17, | |
| left=0.1, right=0.97, hspace=0.3) | |
| fig.savefig(out, dpi=180) | |
| plt.close(fig) | |
| def main(): | |
| parser = argparse.ArgumentParser(description=__doc__) | |
| parser.add_argument("--data", type=Path, | |
| default=Path(__file__).with_name("mimo2-2026-09-23")) | |
| parser.add_argument("--series", action="append", required=True, metavar="PREFIX=LABEL") | |
| parser.add_argument("--out", type=Path, required=True) | |
| parser.add_argument("--metric", choices=("both", "prefill", "decode"), default="both") | |
| parser.add_argument("--note", required=True, help="Verified artifact/MTP/clock conditions") | |
| args = parser.parse_args() | |
| series = [] | |
| prefixes = set() | |
| for value in args.series: | |
| prefix, separator, label = value.partition("=") | |
| if not separator or not prefix or not label or prefix in prefixes: | |
| parser.error("each series must have a unique PREFIX and a nonempty LABEL") | |
| prefixes.add(prefix) | |
| runs, sources = load_runs(args.data, prefix) | |
| series.append({"prefix": prefix, "label": label, "sources": sources, | |
| "metrics": summarize(runs)}) | |
| comparison = {} | |
| if len(series) > 1: | |
| for metric, _ in METRICS: | |
| baseline = series[0]["metrics"][metric] | |
| final = series[-1]["metrics"][metric] | |
| comparison[metric] = { | |
| "final_vs_first_gain_pct": [100 * (new / old - 1) for old, new in | |
| zip(baseline["median"], final["median"])], | |
| "retention_change_percentage_points": 100 * ( | |
| final["retention_64k_over_2k"] - baseline["retention_64k_over_2k"]), | |
| } | |
| metrics = METRICS if args.metric == "both" else (METRICS[0 if args.metric == "prefill" else 1],) | |
| plot(series, args.out, args.note, metrics) | |
| args.out.with_suffix(".json").write_text(json.dumps({ | |
| "frontiers": FRONTIERS, "note": args.note, "plotted_metric": args.metric, "series": series, | |
| "final_vs_first": comparison, | |
| }, indent=2) + "\n") | |
| if __name__ == "__main__": | |
| main() | |