【AI 应用】从“外国人味”到地道中文:kokoroi-rs v0.1.2 架构升级深度解析

从"外国人味"到地道中文:kokoroi-rs v0.1.2 架构升级深度解析

摘要:kokoroi-rs v0.1.2 版本对中文 TTS 引擎进行了重大架构升级,核心改进包括 G2P 引擎从 IPA 全面切换为 Bopomofo 音素方案、模型体系从单一模型升级为三档可选(S/M/L)、以及音频后处理从"过处理"重构为"最小干预"原则。本文深度解析了这些技术细节与设计考量,帮助开发者理解如何消除中文合成语音的"外国人味",实现更自然流畅的语音输出。

关键词:kokoroi-rs, 中文 TTS, G2P, Bopomofo, 注音符号, 音素转换, 模型量化, 音频后处理, 开源项目, Rust

G2P 引擎全面切换 Bopomofo、模型三档可选、音频后处理重构------一次让中文 TTS 脱胎换骨的升级

引子:一个困扰已久的问题

如果你用过早期的 kokoroi-rs,可能会注意到一个细微但难以忽视的问题:合成的中文语音听起来总有一种"外国人味"------发音是准的,但语调、韵律总觉得哪里不对劲。

问题出在 G2P(Grapheme-to-Phoneme,字素转音素) 环节。v0.1.1 及之前版本使用 IPA(国际音标)作为中文音素表示,但 IPA 对中文字素的覆盖不够精确,导致模型学到的音素分布与真实中文语音存在偏差。

v0.1.2 解决这个问题的方案很直接------全面切换为 Bopomofo(注音符号)音素方案。这只是一次升级的冰山一角,本文将系统拆解这次架构升级背后的技术细节与设计考量。


一、G2P 引擎重构:从 IPA 到 Bopomofo

1.1 为什么是 Bopomofo?

Kokoro 模型原生训练使用的正是 Bopomofo 音素表示。早期版本采用 IPA 方案,相当于在模型输入端做了一次"音素转译"------先把中文转成 IPA,再映射到模型词表。这个转译过程引入了信息损失,尤其体现在声调、连读变调等中文特有的韵律特征上。

