edit | blame | history | raw

VoiceSnap 多语言与多模型总体研发规划

状态:研发规划稿
日期:2026-06-01
范围:语言检测、模型 profile 抽象、多模型下载/切换/删除、首批四模型接入

1. 当前技术现状

当前实现基本是单模型架构,核心路径围绕 SenseVoice 写死。

已知硬编码点:

  • 模型目录固定为 models/sensevoice
  • 模型文件固定为 model.int8.onnxmodel.onnx
  • tokens.txt 固定在同一个 SenseVoice 目录下。
  • engine 初始化固定写入 config.ModelConfig.SenseVoice.Model
  • 下载器只识别 sherpa-onnx-sense-voice... 并重命名为 sensevoice
  • 配置项只有一个模型下载 URL 和 fallback URL。

要支持:

中文默认 SenseVoice
中文高级 Qwen3-ASR
English 默认 Moonshine
English 高级 Parakeet

必须引入模型 profile 抽象。

2. 研发目标

本轮研发目标:

  1. 从单 SenseVoice 模型改为多模型 profile。
  2. 支持语言版本和默认模型映射。
  3. 支持按系统语言首次选择默认语言和默认模型。
  4. 支持模型安装状态管理。
  5. 支持下载、校验、切换、删除模型。
  6. 支持四个首批模型:
  • SenseVoice
  • Qwen3-ASR
  • Moonshine English
  • Parakeet
  1. 保持现有录音、热键、上屏、历史、用户词库逻辑可复用。

3. 核心架构设计

新增三个核心概念:

LanguageProfile
ModelProfile
ModelInstallState

4. LanguageProfile

LanguageProfile 表示产品语言版本和默认识别方向。

建议结构:

type LanguageProfile struct {
	ID              string
	DisplayName     string
	UILocale        string
	SystemMatchers  []string
	DefaultModelID  string
	UpgradeModelIDs []string
}

首批配置:

zh-CN
- displayName: 中文
- uiLocale: zh-CN
- systemMatchers: zh, zh-CN, zh-Hans, zh-Hant
- defaultModelId: sensevoice-zh
- upgradeModelIds: qwen3-asr-0.6b

en
- displayName: English
- uiLocale: en
- systemMatchers: en, en-US, en-GB
- defaultModelId: moonshine-en
- upgradeModelIds: parakeet-en

未来可扩展:

yue
ja
ko
fr
de
es
...

粤语应使用独立 languageId,不要简单归入中文。

5. ModelProfile

ModelProfile 表示一个可安装、可切换的 ASR 模型。

建议结构:

type ModelProfile struct {
	ID              string
	DisplayName     string
	BackendKind     string
	Tier            string
	LanguageIDs     []string
	RecommendedFor  []string
	Description     string
	ApproxSize      string
	DownloadURLs    []string
	InstallDirName  string
	RequiredFiles   []string
	ProviderOrder   []string
	NumThreads      int
}

字段说明:

字段 说明
ID 稳定模型 ID,不能随显示名变化
BackendKind 决定 sherpa config builder
Tier defaultadvanced
LanguageIDs 模型支持的语言
RecommendedFor 当前产品推荐使用的语言
DownloadURLs 主下载和备用下载
RequiredFiles 安装完成必须存在的文件
ProviderOrder macOS 可为 coreml,cpucpu

6. 首批 ModelProfile

6.1 SenseVoice

id: sensevoice-zh
backendKind: sensevoice
tier: default
recommendedFor: zh-CN
installDirName: sensevoice-zh
requiredFiles:
  - model.int8.onnx 或 model.onnx
  - tokens.txt

sherpa config:

config.ModelConfig.SenseVoice.Model = modelPath
config.ModelConfig.SenseVoice.UseInverseTextNormalization = 1
config.ModelConfig.Tokens = tokensPath

6.2 Qwen3-ASR

id: qwen3-asr-0.6b
backendKind: qwen3_asr
tier: advanced
recommendedFor: zh-CN, yue
installDirName: qwen3-asr-0.6b
requiredFiles:
  - conv_frontend.onnx
  - encoder.int8.onnx
  - decoder.int8.onnx
  - tokenizer/merges.txt
  - tokenizer/vocab.json

