1.sparrowhawk
谷歌内部基于WFST的TTS-TN系统Kestrel的开源版本 sparrowhawk,可以支持数字,日期,时间,货币,邮箱等多种文本类型的书面语文本转口语文本
2.sparrowhawk基本工作过程
主要包括两个模块
- The tokenizer/classifier
- The verbalizer
2.1.tokenizer / classify模块
2.1.1.输入的句子首先根据空格或自定义字符分割成一个个的token,再根据classifier进行分类为下列几类(分类规则由thrax语法文件确定 grammars/en_toy/classify/xxx.grm)
- 普通单词token(不需要进行处理的):
- 普通单词不进行任何处理
- eg. “apple”、“yes” → “apple” 、“yes”
- 标点符号token(Punctuation):
- sparrowhawk 源码中默认转换成 “sil”(silence,即不发音) 源码 line 157
- eg. “,” 、"?" → sil 、sil
- 需要进行TN处理的token(semiotic classes) sparrowhawk源码中类型定义
- 自定义的类型,处理成对应的proto格式(见2.1.2)
- Cardinal 整数 1,2,3
- Ordinal 序数 1st,2nd
- Fraction 分数 1/3,2/5
- Time 时间 12:30
- Decimal 十进制数 10.21 ,-11.11 ,12k
- Measure 度量单位 10cm,10kg,100%
- Date 日期 3 Jan. 1980
- Money 货币 $10
- Telephone 电话号码
- Electronic URL地址
- Connector 连接符 1:1,4x3
- Abbreviation 缩写词 U.S
- 自定义的类型,处理成对应的proto格式(见2.1.2)
- 未知或者处理失败的token
- 在verbalize中的verbatim.grm二次处理
2.1.2.token经过classify分类之后,处理成不同的proto格式 ,根据编写的语法而定 classify_example (其中的 .grm文件为thrax语法规则,.far文件为编译后的FST Arachive文件)
- eg. 货币格式 $200 ----→ tokens { money { currency: “usd” amount { integer_part: “200”} } }
- eg. 度量格式 66.66% ----→ tokens { measure { decimal { integer_part: “66” fractional_part: “66”} units: “percent”} }
- eg. 数字格式 12 ----→ tokens { cardinal { integer: “12” } }
- sentence eg. He is 180cm tall
- → tokens { name: “He” } tokens { name: “is” } tokens { measure { decimal { integer_part: “180”} units: “centimeter”} } tokens { name: “tall” }
2.1.3. demo 编译 及 测试
/sparrowhawk/documentation/grammars/en_toy/classify 文件夹下
$thraxmakedep cardinal.grm
$make
编译完成
测试
thraxrewrite-tester --far=cardinal.far --rules=CARDINAL
$Input string: 13
$Output string: cardinal { integer: “13” }
2.2.Verbalizer
/sparrowhawk/documentation/grammars/en_toy/verbalize 文件夹下
解析classify处理之后的token,根据相应格式处理,具体规则在 .grm中
2.2.1.根据token的格式来进行不同的处理
- eg. cardinal { integer: “13” } ----→ thirteen
- eg. measure { decimal { integer_part: “100”} units: “kilogram”} ----→ one hundred kilograms
$thraxmakedep measure.grm
$make
$thraxrewrite-tester --far=measure.far --rules=MEASURE
Input string: measure { decimal { integer_part: “100”} units: “kilogram”}
Output string: one hundred kilograms
Peter Ebden and Richard Sproat. 2014. “The Kestrel TTS Text Normalization System.” Journal of Natural Language Engineering.
2.3. Sparrowhawk使用流程
2.3.1编译
主要代码
//引入头文件
#include <sparrowhawk/normalizer.h>
//指定thrax语法库
string grammar_dir = “grammars/”;
//初始化
speech::sparrowhawk::Normalizer normalizer;
//设置配置文件
normalizer.Setup(“sparrowhawk_configuration.ascii_proto”, grammar_dir);
//主程序入口 string in,out
normalizer.Normalize(in, &out);
编译指令
- 见/data/zhuqing2/project/sparrowhawk/compile_textnormalizer.sh
- eg.
- g++ -std=c++11 -I /home/zhuqing2/anaconda2/include -L /home/zhuqing2/anaconda2/lib -lsparrowhawk -lfst -lfstfar -lthrax -lprotobuf -pthread -ldl -lre2 -g -o text_normalizer main.cpp
- 运行 ./text_normlizer <input_file> <output_file>
3.thrax
The OpenGrm Thrax Grammar Compiler is a set of tools for compiling grammars expressed as regular expressions and context-dependent rewrite rules into weighted finite-state transducers using the OpenFst format.
完整参考 官方文档
例子参考 安装thrax文件夹中 grammars/example.grm
3.1.语法规则
-
import :
- 导入文件
- import ‘./example.grm’ as e;
- 导入其他grammar文件,导入后,主文件中就可以使用别名来引用函数和符号
-
func :
- 定义一个函数
- eg. func <func_name> [ ]{return <reuturn_fst>}
-
export :
-
生成fst,写入到 .far文件中后,才能被调用
-
eg**.**
foo = “abc”;
export bar = foo | “xyz”;
-
-
StringFile :
- 加载字符串或者字符串二元组列表,将其中字符编译成表示这些字符的并集的fst
- 相当于 (“string1 | string2 | string3 | …”)
- StringFile[‘strings_file’, ‘byte’, my_symbols]
-
CDRewrite :
- 用于在给定的上下文字符串中重写某些词
- CDRewrite [“s”:“z”,"",“d [EOS]”] ,把字符串末尾的 “d” 前改 “s” 为 “z”
-
Closure
- 正则中的
- * 匹配0-N个
- + 匹配1-N个
- ? 匹配0-1个
- {a,b} 匹配 a-b个
- eg “xyz”*
-
Concatenation
- 将多个字符拼接 以空格连接
- eg. “a” “b” 即为(“ab”)
-
Difference
- eg. fst1 - fst2
- 匹配第一个fst且不匹配第二个fst
-
Composition
- eg. fst1 @ fst2
- 将两个fst拼接,即fst1的输出作为fst2的输入
-
Union
- foo | bar
- 接受两个中任一个fst,即 或
-
Rewrite
- foo : bar
- 替换,即将 foo 替换为 bar
-
Weight
- fst
- 指定权重
-
ArcSort
-
- ArcSort[fst, ‘input’|‘output’]
- 对一个FST的所有状态的所有弧根据弧的输入或输出进行排序
-
Connect
- 使得FST变得全连接图,移除不可达的状态和路径
-
CDRewrite
- 给定一个转换器、2个上下文接收器(以及字母表机),会生成一个在给定上下文中任意位置进行重写的新FST。
- CDRewrite[“s” : “z”, “”, “d[EOS]”, sigma_star]
- “s” : “z” : 将"s" 替换为 “z”
- “” : 左上下文为任意字符匹配
- “d[EOS]” : 右上下文为以"d"结尾
- sigma_star : 函数是不带权接收器
-
Determinize
-
- Determinize[fst]
- 确定化一个fst
-
RmEpsilon
- RmEpsilon[fst]
- 将给定fst中的所有epsilon (label 0 )移除
-
Expand
-
- Expand[fst]
- 显式地将fst展开为VectorFst
-
Invert
-
- Invert[fst]
- 将给定fst倒置
-
Minimize
- Minimize[fst]
- 最小化fst
-
Optimize
- Optimize[fst]
- 优化 fst ,一般跟export一同使用 export fst_out = Optimize[fst];
-
AssertEqual
- AssertEqual[“dog” @ pluralize, “dogs” ]
- 判断两个fst是否相同
4.Google TN开源数据
数据来源:Google采用其内部的TTS系统处理维基百科数据得到的数据
数据描述:token级别的数据,每一行包括
<token的类别(如符号型,数字型,日期型,普通单词等等)>,<原始token>,<标准化后的token>
各类别数据示例:
类别 | 原始token | 标准化后token | 备注 |
---|---|---|---|
PLAIN | file | 普通字符类 | |
PUNCT | , | sil | 标点符号类,sil表沉默(silence)不发音 |
DATE | December 29, 2012 | december twenty ninth twenty twelve | 日期类,日、月、年 |
LETTERS | Ukh | u k h | 字母类,转换成逐个字母的发音 |
CARDINAL | 3 | three | 整数类 |
VERBATIM | & | and | 特殊字符类 |
MEASURE | 100 km/h | one hundred kilometers per hour | 度量类 |
ORDINAL | 40th | fortieth | 序数类 |
DECIMAL | 6.395 | six point three nine five | 十进制类 |
MONEY | $13,959 | thirteen thousand nine hundred fifty nine dollars | 货币类 |
ELECTRONIC | About.com | a_letter b_letter o_letter u_letter t_letter dot c_letter o_letter m_letter | URL类 |
DIGIT | 2011 | two o one one | 单个数字类,转换成逐个数字发音 |
TELEPHONE | 1-58705-008-0 | one sil five eight seven o five sil o o eight sil | 电话号码类 |
TIME | 7:15 AM | seven fifteen a m | 时间类 |
FRACTION | 1/5 | one fifth | 分数类 |
ADDRESS | A728 | a seven two eight | 地址类 |
共分为100个文件,每个文件包括1100w个token的数据。共11亿行。
[RNN Approaches to Text Normalization: A Challenge](