Phonetisaurus  1.0
FST-based Grapheme-to-Phoneme conversion
phonetisaurus-g2prnn.cc
Go to the documentation of this file.
1 #include <fst/fstlib.h>
5 #include <include/RnnLMDecoder.h>
6 #include <include/util.h>
7 #include "utf8.h"
8 #ifdef _GNUC_
9 #include <omp.h>
10 #endif
11 using namespace fst;
12 
14 typedef unordered_map<int, SimpleResult> RMAP;
15 
16 
17 void ThreadedEvaluateWordlist (vector<string>& corpus, RMAP& rmap,
18  LegacyRnnLMHash& h, Decodable& s,
19  int FLAGS_threads, int FLAGS_beam,
20  int FLAGS_kmax, int FLAGS_nbest,
21  bool FLAGS_reverse, string FLAGS_gpdelim,
22  string FLAGS_gdelim, string FLAGS_skip,
23  double FLAGS_thresh, string FLAGS_gsep) {
24  int csize = corpus.size ();
25 
26 #pragma omp parallel for
27  for (int x = 0; x < FLAGS_threads; x++) {
28  RnnLMDecoder<Decodable> decoder (s);
29 
30  int start = x * (csize / FLAGS_threads);
31  int end = (x == FLAGS_threads - 1) ? csize \
32  : start + (csize / FLAGS_threads);
33  for (int i = start; i < end; i++) {
34  vector<string> graphemes = tokenize_utf8_string (&corpus [i],
35  &FLAGS_gsep);
36  if (FLAGS_reverse == true)
37  reverse (graphemes.begin (), graphemes.end ());
38 
39  graphemes.push_back ("</s>");
40  SimpleResult result = \
41  decoder.Decode (graphemes, FLAGS_beam, FLAGS_kmax,
42  FLAGS_nbest, FLAGS_thresh, FLAGS_gpdelim,
43  FLAGS_gdelim, FLAGS_skip);
44  rmap [i] = result;
45  }
46  }
47 
48  for (int i = 0; i < csize; i++) {
49  const SimpleResult& result = rmap [i];
50 
51  for (int k = 0; k < result.pronunciations.size (); k++)
52  cout << result.word << "\t" << result.scores [k] << "\t"
53  << result.pronunciations [k] << "\n";
54  }
55 }
56 
57 void EvaluateWordlist (vector<string>& corpus,
58  LegacyRnnLMHash& h, Decodable& s, int FLAGS_beam,
59  int FLAGS_kmax, int FLAGS_nbest, bool FLAGS_reverse,
60  string FLAGS_gpdelim, string FLAGS_gdelim,
61  string FLAGS_skip, double FLAGS_thresh,
62  string FLAGS_gsep) {
63 
64  RnnLMDecoder<Decodable> decoder (s);
65  for (int i = 0; i < corpus.size (); i++) {
66  vector<string> graphemes = tokenize_utf8_string (&corpus [i],
67  &FLAGS_gsep);
68  if (FLAGS_reverse == true)
69  reverse (graphemes.begin (), graphemes.end ());
70 
71  graphemes.push_back ("</s>");
72 
73  SimpleResult result = \
74  decoder.Decode (graphemes, FLAGS_beam, FLAGS_kmax,
75  FLAGS_nbest, FLAGS_thresh, FLAGS_gpdelim,
76  FLAGS_gdelim, FLAGS_skip);
77 
78  for (int k = 0; k < result.pronunciations.size (); k++)
79  cout << result.word << "\t" << result.scores [k] << "\t"
80  << result.pronunciations [k] << "\n";
81  }
82 }
83 
84 void EvaluateWord (string word, LegacyRnnLMHash& h, Decodable& s,
85  int FLAGS_beam, int FLAGS_kmax, int FLAGS_nbest,
86  bool FLAGS_reverse, string FLAGS_gpdelim,
87  string FLAGS_gdelim, string FLAGS_skip,
88  double FLAGS_thresh, string FLAGS_gsep) {
89 
90  vector<string> graphemes = tokenize_utf8_string (&word,
91  &FLAGS_gsep);
92  if (FLAGS_reverse == true)
93  reverse (graphemes.begin (), graphemes.end ());
94  graphemes.push_back ("</s>");
95 
96  RnnLMDecoder<Decodable> decoder (s);
97  SimpleResult result = \
98  decoder.Decode (graphemes, FLAGS_beam, FLAGS_kmax,
99  FLAGS_nbest, FLAGS_thresh, FLAGS_gpdelim,
100  FLAGS_gdelim, FLAGS_skip);
101 
102  for (int k = 0; k < result.pronunciations.size (); k++)
103  cout << result.word << "\t" << result.scores [k] << "\t"
104  << result.pronunciations [k] << "\n";
105 }
106 
107 DEFINE_string (rnnlm, "", "The input RnnLM model.");
108 DEFINE_string (wordlist, "", "Input word list to evaluate.");
109 DEFINE_string (word, "", "Single input word to evaluate.");
110 DEFINE_string (gdelim, "|", "The default multigram delimiter.");
111 DEFINE_string (gpdelim, "}", "The default grapheme / phoneme delimiter.");
112 DEFINE_string (gsep, "", "The default grapheme delimiter for testing. Typically ''.");
113 DEFINE_string (skip, "_", "The default null/skip token.");
114 DEFINE_int32 (nbest, 1, "Maximum number of hypotheses to return.");
115 DEFINE_int32 (threads, 1, "Number of parallel threads (OpenMP).");
116 DEFINE_int32 (kmax, 20, "State-local maximum queue size.");
117 DEFINE_int32 (beam, 20, "The state-local beam width.");
118 DEFINE_double (thresh, 0.0, "The n-best pruning threshold. Relative to 1-best.");
119 DEFINE_bool (reverse, false, "Reverse the input word before decoding.");
120 
121 int main (int argc, char* argv []) {
122  string usage = "phonetisaurus-g2prnn --rnnlm=test.rnnlm "\
123  "--wordlist=test.words --nbest=5\n\n Usage: ";
124  set_new_handler (FailedNewHandler);
125  PhonetisaurusSetFlags (usage.c_str (), &argc, &argv, false);
126 
127  if (FLAGS_rnnlm.compare ("") == 0) {
128  cout << "--rnnlm model is required!" << endl;
129  exit (1);
130  } else {
131  std::ifstream rnnlm_ifp (FLAGS_rnnlm);
132  if (!rnnlm_ifp.good ()) {
133  cout << "Faile to open --rnnlm file '"
134  << FLAGS_rnnlm << "'" << endl;
135  exit (1);
136  }
137  }
138 
139  bool use_wordlist = false;
140  if (FLAGS_wordlist.compare ("") != 0) {
141  std::ifstream wordlist_ifp (FLAGS_wordlist);
142  if (!wordlist_ifp.good ()) {
143  cout << "Failed to open --wordlist file '"
144  << FLAGS_wordlist << "'" << endl;
145  exit (1);
146  } else {
147  use_wordlist = true;
148  }
149  }
150 
151  if (FLAGS_wordlist.compare ("") == 0 && FLAGS_word.compare ("") == 0) {
152  cout << "Either --wordlist or --word must be set!" << endl;
153  }
154 
155 #ifndef __GNUC__
156  omp_set_num_threads (FLAGS_threads);
157 #endif
158  vector<string> corpus;
159 
160  LoadWordList (FLAGS_wordlist, &corpus);
161 
162  RMAP rmap;
163 
165  LegacyRnnLMHash h = reader.CopyVocabHash (FLAGS_gdelim, FLAGS_gpdelim);
166  Decodable s = reader.CopyLegacyRnnLM (h);
167 
168  if (use_wordlist == true) {
169  if (FLAGS_threads > 1) {
170  ThreadedEvaluateWordlist (corpus, rmap, h, s, FLAGS_threads,
171  FLAGS_beam, FLAGS_kmax, FLAGS_nbest,
172  FLAGS_reverse, FLAGS_gpdelim,
173  FLAGS_gdelim, FLAGS_skip,
174  FLAGS_thresh, FLAGS_gsep);
175  } else {
176  EvaluateWordlist (corpus, h, s, FLAGS_beam,
177  FLAGS_kmax, FLAGS_nbest, FLAGS_reverse,
178  FLAGS_gpdelim, FLAGS_gdelim, FLAGS_skip,
179  FLAGS_thresh, FLAGS_gsep);
180  }
181  } else {
182  EvaluateWord (FLAGS_word, h, s, FLAGS_beam, FLAGS_kmax,
183  FLAGS_nbest, FLAGS_reverse, FLAGS_gpdelim,
184  FLAGS_gdelim, FLAGS_skip, FLAGS_thresh, FLAGS_gsep);
185  }
186 
187  return 0;
188 }
DEFINE_int32(nbest, 1,"Maximum number of hypotheses to return.")
DEFINE_string(rnnlm,"","The input RnnLM model.")
void ThreadedEvaluateWordlist(vector< string > &corpus, RMAP &rmap, LegacyRnnLMHash &h, Decodable &s, int FLAGS_threads, int FLAGS_beam, int FLAGS_kmax, int FLAGS_nbest, bool FLAGS_reverse, string FLAGS_gpdelim, string FLAGS_gdelim, string FLAGS_skip, double FLAGS_thresh, string FLAGS_gsep)
unordered_map< int, SimpleResult > RMAP
void PhonetisaurusSetFlags(const char *usage, int *argc, char ***argv, bool remove_flags)
Definition: util.cc:158
void EvaluateWordlist(vector< string > &corpus, LegacyRnnLMHash &h, Decodable &s, int FLAGS_beam, int FLAGS_kmax, int FLAGS_nbest, bool FLAGS_reverse, string FLAGS_gpdelim, string FLAGS_gdelim, string FLAGS_skip, double FLAGS_thresh, string FLAGS_gsep)
void EvaluateWord(string word, LegacyRnnLMHash &h, Decodable &s, int FLAGS_beam, int FLAGS_kmax, int FLAGS_nbest, bool FLAGS_reverse, string FLAGS_gpdelim, string FLAGS_gdelim, string FLAGS_skip, double FLAGS_thresh, string FLAGS_gsep)
unordered_map< int, vector< PathData > > RMAP
DEFINE_double(thresh, 0.0,"The n-best pruning threshold. Relative to 1-best.")
void LoadWordList(const std::string &filename, std::vector< std::string > *corpus)
Definition: util.cc:250
LegacyRnnLMDecodable< Token, LegacyRnnLMHash > Decodable
int main(int argc, char *argv[])
vector< double > scores
Definition: RnnLMDecoder.h:132
vector< string > tokenize_utf8_string(string *utf8_string, string *delimiter)
Definition: util.cc:50
Decodable CopyLegacyRnnLM(Hasher &h, int max_order=5)
Hasher CopyVocabHash(const string g_delim, const string gp_delim)
DEFINE_bool(reverse, false,"Reverse the input word before decoding.")
vector< string > pronunciations
Definition: RnnLMDecoder.h:133