Files

32 lines
1.6 KiB
Python

#!/usr/bin/env python3
"""Read GGUF metadata/tensor descriptors only; never loads weights or invokes GPUs."""
import collections,json,pathlib,struct,sys
TYPES={0:'F32',1:'F16',2:'Q4_0',3:'Q4_1',6:'Q5_0',7:'Q5_1',8:'Q8_0',9:'Q8_1',10:'Q2_K',11:'Q3_K',12:'Q4_K',13:'Q5_K',14:'Q6_K',15:'Q8_K',16:'IQ2_XXS',17:'IQ2_XS',18:'IQ3_XXS',19:'IQ1_S',20:'IQ4_NL',21:'IQ3_S',22:'IQ2_S',23:'IQ4_XS',30:'BF16'}
def inspect(path):
with open(path,'rb') as f:
def read(fmt):return struct.unpack('<'+fmt,f.read(struct.calcsize('<'+fmt)))[0]
def string(keep=True):
n=read('Q')
if keep:return f.read(n).decode('utf-8')
f.seek(n,1)
def value(t,keep=False):
if t==8:return string(keep)
if t==9:
elem,n=read('I'),read('Q')
for _ in range(n):value(elem,False)
return None
fmt={0:'B',1:'b',2:'H',3:'h',4:'I',5:'i',6:'f',7:'?',10:'Q',11:'q',12:'d'}[t]
return read(fmt)
assert f.read(4)==b'GGUF'
version=read('I');assert version==3
tensors,metas=read('Q'),read('Q');meta={}
for _ in range(metas):
key=string();t=read('I');keep=key in ['general.name','general.architecture','general.file_type','general.quantization_version']
v=value(t,keep)
if keep:meta[key]=v
counts=collections.Counter()
for _ in range(tensors):
name=string();dims=read('I');shape=[read('Q') for _ in range(dims)];ty=read('I');offset=read('Q');counts[TYPES.get(ty,'type_'+str(ty))]+=1
return {'path':str(path),'bytes':pathlib.Path(path).stat().st_size,'metadata':meta,'tensor_count':tensors,'tensor_types':dict(counts),'descriptor_end':f.tell()}
print(json.dumps([inspect(p) for p in sys.argv[1:]],indent=2))