Release TONER-1 Pro: our own 12M model and tokenizer as a single PostScript print job
20aa772 verified Download src/export.py from jacobalansussman/TONER-1-Pro: direct link, hf CLI and curl.
- Browser
- Download file 2.95 kB
-
https://huggingface.co/jacobalansussman/TONER-1-Pro/resolve/main/src/export.py
- Command line
-
hf download hf://jacobalansussman/TONER-1-Pro/src/export.py
-
curl -L -o export.py https://huggingface.co/jacobalansussman/TONER-1-Pro/resolve/main/src/export.py
2.95 kB
| # Export llama2.c stories260K checkpoint to int8 (per-row) weights embedded in a PostScript file. | |
| import struct, sys, array | |
| ckpt, tokf, out = sys.argv[1], sys.argv[2], sys.argv[3] | |
| raw = open(ckpt,'rb').read() | |
| dim, hid, L, nh, nkv, V, seq = struct.unpack('7i', raw[:28]) | |
| shared = V > 0; V = abs(V) | |
| f = array.array('f'); f.frombytes(raw[28:]) | |
| hs = dim//nh; kvd = dim*nkv//nh | |
| p = 0 | |
| def take(n): | |
| global p | |
| a = f[p:p+n]; p += n; return a | |
| emb = take(V*dim); rms_att = take(L*dim); wq = take(L*dim*dim); wk = take(L*dim*kvd); wv = take(L*dim*kvd) | |
| wo = take(L*dim*dim); rms_ffn = take(L*dim); w1 = take(L*hid*dim); w2 = take(L*dim*hid); w3 = take(L*hid*dim) | |
| rms_f = take(dim) | |
| assert shared | |
| nparams = V*dim + L*(2*dim*dim + 2*dim*kvd + 3*dim*hid + 2*dim) + dim | |
| o = open(out,'w') | |
| def psarr(items, chunk=200): | |
| # build arrays in chunks so the operand stack never exceeds ~200 items (Adobe limit is 500) | |
| if len(items) <= chunk: return '[' + ' '.join(items) + ']' | |
| out = '%d array' % len(items) | |
| for i in range(0, len(items), chunk): | |
| out += ' dup %d [%s] putinterval\n' % (i, ' '.join(items[i:i+chunk])) | |
| return out | |
| def realarr(a): return psarr(['%.6g' % v for v in a]) | |
| def qrows(a, rows, cols): | |
| # returns PS text: [ [scales] [<hex> ...] ] | |
| sc=[]; hx=[] | |
| for r in range(rows): | |
| row = a[r*cols:(r+1)*cols] | |
| m = max(abs(v) for v in row) or 1e-8 | |
| s = m/127.0 | |
| b = bytes(max(1,min(255,int(round(v/s))+128)) for v in row) | |
| sc.append(s); hx.append('<'+b.hex()+'>') | |
| return '[' + realarr(sc) + '\n' + psarr(hx) + ']' | |
| o.write('%!PS-Adobe-3.0\n%%Title: TONER-1 (stories260K int8, PostScript inference)\n') | |
| o.write('/D %d def /HID %d def /NL %d def /NH %d def /NKV %d def /V %d def /SEQ %d def /HS %d def /KVD %d def /KVMUL %d def /NPARAMS %d def\n' % (dim,hid,L,nh,nkv,V,seq,hs,kvd,nh//nkv,nparams)) | |
| o.write('/EMB ' + qrows(emb, V, dim) + ' def\n') | |
| for name, t, r, c in [('WQ',wq,dim,dim),('WK',wk,kvd,dim),('WV',wv,kvd,dim),('WO',wo,dim,dim),('W1',w1,hid,dim),('W2',w2,dim,hid),('W3',w3,hid,dim)]: | |
| o.write('/%s [\n' % name) | |
| for l in range(L): | |
| o.write(qrows(t[l*r*c:(l+1)*r*c], r, c) + '\n') | |
| o.write('] def\n') | |
| o.write('/RMSATT [' + ' '.join(realarr(rms_att[l*dim:(l+1)*dim]) for l in range(L)) + '] def\n') | |
| o.write('/RMSFFN [' + ' '.join(realarr(rms_ffn[l*dim:(l+1)*dim]) for l in range(L)) + '] def\n') | |
| o.write('/RMSF ' + realarr(rms_f) + ' def\n') | |
| # tokenizer: decode pieces into raw bytes | |
| tb = open(tokf,'rb').read(); q = 4; pieces=[] | |
| for i in range(V): | |
| sc, ln = struct.unpack('fi', tb[q:q+8]); q += 8 | |
| s = tb[q:q+ln]; q += ln | |
| if len(s)==6 and s.startswith(b'<0x') and s.endswith(b'>'): | |
| s = bytes([int(s[3:5],16)]) | |
| pieces.append(s) | |
| o.write('/VOCAB ' + psarr(['<'+s.hex()+'>' for s in pieces]) + ' def\n') | |
| o.close() | |
| print('params', nparams, 'dim', dim, 'hid', hid, 'L', L, 'nh', nh, 'nkv', nkv, 'V', V, 'seq', seq, 'used floats', p, 'of', len(f)) | |