{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# 造序注音 — ZaoSeq Labs Research Preview\n",
        "造序科技（籌備中）。在自己的 Kaggle session 執行；不是公開 API。\n",
        "開啟 Internet，選 GPU（可用時）。首次安裝與下載需要時間。遵守 Kaggle 配額，不設置保活或自動重啟。\n",
        "使用下方公開範例；Notebook 儲存版本可能保存 cell 輸入與輸出，請勿輸入機密資料。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Download the public source archive from the Labs site.\n",
        "import io, zipfile, urllib.request, pathlib, subprocess, sys\n",
        "root = pathlib.Path(\"/kaggle/working/zaoseq-bopomofo\")\n",
        "root.mkdir(exist_ok=True)\n",
        "archive = urllib.request.urlopen(\"https://lab.zaoseq.com/bopomofo/source.zip\").read()\n",
        "with zipfile.ZipFile(io.BytesIO(archive)) as z:\n",
        "    for item in z.infolist():\n",
        "        target = (root / item.filename).resolve()\n",
        "        if not target.is_relative_to(root.resolve()): raise ValueError(\"Unsafe archive path\")\n",
        "    z.extractall(root)\n",
        "subprocess.check_call([sys.executable, \"-m\", \"pip\", \"install\", \"-q\", \"-e\", str(root)+\"[laya,web]\"])\n",
        "sys.path.insert(0, str(root / \"src\"))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "from zaoseq_bopomofo.service import default_components, parse_input, result_to_json\n",
        "from zaoseq_bopomofo.ranking.base import RankingContext\n",
        "parts = default_components()\n",
        "parts.laya_model.load()\n",
        "print(\"Model loaded. The first inference may take longer.\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Real model output; no expected answer is forced.\n",
        "left_context = \"我明天會\"\n",
        "reading = \"ㄗㄞˋ ㄑㄩˋ ㄊㄞˊ ㄅㄟˇ\"\n",
        "readings = parse_input(reading, parts.inventory)\n",
        "candidates = parts.generator.candidates_for(readings)\n",
        "for name, ranker in parts.rankers.items():\n",
        "    result = result_to_json(ranker.rank(RankingContext(left_context, readings), candidates))\n",
        "    print(name, result[\"status\"], result[\"latency_ms\"], \"ms\")\n",
        "    print([c[\"text\"] for c in result[\"candidates\"][:4]])\n",
        "    if result[\"fallback\"]: print(\"Fallback:\", result[\"fallback\"][\"reason\"])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Research boundary\n",
        "Preliminary DEV results: zero-shot Laya and confidence-aware Hybrid have not demonstrated reliable improvement over the baseline. DEV was used during architecture development and is not an untouched final test set. No personalization or training is performed."
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}