Files
hair/benchmark_steps_res.py
T
xsl 531dcb8279 docs: swap步数+重绘分辨率对比报告(热数据)
4图×2发型×(3步数档+3分辨率档) 热数据对比,48/48成功,0 OOM,峰值20.6GB。
- benchmark_steps_res.py: 测试脚本(预热+正式取热数据)
- benchmark_steps_res_report.py: 报告生成
- static/bench2_report.html: 对比报告
- static/bench2/: 48张结果图

结论: B维度 steps10→20 swap 3.0s→3.9s; C维度 res640比896省3s(comfy 4.3s vs 7.3s)
2026-07-26 17:44:59 +08:00

122 lines
5.4 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""swap步数 + 重绘分辨率 对比测试(热数据)。
每个组合: 预热1次(丢弃) + 正式测1次(取热数据)。
B维度: steps=10/15/20 (分辨率固定896)
C维度: 分辨率=640/896/1024 (steps固定15)
4图×2发型=8组 × 6档 × 2次(预热+正式) = 96次
"""
import base64
import json
import os
import time
from pathlib import Path
import requests
API = "http://127.0.0.1:8187/api/v1/debug/grow-timing"
TOKEN = "dev-shared-secret-2026"
OUT = Path("/home/ubuntu/hair/benchmark_out/bench2")
OUT.mkdir(parents=True, exist_ok=True)
IMGS = [
("asdf", "/home/ubuntu/hair/image/asdf.jpg"),
("qwer", "/home/ubuntu/hair/image/qwer.jpg"),
("girl2", "/home/ubuntu/hair/image/girl_img/girl2.jpg"),
("girl5", "/home/ubuntu/hair/image/girl_img/girl5.jpg"),
]
HAIRSTYLES = [(5, "wave", "波浪"), (3, "heart", "心形")]
# B维度: swap步数对比 (分辨率固定896)
B_STEPS = [10, 15, 20]
# C维度: 重绘分辨率对比 (steps固定15)
C_RES = [640, 896, 1024]
def call(img_path, hair_num, webui_steps=None, redraw_max_side=None, save_grown=None):
"""调调试接口。返回 dict。save_grown 非None时把结果图存到该路径。"""
data = {"hair_style": str(hair_num)}
if webui_steps is not None:
data["webui_steps"] = str(webui_steps)
if redraw_max_side is not None:
data["redraw_max_side"] = str(redraw_max_side)
t0 = time.perf_counter()
try:
with open(img_path, "rb") as f:
r = requests.post(API, headers={"X-Internal-Token": TOKEN},
files={"image_file": (os.path.basename(img_path), f, "image/jpeg")},
data=data, timeout=300)
wall = time.perf_counter() - t0
j = r.json()
if j.get("code") != 0:
return {"ok": False, "error": j.get("message", "")[:100], "wall": wall}
d = j["data"]
hs = d["per_hairstyle"][0]
if save_grown and hs.get("grown_b64"):
b = hs["grown_b64"].split(",")[1] if "," in hs["grown_b64"] else hs["grown_b64"]
with open(save_grown, "wb") as gf:
gf.write(base64.b64decode(b))
return {
"ok": hs.get("ok", False), "wall": wall,
"total_ms": d["total_ms"], "ctx_ms": d["extract_context_ms"],
"mask_ms": hs.get("mask_ms"), "swap_ms": hs.get("swap_ms"),
"blend_ms": hs.get("blend_ms"), "comfy_ms": hs.get("comfyui_redraw_ms"),
"error": hs.get("error"),
}
except Exception as e:
return {"ok": False, "error": str(e)[:100], "wall": time.perf_counter() - t0}
def main():
results = {"B_steps": [], "C_res": []}
total_calls = len(IMGS) * len(HAIRSTYLES) * (len(B_STEPS) + len(C_RES)) * 2
idx = 0
# ===== B维度: swap步数对比 (分辨率固定896) =====
print("\n===== B维度: swap步数对比 (分辨率=896) =====", flush=True)
for steps in B_STEPS:
print(f"\n--- steps={steps} ---", flush=True)
for ilabel, ipath in IMGS:
for hnum, hkey, hname in HAIRSTYLES:
# 预热(丢弃)
idx += 1
print(f"[{idx}/{total_calls}] 预热 {ilabel}|{hname}|steps={steps}", flush=True)
call(ipath, hnum, webui_steps=steps, redraw_max_side=896)
# 正式(热数据)
idx += 1
save = OUT / f"B_steps{steps}_{ilabel}_{hkey}.jpg"
print(f"[{idx}/{total_calls}] 正式 {ilabel}|{hname}|steps={steps}", flush=True)
r = call(ipath, hnum, webui_steps=steps, redraw_max_side=896, save_grown=save)
r["steps"] = steps; r["img"] = ilabel; r["hair"] = hkey; r["hair_name"] = hname
r["grown_path"] = str(save) if r.get("ok") else None
print(f" -> total={r.get('total_ms')}ms swap={r.get('swap_ms')}ms comfy={r.get('comfy_ms')}ms ok={r.get('ok')}", flush=True)
results["B_steps"].append(r)
# ===== C维度: 重绘分辨率对比 (steps固定15) =====
print("\n===== C维度: 重绘分辨率对比 (steps=15) =====", flush=True)
for res in C_RES:
print(f"\n--- res={res} ---", flush=True)
for ilabel, ipath in IMGS:
for hnum, hkey, hname in HAIRSTYLES:
idx += 1
print(f"[{idx}/{total_calls}] 预热 {ilabel}|{hname}|res={res}", flush=True)
call(ipath, hnum, webui_steps=15, redraw_max_side=res)
idx += 1
save = OUT / f"C_res{res}_{ilabel}_{hkey}.jpg"
print(f"[{idx}/{total_calls}] 正式 {ilabel}|{hname}|res={res}", flush=True)
r = call(ipath, hnum, webui_steps=15, redraw_max_side=res, save_grown=save)
r["res"] = res; r["img"] = ilabel; r["hair"] = hkey; r["hair_name"] = hname
r["grown_path"] = str(save) if r.get("ok") else None
print(f" -> total={r.get('total_ms')}ms swap={r.get('swap_ms')}ms comfy={r.get('comfy_ms')}ms ok={r.get('ok')}", flush=True)
results["C_res"].append(r)
with open(OUT / "results.json", "w", encoding="utf-8") as f:
json.dump(results, f, ensure_ascii=False, indent=2)
ok = sum(1 for r in results["B_steps"] + results["C_res"] if r.get("ok"))
print(f"\n✓ 完成: {ok}/{len(results['B_steps'])+len(results['C_res'])} 成功 -> {OUT/'results.json'}", flush=True)
if __name__ == "__main__":
main()