@@ -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
3536struct 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+
103146static 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+
117186static 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+
133231static 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);
0 commit comments