sherpa config:

config.ModelConfig.Qwen3ASR.ConvFrontend = convFrontendPath
config.ModelConfig.Qwen3ASR.Encoder = encoderPath
config.ModelConfig.Qwen3ASR.Decoder = decoderPath
config.ModelConfig.Qwen3ASR.Tokenizer = tokenizerDir

备注:

  • Qwen3-ASR 体积明显大于 SenseVoice。
  • 只作为用户主动选择的高级模型。
  • Qwen3-ASR 支持多语言和多种中文方言,后续可以作为更多语言的高级模型复用。

6.3 Moonshine English

id: moonshine-en
backendKind: moonshine
tier: default
recommendedFor: en
installDirName: moonshine-en
requiredFiles:
  - encoder_model.ort
  - decoder_model_merged.ort
  - tokens.txt

sherpa config:

config.ModelConfig.Moonshine.Encoder = encoderPath
config.ModelConfig.Moonshine.MergedDecoder = mergedDecoderPath
config.ModelConfig.Tokens = tokensPath

备注:

  • 使用 sherpa-onnx Moonshine English quantized 路线。
  • 不在第一阶段接 Moonshine Voice framework。
  • 不做实时 partial transcript。

6.4 Parakeet

id: parakeet-en
backendKind: nemo_transducer
tier: advanced
recommendedFor: en
installDirName: parakeet-en
requiredFiles:
  - encoder.int8.onnx
  - decoder.int8.onnx
  - joiner.int8.onnx
  - tokens.txt

sherpa config:

config.ModelConfig.Transducer.Encoder = encoderPath
config.ModelConfig.Transducer.Decoder = decoderPath
config.ModelConfig.Transducer.Joiner = joinerPath
config.ModelConfig.Tokens = tokensPath
config.ModelConfig.ModelType = "nemo_transducer"

备注:

  • 作为 English 高级模型。
  • 体积大于 Moonshine English。
  • 用户主动下载后可切换。

6.5 X-ASR-zh-en(未来候选)

id: x-asr-zh-en
backendKind: zipformer_transducer_streaming
tier: experimental
recommendedFor: zh-CN, en
installDirName: x-asr-zh-en
requiredFiles:
  - encoder-<chunk>.onnx
  - decoder-<chunk>.onnx
  - joiner-<chunk>.onnx
  - tokens.txt

初始策略:

  • 只做实验性 profile,不进入第一阶段普通模型列表。
  • 不同时下载四个 chunk 变体;先选 480 ms960 ms 之一做 Apple Silicon 真机 spike。
  • 如果当前 Go 绑定不能稳定支持 streaming OnlineRecognizer,先做独立 prototype,不接入正式 EngineFactory。

备注:

  • X-ASR-zh-en 是 Zipformer transducer,基于 sherpa-onnx,技术栈方向与当前项目一致。
  • 主要价值是低延迟流式识别和中英混输,不是单纯追求最高离线准确率。
  • benchmark 显示其离线平均结果接近但低于 Qwen3-ASR 0.6B,高于/接近 SenseVoice-small;因此更适合作为“实时输入候选”,而不是 Qwen3-ASR 替代品。
  • 进入产品前必须复核 Apache-2.0 license、模型卡、技术报告和训练数据说明。

7. 配置文件扩展

当前 config 需要新增字段。

建议:

type Config struct {
	// existing fields...
	LanguageMode    string `json:"LanguageMode"`    // auto | manual
	LanguageID      string `json:"LanguageID"`      // zh-CN | en | yue ...
	SelectedModelID string `json:"SelectedModelID"` // sensevoice-zh | moonshine-en ...
}

默认逻辑:

LanguageMode = auto
LanguageID = detectSystemLanguage()
SelectedModelID = defaultModelFor(LanguageID)

如果用户手动切换语言:

LanguageMode = manual
LanguageID = userSelectedLanguage

切换语言时:

  • 如果当前模型仍适合该语言,可以不强制切换。
  • 如果当前模型不适合该语言,提示用户切换到推荐默认模型。
  • 不自动删除已安装模型。

8. 模型安装状态

建议新增模型状态文件:

models/state.json

