@@ -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 * ggufctx;
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.ggufctx = 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,25 @@ static bool load_labels(const char * filename, std::vector<std::string> & labels
114157 return true ;
115158}
116159
160+ static bool load_labels_kv (const struct gguf_context * ctx, const char * filename, std::vector<std::string> & labels)
161+ {
162+ struct gguf_nobj nobj = gguf_find_name_nobj (ctx, filename);
163+ if (nobj.n == 0 ) {
164+ return false ;
165+ }
166+ membuf buf (nobj.data , nobj.data + nobj.n );
167+ std::istream file_in (&buf);
168+ if (!file_in) {
169+ return false ;
170+ }
171+ std::string line;
172+ while (std::getline (file_in, line)) {
173+ labels.push_back (line);
174+ }
175+ GGML_ASSERT (labels.size () == 80 );
176+ return true ;
177+ }
178+
117179static bool load_alphabet (std::vector<yolo_image> & alphabet)
118180{
119181 alphabet.resize (8 * 128 );
@@ -130,6 +192,27 @@ static bool load_alphabet(std::vector<yolo_image> & alphabet)
130192 return true ;
131193}
132194
195+ static bool load_alphabet_kv (const struct gguf_context * ctx, std::vector<yolo_image> & alphabet)
196+ {
197+ alphabet.resize (8 * 128 );
198+ for (int j = 0 ; j < 8 ; j++) {
199+ for (int i = 32 ; i < 127 ; i++) {
200+ char fname[256 ];
201+ sprintf (fname, " data/labels/%d_%d.png" , i, j);
202+ struct gguf_nobj nobj = gguf_find_name_nobj (ctx, fname);
203+ if (nobj.n == 0 ) {
204+ fprintf (stderr, " Cannot find '%s'\n " , fname);
205+ return false ;
206+ }
207+ if (!load_image_from_memory (nobj.data , nobj.n , alphabet[j*128 + i])) {
208+ fprintf (stderr, " Cannot load '%s'\n " , fname);
209+ return false ;
210+ }
211+ }
212+ }
213+ return true ;
214+ }
215+
133216static ggml_tensor * apply_conv2d (ggml_context * ctx, ggml_tensor * input, const conv2d_layer & layer)
134217{
135218 struct ggml_tensor * result = ggml_conv_2d (ctx, layer.weights , input, 1 , 1 , layer.padding , layer.padding , 1 , 1 );
@@ -503,14 +586,20 @@ int main(int argc, char *argv[])
503586 return 1 ;
504587 }
505588 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 ;
589+ if (!load_labels_kv (model.ggufctx , " data/coco.names" , labels)) {
590+ fprintf (stderr, " %s: failed to load labels from 'data/coco.names' in model\n " , __func__);
591+ if (!load_labels (" data/coco.names" , labels)) {
592+ fprintf (stderr, " %s: failed to load labels from 'data/coco.names'\n " , __func__);
593+ return 1 ;
594+ }
509595 }
510596 std::vector<yolo_image> alphabet;
511- if (!load_alphabet (alphabet)) {
512- fprintf (stderr, " %s: failed to load alphabet\n " , __func__);
513- return 1 ;
597+ if (!load_alphabet_kv (model.ggufctx , alphabet)) {
598+ fprintf (stderr, " %s: failed to load alphabet from model\n " , __func__);
599+ if (!load_alphabet (alphabet)) {
600+ fprintf (stderr, " %s: failed to load alphabet\n " , __func__);
601+ return 1 ;
602+ }
514603 }
515604 const int64_t t_start_ms = ggml_time_ms ();
516605 detect (img, model, params.thresh , labels, alphabet);
0 commit comments