ggufmeta.py
1.35 KB
import struct,sys
f=open(sys.argv[1],'rb')
def rd(n): return f.read(n)
def u32(): return struct.unpack('<I',rd(4))[0]
def u64(): return struct.unpack('<Q',rd(8))[0]
assert rd(4)==b'GGUF'
ver=u32(); nt=u64(); nkv=u64()
def s():
return rd(u64()).decode('utf-8','replace')
def val(t):
if t==0: return struct.unpack('<B',rd(1))[0]
if t==1: return struct.unpack('<b',rd(1))[0]
if t==2: return struct.unpack('<H',rd(2))[0]
if t==3: return struct.unpack('<h',rd(2))[0]
if t==4: return u32()
if t==5: return struct.unpack('<i',rd(4))[0]
if t==6: return struct.unpack('<f',rd(4))[0]
if t==7: return struct.unpack('<?',rd(1))[0]
if t==8: return s()
if t==9:
et=u32(); n=u64()
out=[s() if et==8 else val(et) for _ in range(n)] # 必须全部消费掉,否则后续偏移错位
return out if n<=8 else f'<array n={n}, 首项 {out[0]!r}>'
if t==10: return u64()
if t==11: return struct.unpack('<q',rd(8))[0]
if t==12: return struct.unpack('<d',rd(8))[0]
raise ValueError(t)
print(f'gguf_version={ver} tensors={nt} kv={nkv}')
for _ in range(nkv):
k=s(); t=u32(); v=val(t)
if any(x in k for x in ('context_length','rope','yarn','attention','block_count','head_count','embedding_length','architecture','name','key_length','value_length','interval','linear','ssm','file_type')):
print(f'{k} = {v}')