示例:

{
  "installedModels": {
    "sensevoice-zh": {
      "installedAt": 1780120000000,
      "version": "2025.09.09",
      "path": "models/sensevoice-zh"
    },
    "moonshine-en": {
      "installedAt": 1780120000000,
      "version": "2026.02.27",
      "path": "models/moonshine-en"
    }
  }
}

也可以用每个模型目录下的 manifest:

models/<modelId>/manifest.json

推荐两者都支持:

  • models/state.json 用于快速列出状态。
  • models/<modelId>/manifest.json 用于校验单个模型目录。

9. 路径规划

旧结构:

models/sensevoice

新结构:

models/
  sensevoice-zh/
  qwen3-asr-0.6b/
  moonshine-en/
  parakeet-en/
  state.json

兼容策略:

  • 如果发现旧目录 models/sensevoice,迁移或识别为 sensevoice-zh
  • 不覆盖用户已有模型。
  • 迁移失败时保留旧目录,并提示重新下载。

10. 下载器改造

当前下载器写死 SenseVoice 解压逻辑,需要改成通用下载器。

目标接口:

func DownloadModel(profile ModelProfile, progress ProgressCallback) error

流程:

  1. 创建临时下载目录。
  2. profile.DownloadURLs 顺序下载。
  3. 解压到临时目录。
  4. 在解压结果中定位 RequiredFiles
  5. 移动到 models/<modelId>
  6. 写入 manifest。
  7. 更新 models/state.json
  8. 清理临时文件。

必须保证:

  • 下载失败不破坏已安装模型。
  • 解压失败不破坏已安装模型。
  • 校验失败不破坏已安装模型。
  • 切换模型失败不改变当前 active model。

11. EngineFactory 改造

新增:

func New(profileID string) (Engine, error)

或:

func NewWithProfile(profile ModelProfile) (Engine, error)

内部根据 BackendKind 分发:

switch profile.BackendKind {
case "sensevoice":
	buildSenseVoiceConfig(profile)
case "moonshine":
	buildMoonshineConfig(profile)
case "nemo_transducer":
	buildNemoTransducerConfig(profile)
case "qwen3_asr":
	buildQwen3ASRConfig(profile)
case "zipformer_transducer_streaming":
	buildXASRStreamingConfig(profile)
}

平台文件 engine_darwin.goengine_windows.goengine_linux.go 保留 provider 差异,但不要再写死 SenseVoice。

12. 服务层改造

EngineService 增加:

ListLanguages()
GetCurrentLanguage()
SetLanguage(languageId)

ListModels()
GetCurrentModel()
ModelExists(modelId)
DownloadModel(modelId)
UseModel(modelId)
DeleteModel(modelId)

注意:

  • DeleteModel(currentModelId) 必须拒绝。
  • UseModel(modelId) 要求模型已安装。
  • DownloadModel(modelId) 成功后不一定自动使用,产品可决定。
  • 如果是用户点击“下载并使用”,前端可以下载成功后调用 UseModel

13. 前端改造

设置页增加两个页面或区域:

Language
Recognition Model

13.1 Language 页面

第一阶段显示:

Auto
中文
English

后续扩展为多语言列表。

13.2 Recognition Model 页面

模型卡片字段:

  • 名称
  • 适合语言
  • 特点说明
  • 大小
  • 状态
  • 操作按钮

状态:

Not Installed
Downloading
Installed
In Use

操作:

Download
Use
Delete

14. 实现阶段

Phase 1:模型 profile 基础设施

目标:不改变用户体验,先把现有 SenseVoice 放进 profile 架构。

交付:

  • ModelProfile
  • LanguageProfile
  • ModelRegistry
  • LanguageRegistry
  • sensevoice-zh profile。
  • EngineFactory 初步抽象。
  • 现有 SenseVoice 路径兼容。

验收:

  • 当前中文路径功能不退化。
  • 现有模型仍能加载。
  • 当前配置仍能兼容。

Phase 2:语言检测和默认模型

目标:首次启动按系统语言选择语言版本和默认模型。

交付:

  • 系统语言检测。
  • LanguageModeLanguageIDSelectedModelID 配置字段。
  • 中文默认 sensevoice-zh
  • English 默认 moonshine-en
  • 未支持语言默认 English。

