跳转至

口语发音评测(SOE)技术分册 · GOP / wav2vec2 / 商用 SDK

用途:为「跟读评测」服务提供发音打分能力(用户跟读 → ASR 对齐 → 音素级打分 → JSON 报告);同时说清开源方案的边界,避免把研究代码当产品用。 环境:Windows Server 宿主机,2×Xeon Gold 6138(40 核 / 80 线程)、256GB 内存、F 盘 895G(剩余 862G);无独立 GPU,纯 CPU 推理。所有服务以 Docker 容器部署,产物只落 F:\EricLiu\,模型权重放 labs\models\。 版本基线:OpenPronounce v0.4.0(2026-11-09)|Kaldi egs/gop_speechocean762(recipe 随 Kaldi 主干)|CTC-based-GOP(INTERSPEECH 2024)|speechocean762 语料(SLR101,5000 句)|商用侧 Azure Pronunciation Assessment、讯飞 ISE、腾讯云智聆 SOE、驰声 Chivox(核对日期 2026-11-11,来源:官网/GitHub)


0. 现状核实结论(先看这段,避免走错路)

结论:开源"完整产品"极少,绝大多数是论文研究代码。截至目前,能直接 pip install 上手、且带 HTTP 接口和 Docker 的口语评测开源项目,实际只有 OpenPronounce 一个。

核实到的可用实现:

实现 形态 语言 成熟度 能否直接用
OpenPronounce(Halleck45) pip 包 + FastAPI + Docker + Web UI 英语(另有 6 语种实验性) ★★★★ 有版本、有 benchmark、有 CI ✅ 本机首选,CPU 可跑
Kaldi egs/gop_speechocean762 Kaldi recipe(需自己编译 Kaldi) 英语 ★★★ 官方 baseline,PCC 0.45 ⚠️ 教学价值高,工程化成本高
CTC-based-GOP(NTNU, INTERSPEECH 2024) 论文代码 + 脚本 英语 ★★ 研究代码 ⚠️ 需自己拼流水线
gopt(YuanGongND) 研究代码(GOPT Transformer) 英语 ★★ 研究代码 ⚠️ 偏论文复现
Si-Tones(laoszu) Conformer-CTC + AISHELL-1 + GOP 思路 中文(拼音) ★ 早期项目 ⚠️ 只能作为中文方案起点
商用:Azure / 讯飞 ISE / 腾讯云 / 驰声 SaaS API 中英及多语种 ★★★★★ 需付费,本库只做对比,不代注册

三个必须提前讲清的事实 1. 中文开源 SOE 基本是空白。公开标注语料只有英语的 speechocean762(且说话人是中国学习者);中文要自己解决"拼音音节 + 声调"的音素集与打分标准问题,没有公认开源基线。 2. 开源方案给的是"相对分",不是"考试分"。OpenPronounce 在 speechocean762 上与人类评分的 Spearman ρ≈0.65(按说话人 0.83),属于"可用反馈",不能用于认证、发证、分级考试。 3. 本机无 GPU 不影响 SOE。SOE 用的 wav2vec2-large 是 3 亿参数级模型,CPU 单句 1-3 秒,是语音链路里最不吃算力的一环。真正的瓶颈是"没有中文标注数据",不是算力。


1. 技术路线对比

1.1 三条路线

