| 02-P-NBL/round-4/README.md | ●●●●● patch | view | raw | blame | history | |
| 02-P-NBL/round-4/engineering-tasks.md | ●●●●● patch | view | raw | blame | history | |
| 02-P-NBL/round-4/prd.md | ●●●●● patch | view | raw | blame | history | |
| 02-P-NBL/round-4/qa-test-plan.md | ●●●●● patch | view | raw | blame | history | |
| 02-P-NBL/round-4/todo-list.md | ●●●●● patch | view | raw | blame | history |
02-P-NBL/round-4/README.md
New file @@ -0,0 +1,72 @@ # Round 4:Parakeet English 高级模型 状态:v0.1 启动稿 所属子项目:`02-P-NBL` Round:Round 4 基线版本:`2.1.21 build20260603.1327` 基线 commit:`7bedb18` 工作分支:`codex/round4-parakeet-english` 日期:2026-06-03 ## 1. 本轮目标 Round 4 的目标是让 English 用户可以主动选择 Parakeet 高级英文模型: ```text English effective language -> Moonshine 默认模型 English 用户主动选择 -> Parakeet English 高级模型 ``` 中文路径保持不变: ```text Chinese effective language -> sensevoice-zh -> SenseVoice ``` ## 2. 本轮文档 - [`prd.md`](prd.md):产品需求和验收边界 - [`engineering-tasks.md`](engineering-tasks.md):研发任务拆解 - [`qa-test-plan.md`](qa-test-plan.md):QA 测试计划 - [`todo-list.md`](todo-list.md):本轮执行 Todo ## 3. 关键技术确认 当前项目使用 `github.com/k2-fsa/sherpa-onnx-go-macos v1.12.24`,该版本已有 offline transducer 配置: ```go config.ModelConfig.Transducer.Encoder config.ModelConfig.Transducer.Decoder config.ModelConfig.Transducer.Joiner config.ModelConfig.Tokens config.ModelConfig.ModelType = "nemo_transducer" ``` 因此 Round 4 不需要先升级 sherpa-onnx Go 绑定。 本轮选择的 Parakeet 包: ```text sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-non-streaming ``` 下载包大小: ```text 501350460 bytes ``` Required files: ```text encoder.int8.onnx decoder.int8.onnx joiner.int8.onnx tokens.txt ``` ## 4. 资料依据 - sherpa-onnx NeMo transducer models:<https://k2-fsa.github.io/sherpa/onnx/pretrained_models/offline-transducer/nemo-transducer-models.html> - Parakeet unified source model:<https://huggingface.co/nvidia/parakeet-unified-en-0.6b> - sherpa-onnx model asset:<https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-non-streaming.tar.bz2> 02-P-NBL/round-4/engineering-tasks.md
New file @@ -0,0 +1,237 @@ # Round 4 研发任务拆解:Parakeet English 高级模型 状态:v0.1 研发拆解稿 所属子项目:`02-P-NBL` Round:Round 4 日期:2026-06-03 输入文档: - [`prd.md`](prd.md) - [`../engineering-plan.md`](../engineering-plan.md) - [`../plan.md`](../plan.md) ## 1. 研发目标 让 English 用户可以主动下载并切换到 Parakeet English,同时保持 Moonshine 默认路径和中文 SenseVoice 路径不退化。 ## 2. 交付边界 ### 2.1 必须交付 - `parakeet-en` model profile。 - `BackendNemoTransducer` backend kind。 - Parakeet required files 校验。 - Parakeet sherpa config builder。 - 模型选择 API: - 列出当前语言可用模型。 - 获取每个模型安装状态。 - 选择已安装模型。 - 下载并选择未安装模型。 - English 设置页模型选择 UI。 - Moonshine 和 Parakeet 互相切换。 - 下载失败保护。 - 开发自查、代码复审、QA handoff。 ### 2.2 明确不交付 - Qwen3-ASR。 - 欧洲语言 UI。 - 多 Parakeet 变体选择。 - 自动删除模型。 - 正式签名和 notarization。 ## 3. 推荐任务顺序 ```text T0 现状确认 T1 Parakeet profile T2 Nemo transducer backend builder T3 模型选择服务 API T4 设置页模型选择 UI T5 下载/切换状态处理 T6 单元测试和前端构建 T7 代码复审 T8 QA handoff T9 测试包准备 ``` ## 4. 任务明细 ### T0:现状确认 重点文件: - `privatevoice.src/internal/model/profile.go` - `privatevoice.src/internal/model/registry.go` - `privatevoice.src/internal/model/resolver.go` - `privatevoice.src/internal/engine/engine.go` - `privatevoice.src/internal/engine/engine_darwin.go` - `privatevoice.src/services/engine_service.go` - `privatevoice.src/frontend/src/components/settings/GeneralPage.svelte` 完成标准: - 明确 Round 3 current model resolver 行为。 - 明确设置页现有语言切换路径。 - 明确前端能否复用 `EngineService.DownloadCurrentModel()`。 ### T1:Parakeet profile 工作内容: - 新增常量: - `ParakeetModelID = "parakeet-en"` - `BackendNemoTransducer = "nemo_transducer"` - 新增 `parakeet-en` profile。 - 配置 required files: - `encoder.int8.onnx` - `decoder.int8.onnx` - `joiner.int8.onnx` - `tokens.txt` - `ProviderOrder` 使用 `cpu`。 - `DownloadURLs` 使用官方 unified-en 0.6b int8 URL。 完成标准: - `GetModelProfile("parakeet-en")` 可返回完整 profile。 - `ValidateModelDir(parakeet-en)` 校验准确。 - profile 不改变 English 默认模型,English 默认仍是 `moonshine-en`。 ### T2:Nemo transducer backend builder 工作内容: - `NewWithResolvedModel` 支持 `BackendNemoTransducer`。 - 新增 `buildNemoTransducerConfig`。 - 设置: ```go Transducer.Encoder = resolved.Files["encoder"] Transducer.Decoder = resolved.Files["decoder"] Transducer.Joiner = resolved.Files["joiner"] Tokens = resolved.Files["tokens"] ModelType = "nemo_transducer" Provider = "cpu" ``` 完成标准: - Parakeet 引擎可初始化。 - `HardwareInfo()` 显示 `Parakeet English · CPU`。 - 未知 backend 仍返回明确错误。 ### T3:模型选择服务 API 工作内容: - 新增或扩展服务 API: - `ListModelOptions()` - `SelectModel(modelID string)` - `DownloadModelByID(modelID string)` - `DeleteModel(modelID string)` 可暂缓,不作为本轮强制交付。 - 选择模型时: - 合法性校验。 - 语言兼容性校验。 - 未安装模型不能直接选择,应提示下载。 - 已安装模型选择后设置 `ModelSelectionMode=manual`。 - 更新 `SelectedModelID`。 - 触发 engine reload。 完成标准: - English 可选 Moonshine/Parakeet。 - 中文不自动选择 Parakeet。 - 选择非法模型返回错误,不写坏配置。 ### T4:设置页模型选择 UI 工作内容: - 在设置页语言区域附近新增模型选择区域。 - English 显示 Moonshine 和 Parakeet。 - 中文至少显示 SenseVoice。 - UI 显示: - 当前使用。 - 已安装/未安装。 - 下载大小。 - 下载/使用按钮。 - 下载中进度。 完成标准: - English 用户能从 UI 下载 Parakeet。 - 下载完成后能使用 Parakeet。 - 能切回 Moonshine。 - UI 不显示误导性默认策略。 ### T5:下载/切换状态处理 工作内容: - 下载期间禁用重复点击。 - 下载失败后保留原模型。 - 下载成功后切换到目标模型。 - 切换失败时回到原模型或显示 error,不破坏配置。 完成标准: - Parakeet 下载失败不破坏 Moonshine。 - Parakeet 初始化失败不破坏 SenseVoice。 - `.downloads`、`.staging` 不被判定为可用模型。 ### T6:测试 后端: ```bash cd privatevoice.src go test ./... -count=1 ``` 前端: ```bash cd privatevoice.src/frontend npm run build ``` 检查: ```bash git diff --check ``` 完成标准: - 全部通过。 - 关键测试覆盖 profile、resolver、backend、服务 API。 ### T7:代码复审 复审重点: - 是否保持 Moonshine 默认。 - 是否存在未安装模型直接切换。 - 是否存在下载失败破坏旧模型。 - 是否在中文路径误触发 Parakeet。 - UI 状态是否会误导用户。 ### T8:QA handoff 交付: - QA handoff 文档。 - 开发自查日志。 - 已知风险。 - Parakeet 真实下载 URL 和大小。 ### T9:测试包准备 若 QA 预检通过: - 递增版本到 `2.1.22`。 - 生成新 build 编号。 - 构建 `.dmg`。 - 生成 `RELEASE_MANIFEST.md`。 - 验证 DMG。 - tag。 02-P-NBL/round-4/prd.md
New file @@ -0,0 +1,253 @@ # Round 4 PRD:Parakeet English 高级模型 状态:v0.1 启动稿 所属子项目:`02-P-NBL` Round:Round 4 日期:2026-06-03 基线版本:`2.1.21 build20260603.1327` 基线 commit:`7bedb18` 关联文档: - [`../product-plan.md`](../product-plan.md) - [`../engineering-plan.md`](../engineering-plan.md) - [`../plan.md`](../plan.md) - [`../round-3/prd.md`](../round-3/prd.md) ## 1. 背景 Round 3 已完成 English 默认 Moonshine: - English UI 可用。 - English 默认 current model 为 `moonshine-en`。 - Moonshine 可下载、加载、断网识别。 - 中文 SenseVoice 路径已回归通过。 Round 4 不改变默认策略。Moonshine 仍然是 English 默认模型;Parakeet 是用户主动选择的高级模型。 ## 2. 本轮目标 Round 4 完成后: | 场景 | 期望结果 | |---|---| | English 用户未安装 Parakeet | 继续默认使用 Moonshine | | English 用户主动选择 Parakeet | 未安装则提示下载,安装后切换为 Parakeet | | English 用户从 Parakeet 切回 Moonshine | 立即切回 Moonshine,Parakeet 保留 | | 中文用户 | 不显示或不推荐 Parakeet,不影响 SenseVoice | | Parakeet 下载失败 | 不破坏 Moonshine、SenseVoice、userdict、history | 核心目标: - 新增 `parakeet-en` model profile。 - 新增 `nemo_transducer` backend builder。 - 新增 English 模型选择 UI。 - 用户可以在 `Moonshine English` 和 `Parakeet English` 之间手动切换。 - Parakeet 未安装时不能直接使用,必须下载并校验。 - Moonshine 保留,不自动删除。 ## 3. 本轮非目标 明确不做: - 不把 Parakeet 作为 English 默认模型。 - 不把 Parakeet 暴露给中文默认路径。 - 不接 Qwen3-ASR。 - 不做欧洲语言 UI。 - 不做 30+ 语言列表。 - 不做正式签名和 notarization。 - 不做 Apple Silicon 之外的平台扩展承诺。 - 不删除 Moonshine。 - 不自动迁移用户到 Parakeet。 ## 4. 模型选择决策 本轮选择: ```text model id: parakeet-en actual package: sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-non-streaming backend kind: nemo_transducer language: English tier: advanced ``` 选择 unified-en 0.6b int8 non-streaming,原因: - sherpa-onnx 当前官方页面列出该模型。 - 当前 Go 绑定 `v1.12.24` 支持 offline transducer + `ModelType=nemo_transducer`。 - 官方示例使用 `encoder.int8.onnx`、`decoder.int8.onnx`、`joiner.int8.onnx`、`tokens.txt`。 - 下载包约 `501350460` bytes,适合作为用户主动下载的高级模型,不适合作默认模型。 不选择旧计划里的 `sherpa-onnx-nemo-parakeet-tdt-0.6b-v2-int8` 作为默认实现对象,原因: - 当前 sherpa 官方页面优先展示 unified-en 0.6b。 - unified 包更新时间更新。 - 本轮只需要一个 English 高级模型,避免一次接入多个 Parakeet 变体。 ## 5. Parakeet Profile 新增 profile: ```text ID: parakeet-en DisplayName: Parakeet English BackendKind: nemo_transducer Tier: advanced SupportedLanguageIDs: en RecommendedFor: en Description: 高质量英文离线模型,适合英文长句、技术词和更高准确率需求。 ApproxSize: 约 478 MiB 下载包 InstallDirName: parakeet-en ProviderOrder: cpu NumThreads: 4 ``` 下载 URL: ```text https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-non-streaming.tar.bz2 ``` Required files: | Role | Required file | |---|---| | `encoder` | `encoder.int8.onnx` | | `decoder` | `decoder.int8.onnx` | | `joiner` | `joiner.int8.onnx` | | `tokens` | `tokens.txt` | ## 6. sherpa-onnx 配置 当前项目依赖: ```text github.com/k2-fsa/sherpa-onnx-go-macos v1.12.24 ``` Parakeet builder: ```go config.ModelConfig.Transducer.Encoder = resolved.Files["encoder"] config.ModelConfig.Transducer.Decoder = resolved.Files["decoder"] config.ModelConfig.Transducer.Joiner = resolved.Files["joiner"] config.ModelConfig.Tokens = resolved.Files["tokens"] config.ModelConfig.ModelType = "nemo_transducer" config.ModelConfig.NumThreads = resolved.Profile.NumThreads config.ModelConfig.Provider = "cpu" config.DecodingMethod = "greedy_search" ``` 保留: ```go config.FeatConfig.SampleRate = 16000 config.FeatConfig.FeatureDim = 80 ``` ## 7. 用户故事 ### 7.1 English 用户升级到 Parakeet 前置: - 当前语言为 English。 - Moonshine 已安装并可用。 - Parakeet 未安装。 操作: 1. 用户进入设置页。 2. 在模型区域看到: - Moonshine English - Parakeet English 3. 用户点击 Parakeet。 4. UI 显示下载确认和体积提示。 5. 用户确认下载。 6. 下载完成后自动切换到 Parakeet。 期望: - `ModelSelectionMode=manual` - `SelectedModelID=parakeet-en` - Engine 显示 `Parakeet English · CPU` - Moonshine 模型目录仍保留。 ### 7.2 English 用户切回 Moonshine 前置: - 当前使用 Parakeet。 - Moonshine 已安装。 操作: 1. 用户在模型区域点击 Moonshine English。 2. App 重新加载 Moonshine。 期望: - `SelectedModelID=moonshine-en` - `ModelSelectionMode=manual` - Engine 显示 `Moonshine English · CPU` - Parakeet 模型目录仍保留。 ### 7.3 中文用户不受影响 前置: - 当前语言为中文。 期望: - 继续默认 SenseVoice。 - 不自动下载 Parakeet。 - 不因为 Parakeet 下载失败影响中文识别。 ## 8. UI 要求 设置页新增模型选择区域。 English 状态显示: ```text Recognition Model Moonshine English Lightweight English model, recommended default. Parakeet English Higher quality English model, larger download. ``` 中文状态可以先显示中文模型路径,不强制暴露 Parakeet: ```text 识别模型 SenseVoice 轻量中文离线模型,默认推荐。 ``` 模型卡片至少展示: - 模型名称。 - 一行用途说明。 - 安装状态。 - 当前使用标记。 - 下载/使用按钮。 - 下载大小。 ## 9. 验收标准 Round 4 通过条件: - `parakeet-en` profile 正确。 - Parakeet required files 校验正确。 - Parakeet 可下载、校验、加载。 - English 用户可从 Moonshine 切到 Parakeet。 - English 用户可从 Parakeet 切回 Moonshine。 - Parakeet 下载失败不破坏 Moonshine、SenseVoice、userdict、history。 - 中文 SenseVoice 回归通过。 - 断网状态下 Parakeet 英文识别可用。 - QA 报告记录版本、build、commit、DMG、日志和关键证据。 02-P-NBL/round-4/qa-test-plan.md
New file @@ -0,0 +1,123 @@ # Round 4 QA 测试计划:Parakeet English 高级模型 状态:v0.1 QA 计划稿 所属子项目:`02-P-NBL` Round:Round 4 日期:2026-06-03 输入文档: - [`prd.md`](prd.md) - [`engineering-tasks.md`](engineering-tasks.md) ## 1. QA 目标 证明 Parakeet 作为 English 高级模型可以被用户主动下载、安装、选择、识别,并且不会破坏 Moonshine 默认路径和中文 SenseVoice 路径。 ## 2. 必测范围 - `parakeet-en` profile。 - Parakeet required files 校验。 - Nemo transducer backend builder。 - 模型选择服务 API。 - English 设置页模型选择 UI。 - Parakeet 下载、加载、断网识别。 - Moonshine <-> Parakeet 切换。 - 中文 SenseVoice 回归。 - 下载失败保护。 - 用户数据保护。 ## 3. 不测范围 - Qwen3-ASR。 - 欧洲语言 UI。 - 正式签名和 notarization。 - Parakeet 多变体对比。 - 删除模型 UI,除非研发本轮实现。 ## 4. 测试矩阵 | ID | 场景 | 前置条件 | 期望结果 | |---|---|---|---| | R4-QA-001 | Parakeet profile | 查询 `parakeet-en` | profile 存在,backend=`nemo_transducer` | | R4-QA-002 | required files 完整 | 四个 required files 存在 | 校验通过 | | R4-QA-003 | required files 缺失 | 删除任一 required file | 校验失败 | | R4-QA-004 | English 默认模型 | auto + English | current model 仍为 `moonshine-en` | | R4-QA-005 | English 模型列表 | English 设置页 | 显示 Moonshine 和 Parakeet | | R4-QA-006 | Parakeet 未安装 | 点击 Parakeet | 提示下载,不能直接使用 | | R4-QA-007 | Parakeet 下载 | 联网 | 下载、解压、校验成功 | | R4-QA-008 | Parakeet 加载 | Parakeet 已安装 | engine ready 显示 `Parakeet English · CPU` | | R4-QA-009 | Parakeet 英文识别 | Parakeet ready | 英文可识别 | | R4-QA-010 | Parakeet 断网识别 | 断网 | 英文仍可识别 | | R4-QA-011 | Parakeet 切回 Moonshine | 两模型均安装 | Moonshine ready | | R4-QA-012 | Moonshine 切回 Parakeet | 两模型均安装 | Parakeet ready | | R4-QA-013 | 中文回归 | 切到中文 | SenseVoice ready,中文可识别 | | R4-QA-014 | 下载失败保护 | 坏 URL/坏包 | 不破坏 Moonshine/SenseVoice | | R4-QA-015 | 旧用户数据保护 | 有 userdict/history | 数据不丢 | | R4-QA-016 | 重启持久化 | 选择 Parakeet 后重启 | 仍为 Parakeet,除非用户切回 auto/default | ## 5. 自动化测试建议 后端: - `GetModelProfile("parakeet-en")` - `ValidateModelDir(parakeet-en)` - `NewWithResolvedModel` backend dispatch - `SelectModel` - `DownloadModelByID` - 未安装模型选择失败 - 下载失败不破坏已有模型 命令: ```bash cd privatevoice.src go test ./... -count=1 ``` 前端: ```bash cd privatevoice.src/frontend npm run build ``` ## 6. 手工 QA 步骤 ### 6.1 English 升级 Parakeet 1. 备份真实 App Support。 2. English 状态启动 App。 3. 确认当前 engine 为 Moonshine。 4. 在模型区域点击 Parakeet。 5. 确认 UI 显示下载大小和下载进度。 6. 下载完成后确认 engine 为 Parakeet。 7. 说英文短句,确认上屏和 history。 ### 6.2 断网 Parakeet 1. Parakeet ready。 2. 断开 Wi-Fi。 3. 说英文短句。 4. 确认识别成功。 5. 恢复网络。 ### 6.3 切回 Moonshine 1. Parakeet ready。 2. 点击 Moonshine。 3. 确认 engine 变为 Moonshine。 4. 说英文短句。 ### 6.4 中文 SenseVoice 回归 1. 切回中文。 2. 确认 engine 为 SenseVoice。 3. 说中文短句。 4. 检查识别结果。 ## 7. QA PASS 标准 - R4-QA-001 到 R4-QA-016 全部通过,或失败项有明确非阻断说明。 - Parakeet 是可选高级模型,不改变 English 默认 Moonshine。 - 中文 SenseVoice 核心路径不退化。 - QA 报告记录版本、build、commit、测试包、日志和关键证据。 02-P-NBL/round-4/todo-list.md
New file @@ -0,0 +1,69 @@ # Round 4 Todo List:Parakeet English 高级模型 状态:进行中 所属子项目:`02-P-NBL` Round:Round 4 日期:2026-06-03 ## 1. 文档与启动 - [x] 创建 Round 4 worktree:`/Users/ar/Projects/VoiceSnap-2.1.1-Round4` - [x] 基于 Round 3 完成 commit `7bedb18` 创建分支:`codex/round4-parakeet-english` - [x] 读取项目规则和全局交付/QA/发布规则 - [x] 核准 sherpa-onnx Parakeet 文件结构 - [x] 创建 Round 4 PRD - [x] 创建 Round 4 研发任务拆解 - [x] 创建 Round 4 QA 测试计划 ## 2. 研发实现 - [ ] 新增 `parakeet-en` profile - [ ] 新增 `BackendNemoTransducer` - [ ] 新增 Parakeet required files 校验 - [ ] 新增 Nemo transducer backend builder - [ ] 新增模型选择服务 API - [ ] 设置页新增模型选择 UI - [ ] English 可从 Moonshine 切到 Parakeet - [ ] English 可从 Parakeet 切回 Moonshine - [ ] Parakeet 下载失败不破坏已有模型 - [ ] 中文 SenseVoice 路径不退化 ## 3. 开发自查 - [ ] `go test ./... -count=1` - [ ] `npm run build` - [ ] `git diff --check` - [ ] 研发自查报告 - [ ] 代码复审 - [ ] QA handoff ## 4. QA - [ ] 自动化/半自动 QA - [ ] Parakeet 真实下载和加载 - [ ] Parakeet 英文识别 - [ ] Parakeet 断网英文识别 - [ ] Moonshine 回退 - [ ] 中文 SenseVoice 回归 - [ ] 下载失败保护 - [ ] 用户数据保护 - [ ] QA 报告 ## 5. 交付 - [ ] 测试包版本递增 - [ ] 生成 `.dmg` - [ ] 生成 `RELEASE_MANIFEST.md` - [ ] 验证 `.dmg` - [ ] tag - [ ] 用户验收候选包 - [ ] 用户验收 ## 6. 暂缓记录 以下事项不作为 Round 4 阻断项: - 左侧 Logo 区只显示 `PrivateVoice`,下方小字显示 `Private. Offline.`。 - App 正式名称从 `PrivateVoice Input` 改为 `PrivateVoice Dictation`。 - Qwen3-ASR 中文高级模型。 - 欧洲语言 UI。