Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

支持自定义读音(多音字),非常灵活 #1728

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

yitenghao
Copy link

支持使用在中文文本后通过英文括号包起来的TONE3格式的拼音
例如:这个字的读音是角(jue2)色,而不是角(jiao3)色
实现逻辑:
1、添加了一个处理自定义拼音的函数custom_pinyin,返回去除拼音后的中文文本和拼音列表
2、在_g2p函数中使用custom_pinyin函数,并使用获取到的自定义拼音替换g2pw模型推理出的拼音
3、去除拿词与拼音映射缓存的逻辑

@yitenghao yitenghao changed the title 支持自定义读音(多音字) 支持自定义读音(多音字),非常灵活 Oct 28, 2024
@huanglong123
Copy link

你好,我想问下这个指定多音字读音的要怎么使用,我使用了最新代码,推理了一下,“这个字的读音是角(jue2)色,而不是角(jiao3)色”发现并没有生效

@yitenghao
Copy link
Author

你好,我想问下这个指定多音字读音的要怎么使用,我使用了最新代码,推理了一下,“这个字的读音是角(jue2)色,而不是角(jiao3)色”发现并没有生效

参考pr的文件改动修改代码内容,另外我这个是使用api.py进行推理的

@foreverhell
Copy link

代码已经改动了。同没生效,jue、jiao逐个字母读,2、3读汉字

@hjj-lmx
Copy link

hjj-lmx commented Nov 20, 2024

代码已经改动了。同没生效,jue、jiao逐个字母读,2、3读汉字

大佬,你解决了吗?

@ZiyiLiubird
Copy link

ZiyiLiubird commented Nov 20, 2024

现在的版本会把(jue2)视为英文切割出来,导致custom_pinyin函数失效。
需要在GPT-SoVITS/GPT_SoVITS/TTS_infer_pack/TextPreprocessor.py这个文件里把131-135和162-169两部分代码注释掉才可以。分别是

                if re.search(r'[A-Za-z]', formattext):
                     formattext = re.sub(r'[a-z]', lambda x: x.group(0).upper(), formattext)
                     formattext = chinese.mix_text_normalize(formattext)
                     return self.get_phones_and_bert(formattext,"zh",version)
                else:

以及

             else:
                 for tmp in LangSegment.getTexts(text):
                     if tmp["lang"] == "en":
                         langlist.append(tmp["lang"])
                     else:
                        # 因无法区别中日韩文汉字,以用户输入为准
                         langlist.append(language)
                     textlist.append(tmp["text"])

这样代码无法处理中英文混合情况,但是可以处理多音字

@hjj-lmx
Copy link

hjj-lmx commented Nov 20, 2024

现在的版本会把(jue2)视为英文切割出来,导致custom_pinyin函数失效。 需要在GPT-SoVITS/GPT_SoVITS/TTS_infer_pack/TextPreprocessor.py这个文件里把131-135和162-169两部分代码注释掉才可以。分别是

                if re.search(r'[A-Za-z]', formattext):
                     formattext = re.sub(r'[a-z]', lambda x: x.group(0).upper(), formattext)
                     formattext = chinese.mix_text_normalize(formattext)
                     return self.get_phones_and_bert(formattext,"zh",version)
                else:

以及

             else:
                 for tmp in LangSegment.getTexts(text):
                     if tmp["lang"] == "en":
                         langlist.append(tmp["lang"])
                     else:
                        # 因无法区别中日韩文汉字,以用户输入为准
                         langlist.append(language)
                     textlist.append(tmp["text"])

这样代码无法处理中英文混合情况,但是可以处理多音字

两者共存不了,有点头疼

@yitenghao yitenghao closed this Nov 20, 2024
@yitenghao yitenghao reopened this Nov 20, 2024
@yitenghao
Copy link
Author

yitenghao commented Nov 20, 2024

现在的版本会把(jue2)视为英文切割出来,导致custom_pinyin函数失效。 需要在GPT-SoVITS/GPT_SoVITS/TTS_infer_pack/TextPreprocessor.py这个文件里把131-135和162-169两部分代码注释掉才可以。分别是

                if re.search(r'[A-Za-z]', formattext):
                     formattext = re.sub(r'[a-z]', lambda x: x.group(0).upper(), formattext)
                     formattext = chinese.mix_text_normalize(formattext)
                     return self.get_phones_and_bert(formattext,"zh",version)
                else:

以及

             else:
                 for tmp in LangSegment.getTexts(text):
                     if tmp["lang"] == "en":
                         langlist.append(tmp["lang"])
                     else:
                        # 因无法区别中日韩文汉字,以用户输入为准
                         langlist.append(language)
                     textlist.append(tmp["text"])

这样代码无法处理中英文混合情况,但是可以处理多音字

在get_phones_and_bert函数下加一行代码
LangSegment.setKeepPinyin(True) #用于保留切分后的中文拼音
image

@hjj-lmx
Copy link

hjj-lmx commented Nov 20, 2024

get_phones_and_bert
大佬,我已经按照[yitenghao]的pr修改了代码,你的这段代码压迫加在哪个地方,是已进入方法就加,还是在哪个地方

@yitenghao
Copy link
Author

get_phones_and_bert
大佬,我已经按照[yitenghao]的pr修改了代码,你的这段代码压迫加在哪个地方,是已进入方法就加,还是在哪个地方

进入函数就加

@yitenghao
Copy link
Author

get_phones_and_bert
大佬,我已经按照[yitenghao]的pr修改了代码,你的这段代码压迫加在哪个地方,是已进入方法就加,还是在哪个地方

还不行就直接看我仓库里面的提交记录,我fork仓库改的代码

@hjj-lmx
Copy link

hjj-lmx commented Nov 21, 2024