维度 ① 传统 GOP(GMM/DNN/HMM) ② wav2vec2 / CTC 端到端 ③ 商用 SDK
代表实现 Kaldi gop_speechocean762(TDNN nnet3) OpenPronounce、CTC-based-GOP、GOPT Azure PA、讯飞 ISE、腾讯云智聆 SOE、驰声
核心原理 母语声学模型前向得帧后验 → 强制对齐 → 算"期望音素后验 vs 最强竞争音素后验"的差 自监督表征 + CTC 音素识别,用后验或嵌入距离打分,可免强制对齐 厂商自研(多为 DNN/HMM + 大规模母语/学习者数据 + 专家标定)
是否需要强制对齐 必须(GOP 的定义依赖音素边界) 可选(CTC 后验可直接按帧取;OpenPronounce 用编辑距离对齐替代) 不需要,黑盒
是否需要音素词典 必须(lexicon / LG FST) 需要发音词典做"期望音素串"(espeak-ng / CMUdict / pypinyin) 不需要
中文支持 需自建拼音音素集 + 声调建模 同上,缺标注数据 ✅ 完整(声母/韵母/声调)
可解释性 ★★★★★ 每个音素的 GOP 值可追溯 ★★★☆ 后验/嵌入距离,可解释性中等 ★★ 只给分数与错误类型
冷启动成本 高(编译 Kaldi、训 TDNN、训 SVR) 中(下模型、拼流水线) 低(一个 API Key)
本机 CPU 可行性 ⚠️ 可行但重(Kaldi 编译 + 特征提取慢) ✅ 可行(单句 1-3s) ✅ 但走公网
典型精度 baseline:GOP 特征 + SVR,MSE 0.16 / PCC 0.45(音素级 0-10 分) OpenPronounce:句级 ρ=0.65(对 speechocean762 人工总分) 商用最佳,无公开可比口径

GOP 的定义(Witt & Young, 2000)——理解这一行,就理解了整个传统路线:

GOP(p) = log P(p | O)  −  max_{q ≠ p} log P(q | O)

O 是该音素对齐到的帧区间,p 是词典里的期望音素,q 遍历其它音素。 含义:"这段音频像 p 的程度,比像最强竞争对手 q 的程度高出多少"。差值为 0 或负 → 大概率发错;差值大 → 发音清晰。工程上再把这个标量(或它的分段统计 LPP/LPR)喂给每个音素一个回归器(Kaldi recipe 用 SVR),映射到 0-10 的人类评分。

1.2 商用 SDK 能力对比(只比能力,不代注册、不代调用)

能力 Azure Pronunciation Assessment 讯飞 ISE 腾讯云智聆 SOE 驰声 Chivox
评分维度 Accuracy / Fluency / Completeness / Prosody(+ 非脚本模式的 Content:词汇/语法/话题) 准确度、流利度、完整度、声调、音素级 精准度、流利度、完整度(PronCompletion)、音素级 PhoneInfos 总分 + 声母/韵母/声调,对齐 PSC 普通话水平测试口径
粒度 句 / 词 / 音素(可选 viseme) 句 → 词 → 音节 → 音素 四层 句 / 词 / 音素(起止时间、重音标记) 字 / 词 / 句,中文按拼音拆解
中文声调 支持,但社区反馈中文声调维度弱于国内厂商 ✅ 强项 ✅ 支持 ✅ 核心卖点(mā/má/mǎ/mà 级)
接入方式 REST / SDK(key 或 Entra ID) WebSocket 流式为主 HTTP / WebSocket HTTP + MCP Server(可直连 LLM 工具链)
音频限制 15s(短音频)/ 流式更长 分题型 段落/自由说 ≤300s,其余 ≤60s 按题型
语言覆盖 多语种,Prosody/Content 仅 en-US 中英为主 中英 中英,考试口径(IELTS/TOEFL/PSC)
计费量级 按音频时长 按次(第三方公开数据:20 万次套餐约 ¥0.006/次) 按次/套餐 注册赠 600 次,之后按成功调用计费
数据合规 音频出境需评估 国内 国内 国内,宣称评测后删音频

结论:做产品 → 商用 SDK;做学习/内网/零成本 → 开源。 本库实验一律走开源,商用只做对比说明(这也是 Roadmap 阶段 B 的既定规则)。

1.3 选型决策

要中文、要考试级口径、能付费? ── 是 ──> 商用 SDK(讯飞/驰声/腾讯云)
        │ 否
        ↓
英语跟读、要今天就能跑? ── 是 ──> OpenPronounce(CPU,pip 一行)
        │ 否
        ↓
中文、必须自研? ──> 自己拼:pypinyin 音节+声调 → CTC 音素模型 → GOP/后验打分
                     (参考 Si-Tones 思路,做好"没有标注集"的心理准备)

