
    =i                        U d Z ddlZddlZddlZddlmZ ddlZddlZddlm	Z	 ddl
Z
ddlmZ ddlmZ ddlmZ  ee      j%                         j&                  d   d	z  Z	 ej+                  d
d      5 Z e
j.                  e      Zddd        eej7                  dd            j9                         Z ej<                   eeeej@                                ejB                  e"      Z#e#jI                   eeeej@                               da%ee	   e&d<   da'da(defdZ)de*ddfdZ+de,de-de-fdZ.de	fdZ/dee	   fdZ0y# 1 sw Y   xY w# e$ r i ZY w xY w)u   模型加载与全局单例管理。

职责概览：
- 按配置和运行环境选择 ASR 设备（cpu/cuda/npu）。
- 初始化并缓存全局 Qwen3ASR 模型实例。
- 对外提供 `init_model` 与 `get_model` 供接口层复用。
    N)Optional)Qwen3ASRModel)Path   )choose_device)preload_speaker_modelgzzm_config.jsonrutf-8encoding	log_levelINFO)levelMODELFreturnc                      t        t              j                         j                  dz  dz  } 	 | j	                  d      j                  d      S # t        $ r Y yw xY w)Nbrandzgzzm_ascii.txtr   r   
 )r   __file__resolveparent	read_textrstrip	Exception)banner_paths    /app/gzzm/model.py_read_startup_bannerr   (   s[    x.((*11G;>NNK$$g$6==dCC s    A 	AAtotal_secondsc           	      t   t               }|sy t        t        j                  dd            j	                         j                         dv }d| dd}|rt        t        j                  dd      xs d      j	                         }	 |j                  d	      r|d
d  }t        |      dk7  rt        d      t        |dd d      }t        |dd d      }t        |dd d      }d| d| d| d}d}	t        j                  d| d| |	 d|        y t        j                  d||       y # t        $ r d}Y Hw xY w)Ngzzm_banner_color1r#   trueyesonzstartup_time: .2fsgzzm_banner_hexz#3a96dd#r      zinvalid hexr            z[38;2;;mz[96mz[0mz%sr   z
%s
%s)r   str_GZZM_CONFIG_TOPgetstriplower
startswithlen
ValueErrorintr   loggerinfo)
r    bannercolor_enabledfooterhex_coder
   gbcolor_escaperesets
             r   _render_startup_bannerrE   0   sQ   !#F(,,-@#FGMMOUUW[uuMmC02F'++,=yIVYW]]_	&""3'#AB<8}! //HQqM2&AHQqM2&AHQqM2&A's!A3as!4L D\N"VHUG2fXFGJ/  	&%L	&s   A(D) )D76D7valuedefaultc                 \    | |S t        |       j                         j                         dv S )Nr$   )r2   r5   r6   )rF   rG   s     r   _parse_boolrI   L   s.    }u:##%)CCC    c                  $	   t        j                         } t        t              j	                         j
                  d   dz  }	 |j                  dd      5 }t        j                  |      }ddd       t        j                  dd      d	      }t        |j                  d
      xs d      j                         }t        |      }|dk(  rd}n
|dk(  rd}nd}t        a|r+t         s%	 t#        |       dat$        j'                  d|       t         r(t,        s"t/        t        j                         | z
         dat        S t        |j                  dd            j                         }	t        |j                  dd            j                         }
