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)
        

训练好的词典和模型:

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

相关推荐
神奇夜光杯8 分钟前
Python酷库之旅-第三方库Pandas(202)
开发语言·人工智能·python·excel·pandas·标准库及第三方库·学习与成长
千天夜20 分钟前
使用UDP协议传输视频流!(分片、缓存)
python·网络协议·udp·视频流
测试界的酸菜鱼23 分钟前
Python 大数据展示屏实例
大数据·开发语言·python
羊小猪~~27 分钟前
神经网络基础--什么是正向传播??什么是方向传播??
人工智能·pytorch·python·深度学习·神经网络·算法·机器学习
放飞自我的Coder1 小时前
【python ROUGE BLEU jiaba.cut NLP常用的指标计算】
python·自然语言处理·bleu·rouge·jieba分词
正义的彬彬侠1 小时前
【scikit-learn 1.2版本后】sklearn.datasets中load_boston报错 使用 fetch_openml 函数来加载波士顿房价
python·机器学习·sklearn
张小生1802 小时前
PyCharm中 argparse 库 的使用方法
python·pycharm
秃头佛爷2 小时前
Python使用PDF相关组件案例详解
python
Dxy12393102162 小时前
python下载pdf
数据库·python·pdf
叶知安2 小时前
如何用pycharm连接sagemath?
ide·python·pycharm