From a06767b391b79c56329a919cba8860e73868310d Mon Sep 17 00:00:00 2001 From: Riceball LEE Date: Fri, 26 Jan 2024 21:26:08 +0800 Subject: [PATCH] feat: add basic support to GGUF_TYPE_OBJ on cpp --- examples/llava/clip.cpp | 3 ++- ggml.c | 40 +++++++++++++++++++++++++++++++++++----- ggml.h | 2 ++ llama.cpp | 5 +++-- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/examples/llava/clip.cpp b/examples/llava/clip.cpp index 4a0338a3767750..c2b78ea51e5958 100644 --- a/examples/llava/clip.cpp +++ b/examples/llava/clip.cpp @@ -185,6 +185,7 @@ static std::string gguf_kv_to_str(const struct gguf_context * ctx_gguf, int i) { switch (type) { case GGUF_TYPE_STRING: return gguf_get_val_str(ctx_gguf, i); + case GGUF_TYPE_OBJ: case GGUF_TYPE_ARRAY: { const enum gguf_type arr_type = gguf_get_arr_type(ctx_gguf, i); @@ -753,7 +754,7 @@ struct clip_ctx * clip_model_load(const char * fname, const int verbosity = 1) { const char * name = gguf_get_key(ctx, i); const enum gguf_type type = gguf_get_kv_type(ctx, i); const std::string type_name = - type == GGUF_TYPE_ARRAY + type == GGUF_TYPE_ARRAY || type == GGUF_TYPE_OBJ ? format("%s[%s,%d]", gguf_type_name(type), gguf_type_name(gguf_get_arr_type(ctx, i)), gguf_get_arr_n(ctx, i)) : gguf_type_name(type); diff --git a/ggml.c b/ggml.c index 8f57003e0ac9c6..354ac3e5616ce3 100644 --- a/ggml.c +++ b/ggml.c @@ -19082,8 +19082,9 @@ static const size_t GGUF_TYPE_SIZE[GGUF_TYPE_COUNT] = { [GGUF_TYPE_INT64] = sizeof(int64_t), [GGUF_TYPE_FLOAT64] = sizeof(double), [GGUF_TYPE_ARRAY] = 0, // undefined + [GGUF_TYPE_OBJ] = 0, // undefined }; -static_assert(GGUF_TYPE_COUNT == 13, "GGUF_TYPE_COUNT != 13"); +static_assert(GGUF_TYPE_COUNT == 14, "GGUF_TYPE_COUNT != 14"); static const char * GGUF_TYPE_NAME[GGUF_TYPE_COUNT] = { [GGUF_TYPE_UINT8] = "u8", @@ -19099,8 +19100,9 @@ static const char * GGUF_TYPE_NAME[GGUF_TYPE_COUNT] = { [GGUF_TYPE_UINT64] = "u64", [GGUF_TYPE_INT64] = "i64", [GGUF_TYPE_FLOAT64] = "f64", + [GGUF_TYPE_OBJ] = "obj", }; -static_assert(GGUF_TYPE_COUNT == 13, "GGUF_TYPE_COUNT != 13"); +static_assert(GGUF_TYPE_COUNT == 14, "GGUF_TYPE_COUNT != 14"); union gguf_value { uint8_t uint8; @@ -19289,6 +19291,7 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p case GGUF_TYPE_FLOAT64: ok = ok && gguf_fread_el (file, &kv->value.float64, sizeof(kv->value.float64), &offset); break; case GGUF_TYPE_BOOL: ok = ok && gguf_fread_el (file, &kv->value.bool_, sizeof(kv->value.bool_), &offset); break; case GGUF_TYPE_STRING: ok = ok && gguf_fread_str(file, &kv->value.str, &offset); break; + case GGUF_TYPE_OBJ: case GGUF_TYPE_ARRAY: { ok = ok && gguf_fread_el(file, &kv->value.arr.type, sizeof(kv->value.arr.type), &offset); @@ -19317,6 +19320,7 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p ok = ok && gguf_fread_str(file, &((struct gguf_str *) kv->value.arr.data)[j], &offset); } } break; + case GGUF_TYPE_OBJ: case GGUF_TYPE_ARRAY: case GGUF_TYPE_COUNT: GGML_ASSERT(false && "invalid type"); break; } @@ -19518,7 +19522,7 @@ void gguf_free(struct gguf_context * ctx) { } } - if (kv->type == GGUF_TYPE_ARRAY) { + if (kv->type == GGUF_TYPE_ARRAY || kv->type == GGUF_TYPE_OBJ) { if (kv->value.arr.data) { if (kv->value.arr.type == GGUF_TYPE_STRING) { for (uint64_t j = 0; j < kv->value.arr.n; ++j) { @@ -19615,7 +19619,7 @@ const void * gguf_get_arr_data(const struct gguf_context * ctx, int key_id) { const char * gguf_get_arr_str(const struct gguf_context * ctx, int key_id, int i) { GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx)); - GGML_ASSERT(ctx->kv[key_id].type == GGUF_TYPE_ARRAY); + GGML_ASSERT(ctx->kv[key_id].type == GGUF_TYPE_ARRAY || ctx->kv[key_id].type == GGUF_TYPE_OBJ); struct gguf_kv * kv = &ctx->kv[key_id]; struct gguf_str * str = &((struct gguf_str *) kv->value.arr.data)[i]; return str->data; @@ -19623,7 +19627,7 @@ const char * gguf_get_arr_str(const struct gguf_context * ctx, int key_id, int i int gguf_get_arr_n(const struct gguf_context * ctx, int key_id) { GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx)); - GGML_ASSERT(ctx->kv[key_id].type == GGUF_TYPE_ARRAY); + GGML_ASSERT(ctx->kv[key_id].type == GGUF_TYPE_ARRAY || ctx->kv[key_id].type == GGUF_TYPE_OBJ); return ctx->kv[key_id].value.arr.n; } @@ -19702,6 +19706,7 @@ const char * gguf_get_val_str(const struct gguf_context * ctx, int key_id) { const void * gguf_get_val_data(const struct gguf_context * ctx, int key_id) { GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx)); GGML_ASSERT(ctx->kv[key_id].type != GGUF_TYPE_ARRAY); + GGML_ASSERT(ctx->kv[key_id].type != GGUF_TYPE_OBJ); GGML_ASSERT(ctx->kv[key_id].type != GGUF_TYPE_STRING); return &ctx->kv[key_id].value; } @@ -19864,6 +19869,20 @@ void gguf_set_arr_str(struct gguf_context * ctx, const char * key, const char ** } } +void gguf_set_obj_str(struct gguf_context * ctx, const char * key, const char ** data, int n) { + const int idx = gguf_get_or_add_key(ctx, key); + + ctx->kv[idx].type = GGUF_TYPE_OBJ; + ctx->kv[idx].value.arr.type = GGUF_TYPE_STRING; + ctx->kv[idx].value.arr.n = n; + ctx->kv[idx].value.arr.data = malloc(n*sizeof(struct gguf_str)); + for (int i = 0; i < n; i++) { + struct gguf_str * str = &((struct gguf_str *)ctx->kv[idx].value.arr.data)[i]; + str->n = strlen(data[i]); + str->data = strdup(data[i]); + } +} + // set or add KV pairs from another context void gguf_set_kv(struct gguf_context * ctx, struct gguf_context * src) { for (uint32_t i = 0; i < src->header.n_kv; i++) { @@ -19880,6 +19899,15 @@ void gguf_set_kv(struct gguf_context * ctx, struct gguf_context * src) { case GGUF_TYPE_FLOAT64: gguf_set_val_f64 (ctx, src->kv[i].key.data, src->kv[i].value.float64); break; case GGUF_TYPE_BOOL: gguf_set_val_bool(ctx, src->kv[i].key.data, src->kv[i].value.bool_); break; case GGUF_TYPE_STRING: gguf_set_val_str (ctx, src->kv[i].key.data, src->kv[i].value.str.data); break; + case GGUF_TYPE_OBJ: + { + const char ** data = malloc(src->kv[i].value.arr.n*sizeof(char *)); + for (uint32_t j = 0; j < src->kv[i].value.arr.n; j++) { + data[j] = ((struct gguf_str *)src->kv[i].value.arr.data)[j].data; + } + gguf_set_obj_str(ctx, src->kv[i].key.data, data, src->kv[i].value.arr.n); + free((void *)data); + } break; case GGUF_TYPE_ARRAY: { if (src->kv[i].value.arr.type == GGUF_TYPE_STRING) { @@ -20044,6 +20072,7 @@ static void gguf_write_to_buf(const struct gguf_context * ctx, struct gguf_buf * case GGUF_TYPE_FLOAT64: gguf_bwrite_el (buf, &kv->value.float64, sizeof(kv->value.float64)); break; case GGUF_TYPE_BOOL: gguf_bwrite_el (buf, &kv->value.bool_, sizeof(kv->value.bool_) ); break; case GGUF_TYPE_STRING: gguf_bwrite_str(buf, &kv->value.str ); break; + case GGUF_TYPE_OBJ: case GGUF_TYPE_ARRAY: { gguf_bwrite_el(buf, &kv->value.arr.type, sizeof(kv->value.arr.type)); @@ -20070,6 +20099,7 @@ static void gguf_write_to_buf(const struct gguf_context * ctx, struct gguf_buf * gguf_bwrite_str(buf, &((struct gguf_str *) kv->value.arr.data)[j]); } } break; + case GGUF_TYPE_OBJ: case GGUF_TYPE_ARRAY: case GGUF_TYPE_COUNT: GGML_ASSERT(false && "invalid type"); break; } diff --git a/ggml.h b/ggml.h index 1c497627167742..404a53e9050175 100644 --- a/ggml.h +++ b/ggml.h @@ -2138,6 +2138,7 @@ extern "C" { GGUF_TYPE_UINT64 = 10, GGUF_TYPE_INT64 = 11, GGUF_TYPE_FLOAT64 = 12, + GGUF_TYPE_OBJ = 13, GGUF_TYPE_COUNT, // marks the end of the enum }; @@ -2209,6 +2210,7 @@ extern "C" { GGML_API void gguf_set_val_str (struct gguf_context * ctx, const char * key, const char * val); GGML_API void gguf_set_arr_data(struct gguf_context * ctx, const char * key, enum gguf_type type, const void * data, int n); GGML_API void gguf_set_arr_str (struct gguf_context * ctx, const char * key, const char ** data, int n); + GGML_API void gguf_set_obj_str (struct gguf_context * ctx, const char * key, const char ** data, int n); // set or add KV pairs from another context GGML_API void gguf_set_kv(struct gguf_context * ctx, struct gguf_context * src); diff --git a/llama.cpp b/llama.cpp index b03b67e169955c..77dae7f49290d1 100644 --- a/llama.cpp +++ b/llama.cpp @@ -738,6 +738,7 @@ static std::string gguf_kv_to_str(const struct gguf_context * ctx_gguf, int i) { switch (type) { case GGUF_TYPE_STRING: return gguf_get_val_str(ctx_gguf, i); + case GGUF_TYPE_OBJ: case GGUF_TYPE_ARRAY: { const enum gguf_type arr_type = gguf_get_arr_type(ctx_gguf, i); @@ -2117,7 +2118,7 @@ namespace GGUFMeta { static T get_kv(const gguf_context * ctx, const int k) { const enum gguf_type kt = gguf_get_kv_type(ctx, k); - if (kt != GKV::gt) { + if (kt != GKV::gt && kt != GGUF_TYPE_OBJ && GKV::gt != GGUF_TYPE_ARRAY) { throw std::runtime_error(format("key %s has wrong type %s but expected type %s", gguf_get_key(ctx, k), gguf_type_name(kt), gguf_type_name(GKV::gt))); } @@ -2345,7 +2346,7 @@ struct llama_model_loader { const char * name = gguf_get_key(ctx_gguf, i); const enum gguf_type type = gguf_get_kv_type(ctx_gguf, i); const std::string type_name = - type == GGUF_TYPE_ARRAY + type == GGUF_TYPE_ARRAY || type == GGUF_TYPE_OBJ ? format("%s[%s,%d]", gguf_type_name(type), gguf_type_name(gguf_get_arr_type(ctx_gguf, i)), gguf_get_arr_n(ctx_gguf, i)) : gguf_type_name(type);