bd0db5114b8ec784372f1899f1506e78d5642205
[processor-sdk/kaldi.git] / egs / babel_multilang / s5 / run-4-anydecode-langs.sh
1 #!/bin/bash
2 set -e
3 set -o pipefail
6 dir=dev10h.pem
7 kind=
8 data_only=false
9 skip_kws=false
10 skip_scoring=
11 extra_kws=true
12 vocab_kws=false
13 tri5_only=false
14 use_pitch=true
15 use_pitch_ivector=false # if true, pitch feature used in ivector extraction.
16 use_ivector=false
17 use_bnf=false
18 pitch_conf=conf/pitch.conf
19 wip=0.5
20 decode_stage=-1
21 nnet3_affix=
22 nnet3_dir=nnet3/tdnn_sp
23 is_rnn=false
24 extra_left_context=0
25 extra_right_context=0
26 frames_per_chunk=0
27 feat_suffix=
28 ivector_suffix=
29 iter=final
31 # params for extracting bn features
32 multidir=exp/nnet3/multi_bnf_sp
33 dump_bnf_dir=bnf
34 bnf_layer=5
37 . conf/common_vars.sh || exit 1;
39 . utils/parse_options.sh
41 if [ $# -ne 1 ]; then
42   echo "Usage: $(basename $0) --dir <dir-type> <lang>"
43   echo " e.g.: $(basename $0) --dir dev2h.pem ASM"
44   exit 1
45 fi
47 lang=$1
50 langconf=conf/$lang/lang.conf
52 [ ! -f $langconf ] && echo 'Language configuration does not exist! Use the configurations in conf/lang/* as a startup' && exit 1
53 . $langconf || exit 1;
54 [ -f local.conf ] && . local.conf;
56 mfcc=mfcc/$lang
57 plp=plp/$lang
58 data=data/$lang
59 vector_suffix=_gb
60 #This seems to be the only functioning way how to ensure the comple
61 #set of scripts will exit when sourcing several of them together
62 #Otherwise, the CTRL-C just terminates the deepest sourced script ?
63 # Let shell functions inherit ERR trap.  Same as `set -E'.
64 set -o errtrace
65 trap "echo Exited!; exit;" SIGINT SIGTERM
67 # Set proxy search parameters for the extended lexicon case.
68 if [ -f $data/.extlex ]; then
69   proxy_phone_beam=$extlex_proxy_phone_beam
70   proxy_phone_nbest=$extlex_proxy_phone_nbest
71   proxy_beam=$extlex_proxy_beam
72   proxy_nbest=$extlex_proxy_nbest
73 fi
75 dataset_segments=${dir##*.}
76 dataset_dir=$data/$dir
77 dataset_id=$dir
78 dataset_type=${dir%%.*}
79 #By default, we want the script to accept how the dataset should be handled,
80 #i.e. of  what kind is the dataset
81 if [ -z ${kind} ] ; then
82   if [ "$dataset_type" == "dev2h" ] || [ "$dataset_type" == "dev10h" ]; then
83     dataset_kind=supervised
84   else
85     dataset_kind=unsupervised
86   fi
87 else
88   dataset_kind=$kind
89 fi
91 dataset=$(basename $dataset_dir)
92 mfccdir=mfcc_hires/$lang
93 mfcc_affix=""
94 hires_config="--mfcc-config conf/mfcc_hires.conf"
95 data_dir=${dataset_dir}_hires
96 feat_suffix=_hires
97 ivec_feat_suffix=_hires
98 log_dir=exp/$lang/make_hires/$dataset
100 if $use_pitch_ivector; then
101   ivec_feat_suffix=_hires_pitch
102 fi
104 if $use_pitch; then
105   mfcc_affix="_pitch_online"
106   hires_config="$hires_config --online-pitch-config $pitch_conf"
107   mfccdir=mfcc_hires_pitch/lang
108   data_dir=${dataset_dir}_hires_pitch
109   feat_suffix="_hires_pitch"
110   log_dir=exp/$lang/make_hires_pitch/$dataset
111 fi
113 if [ -z $dataset_segments ]; then
114   echo "You have to specify the segmentation type as well"
115   echo "If you are trying to decode the PEM segmentation dir"
116   echo "such as data/dev10h, specify dev10h.pem"
117   echo "The valid segmentations types are:"
118   echo "\tpem   #PEM segmentation"
119   echo "\tuem   #UEM segmentation in the CMU database format"
120   echo "\tseg   #UEM segmentation (kaldi-native)"
121 fi
123 if [ -z "${skip_scoring}" ] ; then
124   if [ "$dataset_kind" == "unsupervised" ]; then
125     skip_scoring=true
126   else
127     skip_scoring=false
128   fi
129 fi
131 #The $dataset_type value will be the dataset name without any extrension
132 eval my_data_dir=( "\${${dataset_type}_data_dir[@]}" )
133 eval my_data_list=( "\${${dataset_type}_data_list[@]}" )
134 if [ -z $my_data_dir ] || [ -z $my_data_list ] ; then
135   echo "Error: The dir you specified ($dataset_id) does not have existing config";
136   exit 1
137 fi
139 eval my_stm_file=\$${dataset_type}_stm_file
140 eval my_ecf_file=\$${dataset_type}_ecf_file
141 eval my_rttm_file=\$${dataset_type}_rttm_file
142 eval my_nj=\$${dataset_type}_nj  #for shadow, this will be re-set when appropriate
144 if [ -z "$my_nj" ]; then
145   echo >&2 "You didn't specify the number of jobs -- variable \"${dataset_type}_nj\" not defined."
146   exit 1
147 fi
149 my_subset_ecf=false
150 eval ind=\${${dataset_type}_subset_ecf+x}
151 if [ "$ind" == "x" ] ; then
152   eval my_subset_ecf=\$${dataset_type}_subset_ecf
153 fi
155 declare -A my_kwlists=()
156 eval my_kwlist_keys="\${!${dataset_type}_kwlists[@]}"
157 for key in $my_kwlist_keys  # make sure you include the quotes there
158 do
159   eval my_kwlist_val="\${${dataset_type}_kwlists[$key]}"
160   my_kwlists["$key"]="${my_kwlist_val}"
161 done
163 #Just a minor safety precaution to prevent using incorrect settings
164 #The dataset_* variables should be used.
165 set -e
166 set -o pipefail
167 set -u
168 unset dir
169 unset kind
171 function make_plp {
172   target=$1
173   logdir=$2
174   output=$3
175   if $use_pitch; then
176     steps/make_plp_pitch.sh --cmd "$decode_cmd" --nj $my_nj $target $logdir $output
177   else
178     steps/make_plp.sh --cmd "$decode_cmd" --nj $my_nj $target $logdir $output
179   fi
180   utils/fix_data_dir.sh $target
181   steps/compute_cmvn_stats.sh $target $logdir $output
182   utils/fix_data_dir.sh $target
185 function check_variables_are_set {
186   for variable in $mandatory_variables ; do
187     if ! declare -p $variable ; then
188       echo "Mandatory variable ${variable/my/$dataset_type} is not set! "
189       echo "You should probably set the variable in the config file "
190       exit 1
191     else
192       declare -p $variable
193     fi
194   done
196   if [ ! -z ${optional_variables+x} ] ; then
197     for variable in $optional_variables ; do
198       eval my_variable=\$${variable}
199       echo "$variable=$my_variable"
200     done
201   fi
204 if [ ! -f $data/raw_${dataset_type}_data/.done ]; then
205   echo ---------------------------------------------------------------------
206   echo "Subsetting the ${dataset_type} set"
207   echo ---------------------------------------------------------------------
209   l1=${#my_data_dir[*]}
210   l2=${#my_data_list[*]}
211   if [ "$l1" -ne "$l2" ]; then
212     echo "Error, the number of source files lists is not the same as the number of source dirs!"
213     exit 1
214   fi
216   resource_string=""
217   if [ "$dataset_kind" == "unsupervised" ]; then
218     resource_string+=" --ignore-missing-txt true"
219   fi
221   for i in `seq 0 $(($l1 - 1))`; do
222     resource_string+=" ${my_data_dir[$i]} "
223     resource_string+=" ${my_data_list[$i]} "
224   done
225   local/make_corpus_subset.sh $resource_string ./$data/raw_${dataset_type}_data
226   touch $data/raw_${dataset_type}_data/.done
227 fi
228 my_data_dir=`utils/make_absolute.sh ./$data/raw_${dataset_type}_data`
229 [ -f $my_data_dir/filelist.list ] && my_data_list=$my_data_dir/filelist.list
230 nj_max=`cat $my_data_list | wc -l` || nj_max=`ls $my_data_dir/audio | wc -l`
232 if [ "$nj_max" -lt "$my_nj" ] ; then
233   echo "Number of jobs ($my_nj) is too big!"
234   echo "The maximum reasonable number of jobs is $nj_max"
235   my_nj=$nj_max
236 fi
238 #####################################################################
240 # Audio data directory preparation
242 #####################################################################
243 echo ---------------------------------------------------------------------
244 echo "Preparing ${dataset_kind} data files in ${dataset_dir} on" `date`
245 echo ---------------------------------------------------------------------
246 if [ ! -f  $dataset_dir/.done ] ; then
247   if [ "$dataset_kind" == "supervised" ]; then
248     if [ "$dataset_segments" == "seg" ]; then
249       . ./local/datasets/supervised_seg.sh || exit 1
250     elif [ "$dataset_segments" == "uem" ]; then
251       . ./local/datasets/supervised_uem.sh || exit 1
252     elif [ "$dataset_segments" == "pem" ]; then
253       . ./local/datasets/supervised_pem.sh || exit 1
254     else
255       echo "Unknown type of the dataset: \"$dataset_segments\"!";
256       echo "Valid dataset types are: seg, uem, pem";
257       exit 1
258     fi
259   elif [ "$dataset_kind" == "unsupervised" ] ; then
260     if [ "$dataset_segments" == "seg" ] ; then
261       . ./local/datasets/unsupervised_seg.sh
262     elif [ "$dataset_segments" == "uem" ] ; then
263       . ./local/datasets/unsupervised_uem.sh
264     elif [ "$dataset_segments" == "pem" ] ; then
265       ##This combination does not really makes sense,
266       ##Because the PEM is that we get the segmentation
267       ##and because of the format of the segment files
268       ##the transcript as well
269       echo "ERROR: $dataset_segments combined with $dataset_type"
270       echo "does not really make any sense!"
271       exit 1
272       #. ./local/datasets/unsupervised_pem.sh
273     else
274       echo "Unknown type of the dataset: \"$dataset_segments\"!";
275       echo "Valid dataset types are: seg, uem, pem";
276       exit 1
277     fi
278   else
279     echo "Unknown kind of the dataset: \"$dataset_kind\"!";
280     echo "Valid dataset kinds are: supervised, unsupervised, shadow";
281     exit 1
282   fi
284   if [ ! -f ${dataset_dir}/.plp.done ]; then
285     echo ---------------------------------------------------------------------
286     echo "Preparing ${dataset_kind} parametrization files in ${dataset_dir} on" `date`
287     echo ---------------------------------------------------------------------
288     make_plp ${dataset_dir} exp/$lang/make_plp/${dataset_id} plp/$lang
289     touch ${dataset_dir}/.plp.done
290   fi
293   if [ ! -f ${data_dir}/.mfcc.done ]; then
294     echo ---------------------------------------------------------------------
295     echo "Preparing ${dataset_kind} MFCC features in  ${data_dir} and corresponding iVectors in exp/$lang/nnet3${nnet3_affix}/ivectors_${dataset}${feat_suffix}${ivector_suffix} on" `date`
296     echo ---------------------------------------------------------------------
297     if [ ! -d ${data_dir} ]; then
298       utils/copy_data_dir.sh $data/$dataset ${data_dir}
299     fi
302     steps/make_mfcc${mfcc_affix}.sh --nj $my_nj $hires_config \
303         --cmd "$train_cmd" ${data_dir} $log_dir $mfccdir;
304     steps/compute_cmvn_stats.sh ${data_dir} $log_dir $mfccdir;
305     utils/fix_data_dir.sh ${data_dir};
306     touch ${data_dir}/.mfcc.done
307   fi
308   touch $dataset_dir/.done
309 fi
311 # extract ivector
312 dataset=$(basename $dataset_dir)
313 ivector_dir=exp/$lang/nnet3${nnet3_affix}/ivectors_${dataset}${ivec_feat_suffix}${ivector_suffix}
314 if $use_ivector && [ ! -f $ivector_dir/.ivector.done ];then
315   extractor=exp/multi/nnet3${nnet3_affix}/extractor
316   ivec_feat_suffix=$feat_suffix
317   if $use_pitch && ! $use_pitch_ivector; then
318     ivec_feat_suffix=_hires
319     featdir=${dataset_dir}${feat_suffix}
320     mfcc_only_dim=`feat-to-dim scp:$featdir/feats.scp - | awk '{print $1-3}'`
321     steps/select_feats.sh --cmd "$train_cmd" --nj $my_nj 0-$[$mfcc_only_dim-1] \
322       $featdir ${dataset_dir}${ivec_feat_suffix} || exit 1;
323     steps/compute_cmvn_stats.sh ${dataset_dir}${ivec_feat_suffix} || exit 1;
324   fi
326   steps/online/nnet2/extract_ivectors_online.sh --cmd "$train_cmd" --nj $my_nj \
327     ${dataset_dir}${ivec_feat_suffix} $extractor $ivector_dir || exit 1;
328   touch $ivector_dir/.ivector.done
329 fi
331 if $use_bnf; then
332   # put the archives in ${dump_bnf_dir}/.
333   dataset=$(basename $dataset_dir)
334   multi_ivector_dir=exp/$lang/nnet3${nnet3_affix}/ivectors_${dataset}${ivec_feat_suffix}${ivector_suffix}
335   bnf_data_dir=${dataset_dir}_bnf/$lang
336   if [ ! -f $bnf_data_dir/.done ]; then
337   steps/nnet3/dump_bottleneck_features.sh --use-gpu true --nj 100 --cmd "$train_cmd" \
338     --ivector-dir $multi_ivector_dir \
339     --feat-type raw \
340     ${dataset_dir}${feat_suffix} $bnf_data_dir \
341     $multidir $dump_bnf_dir/$lang exp/$lang/make_${dataset}_bnf || exit 1;
342   touch $bnf_data_dir/.done
343   fi
344   appended_bnf=${dataset_dir}${feat_suffix}_bnf
345   if [ ! -f $appended_bnf/.done ]; then
346     steps/append_feats.sh  --nj 16 --cmd "$train_cmd" \
347       $bnf_data_dir ${dataset_dir}${feat_suffix} \
348       ${dataset_dir}${feat_suffix}_bnf exp/$lang/append${feat_suffix}_bnf \
349       mfcc${feat_suffix}_bnf/$lang || exit 1;
351     steps/compute_cmvn_stats.sh $appended_bnf exp/$lang/make_cmvn${feat_suffix}_bnf \
352       mfcc${feat_suffix}_bnf/$lang || exit 1;
353     touch $appended_bnf/.done
354   fi
355   feat_suffix=${feat_suffix}_bnf
356 fi
358 #####################################################################
360 # KWS data directory preparation
362 #####################################################################
363 echo ---------------------------------------------------------------------
364 echo "Preparing kws data files in ${dataset_dir} on" `date`
365 echo ---------------------------------------------------------------------
367 if ! $skip_kws ; then
368   if  $extra_kws ; then
369     L1_lex=data/local/lexiconp.txt
370     . ./local/datasets/extra_kws.sh || exit 1
371   fi
372   if  $vocab_kws ; then
373     . ./local/datasets/vocab_kws.sh || exit 1
374   fi
375 fi
376 if $data_only ; then
377   echo "Exiting, as data-only was requested..."
378   exit 0;
379 fi
381 ####################################################################
382 ## FMLLR decoding
383 ##
384 ####################################################################
385 decode=exp/$lang/tri5/decode_${dataset_id}
386 if [ ! -f exp/$lang/tri5/graph/HCLG.fst ];then
387   utils/mkgraph.sh \
388     data/$lang/lang exp/$lang/tri5 exp/$lang/tri5/graph |tee exp/$lang/tri5/mkgraph.log
389 fi
390 if [ ! -f ${decode}/.done ]; then
391   echo ---------------------------------------------------------------------
392   echo "Spawning decoding with SAT models  on" `date`
393   echo ---------------------------------------------------------------------
394   utils/mkgraph.sh \
395     data/$lang/lang exp/$lang/tri5 exp/$lang/tri5/graph |tee exp/$lang/tri5/mkgraph.log
397   mkdir -p $decode
398   #By default, we do not care about the lattices for this step -- we just want the transforms
399   #Therefore, we will reduce the beam sizes, to reduce the decoding times
400   steps/decode_fmllr_extra.sh --skip-scoring true --beam 10 --lattice-beam 4\
401     --nj $my_nj --cmd "$decode_cmd" "${decode_extra_opts[@]}"\
402     exp/$lang/tri5/graph ${dataset_dir} ${decode} |tee ${decode}/decode.log
403   touch ${decode}/.done
404 fi
407 if $tri5_only; then
408   echo "--tri5-only is true. So exiting."
409   exit 0
410 fi
412 ####################################################################
413 ##
414 ## nnet3 model decoding
415 ##
416 ####################################################################
418 if [ -f $nnet3_dir/$lang/final.mdl ]; then
419   decode=$nnet3_dir/$lang/decode_${dataset_id}
420   rnn_opts=
421   feat_suffix=_hires
422   ivec_feat_suffix=_hires
424   # suffix for using other features such as pitch
425   if $use_pitch; then
426     feat_suffix=${feat_suffix}_pitch
427   fi
428   if $use_pitch_ivector; then
429     ivec_feat_suffix=_hires_pitch
430   fi
431   if $use_bnf; then
432     feat_suffix=${feat_suffix}_bnf
433   fi
434   ivector_opts=
435   if $use_ivector; then
436     ivector_opts="--online-ivector-dir exp/$lang/nnet3${nnet3_affix}/ivectors_${dataset_id}${ivec_feat_suffix}${ivector_suffix}"
437   fi
438   if [ "$is_rnn" == "true" ]; then
439     rnn_opts=" --extra-left-context $extra_left_context --extra-right-context $extra_right_context  --frames-per-chunk $frames_per_chunk "
440   fi
441   if [ ! -f $decode/.done ]; then
442     mkdir -p $decode
443     score_opts="--skip-scoring false"
444     [ ! -z $iter ] && iter_opt="--iter $iter"
445     steps/nnet3/decode.sh --nj $my_nj --cmd "$decode_cmd" $iter_opt $rnn_opts \
446           --stage $decode_stage \
447           --beam $dnn_beam --lattice-beam $dnn_lat_beam \
448           $score_opts $ivector_opts \
449           exp/$lang/tri5/graph ${dataset_dir}${feat_suffix} $decode | tee $decode/decode.log
451     touch $decode/.done
452   fi
453 fi
455 echo "Everything looking good...."
456 exit 0