验收:

  • 中文系统默认中文 + SenseVoice。
  • English 系统默认 English + Moonshine。
  • 用户手动切换语言后保存。

Phase 3:Moonshine English 接入

目标:English 默认模型可用。

交付:

  • moonshine-en profile。
  • Moonshine required files 校验。
  • Moonshine config builder。
  • Moonshine 下载/安装/加载。
  • English UI 文案。

验收:

  • Moonshine 模型可下载。
  • 下载后可初始化。
  • 英文音频可识别。
  • 用户词库、历史、上屏逻辑复用。

Phase 4:Parakeet 接入

目标:English 高级模型可选。

交付:

  • parakeet-en profile。
  • NeMo transducer config builder。
  • Parakeet required files 校验。
  • Parakeet 下载/安装/切换/删除。

验收:

  • Moonshine 和 Parakeet 可在设置中切换。
  • Parakeet 未安装时不能直接使用。
  • Parakeet 下载后可使用。
  • 删除 Parakeet 后可回到 Moonshine。

Phase 5:Qwen3-ASR 接入

目标:中文高级模型可选。

交付:

  • qwen3-asr-0.6b profile。
  • Qwen3-ASR config builder。
  • Qwen3-ASR tokenizer 目录校验。
  • Qwen3-ASR 下载/安装/切换/删除。

验收:

  • SenseVoice 和 Qwen3-ASR 可切换。
  • Qwen3-ASR 未安装时不能直接使用。
  • 删除 Qwen3-ASR 后可回到 SenseVoice。

Phase 6:模型删除与恢复体验

目标:完善长期使用体验。

交付:

  • 当前模型删除保护。
  • 删除确认。
  • 模型磁盘占用展示。
  • 模型损坏后重新下载。
  • 模型切换失败回滚。

验收:

  • 不会删除当前模型。
  • 删除未使用模型不影响设置和用户数据。
  • 模型损坏时可重新下载。

15. 测试计划

15.1 单元测试

  • 系统语言匹配。
  • 默认模型映射。
  • profile required files 校验。
  • 模型状态读写。
  • 旧配置兼容。
  • models/sensevoice 兼容。
  • 删除当前模型被拒绝。
  • 未安装模型不能使用。

15.2 集成测试

  • 中文默认路径。
  • English 默认路径。
  • SenseVoice -> Qwen3-ASR 切换。
  • Qwen3-ASR -> SenseVoice 回退。
  • Moonshine -> Parakeet 切换。
  • Parakeet -> Moonshine 回退。
  • 下载失败不破坏当前模型。
  • 初始化失败不改变当前模型。

15.3 手工 QA

  • macOS 中文系统首次启动。
  • macOS English 系统首次启动。
  • 修改系统语言后首次启动。
  • 用户手动切换语言。
  • 用户下载高级模型。
  • 用户删除非当前模型。
  • 用户尝试删除当前模型。

16. 主要风险

16.1 模型体积

高级模型体积大。Qwen3-ASR 和 Parakeet 都不适合作为默认模型。

缓解:

  • 默认模型轻量。
  • 高级模型主动下载。
  • 下载前显示体积。
  • 默认模型保留。

16.2 模型包结构差异

四个模型文件结构不同。

缓解:

  • BackendKind + RequiredFiles
  • 不再写死 model.int8.onnx

16.3 切换失败

模型下载成功不代表初始化成功。

缓解:

  • 切换前保留旧 recognizer。
  • 新模型初始化成功后再替换 active engine。
  • 失败时回滚。

16.4 未来语言扩展

如果第一版把 UI 和模型写死为中英,会阻碍后续 30 种语言。

缓解:

  • 语言和模型均 profile 化。
  • UI 从 registry 渲染。
  • 不在业务逻辑里硬编码四个模型。

16.5 许可证和分发

模型能否随 App 分发、是否需要用户单独下载,需要发布前确认。

缓解:

  • runtime JSON 不需要保存许可证字段。
  • 但发布流程中必须做模型分发许可检查。
  • 优先采用用户主动下载模型包的方式。

17. 参考资料