v0.1.2 将 G2P 流水线全面切换到 Bopomofo,并配合专为中文优化的 ZH_VOCAB 词表,让模型直接"读懂"注音符号,消除了中间转译层。
#mermaid-svg-3wUw1zvsY8irB5Bz{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-3wUw1zvsY8irB5Bz .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3wUw1zvsY8irB5Bz .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3wUw1zvsY8irB5Bz .error-icon{fill:#552222;}#mermaid-svg-3wUw1zvsY8irB5Bz .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3wUw1zvsY8irB5Bz .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3wUw1zvsY8irB5Bz .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3wUw1zvsY8irB5Bz .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3wUw1zvsY8irB5Bz .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3wUw1zvsY8irB5Bz .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3wUw1zvsY8irB5Bz .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3wUw1zvsY8irB5Bz .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3wUw1zvsY8irB5Bz .marker.cross{stroke:#333333;}#mermaid-svg-3wUw1zvsY8irB5Bz svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3wUw1zvsY8irB5Bz p{margin:0;}#mermaid-svg-3wUw1zvsY8irB5Bz .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-3wUw1zvsY8irB5Bz .cluster-label text{fill:#333;}#mermaid-svg-3wUw1zvsY8irB5Bz .cluster-label span{color:#333;}#mermaid-svg-3wUw1zvsY8irB5Bz .cluster-label span p{background-color:transparent;}#mermaid-svg-3wUw1zvsY8irB5Bz .label text,#mermaid-svg-3wUw1zvsY8irB5Bz span{fill:#333;color:#333;}#mermaid-svg-3wUw1zvsY8irB5Bz .node rect,#mermaid-svg-3wUw1zvsY8irB5Bz .node circle,#mermaid-svg-3wUw1zvsY8irB5Bz .node ellipse,#mermaid-svg-3wUw1zvsY8irB5Bz .node polygon,#mermaid-svg-3wUw1zvsY8irB5Bz .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3wUw1zvsY8irB5Bz .rough-node .label text,#mermaid-svg-3wUw1zvsY8irB5Bz .node .label text,#mermaid-svg-3wUw1zvsY8irB5Bz .image-shape .label,#mermaid-svg-3wUw1zvsY8irB5Bz .icon-shape .label{text-anchor:middle;}#mermaid-svg-3wUw1zvsY8irB5Bz .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-3wUw1zvsY8irB5Bz .rough-node .label,#mermaid-svg-3wUw1zvsY8irB5Bz .node .label,#mermaid-svg-3wUw1zvsY8irB5Bz .image-shape .label,#mermaid-svg-3wUw1zvsY8irB5Bz .icon-shape .label{text-align:center;}#mermaid-svg-3wUw1zvsY8irB5Bz .node.clickable{cursor:pointer;}#mermaid-svg-3wUw1zvsY8irB5Bz .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-3wUw1zvsY8irB5Bz .arrowheadPath{fill:#333333;}#mermaid-svg-3wUw1zvsY8irB5Bz .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3wUw1zvsY8irB5Bz .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3wUw1zvsY8irB5Bz .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3wUw1zvsY8irB5Bz .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3wUw1zvsY8irB5Bz .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3wUw1zvsY8irB5Bz .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-3wUw1zvsY8irB5Bz .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3wUw1zvsY8irB5Bz .cluster text{fill:#333;}#mermaid-svg-3wUw1zvsY8irB5Bz .cluster span{color:#333;}#mermaid-svg-3wUw1zvsY8irB5Bz div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3wUw1zvsY8irB5Bz .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3wUw1zvsY8irB5Bz rect.text{fill:none;stroke-width:0;}#mermaid-svg-3wUw1zvsY8irB5Bz .icon-shape,#mermaid-svg-3wUw1zvsY8irB5Bz .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3wUw1zvsY8irB5Bz .icon-shape p,#mermaid-svg-3wUw1zvsY8irB5Bz .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-3wUw1zvsY8irB5Bz .icon-shape .label rect,#mermaid-svg-3wUw1zvsY8irB5Bz .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3wUw1zvsY8irB5Bz .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-3wUw1zvsY8irB5Bz .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-3wUw1zvsY8irB5Bz :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} v0.1.2 --- Bopomofo 方案
中文文本
jieba 分词 + POS
多音字消歧
变调处理
Bopomofo 注音转换
ZH_VOCAB Tokenization
ONNX 推理
v0.1.1 --- IPA 方案
中文文本
jieba 分词
拼音转换
IPA 音素映射
MODEL_VOCAB Tokenization
ONNX 推理

1.2 G2P 流水线对比

