Compare "GGUF" with file header char by char

1.  Set GGUF_MAGIC to "GGUF" string instead of int value
2. Compare "GGUF" char by char to ensure its byte order
3. Move bytes swap code from convert.py to gguf.py write_tensor_data
This commit is contained in:
chenqiny 2023-10-20 18:45:19 +08:00
parent e513abe37e
commit eb5b8327f6
5 changed files with 15 additions and 22 deletions

View file

@ -932,8 +932,6 @@ class OutputFile:
elapsed = time.time() - start elapsed = time.time() - start
size = ' x '.join(f"{dim:6d}" for dim in lazy_tensor.shape) size = ' x '.join(f"{dim:6d}" for dim in lazy_tensor.shape)
padi = len(str(len(model))) padi = len(str(len(model)))
if endianess==gguf.GGUFEndian.BIG:
ndarray.byteswap(inplace=True)
print(f"[{i+1:{padi}d}/{len(model)}] Writing tensor {name:38s} | size {size:16} | type {lazy_tensor.data_type.name:4} | T+{int(elapsed):4}") print(f"[{i+1:{padi}d}/{len(model)}] Writing tensor {name:38s} | size {size:16} | type {lazy_tensor.data_type.name:4} | T+{int(elapsed):4}")
of.gguf.write_tensor_data(ndarray) of.gguf.write_tensor_data(ndarray)

View file

@ -536,7 +536,7 @@ static bool is_ggml_file(const char * filename) {
if (file.size < 4) { if (file.size < 4) {
return false; return false;
} }
uint32_t magic = file.read_u32(); std::string magic = file.read_string(4);
return magic == GGUF_MAGIC; return magic == GGUF_MAGIC;
} }

19
ggml.c
View file

@ -20813,7 +20813,7 @@ struct gguf_kv {
}; };
struct gguf_header { struct gguf_header {
uint32_t magic; char magic[4];
uint32_t version; uint32_t version;
uint64_t n_tensors; // GGUFv2 uint64_t n_tensors; // GGUFv2
uint64_t n_kv; // GGUFv2 uint64_t n_kv; // GGUFv2
@ -20883,7 +20883,7 @@ static bool gguf_fread_str_v1(FILE * file, struct gguf_str * p, size_t * offset)
struct gguf_context * gguf_init_empty(void) { struct gguf_context * gguf_init_empty(void) {
struct gguf_context * ctx = GGML_ALIGNED_MALLOC(sizeof(struct gguf_context)); struct gguf_context * ctx = GGML_ALIGNED_MALLOC(sizeof(struct gguf_context));
ctx->header.magic = GGUF_MAGIC; memcpy(ctx->header.magic, GGUF_MAGIC, sizeof(ctx->header.magic));
ctx->header.version = GGUF_VERSION; ctx->header.version = GGUF_VERSION;
ctx->header.n_tensors = 0; ctx->header.n_tensors = 0;
ctx->header.n_kv = 0; ctx->header.n_kv = 0;
@ -20909,16 +20909,18 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p
// offset from start of file // offset from start of file
size_t offset = 0; size_t offset = 0;
uint32_t magic = 0; char magic[4];
// check the magic before making allocations // check the magic before making allocations
{ {
gguf_fread_el(file, &magic, sizeof(magic), &offset); gguf_fread_el(file, &magic, sizeof(magic), &offset);
if (magic != GGUF_MAGIC) { for (uint32_t i = 0; i < sizeof(magic); i++) {
fprintf(stderr, "%s: invalid magic number %08x\n", __func__, magic); if (magic[i] != GGUF_MAGIC[i]) {
fclose(file); fprintf(stderr, "%s: invalid magic characters %s.\n", __func__, magic);
return NULL; fclose(file);
return NULL;
}
} }
} }
@ -20928,7 +20930,8 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p
// read the header // read the header
{ {
ctx->header.magic = magic; strncpy(ctx->header.magic, magic, 4);
ctx->kv = NULL; ctx->kv = NULL;
ctx->infos = NULL; ctx->infos = NULL;

12
ggml.h
View file

@ -231,17 +231,7 @@
#define GGML_EXIT_SUCCESS 0 #define GGML_EXIT_SUCCESS 0
#define GGML_EXIT_ABORTED 1 #define GGML_EXIT_ABORTED 1
#if defined(__linux__) #define GGUF_MAGIC "GGUF"
#include <endian.h>
#if BYTE_ORDER == LITTLE_ENDIAN
#define GGUF_MAGIC 0x46554747
#elif BYTE_ORDER == BIG_ENDIAN
#define GGUF_MAGIC 0x47475546
#endif
#else
// Use little endian magic uint_32 value
#define GGUF_MAGIC 0x46554747
#endif
#define GGUF_VERSION 3 #define GGUF_VERSION 3

View file

@ -804,6 +804,8 @@ class GGUFWriter:
fp.write(bytes([0] * pad)) fp.write(bytes([0] * pad))
def write_tensor_data(self, tensor: np.ndarray[Any, Any]): def write_tensor_data(self, tensor: np.ndarray[Any, Any]):
if self.endianess==GGUFEndian.BIG:
tensor.byteswap(inplace=True)
self.write_padding(self.fout, self.fout.tell()) self.write_padding(self.fout, self.fout.tell())
tensor.tofile(self.fout) tensor.tofile(self.fout)
self.write_padding(self.fout, tensor.nbytes) self.write_padding(self.fout, tensor.nbytes)