Skip to content

Commit 2c3603e

Browse files
author
katsu560
committed
load files from model
1 parent 5a4ecab commit 2c3603e

File tree

5 files changed

+186
-8
lines changed

5 files changed

+186
-8
lines changed

examples/yolo/yolo-image.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,31 @@ bool load_image(const char *fname, yolo_image & img)
8888
return true;
8989
}
9090

91+
bool load_image_from_memory(const char *buffer, int len, yolo_image & img)
92+
{
93+
int w, h, c;
94+
uint8_t * data = stbi_load_from_memory((uint8_t *)buffer, len, &w, &h, &c, 3);
95+
if (!data) {
96+
return false;
97+
}
98+
c = 3;
99+
img.w = w;
100+
img.h = h;
101+
img.c = c;
102+
img.data.resize(w*h*c);
103+
for (int k = 0; k < c; ++k){
104+
for (int j = 0; j < h; ++j){
105+
for (int i = 0; i < w; ++i){
106+
int dst_index = i + w*j + w*h*k;
107+
int src_index = k + c*i + c*w*j;
108+
img.data[dst_index] = (float)data[src_index]/255.;
109+
}
110+
}
111+
}
112+
stbi_image_free(data);
113+
return true;
114+
}
115+
91116
static yolo_image resize_image(const yolo_image & im, int w, int h)
92117
{
93118
yolo_image resized(w, h, im.c);
@@ -207,4 +232,4 @@ void draw_label(yolo_image & im, int row, int col, const yolo_image & label, con
207232
}
208233
}
209234
}
210-
}
235+
}

examples/yolo/yolo-image.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ struct yolo_image {
3232
};
3333

3434
bool load_image(const char *fname, yolo_image & img);
35+
bool load_image_from_memory(const char *buffer, int len, yolo_image & img);
3536
void draw_box_width(yolo_image & a, int x1, int y1, int x2, int y2, int w, float r, float g, float b);
3637
yolo_image letterbox_image(const yolo_image & im, int w, int h);
3738
bool save_image(const yolo_image & im, const char *name, int quality);

examples/yolo/yolov3-tiny.cpp

Lines changed: 110 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ struct yolo_model {
3030
int height = 416;
3131
std::vector<conv2d_layer> conv2d_layers;
3232
struct ggml_context * ctx;
33+
struct gguf_context * ctx_gguf;
3334
};
3435