v0.1.2 的中文 G2P 流水线在多个环节做了增强:
#mermaid-svg-KBZ8XPAFs3yiqLW1{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-KBZ8XPAFs3yiqLW1 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .error-icon{fill:#552222;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .marker.cross{stroke:#333333;}#mermaid-svg-KBZ8XPAFs3yiqLW1 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-KBZ8XPAFs3yiqLW1 p{margin:0;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .cluster-label text{fill:#333;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .cluster-label span{color:#333;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .cluster-label span p{background-color:transparent;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .label text,#mermaid-svg-KBZ8XPAFs3yiqLW1 span{fill:#333;color:#333;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .node rect,#mermaid-svg-KBZ8XPAFs3yiqLW1 .node circle,#mermaid-svg-KBZ8XPAFs3yiqLW1 .node ellipse,#mermaid-svg-KBZ8XPAFs3yiqLW1 .node polygon,#mermaid-svg-KBZ8XPAFs3yiqLW1 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .rough-node .label text,#mermaid-svg-KBZ8XPAFs3yiqLW1 .node .label text,#mermaid-svg-KBZ8XPAFs3yiqLW1 .image-shape .label,#mermaid-svg-KBZ8XPAFs3yiqLW1 .icon-shape .label{text-anchor:middle;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .rough-node .label,#mermaid-svg-KBZ8XPAFs3yiqLW1 .node .label,#mermaid-svg-KBZ8XPAFs3yiqLW1 .image-shape .label,#mermaid-svg-KBZ8XPAFs3yiqLW1 .icon-shape .label{text-align:center;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .node.clickable{cursor:pointer;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .arrowheadPath{fill:#333333;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-KBZ8XPAFs3yiqLW1 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-KBZ8XPAFs3yiqLW1 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-KBZ8XPAFs3yiqLW1 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .cluster text{fill:#333;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .cluster span{color:#333;}#mermaid-svg-KBZ8XPAFs3yiqLW1 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-KBZ8XPAFs3yiqLW1 rect.text{fill:none;stroke-width:0;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .icon-shape,#mermaid-svg-KBZ8XPAFs3yiqLW1 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .icon-shape p,#mermaid-svg-KBZ8XPAFs3yiqLW1 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .icon-shape .label rect,#mermaid-svg-KBZ8XPAFs3yiqLW1 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-KBZ8XPAFs3yiqLW1 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-KBZ8XPAFs3yiqLW1 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-KBZ8XPAFs3yiqLW1 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} v0.1.2 G2P 流水线
v0.1.1 G2P 流水线
输入处理
文本输入
数字转换
标点映射
直接分词 + IPA 映射
MODEL_VOCAB

178 token 词表
segment_with_pos

词性标注分词
pre_merge_for_modify

合并修饰词
多音字消歧

PolyphonicDisambiguator
tone_sandhi

变调处理
pinyin_to_bopomofo

拼音 → 注音
ZH_VOCAB

178 token 扩展词表
ONNX 推理

关键改进点:

  • 词性标注分词segment_with_pos 不仅分词,还输出每个词的词性(POS),为后续变调处理提供上下文
  • 多音字消歧PolyphonicDisambiguator 基于上下文规则处理多音字,例如"了"在"了解"中读 liǎo,在"好了"中读 le
  • 变调处理:实现三声变调(两个三声相连,前变二声)以及"一"、"不"的变调规律
  • 拼音 → 注音pinyin_to_bopomofo 将带声调数字的拼音转换为 Bopomofo 符号

1.3 效果对比

维度 v0.1.1 (IPA) v0.1.2 (Bopomofo)
中文语音自然度 有外国人味道 自然流畅
首字延迟 ~730ms 静音可闻 ~50ms 正常前置
处理速度 (L 模型) ~2.2s ~1.9s
实时率 ~5.2x ~5.4x

二、模型体系升级:三档可选,丰俭由人

2.1 从单一到三档

v0.1.1 只有单一的 kokoro-v1.0.onnx(fp32,约 325MB)。v0.1.2 升级为 v1.1-zh 系列三档模型

模型 精度 大小 场景
S (kokoro-v1.1-zh-s.onnx) int4 47MB 最小体积,快速加载,低内存
M (kokoro-v1.1-zh-m.onnx) int8 79MB 默认推荐,平衡体积与质量
L (kokoro-v1.1-zh-l.onnx) fp32 311MB 完整精度,最佳质量

