Spaces:
Running
Running
| import struct | |
| from enum import IntEnum | |
| class GGUFValueType(IntEnum): | |
| UINT8 = 0 | |
| INT8 = 1 | |
| UINT16 = 2 | |
| INT16 = 3 | |
| UINT32 = 4 | |
| INT32 = 5 | |
| FLOAT32 = 6 | |
| BOOL = 7 | |
| STRING = 8 | |
| ARRAY = 9 | |
| UINT64 = 10 | |
| INT64 = 11 | |
| FLOAT64 = 12 | |
| _simple_value_packing = { | |
| GGUFValueType.UINT8: "<B", | |
| GGUFValueType.INT8: "<b", | |
| GGUFValueType.UINT16: "<H", | |
| GGUFValueType.INT16: "<h", | |
| GGUFValueType.UINT32: "<I", | |
| GGUFValueType.INT32: "<i", | |
| GGUFValueType.FLOAT32: "<f", | |
| GGUFValueType.UINT64: "<Q", | |
| GGUFValueType.INT64: "<q", | |
| GGUFValueType.FLOAT64: "<d", | |
| GGUFValueType.BOOL: "?", | |
| } | |
| value_type_info = { | |
| GGUFValueType.UINT8: 1, | |
| GGUFValueType.INT8: 1, | |
| GGUFValueType.UINT16: 2, | |
| GGUFValueType.INT16: 2, | |
| GGUFValueType.UINT32: 4, | |
| GGUFValueType.INT32: 4, | |
| GGUFValueType.FLOAT32: 4, | |
| GGUFValueType.UINT64: 8, | |
| GGUFValueType.INT64: 8, | |
| GGUFValueType.FLOAT64: 8, | |
| GGUFValueType.BOOL: 1, | |
| } | |
| def get_single(value_type, file): | |
| if value_type == GGUFValueType.STRING: | |
| value_length = struct.unpack("<Q", file.read(8))[0] | |
| value = file.read(value_length) | |
| try: | |
| value = value.decode('utf-8') | |
| except: | |
| pass | |
| else: | |
| type_str = _simple_value_packing.get(value_type) | |
| bytes_length = value_type_info.get(value_type) | |
| value = struct.unpack(type_str, file.read(bytes_length))[0] | |
| return value | |
| def load_metadata(fname): | |
| metadata = {} | |
| with open(fname, 'rb') as file: | |
| GGUF_MAGIC = struct.unpack("<I", file.read(4))[0] | |
| GGUF_VERSION = struct.unpack("<I", file.read(4))[0] | |
| ti_data_count = struct.unpack("<Q", file.read(8))[0] | |
| kv_data_count = struct.unpack("<Q", file.read(8))[0] | |
| if GGUF_VERSION == 1: | |
| raise Exception('You are using an outdated GGUF, please download a new one.') | |
| for i in range(kv_data_count): | |
| key_length = struct.unpack("<Q", file.read(8))[0] | |
| key = file.read(key_length) | |
| value_type = GGUFValueType(struct.unpack("<I", file.read(4))[0]) | |
| if value_type == GGUFValueType.ARRAY: | |
| ltype = GGUFValueType(struct.unpack("<I", file.read(4))[0]) | |
| length = struct.unpack("<Q", file.read(8))[0] | |
| for j in range(length): | |
| _ = get_single(ltype, file) | |
| else: | |
| value = get_single(value_type, file) | |
| metadata[key.decode()] = value | |
| return metadata | |