code wiki / (root) / nx_hifigan_run.nx

nx_hifigan_run.nx source

↩ module page · 151 lines · 9026 B

1// nx_hifigan_run.nx -- run the FULL real-weight HiFi-GAN generator at REAL dims (512ch). Loads all 158 tensors 2// from the .bin into a weight pool (data/N -> pool offset), then executes the complete forward on our sovereign 3// nx_vocops: normalize (mel-mean)/scale -> conv_pre -> [leaky -> upsample -> MRF(3 resblocks[K=3,7,11], each 3 4// dilation branches[1,3,5])]x4 -> leaky -> conv_post -> tanh. Verifies it runs end-to-end at real dims + output is 5// finite + tanh-bounded. (Synthetic mel here => output is not speech; a REAL mel makes it speech. This proves the 6// real-weight forward EXECUTES correctly.) CPU f32 = minutes/utterance -> GPU is the speed lever. license_tier: ORIGINAL expect_exit: 0 7import "nx_syscalls.nx" 8import "nx_f32.nx" 9import "nx_f32_activations.nx" 10import "nx_vocops.nx" 11const F_MAGIC_67108864: i64 = 67108864 12const F_MAGIC_16777216: i64 = 16777216 13const F_MAGIC_262144: i64 = 262144 14 15const SLOPE01: i64 = 0x3DCCCCCD // 0.1 16const F_THIRD: i64 = 0x3EAAAAAB // 1/3 17 18func p(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 19func 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 } 20func 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 } 21func u16le(b: *u8, o: i64) -> i64 { return (b[o]&0xff) | ((b[o+1]&0xff)<<8) } 22func 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) } 23func f32_sub(a: i64, b: i64) -> i64 { return nx_f32_add(a, (b & 0xFFFFFFFF) ^ 0x80000000) } 24func vcopy(d: *i64, s: *i64, n: i64) -> i64 { var i: i64=0; while i<n { d[i]=s[i]; i=i+1 } return 0 } 25func 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 } 26func vzero(d: *i64, n: i64) -> i64 { var i: i64=0; while i<n { d[i]=0; i=i+1 } return 0 } 27func 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 } 28func f32_exp(x: i64) -> i64 { return (x>>23)&0xFF } 29 30func main() -> i64 { 31 p("=== nx_hifigan_run -- FULL real-weight HiFi-GAN generator @ real dims ===\n" as *u8) 32 let path: *u8 = "/home/elderwesto/nx_stage/hifigan_pytorch_model.bin" as *u8 33 let fd: i64 = sys_openat_rd(path) 34 if fd<0 { p("open failed\n" as *u8); sys_exit(1); return 1 } 35 let cap: i64 = F_MAGIC_67108864 36 let buf: *u8 = sys_mmap(cap) 37 var n: i64=0; var go: i64=1 38 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}} } 39 sys_close(fd) 40 41 // ZIP central dir -> data/N offset+size 42 var ez: i64 = n-22 43 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 } 44 let n_entries: i64 = u16le(buf, ez+10) 45 let doff: *i64 = sys_mmap(256*8) as *i64 46 let dsz: *i64 = sys_mmap(256*8) as *i64 47 var ii: i64=0; while ii<256 { doff[ii]=0-1; dsz[ii]=0; ii=ii+1 } 48 var off: i64 = u32le(buf, ez+16); var e: i64=0 49 while e<n_entries { 50 if buf[off]!=0x50 as u8 { e=n_entries } else { 51 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) 52 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 } 53 if slash>=0 { let c0: i64=buf[off+46+slash+1] as i64; if c0>=48 { if c0<=57 { 54 var kk: i64=0; var pp: i64=slash+1; while pp<fnl { let c: i64=buf[off+46+pp] as i64; if c>=48 { if c<=57 { kk=kk*10+(c-48); pp=pp+1 } else { pp=fnl } } else { pp=fnl } } 55 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 } 56 } } } 57 off = off+46+fnl+exl+cml; e=e+1 58 } 59 } 60 61 // load ALL tensors into a weight pool; woff[k] = pool index (in f32 units) 62 let wpool: *i64 = sys_mmap(F_MAGIC_16777216*8) as *i64 // 16M f32 slots (~128MB) -- model is ~12.5M params 63 let woff: *i64 = sys_mmap(256*8) as *i64 64 var cur: i64=0; var k: i64=0 65 while k<158 { 66 woff[k]=cur 67 let cnt: i64 = dsz[k]/4 68 var j: i64=0; while j<cnt { wpool[cur+j]=u32le(buf, doff[k]+4*j); j=j+1 } 69 cur=cur+cnt; k=k+1 70 } 71 p("loaded 158 tensors, "); pn(cur); p(" f32 params into the pool\n" as *u8) 72 73 // kernel sizes / dilations 74 let KS: *i64 = sys_mmap(4*8) as *i64; KS[0]=3; KS[1]=7; KS[2]=11 75 let DZ: *i64 = sys_mmap(4*8) as *i64; DZ[0]=1; DZ[1]=3; DZ[2]=5 76 77 // buffers 78 let BS: i64 = F_MAGIC_262144 79 let bufX: *i64 = sys_mmap(BS*8) as *i64 80 let bufU: *i64 = sys_mmap(BS*8) as *i64 81 let xs: *i64 = sys_mmap(BS*8) as *i64 82 let y: *i64 = sys_mmap(BS*8) as *i64 83 let ro: *i64 = sys_mmap(BS*8) as *i64 84 let t1: *i64 = sys_mmap(BS*8) as *i64 85 let t2: *i64 = sys_mmap(BS*8) as *i64 86 87 // mel [80, T] normalized (mel-mean)/scale 88 let T: i64 = 4 89 let mel: *i64 = sys_mmap(80*8*8) as *i64 90 let mean: *i64 = (wpool as i64 + woff[0]*8) as *i64 91 let scale: *i64 = (wpool as i64 + woff[1]*8) as *i64 92 var c: i64=0; while c<80 { var t: i64=0; while t<T { mel[c*T+t]=nx_f32_div(f32_sub(0x3F000000, mean[c]), scale[c]); t=t+1 } c=c+1 } 93 94 // conv_pre: [80,T]->[512,T] (weight=data/3, bias=data/2) 95 p("conv_pre...\n" as *u8) 96 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) 97 var ch: i64=512; var L: i64=T 98 var s: i64=0 99 while s<4 { 100 p("stage "); pn(s); p(" (ch="); pn(ch); p(" L="); pn(L); p(")...\n" as *u8) 101 leaky_relu_vec(bufX, ch*L, SLOPE01) 102 let ch2: i64=ch/2 103 // upsampler[s]: convtranspose ch->ch2, K=8, stride=4, pad=2 ; weight=data/(5+2s) bias=data/(4+2s) 104 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) 105 vzero(xs, ch2*L2) 106 var kk: i64=0 107 while kk<3 { 108 let r: i64 = s*3 + kk 109 let Kk: i64 = KS[kk] 110 let base: i64 = 12 + 12*r 111 vcopy(y, bufU, ch2*L2) // each resblock starts from the upsampled x 112 var jj: i64=0 113 while jj<3 { 114 let dil: i64 = DZ[jj] 115 // convs1[jj]: weight=base+1+2jj bias=base+2jj ; convs2[jj]: weight=base+7+2jj bias=base+6+2jj 116 resblock1_1dil(y, 117 (wpool as i64 + woff[base+1+2*jj]*8) as *i64, (wpool as i64 + woff[base+2*jj]*8) as *i64, 118 (wpool as i64 + woff[base+7+2*jj]*8) as *i64, (wpool as i64 + woff[base+6+2*jj]*8) as *i64, 119 ro, ch2, L2, Kk, dil, SLOPE01, t1, t2) 120 vcopy(y, ro, ch2*L2) 121 jj=jj+1 122 } 123 vaddto(xs, y, ch2*L2) 124 kk=kk+1 125 } 126 vscale(xs, ch2*L2, F_THIRD) 127 vcopy(bufX, xs, ch2*L2) 128 ch=ch2; L=L2 129 s=s+1 130 } 131 leaky_relu_vec(bufX, ch*L, SLOPE01) 132 // conv_post: [32,L]->[1,L] (weight=data/157 bias=data/156) 133 p("conv_post...\n" as *u8) 134 let audio: *i64 = sys_mmap(BS*8) as *i64 135 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) 136 var i2: i64=0; while i2<L { audio[i2]=nx_f32_tanh(audio[i2]); i2=i2+1 } 137 138 let expect: i64 = T*256 139 var finite: i64=1; var bounded: i64=1; i2=0 140 while i2<L { let raw: i64=audio[i2]&0xFFFFFFFF; if f32_exp(raw)==0xFF { finite=0 } if (raw&0x7FFFFFFF)>0x3F800800 { bounded=0 } i2=i2+1 } 141 p("AUDIO len="); pn(L); p(" (expect "); pn(expect); p(") finite="); pn(finite); p(" bounded="); pn(bounded); p("\n" as *u8) 142 p("audio[0..4]="); var z: i64=0; while z<5 { phx(audio[z]&0xFFFFFFFF); p(" " as *u8); z=z+1 } p("\n" as *u8) 143 144 var pass: i64=0; var tot: i64=3 145 if L==expect { pass=pass+1; p("PASS full generator output length = T*256 (all 4 stages ran at real dims)\n" as *u8) } else { p("FAIL len\n" as *u8) } 146 if finite==1 { pass=pass+1; p("PASS no NaN/Inf across the FULL real-weight forward (numerically stable)\n" as *u8) } else { p("FAIL NaN/Inf\n" as *u8) } 147 if bounded==1 { pass=pass+1; p("PASS output tanh-bounded [-1,1] (valid audio range)\n" as *u8) } else { p("FAIL unbounded\n" as *u8) } 148 p("nx_hifigan_run pass="); pn(pass); p("/"); pn(tot) 149 if pass==tot { p(" GREEN -- the REAL HiFi-GAN vocoder runs end-to-end on our sovereign engine. Feed a REAL mel -> real human-grade audio; measure with nx_voice_eval.\n" as *u8); sys_exit(0); return 0 } 150 p(" RED\n" as *u8); sys_exit(1); return 1 151}