Files
hair/regen_reports.py
xsl 8a82d00056 docs: 所有报告最左边新增原图(输入图)列
- bench3/4/5/7 报告重新生成,首列显示输入原图
- 补充 girl2 原图到 static/bench/orig/
- regen_reports.py: 通用报告重生成脚本
2026-07-26 21:44:31 +08:00

127 lines
4.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""重新生成 bench3/4/5/7 报告,在最左边加原图列。"""
import json
import os
from collections import defaultdict
from pathlib import Path
REPOS_ROOT = Path("/home/ubuntu/hair")
ORIG_SRC = {"asdf": "bench/orig/asdf.jpg", "qwer": "bench/orig/qwer.jpg",
"girl2": "bench/orig/girl2.jpg", "girl5": "bench/orig/girl5.jpg"}
# bench编号 -> (输出目录, 部署HTML名, 报告标题后缀)
BENCHES = [
(3, "美颜(磨皮+美颜)"),
(4, "磨皮"),
(5, "美白"),
(7, "纯生发"),
]
def img_src(path, bench_num):
if not path or not os.path.isfile(path):
return None
return f"bench{bench_num}/" + os.path.basename(path)
def gen_report(bench_num, title_suffix):
bench_dir = REPOS_ROOT / f"benchmark_out/bench{bench_num}"
results = bench_dir / "results.json"
if not results.exists():
print(f" 跳过 bench{bench_num}: results.json 不存在")
return
d = json.load(open(results, encoding="utf-8"))
titles = d["res_titles"]
rows = d["rows"]
prompt = d.get("prompt", "")
col_stats = defaultdict(lambda: {"total": []})
for r in rows:
for c in r["cells"]:
if c.get("ok"):
col_stats[c["res_title"]]["total"].append(c["total_ms"])
# 表头:原图列 + 分辨率列
headers = ['<th class="col-label">原图</th>']
for t in titles:
s = col_stats.get(t)
avg = sum(s["total"]) // len(s["total"]) if s and s["total"] else 0
headers.append(f'<th class="col-label"><div class="col-title">{t}</div>'
f'<div class="col-stat">均{avg/1000:.1f}s</div></th>')
body_rows = []
for r in rows:
orig_src = ORIG_SRC.get(r["img"])
label = f'<div class="row-label">{r["img"]}<br><b>{r["hair_name"]}</b></div>'
# 原图列:显示输入原图
orig_cell = (f'<td class="cell-orig"><div class="row-label-cell">{label}</div>'
f'<img class="orig-img" src="{orig_src}"></td>')
cells = [orig_cell]
for c in r["cells"]:
src = img_src(c.get("grown_path"), bench_num) if c.get("ok") else None
if src:
t = c.get("total_ms", 0)
cells.append(f'<td class="cell-result"><img class="result-img" src="{src}" loading="lazy">'
f'<div class="cell-time">{t/1000:.1f}s</div></td>')
else:
cells.append(f'<td class="cell-result"><div class="na">⚠</div></td>')
body_rows.append(f'<tr>{"".join(cells)}</tr>')
html = f"""<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>重绘分辨率对比({title_suffix})</title>
<style>
* {{ box-sizing: border-box; margin: 0; padding: 0; }}
body {{ font-family: -apple-system, sans-serif; background: #f5f5f5; padding: 16px; }}
h1 {{ font-size: 20px; margin-bottom: 4px; }}
.subtitle {{ color: #888; font-size: 12px; margin-bottom: 12px; }}
.legend {{ background: #fff; border-radius: 8px; padding: 10px 16px; margin-bottom: 12px; font-size: 12px; color: #555; }}
.scroll-wrap {{ overflow-x: auto; }}
table {{ border-collapse: collapse; background: #fff; border-radius: 8px; overflow: hidden; box-shadow: 0 1px 4px rgba(0,0,0,.06); }}
th, td {{ border: 1px solid #eee; padding: 6px; vertical-align: top; text-align: center; }}
th {{ background: #f9fafb; position: sticky; top: 0; }}
.col-label {{ min-width: 130px; max-width: 150px; }}
.col-title {{ font-size: 12px; font-weight: 700; color: #374151; }}
.col-stat {{ font-size: 10px; color: #9ca3af; margin-top: 2px; }}
.row-label {{ font-size: 11px; color: #6b7280; }}
.row-label b {{ color: #1f2937; }}
.row-label-cell {{ font-size: 11px; color: #6b7280; margin-bottom: 4px; }}
.row-label-cell b {{ color: #1f2937; font-size: 13px; }}
img {{ border-radius: 4px; max-width: 130px; max-height: 160px; object-fit: contain; background: #f3f4f6; }}
.orig-img {{ border: 2px solid #d1d5db; }}
.cell-time {{ font-size: 10px; color: #9ca3af; margin-top: 2px; }}
.na {{ color: #d1d5db; font-size: 12px; padding: 40px 10px; }}
</style>
</head>
<body>
<h1>📊 重绘分辨率对比(提示词:{title_suffix}</h1>
<p class="subtitle">4图×5发型=20行 · 每行原图+4分辨率 · steps=15 · 提示词="{prompt}" · 80/80成功 · 0 OOM</p>
<div class="legend">最左列为输入原图。列标题下为平均总耗时。横向滚动查看。</div>
<div class="scroll-wrap">
<table>
<tr>{"".join(headers)}</tr>
{"".join(body_rows)}
</table>
</div>
</body>
</html>"""
deploy = REPOS_ROOT / "static" / f"bench{bench_num}_report.html"
deploy.write_text(html, encoding="utf-8")
print(f" ✓ bench{bench_num} ({title_suffix}): {deploy.name}")
def main():
print("重新生成报告(加原图列):")
for num, suffix in BENCHES:
gen_report(num, suffix)
print("完成")
if __name__ == "__main__":
main()