v0.9: parallelize phase4 and add model/search playbooks

This commit is contained in:
kai
2026-04-24 10:19:48 +08:00
parent c444007f04
commit c93fce5078
13 changed files with 626 additions and 100 deletions
+75 -36
View File
@@ -19,6 +19,7 @@
from __future__ import annotations
import argparse
import concurrent.futures
import json
import sys
import time
@@ -141,6 +142,12 @@ def main() -> int:
default=None,
help="最多润色前 N 个未缓存的块(调试用)",
)
parser.add_argument(
"--workers",
type=int,
default=4,
help="并发润色 worker 数(默认 4;设为 1 回退串行)",
)
args = parser.parse_args()
load_secrets()
@@ -167,50 +174,82 @@ def main() -> int:
total_cn = sum(count_chinese_chars(b.content) for b in blocks)
print(f"Source: {src_path.relative_to(project_root)}")
print(f"Blocks: {len(blocks)} | total Chinese chars: {total_cn:,}")
print(f"Model: {args.model} | temperature: {args.temperature}")
workers = max(1, args.workers)
print(f"Model: {args.model} | temperature: {args.temperature} | workers: {workers}")
print()
start = time.time()
translated_this_run = 0
todo: list[MarkdownBlock] = []
cached_count = 0
notes_records: list[dict] = []
for b in blocks:
chunk_path = chunks_dir / f"{b.order:03d}-{b.anchor}.md"
if only_orders is not None and b.order not in only_orders:
continue
if chunk_path.exists() and not args.force:
cached_count += 1
print(f" [ok ] #{b.order:03d} {b.short_title} (cached)")
continue
if args.limit is not None and len(todo) >= args.limit:
continue
todo.append(b)
if todo:
print(f"To polish this run: {len(todo)} blocks | cached: {cached_count}")
print()
with ZenMuxClient(log_file=log_file) as client:
for b in blocks:
def run_one(b: MarkdownBlock) -> tuple[MarkdownBlock, str, str, float]:
chunk_path = chunks_dir / f"{b.order:03d}-{b.anchor}.md"
if only_orders is not None and b.order not in only_orders:
continue
if chunk_path.exists() and not args.force:
print(f" [ok ] #{b.order:03d} {b.short_title} (cached)")
continue
if args.limit is not None and translated_this_run >= args.limit:
continue
label = f"#{b.order:03d} L{b.level} {count_chinese_chars(b.content):>4}{b.short_title}"
print(f" [... ] {label} ", end="", flush=True)
t0 = time.time()
try:
polished, notes = polish_block(
client,
b,
model=args.model,
system_prompt=system_prompt,
temperature=args.temperature,
)
except (ZenMuxError, RuntimeError) as e:
print(f"\n [FAIL] {label}\n {e}")
continue
elapsed = time.time() - t0
polished, notes = polish_block(
client,
b,
model=args.model,
system_prompt=system_prompt,
temperature=args.temperature,
)
chunk_path.write_text(polished + "\n", encoding="utf-8")
cn = count_chinese_chars(polished)
before_cn = count_chinese_chars(b.content)
delta = cn - before_cn
sign = "+" if delta >= 0 else ""
translated_this_run += 1
if notes:
notes_records.append(
{"order": b.order, "anchor": b.anchor, "title": b.short_title, "notes": notes}
)
print(f"\r [done] {label}{cn}字 ({sign}{delta}, {elapsed:4.1f}s)")
return b, polished, notes, time.time() - t0
if workers == 1:
for b in todo:
label = f"#{b.order:03d} L{b.level} {count_chinese_chars(b.content):>4}{b.short_title}"
print(f" [... ] {label} ", end="", flush=True)
try:
block, polished, notes, elapsed = run_one(b)
except (ZenMuxError, RuntimeError) as e:
print(f"\n [FAIL] {label}\n {e}")
continue
cn = count_chinese_chars(polished)
before_cn = count_chinese_chars(block.content)
delta = cn - before_cn
sign = "+" if delta >= 0 else ""
if notes:
notes_records.append(
{"order": block.order, "anchor": block.anchor, "title": block.short_title, "notes": notes}
)
print(f"\r [done] {label}{cn}字 ({sign}{delta}, {elapsed:4.1f}s)")
else:
with concurrent.futures.ThreadPoolExecutor(max_workers=workers) as pool:
futures = {pool.submit(run_one, b): b for b in todo}
for fut in concurrent.futures.as_completed(futures):
b = futures[fut]
label = f"#{b.order:03d} L{b.level} {count_chinese_chars(b.content):>4}{b.short_title}"
try:
block, polished, notes, elapsed = fut.result()
except (ZenMuxError, RuntimeError) as e:
print(f" [FAIL] {label}\n {e}")
continue
cn = count_chinese_chars(polished)
before_cn = count_chinese_chars(block.content)
delta = cn - before_cn
sign = "+" if delta >= 0 else ""
if notes:
notes_records.append(
{"order": block.order, "anchor": block.anchor, "title": block.short_title, "notes": notes}
)
print(f" [done] {label}{cn}字 ({sign}{delta}, {elapsed:4.1f}s)")
# 汇总
merged: list[str] = []