t$        j'                  d|	|
       t        j                          }t        |j                  d      xs d      j1                         }|}t        |      }t3        |j                  dd            }t3        |j                  dd            }|dk(  rCt$        j'                  d       d}t4        j6                  }t9        t4        j6                  d       }n`|dk(  r.d}t4        j:                  }t9        t4        j<                  d       }n-d}t4        j:                  }t9        t4        j6                  d       }t?        j@                  |	|j                  d!d"      ||dd|||
|#
      atB        jD                  jG                          t        j                          |z
  }t$        j'                  d$|d%d&       t$        j'                  d'tI        t        d(d              |r+t         s%	 t#        |       dat$        j'                  d|       t         r(t,        s"t/        t        j                         | z
         dat        S # 1 sw Y   qxY w# t        $ r i }Y w xY w# t(        $ r t$        j+                  d       Y t        $ r!}t$        j+                  d|       Y d}~2d}~ww xY w# t(        $ r t$        j+                  d       Y t        $ r }t$        j+                  d|       Y d}~d}~ww xY w))u@   加载并返回 Qwen3 ASR 模型到模块全局变量 `MODEL`。r   r	   r
   r   r   Nr   T)rG   model_device_speakerr   npuznpu:0cudazcuda:0cpu)devicez-Speaker model preloaded on startup, device=%sz;Speaker model preload skipped: speechbrain is not availablez7Speaker model preload failed, fallback to lazy load: %smodel_name_asrzQwen/Qwen3-ASR-0.6Bforced_aligner_modelzQwen/Qwen3-ForcedAligner-0.6Bu0   【开始加载 ASR 模型】model=%s aligner=%smodel_device_asrmax_inference_batch_sizer.   max_new_tokens   uX   未检测到可用 CUDA/NPU 或已指定 CPU，使用 CPU 加载模型（可能较慢）)dtype
device_maphf_cache_dirz/app/hf_cache)		cache_dirtorch_dtyperX   low_cpu_mem_usageuse_safetensorsrT   rU   forced_alignerforced_aligner_kwargsu!   ✅ 模型加载完成！耗时: r(   u    秒zforced_aligner: r^   )%timeperf_counterr   r   r   parentsopenjsonloadr   rI   r4   r2   r5   r   r   _SPEAKER_MODEL_PRELOADEDr   r;   r<   ImportErrorwarning_STARTUP_BANNER_PRINTEDrE   r6   r:   torchfloat32dictfloat16bfloat16r   from_pretrainedtransformersloggingset_verbosity_errorgetattr)init_started_at_config_path_f_GZZM_CONFIGpreload_speaker_enabledcfg_speaker_devicespeaker_primaryspeaker_deviceerQ   rR   
start_loadconfig_devicedevice_hintselected_devicerT   rU   rX   rW   r_   	load_times                        r   
init_modelr   R   s     '')O >))+33A69KKLsW599R=L 6
 *,*:*:;RTX*Ycgh \--.DEKLRRT#$67O% 	F	"!"+C]%^<+/(K^\
 $,C"4#4#4#6#HI&*#))*:<QRSYY[N|//0FHghiooq
KKBNThiJ (();<BCIIKMK#K0O  #<#3#34NPR#ST))*:C@AN%no
 $--!
 
F	"
 $..!

 
 $--!

 ))"">?C!9%+3E ,,.		j(I
KK3Ic?$GH
KK"752BD#I"JKL'?	Y!8'+$KKGX  (?t002_DE"&LU 65 *  ^\] ]XZ[\\]P  	ZNNXY 	YNNTVWXX	Ysf   O( O,O( )$O: $Q O% O( (O76O7:QQ#P??QR'R/R

Rc                      t         S )N)r    rJ   r   	get_modelr      s    LrJ   )1__doc__osr`   rq   typingr   rp   rj   qwen_asrr   rd   pathlibr   utils.device_utilsr   utils.speaker_idr   r   r   rb   _config_path_toprc   rv   re   r3   r   r2   r4   upper	LOG_LEVELbasicConfigrs   r   	getLogger__name__r;   setLevelr   __annotations__rf   ri   r   floatrE   objectboolrI   r   r   r   rJ   r   <module>r      s   
      "   - 3>))+33A69KK 			sW		5$499R= 
6
  $$[&9:@@B	   ''9gllC D			8	$ GLL9 : "&x %   c 0% 0D 08Dv D D DuM up8M* e 
6	5 s*   !E 4EE E
E EE