3536
struct yolo_layer {
@@ -71,6 +72,7 @@ static bool load_model(const std::string & fname, yolo_model & model) {
7172
fprintf(stderr, "%s: gguf_init_from_file() failed\n", __func__);
7273
return false;
7374
}
75+
model.ctx_gguf = ctx;
7476
model.width = 416;
7577
model.height = 416;
7678
model.conv2d_layers.resize(13);
@@ -100,6 +102,47 @@ static bool load_model(const std::string & fname, yolo_model & model) {
100102
return true;
101103
}
102104

105+
// istream from memory
106+
#include <streambuf>
107+
#include <istream>
108+
109+
struct membuf : std::streambuf {
110+
membuf(const char * begin, const char * end) {
111+
char * b(const_cast<char *>(begin));
112+
char * e(const_cast<char *>(end));
113+
this->begin = b;
114+
this->end = e;
115+
this->setg(b, b, e);
116+
}
117+
118+
membuf(const char * base, size_t size) {
119+
char * b(const_cast<char *>(begin));
120+
this->begin = b;
121+
this->end = b + size;
122+
this->setg(b, b, end);
123+
}
124+
125+
virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which = std::ios_base::in) override {
126+
if(dir == std::ios_base::cur) {
127+
gbump(off);
128+
} else if(dir == std::ios_base::end) {
129+
setg(begin, end + off, end);
130+
} else if(dir == std::ios_base::beg) {
131+
setg(begin, begin + off, end);
132+
}
133+
134+
return gptr() - eback();
135+
}
136+
137+
virtual pos_type seekpos(std::streampos pos, std::ios_base::openmode mode) override {
138+
return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode);
139+
}
140+
141+
char * begin;
142+
char * end;
143+
};
144+
145+
103146
static bool load_labels(const char * filename, std::vector<std::string> & labels)
104147
{
105148
std::ifstream file_in(filename);
@@ -114,6 +157,32 @@ static bool load_labels(const char * filename, std::vector<std::string> & labels
114157
return true;
115158
}
116159

160+
static bool load_labels_gguf(const struct gguf_context * ctx, const char * filename, std::vector<std::string> & labels)
161+
{
162+
int key_id = gguf_find_key_array(ctx, "embedded_files", filename);
163+
if (key_id == -1) {
164+
return false;
165+
}
166+
int tensor = gguf_find_tensor(ctx, filename);
167+
if (tensor == -1) {
168+
return false;
169+
}
170+
const size_t offset = gguf_get_tensor_offset(ctx, tensor);
171+
const size_t len = gguf_get_tensor_size(ctx, tensor);
172+
const char * data = (char *)gguf_get_data(ctx);
173+
membuf buf(data + offset, data + offset + len);
174+
std::istream file_in(&buf);
175+
if (!file_in) {
176+
return false;
177+
}
178+
std::string line;
179+
while (std::getline(file_in, line)) {
180+
labels.push_back(line);
181+
}
182+
GGML_ASSERT(labels.size() == 80);
183+
return true;
184+
}
185+
117186
static bool load_alphabet(std::vector<yolo_image> & alphabet)
118187
{
119188
alphabet.resize(8 * 128);
@@ -130,6 +199,35 @@ static bool load_alphabet(std::vector<yolo_image> & alphabet)
130199
return true;
131200
}
132201

202+
static bool load_alphabet_gguf(const struct gguf_context * ctx, std::vector<yolo_image> & alphabet)
203+
{
204+
alphabet.resize(8 * 128);
205+
for (int j = 0; j < 8; j++) {
206+
for (int i = 32; i < 127; i++) {
207+
char fname[256];
208+
sprintf(fname, "data/labels/%d_%d.png", i, j);
209+
int key_id = gguf_find_key_array(ctx, "embedded_files", fname);
210+
if (key_id == -1) {
211+
fprintf(stderr, "Cannot find '%s' in embedded_files\n", fname);
212+
return false;
213+
}
214+
int tensor = gguf_find_tensor(ctx, fname);
215+
if (tensor == -1) {
216+
fprintf(stderr, "Cannot find '%s' in tensor\n", fname);
217+
return false;
218+
}
219+
const size_t offset = gguf_get_tensor_offset(ctx, tensor);
220+
const size_t len = gguf_get_tensor_size(ctx, tensor);
221+
const char * data = (char *)gguf_get_data(ctx);
222+
if (!load_image_from_memory(data + offset, len, alphabet[j*128 + i])) {
223+
fprintf(stderr, "Cannot load '%s'\n", fname);
224+
return false;
225+
}
226+
}
227+
}
228+
return true;
229+
}
230+
133231
static ggml_tensor * apply_conv2d(ggml_context * ctx, ggml_tensor * input, const conv2d_layer & layer)
134232
{
135233
struct ggml_tensor * result = ggml_conv_2d(ctx, layer.weights, input, 1, 1, layer.padding, layer.padding, 1, 1);
@@ -503,14 +601,20 @@ int main(int argc, char *argv[])
503601
return 1;
504602
}
505603
std::vector<std::string> labels;
506-
if (!load_labels("data/coco.names", labels)) {
507-
fprintf(stderr, "%s: failed to load labels from 'data/coco.names'\n", __func__);
508-
return 1;
604+
if (!load_labels_gguf(model.ctx_gguf, "data/coco.names", labels)) {
605+
fprintf(stderr, "%s: failed to load labels from 'data/coco.names' in model\n", __func__);
606+
if (!load_labels("data/coco.names", labels)) {
607+
fprintf(stderr, "%s: failed to load labels from 'data/coco.names'\n", __func__);
608+
return 1;
609+
}
509610
}
510611
std::vector<yolo_image> alphabet;
511-
if (!load_alphabet(alphabet)) {
512-
fprintf(stderr, "%s: failed to load alphabet\n", __func__);
513-
return 1;
612+
if (!load_alphabet_gguf(model.ctx_gguf, alphabet)) {
613+
fprintf(stderr, "%s: failed to load alphabet from model\n", __func__);
614+
if (!load_alphabet(alphabet)) {
615+
fprintf(stderr, "%s: failed to load alphabet\n", __func__);
616+
return 1;
617+
}
514618
}
515619
const int64_t t_start_ms = ggml_time_ms();
516620
detect(img, model, params.thresh, labels, alphabet);

include/ggml/ggml.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2305,6 +2305,7 @@ extern "C" {
23052305

23062306
GGML_API int gguf_get_n_kv(const struct gguf_context * ctx);
23072307
GGML_API int gguf_find_key(const struct gguf_context * ctx, const char * key);
2308+
GGML_API int gguf_find_key_array(const struct gguf_context * ctx, const char * key, const char * val);
23082309
GGML_API const char * gguf_get_key (const struct gguf_context * ctx, int key_id);
23092310

23102311
GGML_API enum gguf_type gguf_get_kv_type (const struct gguf_context * ctx, int key_id);
@@ -2333,6 +2334,7 @@ extern "C" {
23332334
GGML_API size_t gguf_get_tensor_offset(const struct gguf_context * ctx, int i);
23342335
GGML_API char * gguf_get_tensor_name (const struct gguf_context * ctx, int i);
23352336
GGML_API enum ggml_type gguf_get_tensor_type (const struct gguf_context * ctx, int i);
2337+
GGML_API size_t gguf_get_tensor_size (const struct gguf_context * ctx, int i);
23362338

23372339
// removes key if it exists
23382340
GGML_API void gguf_remove_key(struct gguf_context * ctx, const char * key);

src/ggml.c

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21562,6 +21562,13 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p
2156221562
ok = ok && gguf_fread_el (file, &info->type, sizeof(info->type), &offset);
2156321563
ok = ok && gguf_fread_el (file, &info->offset, sizeof(info->offset), &offset);
2156421564

21565+
// set tensor size
21566+
size_t size = 1;
21567+
for (uint32_t j = 0; j < info->n_dims; ++j) {
21568+
size *= info->ne[j];
21569+
}
21570+
info->size = size;
21571+
2156521572
// TODO: return an error instead of crashing with GGML_ASSERT
2156621573
gguf_tensor_info_sanitize(info);
2156721574

@@ -21784,6 +21791,37 @@ int gguf_find_key(const struct gguf_context * ctx, const char * key) {
2178421791
return keyfound;
2178521792
}
2178621793

21794+
int gguf_find_key_array(const struct gguf_context * ctx, const char * key, const char * val) {
21795+
// return -1 if key not found
21796+
int keyfound = -1;
21797+
int key_id = -1;
21798+
21799+
const int n_kv = gguf_get_n_kv(ctx);
21800+
21801+
for (int i = 0; i < n_kv; ++i) {
21802+
if (strcmp(key, gguf_get_key(ctx, i)) == 0) {
21803+
key_id = i;
21804+
break;
21805+
}
21806+
}
21807+
21808+
if (key_id != -1) {
21809+
if (ctx->kv[key_id].type == GGUF_TYPE_ARRAY) {
21810+
const int n = gguf_get_arr_n(ctx, key_id);
21811+
struct gguf_kv * kv = &ctx->kv[key_id];
21812+
21813+
for (int i = 0; i < n; ++i) {
21814+
struct gguf_str * str = &((struct gguf_str *) kv->value.arr.data)[i];
21815+
if (strcmp(val, str->data) == 0) {
21816+
keyfound = i;
21817+
}
21818+
}
21819+
}
21820+
}
21821+
21822+
return keyfound;
21823+
}
21824+
2178721825
const char * gguf_get_key(const struct gguf_context * ctx, int key_id) {
2178821826
GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
2178921827
return ctx->kv[key_id].key.data;
@@ -21920,17 +21958,25 @@ int gguf_find_tensor(const struct gguf_context * ctx, const char * name) {
2192021958
}
2192121959

2192221960
size_t gguf_get_tensor_offset(const struct gguf_context * ctx, int i) {
21961+
GGML_ASSERT(i >= 0 && i < gguf_get_n_tensors(ctx));
2192321962
return ctx->infos[i].offset;
2192421963
}
2192521964

2192621965
char * gguf_get_tensor_name(const struct gguf_context * ctx, int i) {
21966+
GGML_ASSERT(i >= 0 && i < gguf_get_n_tensors(ctx));
2192721967
return ctx->infos[i].name.data;
2192821968
}
2192921969

2193021970
enum ggml_type gguf_get_tensor_type(const struct gguf_context * ctx, int i) {
21971+
GGML_ASSERT(i >= 0 && i < gguf_get_n_tensors(ctx));
2193121972
return ctx->infos[i].type;
2193221973
}
2193321974

21975+
size_t gguf_get_tensor_size(const struct gguf_context * ctx, int i) {
21976+
GGML_ASSERT(i >= 0 && i < gguf_get_n_tensors(ctx));
21977+
return ctx->infos[i].size;
21978+
}
21979+
2193421980
// returns the index
2193521981
static int gguf_get_or_add_key(struct gguf_context * ctx, const char * key) {
2193621982
const int idx = gguf_find_key(ctx, key);
@@ -22242,7 +22288,7 @@ static void gguf_write_to_buf(const struct gguf_context * ctx, struct gguf_buf *
2224222288
gguf_bwrite_el (buf, &kv->type, sizeof(kv->type));
2224322289

2224422290
switch (kv->type) {
22245-
case GGUF_TYPE_UINT8: gguf_bwrite_el( buf, &kv->value.uint8, sizeof(kv->value.uint8) ); break;
22291+
case GGUF_TYPE_UINT8: gguf_bwrite_el (buf, &kv->value.uint8, sizeof(kv->value.uint8) ); break;
2224622292
case GGUF_TYPE_INT8: gguf_bwrite_el (buf, &kv->value.int8, sizeof(kv->value.int8) ); break;
2224722293
case GGUF_TYPE_UINT16: gguf_bwrite_el (buf, &kv->value.uint16, sizeof(kv->value.uint16) ); break;
2224822294
case GGUF_TYPE_INT16: gguf_bwrite_el (buf, &kv->value.int16, sizeof(kv->value.int16) ); break;

0 commit comments

Comments
 (0)