| 522 | } |
| 523 | |
| 524 | bool common_download_model(const common_params_model & model, |
| 525 | const std::string & bearer_token, |
| 526 | bool offline, |
| 527 | const common_header_list & headers) { |
| 528 | // Basic validation of the model.url |
| 529 | if (model.url.empty()) { |
| 530 | LOG_ERR("%s: invalid model url\n", __func__); |
| 531 | return false; |
| 532 | } |
| 533 | |
| 534 | const int http_status = common_download_file_single(model.url, model.path, bearer_token, offline, headers); |
| 535 | if (!is_http_status_ok(http_status)) { |
| 536 | return false; |
| 537 | } |
| 538 | |
| 539 | // check for additional GGUFs split to download |
| 540 | int n_split = 0; |
| 541 | { |
| 542 | struct gguf_init_params gguf_params = { |
| 543 | /*.no_alloc = */ true, |
| 544 | /*.ctx = */ NULL, |
| 545 | }; |
| 546 | auto * ctx_gguf = gguf_init_from_file(model.path.c_str(), gguf_params); |
| 547 | if (!ctx_gguf) { |
| 548 | LOG_ERR("\n%s: failed to load input GGUF from %s\n", __func__, model.path.c_str()); |
| 549 | return false; |
| 550 | } |
| 551 | |
| 552 | auto key_n_split = gguf_find_key(ctx_gguf, LLM_KV_SPLIT_COUNT); |
| 553 | if (key_n_split >= 0) { |
| 554 | n_split = gguf_get_val_u16(ctx_gguf, key_n_split); |
| 555 | } |
| 556 | |
| 557 | gguf_free(ctx_gguf); |
| 558 | } |
| 559 | |
| 560 | if (n_split > 1) { |
| 561 | char split_prefix[PATH_MAX] = {0}; |
| 562 | char split_url_prefix[LLAMA_MAX_URL_LENGTH] = {0}; |
| 563 | |
| 564 | // Verify the first split file format |
| 565 | // and extract split URL and PATH prefixes |
| 566 | { |
| 567 | if (!llama_split_prefix(split_prefix, sizeof(split_prefix), model.path.c_str(), 0, n_split)) { |
| 568 | LOG_ERR("\n%s: unexpected model file name: %s n_split=%d\n", __func__, model.path.c_str(), n_split); |
| 569 | return false; |
| 570 | } |
| 571 | |
| 572 | if (!llama_split_prefix(split_url_prefix, sizeof(split_url_prefix), model.url.c_str(), 0, n_split)) { |
| 573 | LOG_ERR("\n%s: unexpected model url: %s n_split=%d\n", __func__, model.url.c_str(), n_split); |
| 574 | return false; |
| 575 | } |
| 576 | } |
| 577 | |
| 578 | std::vector<std::pair<std::string, std::string>> urls; |
| 579 | for (int idx = 1; idx < n_split; idx++) { |
| 580 | char split_path[PATH_MAX] = {0}; |
| 581 | llama_split_path(split_path, sizeof(split_path), split_prefix, idx, n_split); |
no test coverage detected