@@ -352,6 +352,8 @@ static std::string get_default_local_path(const std::string & url) {
352352
353353common_models_handler common_models_handler_init (const common_params & params, llama_example curr_ex) {
354354 common_download_hf_plan plan;
355+ common_download_hf_plan plan_spec;
356+ common_download_hf_plan plan_voc;
355357 common_download_opts opts;
356358
357359 const bool spec_type_draft_mtp = std::find (params.speculative .types .begin (),
@@ -377,7 +379,15 @@ common_models_handler common_models_handler_init(const common_params & params, l
377379 plan = common_download_get_hf_plan (params.model , opts);
378380 }
379381
380- return common_models_handler{plan, opts};
382+ if (!params.speculative .draft .mparams .hf_repo .empty ()) {
383+ plan_spec = common_download_get_hf_plan (params.speculative .draft .mparams , opts);
384+ }
385+
386+ if (!params.vocoder .model .hf_repo .empty ()) {
387+ plan_voc = common_download_get_hf_plan (params.vocoder .model , opts);
388+ }
389+
390+ return common_models_handler{plan, plan_spec, plan_voc, opts};
381391}
382392
383393bool common_models_handler_is_preset_repo (const common_models_handler & handler) {
@@ -425,7 +435,9 @@ static std::vector<common_download_task> build_url_tasks(const common_params_mod
425435void common_models_handler_apply (common_models_handler & handler, common_params & params, common_download_callback * callback) {
426436 std::vector<common_download_task> tasks;
427437
428- auto & plan = handler.plan ;
438+ auto & plan = handler.plan ;
439+ auto & plan_spec = handler.plan_spec ;
440+ auto & plan_voc = handler.plan_voc ;
429441
430442 auto opts = handler.opts ; // copy
431443 opts.callback = callback;
@@ -484,19 +496,22 @@ void common_models_handler_apply(common_models_handler & handler, common_params
484496 }
485497
486498 // handle hf_plan tasks
487- if (!plan. model_files . empty () ) {
488- for (size_t i = 0 ; i < plan. model_files .size (); ++i) {
489- auto & model_file = plan. model_files [i];
499+ auto add_tasks = [&opts, &tasks]( const hf_cache::hf_files & model_files, common_params_model & model ) {
500+ for (size_t i = 0 ; i < model_files.size (); ++i) {
501+ auto & model_file = model_files[i];
490502 bool is_first = (i == 0 );
491503 tasks.emplace_back (model_file, opts, [&, is_first]() {
492504 if (is_first) {
493505 // only use first part as model path
494- params. model .path = hf_cache::finalize_file (model_file);
506+ model.path = hf_cache::finalize_file (model_file);
495507 } else {
496508 hf_cache::finalize_file (model_file);
497509 }
498510 });
499511 }
512+ };
513+ if (!plan.model_files .empty ()) {
514+ add_tasks (plan.model_files , params.model );
500515 }
501516 if (!plan.mmproj .local_path .empty ()) {
502517 tasks.emplace_back (plan.mmproj , opts, [&]() {
@@ -522,9 +537,31 @@ void common_models_handler_apply(common_models_handler & handler, common_params
522537 });
523538 }
524539
540+ // handle plan_spec (e.g. --spec-draft-hf)
541+ if (!plan_spec.model_files .empty ()) {
542+ add_tasks (plan_spec.model_files , params.speculative .draft .mparams );
543+ }
544+
545+ // handle vocoder plan (e.g. --hf-repo-v)
546+ if (!plan_voc.model_files .empty ()) {
547+ add_tasks (plan_voc.model_files , params.vocoder .model );
548+ }
549+
525550 // run all tasks in parallel
526551 if (!params.offline ) {
527- common_download_run_tasks (tasks);
552+ // if duplicated files are found, only download once (but still call on_done for each task)
553+ std::unordered_map<std::string, common_download_task *> unique_tasks;
554+ for (auto & task : tasks) {
555+ auto it = unique_tasks.find (task.local_path );
556+ if (it == unique_tasks.end ()) {
557+ unique_tasks[task.local_path ] = &task;
558+ }
559+ }
560+ std::vector<common_download_task> unique_tasks_vec;
561+ for (auto & pair : unique_tasks) {
562+ unique_tasks_vec.push_back (*pair.second );
563+ }
564+ common_download_run_tasks (unique_tasks_vec);
528565 }
529566
530567 // download successful, update params with the downloaded paths
@@ -3711,6 +3748,7 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
37113748 " draft model for speculative decoding (default: unused)" ,
37123749 [](common_params & params, const std::string & value) {
37133750 params.speculative .draft .mparams .path = value;
3751+ params.speculative .draft .mparams .hf_file = value; // will be used if --spec-draft-hf is set
37143752 }
37153753 ).set_spec ().set_examples ({LLAMA_EXAMPLE_SPECULATIVE , LLAMA_EXAMPLE_SERVER , LLAMA_EXAMPLE_CLI }).set_env (" LLAMA_ARG_SPEC_DRAFT_MODEL" ));
37163754 add_opt (common_arg (
0 commit comments