#mermaid-svg-KpQIMDJy702JoD5i{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-KpQIMDJy702JoD5i .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-KpQIMDJy702JoD5i .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-KpQIMDJy702JoD5i .error-icon{fill:#552222;}#mermaid-svg-KpQIMDJy702JoD5i .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-KpQIMDJy702JoD5i .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-KpQIMDJy702JoD5i .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-KpQIMDJy702JoD5i .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-KpQIMDJy702JoD5i .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-KpQIMDJy702JoD5i .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-KpQIMDJy702JoD5i .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-KpQIMDJy702JoD5i .marker{fill:#333333;stroke:#333333;}#mermaid-svg-KpQIMDJy702JoD5i .marker.cross{stroke:#333333;}#mermaid-svg-KpQIMDJy702JoD5i svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-KpQIMDJy702JoD5i p{margin:0;}#mermaid-svg-KpQIMDJy702JoD5i .pieCircle{stroke:#000000;stroke-width:2px;opacity:0.7;}#mermaid-svg-KpQIMDJy702JoD5i .pieOuterCircle{stroke:#000000;stroke-width:1px;fill:none;}#mermaid-svg-KpQIMDJy702JoD5i .pieTitleText{text-anchor:middle;font-size:25px;fill:#000000;font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-KpQIMDJy702JoD5i .slice{font-family:"trebuchet ms",verdana,arial,sans-serif;fill:#000000;font-size:17px;}#mermaid-svg-KpQIMDJy702JoD5i .legend text{fill:#000000;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:17px;}#mermaid-svg-KpQIMDJy702JoD5i :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 43% 41% 10% 6% 模型体积对比 v1.0 fp32 (旧) v1.1-zh L fp32 v1.1-zh M int8 v1.1-zh S int4

默认模型从 325MB 的 fp32 模型切换到 79MB 的 int8 模型,体积缩小 75%,而合成质量保持高水平。对于资源受限的场景(如嵌入式设备、边缘计算),47MB 的 int4 模型提供了更轻量的选择。

2.2 模型输入/输出接口

所有 v1.1-zh 模型统一使用以下接口:
#mermaid-svg-seZYOmHe6vJqMJG2{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-seZYOmHe6vJqMJG2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-seZYOmHe6vJqMJG2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-seZYOmHe6vJqMJG2 .error-icon{fill:#552222;}#mermaid-svg-seZYOmHe6vJqMJG2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-seZYOmHe6vJqMJG2 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-seZYOmHe6vJqMJG2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-seZYOmHe6vJqMJG2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-seZYOmHe6vJqMJG2 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-seZYOmHe6vJqMJG2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-seZYOmHe6vJqMJG2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-seZYOmHe6vJqMJG2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-seZYOmHe6vJqMJG2 .marker.cross{stroke:#333333;}#mermaid-svg-seZYOmHe6vJqMJG2 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-seZYOmHe6vJqMJG2 p{margin:0;}#mermaid-svg-seZYOmHe6vJqMJG2 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-seZYOmHe6vJqMJG2 .cluster-label text{fill:#333;}#mermaid-svg-seZYOmHe6vJqMJG2 .cluster-label span{color:#333;}#mermaid-svg-seZYOmHe6vJqMJG2 .cluster-label span p{background-color:transparent;}#mermaid-svg-seZYOmHe6vJqMJG2 .label text,#mermaid-svg-seZYOmHe6vJqMJG2 span{fill:#333;color:#333;}#mermaid-svg-seZYOmHe6vJqMJG2 .node rect,#mermaid-svg-seZYOmHe6vJqMJG2 .node circle,#mermaid-svg-seZYOmHe6vJqMJG2 .node ellipse,#mermaid-svg-seZYOmHe6vJqMJG2 .node polygon,#mermaid-svg-seZYOmHe6vJqMJG2 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-seZYOmHe6vJqMJG2 .rough-node .label text,#mermaid-svg-seZYOmHe6vJqMJG2 .node .label text,#mermaid-svg-seZYOmHe6vJqMJG2 .image-shape .label,#mermaid-svg-seZYOmHe6vJqMJG2 .icon-shape .label{text-anchor:middle;}#mermaid-svg-seZYOmHe6vJqMJG2 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-seZYOmHe6vJqMJG2 .rough-node .label,#mermaid-svg-seZYOmHe6vJqMJG2 .node .label,#mermaid-svg-seZYOmHe6vJqMJG2 .image-shape .label,#mermaid-svg-seZYOmHe6vJqMJG2 .icon-shape .label{text-align:center;}#mermaid-svg-seZYOmHe6vJqMJG2 .node.clickable{cursor:pointer;}#mermaid-svg-seZYOmHe6vJqMJG2 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-seZYOmHe6vJqMJG2 .arrowheadPath{fill:#333333;}#mermaid-svg-seZYOmHe6vJqMJG2 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-seZYOmHe6vJqMJG2 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-seZYOmHe6vJqMJG2 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-seZYOmHe6vJqMJG2 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-seZYOmHe6vJqMJG2 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-seZYOmHe6vJqMJG2 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-seZYOmHe6vJqMJG2 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-seZYOmHe6vJqMJG2 .cluster text{fill:#333;}#mermaid-svg-seZYOmHe6vJqMJG2 .cluster span{color:#333;}#mermaid-svg-seZYOmHe6vJqMJG2 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-seZYOmHe6vJqMJG2 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-seZYOmHe6vJqMJG2 rect.text{fill:none;stroke-width:0;}#mermaid-svg-seZYOmHe6vJqMJG2 .icon-shape,#mermaid-svg-seZYOmHe6vJqMJG2 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-seZYOmHe6vJqMJG2 .icon-shape p,#mermaid-svg-seZYOmHe6vJqMJG2 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-seZYOmHe6vJqMJG2 .icon-shape .label rect,#mermaid-svg-seZYOmHe6vJqMJG2 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-seZYOmHe6vJqMJG2 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-seZYOmHe6vJqMJG2 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-seZYOmHe6vJqMJG2 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 输出
模型
输入
input_ids

