Skip to content

Commit d82b7a7

Browse files
gguf-py : fix passing non-native endian tensors (editor-gui and new-metadata) (#17553)
gguf_new_metadata.py reads data from reader. Reader doesn't byteswap tensors to native endianness. But writer does expect tensors in native endianness to convert them into requested endianness. There are two ways to fix this: update reader and do conversion to native endianness and back, or skip converting endianness in writer in this particular USE-case. gguf_editor_gui.py doesn't allow editing or viewing tensor data. Let's go with skipping excessive byteswapping. If eventually capability to view or edit tensor data is added, tensor data should be instead byteswapped when reading it.
1 parent 03914c7 commit d82b7a7

File tree

3 files changed

+14
-8
lines changed

3 files changed

+14
-8
lines changed

gguf-py/gguf/gguf_writer.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -371,10 +371,13 @@ def add_tensor_info(
371371

372372
def add_tensor(
373373
self, name: str, tensor: np.ndarray[Any, Any], raw_shape: Sequence[int] | None = None,
374-
raw_dtype: GGMLQuantizationType | None = None,
374+
raw_dtype: GGMLQuantizationType | None = None, tensor_endianess: GGUFEndian | None = None
375375
) -> None:
376-
if (self.endianess == GGUFEndian.BIG and sys.byteorder != 'big') or \
377-
(self.endianess == GGUFEndian.LITTLE and sys.byteorder != 'little'):
376+
# if tensor endianness is not passed, assume it's native to system
377+
if tensor_endianess is None:
378+
tensor_endianess = GGUFEndian.BIG if sys.byteorder == 'big' else GGUFEndian.LITTLE
379+
380+
if tensor_endianess != self.endianess:
378381
# Don't byteswap inplace since lazy copies cannot handle it
379382
tensor = tensor.byteswap(inplace=False)
380383
if self.use_temp_file and self.temp_file is None:
@@ -397,13 +400,16 @@ def write_padding(self, fp: IO[bytes], n: int, align: int | None = None) -> None
397400
if pad != 0:
398401
fp.write(bytes([0] * pad))
399402

400-
def write_tensor_data(self, tensor: np.ndarray[Any, Any]) -> None:
403+
def write_tensor_data(self, tensor: np.ndarray[Any, Any], tensor_endianess: GGUFEndian | None = None) -> None:
401404
if self.state is not WriterState.TI_DATA and self.state is not WriterState.WEIGHTS:
402405
raise ValueError(f'Expected output file to contain tensor info or weights, got {self.state}')
403406
assert self.fout is not None
404407

405-
if (self.endianess == GGUFEndian.BIG and sys.byteorder != 'big') or \
406-
(self.endianess == GGUFEndian.LITTLE and sys.byteorder != 'little'):
408+
# if tensor endianness is not passed, assume it's native to system
409+
if tensor_endianess is None:
410+
tensor_endianess = GGUFEndian.BIG if sys.byteorder == 'big' else GGUFEndian.LITTLE
411+
412+
if tensor_endianess != self.endianess:
407413
# Don't byteswap inplace since lazy copies cannot handle it
408414
tensor = tensor.byteswap(inplace=False)
409415

gguf-py/gguf/scripts/gguf_editor_gui.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1552,7 +1552,7 @@ def save_file(self):
15521552

15531553
# Add tensors (including data)
15541554
for tensor in self.reader.tensors:
1555-
writer.add_tensor(tensor.name, tensor.data, raw_shape=tensor.data.shape, raw_dtype=tensor.tensor_type)
1555+
writer.add_tensor(tensor.name, tensor.data, raw_shape=tensor.data.shape, raw_dtype=tensor.tensor_type, tensor_endianess=self.reader.endianess)
15561556

15571557
# Write header and metadata
15581558
writer.open_output_file(Path(file_path))

gguf-py/gguf/scripts/gguf_new_metadata.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def copy_with_new_metadata(reader: gguf.GGUFReader, writer: gguf.GGUFWriter, new
9494
writer.write_ti_data_to_file()
9595

9696
for tensor in reader.tensors:
97-
writer.write_tensor_data(tensor.data)
97+
writer.write_tensor_data(tensor.data, tensor_endianess=reader.endianess)
9898
bar.update(tensor.n_bytes)
9999

100100
writer.close()

0 commit comments

Comments
 (0)