Code Monkey home page Code Monkey logo

langsegment's Introduction

LangSegment

简介:它是一个强大的多语言(97种语言)的混合文本自动分词工具。[中/日/英/韩:已测试]
主要用途:“一口气” 让你的 TTS 语音合成项目 VITS 说出多国语言,多语种混合文本的分词推理,和预处理训练。
分词支持:中文/英文/日文/韩语/法语/越南语/俄语/泰语/

image

它基于 py3langid 的扩展实现(>=python3.6)。
LangSegment It is a multi-lingual (97 languages) text content automatic recognition and segmentation tool.
The main purposes are: front-end for various TTS (Text-to-Speech) synthesis projects, preprocessing of multilingual text mixing for both training and inference.

Implementation based on py3langid,See LICENSE file for more info.
https://github.com/adbar/py3langid

功能:将文章或句子里的例如(中/英/日/韩),按不同语言自动识别分词,使文本更适合AI处理。
本代码专为各种 TTS 项目的前端文本多语种混合标注区分,多语言混合训练和推理而编写。

最近更新:News

  • 版本:v0.3.3 fix (更新帮助见下文)。

  • 添加支持: "zh"中文(数字拼音pinyin),保留多音字(音素)指定。

  • 添加支持: "ru"俄语Russian / "th"泰语Thai。

  • 添加支持: "fr"法语French / "vi"越南语Vietnamese。

  • 语言优先级,置信度评分和阀值。

  • 优化字符处理。fix: LangSegment.setfilters

  • 更细致的处理,中日英韩,分词更精准!

  • 多语言过滤组功能(默认:中/英/日/韩)!帮您自动清理不需要的语言内容。

  • 添加 WebUI 可视化界面,运行 app.py 即可快捷体验(如图所示)。

  • 点击在线体验,感谢 huggingface 提供服务支持:

image

# Gradio demo:To use our gradio demo locally:
# 运行脚本,打开浏览器 gradio webui 界面,开始快速体验。(gradio==3.50.2)
python app.py  

完全可控:支持

  • (1)自动分词:“韩语中的오빠读什么呢?あなたの体育の先生は誰ですか? 此次带来了四款iPhone 15系列机型”
  • (2)手动分词:“你的名字叫<ja>佐々木?<ja>吗?”

语言标签:支持

分词语言标签:它和html类似,它需要成对出现 <zh>内容<zh> 或者 <zh>内容</zh>。
本处理结果主要针对(中文=zh , 日文=ja , 英文=en , 韩语=ko), 实际上可支持多达 97 种不同的语言混合处理。

安装方法:Install (推荐使用官方源)

# 首次安装:官方源(推荐)
pip3 install LangSegment -i  https://pypi.org/simple
# 后续版本升级或更新:
pip3 install LangSegment -i  https://pypi.org/simple --upgrade

# 或者,国内镜像(国内镜像同步慢几天,可能会导致您无法极时获得最新版本!!!):  
# pip3 install LangSegment -i https://pypi.mirrors.ustc.edu.cn/simple

使用示例:Example Input

示例中的句子,同时包含中日英韩4种语言,接下来将对它们按不同语种进行分词,以方便各种TTS项目进行语音合成。

    # pip3 install LangSegment -i  https://pypi.org/simple
    import LangSegment

    # input text example 示例:
    text = "你的名字叫<ja>佐々木?<ja>吗?韩语中的오빠读什么呢?あなたの体育の先生は\
    誰ですか? 此次发布会带来了四款iPhone 15系列机型\
    和三款Apple Watch等一系列新品,这次的iPad Air采用了LCD屏幕" 

    # example
    langlist = LangSegment.getTexts(text)

    # output list : {'lang': 'zh', 'text': '...'}
    print("=================================")
    for line in langlist:
        print(line)
    print("=================================")

