@@ -140,7 +140,7 @@ cli_args cli_parse(int argc, char** argv) {
140140 } else if (arg == " -o" || arg == " --output" ) {
141141 r.output = next_arg (argc, argv, i);
142142 } else if (arg == " -m" || arg == " --model" ) {
143- r.model = validate_path ( next_arg (argc, argv, i) );
143+ r.model = next_arg (argc, argv, i);
144144 } else if (arg == " -p" || arg == " --prompt" ) {
145145 r.prompt = collect_args (argc, argv, i, ' -' );
146146 } else if (arg == " -b" || arg == " --backend" ) {
@@ -245,6 +245,42 @@ char const* to_string(tensor_data_layout l) {
245245 }
246246}
247247
248+ path find_model (char const * model_name_or_path) {
249+ path p = path (model_name_or_path);
250+ if (exists (p) || p.is_absolute ()) {
251+ return p;
252+ }
253+ path search_paths[5 ];
254+ search_paths[0 ] = path (" models" );
255+ if (char const * vision_model_dir = getenv (" VISION_MODEL_DIR" )) {
256+ search_paths[1 ] = path (vision_model_dir);
257+ }
258+ if (char const * xdg_data_home = getenv (" XDG_DATA_HOME" )) {
259+ search_paths[2 ] = path (xdg_data_home) / " visioncpp" ;
260+ }
261+ if (char const * home = getenv (" HOME" )) {
262+ search_paths[3 ] = path (home) / " .local/share/visioncpp" ;
263+ }
264+ if constexpr (VISP_MODEL_INSTALL_DIR[0 ] != ' \0 ' ) {
265+ search_paths[4 ] = path (VISP_MODEL_INSTALL_DIR);
266+ }
267+ for (auto & sp : search_paths) {
268+ if (!sp.empty ()) {
269+ path candidate = sp / p;
270+ if (exists (candidate)) {
271+ return candidate;
272+ }
273+ }
274+ }
275+ printf (" Looking for %s\n " , p.generic_string ().c_str ());
276+ for (auto & sp : search_paths) {
277+ if (!sp.empty ()) {
278+ printf (" Looking for %s\n " , (sp / p).generic_string ().c_str ());
279+ }
280+ }
281+ throw except (" Model file not found: {}" , model_name_or_path);
282+ }
283+
248284std::tuple<model_file, model_weights> load_model_weights (
249285 cli_args const & args,
250286 backend_device const & dev,
@@ -253,10 +289,11 @@ std::tuple<model_file, model_weights> load_model_weights(
253289 tensor_data_layout preferred_layout = tensor_data_layout::unknown) {
254290
255291 timer t;
256- char const * model_path = args.model ? args.model : default_model;
257- printf (" Loading model weights from '%s'... " , model_path);
292+ path model_path = find_model (args.model ? args.model : default_model);
293+ auto model_path_str = model_path.generic_string ();
294+ printf (" Loading model weights from '%s'... " , model_path_str.c_str ());
258295
259- model_file file = model_load (model_path );
296+ model_file file = model_load (model_path_str. c_str () );
260297 model_weights weights = model_init (file.n_tensors () + n_tensors);
261298 if (preferred_layout == tensor_data_layout::unknown) {
262299 preferred_layout = file.tensor_layout ();
@@ -355,7 +392,7 @@ sam_prompt sam_parse_prompt(std::span<char const* const> args, i32x2 extent) {
355392void run_sam (cli_args const & args) {
356393 backend_device backend = backend_init (args);
357394 auto [file, weights] = load_model_weights (
358- args, backend, " models/ MobileSAM-F16.gguf" , 0 , backend.preferred_layout ());
395+ args, backend, " MobileSAM-F16.gguf" , 0 , backend.preferred_layout ());
359396 sam_params params{};
360397
361398 require_inputs (args.inputs , 1 , " <image>" );
@@ -409,7 +446,7 @@ void run_sam(cli_args const& args) {
409446void run_birefnet (cli_args const & args) {
410447 backend_device backend = backend_init (args);
411448 auto [file, weights] = load_model_weights (
412- args, backend, " models/ BiRefNet-F16.gguf" , 0 , backend.preferred_layout ());
449+ args, backend, " BiRefNet-lite -F16.gguf" , 0 , backend.preferred_layout ());
413450
414451 require_inputs (args.inputs , 1 , " <image>" );
415452 image_data image = image_load (args.inputs [0 ]);
@@ -453,7 +490,7 @@ void run_birefnet(cli_args const& args) {
453490void run_depth_anything (cli_args const & args) {
454491 backend_device backend = backend_init (args);
455492 auto [file, weights] = load_model_weights (
456- args, backend, " models/ DepthAnythingV2-Small-F32.gguf" , 0 , backend.preferred_layout ());
493+ args, backend, " DepthAnythingV2-Small-F32.gguf" , 0 , backend.preferred_layout ());
457494
458495 require_inputs (args.inputs , 1 , " <image>" );
459496 image_data image = image_load (args.inputs [0 ]);
@@ -489,7 +526,7 @@ void run_depth_anything(cli_args const& args) {
489526void run_migan (cli_args const & args) {
490527 backend_device backend = backend_init (args);
491528 auto [file, weights] = load_model_weights (
492- args, backend, " models/ MIGAN-512-places2-F16.gguf" , backend.preferred_layout ());
529+ args, backend, " MIGAN-512-places2-F16.gguf" , backend.preferred_layout ());
493530 migan_params params = migan_detect_params (file);
494531 params.invert_mask = true ; // -> inpaint opaque areas
495532
@@ -527,7 +564,7 @@ void run_migan(cli_args const& args) {
527564void run_esrgan (cli_args const & args) {
528565 backend_device backend = backend_init (args);
529566 auto [file, weights] = load_model_weights (
530- args, backend, " models/ RealESRGAN-x4.gguf" , 0 , backend.preferred_layout ());
567+ args, backend, " RealESRGAN-x4.gguf" , 0 , backend.preferred_layout ());
531568 esrgan_params params = esrgan_detect_params (file);
532569 printf (" - scale: %dx\n " , params.scale );
533570 printf (" - block count: %d\n " , params.n_blocks );
0 commit comments