
    aqjkX                         S r SSKrSSKrSSKrSSKrSSKrSSKrSSKr	SSK
r
SSKrSrSrSrSrSr\R$                  / SQ-   rS	 rS
 rS rS r\S:X  a  \" 5         gg)a  Cossim debug : C++ qwen-tts vs Python Qwen3-TTS on the Voice Clone Mode B
(ICL) path.

Inputs (relative to CWD = tests/) :
    ../examples/prompt.txt       target text fed to both pipelines
    ../examples/freeman.wav      reference audio for cloning
    ../examples/freeman.txt      transcript of the reference audio

Default mode is greedy on both sides, non_streaming_mode=False which is
the ICL branch upstream : text + codec streams are aligned to the codec
length, the shorter one padded with tts_pad / truncated as needed.

Cote Python the speaker embedding is captured directly via
model.extract_speaker_embedding, and the reference codec frames via
model.speech_tokenizer.encode. Both intermediates land as spk-emb.bin
and ref-codes.bin and are compared against the C++ side dumps emitted
by pipeline-tts.cpp when --ref-wav and --ref-text are set.

Dumps land in cpp/clone/ (C++) and python/clone/ (Python).
    Nz(../models/qwen-talker-1.7b-base-{q}.ggufz&../models/qwen-tokenizer-12hz-{q}.ggufz'../checkpoints/Qwen3-TTS-12Hz-1.7B-Basez	cpp/clonezpython/clone))MelHannmel-hann.bin)MelBasismel-basis.bin)MelMagmel-mag.bin)MelSpkmel-spk.bin)
SeanetInitseanet-init.bin)SeanetResnet0seanet-resnet0.bin)SeanetStage0seanet-stage0.bin)SeanetStage1seanet-stage1.bin)SeanetStage3seanet-stage3.bin)	SeanetOutseanet-out.bin)EncTransformerenc-transformer-out.bin)CodecPreFSQcodec-pre-fsq.bin)SpkFrontendspk-frontend.bin)	SpkBlock3spk-block3.bin)SpkMFAspk-mfa.bin)SpkASPspk-asp.bin)
SpeakerEmbspk-emb.binc                 D  ^^^^^^^^^^^^^^ U R                   R                  R                  nSS0mUU4S jnUR                  R                  U5        SS0mUU4S jnUR                  R                  U5        SS0mUU4S jnUR
                  R                  U5        UR                  R                  nSS0mUU4S jnUS   R                  U5        SS0mUU4S jnUS	   R                  U5        SS0mUU4S
 jn	US   R                  U	5        SS0mUU4S jn
