__all__= ['load'] import sys,threading,collections,time import TLK import lmodel,oepmodel,segmodel import logging as Log Hyp= collections.namedtuple('Hyp',['var','novar','err', 'score','nframes', 'eos']) class Recogniser: def __init__(self,models,params, # uppercase_tbl,uppercase_tbl_bi, sil_word,sil_sym,fea_freq,mng): args= { 'ifreq' : 16000, 'bsize' : 400, 'amodel' : models['amodel'], 'lm' : models['lm'], 'params' : params, 'output' : self, } self._fea_freq= fea_freq if sil_word!=None: args['sil_word']= sil_word if sil_sym!=None: args['sil_sym']= sil_sym if models['dnn']!=None: args['dnn']= models['dnn'] if models['dlm']!=None: args['dlm']= models['dlm'] if models['mustd']!=None: args['mustd']= models['mustd'] if models['oep-factory']!=None: oep= models['oep-factory'](models['oep-model']) args['oep']= oep self.reco= TLK.ORecogniser(**args) if models['seg-factory']!=None: self.seg= models['seg-factory'](models['seg-model']) else: self.seg= None self._mng= mng self._cv= threading.Condition() def reset(self): self._err= False self._hyps= [] self._prev= None if self.seg is not None: self.seg.reset() # Per a gestionar tokens insertats el que vaig a fer es tindre # una llista de llistes. En la primera llista estaran els # tokens del segment que s'està processant actualment i en # l'última els tokens de l'últim segment. Cada token serà una # tupla paraula i número de frames on es va insertar. self._itokens= [[]] self._inframes= 0.0 # Numero de frames del segment actual # insertats en el reconeixedor def __register_itoken_nosec(self,token): token= token.strip() if token=='': return nframes= int(self._inframes) if self._inframes>0.0 else None self._itokens[-1].append((token,nframes)) def __register_itoken(self,token): try: self.__register_itoken_nosec(token) except: pass def __register_itoken_eos(self): if self._inframes>0.0: self._itokens.append([]) self._inframes= 0.0 def __merge_itokens_nosec(self,code,hyp): # Comprovacions inicials i eliminació itokens= self._itokens[0] if code==TLK.OUT_RES: self._itokens.pop(0) if itokens==[]: return hyp # Inserta hyp,pos_var= hyp[0],hyp[1] pref,novar,var= [],list(hyp[:pos_var]),list(hyp[pos_var:]) # -> Inserta inici segment while len(itokens)>0 and itokens[0][1] is None: tok= itokens.pop(0) pref.append((tok[0],0,0)) # --> Processa novar if len(itokens)>0 and len(novar)>0: i,new_novar= 0,[] while len(itokens)>0 and i0 and itokens[0][1] Processa var if len(itokens)>0 and len(var)>0: i,j,new_var= 0,0,[] while len(itokens)>0 and i Afegeix pendents si code==TLK.OUT_RES if code==TLK.OUT_RES and len(itokens)>0: assert var==[] pos= new_novar[-1][1]+new_novar[-1][2] if len(new_novar)>0 else -1 for tok in itokens: tmp_pos= pos if pos!=-1 else tok[1] new_novar.append((tok[0],tmp_pos,0)) return pref+new_novar+new_var,len(pref)+len(new_novar) # end __merge_itokens_nosec def __merge_itokens(self,code,hyp): try: return self.__merge_itokens_nosec(code,hyp) except: return hyp # None denotes end of segment def feed(self,data=None): if data==None: self.reco.feed() elif not self._err: if type(data)==str: self.__register_itoken(data) elif len(data)==0: self.reco.split() self.__register_itoken_eos() else: self._inframes+= (len(data)/32000)*self._fea_freq self.reco.feed(data) def __write_hyp(self,novar,var,score,nframes,err,eos): h= Hyp(novar=novar,var=var,err=err, score=score,nframes=nframes, eos=eos) with self._cv: self._hyps.append(h) self._cv.notify_all() def process_out(self,code,hyp,stats): #def totxt(rec,last_word): # aux= [] # for x in rec: # w= x[0].lower() # aux.append(toupper(w,last_word)) # last_word= w # ret= ' '.join(aux) # ret= ret.replace('[hesitation]','').replace('','') # return ret def totxt(rec): ret= ' '.join([x[0] for x in rec]) ret= ret.replace('[hesitation]','').replace('','') return ret hyp,pos_var= hyp[0],hyp[1] novar= hyp[:pos_var] #new_last_word= novar[-1][0] if len(novar)>0 else self.last_word #novar= totxt(novar,self.last_word) #var= totxt(hyp[pos_var:],new_last_word) #self.last_word= new_last_word novar= totxt(novar) var= totxt(hyp[pos_var:]) if novar=='' and var==self._prev and code==TLK.OUT_HYP: return self._prev= var score,nframes= stats self.__write_hyp(novar,var,score,nframes,False, code==TLK.OUT_RES) # Output method def write(self,code,hyp,stats): hyp= self.__merge_itokens(code,hyp) if code==TLK.OUT_ERR: txt= self._prev if self._prev!=None else '' self.__write_hyp(txt,'',0,0,False,False) self._err= True return if code==TLK.OUT_END: self.__write_hyp(None,None,0,0,self._err,False) return if self.seg is not None: hyp= self.seg(hyp) if code==TLK.OUT_RES: hyp0,pos_var0= hyp hyp1= self.seg.eos() if hyp1 is not None: hyp1,pos_var1= hyp1 hyp= hyp0[:pos_var0]+hyp1[:pos_var1] hyp= hyp,len(hyp) self.seg.reset() self.process_out(code,hyp,stats) @property def output(self): end= False while not end: with self._cv: self._cv.wait_for(lambda: len(self._hyps)>0) ret= self._hyps.pop(0) end= ret.novar is None yield ret # end Recogniser class RecogniserManager: def __init__(self,name,tag,date,lang, models,params,nreco, sil_word,sil_sym,fea_freq): self.v= [] self.vv= [] # Reference copy #self.cmllr= params.cmllr_enabled for n in range(0,nreco): reco= Recogniser(models,params, sil_word,sil_sym, fea_freq,self) self.v.append(reco) self.vv.append(reco) self.name= name self.tag= tag self.date= date self.lang= lang self._lock= threading.Lock() self._models= models self._enabled= True def __len__(self): return len(self.vv) def get_reco(self): with self._lock: if self.v==[]: return None if not self._enabled: return None ret= self.v.pop() ret.reset() #ret.reset_cmllr() Log.info(('Recogniser taken from %s '+ '(available: %d of %d)')%(self.name, len(self.v), len(self.vv))) return ret def append(self,reco): with self._lock: self.v.append(reco) Log.info(('Recogniser from %s realeased'+ '(available: %d of %d)')%(self.name, len(self.v), len(self.vv))) def set_enabled(self,value): with self._lock: self._enabled= value @property def num_recos_available(self): with self._lock: return len(self.v) @property def enabled(self): with self._lock: return self._enabled # end RecogniserManager def prepare_params(cfg): params= TLK.OParameters() aux= cfg.get('hp') if aux!=None: params.hp= int(aux) aux= cfg.get('hp_min') if aux!=None: params.hp_min= int(aux) aux= cfg.get('wep') if aux!=None: params.wep= float(aux) aux= cfg.get('beam') if aux!=None: params.beam= float(aux) aux= cfg.get('dynormthr') if aux!=None: params.dynormthr= int(aux) aux= cfg.get('meannorm') if aux!=None: params.meannorm= bool(aux) aux= cfg.get('cmllr') if aux!=None: params.cmllr_enabled= bool(aux) aux= cfg.get('cmllr_nframes_step0') if aux!=None: params.cmllr_nframes_step0= int(aux) aux= cfg.get('cmllr_nframes') if aux!=None: params.cmllr_nframes= int(aux) aux= cfg.get('cmllr_niters') if aux!=None: params.cmllr_niters= int(aux) aux= cfg.get('numceps') if aux!=None: params.numceps= int(aux) aux= cfg.get('numchans') if aux!=None: params.numchans= int(aux) aux= cfg.get('accwindow') if aux!=None: params.accwindow= int(aux) aux= cfg.get('deltawindow') if aux!=None: params.deltawindow= int(aux) aux= cfg.get('hp_lm') if aux!=None: params.hp_lm= int(aux) aux= cfg.get('order') if aux!=None: params.order= int(aux) aux= cfg.get('ftype') if aux!=None: params.ftype= str(aux) aux= cfg.get('mustdnorm') if aux!=None: params.mustdnorm= bool(aux) aux= cfg.get('gsf') gsf= float(aux) if aux!=None else 1.0 params.gsf= gsf aux= cfg.get('wip') wip= float(aux) if aux!=None else 0.0 params.wip= wip params.amla= cfg.get('amla-fs')!=None params.sil= cfg.get('sil_sym','SP') # IMPORTANT !!!!! Deshabilita l'heurístic de segmentació params.sil_length= 20000 params.sil_thr= 0.0 return params # end prepare_params def load_models(cfg,name,params,sil_word): Log.info("Loading '%s' models..."%name) mustd= cfg.get('mustd') dnn= cfg.get('dnn') if params.cmllr_enabled: sys.exit('CMLLR NOT SUPPORTED !!!!') target= cfg.get('target') dnn_cmllr= cfg.get('dnn_cmllr') else: target= dnn_cmllr= None lexicon= cfg.get('lexicon') amodel= TLK.AModel(cfg['amodel']) if lexicon!=None: lex= TLK.Lexicon(lexicon, syms=amodel.syms) lm= TLK.LM() lm.load(cfg['lm'],lexicon=lex) else: try: lm= TLK.SearchGraph(cfg['lm'], syms=amodel.syms) except: lm= TLK.StaticLookaheadTables(cfg['lm'], syms=amodel.syms) dlm= cfg.get('dlm') if dlm!=None: dlm= lmodel.load_model(dlm)(lm.words) oep= cfg.get('oep') if oep!=None: step= cfg.get('oep-step') if step==None: sys.exit('oep-step not defined') step= int(step) lookahead= cfg.get('oep-lookahead') if lookahead==None: sys.exit('oep-lookahead not defined') lookahead= int(lookahead) priors_fn= cfg.get('oep-priors') amla_fs= cfg.get('amla-fs') tmp= oepmodel.load_model(oep,step,lookahead, priors_fn,amla_fs) oep_factory,oep_model= tmp else: oep_factory= oep_model= None seg= cfg.get('seg') if seg!=None: tmp= segmodel.load_model(seg,sil_word=sil_word) seg_factory,seg_model= tmp else: seg_factory= seg_model= None aux= cfg.get('gsf') gsf= float(aux) if aux!=None else 1.0 aux= cfg.get('wip') wip= float(aux) if aux!=None else 0.0 models= {} models["amodel"]=amodel models["lm"]=lm models["dnn"]=dnn models["gsf"]=gsf models["wip"]=wip models['dlm']= dlm models['oep-factory']= oep_factory models['oep-model']= oep_model models['mustd']= mustd models['seg-factory']= seg_factory models['seg-model']= seg_model return models # end load_models def load_system(conf): sil_word= conf.get('sil_word') sil_sym= conf.get('sil_sym') fea_freq= conf.get('fea_freq',100) params= prepare_params(conf) name= conf['id'] tag= conf.get('tag',name) date= tuple(conf.get('date',[1,1,1971])) models= load_models(conf,tag,params,sil_word) Log.info("Creating '%s' recognisers..."%name) return RecogniserManager(name,tag,date,conf['lang'], models,params,conf['nreco'], sil_word,sil_sym,fea_freq) # uppercase_tbl,uppercase_tbl_bi, # Uppercase-table (Deshabilitat de moment) #aux= cfg.get('uppercase-table') #uppercase_tbl= load_uppercase_table(aux) if aux!=None else None #aux= cfg.get('uppercase-table-bi') #uppercase_tbl_bi= load_uppercase_table_bi(aux) if aux!=None else None # end create_recognisers