12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- # Copyright (c) Meta Platforms, Inc. and affiliates.
- # All rights reserved.
- # This source code is licensed under the license found in the
- # LICENSE file in the root directory of this source tree.
- import struct
- from io import BufferedWriter
- import torch
- from ggml.examples.unity.type_utils import to_ctype
- class BufferedGGMLWriter:
- buffer: BufferedWriter
- def __init__(self, buffer: BufferedWriter) -> None:
- self.buffer = buffer
- def write_magic_hex(self) -> None:
- """Write GGML Magic Number to internal buffer.
- This should be called at the start of your convert process.
- """
- self.buffer.write(struct.pack("i", 0x67676d6c))
- def write_hparams(self, hparams: dict) -> None:
- """Write hyper parameters to internal buffer.
- :params hparams:
- flattened dict containing model's hyper parameters.
- """
- for key in hparams.keys():
- try:
- value = hparams[key]
- ctype, cvalue = to_ctype(value)
- self.buffer.write(struct.pack(ctype, cvalue))
- except ValueError as e:
- # TODO use logger
- print(f"[Warning] {e}. Skipping config for key {key}")
- continue
- def write_state_dict(self, state_dict: dict) -> None:
- """Write pytorch state dict to internal buffer.
- :paras state_dict:
- state dict returned by pytorch model
- """
- for key, value in state_dict.items():
- self.write_string(key)
- self.write_tensor(value)
- def write_string(self, value: str) -> None:
- """Write string in utf-8 format to internal buffer.
- :params value:
- string value to dump.
- """
- str_ = value.encode("utf-8")
- self.buffer.write(struct.pack("i", len(str_)))
- self.buffer.write(str_)
- def write_tensor(self, value: torch.Tensor) -> None:
- """Write torch tensor in ggml format to internal buffer.
- First we save the number of dimensions and the dtype.
- Then we save the data as numpy array.
- :params value:
- Tensor to dump.
- """
- data = value.squeeze().numpy()
- n_dims = len(data.shape)
- # TODO: Convert to fp16 when necessary!
- ftype = 0
- self.buffer.write(struct.pack("ii", n_dims, ftype))
- for i in range(n_dims):
- self.buffer.write(struct.pack("i", data.shape[n_dims - 1 - i]))
- data.tofile(self.buffer)
|