1.4 推荐结论

  • 首选 = OpenPronounce v0.4.0(MIT,纯 CPU):目前唯一"pip 一行 + 自带 FastAPI/Docker/Web UI"的开源 SOE,句级 ρ≈0.65 足以做练习反馈(不是考试分,官方亦明示 CPU 可跑)。
  • 选配 = Kaldi egs/gop_speechocean762:只想理解 GOP 原理或做学术复现时用;它是研究 recipe(PCC 仅 0.45,需自编译 Kaldi + 训 TDNN/SVR),不是产品。
  • 商用对照 = 讯飞 ISE / 腾讯云智聆 SOE / 驰声(Azure PA 补多语):要考试级口径、中文声调、四层粒度只能走商用;本库只做能力对比、不代注册不代调用。
  • 回避 = 把研究代码当生产、给中文硬套英语阈值:GOPT/Si-Tones 等仅作起点;中文没有公开标注集,必须先自建"拼音音节 + 声母/韵母/声调"评测集并标定,否则不得对外宣称支持中文评分。

2. 最小跑通路径:OpenPronounce(EB3-1)

2.1 为什么选它

  • MIT 许可,可改可商用(商用仍需自评效果)。
  • 纯 CPU,官方明示 "Runs on your machine, on CPU"。
  • 自带 HTTP 服务,有 POST /pronunciation、GET /health、GET /docs,与我们的服务化规范天然对齐。
  • pipeline 完整:音素识别 → 编辑距离对齐 → CTC 后验置信度 → DTW 声学距离 → 韵律曲线 → 0-100 分。

代价:模型不小(两个 wav2vec2-large,各约 1.2GB),首次运行要下 2.4GB;中文未标定。

2.2 安装(二选一)

方式 A:pip(最快,宿主机 venv)

python -m venv F:/EricLiu/Envs/openpronounce
F:/EricLiu/Envs/openpronounce/Scripts/activate

# 关键:先装 CPU 版 torch,体积小一半以上
pip install torch --index-url https://download.pytorch.org/whl/cpu
pip install openpronounce

# 系统依赖:ffmpeg(解码任意音频)+ espeak-ng(音素化)
# Windows 用 winget / choco 安装后确认在 PATH 里:
ffmpeg -version
espeak-ng --version

方式 B:Docker(服务化用)

cd F:/EricLiu/AppDocs/SOE/labs/src
git clone https://github.com/Halleck45/OpenPronounce.git
cd OpenPronounce
docker build -t local/openpronounce:0.4.0 .
docker run -d --name soe -p 8102:8000 \
  -e OPENPRONOUNCE_DEVICE=cpu \
  -e OPENPRONOUNCE_TTS=piper \
  -e OPENPRONOUNCE_TTS_VOICE=en_GB-cori-medium \
  -v F:/EricLiu/AppDocs/SOE/labs/models/hf:/root/.cache/huggingface \
  local/openpronounce:0.4.0

OPENPRONOUNCE_TTS=piper 让"参考音"离线合成(默认 gTTS 需要联网);但注意 Piper 音色会改变声学距离的基准,换引擎后要为该引擎重新校准(官方文档实测:换 Piper 会让好朗读的声学距离上移 1-2,分数略偏低)。

2.3 验证(EB3-1 判据)

# CLI 一行验证
openpronounce F:/EricLiu/AppDocs/SOE/labs/EB3-1-first-run/record.wav \
  "Hello, how are you?" --json --no-prosody

期望输出结构:

Score        : 59.0/100
Transcription: HELL NO WHO ARE YOU
Mispronounced:
  - hello: expected /həloʊ/, heard /hɛlnoʊ/ (confidence 89%)
  - how:   expected /haʊ/,  heard /hu/     (confidence 50%)
# HTTP 验证
curl -s localhost:8102/health
curl -s -X POST localhost:8102/pronunciation \
     -F "file=@record.wav" \
     -F "expected_text=Hello, how are you?" \
     -F "lang=en" | python -m json.tool | head -40