US   R                  U
5        SS0mUU4S jnUS   R                  U5        SS0mUU4S jnU R                  R                  USS9  U R                  nSS0mUU4S jnUR                  S   R                  U5        SS0mUU4S jnUR                  S   R                  U5        SS0mUU4S jnUR                  R                  U5        SS0mUU4S jnUR                  R                  U5        g)a  Capture the codec encoder bisection points (SEANet, encoder_transformer,
downsample = pre-FSQ latents), the ECAPA mel front end input, and four
ECAPA forward bisection points (frontend conv0 output, third SE-Res2Net
block output, MFA output, ASP output). Mirrors exactly what
pipeline-codec.cpp and speaker-encoder-extract.h dump on the C++ side,
with matching shapes : [T, 512] for the codec stages, [T_frames, 128]
for the speaker mel, [T_frames, 512] for spk-frontend / spk-block3,
[T_frames, 1536] for spk-mfa, and [1, 3072] for spk-asp.doneFc                 
  > TS   (       a  g [        U[        5      (       a  US   OUn[        R                  " [        R
                  R                  TS5      US   R                  SS5      R                  5       5        STS'   g )Nr&   r   r      T	
isinstancetuplecc	save_dumpospathjoin	transpose
contiguous)moduleargsoutputoutdump_dirseen_seanets       debug-clone-cossim.pyhook_seanet(install_clone_hooks.<locals>.hook_seanetP   si    v%fe44fQi&
RWW\\(,<=s1v?O?OPQST?U?`?`?bc"F    c                    > TS   (       a  g [        U[        5      (       a  US   OUn[        R                  " [        R
                  R                  TS5      US   5        STS'   g )Nr&   r   r   T)r*   r+   r,   r-   r.   r/   r0   )r3   r4   r5   r6   r7   	seen_encts       r9   	hook_enct&install_clone_hooks.<locals>.hook_enctZ   sS    V%fe44fQi& 	RWW\\(,EFAO 	&r<   c                 
  > TS   (       a  g [        U[        5      (       a  US   OUn[        R                  " [        R
                  R                  TS5      US   R                  SS5      R                  5       5        STS'   g )Nr&   r   r   r(   Tr)   )r3   r4   r5   r6   r7   	seen_downs       r9   	hook_down&install_clone_hooks.<locals>.hook_downe   sk    V%fe44fQi& 	RWW\\(,?@#a&BRBRSTVWBXBcBcBef 	&r<   c                 
  > TS   (       a  g [        U[        5      (       a  US   OUn[        R                  " [        R
                  R                  TS5      US   R                  SS5      R                  5       5        STS'   g )Nr&   r   r   r(   Tr)   )r3   r4   r5   r6   r7   seen_sn_inits       r9   hook_sn_init)install_clone_hooks.<locals>.hook_sn_initx   si    %fe44fQi&
RWW\\(,=>A@P@PQRTU@V@a@a@cd#Vr<   r   c                 
  > TS   (       a  g [        U[        5      (       a  US   OUn[        R                  " [        R
                  R                  TS5      US   R                  SS5      R                  5       5        STS'   g )Nr&   r   r   r(   Tr)   )r3   r4   r5   r6   r7   
seen_sn_r0s       r9   hook_sn_resnet0,install_clone_hooks.<locals>.hook_sn_resnet0   si    f%fe44fQi&
RWW\\(,@A3q6CSCSTUWXCYCdCdCfg!
6r<   r(   c                 
  > TS   (       a  g [        U[        5      (       a  US   OUn[        R                  " [        R
                  R                  TS5      US   R                  SS5      R                  5       5        STS'   g )Nr&   r   r   r(   Tr)   )r3   r4   r5   r6   r7   
seen_sn_s0s       r9   hook_sn_stage0+install_clone_hooks.<locals>.hook_sn_stage0   i    f%fe44fQi&
RWW\\(,?@#a&BRBRSTVWBXBcBcBef!
6r<      c                 
  > TS   (       a  g [        U[        5      (       a  US   OUn[        R                  " [        R
                  R                  TS5      US   R                  SS5      R                  5       5        STS'   g )Nr&   r   r   r(   Tr)   )r3   r4   r5   r6   r7   
seen_sn_s1s       r9   hook_sn_stage1+install_clone_hooks.<locals>.hook_sn_stage1   rQ   r<      c                 
  > TS   (       a  g [        U[        5      (       a  US   OUn[        R                  " [        R
                  R                  TS5      US   R                  SS5      R                  5       5        STS'   g )Nr&   r   r   r(   Tr)   )r3   r4   r5   r6   r7   
seen_sn_s3s       r9   hook_sn_stage3+install_clone_hooks.<locals>.hook_sn_stage3   rQ   r<      c                   > TS   (       a  g U(       a  US   OUR                  SS 5      nUb  UR                  5       S:w  a  g [        R                  " [        R
                  R                  TS5      US   5        STS'   g )Nr&   r   melsrR   r
   T)getdimr,   r-   r.   r/   r0   )r3   r4   kwargsr^   r7   seen_mels       r9   hook_spk_pre)install_clone_hooks.<locals>.hook_spk_pre   sg    F
 tAwFJJvt$<<488:?
RWW\\(M:DGDr<   T)with_kwargsc                 
  > TS   (       a  g [        U[        5      (       a  US   OUn[        R                  " [        R
                  R                  TS5      US   R                  SS5      R                  5       5        STS'   g )Nr&   r   r   r(   Tr)   )r3   r4   r5   r6   r7   
seen_fronts       r9   hook_frontend*install_clone_hooks.<locals>.hook_frontend   si    f%fe44fQi&
RWW\\(,>?QAQAQRSUVAWAbAbAde!
6r<   c                 
  > TS   (       a  g [        U[        5      (       a  US   OUn[        R                  " [        R
                  R                  TS5      US   R                  SS5      R                  5       5        STS'   g )Nr&   r   r   r(   Tr)   )r3   r4   r5   r6   r7   	seen_blk3s       r9   hook_block3(install_clone_hooks.<locals>.hook_block3   si    V%fe44fQi&
RWW\\(,<=s1v?O?OPQST?U?`?`?bc 	&r<   c                 
  > TS   (       a  g [        U[        5      (       a  US   OUn[        R                  " [        R
                  R                  TS5      US   R                  SS5      R                  5       5        STS'   g )Nr&   r   r    r(   Tr)   )r3   r4   r5   r6   r7   seen_mfas       r9   hook_mfa%install_clone_hooks.<locals>.hook_mfa   sg    F%fe44fQi&
RWW\\(M:CF<L<LQPQ<R<]<]<_`r<   c                 
  > TS   (       a  g [        U[        5      (       a  US   OUn[        R                  " [        R
                  R                  TS5      US   R                  SS5      R                  5       5        STS'   g )Nr&   r   r"   r(   Tr)   )r3   r4   r5   r6   r7   seen_asps       r9   hook_asp%install_clone_hooks.<locals>.hook_asp   si    F%fe44fQi& 	RWW\\(M:CF<L<LQPQ<R<]<]<_`r<   N)speech_tokenizermodelencoderregister_forward_hookencoder_transformer
downsamplelayersspeaker_encoderregister_forward_pre_hookblocksmfaasp)rw   r7   encr:   r?   rC   	sn_layersrG   rK   rO   rU   rZ   rc   spkrh   rl   rp   rt   rs   rk   rB   r>   rg   rb   ro   r8   rF   rJ   rN   rT   rY   s    `                @@@@@@@@@@@@@r9   install_clone_hooksr   D   s    
 
 
&
&
.
.C5/K# KK%%k2I! 11)<I! NN((3 ""IE?L$ aL&&|4%J" aL&&7%J" aL&&~6%J" aL&&~6%J" bM''7H  
33Ld3S 

C%J" JJqM''6I! JJqM''4H  GG!!(+H  GG!!(+r<   c                    SSK nSnSnSnSnSn[        R                  " USS	9R                  5       R	                  [
        R                  5      n[        R                  " [        R                  R                  U S
5      U5        UR                  R                  XBX5US9n[        R                  " [        R                  R                  U S5      UR	                  [
        R                  5      5        g)a;  Reproduce the speaker encoder mel front end CPU constants the same
way the upstream mel_spectrogram() builds them (torch.hann_window for
the window and librosa.filters.mel for the Slaney filterbank), and
save them under dump_dir/mel-hann.bin and dump_dir/mel-basis.bin so
they can be paired with the C++ side dumps.r   N      i]  g        g     p@Tperiodicr   )srn_fftn_melsfminfmaxr   )librosatorchhann_windownumpyastypenpfloat32r,   r-   r.   r/   r0   filtersmel)	r7   r   r   r   r   r   r   hann	mel_basiss	            r9   dump_mel_constantsr      s     EFBDDut4::<CCBJJODLLh7>##rvW[#\ILLh8):J:J2:::VWr<   c                    SnSnSnX#-
  S-  n[         R                  " U 5      R                  S5      n[         R                  R                  R                  UR                  S5      XU4SS9R                  S5      n[         R                  " XbX4[         R                  " USS	9S
SS
SSS9
n[         R                  " [         R                  " U5      R                  S5      R                  S5      S-   5      n[        R                  " [        R                   R#                  US5      US   R%                  SS5      R'                  5       5        g)a  Reproduce the upstream mel_spectrogram STFT path (same n_fft / hop /
window / pad as modeling_qwen3_tts.mel_spectrogram) and dump the post
magnitude tensor [T_frames, n_freq] for direct pairing with the C++
spk.mag_dump output. This isolates the STFT step from the mel filter.r         r   r(   reflect)modeTr   F)
hop_length
win_lengthwindowcenterpad_mode
normalizedonesidedreturn_complexg&.>r   N)r   
from_numpy	unsqueezenn
functionalpadsqueezestftr   sqrtview_as_realpowsumr,   r-   r.   r/   r0   r1   r2   )	ref_wavr7   r   hopwinpaddingyspecmags	            r9   dump_mel_mag_pythonr      s   
 ECC{q Gw'11!4Ahh!!%%akk!nw6Hy%YaabcdAjj	S  t4yUd	D **U''-11!488<tC
DCLLh6A8H8HA8N8Y8Y8[\r<   c                  $   [         R                  " 5       n U R                  SSS9  U R                  SSSS9  U R                  SS	S
S9  U R                  S[        SS9  U R                  SSS9  U R                  SSSS9  U R                  S[        R
                  R                  [        S5      S9  U R                  S[        R
                  R                  [        S5      S9  U R                  S[        SS9  U R                  SSSS9  U R                  5       n[        R                  " [        5        [        R                  " [        5        [        R                  " [        R
                  R                  UR                  5      =(       d    SSS9  [        [        5        [!        UR"                  S S!S"9 nUR%                  5       R'                  5       nS S S 5        [!        UR(                  S S!S"9 nUR%                  5       R'                  5       nS S S 5        [+        S#[-        W5       S$US S%  [-        U5      S%:  a  S&OS' 35        [+        S(UR.                   35        [+        S)[-        W5       S$US S%  [-        U5      S%:  a  S&OS' 35        [+        S*UR0                   S+UR2                   S,UR4                   35        [+        S-5        [6        R8                  " UR2                  5        [:        R<                  R3                  UR2                  5        [        R>                  " UR@                  5        [        RB                  " 5         [6        RD                  RG                  5       (       a  S.OS/n[+        S0U 35        [        RH                  RK                  [L        U[6        RN                  S1S29RQ                  5       n[        RR                  RK                  [L        SS39n[U        U[        5        [V        R$                  " UR.                  S4S59u  pURX                  S6:  a	  US S 2S74   nUR[                  [:        RN                  5      nUR\                  n
X:w  at  S7S K/nUR`                  Rc                  [6        Rd                  " UR[                  [:        RN                  5      5      [        U	5      [        U
5      5      Rg                  5       nU
n	[+        S8URh                  S7    S9U	 S:URh                  S7   U	-  S; S<35        [k        U[        5        URm                  XS=9n[+        S>[o        URh                  5       S?URp                   35        [        Rr                  " [        R
                  R                  [        S@5      U5        SAnURh                  S7   U-  U-  nUS U n[        Rr                  " [        R
                  R                  [        SB5      [6        Rd                  " UR[                  [:        RN                  5      5      5        URt                  Rw                  U/[        U	5      SC9nURx                  S7   nUR{                  S7S65      R}                  5       n[+        SD[o        URh                  5       SE35        [        R~                  " [        R
                  R                  [        SF5      U5        SGU SH3nU" USISSJ9nUSK   R                  U5      nUR                  5       S6:X  a  UR                  S75      n[+        SL[o        URh                  5       35        [        R~                  " [        R
                  R                  [        SM5      US7   5        SGU SN3nU" USISSJ9nUSK   R                  U5      nUR                  5       S6:X  a  UR                  S75      n[+        SO[o        URh                  5       35        [        R~                  " [        R
                  R                  [        SP5      US7   5        [        R                  " U[        5        SQ UR                  lE        [        U/U/S4/S/SR9nUR                  " SxU/U/UUR0                  /S4UR4                  SS.[        R                  D6u  nnUS7   n[+        ST[o        URh                  5       SU35        [        R~                  " [        R
                  R                  [        SV5      U5        [        R~                  " [        R
                  R                  [        SW5      US7   5        [6        R                  " UR                  UR                  5      U/S7SX9nURt                  R                  SYU0/5      u  nn[:        R                  " US7   [:        RN                  SZ9n [        URh                  S7   5      n![        URh                  S7   5      n"[        U![        U"S65      -  U Rh                  S7   -  5      n#U U#S  n$[V        R                  " UR                  U$US[S\9  [        Rr                  " [        R
                  R                  [        S]5      U$5        [+        S^U$Rh                  S7    S9U S:U$Rh                  S7   U-  S; S_UR                   35        [        R
                  R                  [        R                  5      (       d3  [+        S`[        R                   Sa35        [        R                  " S65        [        R                  UR                  Sb9n%[        R                  UR                  Sb9n&U%U&4 HM  n'[        R
                  R                  U'5      (       a  M)  [+        ScU' 35        [        R                  " S65        MO     [+        SdUR                   SeU% SfU& 35        AUS.:X  a  [6        RD                  R                  5         [        R                  SgU%ShU&S[        UR2                  5      SUR.                  SUR(                  SUR0                  Si[        UR4                  5      Sj[        SkUR                  Sl/n([+        SmSnR                  U(5       35        [        R                  " U(USSo9n)U)R                  S7:w  a   [        R                  " U)R                  5        [V        R$                  " UR                  5      u  n*n+U*RX                  S6:  a	  U*S S 2S74   n*U*R[                  [:        RN                  5      n*[+        SpU*Rh                  S7    S9U+ S:U*Rh                  S7   U+-  S; S_UR                   35        [        R                  " SM[        [        Sq5        [        R                  " SF[        [        Sr5        [        R                  " [        [        [        5        [        R                  " SV[        [        Ss5        [        R                  " S][        [        5      u  n,n-[+        St[        R                  " U,U-5      Su 35        [        U,R                  U-R                  5      n.[+        Sv[        R                  " U,R                  5       S U. U-R                  5       S U. 5      Su SwU. 35        g ! , (       d  f       GN= f! , (       d  f       GNw= f)yNz--promptz../examples/prompt.txt)defaultz	--ref-wavz../examples/freeman.wavz$reference WAV path for voice cloning)r   helpz
--ref-textz../examples/freeman.txtz3path to a UTF-8 file with the transcript of ref-wavz--seed*   )typer   z--langenglishz--quantF32z2GGUF quantization suffix (F32, BF16, Q8_0, Q4_K_M)z--out-ptzclone-python.wavz	--out-cppzclone-cpp.wavz--max-new-tokens@   z--trace
store_truez3print per sample u and idx for the first 32 samples)actionr   .T)exist_okrzutf-8)encodingz[Input] Prompt: z chars: <   z... z[Input] RefAudio: z[Input] RefText: z[Input] Lang: z Seed: z MaxNewTokens: z[Input] Mode: greedy ICLcudacpuz[Python] Device: eager)
device_mapdtypeattn_implementation)fix_mistral_regexF)	always_2dr(   r   z[Python] RefWav: z	 samples z Hz z.2fs)audior   z[Python] SpeakerEmb shape: z dtype: r$   i  zaudio-input.bin)r   z[Python] RefCodes shape: z (K, T_codec)zref-codes.binz<|im_start|>assistant
z!<|im_end|>
<|im_start|>assistant
pt)textreturn_tensorsr   	input_idsz[Python] InputIds shape: zprompt-ids.binz<|im_end|>
z[Python] RefIds shape: zref-ids.binc                      g )N )aks     r9   <lambda>main.<locals>.<lambda>  s    $r<   )ref_coderef_spk_embeddingx_vector_only_modeicl_mode)r   ref_idsvoice_clone_prompt	languagesnon_streaming_modemax_new_tokensz[Python] Codes shape: z (T_frames, num_code_groups)zcodes-full.binzcodes-step0.bin)r`   audio_codes)r   FLOAT)subtypezoutput-audio.binz[Python] Audio: zs -> z[Cossim] FATAL: z  not found, build qwen-tts first)qz [Cossim] FATAL: GGUF not found: z[Quant] z -> z + z--modelz--codecz	--max-newz--dumpz-oz--greedyz[GGML] Cmd:  )inputr   z[GGML] Audio: 	PromptIDsRefCodes	CodesFullz[Cossim] Audio cos: z.6fz[Cossim] WAV stft_cos: z
 samples: r   )fargparseArgumentParseradd_argumentintr.   r/   r0   DUMP_PTDUMP_CPP
parse_argsr,   
ensure_dirmakedirsdirnameout_ptr   openpromptreadstripref_textprintlenr   langseedr   r   manual_seedr   random	set_tracetraceregister_qwen3_ttsr   is_available	AutoModelfrom_pretrainedCKPTr   evalAutoProcessorr   sfndimr   speaker_encoder_sample_rate
torchaudior   resampler   r   shaper   extract_speaker_embeddingr+   r   r-   rv   encoder   r1   r2   save_dump_i32tor`   r   install_hookstalker_validate_model_kwargsdictgenerateGEN_KWARGS_GREEDYcatdevicedecodeasarraymaxwriteisfileBINsysexitMODEL_TformatquantMODEL_CDC_Tempty_cachestrout_cpp
subprocessrun
returncodecompare_exact_i32compare_stagesSTAGES_CLONEpaircosminsizestft_cosravel)/apr4   fr   r  r#  rw   	processorr   ref_sr	target_srr  spk_embHOP	aligned_Tref_wav_alnr   ref_code_ptref_code_ktassistant_textinp_uttr   ref_text_wrapinp_refr   voice_clone_prompt_dicttalker_codes_list_codes	cat_codeswavsfsfull_wavref_len	total_lencutaudio_ptmodel_lm	model_cdcpcmdr   	audio_cppr   aaabns/                                                  r9   mainrb    s   		 	 	"BOOJ0HOIOOK0I?  AOOL0IN  POOHS"O=OOH	O:OOIM  OOOJWGY0ZO[OOKX0WOXOO&S"O=OOI|N  P==?DMM'MM(KK,3dC
 w	dkk3	1Qvvx~~ 
2	dmmS7	3q668>># 
4	SYKxSb	{CIPRN5XZ:[
\]	t||n
-.	c(m_HXcr]OSQY]]_M_EegCh
ij	N499+WTYYKtGZGZF[
\]	$&	dii IINN499LLzz..00VeF	fX
&'LL((mm#	 ) 
 df 
   000NI
 w' ggdlle<OG||a!Q$-nnRZZ(G11I 	''00W^^BJJ78KY
 %' 	 	gmmA./yW]]STEUV\E\]`Daab
cd ) --G-GG	'gmm(<'=Xgmm_
UVLLg}5w? C==#s*c1I*9%KLLg'895;K;KKL^L^_a_i_iLj;kl((//#f+/NC//!$K''1-88:K	%eK,=,=&>%?}
MNRWW\\'?;[I /tf4WXNN4QUVG[),,V4I}}!''*		%eIOO&<%=
>?RWW\\'+;<ilK-hZ|DM=tTGK(++F3G{{}##A&	#E'--$8#9
:;RWW\\'=971:FUG$
 +?ELL' #)]%Y#W"V	 !>> +	299+ ** 

q a E	"5#5"66R
STRWW\\'+;<uERWW\\'+<=uQxH
 		;>>%,,7?QGI&&--y/I.JKHD"

47"**5HK%%a()GIOOA&'IGc)Q//(..2CCDCHHHT[[(B8LLg'9:HE	X^^A./yDPQARSUAUVY@ZZ_`d`k`k_l
mn77>>"&&!! (HIJ,H""TZZ"0I	"ww~~a  4QC89HHQK # 
HTZZLXJc)
=>

  	xys499~t||t}}tyys4../xt||C 
L#
()s$T2A||qGGDLL)MIr~~adO	  ,I	N9??1-.it4	PQ@RSU@UVY?ZZ_`d`l`l_m
no)8WkJ8WjIlHg6)8WkJWW'7;FB	 B 4
56BGGRWWA	#BKK
2A
2A$OPS#TT^_`^a
bc 
2	1	3	3s   5y.1z .
y= 
z__main__)__doc__r   r.   r3  r*  r   r   r   	soundfiler  r   cossim_commonr,   r,  r/  r  r   r   STAGES_STANDARDr8  r   r   r   rb  __name__r   r<   r9   <module>ri     s   *  	  
     867 !! % (`,DX"]*Zdz zF r<   