MFA(Montreal Forced Aligner3.0.0)使用过程遇到的问题总结

话说真的好久没有更新文章了,这段时间,自己在技术上也发生很大的转变,从原来做直播中台Android相关,后来中台的解散,转到公司的RTC部门做音视频开发,随着元宇宙的热门,又转战Unity数字人相关开发,现在又做AI照片人相关工作,真的好曲折,不过没有办法,现在大环境不好,只能拥抱变化了,下面是最近做的一个音频音素对齐的项目,在使用MFA3.0.0遇到的一些问题总结

项目地址

主页:montreal-forced-aligner.readthedocs.io/en/latest/i...

github: github.com/MontrealCor...

环境搭建:

安装项目主页的安装流程,这个过程没有遇到什么问题

生成字典

这里以中文拼音举例,montreal-forced-aligner.readthedocs.io/en/latest/f... model download g2p mandarin_pinyin_g2p,是下载不下来,据说是github的限制,不过这个模型可以在github.com/MontrealCor...

例如774.lab这个文件的一些拼音没有用空格分割开,这里只能手动fix一下

运行命令生成字典

按照官网的命令

bash 复制代码
mfa g2p mandarin_pinyin_g2p /path/to/mandarin/dataset /path/to/save/mandarin_dict.txt

mandarin_pinyin_g2p:刚才下载的模型

/path/to/mandarin/dataset:下载的测试数据集

/path/to/save/mandarin_dict.txt:生成字典文件位置

直接编码错误,难道模型或者数据集有不是UTF-8编码的文件,但是对比一下都是UTF-8,没有办法,参考网上怎么解决这种错误,然后改造MFA代码,使用codecs读取

直接再运行,这里不报错了,但是又报下面的错误

找不到model.fst,但是注意到怎么是在我数据集的目录下找这个呢,不是模型目录下?于是跟踪一下MFA这个命令的模型,在接收模型路径的地方输出一下日志

结果

数据集和模型路径刚好相反了,查看官网montreal-forced-aligner.readthedocs.io/en/latest/u... mfa g2p的命令

css 复制代码
mfa g2p [OPTIONS] INPUT_PATH G2P_MODEL_PATH OUTPUT_PATH

模型和数据集输入顺序刚好相反

调换位置重新执行

bash 复制代码
mfa g2p /data2/dengqu/mfa/mandarin_example /data2/dengqu/mfa/mandarin_pinyin_g2p.zip /data2/dengqu/mfa/dict/dict.txt

这样就成功了,查看生成的字典也是对的

生成声学模型

按照官网给出的命令

lua 复制代码
mfa train /path/to/mandarin/dataset /path/to/save/mandarin_dict.txt /path/to/save/output
/

报上面错误,找了一些资料,加上--clean试试

开始训练模型了

成功生成模型

使用生成的声学模型进行对齐

css 复制代码
mfa align [OPTIONS] CORPUS_DIRECTORY DICTIONARY_PATH ACOUSTIC_MODEL_PATH
          OUTPUT_DIRECTORY

CORPUS_DIRECTORY:需要对齐的数据集

DICTIONARY_PATH:字典路径,这里上面生成的字典

ACOUSTIC_MODEL_PATH:声学模型路径,这里填写上面生成的声学模型

OUTPUT_DIRECTORY:对齐结果存储目录

OPTIONS:这个可以参考montreal-forced-aligner.readthedocs.io/en/latest/u...

bash 复制代码
mfa align /data2/dengqu/mfa/mandarin_example /data2/dengqu/mfa/dict/dict.txt /data2/dengqu/mfa/dict/test_model.zip /data2/dengqu/mfa/dict --clean

成功生成对齐结果

Praat结果查看

具体Praat的使用教程可以自行google

打开wav和textGrid文件,然后选中两个,点击view&Edit

发现不太准,不过毕竟训练的数据量太少了,官网也是这样解析

使用MFA1.0.0现有训练的模型和字典

要使模型精准,需要大量的训练集进行训练,目前这里有份网上训练好的,军富他们也在用,不过MFA的版本是1.0.0的,MFA1.0.0版本下载

github.com/MontrealCor...

训练好的拼音的声学模型:

暂时无法在飞书文档外展示此内容

对应的拼音词典:

暂时无法在飞书文档外展示此内容

解压下载好MFA1.0.0压缩包

其中bin文件夹下就是mfa 执行命名的exe,使用上面的声学模型和词典对齐数据集,window上打开cmd

r 复制代码
F:\download\montreal-forced-aligner\bin\mfa_align.exe F:\download\montreal-forced-aligner\mandarin_example F:\download\montreal-forced-aligner\pinyin-lexicon-r.txt F:\download\montreal-forced-aligner\aishell_alignment_model.zip F:\download\montreal-forced-aligner\output

进行对齐

数据集

上面进行训练的数据集很少,只有6个,所以训练出来的效果很差,不过有开源的数据集可以自行下载进行训练

THCHS-30 不过下载的数据需要自行提取一下lab内容,原来内容如下:

我们只需要提取第二行拼音,然后保存为.lab文件就行,可以参考如下脚本

py 复制代码
import os

dir = "/Users/spring/Downloads/data_thchs30/data"
filter=[".trn"] #设置过滤后的文件类型 当然可以设置多个类型

def all_path(dirname):

    result = []#所有的文件

    for maindir, subdir, file_name_list in os.walk(dirname):

        # print("1:",maindir) #当前主目录
        # print("2:",subdir) #当前主目录下的所有目录
        # print("3:",file_name_list)  #当前主目录下的所有文件

        for filename in file_name_list:
            apath = os.path.join(maindir, filename)#合并成一个完整路径
            ext = os.path.splitext(apath)[1]  # 获取文件后缀 [0]获取的是除了文件名以外的内容

            if ext in filter:
                result.append(apath)

    return result

all_paths = all_path(dir)

parent_dir = os.path.dirname(dir)
train_data_dir = os.path.join(parent_dir, 'mfaTrainData')
isExists=os.path.exists(train_data_dir) #判断路径是否存在,存在则返回true
if not isExists:
  #如果不存在则创建目录
  #创建目录操作函数
  os.makedirs(train_data_dir)
  print('创建成功:' + train_data_dir)

count = all_paths.count
print('data count:' + str(count))
index = 0
for path in all_paths:
    #if index == 1:
    #    break
    index = index + 1
    index = path.rindex('.')
    wav_path = path[0:index]
    a = os.path.basename(wav_path)#带后缀的文件名
    b = os.path.basename(wav_path).split('.')[0]#不含后缀带路径的文件名

    lab_path = os.path.join(train_data_dir, (b + '.lab'))
    print('lab_path:' + lab_path)
    if os.path.exists(lab_path):
       os.remove(lab_path)
    
    copy_wav_file = os.path.join(train_data_dir, a)
    print('copy_wav_file:' + copy_wav_file)
    if os.path.exists(copy_wav_file):
       os.remove(copy_wav_file)
    os.popen('cp ' + wav_path + ' ' + copy_wav_file)
    #print('cp ' + wav_path + ' to ' + copy_wav_file)
    with open(path,'r') as f:
        lines=f.readlines()
        start = 1
        end  = len(lines)
        with open(lab_path,'w') as t:
            t.write(lines[1])
        #print(lines[1])
        #print('一行数据')
            

训练好的词典和模型:

貌似上传不了,需要的可以私信我

AISHELL-3

AISHELL-3数据集是比THCHS-30大很多的数据集,当然其生成的词典和模型就更加完善,同样需要自行提取lab内容

参考脚本

py 复制代码
import os
import FileUtils
contentPath = "/Users/spring/fsdownload/AISHELL-3/train/content.txt"
wavDir = os.path.join(os.path.dirname(contentPath), 'wav')
print('wavDir:' + wavDir)
dataDir = os.path.join(os.path.dirname(contentPath), 'data')
isExists=os.path.exists(dataDir) #判断路径是否存在,存在则返回true
if not isExists:
  #如果不存在则创建目录
  #创建目录操作函数
  os.makedirs(dataDir)
  print('创建成功:' + dataDir)
wavFiles = FileUtils.filterFiles(wavDir, filter=[".wav"])
wavDict = {}
for wavFile in wavFiles:
    key = os.path.basename(wavFile)
    wavDict[key] = wavFile
print('wavFiles count:' + str(len(wavDict)))
with open(contentPath,'r') as f:
    lines=f.readlines()
    for line in lines:
        wavName = line.split('	')[0]
        wavFile = wavDict[wavName]
        a = os.path.basename(wavFile)#带后缀的文件名
        copy_wav_file = os.path.join(dataDir, a)
#       print('copy_wav_file:' + copy_wav_file)
        if os.path.exists(copy_wav_file):
           os.remove(copy_wav_file)
        os.popen('cp ' + wavFile + ' ' + copy_wav_file)
        #print('cp ' + wavFile + ' to ' + copy_wav_file)
        b = os.path.basename(wavFile).split('.')[0]#不含后缀带路径的文件名
        labPath = os.path.join(dataDir, b + '.lab')
        texts = line.split('	')[1].split(' ')[1::2]
        lineText = ' '.join(texts)
        #print('wavFile:' + wavFile + ' line:' + lineText)
        with open(labPath,'w') as t:
             t.write(lineText)
        

训练好的词典和模型:

貌似上传不了,需要的可以私信我

相关推荐
数据智能老司机3 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机4 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机4 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机4 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i4 小时前
drf初步梳理
python·django
每日AI新事件4 小时前
python的异步函数
python
这里有鱼汤5 小时前
miniQMT下载历史行情数据太慢怎么办?一招提速10倍!
前端·python
databook14 小时前
Manim实现脉冲闪烁特效
后端·python·动效
程序设计实验室15 小时前
2025年了,在 Django 之外,Python Web 框架还能怎么选?
python
倔强青铜三16 小时前
苦练Python第46天:文件写入与上下文管理器
人工智能·python·面试