判据:CLI 输出 0-100 分 + 至少一个 words 级错误项;/health 返回 200;同一段音频重复跑分数稳定(±2 内)。

2.4 耗时与内存(本机估算,首次跑完请回填实测)

环节 CPU 耗时(估算) 说明
首次启动(下模型) 2.4GB / 视带宽 5-30 分钟 之后走本地缓存,HF_HUB_OFFLINE=1 可断网
模型加载到内存 10-30s 常驻进程只付一次
单句分析(5-10s 音频) 2-6s = 音素识别 + 词识别 + 参考音合成 + DTW + pYIN
常驻内存 3-5GB 两个 wav2vec2-large + torch
并发 1 路/容器 CPU 上别开多线程并发,靠多副本扩

3. 评测流水线设计(EB3-2)

3.1 架构

                    ┌─────────────────────────────────────────────┐
 句子文本 ──────────▶│ ① 文本前端:分词 + 音素化(拼音/CMU/espeak) │
                    └───────────────┬─────────────────────────────┘
                                    │ 期望音素序列 P_ref
 麦克风/上传 ──▶ ② 规整:重采样 16k 单声道、去首尾静音、峰值归一
                                    │
                                    ▼
                    ┌─────────────────────────────────────────────┐
                    │ ③ 声学模型:CTC 音素后验 / 强制对齐边界      │
                    └───────────────┬─────────────────────────────┘
                                    │ 帧后验 + 音素边界
                                    ▼
                    ┌─────────────────────────────────────────────┐
                    │ ④ 打分:GOP(p) → 音素分 → 词分 → 句分       │
                    │    辅以:PER/WER、DTW 声学距离、韵律(F0/能量)│
                    └───────────────┬─────────────────────────────┘
                                    ▼
                    ┌─────────────────────────────────────────────┐
                    │ ⑤ 聚合与反馈:错音定位 + 建议 + JSON 报告    │
                    └─────────────────────────────────────────────┘

3.2 各环节要点

环节 做法 坑
① 文本前端 英文 CMUdict/espeak;中文 pypinyin 取带声调拼音,再拆声母/韵母/声调三元组 多音字必须按上下文取音("银行/行走")
② 规整 统一 16kHz/16bit/单声道;ffmpeg -ar 16000 -ac 1;VAD 掐头去尾 采样率不对 → 后验全错;不归一化 → 音量小的被判"没发出来"
③ 声学 优先 CTC 音素模型(wav2vec2 微调);传统法需 nnet3 TDNN + LG FST 强制对齐 Kaldi 的 chain 模型不适合算 GOP(官方 recipe 明确用 no-chain TDNN)
④ 打分 音素 GOP → 词内加权 → 句内加权;再与流利度/完整度融合 单词过短(<3 音素)GOP 噪声大,需要置信度衰减
⑤ 反馈 只报"高置信度错误",宁缺勿滥 假阳性比漏报更伤学习体验

3.3 JSON 报告契约(服务间统一格式)

{
  "request_id": "20261111-0001",
  "lang": "en",
  "reference_text": "Hello, how are you?",
  "asr_transcript": "HELL NO WHO ARE YOU",
  "scores": {
    "overall": 59.0,
    "accuracy": 62.5,
    "fluency": 70.1,
    "completeness": 100.0,
    "prosody": null
  },
  "metrics": {
    "phoneme_error_rate": 0.21,
    "word_error_rate": 0.25,
    "acoustic_distance": 12.4
  },
  "words": [
    {
      "word": "hello",
      "position": 0,
      "score": 31,
      "expected_ipa": "h ə l oʊ",
      "heard_ipa": "h ɛ l n oʊ",
      "phones": [
        {"expected": "ə", "heard": "ɛ", "confidence": 0.89, "gop": -1.42},
        {"expected": "oʊ", "heard": "n oʊ", "confidence": 0.55, "gop": -0.31}
      ]
    }
  ],
  "prosody": {"f0_mean": 118.3, "f0_range": [82.1, 191.4], "energy_rms": 0.071},
  "engine": {"name": "openpronounce", "version": "0.4.0", "device": "cpu"},
  "elapsed_ms": 3180
}

