code wiki / (root) / nx_hifigan_verify.nx

nx_hifigan_verify.nx source

↩ module page · 149 lines · 10527 B

1// nx_hifigan_verify.nx -- VERIFY our sovereign HiFi-GAN against the transformers oracle (Qwen-style). Reads a REAL 2// SpeechT5 mel (ref_mel_short.f32, [T,80] row-major) + the reference vocoder output (ref_audio_short.f32, [T*256]) 3// produced by hifigan_oracle.py, runs OUR nx_hifigan forward on the same mel, and reports the max/mean abs error. 4// Small error => our vocoder is CORRECT (produces the same human-grade audio as the reference). Also writes our 5// audio as a 16kHz WAV so it can be published to /listen and HEARD. license_tier: ORIGINAL expect_exit: 0 6import "nx_syscalls.nx" 7import "nx_f32.nx" 8import "nx_f32_activations.nx" 9import "nx_f32_cvt.nx" 10import "nx_vocops.nx" 11 12const SLOPE01: i64 = 0x3DCCCCCD 13const F_THIRD: i64 = 0x3EAAAAAB 14 15func p(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 16func pn(v: i64) -> i64 { if v==0 { sys_write(1,"0" as *u8,1); return 0 } var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m} let d: *u8=sys_mmap(24); var k: i64=0; while m>0 {d[k]=(48+(m%10)) as u8; m=m/10; k=k+1} var i: i64=k-1; while i>=0 {let o: *u8=sys_mmap(1); o[0]=d[i]; sys_write(1,o,1); i=i-1} return 0 } 17func phx(v: i64) -> i64 { let b: *u8=sys_mmap(8); var i: i64=0; while i<8 { let n: i64=(v>>((7-i)*4))&0xF; if n<10 {b[i]=(48+n) as u8} else {b[i]=(87+n) as u8} i=i+1 } sys_write(1,b,8); return 0 } 18func u16le(b: *u8, o: i64) -> i64 { return (b[o]&0xff) | ((b[o+1]&0xff)<<8) } 19func u32le(b: *u8, o: i64) -> i64 { return (b[o]&0xff) | ((b[o+1]&0xff)<<8) | ((b[o+2]&0xff)<<16) | ((b[o+3]&0xff)<<24) } 20func f32_sub(a: i64, b: i64) -> i64 { return nx_f32_add(a, (b & 0xFFFFFFFF) ^ 0x80000000) } 21func f32_abs(a: i64) -> i64 { return a & 0x7FFFFFFF } 22func vcopy(d: *i64, s: *i64, n: i64) -> i64 { var i: i64=0; while i<n { d[i]=s[i]; i=i+1 } return 0 } 23func vaddto(d: *i64, s: *i64, n: i64) -> i64 { var i: i64=0; while i<n { d[i]=nx_f32_add(d[i],s[i]); i=i+1 } return 0 } 24func vzero(d: *i64, n: i64) -> i64 { var i: i64=0; while i<n { d[i]=0; i=i+1 } return 0 } 25func vscale(d: *i64, n: i64, s: i64) -> i64 { var i: i64=0; while i<n { d[i]=nx_f32_mul(d[i],s); i=i+1 } return 0 } 26 27// read a whole file into a fresh buffer; returns bytes read, sets *bufp. 28func read_all(path: *u8, cap: i64, bufp: *i64) -> i64 { 29 let fd: i64 = sys_openat_rd(path); if fd<0 { return 0-1 } 30 let buf: *u8 = sys_mmap(cap); var n: i64=0; var go: i64=1 31 while go==1 { let r: i64=sys_read(fd,(buf as i64+n) as *u8,cap-n); if r<=0 {go=0} else {n=n+r; if n>=cap {go=0}} } 32 sys_close(fd); bufp[0]=buf as i64; return n 33} 34 35func main() -> i64 { 36 p("=== nx_hifigan_verify -- our vocoder vs the transformers oracle ===\n" as *u8) 37 // dims: ref_dims_short.txt = "T 80 audiolen" 38 let dbp: *i64 = sys_mmap(8) as *i64 39 let dn: i64 = read_all("/home/elderwesto/nx_stage/ref_dims_short.txt" as *u8, 256, dbp) 40 if dn<0 { p("no ref_dims_short.txt (run the oracle short-slice first)\n" as *u8); sys_exit(1); return 1 } 41 let db: *u8 = dbp[0] as *u8 42 var T: i64=0; var i: i64=0; while i<dn { let c: i64=db[i] as i64; if c>=48 { if c<=57 { T=T*10+(c-48) } else { i=dn } } else { i=dn } i=i+1 } 43 p("mel frames T="); pn(T); p("\n" as *u8) 44 let AUD: i64 = T*256 45 46 // read ref_mel_short.f32 [T,80] row-major -> mel[80,T] 47 let mbp: *i64 = sys_mmap(8) as *i64 48 let mn: i64 = read_all("/home/elderwesto/nx_stage/ref_mel_short.f32" as *u8, T*80*4 + 64, mbp) 49 if mn<0 { p("no ref_mel_short.f32\n" as *u8); sys_exit(1); return 1 } 50 let mb: *u8 = mbp[0] as *u8 51 let mel: *i64 = sys_mmap(80*T*8 + 64) as *i64 52 var c: i64=0; while c<80 { var t: i64=0; while t<T { mel[c*T+t]=u32le(mb, (t*80+c)*4); t=t+1 } c=c+1 } 53 54 // read ref_audio_short.f32 [AUD] 55 let abp: *i64 = sys_mmap(8) as *i64 56 read_all("/home/elderwesto/nx_stage/ref_audio_short.f32" as *u8, AUD*4 + 64, abp) 57 let ab: *u8 = abp[0] as *u8 58 59 // load HiFi-GAN weights from the .bin 60 let wbp: *i64 = sys_mmap(8) as *i64 61 let bn: i64 = read_all("/home/elderwesto/nx_stage/hifigan_pytorch_model.bin" as *u8, 67108864, wbp) 62 let buf: *u8 = wbp[0] as *u8 63 var ez: i64 = bn-22; while ez>=0 { if buf[ez]==0x50 as u8 { if buf[ez+1]==0x4B as u8 { if buf[ez+2]==0x05 as u8 { if buf[ez+3]==0x06 as u8 { break } } } } ez=ez-1 } 64 let n_entries: i64 = u16le(buf, ez+10) 65 let doff: *i64 = sys_mmap(256*8) as *i64; let dsz: *i64 = sys_mmap(256*8) as *i64 66 var z: i64=0; while z<256 { doff[z]=0-1; dsz[z]=0; z=z+1 } 67 var off: i64=u32le(buf,ez+16); var e: i64=0 68 while e<n_entries { 69 if buf[off]!=0x50 as u8 { e=n_entries } else { 70 let usize: i64=u32le(buf,off+24); let fnl: i64=u16le(buf,off+28); let exl: i64=u16le(buf,off+30); let cml: i64=u16le(buf,off+32); let lho: i64=u32le(buf,off+42) 71 var slash: i64=0-1; var q: i64=0; while q<fnl { if buf[off+46+q]==0x2F as u8 { slash=q } q=q+1 } 72 if slash>=0 { let c0: i64=buf[off+46+slash+1] as i64; if c0>=48 { if c0<=57 { 73 var kk: i64=0; var pp: i64=slash+1; while pp<fnl { let cc: i64=buf[off+46+pp] as i64; if cc>=48 { if cc<=57 { kk=kk*10+(cc-48); pp=pp+1 } else { pp=fnl } } else { pp=fnl } } 74 if kk<256 { let lfnl: i64=u16le(buf,lho+26); let lexl: i64=u16le(buf,lho+28); doff[kk]=lho+30+lfnl+lexl; dsz[kk]=usize } 75 } } } 76 off=off+46+fnl+exl+cml; e=e+1 77 } 78 } 79 let wpool: *i64 = sys_mmap(16777216*8) as *i64; let woff: *i64 = sys_mmap(256*8) as *i64 80 var cur: i64=0; var k: i64=0 81 while k<158 { woff[k]=cur; let cnt: i64=dsz[k]/4; var j: i64=0; while j<cnt { wpool[cur+j]=u32le(buf, doff[k]+4*j); j=j+1 } cur=cur+cnt; k=k+1 } 82 83 // normalize mel (mel-mean)/scale 84 let mean: *i64=(wpool as i64+woff[0]*8) as *i64; let scale: *i64=(wpool as i64+woff[1]*8) as *i64 85 c=0; while c<80 { var t: i64=0; while t<T { mel[c*T+t]=nx_f32_div(f32_sub(mel[c*T+t],mean[c]),scale[c]); t=t+1 } c=c+1 } 86 87 let KS: *i64=sys_mmap(4*8) as *i64; KS[0]=3; KS[1]=7; KS[2]=11 88 let DZ: *i64=sys_mmap(4*8) as *i64; DZ[0]=1; DZ[1]=3; DZ[2]=5 89 let BS: i64=524288 90 let bufX: *i64=sys_mmap(BS*8) as *i64; let bufU: *i64=sys_mmap(BS*8) as *i64; let xs: *i64=sys_mmap(BS*8) as *i64 91 let y: *i64=sys_mmap(BS*8) as *i64; let ro: *i64=sys_mmap(BS*8) as *i64; let t1: *i64=sys_mmap(BS*8) as *i64; let t2: *i64=sys_mmap(BS*8) as *i64 92 93 conv1d(mel, (wpool as i64+woff[3]*8) as *i64, (wpool as i64+woff[2]*8) as *i64, bufX, 80, T, 512, 7, 1, 3, 1) 94 var ch: i64=512; var L: i64=T; var s: i64=0 95 while s<4 { 96 leaky_relu_vec(bufX, ch*L, SLOPE01) 97 let ch2: i64=ch/2 98 let L2: i64=conv_transpose1d(bufX, (wpool as i64+woff[5+2*s]*8) as *i64, (wpool as i64+woff[4+2*s]*8) as *i64, bufU, ch, L, ch2, 8, 4, 2, 0, 1) 99 vzero(xs, ch2*L2) 100 var kk: i64=0 101 while kk<3 { 102 let r: i64=s*3+kk; let Kk: i64=KS[kk]; let base: i64=12+12*r 103 vcopy(y, bufU, ch2*L2) 104 var jj: i64=0 105 while jj<3 { let dil: i64=DZ[jj] 106 resblock1_1dil(y, (wpool as i64+woff[base+1+2*jj]*8) as *i64, (wpool as i64+woff[base+2*jj]*8) as *i64, (wpool as i64+woff[base+7+2*jj]*8) as *i64, (wpool as i64+woff[base+6+2*jj]*8) as *i64, ro, ch2, L2, Kk, dil, SLOPE01, t1, t2) 107 vcopy(y, ro, ch2*L2); jj=jj+1 } 108 vaddto(xs, y, ch2*L2); kk=kk+1 109 } 110 vscale(xs, ch2*L2, F_THIRD); vcopy(bufX, xs, ch2*L2); ch=ch2; L=L2; s=s+1 111 } 112 leaky_relu_vec(bufX, ch*L, SLOPE01) 113 let audio: *i64=sys_mmap(BS*8) as *i64 114 conv1d(bufX, (wpool as i64+woff[157]*8) as *i64, (wpool as i64+woff[156]*8) as *i64, audio, ch, L, 1, 7, 1, 3, 1) 115 var ia: i64=0; while ia<L { audio[ia]=nx_f32_tanh(audio[ia]); ia=ia+1 } 116 117 // compare to reference 118 var maxe: i64=0; var sume: i64=0; var cmp: i64=L; if AUD<cmp { cmp=AUD } 119 ia=0; while ia<cmp { let d0: i64=f32_abs(f32_sub(audio[ia], u32le(ab, ia*4))); if f32_abs(d0)>f32_abs(maxe) { maxe=d0 } sume=nx_f32_add(sume, d0); ia=ia+1 } 120 let meane: i64=nx_f32_div(sume, nx_i32_to_f32(cmp)) 121 p("our audio len="); pn(L); p(" ref len="); pn(AUD); p(" compared="); pn(cmp); p("\n" as *u8) 122 p("our[0..3]="); phx(audio[0]&0xFFFFFFFF); p(" "); phx(audio[1]&0xFFFFFFFF); p(" "); phx(audio[2]&0xFFFFFFFF); p("\n" as *u8) 123 p("ref[0..3]="); phx(u32le(ab,0)); p(" "); phx(u32le(ab,4)); p(" "); phx(u32le(ab,8)); p("\n" as *u8) 124 p("max abs err="); phx(maxe&0xFFFFFFFF); p(" mean abs err="); phx(meane&0xFFFFFFFF); p(" (small => our vocoder matches the reference)\n" as *u8) 125 126 // write our audio as 16kHz mono int16 WAV 127 let wav: *u8 = sys_mmap(L*2 + 128) 128 // header 129 let hdr: *u8 = "RIFF" as *u8; var hi: i64=0; while hi<4 { wav[hi]=hdr[hi]; hi=hi+1 } 130 let dsize: i64 = L*2; let csize: i64 = 36 + dsize 131 wav[4]=(csize&0xff) as u8; wav[5]=((csize>>8)&0xff) as u8; wav[6]=((csize>>16)&0xff) as u8; wav[7]=((csize>>24)&0xff) as u8 132 let wave: *u8="WAVEfmt " as *u8; hi=0; while hi<8 { wav[8+hi]=wave[hi]; hi=hi+1 } 133 wav[16]=16 as u8; wav[17]=0 as u8; wav[18]=0 as u8; wav[19]=0 as u8 134 wav[20]=1 as u8; wav[21]=0 as u8; wav[22]=1 as u8; wav[23]=0 as u8 // PCM, mono 135 wav[24]=0x80 as u8; wav[25]=0x3E as u8; wav[26]=0 as u8; wav[27]=0 as u8 // 16000 Hz 136 wav[28]=0 as u8; wav[29]=0x7D as u8; wav[30]=0 as u8; wav[31]=0 as u8 // byte rate 32000 137 wav[32]=2 as u8; wav[33]=0 as u8; wav[34]=16 as u8; wav[35]=0 as u8 138 let dt: *u8="data" as *u8; hi=0; while hi<4 { wav[36+hi]=dt[hi]; hi=hi+1 } 139 wav[40]=(dsize&0xff) as u8; wav[41]=((dsize>>8)&0xff) as u8; wav[42]=((dsize>>16)&0xff) as u8; wav[43]=((dsize>>24)&0xff) as u8 140 // samples: f32 [-1,1] -> int16 141 ia=0; while ia<L { let sv: i64=nx_f32_to_i32(nx_f32_mul(audio[ia], nx_i32_to_f32(32000))); var iv: i64=sv; if iv>32767 {iv=32767} if iv<0-32768 {iv=0-32768} wav[44+ia*2]=(iv&0xff) as u8; wav[45+ia*2]=((iv>>8)&0xff) as u8; ia=ia+1 } 142 let wfd: i64=sys_openat_wr("/mnt/c/Users/elder/nishi-core/nxc2/web_assets/ng_elara_neural.wav" as *u8, 0x1a4) 143 if wfd>=0 { sys_write(wfd, wav, 44+L*2); sys_close(wfd); p("wrote web_assets/ng_elara_neural.wav ("); pn(44+L*2); p(" bytes)\n" as *u8) } 144 145 // GATE: mean abs err below ~0.02 => match (f32 0.02 = 0x3CA3D70A) 146 if f32_abs(meane) < 0x3CA3D70A { p("verdict=GREEN -- our sovereign vocoder MATCHES the transformers reference (mean err < 0.02). Real neural audio, verified.\n" as *u8); sys_exit(0); return 0 } 147 p("verdict=NOTE -- audio differs from reference; inspect errs above (may be a forward bug -- bisect like Qwen)\n" as *u8) 148 sys_exit(1); return 1 149}