KBaba7/llama.cpp
0
1#include "ggml.h"2#include "gguf.h"3 4#include <cstdio>5#include <string>6#include <sstream>7#include <vector>8 9#undef MIN10#undef MAX11#define MIN(a, b) ((a) < (b) ? (a) : (b))12#define MAX(a, b) ((a) > (b) ? (a) : (b))13 14template <typename T>15static std::string to_string(const T & val) {16 std::stringstream ss;17 ss << val;18 return ss.str();19}20 21static bool gguf_ex_write(const std::string & fname) {22 struct gguf_context * ctx = gguf_init_empty();23 24 gguf_set_val_u8 (ctx, "some.parameter.uint8", 0x12);25 gguf_set_val_i8 (ctx, "some.parameter.int8", -0x13);26 gguf_set_val_u16 (ctx, "some.parameter.uint16", 0x1234);27 gguf_set_val_i16 (ctx, "some.parameter.int16", -0x1235);28 gguf_set_val_u32 (ctx, "some.parameter.uint32", 0x12345678);29 gguf_set_val_i32 (ctx, "some.parameter.int32", -0x12345679);30 gguf_set_val_f32 (ctx, "some.parameter.float32", 0.123456789f);31 gguf_set_val_u64 (ctx, "some.parameter.uint64", 0x123456789abcdef0ull);32 gguf_set_val_i64 (ctx, "some.parameter.int64", -0x123456789abcdef1ll);33 gguf_set_val_f64 (ctx, "some.parameter.float64", 0.1234567890123456789);34 gguf_set_val_bool(ctx, "some.parameter.bool", true);35 gguf_set_val_str (ctx, "some.parameter.string", "hello world");36 37 gguf_set_arr_data(ctx, "some.parameter.arr.i16", GGUF_TYPE_INT16, std::vector<int16_t>{ 1, 2, 3, 4, }.data(), 4);38 gguf_set_arr_data(ctx, "some.parameter.arr.f32", GGUF_TYPE_FLOAT32, std::vector<float>{ 3.145f, 2.718f, 1.414f, }.data(), 3);39 gguf_set_arr_str (ctx, "some.parameter.arr.str", std::vector<const char *>{ "hello", "world", "!" }.data(), 3);40 41 struct ggml_init_params params = {42 /*.mem_size =*/ 128ull*1024ull*1024ull,43 /*.mem_buffer =*/ NULL,44 /*.no_alloc =*/ false,45 };46 47 struct ggml_context * ctx_data = ggml_init(params);48 49 const int n_tensors = 10;50 51 // tensor infos52 for (int i = 0; i < n_tensors; ++i) {53 const std::string name = "tensor_" + to_string(i);54 55 int64_t ne[GGML_MAX_DIMS] = { 1 };56 int32_t n_dims = rand() % GGML_MAX_DIMS + 1;57 58 for (int j = 0; j < n_dims; ++j) {59 ne[j] = rand() % 10 + 1;60 }61 62 struct ggml_tensor * cur = ggml_new_tensor(ctx_data, GGML_TYPE_F32, n_dims, ne);63 ggml_set_name(cur, name.c_str());64 65 {66 float * data = (float *) cur->data;67 for (int j = 0; j < ggml_nelements(cur); ++j) {68 data[j] = 100 + i;69 }70 }71 72 gguf_add_tensor(ctx, cur);73 }74 75 gguf_write_to_file(ctx, fname.c_str(), false);76 77 printf("%s: wrote file '%s;\n", __func__, fname.c_str());78 79 ggml_free(ctx_data);80 gguf_free(ctx);81 82 return true;83}84 85// just read tensor info86static bool gguf_ex_read_0(const std::string & fname) {87 struct gguf_init_params params = {88 /*.no_alloc = */ false,89 /*.ctx = */ NULL,90 };91 92 struct gguf_context * ctx = gguf_init_from_file(fname.c_str(), params);93 94 if (!ctx) {95 fprintf(stderr, "%s: failed to load '%s'\n", __func__, fname.c_str());96 return false;97 }98 99 printf("%s: version: %d\n", __func__, gguf_get_version(ctx));100 printf("%s: alignment: %zu\n", __func__, gguf_get_alignment(ctx));101 printf("%s: data offset: %zu\n", __func__, gguf_get_data_offset(ctx));102 103 // kv104 {105 const int n_kv = gguf_get_n_kv(ctx);106 107 printf("%s: n_kv: %d\n", __func__, n_kv);108 109 for (int i = 0; i < n_kv; ++i) {110 const char * key = gguf_get_key(ctx, i);111 112 printf("%s: kv[%d]: key = %s\n", __func__, i, key);113 }114 }115 116 // find kv string117 {118 const char * findkey = "some.parameter.string";119 120 const int keyidx = gguf_find_key(ctx, findkey);121 if (keyidx == -1) {122 printf("%s: find key: %s not found.\n", __func__, findkey);123 } else {124 const char * key_value = gguf_get_val_str(ctx, keyidx);125 printf("%s: find key: %s found, kv[%d] value = %s\n", __func__, findkey, keyidx, key_value);126 }127 }128 129 // tensor info130 {131 const int n_tensors = gguf_get_n_tensors(ctx);132 133 printf("%s: n_tensors: %d\n", __func__, n_tensors);134 135 for (int i = 0; i < n_tensors; ++i) {136 const char * name = gguf_get_tensor_name (ctx, i);137 const size_t size = gguf_get_tensor_size (ctx, i);138 const size_t offset = gguf_get_tensor_offset(ctx, i);139 140 printf("%s: tensor[%d]: name = %s, size = %zu, offset = %zu\n", __func__, i, name, size, offset);141 }142 }143 144 gguf_free(ctx);145 146 return true;147}148 149// read and create ggml_context containing the tensors and their data150static bool gguf_ex_read_1(const std::string & fname, bool check_data) {151 struct ggml_context * ctx_data = NULL;152 153 struct gguf_init_params params = {154 /*.no_alloc = */ false,155 /*.ctx = */ &ctx_data,156 };157 158 struct gguf_context * ctx = gguf_init_from_file(fname.c_str(), params);159 160 printf("%s: version: %d\n", __func__, gguf_get_version(ctx));161 printf("%s: alignment: %zu\n", __func__, gguf_get_alignment(ctx));162 printf("%s: data offset: %zu\n", __func__, gguf_get_data_offset(ctx));163 164 // kv165 {166 const int n_kv = gguf_get_n_kv(ctx);167 168 printf("%s: n_kv: %d\n", __func__, n_kv);169 170 for (int i = 0; i < n_kv; ++i) {171 const char * key = gguf_get_key(ctx, i);172 173 printf("%s: kv[%d]: key = %s\n", __func__, i, key);174 }175 }176 177 // tensor info178 {179 const int n_tensors = gguf_get_n_tensors(ctx);180 181 printf("%s: n_tensors: %d\n", __func__, n_tensors);182 183 for (int i = 0; i < n_tensors; ++i) {184 const char * name = gguf_get_tensor_name (ctx, i);185 const size_t size = gguf_get_tensor_size (ctx, i);186 const size_t offset = gguf_get_tensor_offset(ctx, i);187 188 printf("%s: tensor[%d]: name = %s, size = %zu, offset = %zu\n", __func__, i, name, size, offset);189 }190 }191 192 // data193 {194 const int n_tensors = gguf_get_n_tensors(ctx);195 196 for (int i = 0; i < n_tensors; ++i) {197 printf("%s: reading tensor %d data\n", __func__, i);198 199 const char * name = gguf_get_tensor_name(ctx, i);200 201 struct ggml_tensor * cur = ggml_get_tensor(ctx_data, name);202 203 printf("%s: tensor[%d]: n_dims = %d, ne = (%d, %d, %d, %d), name = %s, data = %p\n",204 __func__, i, ggml_n_dims(cur), int(cur->ne[0]), int(cur->ne[1]), int(cur->ne[2]), int(cur->ne[3]), cur->name, cur->data);205 206 // print first 10 elements207 const float * data = (const float *) cur->data;208 209 printf("%s data[:10] : ", name);210 for (int j = 0; j < MIN(10, ggml_nelements(cur)); ++j) {211 printf("%f ", data[j]);212 }213 printf("\n\n");214 215 // check data216 if (check_data) {217 const float * data = (const float *) cur->data;218 for (int j = 0; j < ggml_nelements(cur); ++j) {219 if (data[j] != 100 + i) {220 fprintf(stderr, "%s: tensor[%d], data[%d]: found %f, expected %f\n", __func__, i, j, data[j], float(100 + i));221 gguf_free(ctx);222 return false;223 }224 }225 }226 }227 }228 229 printf("%s: ctx_data size: %zu\n", __func__, ggml_get_mem_size(ctx_data));230 231 ggml_free(ctx_data);232 gguf_free(ctx);233 234 return true;235}236 237int main(int argc, char ** argv) {238 if (argc < 3) {239 printf("usage: %s data.gguf r|w [n]\n", argv[0]);240 printf("r: read data.gguf file\n");241 printf("w: write data.gguf file\n");242 printf("n: no check of tensor data\n");243 return -1;244 }245 bool check_data = true;246 if (argc == 4) {247 check_data = false;248 }249 250 srand(123456);251 252 const std::string fname(argv[1]);253 const std::string mode (argv[2]);254 255 GGML_ASSERT((mode == "r" || mode == "w") && "mode must be r or w");256 257 if (mode == "w") {258 GGML_ASSERT(gguf_ex_write(fname) && "failed to write gguf file");259 } else if (mode == "r") {260 GGML_ASSERT(gguf_ex_read_0(fname) && "failed to read gguf file");261 GGML_ASSERT(gguf_ex_read_1(fname, check_data) && "failed to read gguf file");262 }263 264 return 0;265}266 