字段命名对齐 OpenPronounce 原生输出(score / differences.errors[] / acoustic_distance / prosody.f0),外层再包一层统一信封,便于后续换引擎(商用 SDK)时上层不改。

3.4 编排骨架(可直接改成 assess.py)

"""跟读评测编排:音频 → 规整 → 音素打分 → JSON 报告。
依赖:openpronounce(音素识别/对齐/打分)、faster-whisper(可选,要词级时间戳时用)。
"""
import json
import subprocess
import tempfile
from pathlib import Path

from openpronounce import load_audio, compare_audio_with_text


def to_wav16k(src: str | Path) -> Path:
    """统一成 16kHz/16bit/单声道 —— 采样率错了后面全错。"""
    dst = Path(tempfile.mkdtemp()) / "norm.wav"
    subprocess.run(
        ["ffmpeg", "-y", "-i", str(src), "-ar", "16000", "-ac", "1",
         "-af", "silenceremove=start_periods=1:start_threshold=-45dB",
         str(dst)],
        check=True, capture_output=True,
    )
    return dst


def assess(audio_path: str, expected_text: str, lang: str = "en") -> dict:
    wav = to_wav16k(audio_path)
    sound = load_audio(str(wav))          # 内部已重采样为 16k mono
    raw = compare_audio_with_text(sound, expected_text, lang=lang)

    errors = raw.get("differences", {}).get("errors", [])
    words = [{
        "word": e["word"],
        "position": e.get("position"),
        "expected_ipa": e.get("expected"),
        "heard_ipa": e.get("actual"),
        "confidence": round(float(e.get("confidence", 0)), 3),
        "phones": e.get("phones", []),
    } for e in errors]

    # 置信度过滤:低于 0.5 的错误不报,减少假阳性(教学体验优先)
    words = [w for w in words if w["confidence"] >= 0.5]

    return {
        "lang": lang,
        "reference_text": expected_text,
        "asr_transcript": raw.get("transcribe"),
        "scores": {
            "overall": round(float(raw["score"]), 1),
            "accuracy": None,          # 开源版没有独立 accuracy,留空待融合
            "fluency": None,
            "completeness": None,
            "prosody": None,
        },
        "metrics": {
            "phoneme_error_rate": raw.get("differences", {}).get("phoneme_error_rate"),
            "word_error_rate": raw.get("differences", {}).get("word_error_rate"),
            "acoustic_distance": raw.get("acoustic_distance"),
        },
        "words": words,
        "engine": {"name": "openpronounce", "device": "cpu"},
    }


if __name__ == "__main__":
    print(json.dumps(
        assess("F:/EricLiu/AppDocs/SOE/labs/EB3-1-first-run/record.wav",
               "Hello, how are you?"),
        ensure_ascii=False, indent=2))

3.5 想自己算 GOP?核心只有 20 行(示意,非可直接运行)

import numpy as np
import torch

# posteriors: (T, V) 音素后验,来自 CTC 模型 softmax
# spans:      [(p_idx, t_start, t_end), ...] 期望音素及其对齐区间
def gop(posteriors: torch.Tensor, spans, eps: float = 1e-8) -> list[dict]:
    logp = torch.log(posteriors + eps)
    out = []
    for p, ts, te in spans:
        seg = logp[ts:te]                      # (L, V)
        if seg.numel() == 0:
            continue
        # 期望音素在该段的平均对数后验
        target = seg[:, p].mean().item()
        # 最强竞争音素(排除自身与静音)
        others = seg.clone()
        others[:, p] = -1e9
        best_other = others.max(dim=1).values.mean().item()
        out.append({
            "phone_idx": int(p),
            "gop": round(target - best_other, 4),   # 越接近 0/负 → 越可疑
            "lpp": round(target, 4),                # 绝对后验,辅助判断
        })
    return out

