@@ -69,6 +69,7 @@ class GGUFReader:
69
69
# I - same as host, S - swapped
70
70
byte_order : Literal ['I' ] | Literal ['S' ] = 'I'
71
71
alignment : int = GGUF_DEFAULT_ALIGNMENT
72
+ data_offset : int
72
73
73
74
# Note: Internal helper, API may change.
74
75
gguf_scalar_to_np : dict [GGUFValueType , type [np .generic ]] = {
@@ -88,9 +89,13 @@ class GGUFReader:
88
89
def __init__ (self , path : os .PathLike [str ] | str , mode : Literal ['r' ] | Literal ['r+' ] | Literal ['c' ] = 'r' ):
89
90
self .data = np .memmap (path , mode = mode )
90
91
offs = 0
92
+
93
+ # Check for GGUF magic
91
94
if self ._get (offs , np .uint32 , override_order = '<' )[0 ] != GGUF_MAGIC :
92
95
raise ValueError ('GGUF magic invalid' )
93
96
offs += 4
97
+
98
+ # Check GGUF version
94
99
temp_version = self ._get (offs , np .uint32 )
95
100
if temp_version [0 ] & 65535 == 0 :
96
101
# If we get 0 here that means it's (probably) a GGUF file created for
@@ -103,12 +108,16 @@ def __init__(self, path: os.PathLike[str] | str, mode: Literal['r'] | Literal['r
103
108
self .fields : OrderedDict [str , ReaderField ] = OrderedDict ()
104
109
self .tensors : list [ReaderTensor ] = []
105
110
offs += self ._push_field (ReaderField (offs , 'GGUF.version' , [temp_version ], [0 ], [GGUFValueType .UINT32 ]))
111
+
112
+ # Check tensor count and kv count
106
113
temp_counts = self ._get (offs , np .uint64 , 2 )
107
114
offs += self ._push_field (ReaderField (offs , 'GGUF.tensor_count' , [temp_counts [:1 ]], [0 ], [GGUFValueType .UINT64 ]))
108
115
offs += self ._push_field (ReaderField (offs , 'GGUF.kv_count' , [temp_counts [1 :]], [0 ], [GGUFValueType .UINT64 ]))
109
116
tensor_count , kv_count = temp_counts
110
117
offs = self ._build_fields (offs , kv_count )
111
- offs , tensors_fields = self ._build_tensors_fields (offs , tensor_count )
118
+
119
+ # Build Tensor Info Fields
120
+ offs , tensors_fields = self ._build_tensor_info (offs , tensor_count )
112
121
new_align = self .fields .get ('general.alignment' )
113
122
if new_align is not None :
114
123
if new_align .types != [GGUFValueType .UINT32 ]:
@@ -117,6 +126,7 @@ def __init__(self, path: os.PathLike[str] | str, mode: Literal['r'] | Literal['r
117
126
padding = offs % self .alignment
118
127
if padding != 0 :
119
128
offs += self .alignment - padding
129
+ self .data_offset = offs
120
130
self ._build_tensors (offs , tensors_fields )
121
131
122
132
_DT = TypeVar ('_DT' , bound = npt .DTypeLike )
@@ -193,18 +203,29 @@ def _get_field_parts(
193
203
# We can't deal with this one.
194
204
raise ValueError ('Unknown/unhandled field type {gtype}' )
195
205
196
- def _get_tensor (self , orig_offs : int ) -> ReaderField :
206
+ def _get_tensor_info_field (self , orig_offs : int ) -> ReaderField :
197
207
offs = orig_offs
208
+
209
+ # Get Tensor Name
198
210
name_len , name_data = self ._get_str (offs )
199
211
offs += int (name_len .nbytes + name_data .nbytes )
212
+
213
+ # Get Tensor Dimensions Count
200
214
n_dims = self ._get (offs , np .uint32 )
201
215
offs += int (n_dims .nbytes )
216
+
217
+ # Get Tensor Dimension Array
202
218
dims = self ._get (offs , np .uint64 , n_dims [0 ])
203
219
offs += int (dims .nbytes )
220
+
221
+ # Get Tensor Encoding Scheme Type
204
222
raw_dtype = self ._get (offs , np .uint32 )
205
223
offs += int (raw_dtype .nbytes )
224
+
225
+ # Get Tensor Offset
206
226
offset_tensor = self ._get (offs , np .uint64 )
207
227
offs += int (offset_tensor .nbytes )
228
+
208
229
return ReaderField (
209
230
orig_offs ,
210
231
str (bytes (name_data ), encoding = 'utf-8' ),
@@ -233,10 +254,10 @@ def _build_fields(self, offs: int, count: int) -> int:
233
254
offs += field_size
234
255
return offs
235
256
236
- def _build_tensors_fields (self , offs : int , count : int ) -> tuple [int , list [ReaderField ]]:
257
+ def _build_tensor_info (self , offs : int , count : int ) -> tuple [int , list [ReaderField ]]:
237
258
tensor_fields = []
238
259
for _ in range (count ):
239
- field = self ._get_tensor (offs )
260
+ field = self ._get_tensor_info_field (offs )
240
261
offs += sum (int (part .nbytes ) for part in field .parts )
241
262
tensor_fields .append (field )
242
263
return offs , tensor_fields
0 commit comments