hoang.nguyen6
deploy
f66643d unverified
Raw
History Blame Contribute Delete
5 kB
"""Gộp latency + COMET -> bảng markdown cho báo cáo (§10).
python -m benchmark.translation.aggregate --out-dir benchmark/translation/out
Đọc: latency.jsonl, comet_scores.json
Ghi: benchmark/translation/out/report.md
"""
from __future__ import annotations
import argparse
import json
import statistics as stats
from collections import defaultdict
from pathlib import Path
def _pct(xs, p):
if not xs:
return 0.0
s = sorted(xs)
k = (len(s) - 1) * p / 100
lo, hi = int(k), min(int(k) + 1, len(s) - 1)
return s[lo] + (s[hi] - s[lo]) * (k - lo)
def load_latency(path: Path):
"""Return per-system aggregate over latency-measure records."""
recs = defaultdict(list)
if not path.exists():
return {}
for line in open(path, encoding="utf-8"):
if not line.strip():
continue
r = json.loads(line)
if r.get("mode") == "latency-measure":
recs[r["system"]].append(r)
agg = {}
for sys_, rs in recs.items():
walls = [r["wall_s"] for r in rs]
total_w = sum(walls)
tok_out = sum(r.get("tok_out", 0) or 0 for r in rs)
src_words = sum(r.get("src_words", 0) or 0 for r in rs)
# s / 1000 source words — chuẩn hoá latency theo độ dài, so được doc dài/ngắn.
s_per_kword = [1000 * r["wall_s"] / r["src_words"]
for r in rs if r.get("src_words")]
# Tỉ lệ giãn ký tự dst/src (ràng buộc ±15% là theo ký tự) — theo từng doc.
char_ratio = [r["dst_chars"] / r["src_chars"]
for r in rs if r.get("src_chars") and r.get("dst_chars")]
agg[sys_] = {
"s_per_doc_median": round(stats.median(walls), 2),
"s_per_doc_p25": round(_pct(walls, 25), 2),
"s_per_doc_p95": round(_pct(walls, 95), 2),
"src_words_per_s": round(src_words / total_w, 2) if total_w else 0,
"s_per_kword_median": round(stats.median(s_per_kword), 2) if s_per_kword else 0,
"char_ratio_median": round(stats.median(char_ratio), 3) if char_ratio else 0,
"out_tok_per_s": round(tok_out / total_w, 1) if total_w else 0,
"retries": sum(r.get("n_retry", 0) or 0 for r in rs),
"n": len(rs),
}
return agg
def md_table(headers, rows) -> str:
out = ["| " + " | ".join(headers) + " |",
"|" + "|".join("---" for _ in headers) + "|"]
for row in rows:
out.append("| " + " | ".join(str(c) for c in row) + " |")
return "\n".join(out)
def main() -> None:
ap = argparse.ArgumentParser()
ap.add_argument("--out-dir", default="benchmark/translation/out")
args = ap.parse_args()
d = Path(args.out_dir)
comet = json.loads((d / "comet_scores.json").read_text()) if (d / "comet_scores.json").exists() else {}
lat = load_latency(d / "latency.jsonl")
md = ["# Kết quả đánh giá — bảng tổng hợp\n"]
# (A) per-language COMET × system
langs = sorted({lang for rel in comet.values() for lang in rel.get("by_language", {})})
if langs:
systems = list(comet)
md.append("## (A) COMET-DA theo ngôn ngữ × hệ\n")
headers = ["Target"] + systems
rows = []
for lang in langs:
row = [lang]
for s in systems:
m = comet[s]["by_language"].get(lang, {}).get("comet", {})
row.append(m.get("mean", "—"))
rows.append(row)
md.append(md_table(headers, rows) + "\n")
# (B) system × quality × latency × cost
md.append("## (B) So sánh hệ — quality × latency\n")
headers = ["System", "COMET-DA", "chrF++", "s/doc (median)", "p25–p95",
"s/1k-words", "words/s", "len ratio (dst/src)", "len-viol%",
"out tok/s", "429 retries", "fallback%"]
rows = []
for s, rel in comet.items():
o = rel["overall"]
L = lat.get(s, {})
rows.append([
s, o["comet"]["mean"], o["chrf"]["mean"],
L.get("s_per_doc_median", "—"),
f'{L.get("s_per_doc_p25","—")}{L.get("s_per_doc_p95","—")}',
L.get("s_per_kword_median", "—"),
L.get("src_words_per_s", "—"),
L.get("char_ratio_median", "—"),
o.get("len_viol_pct", "—"),
L.get("out_tok_per_s", "—"), L.get("retries", "—"), o["fallback_pct"],
])
md.append(md_table(headers, rows) + "\n")
# per-domain
for s, rel in comet.items():
md.append(f"### per-domain — {s}\n")
rows = [[dom, m["comet"]["mean"], m["comet"]["n"]] for dom, m in rel["by_domain"].items()]
md.append(md_table(["domain", "COMET-DA", "n"], rows) + "\n")
report = "\n".join(md)
d.mkdir(parents=True, exist_ok=True)
(d / "report.md").write_text(report, encoding="utf-8")
print(report)
print(f"\nSaved -> {d/'report.md'}")
if __name__ == "__main__":
main()