真实实现还要处理:静音/停顿帧、插入与删除(对齐路径里没有对应音素)、音素时长归一化、以及对 GOP 做时长与上下文归一化后再回归到 0-10 分(Kaldi recipe 用音素级 SVR)。别自己从零写打分器,除非你准备标几千条数据。


4. 与 TTS / ASR 的集成要点(EB3-3 里程碑)

4.1 端到端时序

① 取题:题库给一句文本 S
② TTS:Piper 合成 S 的参考音 ref.wav(0.1-0.5s),缓存 key = hash(S+voice+length_scale)
③ 播放:前端放 ref.wav,用户跟读,录 user.wav(16k mono)
④ ASR:faster-whisper int8 转写 → 判断"是不是念的这句"(WER 过高直接提示重录,不进打分)
⑤ SOE:OpenPronounce 对 user.wav + S 打分 → JSON
⑥ 融合:SOE 分(发音)+ ASR WER(内容)+ 时长比(流利度)→ 最终报告
⑦ 反馈:错音高亮 + 参考音重播 + 建议("th 咬舌")

4.2 集成清单

要点 做法 原因
参考音必须缓存 cache/{sha1(text+voice+len)}.wav 同一句重复练,避免重复合成;也保证分数基准一致
参考音引擎固定 全站固定同一个 Piper 音色,勿混用 gTTS 换引擎会让 acoustic_distance 整体偏移,分数不可比
采样率统一 16k/单声道 前端录音也强制 16k,服务入口再 ffmpeg 兜底 wav2vec2 输入固定 16k,错了结果全废
先 ASR 再 SOE WER>0.6 直接判"未按要求朗读" 防止"念完全无关内容"被算成发音错误
超时预算 TTS 1s + ASR 3s + SOE 6s,总 ≤10s CPU 现实值;超过就异步任务 + 轮询
端口规划 TTS 8101 / ASR 8103 / SOE 8102 与 §TTS 分册一致,避免冲突
同网段 docker network create ai-net,服务名互访 避免走宿主机 IP
健康检查 三服务都要 /health,网关按此摘除 EB1-2 已定规范
音频落盘 labs/EB3-3-follow-read/{req_id}/{ref,user}.wav 便于复现与听感对比

4.3 与 ASR 分册的边界

需求 用谁 说明
只要"说了什么" faster-whisper / FunASR 有语言模型纠错,恰恰不适合发音评测(会把错音"纠正"成对的)
要"说得准不准" SOE 音素识别模型 必须关掉/绕过语言模型,直接看音素后验
要词级时间戳 faster-whisper word_timestamps=True 只用于定位,不用于判分

一句话:ASR 负责"内容对不对",SOE 负责"发音准不准",两者不可互相替代。 OpenPronounce 内部同时用了两种 wav2vec2(音素识别 + 词识别),已经隐含这个分工。


5. 排障与局限

5.1 排障速查

现象 根因 处理
espeak-ng: command not found 系统缺音素化工具 Windows 装 espeak-ng 并加入 PATH;Docker 镜像已内置
ffmpeg not found 同上 装 ffmpeg,或用镜像
分数莫名很低(20-40) 采样率/声道不对、或音量为 0 ffprobe 查 16k/mono;加峰值归一化
所有词都报错 参考文本与音频语言不匹配(lang 传错) --lang en;中文目前不校准
分数波动大 短词(<3 音素)、背景噪声 置信度阈值提到 0.6;前端加降噪/VAD
首次调用超时 下 2.4GB 模型 预下载并挂载 HF 缓存;HF_HUB_OFFLINE=1
内存爆 多进程各自加载模型 单容器单进程,副本横向扩
OPENPRONOUNCE_TTS=gtts 报网络错 默认走 Google TTS 改 piper 或 kokoro 离线
Docker 里 GPU 报错 镜像选错 CPU 用 Dockerfile,GPU 才用 Dockerfile.gpu

