| """twlat 命令列介面。 |
| |
| twlat "这个程序有bug" # 單段轉換 |
| cat in.txt | twlat # 從 stdin 逐行轉換 |
| twlat -i in.txt -o out.txt # 檔案轉檔案 |
| twlat --preset taiwanize "视频" # 選操作點 |
| twlat --explain "他在那里" # 顯示逐項決策 |
| """ |
| from __future__ import annotations |
|
|
| import argparse |
| import json |
| import sys |
|
|
|
|
| def main(argv: list[str] | None = None) -> int: |
| ap = argparse.ArgumentParser( |
| prog="twlat", |
| description="中國大陸中文 → 臺灣正體中文(確定性、可解釋、離線)") |
| ap.add_argument("text", nargs="*", help="要轉換的文字;省略則讀 stdin") |
| ap.add_argument("-i", "--input", help="輸入檔(每行一段)") |
| ap.add_argument("-o", "--output", help="輸出檔") |
| ap.add_argument("--preset", default="balanced", |
| choices=["accuracy", "balanced", "taiwanize", "aggressive"], |
| help="操作點(預設 balanced)") |
| ap.add_argument("--device", default="cpu", |
| help="cpu/mps/cuda(預設 cpu;單執行緒吞吐最佳)") |
| ap.add_argument("--threads", type=int, default=1, |
| help="torch 執行緒數(預設 1,實測最快)") |
| ap.add_argument("--batch-size", type=int, default=8) |
| ap.add_argument("--explain", action="store_true", help="輸出逐項決策 JSON") |
| ap.add_argument("--ckpt", default=None) |
| ap.add_argument("--version", action="store_true") |
| a = ap.parse_args(argv) |
|
|
| import twlat |
| if a.version: |
| print(twlat.__version__) |
| return 0 |
|
|
| import torch |
| torch.set_num_threads(max(1, a.threads)) |
|
|
| if a.text: |
| lines = [" ".join(a.text)] |
| elif a.input: |
| with open(a.input, encoding="utf-8") as fh: |
| lines = [ln.rstrip("\n") for ln in fh] |
| else: |
| lines = [ln.rstrip("\n") for ln in sys.stdin] |
| if not lines: |
| return 0 |
|
|
| conv = twlat.Converter(ckpt=a.ckpt, device=a.device, preset=a.preset) |
|
|
| if a.explain: |
| out = [] |
| for r in conv.explain_batch(lines, batch_size=a.batch_size): |
| out.append({"text": r.text, |
| "decisions": [{"span": [d.start, d.end], |
| "from": d.source, "to": d.target, |
| "utility": round(d.utility, 3), |
| "rule_type": d.rule_type} |
| for d in r.decisions]}) |
| payload = json.dumps(out, ensure_ascii=False, indent=1) |
| else: |
| payload = "\n".join(conv.convert_batch(lines, batch_size=a.batch_size)) |
|
|
| if a.output: |
| with open(a.output, "w", encoding="utf-8") as fh: |
| fh.write(payload + "\n") |
| else: |
| print(payload) |
| return 0 |
|
|
|
|
| if __name__ == "__main__": |
| raise SystemExit(main()) |
|
|