int641, N
style

float321, 256
speed

float321
ONNX 模型

v1.1-zh
waveform

float32N

模型输入输出保持稳定,切换模型无需修改业务代码,只需更换模型文件路径。


三、音频后处理:从"过处理"到"最小干预"

v0.1.1 的音频后处理存在过度加工的问题:全局 DC 偏移消除、RMS 窗口尾部检测、淡入淡出------这些操作本意是提升听感,但实际效果适得其反,静音区被偏移引入嗡嗡声,尾部裁切又带来爆音

v0.1.2 采取最小干预原则,仅保留振幅阈值静音裁切:
#mermaid-svg-j6d0KBxb40N2yWrp{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-j6d0KBxb40N2yWrp .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-j6d0KBxb40N2yWrp .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-j6d0KBxb40N2yWrp .error-icon{fill:#552222;}#mermaid-svg-j6d0KBxb40N2yWrp .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-j6d0KBxb40N2yWrp .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-j6d0KBxb40N2yWrp .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-j6d0KBxb40N2yWrp .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-j6d0KBxb40N2yWrp .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-j6d0KBxb40N2yWrp .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-j6d0KBxb40N2yWrp .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-j6d0KBxb40N2yWrp .marker{fill:#333333;stroke:#333333;}#mermaid-svg-j6d0KBxb40N2yWrp .marker.cross{stroke:#333333;}#mermaid-svg-j6d0KBxb40N2yWrp svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-j6d0KBxb40N2yWrp p{margin:0;}#mermaid-svg-j6d0KBxb40N2yWrp .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-j6d0KBxb40N2yWrp .cluster-label text{fill:#333;}#mermaid-svg-j6d0KBxb40N2yWrp .cluster-label span{color:#333;}#mermaid-svg-j6d0KBxb40N2yWrp .cluster-label span p{background-color:transparent;}#mermaid-svg-j6d0KBxb40N2yWrp .label text,#mermaid-svg-j6d0KBxb40N2yWrp span{fill:#333;color:#333;}#mermaid-svg-j6d0KBxb40N2yWrp .node rect,#mermaid-svg-j6d0KBxb40N2yWrp .node circle,#mermaid-svg-j6d0KBxb40N2yWrp .node ellipse,#mermaid-svg-j6d0KBxb40N2yWrp .node polygon,#mermaid-svg-j6d0KBxb40N2yWrp .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-j6d0KBxb40N2yWrp .rough-node .label text,#mermaid-svg-j6d0KBxb40N2yWrp .node .label text,#mermaid-svg-j6d0KBxb40N2yWrp .image-shape .label,#mermaid-svg-j6d0KBxb40N2yWrp .icon-shape .label{text-anchor:middle;}#mermaid-svg-j6d0KBxb40N2yWrp .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-j6d0KBxb40N2yWrp .rough-node .label,#mermaid-svg-j6d0KBxb40N2yWrp .node .label,#mermaid-svg-j6d0KBxb40N2yWrp .image-shape .label,#mermaid-svg-j6d0KBxb40N2yWrp .icon-shape .label{text-align:center;}#mermaid-svg-j6d0KBxb40N2yWrp .node.clickable{cursor:pointer;}#mermaid-svg-j6d0KBxb40N2yWrp .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-j6d0KBxb40N2yWrp .arrowheadPath{fill:#333333;}#mermaid-svg-j6d0KBxb40N2yWrp .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-j6d0KBxb40N2yWrp .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-j6d0KBxb40N2yWrp .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-j6d0KBxb40N2yWrp .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-j6d0KBxb40N2yWrp .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-j6d0KBxb40N2yWrp .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-j6d0KBxb40N2yWrp .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-j6d0KBxb40N2yWrp .cluster text{fill:#333;}#mermaid-svg-j6d0KBxb40N2yWrp .cluster span{color:#333;}#mermaid-svg-j6d0KBxb40N2yWrp div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-j6d0KBxb40N2yWrp .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-j6d0KBxb40N2yWrp rect.text{fill:none;stroke-width:0;}#mermaid-svg-j6d0KBxb40N2yWrp .icon-shape,#mermaid-svg-j6d0KBxb40N2yWrp .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-j6d0KBxb40N2yWrp .icon-shape p,#mermaid-svg-j6d0KBxb40N2yWrp .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-j6d0KBxb40N2yWrp .icon-shape .label rect,#mermaid-svg-j6d0KBxb40N2yWrp .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-j6d0KBxb40N2yWrp .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-j6d0KBxb40N2yWrp .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-j6d0KBxb40N2yWrp :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} v0.1.2 --- 最小干预
模型原始输出

