Featured image of post TTS Evaluation Targets

TTS Evaluation Targets

语音评估指标及工具

声音质量指标:

MOS (Mean Opinion Score)

虽然这通常是主观评分,但也有自动MOS预测工具,如AutoMOS。

image.png

PESQ (Perceptual Evaluation of Speech Quality):

用于评估语音质量,特别是在电信系统中。

STOI (Short-Time Objective Intelligibility):

评估语音的可懂度

声音相似度指标:

  • Speaker Similarity Score:通常使用说话人验证模型(如d-vector或x-vector)来计算。
  • Voice Conversion Score:评估转换后的声音与目标声音的相似度。

发音准确度指标:

  • PER (Phoneme Error Rate):评估音素级别的准确性。
  • MCD (Mel Cepstral Distortion):测量合成语音与参考语音之间的频谱差异。

韵律指标:

  • F0 RMSE (Root Mean Square Error):评估基频(音高)的准确性
  • V/UV error (Voiced/Unvoiced error):评估浊音和清音的判断准确性。

整体性能指标:

  • WER (Word Error Rate):虽然主要用于ASR,但也可用于评估TTS的可懂度。
  • CER (Character Error Rate):类似WER,但在字符级别评估。

特定于声音克隆的指标:

  • EER (Equal Error Rate):在说话人验证任务中使用,评估克隆声音的欺骗性。 EER是FAR和FRR相等时的错误率。
  • FAR (False Acceptance Rate) 和 FRR (False Rejection Rate):在声音克隆任务中。 FAR = (错误接受的克隆声音样本数) / (总克隆声音样本数)
  • FRR(False Rejection Rate):FRR表示系统错误地拒绝了真实声音的比率。 FRR = (错误拒绝的真实声音样本数) / (总真实声音样本数)

声学特征相似度:

  • MFCC距离:比较原始声音和合成声音的MFCC(Mel频率倒谱系数)。
  • Spectral Convergence:评估频谱的相似度。

自然度指标:

  • Naturalness MOS:评估合成语音的自然程度。
  • Prosody MOS:评估韵律的自然度。

测试工具

音色相似度

resemblyzer

resemblyzer是一个可以计算音色向量的开源仓库,它使用深度学习模型来提取声音的高级表示,对音频进行decoder从而得到音色向量,通过计算音色向量之间的余弦相似度可以得到两个音频的相似分数。

使用示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
from resemblyzer import VoiceEncoder, preprocess_wav
from pathlib import Path

# 加载音频文件
wav_fpath = Path("path/to/audio/file.wav")
wav = preprocess_wav(wav_fpath)

# 初始化编码器
encoder = VoiceEncoder()

# 提取音频的嵌入向量
embed = encoder.embed_utterance(wav)

# 现在可以使用这个嵌入向量进行相似度比较

speechbrain

SpeechBrain是另一个强大的开源工具包,用于语音处理任务,包括声音相似度比较。虽然搜索结果中没有直接提到SpeechBrain,但根据我的知识,我可以为您介绍它的一些特点:

  • SpeechBrain提供了多种预训练模型,包括说话人识别模型,可以用于声音相似度比较。
  • 它支持提取说话人嵌入向量,这些向量可以用于计算不同音频之间的相似度。
  • SpeechBrain的模型通常输出说话人嵌入向量,这是一种编码不同人语音相似性的向量表示。[2]

使用示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import torch
from speechbrain.pretrained import EncoderClassifier

# 加载预训练的说话人识别模型
classifier = EncoderClassifier.from_hparams(source="speechbrain/spkrec-ecapa-voxceleb")

# 提取两个音频文件的嵌入向量
embedding1 = classifier.encode_batch(torch.tensor([waveform1]))
embedding2 = classifier.encode_batch(torch.tensor([waveform2]))

# 计算相似度(例如,使用余弦相似度)
similarity = torch.nn.functional.cosine_similarity(embedding1, embedding2)

测试下来speechbrain的分数差别比resemblyzer要大,但似乎有些不大准确的地方

PER (Phoneme Error Rate)&WER(Word Error Rate)测试工具:

jiwer

jiwer通常用来计算WER和PER

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import jiwer

def calculate_per(reference, hypothesis):
    reference = "sil dh ax cl t r ey n r ae n f ae s cl t sil"
    hypothesis = "sil dh ax cl t r ey n r ae n s l ow sil"
    return jiwer(reference, hypothesis)
    
def calculate_chinese_wer(self, reference, hypothesis):
    """计算中文WER"""
    reference = clean_text(reference)
    hypothesis = clean_text(hypothesis)

    ref_tokens = ' '.join(jieba.cut(reference))
    hyp_tokens = ' '.join(jieba.cut(hypothesis))
    
    ref_tokens = self.transformation(ref_tokens)
    hyp_tokens = self.transformation(hyp_tokens)
        
    return jiwer.wer(ref_tokens, hyp_tokens)

leven

leven 是一个Python包,可以用来计算PER和WER。它基于Levenshtein距离算法,能够产生与其他标准工具相同的结果。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
from leven import levenshtein

def calculate_error_rate(reference, hypothesis):
    """
    计算错误率 (可用于WER或PER)
    Args:
        reference: 参考序列(列表)
        hypothesis: 预测序列(列表)
    Returns:
        error_rate: 错误率
        num_errors: 编辑距离
    """
    # 计算编辑距离
    distance = levenshtein(reference, hypothesis)
    # 错误率 = 编辑距离 / 参考序列长度
    error_rate = distance / len(reference) if len(reference) > 0 else 0
    return error_rate, distance

def calculate_wer(reference_text, hypothesis_text):
    """
    计算词错误率 (WER)
    Args:
        reference_text: 参考文本
        hypothesis_text: 预测文本
    Returns:
        wer: 词错误率
        num_errors: 编辑距离
    """
    # 将文本分割成单词列表
    reference_words = reference_text.strip().split()
    hypothesis_words = hypothesis_text.strip().split()
    return calculate_error_rate(reference_words, hypothesis_words)

def calculate_per(reference_phones, hypothesis_phones):
    """
    计算音素错误率 (PER)
    Args:
        reference_phones: 参考音素序列
        hypothesis_phones: 预测音素序列
    Returns:
        per: 音素错误率
        num_errors: 编辑距离
    """
    # 如果输入是字符串,先分割成列表
    if isinstance(reference_phones, str):
        reference_phones = reference_phones.strip().split()
    if isinstance(hypothesis_phones, str):
        hypothesis_phones = hypothesis_phones.strip().split()
    return calculate_error_rate(reference_phones, hypothesis_phones)
Licensed under CC BY-NC-SA 4.0
使用 Hugo 构建
主题 StackJimmy 设计