static void vithist_lmstate_dump (vithist_t *vh, kbcore_t *kbc, FILE *fp) { glist_t gl; gnode_t *lgn, *gn; int32 i; vh_lmstate2vithist_t *lms2vh; mdef_t *mdef; lm_t *lm; mdef = kbcore_mdef (kbc); lm = kbcore_lm (kbc); fprintf (fp, "LMSTATE\n"); for (lgn = vh->lwidlist; lgn; lgn = gnode_next(lgn)) { i = (int32) gnode_int32 (lgn); gl = vh->lmstate_root[i]; assert (gl); for (gn = gl; gn; gn = gnode_next(gn)) { lms2vh = (vh_lmstate2vithist_t *) gnode_ptr (gn); fprintf (fp, "\t%s.%s -> %d\n", lm_wordstr(lm, i), mdef_ciphone_str (mdef, lms2vh->state), lms2vh->vhid); vithist_lmstate_subtree_dump (vh, kbc, lms2vh, 1, fp); } } fprintf (fp, "END_LMSTATE\n"); fflush (fp); }
int32 s3_cd_gmm_compute_sen(void *srch, float32 ** feat, int32 wav_idx) { srch_t *s; mdef_t *mdef; ms_mgau_model_t *ms_mgau; mgau_model_t *mgau; ascr_t *ascr; kbcore_t *kbcore; fast_gmm_t *fgmm; pl_t *pl; stat_t *st; float32 *fv; s = (srch_t *) srch; kbcore = s->kbc; pl = s->pl; fgmm = s->fastgmm; st = s->stat; mdef = kbcore_mdef(kbcore); ms_mgau = kbcore_ms_mgau(kbcore); mgau = kbcore_mgau(kbcore); ascr = s->ascr; assert(kbcore->ms_mgau || kbcore->mgau || kbcore->s2_mgau); assert(!(kbcore->ms_mgau && kbcore->mgau && kbcore->s2_mgau)); /* Always use the first buffer in the cache */ if (kbcore->ms_mgau) { s->senscale = ms_cont_mgau_frame_eval(ascr, ms_mgau, mdef, feat, wav_idx); /* FIXME: Statistics is not correctly updated */ } else if (kbcore->s2_mgau) { s->senscale = s2_semi_mgau_frame_eval(kbcore->s2_mgau, ascr, fgmm, feat, wav_idx); /* FIXME: Statistics is not correctly updated */ } else if (kbcore->mgau) { fv = feat[0]; s->senscale = approx_cont_mgau_frame_eval(mdef, kbcore_svq(kbcore), kbcore_gs(kbcore), mgau, fgmm, ascr, fv, wav_idx, ascr->cache_ci_senscr[s-> cache_win_strt], &(st->tm_ovrhd), kbcore_logmath(kbcore)); st->utt_sen_eval += mgau_frm_sen_eval(mgau); st->utt_gau_eval += mgau_frm_gau_eval(mgau); } else E_FATAL("Panic, someone delete the assertion before this block\n"); return SRCH_SUCCESS; }
int srch_FLAT_FWD_uninit(void *srch) { srch_FLAT_FWD_graph_t *fwg; srch_t *s; s = (srch_t *) srch; fwg = (srch_FLAT_FWD_graph_t *) s->grh->graph_struct; if (fwg->rcscore) ckd_free(fwg->rcscore); if (fwg->ug_backoff) ckd_free(fwg->ug_backoff); if (fwg->filler_backoff) ckd_free(fwg->filler_backoff); if (fwg->tg_trans_done) ckd_free(fwg->tg_trans_done); if (fwg->word_cand_cf) ckd_free(fwg->word_cand_cf); if (fwg->word_cand) ckd_free(fwg->word_cand); if (fwg->ctxt) ctxt_table_free(fwg->ctxt); if (fwg->lathist) latticehist_free(fwg->lathist); if (fwg->fwdDBG) ckd_free(fwg->fwdDBG); if (fwg->whmm) ckd_free(fwg->whmm); if (fwg->hmmctx) hmm_context_free(fwg->hmmctx); if (fwg->word_ugprob) word_ugprob_free(fwg->word_ugprob, kbcore_mdef(s->kbc)->n_ciphone); pctr_free(fwg->ctr_mpx_whmm); pctr_free(fwg->ctr_nonmpx_whmm); pctr_free(fwg->ctr_latentry); ckd_free(fwg); return SRCH_SUCCESS; }
int srch_FLAT_FWD_select_active_gmm(void *srch) { kbcore_t *kbc; s3wid_t w; whmm_t *h; int32 st; s3pid_t p; s3senid_t *senp; ascr_t *ascr; srch_FLAT_FWD_graph_t *fwg; srch_t *s; mdef_t *mdef; dict_t *dict; s = (srch_t *) srch; fwg = (srch_FLAT_FWD_graph_t *) s->grh->graph_struct; ascr = s->ascr; kbc = s->kbc; mdef = kbcore_mdef(kbc); dict = kbcore_dict(kbc); ascr_clear_sen_active(ascr); /* Flag active senones */ for (w = 0; w < dict->n_word; w++) { for (h = fwg->whmm[w]; h; h = h->next) { if (hmm_is_mpx(h)) { for (st = 0; st < hmm_n_emit_state(h); ++st) { p = hmm_mpx_ssid(h, st); if (p == -1) break; /* All subsequent ones are also inactive */ senp = mdef->sseq[p]; ascr->sen_active[senp[st]] = 1; } } else { p = hmm_nonmpx_ssid(h); senp = mdef->sseq[p]; for (st = 0; st < hmm_n_emit_state(h); ++st) ascr->sen_active[senp[st]] = 1; } } } return SRCH_SUCCESS; }
int32 approx_ci_gmm_compute(void *srch, float32 * feat, int32 cache_idx, int32 wav_idx) { srch_t *s; stat_t *st; fast_gmm_t *fgmm; mdef_t *mdef; mgau_model_t *mgau; kbcore_t *kbcore; ascr_t *ascr; s = (srch_t *) srch; kbcore = s->kbc; mdef = kbcore_mdef(kbcore); mgau = kbcore_mgau(kbcore); fgmm = s->fastgmm; st = s->stat; ascr = s->ascr; /* No CI-GMM done for multistream models (for now) */ if (mgau == NULL) { assert(kbcore_ms_mgau(kbcore) || kbcore_s2_mgau(kbcore)); return SRCH_SUCCESS; } approx_cont_mgau_ci_eval(kbcore_svq(kbcore), kbcore_gs(kbcore), mgau, fgmm, mdef, feat, ascr->cache_ci_senscr[cache_idx], &(ascr->cache_best_list[cache_idx]), wav_idx, kbcore_logmath(kbcore)); st->utt_cisen_eval += mgau_frm_cisen_eval(mgau); st->utt_cigau_eval += mgau_frm_cigau_eval(mgau); return SRCH_SUCCESS; }
/** ARCHAN: Dangerous! Mixing global and local */ static void dump_fwd_dbg_info(srch_FLAT_FWD_graph_t * fwg, fwd_dbg_t * fd, ascr_t * ascr, int32 bestscr, int32 whmm_thresh, int32 word_thresh, int32 * senscr) { whmm_t *h; int32 n_frm; kbcore_t *kbc; tmat_t *tmat; dict_t *dict; mdef_t *mdef; n_frm = fwg->n_frm; kbc = fwg->kbcore; dict = kbcore_dict(kbc); tmat = kbcore_tmat(kbc); mdef = kbcore_mdef(kbc); /* Dump bestscore and pruning thresholds if any detailed tracing specified */ if (((fd->hmm_dump_sf < n_frm) && (n_frm < fd->hmm_dump_ef)) || ((fd->word_dump_sf < n_frm) && (n_frm < fd->word_dump_ef)) || (IS_S3WID(fd->trace_wid) && fwg->whmm[fd->trace_wid])) { printf ("[%4d]: >>>> bestscore= %11d, whmm-thresh= %11d, word-thresh= %11d\n", n_frm, bestscr, whmm_thresh, word_thresh); } /* Dump all active HMMs or words, if indicated */ if (fd->hmm_dump_sf < n_frm && n_frm < fd->hmm_dump_ef) dump_all_whmm(fwg, fwg->whmm, n_frm, ascr->senscr); else if (fd->word_dump_sf < n_frm && n_frm < fd->word_dump_ef) dump_all_word(fwg, fwg->whmm); /* Trace active HMMs for specified word, if any */ if (IS_S3WID(fd->trace_wid)) { for (h = fwg->whmm[fd->trace_wid]; h; h = h->next) dump_whmm(fd->trace_wid, h, senscr, tmat, n_frm, dict, mdef); } }
void kb_init(kb_t * kb, cmd_ln_t *config) { kbcore_t *kbcore; mdef_t *mdef; dict_t *dict; dict2pid_t *d2p; int32 cisencnt; /* STRUCTURE: Initialize the kb structure to zero, just in case */ memset(kb, 0, sizeof(*kb)); kb->kbcore = kbcore_init(config); if (kb->kbcore == NULL) E_FATAL("Initialization of kb failed\n"); kbcore = kb->kbcore; mdef = kbcore_mdef(kbcore); dict = kbcore_dict(kbcore); d2p = kbcore_dict2pid(kbcore); err_set_debug_level(cmd_ln_int32_r(config, "-debug")); /* STRUCTURE INITIALIZATION: Initialize the beam data structure */ if (cmd_ln_exists_r(config, "-ptranskip")) { kb->beam = beam_init(cmd_ln_float64_r(config, "-beam"), cmd_ln_float64_r(config, "-pbeam"), cmd_ln_float64_r(config, "-wbeam"), cmd_ln_float64_r(config, "-wend_beam"), cmd_ln_int32_r(config, "-ptranskip"), mdef_n_ciphone(mdef), kbcore->logmath ); /* REPORT : Report the parameters in the beam data structure */ if (REPORT_KB) beam_report(kb->beam); } /* STRUCTURE INITIALIZATION: Initialize the fast GMM computation data structure */ if (cmd_ln_exists_r(config, "-ci_pbeam")) { kb->fastgmm = fast_gmm_init(cmd_ln_int32_r(config, "-ds"), cmd_ln_int32_r(config, "-cond_ds"), cmd_ln_int32_r(config, "-dist_ds"), cmd_ln_int32_r(config, "-gs4gs"), cmd_ln_int32_r(config, "-svq4svq"), cmd_ln_float64_r(config, "-subvqbeam"), cmd_ln_float64_r(config, "-ci_pbeam"), cmd_ln_float64_r(config, "-tighten_factor"), cmd_ln_int32_r(config, "-maxcdsenpf"), mdef->n_ci_sen, kbcore->logmath); /* REPORT : Report the parameters in the fast_gmm_t data struture */ if (REPORT_KB) fast_gmm_report(kb->fastgmm); } /* STRUCTURE INITIALIZATION: Initialize the phoneme lookahead data structure */ if (cmd_ln_exists_r(config, "-pl_beam")) { kb->pl = pl_init(cmd_ln_int32_r(config, "-pheurtype"), cmd_ln_float64_r(config, "-pl_beam"), mdef_n_ciphone(mdef), kbcore->logmath ); /* REPORT : Report the parameters in the pl_t data struture */ if (REPORT_KB) pl_report(kb->pl); } /* STRUCTURE INITIALIZATION: Initialize the acoustic score data structure */ { int32 pl_window = 1; if (cmd_ln_exists_r(config, "-pl_window")) pl_window = cmd_ln_int32_r(config, "-pl_window"); for (cisencnt = 0; cisencnt == mdef->cd2cisen[cisencnt]; cisencnt++) ; kb->ascr = ascr_init(kbcore_n_mgau(kbcore), kb->kbcore->dict2pid->n_comstate, mdef_n_sseq(mdef), dict2pid_n_comsseq(d2p), pl_window, cisencnt); if (REPORT_KB) ascr_report(kb->ascr); } /* Initialize the front end if -adcin is specified */ if (cmd_ln_exists_r(config, "-adcin") && cmd_ln_boolean_r(config, "-adcin")) { if ((kb->fe = fe_init_auto_r(config)) == NULL) { E_FATAL("fe_init_auto_r() failed\n"); } } /* STRUCTURE INITIALIZATION : The feature vector */ if ((kb->feat = feat_array_alloc(kbcore_fcb(kbcore), S3_MAX_FRAMES)) == NULL) E_FATAL("feat_array_alloc() failed\n"); /* STRUCTURE INITIALIZATION : The statistics for the search */ kb->stat = stat_init(); /* STRUCTURE INITIALIZATION : The adaptation routines of the search */ kb->adapt_am = adapt_am_init(); if (cmd_ln_str_r(config, "-mllr")) { kb_setmllr(cmd_ln_str_r(config, "-mllr"), cmd_ln_str_r(config, "-cb2mllr"), kb); } /* CHECK: make sure when (-cond_ds) is specified, a Gaussian map is also specified */ if (cmd_ln_int32_r(config, "-cond_ds") > 0 && kb->kbcore->gs == NULL) E_FATAL ("Conditional Down Sampling require the use of Gaussian Selection map\n"); /* MEMORY ALLOCATION : Word best score and exit */ /* Open hypseg file if specified */ kb->matchsegfp = kb->matchfp = NULL; kb->matchsegfp = file_open(cmd_ln_str_r(config, "-hypseg")); kb->matchfp = file_open(cmd_ln_str_r(config, "-hyp")); if (cmd_ln_exists_r(config, "-hmmdump")) kb->hmmdumpfp = cmd_ln_int32_r(config, "-hmmdump") ? stderr : NULL; /* STRUCTURE INITIALIZATION : The search data structure, done only after kb is initialized kb is acted as a clipboard. */ if (cmd_ln_exists_r(config, "-op_mode")) { /* -op_mode, if set (i.e. not -1), takes precedence over -mode. */ if (cmd_ln_int32_r(config, "-op_mode") != -1) kb->op_mode = cmd_ln_int32_r(config, "-op_mode"); else kb->op_mode = srch_mode_str_to_index(cmd_ln_str_r(config, "-mode")); E_INFO("SEARCH MODE INDEX %d\n", kb->op_mode); if ((kb->srch = (srch_t *) srch_init(kb, kb->op_mode)) == NULL) { E_FATAL("Search initialization failed. Forced exit\n"); } if (REPORT_KB) { srch_report(kb->srch); } } }
/*ARCHAN, to allow backward compatibility -lm, -lmctlfn coexists. This makes the current implmentation more complicated than necessary. */ void kb_init (kb_t *kb) { kbcore_t *kbcore; mdef_t *mdef; dict_t *dict; dict2pid_t *d2p; lm_t *lm; lmset_t *lmset; s3cipid_t sil, ci; s3wid_t w; int32 i, n, n_lc; wordprob_t *wp; s3cipid_t *lc; bitvec_t lc_active; char *str; int32 cisencnt; int32 j; /* Initialize the kb structure to zero, just in case */ memset(kb, 0, sizeof(*kb)); kb->kbcore = NULL; kb->kbcore = kbcore_init (cmd_ln_float32 ("-logbase"), cmd_ln_str("-feat"), cmd_ln_str("-cmn"), cmd_ln_str("-varnorm"), cmd_ln_str("-agc"), cmd_ln_str("-mdef"), cmd_ln_str("-dict"), cmd_ln_str("-fdict"), "", /* Hack!! Hardwired constant for -compsep argument */ cmd_ln_str("-lm"), cmd_ln_str("-lmctlfn"), cmd_ln_str("-lmdumpdir"), cmd_ln_str("-fillpen"), cmd_ln_str("-senmgau"), cmd_ln_float32("-silprob"), cmd_ln_float32("-fillprob"), cmd_ln_float32("-lw"), cmd_ln_float32("-wip"), cmd_ln_float32("-uw"), cmd_ln_str("-mean"), cmd_ln_str("-var"), cmd_ln_float32("-varfloor"), cmd_ln_str("-mixw"), cmd_ln_float32("-mixwfloor"), cmd_ln_str("-subvq"), cmd_ln_str("-gs"), cmd_ln_str("-tmat"), cmd_ln_float32("-tmatfloor")); if(kb->kbcore==NULL){ E_FATAL("Initialization of kb failed\n"); } kbcore = kb->kbcore; mdef = kbcore_mdef(kbcore); dict = kbcore_dict(kbcore); lm = kbcore_lm(kbcore); lmset=kbcore_lmset(kbcore); d2p = kbcore_dict2pid(kbcore); if (NOT_S3WID(dict_startwid(dict)) || NOT_S3WID(dict_finishwid(dict))) E_FATAL("%s or %s not in dictionary\n", S3_START_WORD, S3_FINISH_WORD); if(lmset){ for(i=0;i<kbcore_nlm(kbcore);i++){ if (NOT_S3LMWID(lm_startwid(lmset[i].lm)) || NOT_S3LMWID(lm_finishwid(lmset[i].lm))) E_FATAL("%s or %s not in LM %s\n", S3_START_WORD, S3_FINISH_WORD,lmset[i].name); } }else if(lm){ if (NOT_S3LMWID(lm_startwid(lm)) || NOT_S3LMWID(lm_finishwid(lm))) E_FATAL("%s or %s not in LM\n", S3_START_WORD, S3_FINISH_WORD); } /* Check that HMM topology restrictions are not violated */ if (tmat_chk_1skip (kbcore->tmat) < 0) E_FATAL("Tmat contains arcs skipping more than 1 state\n"); /* * Unlink <s> and </s> between dictionary and LM, to prevent their * recognition. They are merely dummy words (anchors) at the beginning * and end of each utterance. */ if(lmset){ for(i=0;i<kbcore_nlm(kbcore);i++){ lm_lmwid2dictwid(lmset[i].lm, lm_startwid(lmset[i].lm)) = BAD_S3WID; lm_lmwid2dictwid(lmset[i].lm, lm_finishwid(lmset[i].lm)) = BAD_S3WID; for (w = dict_startwid(dict); IS_S3WID(w); w = dict_nextalt(dict, w)) lmset[i].lm->dict2lmwid[w] = BAD_S3LMWID; for (w = dict_finishwid(dict); IS_S3WID(w); w = dict_nextalt(dict, w)) lmset[i].lm->dict2lmwid[w] = BAD_S3LMWID; } }else if(lm){ /* No LM is set at this point*/ lm_lmwid2dictwid(lm, lm_startwid(lm)) = BAD_S3WID; lm_lmwid2dictwid(lm, lm_finishwid(lm)) = BAD_S3WID; for (w = dict_startwid(dict); IS_S3WID(w); w = dict_nextalt(dict, w)) kbcore->dict2lmwid[w] = BAD_S3LMWID; for (w = dict_finishwid(dict); IS_S3WID(w); w = dict_nextalt(dict, w)) kbcore->dict2lmwid[w] = BAD_S3LMWID; } sil = mdef_silphone (kbcore_mdef (kbcore)); if (NOT_S3CIPID(sil)) E_FATAL("Silence phone '%s' not in mdef\n", S3_SILENCE_CIPHONE); kb->sen_active = (int32 *) ckd_calloc (mdef_n_sen(mdef), sizeof(int32)); kb->rec_sen_active = (int32 *) ckd_calloc (mdef_n_sen(mdef), sizeof(int32)); kb->ssid_active = (int32 *) ckd_calloc (mdef_n_sseq(mdef), sizeof(int32)); kb->comssid_active = (int32 *) ckd_calloc (dict2pid_n_comsseq(d2p), sizeof(int32)); /* Build set of all possible left contexts */ lc = (s3cipid_t *) ckd_calloc (mdef_n_ciphone(mdef) + 1, sizeof(s3cipid_t)); lc_active = bitvec_alloc (mdef_n_ciphone (mdef)); for (w = 0; w < dict_size (dict); w++) { ci = dict_pron (dict, w, dict_pronlen(dict, w) - 1); if (! mdef_is_fillerphone (mdef, (int)ci)) bitvec_set (lc_active, ci); } ci = mdef_silphone(mdef); bitvec_set (lc_active, ci); for (ci = 0, n_lc = 0; ci < mdef_n_ciphone(mdef); ci++) { if (bitvec_is_set (lc_active, ci)) lc[n_lc++] = ci; } lc[n_lc] = BAD_S3CIPID; E_INFO("Building lextrees\n"); /* Get the number of lexical tree*/ kb->n_lextree = cmd_ln_int32 ("-Nlextree"); if (kb->n_lextree < 1) { E_ERROR("No. of ugtrees specified: %d; will instantiate 1 ugtree\n", kb->n_lextree); kb->n_lextree = 1; } /* ARCHAN: This code was rearranged in s3.4 implementation of dynamic LM */ /* Build active word list */ wp = (wordprob_t *) ckd_calloc (dict_size(dict), sizeof(wordprob_t)); if(lmset){ kb->ugtreeMulti = (lextree_t **) ckd_calloc (kbcore_nlm(kbcore)*kb->n_lextree, sizeof(lextree_t *)); /* Just allocate pointers*/ kb->ugtree = (lextree_t **) ckd_calloc (kb->n_lextree, sizeof(lextree_t *)); for(i=0;i<kbcore_nlm(kbcore);i++){ E_INFO("Creating Unigram Table for lm %d name %s\n",i,lmset[i].name); n=0; for(j=0;j<dict_size(dict);j++){ /*try to be very careful again */ wp[j].wid=-1; wp[j].prob=-1; } n = lm_ug_wordprob (lmset[i].lm, dict,MAX_NEG_INT32, wp); E_INFO("Size of word table after unigram + words in class: %d.\n",n); if (n < 1) E_FATAL("%d active words in %s\n", n,lmset[i].name); n = wid_wordprob2alt(dict,wp,n); E_INFO("Size of word table after adding alternative prons: %d.\n",n); if (cmd_ln_int32("-treeugprob") == 0) { for (i = 0; i < n; i++) wp[i].prob = -1; /* Flatten all initial probabilities */ } for (j = 0; j < kb->n_lextree; j++) { kb->ugtreeMulti[i*kb->n_lextree+j] = lextree_build (kbcore, wp, n, lc); lextree_type (kb->ugtreeMulti[i*kb->n_lextree+j]) = 0; E_INFO("Lextrees (%d) for lm %d name %s, %d nodes(ug)\n", kb->n_lextree, i, lmset[i].name,lextree_n_node(kb->ugtreeMulti[i*kb->n_lextree+j])); } } }else if (lm){ E_INFO("Creating Unigram Table\n"); n=0; n = lm_ug_wordprob (lm, dict,MAX_NEG_INT32, wp); E_INFO("Size of word table after unigram + words in class: %d\n",n); if (n < 1) E_FATAL("%d active words\n", n); n = wid_wordprob2alt (dict, wp, n); /* Add alternative pronunciations */ /* Retain or remove unigram probs from lextree, depending on option */ if (cmd_ln_int32("-treeugprob") == 0) { for (i = 0; i < n; i++) wp[i].prob = -1; /* Flatten all initial probabilities */ } /* Create the desired no. of unigram lextrees */ kb->ugtree = (lextree_t **) ckd_calloc (kb->n_lextree, sizeof(lextree_t *)); for (i = 0; i < kb->n_lextree; i++) { kb->ugtree[i] = lextree_build (kbcore, wp, n, lc); lextree_type (kb->ugtree[i]) = 0; } E_INFO("Lextrees(%d), %d nodes(ug)\n", kb->n_lextree, lextree_n_node(kb->ugtree[0])); } /* Create filler lextrees */ /* ARCHAN : only one filler tree is supposed to be build even for dynamic LMs */ n = 0; for (i = dict_filler_start(dict); i <= dict_filler_end(dict); i++) { if (dict_filler_word(dict, i)) { wp[n].wid = i; wp[n].prob = fillpen (kbcore->fillpen, i); n++; } } kb->fillertree = (lextree_t **)ckd_calloc(kb->n_lextree,sizeof(lextree_t*)); for (i = 0; i < kb->n_lextree; i++) { kb->fillertree[i] = lextree_build (kbcore, wp, n, NULL); lextree_type (kb->fillertree[i]) = -1; } ckd_free ((void *) wp); ckd_free ((void *) lc); bitvec_free (lc_active); E_INFO("Lextrees(%d), %d nodes(filler)\n", kb->n_lextree, lextree_n_node(kb->fillertree[0])); if (cmd_ln_int32("-lextreedump")) { if(lmset){ E_FATAL("Currently, doesn't support -lextreedump for multiple-LMs\n"); } for (i = 0; i < kb->n_lextree; i++) { fprintf (stderr, "UGTREE %d\n", i); lextree_dump (kb->ugtree[i], dict, stderr); } for (i = 0; i < kb->n_lextree; i++) { fprintf (stderr, "FILLERTREE %d\n", i); lextree_dump (kb->fillertree[i], dict, stderr); } fflush (stderr); } kb->ascr = ascr_init (mgau_n_mgau(kbcore_mgau(kbcore)), kbcore->dict2pid->n_comstate); kb->beam = beam_init (cmd_ln_float64("-subvqbeam"), cmd_ln_float64("-beam"), cmd_ln_float64("-pbeam"), cmd_ln_float64("-wbeam")); E_INFO("Beam= %d, PBeam= %d, WBeam= %d, SVQBeam= %d\n", kb->beam->hmm, kb->beam->ptrans, kb->beam->word, kb->beam->subvq); /*Sections of optimization related parameters*/ kb->ds_ratio=cmd_ln_int32("-ds"); E_INFO("Down Sampling Ratio = %d\n",kb->ds_ratio); kb->rec_bstcid=-1; kb->skip_count=0; kb->cond_ds=cmd_ln_int32("-cond_ds"); E_INFO("Conditional Down Sampling Parameter = %d\n",kb->cond_ds); if(kb->cond_ds>0&&kb->kbcore->gs==NULL) E_FATAL("Conditional Down Sampling require the use of Gaussian Selection map\n"); kb->gs4gs=cmd_ln_int32("-gs4gs"); E_INFO("GS map would be used for Gaussian Selection? = %d\n",kb->gs4gs); kb->svq4svq=cmd_ln_int32("-svq4svq"); E_INFO("SVQ would be used as Gaussian Score ?= %d\n",kb->svq4svq); kb->ci_pbeam=-1*logs3(cmd_ln_float32("-ci_pbeam")); E_INFO("CI phone beam to prune the number of parent CI phones in CI-base GMM Selection = %d\n",kb->ci_pbeam); if(kb->ci_pbeam>10000000){ E_INFO("Virtually no CI phone beam is applied now. (ci_pbeam>1000000)\n"); } kb->wend_beam=-1*logs3(cmd_ln_float32("-wend_beam")); E_INFO("Word-end pruning beam: %d\n",kb->wend_beam); kb->pl_window=cmd_ln_int32("-pl_window"); E_INFO("Phoneme look-ahead window size = %d\n",kb->pl_window); kb->pl_window_start=0; kb->pl_beam=logs3(cmd_ln_float32("-pl_beam")); E_INFO("Phoneme look-ahead beam = %d\n",kb->pl_beam); for(cisencnt=0;cisencnt==mdef->cd2cisen[cisencnt];cisencnt++) ; kb->cache_ci_senscr=(int32**)ckd_calloc_2d(kb->pl_window,cisencnt,sizeof(int32)); kb->cache_best_list=(int32*)ckd_calloc(kb->pl_window,sizeof(int32)); kb->phn_heur_list=(int32*)ckd_calloc(mdef_n_ciphone (mdef),sizeof(int32)); if ((kb->feat = feat_array_alloc(kbcore_fcb(kbcore),S3_MAX_FRAMES)) == NULL) E_FATAL("feat_array_alloc() failed\n"); kb->vithist = vithist_init(kbcore, kb->beam->word, cmd_ln_int32("-bghist")); ptmr_init (&(kb->tm_sen)); ptmr_init (&(kb->tm_srch)); ptmr_init (&(kb->tm_ovrhd)); kb->tot_fr = 0; kb->tot_sen_eval = 0.0; kb->tot_gau_eval = 0.0; kb->tot_hmm_eval = 0.0; kb->tot_wd_exit = 0.0; kb->hmm_hist_binsize = cmd_ln_int32("-hmmhistbinsize"); if(lmset) n = ((kb->ugtreeMulti[0]->n_node) + (kb->fillertree[0]->n_node)) * kb->n_lextree; else n = ((kb->ugtree[0]->n_node) + (kb->fillertree[0]->n_node)) * kb->n_lextree; n /= kb->hmm_hist_binsize; kb->hmm_hist_bins = n+1; kb->hmm_hist = (int32 *) ckd_calloc (n+1, sizeof(int32)); /* Really no need for +1 */ /* Open hypseg file if specified */ str = cmd_ln_str("-hypseg"); kb->matchsegfp = NULL; if (str) { #ifdef SPEC_CPU_WINDOWS if ((kb->matchsegfp = fopen(str, "wt")) == NULL) #else if ((kb->matchsegfp = fopen(str, "w")) == NULL) #endif E_ERROR("fopen(%s,w) failed; use FWDXCT: from std logfile\n", str); } str = cmd_ln_str("-hyp"); kb->matchfp = NULL; if (str) { #ifdef SPEC_CPU_WINDOWS if ((kb->matchfp = fopen(str, "wt")) == NULL) #else if ((kb->matchfp = fopen(str, "w")) == NULL) #endif E_ERROR("fopen(%s,w) failed; use FWDXCT: from std logfile\n", str); } }
void kb_init (kb_t *kb) { kbcore_t *kbcore; mdef_t *mdef; dict_t *dict; dict2pid_t *d2p; lm_t *lm; s3cipid_t sil, ci; s3wid_t w; int32 i, n, n_lc; wordprob_t *wp; s3cipid_t *lc; bitvec_t lc_active; char *str; /* Initialize the kb structure to zero, just in case */ memset(kb, 0, sizeof(*kb)); kb->kbcore = kbcore_init (cmd_ln_float32 ("-logbase"), "1s_c_d_dd", /* Hack!! Hardwired constant for -feat argument */ cmd_ln_str("-cmn"), cmd_ln_str("-varnorm"), cmd_ln_str("-agc"), cmd_ln_str("-mdef"), cmd_ln_str("-dict"), cmd_ln_str("-fdict"), "", /* Hack!! Hardwired constant for -compsep argument */ cmd_ln_str("-lm"), cmd_ln_str("-fillpen"), cmd_ln_float32("-silprob"), cmd_ln_float32("-fillprob"), cmd_ln_float32("-lw"), cmd_ln_float32("-wip"), cmd_ln_float32("-uw"), cmd_ln_str("-mean"), cmd_ln_str("-var"), cmd_ln_float32("-varfloor"), cmd_ln_str("-mixw"), cmd_ln_float32("-mixwfloor"), cmd_ln_str("-subvq"), cmd_ln_str("-tmat"), cmd_ln_float32("-tmatfloor")); kbcore = kb->kbcore; mdef = kbcore_mdef(kbcore); dict = kbcore_dict(kbcore); lm = kbcore_lm(kbcore); d2p = kbcore_dict2pid(kbcore); if (NOT_S3WID(dict_startwid(dict)) || NOT_S3WID(dict_finishwid(dict))) E_FATAL("%s or %s not in dictionary\n", S3_START_WORD, S3_FINISH_WORD); if (NOT_S3LMWID(lm_startwid(lm)) || NOT_S3LMWID(lm_finishwid(lm))) E_FATAL("%s or %s not in LM\n", S3_START_WORD, S3_FINISH_WORD); /* Check that HMM topology restrictions are not violated */ if (tmat_chk_1skip (kbcore->tmat) < 0) E_FATAL("Tmat contains arcs skipping more than 1 state\n"); /* * Unlink <s> and </s> between dictionary and LM, to prevent their * recognition. They are merely dummy words (anchors) at the beginning * and end of each utterance. */ lm_lmwid2dictwid(lm, lm_startwid(lm)) = BAD_S3WID; lm_lmwid2dictwid(lm, lm_finishwid(lm)) = BAD_S3WID; for (w = dict_startwid(dict); IS_S3WID(w); w = dict_nextalt(dict, w)) kbcore->dict2lmwid[w] = BAD_S3LMWID; for (w = dict_finishwid(dict); IS_S3WID(w); w = dict_nextalt(dict, w)) kbcore->dict2lmwid[w] = BAD_S3LMWID; sil = mdef_silphone (kbcore_mdef (kbcore)); if (NOT_S3CIPID(sil)) E_FATAL("Silence phone '%s' not in mdef\n", S3_SILENCE_CIPHONE); E_INFO("Building lextrees\n"); kb->sen_active = (int32 *) ckd_calloc (mdef_n_sen(mdef), sizeof(int32)); kb->ssid_active = (int32 *) ckd_calloc (mdef_n_sseq(mdef), sizeof(int32)); kb->comssid_active = (int32 *) ckd_calloc (dict2pid_n_comsseq(d2p), sizeof(int32)); /* Build active word list */ wp = (wordprob_t *) ckd_calloc (dict_size(dict), sizeof(wordprob_t)); n = lm_ug_wordprob (lm, MAX_NEG_INT32, wp); if (n < 1) E_FATAL("%d active words\n", n); n = wid_wordprob2alt (dict, wp, n); /* Add alternative pronunciations */ /* Retain or remove unigram probs from lextree, depending on option */ if (cmd_ln_int32("-treeugprob") == 0) { for (i = 0; i < n; i++) wp[i].prob = -1; /* Flatten all initial probabilities */ } /* Build set of all possible left contexts */ lc = (s3cipid_t *) ckd_calloc (mdef_n_ciphone(mdef) + 1, sizeof(s3cipid_t)); lc_active = bitvec_alloc (mdef_n_ciphone (mdef)); for (w = 0; w < dict_size (dict); w++) { ci = dict_pron (dict, w, dict_pronlen(dict, w) - 1); if (! mdef_is_fillerphone (mdef, (int)ci)) bitvec_set (lc_active, ci); } ci = mdef_silphone(mdef); bitvec_set (lc_active, ci); for (ci = 0, n_lc = 0; ci < mdef_n_ciphone(mdef); ci++) { if (bitvec_is_set (lc_active, ci)) lc[n_lc++] = ci; } lc[n_lc] = BAD_S3CIPID; /* Create the desired no. of unigram lextrees */ kb->n_lextree = cmd_ln_int32 ("-Nlextree"); if (kb->n_lextree < 1) { E_ERROR("No. of ugtrees specified: %d; will instantiate 1 ugtree\n", kb->n_lextree); kb->n_lextree = 1; } kb->ugtree = (lextree_t **) ckd_calloc (kb->n_lextree, sizeof(lextree_t *)); for (i = 0; i < kb->n_lextree; i++) { kb->ugtree[i] = lextree_build (kbcore, wp, n, lc); lextree_type (kb->ugtree[i]) = 0; } bitvec_free (lc_active); ckd_free ((void *) lc); /* Create filler lextrees */ n = 0; for (i = dict_filler_start(dict); i <= dict_filler_end(dict); i++) { if (dict_filler_word(dict, i)) { wp[n].wid = i; wp[n].prob = fillpen (kbcore->fillpen, i); n++; } } kb->fillertree = (lextree_t **)ckd_calloc(kb->n_lextree,sizeof(lextree_t*)); for (i = 0; i < kb->n_lextree; i++) { kb->fillertree[i] = lextree_build (kbcore, wp, n, NULL); lextree_type (kb->fillertree[i]) = -1; } ckd_free ((void *) wp); E_INFO("Lextrees(%d), %d nodes(ug), %d nodes(filler)\n", kb->n_lextree, lextree_n_node(kb->ugtree[0]), lextree_n_node(kb->fillertree[0])); if (cmd_ln_int32("-lextreedump")) { for (i = 0; i < kb->n_lextree; i++) { fprintf (stderr, "UGTREE %d\n", i); lextree_dump (kb->ugtree[i], dict, stderr); } for (i = 0; i < kb->n_lextree; i++) { fprintf (stderr, "FILLERTREE %d\n", i); lextree_dump (kb->fillertree[i], dict, stderr); } fflush (stderr); } kb->ascr = ascr_init (mgau_n_mgau(kbcore_mgau(kbcore)), kbcore->dict2pid->n_comstate); kb->beam = beam_init (cmd_ln_float64("-subvqbeam"), cmd_ln_float64("-beam"), cmd_ln_float64("-pbeam"), cmd_ln_float64("-wbeam")); E_INFO("Beam= %d, PBeam= %d, WBeam= %d, SVQBeam= %d\n", kb->beam->hmm, kb->beam->ptrans, kb->beam->word, kb->beam->subvq); if ((kb->feat = feat_array_alloc(kbcore_fcb(kbcore),S3_MAX_FRAMES)) == NULL) E_FATAL("feat_array_alloc() failed\n"); kb->vithist = vithist_init(kbcore, kb->beam->word, cmd_ln_int32("-bghist")); ptmr_init (&(kb->tm_sen)); ptmr_init (&(kb->tm_srch)); kb->tot_fr = 0; kb->tot_sen_eval = 0.0; kb->tot_gau_eval = 0.0; kb->tot_hmm_eval = 0.0; kb->tot_wd_exit = 0.0; kb->hmm_hist_binsize = cmd_ln_int32("-hmmhistbinsize"); n = ((kb->ugtree[0]->n_node) + (kb->fillertree[0]->n_node)) * kb->n_lextree; n /= kb->hmm_hist_binsize; kb->hmm_hist_bins = n+1; kb->hmm_hist = (int32 *) ckd_calloc (n+1, sizeof(int32)); /* Really no need for +1 */ /* Open hypseg file if specified */ str = cmd_ln_str("-hypseg"); kb->matchsegfp = NULL; if (str) { #ifdef WIN32 if ((kb->matchsegfp = fopen(str, "wt")) == NULL) #else if ((kb->matchsegfp = fopen(str, "w")) == NULL) #endif E_ERROR("fopen(%s,w) failed; use FWDXCT: from std logfile\n", str); } }
/* * Find Viterbi alignment. */ static void align_utt(char *sent, /* In: Reference transcript */ int32 nfr, /* In: #frames of input */ char *ctlspec, /* In: Utt specifiction from control file */ char *uttid) { /* In: Utterance id, for logging and other use */ int32 i; align_stseg_t *stseg; align_phseg_t *phseg; align_wdseg_t *wdseg; int32 w; w = feat_window_size(kbcore_fcb(kbc)); /* #MFC vectors needed on either side of current frame to compute one feature vector */ if (nfr <= (w << 1)) { E_ERROR("Utterance %s < %d frames (%d); ignored\n", uttid, (w << 1) + 1, nfr); return; } ptmr_reset_all(timers); ptmr_reset(&tm_utt); ptmr_start(&tm_utt); ptmr_reset(&tm_ovrhd); ptmr_start(&tm_ovrhd); ptmr_start(timers + tmr_utt); if (align_build_sent_hmm(sent, cmd_ln_int32_r(kbc->config, "-insert_sil")) != 0) { align_destroy_sent_hmm(); ptmr_stop(timers + tmr_utt); E_ERROR("No sentence HMM; no alignment for %s\n", uttid); return; } align_start_utt(uttid); for (i = 0; i < nfr; i++) { ptmr_start(timers + tmr_utt); /* Obtain active senone flags */ ptmr_start(timers + tmr_gauden); ptmr_start(timers + tmr_senone); align_sen_active(ascr->sen_active, ascr->n_sen); /* Bah, there ought to be a function for this. */ if (kbc->ms_mgau) { ms_cont_mgau_frame_eval(ascr, kbc->ms_mgau, kbc->mdef, feat[i], i); } else if (kbc->s2_mgau) { s2_semi_mgau_frame_eval(kbc->s2_mgau, ascr, fastgmm, feat[i], i); } else if (kbc->mgau) { approx_cont_mgau_ci_eval(kbcore_svq(kbc), kbcore_gs(kbc), kbcore_mgau(kbc), fastgmm, kbc->mdef, feat[i][0], ascr->cache_ci_senscr[0], &(ascr->cache_best_list[0]), i, kbcore_logmath(kbc)); approx_cont_mgau_frame_eval(kbcore_mdef(kbc), kbcore_svq(kbc), kbcore_gs(kbc), kbcore_mgau(kbc), fastgmm, ascr, feat[i][0], i, ascr-> cache_ci_senscr[0], &tm_ovrhd, kbcore_logmath(kbc)); } ptmr_stop(timers + tmr_gauden); ptmr_stop(timers + tmr_senone); /* Step alignment one frame forward */ ptmr_start(timers + tmr_align); align_frame(ascr->senscr); ptmr_stop(timers + tmr_align); ptmr_stop(timers + tmr_utt); } ptmr_stop(&tm_utt); ptmr_stop(&tm_ovrhd); printf("\n"); /* Wind up alignment for this utterance */ if (align_end_utt(&stseg, &phseg, &wdseg) < 0) E_ERROR("Final state not reached; no alignment for %s\n\n", uttid); else { if (s2stsegdir) write_s2stseg(s2stsegdir, stseg, uttid, ctlspec, cmd_ln_boolean_r(kbc->config, "-s2cdsen")); if (stsegdir) write_stseg(stsegdir, stseg, uttid, ctlspec); if (phsegdir) write_phseg(phsegdir, phseg, uttid, ctlspec); if (phlabdir) write_phlab(phlabdir, phseg, uttid, ctlspec, cmd_ln_int32_r(kbc->config, "-frate")); if (wdsegdir) write_wdseg(wdsegdir, wdseg, uttid, ctlspec); if (outsentfp) write_outsent(outsentfp, wdseg, uttid); if (outctlfp) write_outctl(outctlfp, ctlspec); } align_destroy_sent_hmm(); ptmr_print_all(stdout, timers, nfr * 0.1); printf ("EXECTIME: %5d frames, %7.2f sec CPU, %6.2f xRT; %7.2f sec elapsed, %6.2f xRT\n", nfr, tm_utt.t_cpu, tm_utt.t_cpu * 100.0 / nfr, tm_utt.t_elapsed, tm_utt.t_elapsed * 100.0 / nfr); tot_nfr += nfr; }
/* Update kb w/ new dictionary and new LM. * assumes: single-LM kbcore (before & after) * requires: updating kbcore * Lucian Galescu, 08/11/2005 */ void kb_update_lm(kb_t *kb, char *dictfile, char *lmfile) { kbcore_t *kbcore; mdef_t *mdef; dict_t *dict; dict2pid_t *d2p; lm_t *lm; s3cipid_t ci; s3wid_t w; int32 i, n, n_lc; wordprob_t *wp; s3cipid_t *lc; bitvec_t lc_active; /*** clean up ***/ vithist_t *vithist = kb->vithist; if (kb->fillertree) ckd_free ((void *)kb->fillertree); if (kb->hmm_hist) ckd_free ((void *)kb->hmm_hist); /* vithist */ if (vithist) { ckd_free ((void *) vithist->entry); ckd_free ((void *) vithist->frame_start); ckd_free ((void *) vithist->bestscore); ckd_free ((void *) vithist->bestvh); ckd_free ((void *) vithist->lms2vh_root); ckd_free ((void *) kb->vithist); } /*** re-initialize ***/ kb->kbcore = kbcore_update_lm(kb->kbcore, dictfile, cmd_ln_str("-fdict"), "", /* Hack!! Hardwired constant for -compsep argument */ lmfile, cmd_ln_str("-fillpen"), cmd_ln_float32("-silprob"), cmd_ln_float32("-fillprob"), cmd_ln_float32("-lw"), cmd_ln_float32("-wip"), cmd_ln_float32("-uw")); if(kb->kbcore==NULL){ E_FATAL("Updating kbcore failed\n"); } kbcore = kb->kbcore; mdef = kbcore_mdef(kbcore); dict = kbcore_dict(kbcore); lm = kbcore_lm(kbcore); d2p = kbcore_dict2pid(kbcore); if (NOT_S3WID(dict_startwid(dict)) || NOT_S3WID(dict_finishwid(dict))) E_FATAL("%s or %s not in dictionary\n", S3_START_WORD, S3_FINISH_WORD); if(lm){ if (NOT_S3LMWID(lm_startwid(lm)) || NOT_S3LMWID(lm_finishwid(lm))) E_FATAL("%s or %s not in LM\n", S3_START_WORD, S3_FINISH_WORD); } /* * Unlink <s> and </s> between dictionary and LM, to prevent their * recognition. They are merely dummy words (anchors) at the beginning * and end of each utterance. */ if(lm){ lm_lmwid2dictwid(lm, lm_startwid(lm)) = BAD_S3WID; lm_lmwid2dictwid(lm, lm_finishwid(lm)) = BAD_S3WID; for (w = dict_startwid(dict); IS_S3WID(w); w = dict_nextalt(dict, w)) kbcore->dict2lmwid[w] = BAD_S3LMWID; for (w = dict_finishwid(dict); IS_S3WID(w); w = dict_nextalt(dict, w)) kbcore->dict2lmwid[w] = BAD_S3LMWID; } /* Build set of all possible left contexts */ lc = (s3cipid_t *) ckd_calloc (mdef_n_ciphone(mdef) + 1, sizeof(s3cipid_t)); lc_active = bitvec_alloc (mdef_n_ciphone (mdef)); for (w = 0; w < dict_size (dict); w++) { ci = dict_pron (dict, w, dict_pronlen(dict, w) - 1); if (! mdef_is_fillerphone (mdef, (int)ci)) bitvec_set (lc_active, ci); } ci = mdef_silphone(mdef); bitvec_set (lc_active, ci); for (ci = 0, n_lc = 0; ci < mdef_n_ciphone(mdef); ci++) { if (bitvec_is_set (lc_active, ci)) lc[n_lc++] = ci; } lc[n_lc] = BAD_S3CIPID; E_INFO("Building lextrees\n"); /* Get the number of lexical tree*/ kb->n_lextree = cmd_ln_int32 ("-Nlextree"); if (kb->n_lextree < 1) { E_ERROR("No. of ugtrees specified: %d; will instantiate 1 ugtree\n", kb->n_lextree); kb->n_lextree = 1; } /* ARCHAN: This code was rearranged in s3.4 implementation of dynamic LM */ /* Build active word list */ wp = (wordprob_t *) ckd_calloc (dict_size(dict), sizeof(wordprob_t)); if (lm) { E_INFO("Creating Unigram Table\n"); n=0; n = lm_ug_wordprob (lm, dict, MAX_NEG_INT32, wp); E_INFO("Size of word table after unigram + words in class: %d\n",n); if (n < 1) E_FATAL("%d active words\n", n); n = wid_wordprob2alt (dict, wp, n); /* Add alternative pronunciations */ /* Retain or remove unigram probs from lextree, depending on option */ if (cmd_ln_int32("-treeugprob") == 0) { for (i = 0; i < n; i++) wp[i].prob = -1; /* Flatten all initial probabilities */ } /* Create the desired no. of unigram lextrees */ kb->ugtree = (lextree_t **) ckd_calloc (kb->n_lextree, sizeof(lextree_t *)); for (i = 0; i < kb->n_lextree; i++) { kb->ugtree[i] = lextree_build (kbcore, wp, n, lc); lextree_type (kb->ugtree[i]) = 0; } E_INFO("Lextrees(%d), %d nodes(ug)\n", kb->n_lextree, lextree_n_node(kb->ugtree[0])); } /* Create filler lextrees */ /* ARCHAN : only one filler tree is supposed to be build even for dynamic LMs */ n = 0; for (i = dict_filler_start(dict); i <= dict_filler_end(dict); i++) { if (dict_filler_word(dict, i)) { wp[n].wid = i; wp[n].prob = fillpen (kbcore->fillpen, i); n++; } } kb->fillertree = (lextree_t **)ckd_calloc(kb->n_lextree,sizeof(lextree_t*)); for (i = 0; i < kb->n_lextree; i++) { kb->fillertree[i] = lextree_build (kbcore, wp, n, NULL); lextree_type (kb->fillertree[i]) = -1; } ckd_free ((void *) wp); ckd_free ((void *) lc); bitvec_free (lc_active); E_INFO("Lextrees(%d), %d nodes(filler)\n", kb->n_lextree, lextree_n_node(kb->fillertree[0])); if (cmd_ln_int32("-lextreedump")) { for (i = 0; i < kb->n_lextree; i++) { fprintf (stderr, "UGTREE %d\n", i); lextree_dump (kb->ugtree[i], dict, stderr); } for (i = 0; i < kb->n_lextree; i++) { fprintf (stderr, "FILLERTREE %d\n", i); lextree_dump (kb->fillertree[i], dict, stderr); } fflush (stderr); } kb->ascr = ascr_init (mgau_n_mgau(kbcore_mgau(kbcore)), kbcore->dict2pid->n_comstate); kb->vithist = vithist_init(kbcore, kb->beam->word, cmd_ln_int32("-bghist")); kb->hmm_hist_binsize = cmd_ln_int32("-hmmhistbinsize"); n = ((kb->ugtree[0]->n_node) + (kb->fillertree[0]->n_node)) * kb->n_lextree; n /= kb->hmm_hist_binsize; kb->hmm_hist_bins = n+1; kb->hmm_hist = (int32 *) ckd_calloc (n+1, sizeof(int32)); /* Really no need for +1 */ }
int srch_FLAT_FWD_init(kb_t * kb, /**< The KB */ void *srch /**< The pointer to a search structure */ ) { srch_FLAT_FWD_graph_t *fwg; kbcore_t *kbc; srch_t *s; mdef_t *mdef; dict_t *dict; lm_t *lm; kbc = kb->kbcore; s = (srch_t *) srch; mdef = kbcore_mdef(kbc); dict = kbcore_dict(kbc); lm = kbcore_lm(kbc); fwg = ckd_calloc(1, sizeof(srch_FLAT_FWD_graph_t)); E_INFO("Initialization\n"); /** For convenience */ fwg->kbcore = s->kbc; /* Allocate whmm structure */ fwg->hmmctx = hmm_context_init(mdef_n_emit_state(mdef), kbcore_tmat(kbc)->tp, NULL, mdef->sseq); fwg->whmm = (whmm_t **) ckd_calloc(dict->n_word, sizeof(whmm_t *)); /* Data structures needed during word transition */ /* These five things need to be tied into the same structure. Such that when multiple LM they could be switched. */ fwg->rcscore = NULL; fwg->rcscore = (int32 *) ckd_calloc(mdef->n_ciphone, sizeof(int32)); fwg->ug_backoff = (backoff_t *) ckd_calloc(mdef->n_ciphone, sizeof(backoff_t)); fwg->filler_backoff = (backoff_t *) ckd_calloc(mdef->n_ciphone, sizeof(backoff_t)); fwg->tg_trans_done = (uint8 *) ckd_calloc(dict->n_word, sizeof(uint8)); fwg->word_ugprob = init_word_ugprob(mdef, lm, dict); /* Input candidate-word lattices information to restrict search; if any */ fwg->word_cand_dir = cmd_ln_str_r(kbcore_config(fwg->kbcore), "-inlatdir"); fwg->latfile_ext = cmd_ln_str_r(kbcore_config(fwg->kbcore), "-latext"); fwg->word_cand_win = cmd_ln_int32_r(kbcore_config(fwg->kbcore), "-inlatwin"); if (fwg->word_cand_win < 0) { E_ERROR("Invalid -inlatwin argument: %d; set to 50\n", fwg->word_cand_win); fwg->word_cand_win = 50; } /* Allocate pointers to lists of word candidates in each frame */ if (fwg->word_cand_dir) { fwg->word_cand = (word_cand_t **) ckd_calloc(S3_MAX_FRAMES, sizeof(word_cand_t *)); fwg->word_cand_cf = (s3wid_t *) ckd_calloc(dict->n_word + 1, sizeof(s3wid_t)); } /* Initializing debugging information such as trace_wid, word_dump_sf, word_dump_ef, hmm_dump_sf and hmm_dump_ef */ fwg->fwdDBG = init_fwd_dbg(fwg); fwg->ctr_mpx_whmm = pctr_new("mpx"); fwg->ctr_nonmpx_whmm = pctr_new("~mpx"); fwg->ctr_latentry = pctr_new("lat"); /** Initialize the context table */ fwg->ctxt = ctxt_table_init(kbcore_dict(kbc), kbcore_mdef(kbc)); /* Viterbi history structure */ fwg->lathist = latticehist_init(cmd_ln_int32_r(kbcore_config(fwg->kbcore), "-bptblsize"), S3_MAX_FRAMES + 1); /* Glue the graph structure */ s->grh->graph_struct = fwg; s->grh->graph_type = GRAPH_STRUCT_FLAT; return SRCH_SUCCESS; }
void gmm_compute(void *data, utt_res_t * ur, int32 sf, int32 ef, char *uttid) { kb_t *kb; kbcore_t *kbcore; mdef_t *mdef; dict_t *dict; dict2pid_t *d2p; mgau_model_t *mgau; subvq_t *svq; gs_t *gs; int32 ptranskip; int32 s, f, t; int32 single_el_list[2]; stats_t cur_ci_st; stats_t cur_cd_st; stats_t cur_cd_Nbest_st; stats_t *stptr; char str[100]; int32 *idx; int32 *cur_bstidx; int32 *last_bstidx; int32 *cur_scr; int32 *last_scr; int32 tmpint; s3senid_t *cd2cisen; int32 pheurtype; E_INFO("Processing: %s\n", uttid); kb = (kb_t *) data; kbcore = kb->kbcore; mdef = kbcore_mdef(kbcore); dict = kbcore_dict(kbcore); d2p = kbcore_dict2pid(kbcore); mgau = kbcore_mgau(kbcore); svq = kbcore_svq(kbcore); gs = kbcore_gs(kbcore); kb->uttid = uttid; ptranskip = kb->beam->ptranskip; pheurtype = kb->pl->pheurtype; single_el_list[0] = -1; single_el_list[1] = -1; /* Read mfc file and build feature vectors for entire utterance */ kb->stat->nfr = feat_s2mfc2feat(kbcore_fcb(kbcore), ur->uttfile, cmd_ln_str("-cepdir"), ".mfc", sf, ef, kb->feat, S3_MAX_FRAMES); cd2cisen = mdef_cd2cisen(mdef); /*This should be a procedure instead of just logic */ init_stat(&cur_cd_st, "Current CD Senone"); init_stat(&cur_ci_st, "Current CI Senone"); init_stat(&cur_cd_Nbest_st, "Current CD NBest Senone"); for (s = 0; s < mdef->n_ci_sen; s++) { sprintf(str, "Cur Senone %d", s); init_stat(&cur_sen_st[s], str); } for (t = 0; t < (int32) (mdef->n_sen - mdef->n_ci_sen) / NBEST_STEP; t++) { sprintf(str, " %d -Cur Best Senone", t * NBEST_STEP); init_stat(&cur_sen_Nbest_st[t], str); } idx = ckd_calloc(mdef->n_sen - mdef->n_ci_sen, sizeof(int32)); /* Allocate temporary array for CurScr and Curbst indx and Lat index */ cur_bstidx = ckd_calloc(mdef->n_sen, sizeof(int32)); last_bstidx = ckd_calloc(mdef->n_sen, sizeof(int32)); cur_scr = ckd_calloc(mdef->n_sen, sizeof(int32)); last_scr = ckd_calloc(mdef->n_sen, sizeof(int32)); for (f = 0; f < kb->stat->nfr; f++) { for (s = 0; s < mgau->n_mgau; s++) { /*1, Compute the approximate scores with the last best index. */ if (mgau->mgau[s].bstidx != NO_BSTIDX) { single_el_list[0] = mgau->mgau[s].bstidx; last_bstidx[s] = mgau->mgau[s].bstidx; last_scr[s] = mgau_eval(mgau, s, single_el_list, kb->feat[f][0], f, 0); } else { last_bstidx[s] = NO_BSTIDX; } /*2, Compute the exact scores and sort them and get the ranking. */ kb->ascr->senscr[s] = mgau_eval(mgau, s, NULL, kb->feat[f][0], f, 1); /*3, Compute the approximate scores with the current best index */ if (mgau->mgau[s].bstidx != NO_BSTIDX) { single_el_list[0] = mgau->mgau[s].bstidx; cur_bstidx[s] = mgau->mgau[s].bstidx; cur_scr[s] = mgau_eval(mgau, s, single_el_list, kb->feat[f][0], f, 0); } else { cur_bstidx[s] = NO_BSTIDX; } /* Only test for CD senones, test for best index hit */ /*Update either CI senone and CD senone) */ if (!mdef_is_cisenone(mdef, s)) stptr = &cur_cd_st; else stptr = &cur_ci_st; increment_stat(stptr, abs(last_scr[s] - kb->ascr->senscr[s]), abs(cur_scr[s] - kb->ascr->senscr[s]), abs(kb->ascr->senscr[cd2cisen[s]] - kb->ascr->senscr[s]), (cur_bstidx[s] == last_bstidx[s])); if (!mdef_is_cisenone(mdef, s)) { stptr = &cur_sen_st[cd2cisen[s]]; increment_stat(stptr, abs(last_scr[s] - kb->ascr->senscr[s]), abs(cur_scr[s] - kb->ascr->senscr[s]), abs(kb->ascr->senscr[cd2cisen[s]] - kb->ascr->senscr[s]), (cur_bstidx[s] == last_bstidx[s])); stptr->total_senone += 1; } } cur_cd_st.total_fr++; cur_cd_st.total_senone += mdef->n_sen - mdef->n_ci_sen; cur_ci_st.total_fr++; cur_ci_st.total_senone += mdef->n_ci_sen; for (s = 0; s < mdef->n_ci_sen; s++) { cur_sen_st[s].total_fr++; } /*This is the part we need to do sorting */ /*1, sort the scores in the current frames */ /*E_INFO("At frame %d\n",f); */ /*Pointer trick at here. */ for (s = 0; s < mdef->n_sen - mdef->n_ci_sen; s++) { idx[s] = s; } cd = &(kb->ascr->senscr[mdef->n_ci_sen]); qsort(idx, mdef->n_sen - mdef->n_ci_sen, sizeof(int32), intcmp_gmm_compute); /*This loop is stupid and it is just a hack. */ for (s = 0; s < mdef->n_sen - mdef->n_ci_sen; s++) { tmpint = idx[s] + mdef->n_ci_sen; for (t = 0; t < (int32) ((float) (mdef->n_sen - mdef->n_ci_sen) / (float) NBEST_STEP); t++) { if (s < t * NBEST_STEP) { increment_stat(&cur_sen_Nbest_st[t], abs(last_scr[tmpint] - kb->ascr->senscr[tmpint]), abs(cur_scr[tmpint] - kb->ascr->senscr[tmpint]), abs(kb->ascr->senscr[cd2cisen[tmpint]] - kb->ascr->senscr[tmpint]), (cur_bstidx[tmpint] == last_bstidx[tmpint])); cur_sen_Nbest_st[t].total_senone += 1; } } } for (t = 0; t < (int32) ((float) (mdef->n_sen - mdef->n_ci_sen) / (float) NBEST_STEP); t++) { cur_sen_Nbest_st[t].total_fr++; } } print_stat(&cur_cd_st); print_stat(&cur_ci_st); print_stat(&cur_sen_Nbest_st[1]); /*Only show the first NBEST_STEP best */ add_stat(&cd_st, &cur_cd_st); add_stat(&ci_st, &cur_ci_st); for (s = 0; s < mdef->n_ci_sen; s++) { add_stat(&sen_st[s], &cur_sen_st[s]); } for (s = 0; s < (int32) (mdef->n_sen - mdef->n_ci_sen) / NBEST_STEP; s++) { add_stat(&sen_Nbest_st[s], &cur_sen_Nbest_st[s]); } ckd_free(idx); ckd_free(cur_bstidx); ckd_free(last_bstidx); ckd_free(cur_scr); ckd_free(last_scr); }