11.65s
振幅阈值静音裁切

threshold: 0.006
纯净输出

9.51s,无加工伪影
v0.1.1 --- 过处理
模型原始输出

11.65s
全局 DC 偏移消除
RMS 窗口尾部检测
淡入淡出
!! 问题 !!

静音区偏移 → 嗡嗡声

尾部裁切 → 爆音

效果:尾部噪音被精准裁切,文件时长从 11.65s 精确到 9.51s,消除了约 1.4s 的冗余静音,且无任何加工伪影。


四、各模块改进一览

4.1 CLI 工具

diff 复制代码
- 默认模型: models/kokoro-v1.0.onnx (325MB)
+ 默认模型: models/kokoro-v1.1-zh-m.onnx (79MB, int8)

+ 新增 -m/--model 参数,支持模型切换
+ 自动下载指向本项目 Release

4.2 HTTP Server

diff 复制代码
- Web 页面: 仅 SSE 流式播放,无下载功能
+ Web 页面: SSE 流式播放 + 自动拼接完整 WAV + 下载链接

+ 音频后处理: 振幅阈值静音裁切

Server 端的 Web 演示页面现在支持流式播放的同时自动拼接完整音频,用户试听满意后可直接下载 WAV 文件,体验更完整。

4.3 WASM 模块

diff 复制代码
- 模型: 固定 model_fp16.onnx
+ 模型: 三档切换 (S int4 / M int8 / L fp32)

+ 新增 phonemizeBopomofo() API
+ 新增 tokenizeV11() API

WASM 模块的 JavaScript API 同步升级,支持 Bopomofo 音素化接口,前端开发者可以更灵活地控制合成流程。

4.4 工程化改进

