Moonshine 配置项完全指南:options 字符串映射机制与 STT/TTS/G2P 全部键值详解
【免费下载链接】moonshineVery low latency speech to text, intent recognition, and text to speech, for building voice agents and interfaces项目地址: https://gitcode.com/GitHub_Trending/moonshine3/moonshine
Moonshine 的绝大多数构造器(Transcriber、TextToSpeech、GraphemeToPhonemizer、SpeechClip 提取等)都通过一张统一的"字符串到字符串"选项映射表接收配置:Python 里是 dict,C 语言里是moonshine_option_t数组,其他语言绑定是 name/value 对。本文以 docs/api/options.md 为主线,完整梳理这套 options 机制的解析流程与全部键值目录,并结合core/moonshine-c-api.cpp、core/moonshine-tts/src/moonshine-tts-options.cpp、core/transcriber.cpp等源码说明每个参数的底层作用。读完本文,你可以为任意 Moonshine 组件写出精确、可复现的配置,也能理解键别名、未知键转发、内存加载与文件加载之间的差异。
options 机制总览:一套字符串契约贯穿所有语言绑定
Moonshine 在 ABI 层统一约定:选项值永远是字符串。这意味着布尔值、数字等类型要么由各语言绑定在传入前自动字符串化,要么在 C 层由解析器负责转回具体类型。例如 Python 端可以写options={"vad_threshold": 0.6},而 C 端对应的是:
// core/moonshine-c-api.h L164-167 struct moonshine_option_t { const char *name; const char *value; };传入后由各构造器的专用解析函数逐条消费。以转写器为例,core/moonshine-c-api.cpp 中的parse_transcriber_options()按option_name分支把字符串转成布尔(bool_from_string)、浮点(float_from_string)、整数(int32_from_string)或原样保留的路径字符串,最终填充到TranscriberOptions结构体。
几个值得注意的机制细节:
- 大小写与连字符归一化:TTS 的解析器(moonshine-tts-options.cpp)会先把键名
to_lowercase并把-替换为_,所以model-root、Model_Root、model_root等价。 - 公共键先剥离:
log_api_calls由parse_common_options()(moonshine-c-api.cpp)在进入任何 API 专用解析之前先行取出,其余键再继续分发;ort_providers、coreml_cache_dir则在所有创建 ONNX Runtime 会话的路径上生效。 - 未知键的处理策略分叉:Transcriber 的解析器遇到未知键直接
throw std::runtime_error("Unknown transcriber option: ...");而 TTS 解析器会把未知键转发给 G2P 解析器,因为 TTS 依赖 G2P 的资产布局与语言规则,二者共享同一套解析入口。 - 逗号分隔即列表:凡是"列表型"值(如
keyterms、ort_providers)都以逗号分隔字符串传递,parse_keyterms()(moonshine-c-api.cpp)会逐段trim并丢弃空项——这是为了让每种绑定都只用字符串这一种类型就能表达数组。
这套契约的直接收益是:moonshine_load_transcriber_from_files()、moonshine_create_tts_synthesizer_from_files()、moonshine_create_grapheme_to_phonemizer_*等所有 C 入口(定义见 core/moonshine-c-api.h)共用同一套选项语义,Python、Swift、Wasm 绑定(language-bindings 目录)只需做字符串化转发。
Shared options:跨构造器共享的通用键
以下键在多个构造器中都被识别。log_api_calls由公共解析器剥离;ort_providers与coreml_cache_dir在创建 ONNX Runtime 会话的任何地方生效。
| 键 | 适用对象 | 说明 |
|---|---|---|
log_api_calls | Transcriber、TTS、G2P、speech-clip extract 以及其他走公共选项解析的 C 入口 | 为 true 时,把 C API 入口点及其参数打印到 stderr/console。从源码看,moonshine_get_version、各加载/创建函数、moonshine_transcriber_add_audio等入口(moonshine-c-api.cpp 大量if (log_api_calls)分支)都会先打印调用名,便于定位"谁在什么时候调了哪个 API"。 |
ort_providers(别名ort_provider) | Transcriber、TTS、G2P | 逗号分隔、有序的 ONNX Runtime 执行提供者列表,例如CoreML,CPU。名称不区分大小写,短形式(CPU、CoreML、NNAPI)或全名均可。未设置时默认仅 CPU(推荐)。移动端库只随附 CPU-only,请求其他提供者会报错。详见 execution providers。 |
coreml_cache_dir | Transcriber、TTS、G2P | macOS 上 CoreML 编译后模型的缓存目录。仅当ort_providers中包含CoreML时生效。 |
log_profiling | TTS、G2P | 为 true 时向控制台输出剖析信息。 |
g2p_root | TTS、G2P(以及 TTS 依赖/声音列取) | G2P 与 TTS 文件布局的资源根目录。为空表示进程当前工作目录。 |
path_root/model_root | 同g2p_root | g2p_root的别名。TTS 解析器中tts_root、path_root、model_root三者等价(moonshine-tts-options.cpp)。 |
tts_root | TTS create / dependencies / voices | 解析 TTS 布局时资源根的别名。 |
MicTranscriber 的.options()与 AgentFlow 的.speech_options()分别转发到原生 transcriber 与 TTS 加载器,因此上述键在移动端/桌面示例(examples 目录)中同样适用。
Speech to Text 选项:从 VAD 到解码的全链路调优
STT 选项传给Transcriber(..., options=…)、MicTranscriber.options()、moonshine_load_transcriber_from_files()、_from_memory_files()及已废弃的_from_memory()。下表为完整目录,解析实现见 moonshine-c-api.cpp。
| 键 | 默认值 | 说明 |
|---|---|---|
skip_transcription | false | 为 true 时只跑 VAD/分段、不做 STT,把每行的音频缓冲交给调用方进一步处理。源码中该键直接把ModelSource置为NONE,即不加载解码模型。 |
max_tokens_per_second | 6.5 | 解码循环的"病理速率"截断阈值:当 token 速率看起来异常时截断循环。许多非拉丁语系建议约13.0。源码中该值传入MoonshineModel(moonshine-model.cpp),用于估算一段音频对应的最大解码 token 数(moonshine-model.cpp)。 |
use_speculative_decoding | true | 流式解码时验证上一轮假设、从第一个不匹配处继续;false 则回退为从 BOS 起贪心重解码。 |
keyterms | (无) | 逗号分隔的偏置词表(仅流式架构)。详见 Domain Customization。运行时也可用set_keyterms/moonshine_transcriber_set_keyterms()设置。 |
keyterm_boost | 2.0 | 关键词偏置强度。向 4.0 调高更偏向词表、牺牲周边词;向 1.0 调低则相反;超过 4.0 失效。 |
context | (无) | 一段自由文本,用于"有上下文但没有词表"的场景,从其中抽取关键词(仅流式架构)。会叠加到keyterms上。运行时也可用set_context/moonshine_transcriber_set_context()设置。 |
context_max_terms | 200 | 从context中最多提取的词条数。建议保持克制:长度会计入你没有请求的那些词的代价。 |
transcription_interval | 0.5 | 两次自动转写之间的秒数(对应 Python 的update_interval)。源码中用它判断新音频是否达到再转写门槛(transcriber.cpp)。 |
vad_threshold | 0.5 | VAD 灵敏度。越低分段越长、越高分块越短;0表示禁用 VAD(音频仍按vad_max_segment_duration分块)。 |
vad_window_duration | 0.5 | 检测语音时用于平均的 VAD 分数窗口秒数。 |
vad_hop_size | 512 | VAD 跳步大小(采样点)。 |
vad_look_behind_sample_count | 8192 | 语音开始时向前补的采样点数(补偿 VAD 平均带来的滞后),基于 16 kHz。 |
vad_max_segment_duration | 15 | 行(line)的最大长度秒数,达到后强制完成;段末阈值会逐步降低。源码中VoiceActivityDetector与分段逻辑据此工作(transcriber.cpp)。 |
save_input_wav_path | (无) | 目录路径:把接收到的音频写成 16 kHz 单声道 WAV 用于调试。 |
log_ort_run | false | 记录 ONNX Runtime 推理运行与耗时。 |
word_timestamps | false | 填充每行的words数组。需要带注意力的解码器资产(decoder_kv_with_attention.ort),identify_speakers会隐式开启它。加载时若该文件存在则替换流式解码器(transcriber.cpp)。 |
decode_incomplete_lines | true | 解码进行中的行,让人说话时文本就能持续更新;false 则等待该行完整后再解码。 |
identify_speakers | false | 开启说话人分离(diarization)与speaker_spans。需要 diarization 模型,详见 diarization-models。 |
diarization_model_dir | (无) | 直接构造 transcriber 时,包含segmentation.ort和embedding.ort的目录。 |
diarization_cluster_cadence | 2.0 | 两次重新聚类之间所需的最短新音频秒数。 |
diarization_analyze_cadence | 0(= 模型默认1.0) | 分段/嵌入的滑动窗口步长。实时add_audio/transcribe()每次调用最多跑一个窗口,其余窗口等到下次调用或 Stop;静音说话人类别会跳过嵌入推理。 |
diarization_cluster_window_sec | 120 | 流式 VBx 保留的最近历史秒数;0表示不限。批量/一次性模式始终使用完整历史。 |
return_audio_data | true | 转写结果中包含每行 PCM。 |
log_output_text | false | 把 STT 文本输出到控制台。 |
spelling_model_path | (无) | 拼写 CNN.ort模型的路径,用于MOONSHINE_FLAG_SPELLING_MODE(该标志定义于 moonshine-c-api.h,用于字母数字拼写融合)。 |
关键词偏置的底层实现
从 transcriber.cpp 可以看到set_keyterms()的完整行为链:设置后先清空ContextBiaser并按keyterm_boost设偏置强度,然后丢弃投机解码草稿(last_streaming_tokens.clear())——因为草稿是在旧词表下解码的,保留会让旧词表继续影响下一轮验证,代价是下一次从 BOS 重解码一次。随后对每个词条的每个变体(ContextBiaser::variants_for_term)经streaming_model->text_to_tokens()转成 token 序列并add_token_sequence()注册进偏置器。若加载的不是流式模型而设置了keyterms,会直接抛出"Key-term biasing requires one of the streaming model architectures"的运行时错误。
set_context()(transcriber.cpp)则把自由文本按context_max_terms抽取成词表后走set_keyterms()。context文本中一个无法拼写的词只会丢弃该词本身,不会拖累整段上下文(见 transcriber.cpp 的注释)。
说话人分离时的行语义
开启identify_speakers后,每一行会携带speaker_spans数组,描述说话人与该行文本的 UTF-8 字符区间对应关系,并自动启用word_timestamps。说话人 ID 是 64 位随机数,在同一流内稳定;说话人索引按首次出现顺序计数。值得注意的是,近期音频的说话人跨度是可变的:流式 diarization 会随着更多语音到达在滑动窗口(diarization_cluster_window_sec,默认 120s)内重新聚类,更早音频的归属则被冻结;have_speakers_changed标志用于标记跨度在上一调用后是否变化(moonshine-c-api.h)。
常见调优组合
- 更低延迟的流式体验:
transcription_interval调小(如0.2)、decode_incomplete_lines=true、use_speculative_decoding=true。 - 更准的断句:
vad_threshold调低(如0.3)以延长分段;配合vad_max_segment_duration限制最长行。 - 领域词汇纠偏:
keyterms="Moonshine,voice agent"+keyterm_boost=3.0,或用context传入整段领域文本。 - 调试:
log_api_calls=true、log_ort_run=true、save_input_wav_path="debug_audio"。
Text to Speech 选项:voice、speed 与三套声码器覆盖项
TTS 选项传给TextToSpeech.options()、AgentFlow.speech_options()、moonshine_create_tts_synthesizer_from_files()/_from_memory();moonshine_get_tts_dependencies()与moonshine_get_tts_voices()在相关处复用同一集合。解析实现见 moonshine-tts-options.cpp。
| 键 | 说明 |
|---|---|
voice | 目录声音 ID。用kokoro_、piper_或zipvoice_前缀选择声码器,例如kokoro_af_heart。 |
speed | 语速倍率。也是say()/synthesize()/moonshine_text_to_speech()/moonshine_phonemes_to_speech()唯一尊重的逐调用覆盖项。测试中常见{"speed", "2.0"}用于验证加速路径(见 moonshine-tts-speed-test.cpp)。 |
lang/language | 通过 options 提供语言标签(通常改由构造器或language()setter 设置)。源码中该键要求传入语言输出指针,否则抛"invalid without a language output pointer"错误。 |
kokoro_dir | 覆盖 Kokoro 目录:其下应含prosody.model.ort、prosody.weights.ort、decoder.model.ort、decoder.weights.ort与config.json。 |
kokoro_model/kokoro_model_onnx | 覆盖 Kokoro 模型路径。它指定的是"模型"而非必须存在的文件:优先使用其旁的拆分权重对(split pair),否则加载该路径上的单个.ort。 |
kokoro_config/kokoro_config_json | 覆盖 Kokoro 配置 JSON 路径。 |
piper_onnx/piper_model_onnx/piper_model | 覆盖 Piper 模型路径(必须是.ort)。源码会调用require_ort_model_path校验扩展名。 |
piper_onnx_json/piper_model_json/piper_onnx_config | 覆盖 Piper JSON 侧车文件(sidecar)。 |
piper_voices_dir/voices_dir | 覆盖 Piper 声音目录。 |
piper_voices_json_dir/voices_json_dir | 覆盖 Piper*.onnx.json目录。 |
normalize_audio/piper_normalize_audio | 先做峰值归一化再应用增益/限幅(默认 true)。 |
output_volume/piper_output_volume | 归一化后的线性增益(默认1)。 |
piper_noise_scale/piper_noise_scale_override | Piper 推理噪声尺度。 |
piper_noise_w/piper_noise_w_override | Piper 推理 noise_w。 |
zipvoice_clone_sample_rate/clone_sample_rate | 调用方提供的zipvoice/clone_audio的采样率(默认24000)。 |
zipvoice_clone_transcript/clone_transcript | 该克隆片段的文本。 |
zipvoice_model/zipvoice_model_name | zipvoice(完整版)还是蒸馏版;只改变采样默认值。源码中"zipvoice"之外的任意值都视为蒸馏。 |
zipvoice_distill | 使用蒸馏版 ZipVoice 采样默认值(默认 true)。 |
zipvoice_num_step/num_step | 扩散步数;<=0用模型默认值。 |
zipvoice_guidance_scale/guidance_scale | 引导尺度;<0用模型默认值。 |
zipvoice_t_shift/t_shift | 时间偏移(默认0.5)。 |
output/o | CLI 风格工具默认 WAV 输出路径(默认out.wav)。 |
engine/vocoder_engine | 接受但忽略(引擎由voice前缀决定)。源码注释明确标注 Deprecated。 |
键的别名与空值语义
源码中每个路径类键都有明确的"空值擦除"语义:例如kokoro_model传空串会files.erase_key(...)移除已设置的模型键,允许上层"取消覆盖"恢复默认布局;piper_noise_scale_override传空串则恢复为nullopt(即回到模型默认)。TTS 同样接受共享的资源根别名(g2p_root/path_root/model_root/tts_root)与 ORT 键。
未知键转发到 G2P
TTS 解析器对未识别的键不会报错,而是转发给 G2P 解析器——因为 TTS 内部依赖 G2P 完成文本到音素转换,语言相关的 G2P 键(如spanish_with_stress)需要在 TTS 选项中直接可用。反过来,在列取 G2P 依赖时,TTS 专属键(voice、Piper/Kokoro 路径等)会被忽略。
内存创建的键差异
用内存数据创建合成器(moonshine_create_tts_synthesizer_from_memory)时,传入的是文件映射键而非选项名,例如kokoro/prosody.model.ort、zipvoice/clone_audio、clone_asr/...——参见 C API 文档。这是"文件加载用选项、内存加载用文件键"的两种互补接口。
Grapheme to Phonemes 选项:资源根、词典覆盖与语言规则开关
G2P 选项传给GraphemeToPhonemizer(..., options=…)、moonshine_create_grapheme_to_phonemizer_*及moonshine_get_g2p_dependencies()。
Roots 与运行时
| 键 | 说明 |
|---|---|
g2p_root/path_root/model_root | 资源根(见 Shared options)。 |
use_cuda | 为 G2P ORT 会话启用 CUDA。 |
oov_onnx_override | 覆盖英文 OOV(out-of-vocabulary)模型路径/字节。 |
oov_onnx_config | 覆盖英文 OOV 的onnx-config.jsonUTF-8 文本。 |
allow_builtin_g2p_data | 已废弃,忽略。 |
同时接受ort_providers、coreml_cache_dir、log_profiling与log_api_calls。
词典与模型路径覆盖
以下键把对应的布局路径替换为自定义位置,与 moonshine-tts/data 目录下的语言资产目录一一对应:
| 键 | 设置 |
|---|---|
english_dict_path | en_us/dict_filtered_heteronyms.tsv |
german_dict_path | de/dict.tsv |
french_dict_path | fr/dict.tsv |
french_csv_dir | fr(POS CSV 目录) |
dutch_dict_path | nl/dict.tsv |
italian_dict_path | it/dict.tsv |
russian_dict_path | ru/dict.tsv |
chinese_dict_path | zh_hans/dict.tsv |
chinese_onnx_model_dir | 中文 RoBERTa UPOS 包目录 |
korean_dict_path | ko/dict.tsv |
vietnamese_dict_path | vi/dict.tsv |
japanese_dict_path | ja/dict.tsv |
japanese_onnx_model_dir | 日语 tok-POS 包目录 |
arabic_dict_path | ar_msa/dict.tsv |
arabic_onnx_model_dir | 阿拉伯语变音符号标注器包目录 |
hindi_dict_path | hi/dict.tsv |
portuguese_dict_path | 葡萄牙语词典覆盖 |
这些键对应的语言规则实现位于 core/moonshine-tts/src/lang-specific(40 个.cpp、39 个.h),每个语言模块都有配套的规则 G2P 测试(如 chinese-rule-g2p-test.cpp、russian-rule-g2p-test.cpp),可以据此验证自定义词典的生效行为。
语言特性开关
控制各语言 G2P 行为的布尔键(默认通常为 true,除非特别注明):
| 键 | 备注 |
|---|---|
spanish_with_stress、spanish_narrow_obstruents | 西班牙语 |
german_with_stress、german_vocoder_stress | 德语 |
french_with_stress、french_liaison、french_liaison_optional、french_oov_rules、french_expand_cardinal_digits | 法语 |
dutch_with_stress、dutch_vocoder_stress、dutch_expand_cardinal_digits | 荷兰语 |
italian_with_stress、italian_vocoder_stress、italian_expand_cardinal_digits | 意大利语 |
russian_with_stress、russian_vocoder_stress | 俄语 |
korean_expand_cardinal_digits | 韩语 |
portuguese_with_stress、portuguese_vocoder_stress、portuguese_expand_cardinal_digits、portuguese_apply_pt_pt_final_esh | 葡萄牙语;portuguese_keep_syllable_dots默认 false |
turkish_with_stress、turkish_expand_cardinal_digits | 土耳其语 |
ukrainian_with_stress、ukrainian_expand_cardinal_digits | 乌克兰语 |
hindi_with_stress、hindi_expand_cardinal_digits | 印地语 |
例如把french_liaison=false可关闭法语连诵规则、spanish_with_stress=false可关闭西班牙语重音标注,适合在需要与特定词典/训练数据对齐时微调。
Embeddings 选项:model_variant 独立参数与依赖清单
moonshine_create_embedding_model()使用独立参数model_variant(默认q4,可选q8),而不是 options 映射表;"fp32"、"fp16"、"q4f16"已不再支持。从内存创建虽然接受 options 数组,但当前会忽略它。
对于moonshine_get_embedding_dependencies(),只有:
| 键 | 说明 |
|---|---|
variant(别名model_variant) | 下载清单中包含哪个量化/浮点文件。 |
Speech clip extract 选项:语音片段提取的窗口控制
传给moonshine_extract_speech_clip()(以及包装它的 Python/VoiceClone 采集路径):
| 键 | 默认值 | 说明 |
|---|---|---|
clip_duration_seconds | 4 | 要提取的窗口长度(秒)。 |
minimum_speech_seconds | 2 | 窗口内is_complete所需的最少语音秒数。 |
vad_threshold | 0.5 | 语音概率阈值。 |
tail_pad_seconds | 0 | VAD 窗口之后追加的额外音频秒数。 |
同时接受log_api_calls。典型用法是在 VoiceClone 流程里先以较长的clip_duration_seconds圈定候选片段,再通过minimum_speech_seconds过滤掉静音过多的窗口。
Download manifests 选项:按需裁剪下载清单
依赖列取 API 与加载 API 共享同一套选项语法,只有少数键会改变清单内容。
Speech to Text(moonshine_get_stt_dependencies())
可传入与加载模型时相同的选项列表,但仅以下键影响列出的文件:
| 键 | 说明 |
|---|---|
model_arch | MOONSHINE_MODEL_ARCH_*常量的十进制字符串;省略则用语言默认。常量定义于 moonshine-c-api.h:TINY=0、BASE=1、TINY_STREAMING=2、BASE_STREAMING=3、SMALL_STREAMING=4、MEDIUM_STREAMING=5(其中BASE_STREAMING已定义但未发布)。 |
word_timestamps | 下载清单中包含注意力解码器。 |
include_spelling/spelling | 当该语言发布了拼写 CNN 组时将其纳入。 |
spelling_model_path | 非空路径与纳入拼写组等价。 |
TTS / G2P 依赖与声音列取
使用 TTS 与 G2P 章节的键(voice、g2p_root及相关项)。对应 C 入口为moonshine_get_tts_dependencies()、moonshine_get_tts_voices()、moonshine_get_g2p_dependencies(),签名见 C API。例如用{"voice": "kokoro_af_heart", "g2p_root": "..."}即可拿到该声音及其 G2P 资产的完整下载清单。
如何验证你的配置
- C API 测试:moonshine-c-api-test.cpp 中覆盖了
voice/speed/kokoro_dir/piper_onnx等组合与speed=2.0的逐调用覆盖(如 L691-L733、L1646-L1647);moonshine-c-api-memory-test.cpp 覆盖内存加载路径。 - TTS 速度测试:moonshine-tts-speed-test.cpp 通过
synthesize(text, {{"speed", "2.0"}})验证speed作为逐调用覆盖项的行为。 - 流式冒烟测试:streaming-language-smoke-test.cpp 涉及
max_tokens_per_second等流式参数的端到端行为。 - 选项解析单元测试:moonshine-tts-options-test.cpp 与 moonshine-g2p-options-test.cpp 直接验证各类键的解析与默认值。
小结
Moonshine 的 options 体系可以概括为三条规则:值永远是字符串(类型转换在解析器内完成)、键名大小写与连字符不敏感(且大量别名共存)、未知键按组件转发或报错(TTS→G2P 转发,Transcriber 直接抛错)。掌握 docs/api/options.md 这份目录,配合 C API 与 classes 文档中的入口说明,你就能在 Python、C、Swift 等任意绑定中写出等价且可移植的配置;需要更细的模型选择可参考 available-models,执行提供者与移动端限制见 execution-providers。
【免费下载链接】moonshineVery low latency speech to text, intent recognition, and text to speech, for building voice agents and interfaces项目地址: https://gitcode.com/GitHub_Trending/moonshine3/moonshine
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考