Phonetisaurus  1.0
FST-based Grapheme-to-Phoneme conversion
phonetisaurus-g2pfst.cc
Go to the documentation of this file.
1 /*
2  phonetisaurus-g2pfst.cc
3 
4  Copyright (c) [2012-], Josef Robert Novak
5  All rights reserved.
6 
7  Redistribution and use in source and binary forms, with or without
8  modification, are permitted #provided that the following conditions
9  are met:
10 
11  * Redistributions of source code must retain the above copyright
12  notice, this list of conditions and the following disclaimer.
13  * Redistributions in binary form must reproduce the above
14  copyright notice, this list of #conditions and the following
15  disclaimer in the documentation and/or other materials provided
16  with the distribution.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29  OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 */
32 #include <fst/fstlib.h>
34 #include <include/util.h>
35 #ifdef _GNUC_
36 #include <omp.h>
37 #endif
38 using namespace fst;
39 
40 typedef unordered_map<int, vector<PathData> > RMAP;
41 
42 void PrintPathData (const vector<PathData>& results, string FLAGS_word,
43  const SymbolTable* osyms) {
44  for (int i = 0; i < results.size (); i++) {
45  cout << FLAGS_word << "\t";
46  cout << results [i].PathWeight << "\t";
47  for (int j = 0; j < results [i].Uniques.size (); j++) {
48  cout << osyms->Find (results [i].Uniques [j]);
49  if (j < results [i].Uniques.size () - 1)
50  cout << " ";
51  }
52  cout << endl;
53  }
54 }
55 
56 void EvaluateWordlist (PhonetisaurusScript& decoder, vector<string> corpus,
57  int FLAGS_beam, int FLAGS_nbest, bool FLAGS_reverse,
58  string FLAGS_skip, double FLAGS_thresh, string FLAGS_gsep,
59  bool FLAGS_write_fsts) {
60  for (int i = 0; i < corpus.size (); i++) {
61  vector<PathData> results = decoder.Phoneticize (corpus [i], FLAGS_nbest,
62  FLAGS_beam, FLAGS_thresh,
63  FLAGS_write_fsts);
64  PrintPathData (results, corpus [i], decoder.osyms_);
65  }
66 }
67 
68 void ThreadedEvalaateWordlist (string FLAGS_model, vector<string> corpus,
69  int FLAGS_beam, int FLAGS_nbest,
70  bool FLAGS_reverse, string FLAGS_skip,
71  double FLAGS_thresh, string FLAGS_gsep,
72  bool FLAGS_write_fsts, int FLAGS_threads) {
73  int csize = corpus.size ();
74  RMAP rmap;
75  SymbolTable osyms;
76 
77 #pragma omp parallel for
78  for (int x = 0; x < FLAGS_threads; x++) {
79  PhonetisaurusScript decoder (FLAGS_model, FLAGS_gsep);
80  if (x == 0)
81  osyms = *decoder.osyms_;
82  int start = x * (csize / FLAGS_threads);
83  int end = (x == FLAGS_threads - 1) ? csize \
84  : start + (csize / FLAGS_threads);
85  for (int i = start; i < end; i++) {
86  vector<PathData> results = decoder.Phoneticize (corpus [i], FLAGS_nbest,
87  FLAGS_beam, FLAGS_thresh,
88  FLAGS_write_fsts);
89  rmap [i] = results;
90  }
91  }
92 
93  for (int i = 0; i < csize; i++) {
94  const vector<PathData> results = rmap [i];
95  PrintPathData (results, corpus [i], &osyms);
96  }
97 }
98 
99 DEFINE_string (model, "", "Input FST G2P model.");
100 DEFINE_string (word, "", "Input word to phoneticize.");
101 DEFINE_string (wordlist, "", "Input wordlist to phoneticize");
102 DEFINE_string (gsep, "", "Grapheme separator.");
103 DEFINE_string (skip, "_", "Phoneme skip marker.");
104 DEFINE_int32 (nbest, 1, "N-best hypotheses to output.");
105 DEFINE_int32 (beam, 10000, "Decoder beam.");
106 DEFINE_int32 (threads, 1, "Number of parallel threads.");
107 DEFINE_double (thresh, 99.0, "N-best comparison threshold.");
108 DEFINE_bool (write_fsts, false, "Write the output FSTs for debugging.");
109 DEFINE_bool (reverse, false, "Reverse input word.");
110 
111 int main (int argc, char* argv []) {
112  string usage = "phonetisaurus-g2pfst - joint N-gram decoder.\n\n Usage: ";
113  set_new_handler (FailedNewHandler);
114  PhonetisaurusSetFlags (usage.c_str(), &argc, &argv, false);
115 
116  if (FLAGS_model.compare ("") == 0) {
117  cerr << "You must supply an FST model to --model" << endl;
118  exit (1);
119  } else {
120  std::ifstream model_ifp (FLAGS_model);
121  if (!model_ifp.good ()) {
122  cout << "Failed to open --model file '"
123  << FLAGS_model << "'" << endl;
124  exit (1);
125  }
126  }
127 
128 
129  bool use_wordlist = false;
130  if (FLAGS_wordlist.compare ("") != 0) {
131  std::ifstream wordlist_ifp (FLAGS_wordlist);
132  if (!wordlist_ifp.good ()) {
133  cout << "Failed to open --wordlist file '"
134  << FLAGS_wordlist << "'" << endl;
135  exit (1);
136  } else {
137  use_wordlist = true;
138  }
139  }
140 
141  if (FLAGS_wordlist.compare ("") == 0 && FLAGS_word.compare ("") == 0) {
142  cout << "Either --wordlist or --word must be set!" << endl;
143  }
144 
145  #ifndef __GNUC__
146  omp_set_num_threads (FLAGS_threads);
147  #endif
148 
149 
150  if (use_wordlist == true) {
151  vector<string> corpus;
152  LoadWordList (FLAGS_wordlist, &corpus);
153 
154  if (FLAGS_threads > 1) {
155  cout << "TODO: Current OpenMP parallel output is non-deterministic." << endl;
156  /*
157  ThreadedEvalaateWordlist (FLAGS_model, corpus, FLAGS_beam,
158  FLAGS_nbest, FLAGS_reverse, FLAGS_skip,
159  FLAGS_thresh, FLAGS_gsep, FLAGS_write_fsts,
160  FLAGS_threads);
161  */
162  } else {
163  PhonetisaurusScript decoder (FLAGS_model, FLAGS_gsep);
164  EvaluateWordlist (decoder, corpus, FLAGS_beam, FLAGS_nbest,
165  FLAGS_reverse, FLAGS_skip, FLAGS_thresh,
166  FLAGS_gsep, FLAGS_write_fsts);
167  }
168  } else {
169  PhonetisaurusScript decoder (FLAGS_model, FLAGS_gsep);
170  vector<PathData> results = decoder.Phoneticize (FLAGS_word, FLAGS_nbest,
171  FLAGS_beam, FLAGS_thresh,
172  FLAGS_write_fsts);
173  PrintPathData (results, FLAGS_word, decoder.osyms_);
174  }
175 
176  return 0;
177 }
void EvaluateWordlist(PhonetisaurusScript &decoder, vector< string > corpus, int FLAGS_beam, int FLAGS_nbest, bool FLAGS_reverse, string FLAGS_skip, double FLAGS_thresh, string FLAGS_gsep, bool FLAGS_write_fsts)
vector< PathData > Phoneticize(const string &word, int nbest=1, int beam=10000, float threshold=99, bool write_fsts=false)
void PrintPathData(const vector< PathData > &results, string FLAGS_word, const SymbolTable *osyms)
void ThreadedEvalaateWordlist(string FLAGS_model, vector< string > corpus, int FLAGS_beam, int FLAGS_nbest, bool FLAGS_reverse, string FLAGS_skip, double FLAGS_thresh, string FLAGS_gsep, bool FLAGS_write_fsts, int FLAGS_threads)
const SymbolTable * osyms_
A wrapper class encapsulating the FST G2P decoder.
void PhonetisaurusSetFlags(const char *usage, int *argc, char ***argv, bool remove_flags)
Definition: util.cc:158
DEFINE_string(model,"","Input FST G2P model.")
DEFINE_int32(nbest, 1,"N-best hypotheses to output.")
int main(int argc, char *argv[])
unordered_map< int, vector< PathData > > RMAP
DEFINE_double(thresh, 99.0,"N-best comparison threshold.")
void LoadWordList(const std::string &filename, std::vector< std::string > *corpus)
Definition: util.cc:250
DEFINE_bool(write_fsts, false,"Write the output FSTs for debugging.")