diff 复制代码
+ 模型文件纳入 Git 管理 (S/M,<100MB)
+ 模型下载从本项目 Release 获取
+ 文档更新: README / README_EN / docs/wasm.md
+ Server/WASM 界面截图
+ 移除所有 tiandy 字样及外部仓库依赖
+ 移除开发环境私有路径

项目彻底清理了历史遗留的外部依赖和私有路径,现在完全自包含,开箱即用。


五、升级路径

从 v0.1.1 升级到 v0.1.2 非常简单:

bash 复制代码
# 1. 下载新模型(以 M 档为例)
wget https://github.com/doiito/kokoroi-rs/releases/download/v0.1.2/kokoro-v1.1-zh-m.onnx \
  -O models/kokoro-v1.1-zh-m.onnx

# 2. 更新配置文件 config.toml
# model_path = "models/kokoro-v1.1-zh-m.onnx"

# 3. 运行(CLI 自动使用新 G2P 流水线)
./koko --text "你好世界" --model models/kokoro-v1.1-zh-m.onnx

无需修改业务代码,新架构自动使用 Bopomofo G2P + ZH_VOCAB。


六、系统架构总览

#mermaid-svg-W9NncPsVFZ8lwfNZ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-W9NncPsVFZ8lwfNZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-W9NncPsVFZ8lwfNZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-W9NncPsVFZ8lwfNZ .error-icon{fill:#552222;}#mermaid-svg-W9NncPsVFZ8lwfNZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-W9NncPsVFZ8lwfNZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-W9NncPsVFZ8lwfNZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-W9NncPsVFZ8lwfNZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-W9NncPsVFZ8lwfNZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-W9NncPsVFZ8lwfNZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-W9NncPsVFZ8lwfNZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-W9NncPsVFZ8lwfNZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-W9NncPsVFZ8lwfNZ .marker.cross{stroke:#333333;}#mermaid-svg-W9NncPsVFZ8lwfNZ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-W9NncPsVFZ8lwfNZ p{margin:0;}#mermaid-svg-W9NncPsVFZ8lwfNZ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-W9NncPsVFZ8lwfNZ .cluster-label text{fill:#333;}#mermaid-svg-W9NncPsVFZ8lwfNZ .cluster-label span{color:#333;}#mermaid-svg-W9NncPsVFZ8lwfNZ .cluster-label span p{background-color:transparent;}#mermaid-svg-W9NncPsVFZ8lwfNZ .label text,#mermaid-svg-W9NncPsVFZ8lwfNZ span{fill:#333;color:#333;}#mermaid-svg-W9NncPsVFZ8lwfNZ .node rect,#mermaid-svg-W9NncPsVFZ8lwfNZ .node circle,#mermaid-svg-W9NncPsVFZ8lwfNZ .node ellipse,#mermaid-svg-W9NncPsVFZ8lwfNZ .node polygon,#mermaid-svg-W9NncPsVFZ8lwfNZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-W9NncPsVFZ8lwfNZ .rough-node .label text,#mermaid-svg-W9NncPsVFZ8lwfNZ .node .label text,#mermaid-svg-W9NncPsVFZ8lwfNZ .image-shape .label,#mermaid-svg-W9NncPsVFZ8lwfNZ .icon-shape .label{text-anchor:middle;}#mermaid-svg-W9NncPsVFZ8lwfNZ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-W9NncPsVFZ8lwfNZ .rough-node .label,#mermaid-svg-W9NncPsVFZ8lwfNZ .node .label,#mermaid-svg-W9NncPsVFZ8lwfNZ .image-shape .label,#mermaid-svg-W9NncPsVFZ8lwfNZ .icon-shape .label{text-align:center;}#mermaid-svg-W9NncPsVFZ8lwfNZ .node.clickable{cursor:pointer;}#mermaid-svg-W9NncPsVFZ8lwfNZ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-W9NncPsVFZ8lwfNZ .arrowheadPath{fill:#333333;}#mermaid-svg-W9NncPsVFZ8lwfNZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-W9NncPsVFZ8lwfNZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-W9NncPsVFZ8lwfNZ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-W9NncPsVFZ8lwfNZ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-W9NncPsVFZ8lwfNZ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-W9NncPsVFZ8lwfNZ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-W9NncPsVFZ8lwfNZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-W9NncPsVFZ8lwfNZ .cluster text{fill:#333;}#mermaid-svg-W9NncPsVFZ8lwfNZ .cluster span{color:#333;}#mermaid-svg-W9NncPsVFZ8lwfNZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-W9NncPsVFZ8lwfNZ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-W9NncPsVFZ8lwfNZ rect.text{fill:none;stroke-width:0;}#mermaid-svg-W9NncPsVFZ8lwfNZ .icon-shape,#mermaid-svg-W9NncPsVFZ8lwfNZ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-W9NncPsVFZ8lwfNZ .icon-shape p,#mermaid-svg-W9NncPsVFZ8lwfNZ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-W9NncPsVFZ8lwfNZ .icon-shape .label rect,#mermaid-svg-W9NncPsVFZ8lwfNZ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-W9NncPsVFZ8lwfNZ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-W9NncPsVFZ8lwfNZ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-W9NncPsVFZ8lwfNZ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 模型数据
核心引擎
前端
CLI