5.2 局限(必须向用户明说)

  1. 只有英语被人工评分校准。法/西/德/意/葡/荷为实验性,直接复用英语阈值;中文不在支持列表。
  2. 音素识别器本身有错误率。官方说明:干净母语朗读约 1/10 音素会错 → 短词偶发假警报。在 speechocean762 上,被它标错的词里只有 1/5 被人类评委也判为错。
  3. 它是"校准过的启发式",不是在学习者标注数据上训练的模型。别当考试系统用。
  4. 强口音、儿童、噪声会显著掉点。wav2vec2 训练集是成人朗读语音;speechocean762 里儿童占一半,这正是它的短板场景。
  5. 中文需要另起炉灶:pypinyin 取带声调音节 → 声母/韵母/声调三元组 → 训练中文 CTC 音素模型(可参考 Si-Tones 用 AISHELL-1 的做法)→ 自建母语者参考分布。没有标注集就没有可信分数,这是最大障碍。
  6. 无 GPU 的现实:本方案能跑,但别指望实时并发。10 路并发需要 ~10 个副本 ≈ 40GB 内存 + 80 vCPU,已接近宿主机红线。
  7. 评分不可跨引擎比较。换 TTS 参考音、换麦克风、换阈值,分数都会整体平移;只在同一配置内做纵向对比(同一个用户多次练习)。

6. AI 操作守则(本分册强制)

  1. 先声明"这是相对分"。任何给出分数的场合,都要附带"非考试级、仅供练习反馈"的说明。
  2. 模型下载先报体积:OpenPronounce 两个 wav2vec2 约 2.4GB;Kaldi 镜像/编译产物 5GB+;中文 CTC 模型另算。确认后再下,落 labs\models\。
  3. 长任务后台跑:模型下载、Kaldi 编译、批量评测(>20 条)一律后台 + 定期汇报,不阻塞对话。
  4. CPU 耗时先预告:单句评测按 3-6 秒报,批量按 条数 × 5s 报;禁止承诺"实时"。
  5. 先跑 1 条再批量:批量前用 1 条已知"读对/读错"的样本验证,确认分数方向正确(读对高分、读错低分),再放大。
  6. 不碰商用 SDK 的注册与密钥:讯飞/腾讯云/Azure/驰声只做能力对比;用户自己要接,给文档链接即可。
  7. 不伪造语料:没有中文标注集就如实说"中文开源方案不成熟",不要用英语模型硬套中文再宣称"支持中文"。
  8. 产物留证:每次评测把 ref.wav / user.wav / report.json 存到 labs\E*XX-*\,报告里引用文件名。
  9. 改阈值要记录:置信度阈值、分数权重任何改动,写进实验报告,否则历史分数不可比。
  10. 失败即沉淀:踩坑与解决方式同步 AppDocs\Reusable\。

7. 参考链接与更新记录

  • OpenPronounce:https://github.com/Halleck45/OpenPronounce | PyPI: openpronounce
  • speechocean762 论文:Zhang et al., speechocean762: An Open-Source Non-native English Speech Corpus For Pronunciation Assessment, Interspeech 2021(arXiv:2104.01378)
  • speechocean762 数据:https://github.com/jimbozhang/speechocean762 | OpenSLR SLR101
  • Kaldi GOP recipe:https://github.com/kaldi-asr/kaldi/tree/master/egs/gop_speechocean762
  • CTC-based-GOP(INTERSPEECH 2024):https://github.com/a2d8a4v/CTC-based-GOP
  • GOPT:https://github.com/YuanGongND/gopt
  • Si-Tones(中文,实验性):https://github.com/laoszu/si-tones
  • Azure Pronunciation Assessment:https://learn.microsoft.com/azure/ai-services/speech-service/how-to-pronunciation-assessment
  • 腾讯云口语评测:https://cloud.tencent.com/document/product/269/136040
  • 讯飞语音评测(ISE):https://www.xfyun.cn/doc/Ise/IseAPI.html
  • 驰声:https://www.chivox.com/
日期 变更
2026-11-11 建档:核实开源 SOE 现状(结论:完整产品仅 OpenPronounce)、三路线对比、OpenPronounce 最小路径、GOP 流水线与 JSON 契约