get_phones_and_bert
大佬,我已经按照[yitenghao]的pr修改了代码,你的这段代码压迫加在哪个地方,是已进入方法就加,还是在哪个地方

进入函数就加

可以了,谢谢大佬!但这个好像不是所有的都可以改正过来,例如:单(dan1)身,如果我写成单(shan4)身,最后的语音还是单(dan1)身,这个应该是底模的问题吧

你知道这个项目的停顿怎么加吗?就算自定义在某个地方添加停顿,例如:测试[1秒]停顿

@yitenghao
Copy link
Author

get_phones_and_bert
大佬,我已经按照[yitenghao]的pr修改了代码,你的这段代码压迫加在哪个地方,是已进入方法就加,还是在哪个地方

进入函数就加

可以了,谢谢大佬!但这个好像不是所有的都可以改正过来,例如:单(dan1)身,如果我写成单(shan4)身,最后的语音还是单(dan1)身,这个应该是底模的问题吧

你知道这个项目的停顿怎么加吗?就算自定义在某个地方添加停顿,例如:测试[1秒]停顿

作者说加多个句号可以停顿,但是有人说不行,我建议是在要停顿的地方将文本切成两半,中间添加零点几秒的空白音频zero_wav = np.zeros(int(hps.data.sampling_rate * 0.3), dtype=np.float16 if is_half == True else np.float32)

@yitenghao
Copy link
Author

get_phones_and_bert
大佬,我已经按照[yitenghao]的pr修改了代码,你的这段代码压迫加在哪个地方,是已进入方法就加,还是在哪个地方

进入函数就加

可以了,谢谢大佬!但这个好像不是所有的都可以改正过来,例如:单(dan1)身,如果我写成单(shan4)身,最后的语音还是单(dan1)身,这个应该是底模的问题吧

你知道这个项目的停顿怎么加吗?就算自定义在某个地方添加停顿,例如:测试[1秒]停顿

你看下提交记录里的这个地方是不是没注释掉
image
这个是有一个缓存的词与读音的映射缓存,“单身”可能是已经在里面了,拿缓存的话会覆盖自定义的读音

@hjj-lmx
Copy link

hjj-lmx commented Nov 21, 2024

get_phones_and_bert
大佬,我已经按照[yitenghao]的pr修改了代码,你的这段代码压迫加在哪个地方,是已进入方法就加,还是在哪个地方

进入函数就加

可以了,谢谢大佬!但这个好像不是所有的都可以改正过来,例如:单(dan1)身,如果我写成单(shan4)身,最后的语音还是单(dan1)身,这个应该是底模的问题吧
你知道这个项目的停顿怎么加吗?就算自定义在某个地方添加停顿,例如:测试[1秒]停顿

你看下提交记录里的这个地方是不是没注释掉 image 这个是有一个缓存的词与读音的映射缓存,“单身”可能是已经在里面了,拿缓存的话会覆盖自定义的读音

好的,我是没有删除这个地方,我早测试一下

@hjj-lmx
Copy link

hjj-lmx commented Nov 23, 2024

get_phones_and_bert
大佬,我已经按照[yitenghao]的pr修改了代码,你的可疑代码加在哪个地方,是已进入方法就加,还是在哪个地方

进入函数就加

可以了,谢谢大佬!但是这个希望不是所有的都可以改正过来,例如:单(dan1)身,如果我写成单(shan4)身,最后的语音还是单(dan1)身,这个应该是底模的问题吧
你知道这个项目的停顿怎么加吗?甚至可以自定义在某个位置添加停顿,例如:测试[1秒]停顿

作者说加多个句号可以停顿,但是有人说不行,我建议是在要停顿的位置将文本重两半,中间添加零点几秒的空白音频zero_wav = np.zeros(int(hps.data.sampling_rate) * 0.3), dtype=np.float16 如果 is_half == True 否则 np.float32)

没有特殊标记去分,在文本处理的时候“[1秒]”就直接变成了“1秒”,在里面没办法二次分割。我最开始也是像你那样想的,但是代码上没有实现出来。而且源码中本身分段就会停顿0.3,切分后就会多一个0.6出来,这样就很不好算值了

@yitenghao
Copy link
Author

get_phones_and_bert
大佬,我已经按照[yitenghao]的pr修改了代码,你的可疑代码加在哪个地方,是已进入方法就加,还是在哪个地方

进入函数就加

可以了,谢谢大佬!但是这个希望不是所有的都可以改正过来,例如:单(dan1)身,如果我写成单(shan4)身,最后的语音还是单(dan1)身,这个应该是底模的问题吧
你知道这个项目的停顿怎么加吗?甚至可以自定义在某个位置添加停顿,例如:测试[1秒]停顿

作者说加多个句号可以停顿,但是有人说不行,我建议是在要停顿的位置将文本重两半,中间添加零点几秒的空白音频zero_wav = np.zeros(int(hps.data.sampling_rate) * 0.3), dtype=np.float16 如果 is_half == True 否则 np.float32)

没有特殊标记去分,在文本处理的时候“[1秒]”就直接变成了“1秒”,在里面没办法二次分割。我最开始也是像你那样想的,但是代码上没有实现出来。而且源码中本身分段就会停顿0.3,切分后就会多一个0.6出来,这样就很不好算值了

自己加个特殊标记然后改代码解析去解析呗

@yitenghao
Copy link
Author

api_v2已支持多音字

@hjj-lmx
Copy link

hjj-lmx commented Dec 9, 2024

api_v2已支持多音字

和你的写法不一样吗?他改了些什么

@yitenghao
Copy link
Author

api_v2已支持多音字

和你的写法不一样吗?他改了些什么

get_phones_and_bert

有两个get_phones_and_bert函数,api.py和api_v2.py分别用了一个,之前只改了api.py的

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants