状态:研发规划稿
日期:2026-06-01
范围:语言检测、模型 profile 抽象、多模型下载/切换/删除、首批四模型接入
当前实现基本是单模型架构,核心路径围绕 SenseVoice 写死。
已知硬编码点:
models/sensevoice。model.int8.onnx 或 model.onnx。tokens.txt 固定在同一个 SenseVoice 目录下。config.ModelConfig.SenseVoice.Model。sherpa-onnx-sense-voice... 并重命名为 sensevoice。要支持:
中文默认 SenseVoice
中文高级 Qwen3-ASR
English 默认 Moonshine
English 高级 Parakeet
必须引入模型 profile 抽象。
本轮研发目标:
新增三个核心概念:
LanguageProfile
ModelProfile
ModelInstallState
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,不要简单归入中文。
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 |
default 或 advanced |
LanguageIDs |
模型支持的语言 |
RecommendedFor |
当前产品推荐使用的语言 |
DownloadURLs |
主下载和备用下载 |
RequiredFiles |
安装完成必须存在的文件 |
ProviderOrder |
macOS 可为 coreml,cpu 或 cpu |
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
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
备注:
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
备注:
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"
备注:
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
初始策略:
480 ms 或 960 ms 之一做 Apple Silicon 真机 spike。OnlineRecognizer,先做独立 prototype,不接入正式 EngineFactory。备注:
当前 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
切换语言时:
建议新增模型状态文件:
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 用于校验单个模型目录。旧结构:
models/sensevoice
新结构:
models/
sensevoice-zh/
qwen3-asr-0.6b/
moonshine-en/
parakeet-en/
state.json
兼容策略:
models/sensevoice,迁移或识别为 sensevoice-zh。当前下载器写死 SenseVoice 解压逻辑,需要改成通用下载器。
目标接口:
func DownloadModel(profile ModelProfile, progress ProgressCallback) error
流程:
profile.DownloadURLs 顺序下载。RequiredFiles。models/<modelId>。models/state.json。必须保证:
新增:
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.go、engine_windows.go、engine_linux.go 保留 provider 差异,但不要再写死 SenseVoice。
EngineService 增加:
ListLanguages()
GetCurrentLanguage()
SetLanguage(languageId)
ListModels()
GetCurrentModel()
ModelExists(modelId)
DownloadModel(modelId)
UseModel(modelId)
DeleteModel(modelId)
注意:
DeleteModel(currentModelId) 必须拒绝。UseModel(modelId) 要求模型已安装。DownloadModel(modelId) 成功后不一定自动使用,产品可决定。UseModel。设置页增加两个页面或区域:
Language
Recognition Model
第一阶段显示:
Auto
中文
English
后续扩展为多语言列表。
模型卡片字段:
状态:
Not Installed
Downloading
Installed
In Use
操作:
Download
Use
Delete
目标:不改变用户体验,先把现有 SenseVoice 放进 profile 架构。
交付:
ModelProfile。LanguageProfile。ModelRegistry。LanguageRegistry。sensevoice-zh profile。EngineFactory 初步抽象。验收:
目标:首次启动按系统语言选择语言版本和默认模型。
交付:
LanguageMode、LanguageID、SelectedModelID 配置字段。sensevoice-zh。moonshine-en。验收:
目标:English 默认模型可用。
交付:
moonshine-en profile。验收:
目标:English 高级模型可选。
交付:
parakeet-en profile。验收:
目标:中文高级模型可选。
交付:
qwen3-asr-0.6b profile。验收:
目标:完善长期使用体验。
交付:
验收:
models/sensevoice 兼容。高级模型体积大。Qwen3-ASR 和 Parakeet 都不适合作为默认模型。
缓解:
四个模型文件结构不同。
缓解:
BackendKind + RequiredFiles。model.int8.onnx。模型下载成功不代表初始化成功。
缓解:
如果第一版把 UI 和模型写死为中英,会阻碍后续 30 种语言。
缓解:
模型能否随 App 分发、是否需要用户单独下载,需要发布前确认。
缓解: