コード例 #1
0
    def _read_array_header(file: BinaryIO) -> Tuple[int, int]:
        """
        Helper method to read the header of an NdArray chunk.

        The method reads the shape tuple, verifies the TypeId and seeks the file to the start
        of the array. The shape tuple is returned.

        Parameters
        ----------
        file : BinaryIO
            finalfusion file with a storage at the start of a NdArray chunk.

        Returns
        -------
        shape : Tuple[int, int]
            Shape of the storage.

        Raises
        ------
        FinalfusionFormatError
            If the TypeId does not match TypeId.f32
        """
        rows, cols = _read_required_binary(file, "<QI")
        type_id = TypeId(_read_required_binary(file, "<I")[0])
        if TypeId.f32 != type_id:
            raise FinalfusionFormatError(
                f"Invalid Type, expected {TypeId.f32}, got {type_id}")
        file.seek(_pad_float32(file.tell()), 1)
        return rows, cols
コード例 #2
0
 def write_chunk(self, file: BinaryIO):
     _write_binary(file, "<I", int(self.chunk_identifier()))
     padding = _pad_float32(file.tell())
     chunk_len = struct.calcsize("QI") + padding + struct.calcsize(
         f"<{self.size}f")
     _write_binary(file, f"<QQI{padding}x", chunk_len, self.size,
                   int(TypeId.f32))
     _serialize_array_as_le(file, self)
コード例 #3
0
 def write_chunk(self, file: BinaryIO):
     _write_binary(file, "<I", int(self.chunk_identifier()))
     padding = _pad_float32(file.tell())
     chunk_len = struct.calcsize("<QII") + padding + struct.calcsize(
         f'<{self.size}f')
     # pylint: disable=unpacking-non-sequence
     rows, cols = self.shape
     _write_binary(file, "<QQII", chunk_len, rows, cols, int(TypeId.f32))
     _write_binary(file, f"{padding}x")
     _serialize_array_as_le(file, self)
コード例 #4
0
 def read_chunk(file: BinaryIO) -> 'Norms':
     n_norms, dtype = _read_required_binary(file, "<QI")
     type_id = TypeId(dtype)
     if TypeId.f32 != type_id:
         raise FinalfusionFormatError(
             f"Invalid Type, expected {TypeId.f32}, got {str(type_id)}")
     padding = _pad_float32(file.tell())
     file.seek(padding, 1)
     array = np.fromfile(file=file, count=n_norms, dtype=np.float32)
     if sys.byteorder == "big":
         array.byteswap(inplace=True)
     return Norms(array)
コード例 #5
0
 def _read_quantized_header(
         file: BinaryIO
 ) -> Tuple[PQ, Tuple[int, int], Optional[np.ndarray]]:
     """
     Helper method to read the header of a quantized array chunk.
     Returns a tuple containing PQ, quantized_shape and optional norms.
     """
     projection = _read_required_binary(file, '<I')[0] != 0
     read_norms = _read_required_binary(file, '<I')[0] != 0
     quantized_len = _read_required_binary(file, '<I')[0]
     reconstructed_len = _read_required_binary(file, '<I')[0]
     n_centroids = _read_required_binary(file, '<I')[0]
     n_embeddings = _read_required_binary(file, '<Q')[0]
     assert reconstructed_len % quantized_len == 0
     type_id = _read_required_binary(file, '<I')[0]
     if int(TypeId.u8) != type_id:
         raise FinalfusionFormatError(
             f"Invalid Type, expected {str(TypeId.u8)}, got {type_id}")
     type_id = _read_required_binary(file, '<I')[0]
     if int(TypeId.f32) != type_id:
         raise FinalfusionFormatError(
             f"Invalid Type, expected {str(TypeId.f32)}, got {type_id}")
     file.seek(_pad_float32(file.tell()), 1)
     if projection:
         projection = _read_array_as_native(file, np.float32,
                                            reconstructed_len**2)
         projection_shape = (reconstructed_len, reconstructed_len)
         projection = projection.reshape(projection_shape)
     else:
         projection = None
     quantizer_shape = (quantized_len, n_centroids,
                        reconstructed_len // quantized_len)
     quantizers_size = quantized_len * n_centroids * (reconstructed_len //
                                                      quantized_len)
     quantizers = _read_array_as_native(file, np.float32, quantizers_size)
     quantizers = quantizers.reshape(quantizer_shape)
     if read_norms:
         norms = _read_array_as_native(file, np.float32, n_embeddings)
     else:
         norms = None
     quantizer = PQ(quantizers, projection)
     return quantizer, (n_embeddings, quantized_len), norms
コード例 #6
0
 def write_chunk(self, file: BinaryIO):
     _write_binary(file, "<I", int(self.chunk_identifier()))
     padding = _pad_float32(file.tell())
     chunk_len = struct.calcsize("<IIIIIQII") + padding
     proj = self._quantizer.projection is not None
     if proj:
         chunk_len += struct.calcsize(
             f"<{pow(self._quantizer.reconstructed_len, 2)}f")
     chunk_len += struct.calcsize(f"<{self._quantizer.subquantizers.size}f")
     norms = self._norms is not None
     if self._norms is not None:
         chunk_len += struct.calcsize(f"<{self._norms.size}f")
     chunk_len += self._quantized_embeddings.size
     chunk_header = (chunk_len, proj, norms, self.quantized_len,
                     self.shape[1], self.quantizer.n_centroids,
                     self.shape[0], int(TypeId.u8), int(TypeId.f32))
     _write_binary(file, "<QIIIIIQII", *chunk_header)
     file.write(struct.pack(f"{padding}x"))
     if proj:
         _serialize_array_as_le(file, self.quantizer.projection)
     _serialize_array_as_le(file, self.quantizer.subquantizers)
     if norms:
         _serialize_array_as_le(file, self._norms)
     self._quantized_embeddings.tofile(file)