处理结果:Example Output

    # output 输出列表行:lang=语言,text=内容
    # ===========================================================================
    # {'lang': 'zh', 'text': '你的名字叫'}
    # {'lang': 'ja', 'text': '佐々木?'}
    # {'lang': 'zh', 'text': '吗?韩语中的'}
    # {'lang': 'ko', 'text': '오빠'}
    # {'lang': 'zh', 'text': '读什么呢?'}
    # {'lang': 'ja', 'text': 'あなたの体育の先生は誰ですか?'}
    # {'lang': 'zh', 'text': ' 此次发布会带来了四款'}
    # {'lang': 'en', 'text': 'i Phone'}
    # {'lang': 'zh', 'text': ' 15系列机型和三款'}
    # {'lang': 'en', 'text': 'Apple Watch'}
    # {'lang': 'zh', 'text': '等一系列新品,这次的'}
    # {'lang': 'en', 'text': 'i Pad Air'}
    # {'lang': 'zh', 'text': '采用了'}
    # {'lang': 'en', 'text': 'L C D'}
    # {'lang': 'zh', 'text': '屏幕'}
    # ===========================================================================
    # 其中英文缩写字母如“LCD”,英文标准发音为“L-C-D”,
    # 而在语音合成TTS项目中,一般用空格隔开字母来单独发音:“L C D”

英文拼读:支持

TTS语音合成英文字母大小写拼读规则:
(1需要单个字母发音就大写比如USAUSBChatGPTLCDGPUCEO。
(2其它情况正常拼读就按正常拼写比如NvidiaCuda 或者全小写nvidiacuda

拼音保留:支持(多音字)

版本支持:>= 0.3.2
常见需求:直接修改 TTS 的汉字读音,保留拼音输入。

# 开启汉语拼音保留,(TTS标准:数字拼音格式),默认关闭。  
LangSegment.setKeepPinyin(True)  

# 汉字拼音指定示例:以下句子,括号中的拼音,均识别为中文。
text = "这个字的读音是角(jue2)色,而不是角(jiao3)色"  

分词纠错:很重要!

综上所述,“自动分词”已经极大的提高了我们的工作效率,但还是建议您对分词结果进行人工校对。
特别是中文与日文,存在大量汉字互用,这对自动分词是极具挑战性的,“分词纠错” 解决方案如下:

  • (1)自动分词纠错:在中文与日文句子之间,打上句号。来辅助分词(自动上下文分词)。
  • (2)手动分词纠错:您可手动添加语言标签<ja>,<ko>,<zh>,<en>等来辅助进行强制分词。

以下是语言标签分词详细示例:

    # 手动分词标签的应用示例,例如针对中日汉字有重叠,而需要在 TTS 中混合发音的情况:
    # 分词标签内的文本将识别成日文ja内容,也可以写成<ja>内容</ja>
    text = "你的名字叫<ja>佐々木?<ja>"  
    # 或者:
    text = "你的名字叫<ja>佐々木?</ja>"  
    # 以上均能正确输出:
    # 处理成中文-- {'lang': 'zh', 'text': '你的名字叫'}
    # 处理成日文-- {'lang': 'ja', 'text': '佐々木?'}

自动分词能力目前主要针对中文(zh)/日文(ja)/英文(en)/韩文(ko),进行了特别优化。
它特别适合各种 TTS 前端文本多语种内容的混合分词(自动/手动),训练和推理使用。

    # 手动分词标签规范:<语言标签>文本内容</语言标签>
    # ===========================================================================
    # 如需手动标注,标签需要成对出现,如:“<ja>佐々木<ja>”  或者  “<ja>佐々木</ja>”
    # 错误示范:“你的名字叫<ja>佐々木。” 此句子中出现的单个<ja>标签将被忽略,不会处理。
    # ===========================================================================

语言过滤:支持

版本支持:>=0.2.0
语言过滤组功能, 可以指定保留语言。不在过滤组中的语言将被清除。您可随心搭配TTS语音合成所支持的语言。

# Set language filters
# 设置语言过滤功能,未指定的语言将被清除,使它完全适配您的TTS项目。
LangSegment.setfilters(["zh", "en", "ja", "ko"]) # 标准写法
# 或者写成:
# LangSegment.setfilters(["zh_en_ja_ko"]) # 写法1,过滤效果相同
# LangSegment.setfilters(["zh-en-ja-ko"]) # 写法2,过滤效果相同
# 获取过滤器:
# LangSegment.getfilters()

# 参数组合说明,以下是部份场景示例:
# ["zh"]        # 按中文识别
# ["en"]        # 按英文识别
# ["ja"]        # 按日文识别
# ["ko"]        # 按韩文识别
# ["zh_ja"]     # 中日混合识别
# ["zh_en"]     # 中英混合识别
# ["zh_ko"]     # 中韩混合识别
# ["ja_en"]     # 日英混合识别
# ["zh_ko_en"]  # 中韩英混合识别
# 以上是示例,您可根据自己的TTS项目进行自由组合。

语言优先级:支持(纯数字输入示例)

版本支持:>=0.2.1
当我们在鉴别纯数字时,比如“123456”,全球通用。如果没有提供上下文,将无法区分归属(默认en)。
这时候,您只需调整语言优先级。就能准确识别。相关示例如下:

# 仅输入独立纯数字:所有国家通用,因为没有提供上下文,所以无法区分语言归属
print(LangSegment.getTexts("123456789")) # 国际纯数字,默认输出:英文=en

# 调整过滤语言优先级,中文优先,数字按中文优先识别
LangSegment.setfilters(["zh","ja"])
print(LangSegment.getTexts("123456789")) # 识别输出:中文=zh

# 调整过滤语言优先级,日语优先,数字按日语优先识别
LangSegment.setfilters(["ja","zh"])
print(LangSegment.getTexts("123456789")) # 识别输出:日文=ja

# 调整过滤语言优先级,韩语优先,数字按韩语优先识别
LangSegment.setfilters(["ko","zh"])
print(LangSegment.getTexts("123456789")) # 识别输出:韩文=ko  

# 识别输出:中文,(因为提供了上下文,汉字“编号:”)
LangSegment.setfilters(["ko","zh","en","ja"])
print(LangSegment.getTexts("编号:123456789"))  # 提供上下文,识别输出:中文=zh  
print(LangSegment.getTexts("Number:123456789"))  # 提供上下文,识别输出:英文=en  
print(LangSegment.getTexts("번호:123456789"))  # 提供上下文,识别输出:韩文=ko  

优先级与置信度:特殊示例

版本支持:>=0.2.1
语言优先级除了对输入的纯数字外,它对中文与日文也特别有用,以下是使用示例:

  • 示例汉字词:“番号”,由于在中文和日语,两者使用几乎完全一样,在中日混合模式下。
# 在中日混合下,默认情况为中文优先。
LangSegment.setfilters(["zh","ja","en","ko"])
# 默认处理:
print(LangSegment.getTexts("番号: 123456789"))  
# [{'lang': 'zh', 'text': '番号: 123456789 ', 'score': 0.87188566}]
# 默认识别:中文=zh ,识别的参考置信度是:0.87
  • 而此时,在中日混合模式下,我们希望它识别成:日语=ja。
# 只需按如下调整过滤器的语言优先级。让 ja 优先于 zh 之前。
LangSegment.setfilters(["ja","zh","en","ko"])
# 再次处理:
print(LangSegment.getTexts("番号: 123456789"))  
# [{'lang': 'ja', 'text': '番号: 123456789 ', 'score': 0.87188566}]
# 阀值的精准控制下,它被优先识别为我们希望的结果:日文=ja  

# 您还可以添加语言标签:精准控制
print(LangSegment.getTexts("<ja>番号: 123456789</ja>")) 
# 添加语言标签,正确输出:日文=ja

预览新增:法语(French)/越南语(Vietnamese)/俄语(Russian)/泰语(Thai)

版本支持:>=0.2.2 (法语(French)/越南语(Vietnamese))
版本支持:>=0.2.3 (俄语(Russian)/泰语(Thai))
法语和越南语,您只需在语言过滤器中添加,即可配合分词标签使用。

# 自动分词启用设置:法语="fr" , 越南语="vi", "ru"俄语=Russian, "th"泰语=Thai
LangSegment.setfilters(["fr", "vi" , "zh", "ja", "ko", "en"])

# 可以随意搭配,比如您的TTS只需(越南语/中文),则仅需保留两个语言。
# LangSegment.setfilters(["vi" , "zh"])

# 对应的(法语fr和越南语vi)手动分词语言标签:
# <fr>Français</fr>、<vi>Tiếng Việt</vi>

每个语种它们对应的语言分词标签: (ISO 639-1 codes given):

  • <zh>:中文 = Chinese
  • <en>:英语 = English
  • <ja>:日语 = Japanese
  • <ko>:韩语 = Korean
  • <fr>:法语 = French
  • <vi>:越南语 = Vietnamese
  • <ru>:俄语 = Russian
  • <th>:泰语 = Thai
  • 更多其它97个语种标签,在下方完整列表已经列出。

总结说明:

它经过了高达 97 种语言的预训练,相信它绝对能满足您的 TTS 语音合成项目所需。
comes pre-trained on 97 languages (ISO 639-1 codes given):

af, am, an, ar, as, az, be, bg, bn, br, bs, ca, cs, cy, da, de, dz, el, en, eo, es, et, eu, fa, fi, fo, fr, ga, gl, gu, he, hi, hr, ht, hu, hy, id, is, it, ja, jv, ka, kk, km, kn, ko, ku, ky, la, lb, lo, lt, lv, mg, mk, ml, mn, mr, ms, mt, nb, ne, nl, nn, no, oc, or, pa, pl, ps, pt, qu, ro, ru, rw, se, si, sk, sl, sq, sr, sv, sw, ta, te, th, tl, tr, ug, uk, ur, vi, vo, wa, xh, zh, zu



备注:多语种混合文本转语音合成(TTS),中/日/英/韩/已完成测试。
其它语种未作具体测试,如有Bug和优化建议,欢迎提出或指正,感谢~。
Note: The speech synthesis test content is currently mainly for four categories: Chinese, Japanese, English and Korean.
Other languages have not been specifically tested. If there are any bugs or optimization suggestions, please feel free to raise them or correct them. Thank you~
Special thanks to the following projects: py3langid



langsegment's People

Contributors

juntaosun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

langsegment's Issues

TypeError: list indices must be integers or slices, not str

Traceback (most recent call last):
  File "e:\AItools\GPT-SoVITS-Inference\runtime\lib\site-packages\werkzeug\serving.py", line 362, in run_wsgi
    execute(self.server.app)
  File "e:\AItools\GPT-SoVITS-Inference\runtime\lib\site-packages\werkzeug\serving.py", line 325, in execute
    for data in application_iter:
  File "e:\AItools\GPT-SoVITS-Inference\runtime\lib\site-packages\werkzeug\wsgi.py", line 256, in __next__
    return self._next()
  File "e:\AItools\GPT-SoVITS-Inference\runtime\lib\site-packages\werkzeug\wrappers\response.py", line 32, in _iter_encoded
    for item in iterable:
  File "e:\AItools\GPT-SoVITS-Inference\runtime\lib\site-packages\flask\helpers.py", line 113, in generator
    yield from gen
  File "E:\AItools\GPT-SoVITS-Inference\Inference\src\inference_core.py", line 140, in get_streaming_tts_wav
    for sr, chunk in chunks:
  File "E:\AItools\GPT-SoVITS-Inference\Inference\src\inference_core.py", line 112, in inference
    yield next(tts_pipline.run(inputs))
  File "E:\AItools\GPT-SoVITS-Inference\GPT_SoVITS\TTS_infer_pack\TTS.py", line 531, in run
    data = self.text_preprocessor.preprocess(text, text_lang, text_split_method)
  File "E:\AItools\GPT-SoVITS-Inference\GPT_SoVITS\TTS_infer_pack\TextPreprocessor.py", line 53, in preprocess
    phones, bert_features, norm_text = self.segment_and_extract_feature_for_text(text, lang)
  File "E:\AItools\GPT-SoVITS-Inference\GPT_SoVITS\TTS_infer_pack\TextPreprocessor.py", line 87, in segment_and_extract_feature_for_text
    textlist, langlist = self.seg_text(texts, language)
  File "E:\AItools\GPT-SoVITS-Inference\GPT_SoVITS\TTS_infer_pack\TextPreprocessor.py", line 99, in seg_text
    for tmp in LangSegment.getTexts(text):
  File "e:\AItools\GPT-SoVITS-Inference\runtime\lib\site-packages\LangSegment\LangSegment.py", line 676, in getTexts
    return LangSegment.getTexts(text)
  File "e:\AItools\GPT-SoVITS-Inference\runtime\lib\site-packages\LangSegment\LangSegment.py", line 572, in getTexts
    text = LangSegment._parse_symbols(text)
  File "e:\AItools\GPT-SoVITS-Inference\runtime\lib\site-packages\LangSegment\LangSegment.py", line 508, in _parse_symbols
    cur_word = LangSegment._process_tags([] , text , True)
  File "e:\AItools\GPT-SoVITS-Inference\runtime\lib\site-packages\LangSegment\LangSegment.py", line 461, in _process_tags
    LangSegment._parse_language(words , text)
  File "e:\AItools\GPT-SoVITS-Inference\runtime\lib\site-packages\LangSegment\LangSegment.py", line 330, in _parse_language
    LangSegment._addwords(words,language,text,score)
  File "e:\AItools\GPT-SoVITS-Inference\runtime\lib\site-packages\LangSegment\LangSegment.py", line 250, in _addwords
    else:LangSegment._saveData(words,language,text,score)
  File "e:\AItools\GPT-SoVITS-Inference\runtime\lib\site-packages\LangSegment\LangSegment.py", line 212, in _saveData
    LangSegment._statistics(preData["lang"],text)
  File "e:\AItools\GPT-SoVITS-Inference\runtime\lib\site-packages\LangSegment\LangSegment.py", line 191, in _statistics
    if not "|" in language:lang_count[language] += int(len(text)*2) if language == "zh" else len(text)
TypeError: list indices must be integers or slices, not str

LangSegment.py 第186行
有的时候会报错如上

增加了一些鲁棒性检测后不会报错了:

修正后代码

@staticmethod
def _statistics(language, text):
    if LangSegment._lang_count is None or not isinstance(LangSegment._lang_count, defaultdict):
        LangSegment._lang_count = defaultdict(int)
    lang_count = LangSegment._lang_count
    if not "|" in language:
        lang_count[language] += int(len(text)*2) if language == "zh" else len(text)
    LangSegment._lang_count = lang_count

处理中文会丢字

输入:
每题0.5分,共10分,第二部分

输出:
每题0.5第二部分

丢失了"分共10分"这几个字。我尝试了把分改为别的字,比如“元”,不会发生丢字

希望获得联系方式

你好 juntaosun,我是一个产品经理,我的newsletter在这里:https://produck.zhubai.love/

希望与你取得联系讨论一个音视频项目的实现,望不吝赐教。

我的联系方式:de_base64("d2VjaGF0OiBtYWRsaWZlcjEzMzcgLyBtYWlsOiBtYWRsaWZlckBsaXZlLmNvbQ==”)

语言过滤模块逻辑

text = "English中文"
LangSegment.setLangfilters(["en"])
print(LangSegment.getTexts(text))
LangSegment.setLangfilters(["zh"])
print(LangSegment.getTexts(text))

运行结果

[{'lang': 'en', 'text': 'English '}]
[{'lang': 'en', 'text': 'English '}]

識別錯誤

使用完整的ALL模型去做識別
日本 chatgpt 萬 chatgpt
{'lang': 'ja', 'text': '日本', 'score': 0.72695434}
{'lang': 'en', 'text': 'chatgpt ', 'score': 0.75385803}
{'lang': 'ja', 'text': '萬 ', 'score': 0.84992695}
{'lang': 'en', 'text': 'chatgpt ', 'score': 0.75385803}

日本、日本語、數字(一~十、百、千、萬等等)
日本、日本語 ->單獨打會出錯
單獨一個數字 ->前後包夾一個英文字會出錯(若換成使用中英日模型怎不會出錯)

[Bug] list indices must be integers or slices, not str

错误日志

File "c:\Users\14404\Project\GPT-SoVITS-beta0306fix2\runtime\lib\site-packages\LangSegment\LangSegment.py", line 676, in getTexts
return LangSegment.getTexts(text)
File "c:\Users\14404\Project\GPT-SoVITS-beta0306fix2\runtime\lib\site-packages\LangSegment\LangSegment.py", line 572, in getTexts
text = LangSegment._parse_symbols(text)
File "c:\Users\14404\Project\GPT-SoVITS-beta0306fix2\runtime\lib\site-packages\LangSegment\LangSegment.py", line 508, in _parse_symbols
cur_word = LangSegment._process_tags([] , text , True)
File "c:\Users\14404\Project\GPT-SoVITS-beta0306fix2\runtime\lib\site-packages\LangSegment\LangSegment.py", line 461, in _process_tags
LangSegment._parse_language(words , text)
File "c:\Users\14404\Project\GPT-SoVITS-beta0306fix2\runtime\lib\site-packages\LangSegment\LangSegment.py", line 330, in _parse_language
LangSegment._addwords(words,language,text,score)
File "c:\Users\14404\Project\GPT-SoVITS-beta0306fix2\runtime\lib\site-packages\LangSegment\LangSegment.py", line 250, in _addwords
else:LangSegment._saveData(words,language,text,score)
File "c:\Users\14404\Project\GPT-SoVITS-beta0306fix2\runtime\lib\site-packages\LangSegment\LangSegment.py", line 228, in _saveData
LangSegment._statistics(data["lang"],data["text"])
File "c:\Users\14404\Project\GPT-SoVITS-beta0306fix2\runtime\lib\site-packages\LangSegment\LangSegment.py", line 191, in _statistics
if not "|" in language:lang_count[language] += int(len(text)*2) if language == "zh" else len(text)
TypeError: list indices must be integers or slices, not str

一个神奇的bug

image
只要遇到”加分!加分!“两个连续就会出现空的结果,导致报错。而单独的”加分!“却不会导致结果报错。
image
image
所以大家在使用的时候,如果出现报空的情况下,还是得多加一层判断,保证正确执行。

数字部分分类逻辑

textlist = ["【齐鲁艺票通】恭喜您购票成功!","订单编号:","669775550013131,","取票码:","93342253;","请凭取票码在演出开始前30分钟到指定地点换取纸质票。"]
for text in textlist:
    print(LangSegment.getTexts(text))
# [{'lang': 'zh', 'text': '【齐鲁艺票通】恭喜您购票成功!'}]
# [{'lang': 'zh', 'text': '订单编号:'}]
# [{'lang': 'en', 'text': '669775550013131, '}]
# [{'lang': 'zh', 'text': '取票码:'}]
# [{'lang': 'en', 'text': '93342253; '}]
# [{'lang': 'zh', 'text': '请凭取票码在演出开始前30分钟到指定地点换取纸质票。'}]

大佬。整句输入判定正常,当用户选择按标点符号切割时,纯数字会被识别为英文,能否改成参照上文的逻辑处理?

语言判断错误

输入:
那我们拆分来看一下:Part A(传统阅读理解)

Part A被识别成了日文

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.