Signed-off-by: Adrien Gallouët <angt@huggingface.co>
This commit is contained in:
Adrien Gallouët 2026-03-20 17:30:49 +00:00
parent e915644c7b
commit b6c7bcfa62
No known key found for this signature in database
4 changed files with 44 additions and 60 deletions

View File

@ -441,42 +441,43 @@ int common_download_file_single(const std::string & url,
return 304; // Not Modified - fake cached response
}
// "subdir/model-00001-of-00002.gguf" -> "subdir/model", 1, 2
static std::tuple<std::string, int, int> get_gguf_split_info(const std::string & path) {
if (path.empty()) {
return {};
}
struct gguf_split_info {
std::string prefix;
int index = 0;
int count = 0;
};
static gguf_split_info get_gguf_split_info(const std::string & path) {
static const std::regex re(R"(^(.+)-([0-9]+)-of-([0-9]+)\.gguf$)", std::regex::icase);
std::smatch m;
if (std::regex_match(path, m, re)) {
return {m[1].str(), std::stoi(m[2].str()), std::stoi(m[3].str())};
}
return {};
}
static hf_cache::hf_files get_split_files(const hf_cache::hf_files & all_files,
const hf_cache::hf_file & primary_file) {
hf_cache::hf_files result;
auto [prefix, idx, count] = get_gguf_split_info(primary_file.path);
static hf_cache::hf_files get_split_files(const hf_cache::hf_files & files,
const hf_cache::hf_file & file) {
auto split = get_gguf_split_info(file.path);
if (count > 1) {
for (const auto & f : all_files) {
auto [sprefix, sidx, scount] = get_gguf_split_info(f.path);
if (scount == count && sprefix == prefix) {
result.push_back(f);
}
if (split.count <= 1) {
return {file};
}
hf_cache::hf_files result;
for (const auto & f : files) {
auto split_f = get_gguf_split_info(f.path);
if (split_f.count == split.count && split_f.prefix == split.prefix) {
result.push_back(f);
}
} else {
result.push_back(primary_file);
}
return result;
}
static hf_cache::hf_files filter_gguf_by_quant(const hf_cache::hf_files & files,
const std::string & quant_tag) {
hf_cache::hf_files matches;
hf_cache::hf_files result;
std::regex pattern(quant_tag + "[.-]", std::regex::icase);
for (const auto & f : files) {
@ -487,10 +488,10 @@ static hf_cache::hf_files filter_gguf_by_quant(const hf_cache::hf_files & files,
continue;
}
if (std::regex_search(f.path, pattern)) {
matches.push_back(f);
result.push_back(f);
}
}
return matches;
return result;
}
static void list_available_gguf_files(const hf_cache::hf_files & files) {

View File

@ -1,7 +1,5 @@
#pragma once
#include "hf-cache.h"
#include <string>
#include <vector>

View File

@ -7,12 +7,12 @@
#define JSON_ASSERT GGML_ASSERT
#include <nlohmann/json.hpp>
#include <ctime>
#include <filesystem>
#include <fstream>
#include <mutex>
#include <regex> // migration only
#include <string>
#include <string_view>
namespace nl = nlohmann;
@ -86,37 +86,36 @@ static bool symlinks_supported() {
}
static std::string folder_name_to_repo(const std::string & folder) {
if (folder.size() < 8 || folder.substr(0, 8) != "models--") {
constexpr std::string_view prefix = "models--";
if (folder.rfind(prefix, 0)) {
return {};
}
std::string repo_id;
for (size_t i = 8; i < folder.size(); ++i) {
if (i + 1 < folder.size() && folder[i] == '-' && folder[i+1] == '-') {
repo_id += '/';
i++;
} else {
repo_id += folder[i];
}
}
return repo_id;
std::string result = folder.substr(prefix.length());
string_replace_all(result, "--", "/");
return result;
}
static std::string repo_to_folder_name(const std::string & repo_id) {
std::string name = "models--";
for (char c : repo_id) {
if (c == '/') {
name += "--";
} else {
name += c;
}
}
return name;
constexpr std::string_view prefix = "models--";
std::string result = std::string(prefix) + repo_id;
string_replace_all(result, "/", "--");
return result;
}
static fs::path get_repo_path(const std::string & repo_id) {
return get_cache_directory() / repo_to_folder_name(repo_id);
}
static void set_default_headers(httplib::Client & cli, const std::string & bearer_token) {
httplib::Headers headers;
headers.emplace("User-Agent", "llama-cpp/" + build_info);
headers.emplace("Accept", "application/json");
if (!bearer_token.empty()) {
headers.emplace("Authorization", "Bearer " + bearer_token);
}
cli.set_default_headers(headers);
}
static void write_ref(const std::string & repo_id,
const std::string & ref,
const std::string & commit) {
@ -146,13 +145,7 @@ static std::string get_repo_ref(const std::string & repo_id,
std::string url = get_model_endpoint() + "api/models/" + repo_id + "/refs";
auto [cli, parts] = common_http_client(url);
httplib::Headers headers;
headers.emplace("User-Agent", "llama-cpp/" + build_info);
headers.emplace("Accept", "application/json");
if (!bearer_token.empty()) {
headers.emplace("Authorization", "Bearer " + bearer_token);
}
cli.set_default_headers(headers);
set_default_headers(cli, bearer_token);
auto res = cli.Get(parts.path);
if (!res || res->status != 200) {
@ -211,13 +204,7 @@ hf_files get_repo_files(const std::string & repo_id,
auto [cli, parts] = common_http_client(url);
httplib::Headers headers;
headers.emplace("User-Agent", "llama-cpp/" + build_info);
headers.emplace("Accept", "application/json");
if (!bearer_token.empty()) {
headers.emplace("Authorization", "Bearer " + bearer_token);
}
cli.set_default_headers(headers);
set_default_headers(cli, bearer_token);
auto res = cli.Get(parts.path);
if (!res || res->status != 200) {

View File

@ -1,8 +1,6 @@
#pragma once
#include <filesystem>
#include <string>
#include <utility>
#include <vector>
// Ref: https://huggingface.co/docs/hub/local-cache.md