koko-cli
REST API

kokoros-server
WASM Browser

kokoros_bg.wasm
G2P 引擎

ChineseG2P
音素化

Phonemizer

Bopomofo 模式
Tokenization

ZH_VOCAB
ONNX 推理

OrtKoko
后处理

振幅阈值裁切
ONNX 模型

v1.1-zh S/M/L
发音人嵌入

voices-v1.0.bin


七、总结与展望

v0.1.2 是一次从音素表示到模型体系到音频后处理的全链路升级:

  • G2P 引擎:IPA → Bopomofo,消除"外国人味道"
  • 模型体系:三档可选(int4/int8/fp32),默认模型体积缩小 75%
  • 音频后处理:从过处理到最小干预,消除爆音和嗡嗡声
  • 各模块同步升级:CLI、Server、WASM 全部适配新架构

如果你曾在 kokoroi-rs 上遇到过中文语音不够自然的问题,现在值得重新体验一次。

项目持续迭代中,欢迎到 GitHub 仓库体验、提 Issue 或贡献代码。

项目地址:github.com/doiito/kokoroi-rs


本文基于 kokoroi-rs v0.1.2 版本更新整理,欢迎交流讨论。

相关推荐
GuWenyue1 小时前
AI对话打字机效果卡顿崩溃?1套Vue3流式代码搞定逐Token输出,彻底解决断包报错
人工智能
叶总没有会1 小时前
3.2 构建AI智能体项目扩展知识
java·数据库·人工智能·spring·ai
易知微EasyV数据可视化1 小时前
工业制造如何实现柔性规划?数字孪生技术助力产线布局编排与方案推演
人工智能·经验分享·制造·数字孪生·可视化·三维建模
pla888888881 小时前
热词驱动,智辨声纹——从ASR热词到说话人日志的尝试:海光DCU环境部署FunASR热词语音识别系统(说话人日志已集成,含完整代码)
人工智能·语音识别
编程牛马姐1 小时前
并发、多线程和HTTP连接之间有什么关系?
人工智能
羑悻的小杀马特2 小时前
把随身WiFi改成网盘聚合器:中兴F50挂载本地存储+夸克网盘实战
运维·服务器·人工智能·网盘·openlist
meilindehuzi_a2 小时前
从跑分到生产力:重新理解大模型基准测试与分层协作
人工智能
蜜桃味女焊匠人3 小时前
焊接生产线优化思路:解决手工焊、机器人焊气体浪费问题
人工智能·经验分享·其他·机器人
Georgeviewer8 小时前
商业落地评测|实体门店GEO优化性价比与服务体系深度复盘
大数据·人工智能