Merge branch 'ggml-org:master' into master
This commit is contained in:
12 files changed
+151
-32
No files matched your search
@@ -45,7 +45,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
server:
|
||||
runs-on: hf-jobs-cpu-upgrade
|
||||
runs-on: hf-jobs-cpu-xl
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
|
||||
+2
-2
@@ -4,8 +4,8 @@ include(CheckIncludeFileCXX)
|
||||
|
||||
### llama.cpp version
|
||||
set(LLAMA_VERSION_MAJOR 0)
|
||||
set(LLAMA_VERSION_MINOR 4)
|
||||
set(LLAMA_VERSION_PATCH 1)
|
||||
set(LLAMA_VERSION_MINOR 5)
|
||||
set(LLAMA_VERSION_PATCH 0)
|
||||
set(LLAMA_VERSION_BASE "${LLAMA_VERSION_MAJOR}.${LLAMA_VERSION_MINOR}.${LLAMA_VERSION_PATCH}")
|
||||
|
||||
# whether this is a development/nightly build
|
||||
|
||||
+15
-6
@@ -30,8 +30,8 @@ namespace hf_cache {
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
std::string get_cache_path() {
|
||||
static const std::string cache = []() {
|
||||
static fs::path get_cache_directory() {
|
||||
static const fs::path cache = []() {
|
||||
struct {
|
||||
const char * var;
|
||||
fs::path path;
|
||||
@@ -46,14 +46,14 @@ std::string get_cache_path() {
|
||||
for (const auto & entry : entries) {
|
||||
if (auto * p = std::getenv(entry.var); p && *p) {
|
||||
fs::path base(p);
|
||||
return (entry.path.empty() ? base : base / entry.path).string();
|
||||
return entry.path.empty() ? base : base / entry.path;
|
||||
}
|
||||
}
|
||||
#ifndef _WIN32
|
||||
const struct passwd * pw = getpwuid(getuid());
|
||||
|
||||
if (pw && pw->pw_dir && *pw->pw_dir) {
|
||||
return (fs::path(pw->pw_dir) / ".cache" / "huggingface" / "hub").string();
|
||||
return fs::path(pw->pw_dir) / ".cache" / "huggingface" / "hub";
|
||||
}
|
||||
#endif
|
||||
throw std::runtime_error("Failed to determine HF cache directory");
|
||||
@@ -62,6 +62,15 @@ std::string get_cache_path() {
|
||||
return cache;
|
||||
}
|
||||
|
||||
std::string get_cache_path() {
|
||||
#if defined(__cpp_lib_char8_t)
|
||||
const std::u8string u8str = get_cache_directory().u8string();
|
||||
return std::string(reinterpret_cast<const char *>(u8str.data()), u8str.size());
|
||||
#else
|
||||
return get_cache_directory().u8string();
|
||||
#endif
|
||||
}
|
||||
|
||||
static std::string folder_name_to_repo(const std::string & folder) {
|
||||
constexpr std::string_view prefix = "models--";
|
||||
if (folder.rfind(prefix, 0)) {
|
||||
@@ -80,7 +89,7 @@ static std::string repo_to_folder_name(const std::string & repo_id) {
|
||||
}
|
||||
|
||||
static fs::path get_repo_path(const std::string & repo_id) {
|
||||
return fs::path(get_cache_path()) / repo_to_folder_name(repo_id);
|
||||
return get_cache_directory() / repo_to_folder_name(repo_id);
|
||||
}
|
||||
|
||||
static bool is_hex_char(const char c) {
|
||||
@@ -393,7 +402,7 @@ static std::string get_cached_ref(const fs::path & repo_path) {
|
||||
}
|
||||
|
||||
hf_files get_cached_files(const std::string & repo_id) {
|
||||
const fs::path cache_path = get_cache_path();
|
||||
const fs::path cache_path = get_cache_directory();
|
||||
if (!fs::exists(cache_path)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
+2
-15
@@ -10,7 +10,7 @@ import torch
|
||||
if TYPE_CHECKING:
|
||||
from torch import Tensor
|
||||
|
||||
from .base import LazyTorchTensor, ModelBase, TextModel, gguf, logger
|
||||
from .base import LazyTorchTensor, ModelBase, ModelType, TextModel, get_model_architecture, gguf, logger
|
||||
|
||||
|
||||
@ModelBase.register("QWenLMHeadModel")
|
||||
@@ -666,7 +666,7 @@ class DFlashModel(Qwen3Model):
|
||||
from . import get_model_class
|
||||
with open(self.target_model_dir / "config.json", "r", encoding="utf-8") as f:
|
||||
target_hparams = json.load(f)
|
||||
target_arch = target_hparams["architectures"][0]
|
||||
target_arch = get_model_architecture(target_hparams, ModelType.TEXT)
|
||||
target_cls = get_model_class(target_arch)
|
||||
|
||||
if target_cls is not type(self):
|
||||
@@ -841,13 +841,6 @@ class DSparkModel(DFlashModel):
|
||||
return None
|
||||
return super().filter_tensors(item)
|
||||
|
||||
_ROPE_PERMUTE_SUFFIXES = (
|
||||
"self_attn.q_proj.weight",
|
||||
"self_attn.k_proj.weight",
|
||||
"self_attn.q_norm.weight",
|
||||
"self_attn.k_norm.weight",
|
||||
)
|
||||
|
||||
def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iterable[tuple[str, Tensor]]:
|
||||
if name == "model.d2t":
|
||||
self._d2t = data_torch
|
||||
@@ -856,12 +849,6 @@ class DSparkModel(DFlashModel):
|
||||
if self._n_vocab_draft == self.hparams["vocab_size"] and name.endswith("lm_head.weight"):
|
||||
return
|
||||
|
||||
# interleaved-rope checkpoints (rope_is_neox_style = false) -> NeoX layout: per head, even dims first then odd
|
||||
if not self.hparams.get("rope_is_neox_style", True) and name.endswith(self._ROPE_PERMUTE_SUFFIXES):
|
||||
head_dim = self.hparams["head_dim"]
|
||||
shape = data_torch.shape
|
||||
data_torch = data_torch.reshape(-1, head_dim // 2, 2, *shape[1:]).transpose(1, 2).reshape(shape)
|
||||
|
||||
yield from super().modify_tensors(data_torch, name, bid)
|
||||
|
||||
def prepare_tensors(self):
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ project("ggml" C CXX ASM)
|
||||
### GGML Version
|
||||
set(GGML_VERSION_MAJOR 0)
|
||||
set(GGML_VERSION_MINOR 25)
|
||||
set(GGML_VERSION_PATCH 0)
|
||||
set(GGML_VERSION_PATCH 1)
|
||||
set(GGML_VERSION_BASE "${GGML_VERSION_MAJOR}.${GGML_VERSION_MINOR}.${GGML_VERSION_PATCH}")
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
||||
|
||||
@@ -3573,6 +3573,7 @@ static int ggml_cuda_try_fuse(ggml_backend_cuda_context * cuda_ctx, ggml_cgraph
|
||||
ggml_cuda_topk_moe_args args;
|
||||
const bool can_fuse = ggml_cuda_topk_moe_fusion(cgraph, i, args);
|
||||
std::vector<ggml_op> ops;
|
||||
ops.reserve(13); // max ops; avoids gcc -Wstringop-overflow false positive
|
||||
|
||||
if (can_fuse) {
|
||||
const ggml_tensor * logits = node->src[0];
|
||||
@@ -4642,6 +4643,7 @@ static void ggml_backend_cuda_graph_optimize(ggml_backend_t backend, ggml_cgraph
|
||||
ggml_cuda_topk_moe_args args;
|
||||
const bool can_fuse = ggml_cuda_topk_moe_fusion(cgraph, i, args);
|
||||
std::vector<ggml_op> ops;
|
||||
ops.reserve(13); // max ops; avoids gcc -Wstringop-overflow false positive
|
||||
|
||||
const ggml_tensor * node = cgraph->nodes[i];
|
||||
|
||||
|
||||
@@ -5476,6 +5476,10 @@ static bool ggml_hexagon_supported_mul_mat_id(const struct ggml_hexagon_session
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ggml_get_op_params_i32(op, 3) == GGML_PREC_F32) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (src0->type) {
|
||||
case GGML_TYPE_Q4_0:
|
||||
case GGML_TYPE_Q4_1:
|
||||
|
||||
@@ -1259,6 +1259,7 @@ struct ggml_backend_opencl_context {
|
||||
cl_kernel kernel_gemm_noshuffle_q6_K_f32;
|
||||
cl_kernel kernel_gemm_noshuffle_q6_K_f32_cok;
|
||||
cl_kernel kernel_gemm_noshuffle_q6_k_f32_32b_trans_ila_a8_bin;
|
||||
cl_kernel kernel_gemm_noshuffle_q6_k_q8_1_dp4a_ila_a8_bin;
|
||||
cl_kernel kernel_gemv_noshuffle_q6_k_f32_32b_trans;
|
||||
cl_kernel kernel_gemv_noshuffle_q5_k_f32;
|
||||
cl_kernel kernel_gemv_noshuffle_q5_k_f32_mc3; // multi-column (N=3) verify GEMV (spec/MTP)
|
||||
@@ -4407,6 +4408,7 @@ static void load_cl_kernels(ggml_backend_opencl_context *backend_ctx) {
|
||||
|
||||
backend_ctx->kernel_gemv_noshuffle_q6_k_f32_32b_trans = nullptr;
|
||||
backend_ctx->kernel_gemm_noshuffle_q6_k_f32_32b_trans_ila_a8_bin = nullptr;
|
||||
backend_ctx->kernel_gemm_noshuffle_q6_k_q8_1_dp4a_ila_a8_bin = nullptr;
|
||||
if (backend_ctx->adreno_gen == ADRENO_GPU_GEN::X2E) {
|
||||
{
|
||||
std::string opts = std::string("-cl-std=") + opencl_c_std +
|
||||
@@ -4439,6 +4441,17 @@ static void load_cl_kernels(ggml_backend_opencl_context *backend_ctx) {
|
||||
CL_CHECK(clReleaseProgram(bin_prog));
|
||||
GGML_LOG_CONT(".");
|
||||
}
|
||||
|
||||
kernel_bin = (const char *)backend_ctx->get_adreno_bin_kernel("gemm_noshuffle_q6_k_q8_1_dp4a_ila_a8", &bin_size);
|
||||
if (kernel_bin && bin_size > 0) {
|
||||
cl_program bin_prog =
|
||||
build_program_from_binary(backend_ctx->context, backend_ctx->device, kernel_bin, "", bin_size);
|
||||
|
||||
CL_CHECK((backend_ctx->kernel_gemm_noshuffle_q6_k_q8_1_dp4a_ila_a8_bin =
|
||||
clCreateKernel(bin_prog, "kernel_gemm_noshuffle_q6_k_q8_1_dp4a_ila_a8", &err), err));
|
||||
CL_CHECK(clReleaseProgram(bin_prog));
|
||||
GGML_LOG_CONT(".");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21919,6 +21932,74 @@ static void ggml_cl_mul_mat_q6_K_f32_adreno_ila(ggml_backend_t backend, const gg
|
||||
const int gemm_tile_n = 64;
|
||||
int N_pad = CEIL_DIV(N, gemm_tile_n) * gemm_tile_n;
|
||||
|
||||
static const char * q6_k_bin_dp4a_env = getenv("GGML_OPENCL_Q6_K_BIN_DP4A");
|
||||
bool q6_k_bin_dp4a_on = q6_k_bin_dp4a_env
|
||||
? (atoi(q6_k_bin_dp4a_env) != 0)
|
||||
: true;
|
||||
// dot prod has to be available
|
||||
q6_k_bin_dp4a_on = backend_ctx->has_integer_dot && q6_k_bin_dp4a_on;
|
||||
|
||||
if (q6_k_bin_dp4a_on && backend_ctx->kernel_gemm_noshuffle_q6_k_q8_1_dp4a_ila_a8_bin) {
|
||||
const int dp4a_N_pad = CEIL_DIV(N, 32) * 32;
|
||||
const size_t n_blocks = (size_t)dp4a_N_pad * (K / 32);
|
||||
|
||||
backend_ctx->prealloc_moe_qa.allocate(context, (size_t)dp4a_N_pad * K * sizeof(cl_char));
|
||||
backend_ctx->prealloc_moe_da.allocate(context, n_blocks * sizeof(cl_half));
|
||||
backend_ctx->prealloc_moe_sa.allocate(context, n_blocks * sizeof(cl_half));
|
||||
|
||||
cl_mem b_sub = nullptr;
|
||||
region.origin = offset1;
|
||||
region.size = (size_t)K * N * sizeof(float);
|
||||
CL_CHECK((b_sub = clCreateSubBuffer(extra1->data_device, 0, CL_BUFFER_CREATE_TYPE_REGION, ®ion, &err), err));
|
||||
|
||||
cl_int tb = (cl_int)((size_t)N * (K / 32));
|
||||
cl_kernel qk = backend_ctx->kernel_quant_a_q8_1;
|
||||
CL_CHECK(clSetKernelArg(qk, 0, sizeof(cl_mem), &b_sub));
|
||||
CL_CHECK(clSetKernelArg(qk, 1, sizeof(cl_mem), &backend_ctx->prealloc_moe_qa.buffer));
|
||||
CL_CHECK(clSetKernelArg(qk, 2, sizeof(cl_mem), &backend_ctx->prealloc_moe_da.buffer));
|
||||
CL_CHECK(clSetKernelArg(qk, 3, sizeof(cl_mem), &backend_ctx->prealloc_moe_sa.buffer));
|
||||
CL_CHECK(clSetKernelArg(qk, 4, sizeof(cl_int), &tb));
|
||||
size_t q_local[1] = { 64 };
|
||||
size_t q_global[1] = { (size_t)CEIL_DIV(tb, 64) * 64 };
|
||||
backend_ctx->enqueue_ndrange_kernel(qk, 1, q_global, q_local, dst);
|
||||
|
||||
cl_mem d_sub = nullptr;
|
||||
cl_mem d_img = nullptr;
|
||||
region.origin = offsetd;
|
||||
region.size = (size_t)M * N * sizeof(float);
|
||||
CL_CHECK((d_sub = clCreateSubBuffer(extrad->data_device, 0, CL_BUFFER_CREATE_TYPE_REGION, ®ion, &err), err));
|
||||
|
||||
img_fmt = { CL_R, CL_FLOAT };
|
||||
memset(&img_desc, 0, sizeof(img_desc));
|
||||
img_desc.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;
|
||||
img_desc.image_width = (size_t)M * N;
|
||||
img_desc.buffer = d_sub;
|
||||
CL_CHECK((d_img = clCreateImage(context, CL_MEM_WRITE_ONLY, &img_fmt, &img_desc, NULL, &err), err));
|
||||
|
||||
kernel = backend_ctx->kernel_gemm_noshuffle_q6_k_q8_1_dp4a_ila_a8_bin;
|
||||
|
||||
cl_uint k_arg = 0;
|
||||
CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(cl_mem), &extra0_q6_K->ql_img));
|
||||
CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(cl_mem), &extra0_q6_K->qh));
|
||||
CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(cl_mem), &extra0_q6_K->s));
|
||||
CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(cl_mem), &extra0_q6_K->d));
|
||||
CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(cl_mem), &backend_ctx->prealloc_moe_qa.buffer));
|
||||
CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(cl_mem), &backend_ctx->prealloc_moe_da.buffer));
|
||||
CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(cl_mem), &d_img));
|
||||
CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(int), &K));
|
||||
CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(int), &M));
|
||||
CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(int), &N));
|
||||
|
||||
size_t local_work_size[3] = { 64, 1, 1 };
|
||||
size_t global_work_size[3] = { 64, (size_t)(M / 64), (size_t)(dp4a_N_pad / 32) };
|
||||
backend_ctx->enqueue_ndrange_kernel(kernel, 3, global_work_size, local_work_size, dst);
|
||||
|
||||
CL_CHECK(clReleaseMemObject(b_sub));
|
||||
CL_CHECK(clReleaseMemObject(d_img));
|
||||
CL_CHECK(clReleaseMemObject(d_sub));
|
||||
return;
|
||||
}
|
||||
|
||||
cl_mem b_sub_buf = nullptr;
|
||||
cl_mem b_padded = nullptr;
|
||||
cl_mem b_buf = nullptr;
|
||||
|
||||
@@ -39,6 +39,15 @@ if ! git fetch --tags origin 2>/dev/null; then
|
||||
echo "Warning: could not fetch tags from origin (local run?)"
|
||||
fi
|
||||
|
||||
# Canonical https URL of this repository (from the origin remote), used to link the previous release.
|
||||
# Left empty on local runs without an origin remote.
|
||||
if ORIGIN_URL="$(git remote get-url origin 2>/dev/null)"; then
|
||||
REPO_URL="https://$(printf '%s' "${ORIGIN_URL}" \
|
||||
| sed -E -e 's#^git@([^:]+):#https://\1/#' -e 's#^https?://##' -e 's#\.git$##')"
|
||||
else
|
||||
REPO_URL=""
|
||||
fi
|
||||
|
||||
# Release commit: the commit <version> points at when the tag exists, HEAD otherwise.
|
||||
if ! RELEASE_COMMIT="$(git rev-parse -q --verify "refs/tags/${VERSION}^{commit}" 2>/dev/null)"; then
|
||||
RELEASE_COMMIT="$(git rev-parse HEAD)"
|
||||
@@ -53,7 +62,11 @@ PREV="$( { git tag --list; echo "${VERSION}"; } \
|
||||
|
||||
if [[ -n "${PREV}" ]]; then
|
||||
CHANGELOG="$(git log --oneline "${PREV}..${RELEASE_COMMIT}")"
|
||||
CHANGELOG_TITLE="Changelog since ${PREV}"
|
||||
if [[ -n "${REPO_URL}" ]]; then
|
||||
CHANGELOG_TITLE="Changelog since [${PREV}](${REPO_URL}/releases/tag/${PREV})"
|
||||
else
|
||||
CHANGELOG_TITLE="Changelog since ${PREV}"
|
||||
fi
|
||||
else
|
||||
CHANGELOG="(no previous release tag found)"
|
||||
CHANGELOG_TITLE="Changelog"
|
||||
|
||||
@@ -1 +1 @@
|
||||
cae37675560bce40e5e8b7a505cb0cd06d211a5c
|
||||
e565a8f4ce2e462c4973a24c51098dd3c81c0256
|
||||
@@ -93,6 +93,7 @@ static void usage(char ** argv) {
|
||||
LOG(" -d, --stdev <stdev> Set the standard deviation of the tensor initialization distribution (default: 0.1f)\n");
|
||||
LOG(" -o, --out <dir> Save generated test models to <dir> instead of running backend tests\n");
|
||||
LOG(" -v <N> Set log verbosity level\n");
|
||||
LOG(" -b, --backend <backend> Run only on the given backend device\n");
|
||||
LOG(" -h, --help Show this help message\n\n");
|
||||
LOG("Examples:\n");
|
||||
LOG(" %s\n", argv[0]);
|
||||
@@ -704,7 +705,7 @@ static int save_models(const std::string & arch_filter, const size_t seed, const
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_backends(const std::string & arch_filter, const size_t seed, const float stdev, const int verbosity) {
|
||||
static int test_backends(const std::string & arch_filter, const size_t seed, const float stdev, const int verbosity, const char * target_backend) {
|
||||
struct user_data_t {
|
||||
struct {
|
||||
ggml_log_callback callback;
|
||||
@@ -746,6 +747,9 @@ static int test_backends(const std::string & arch_filter, const size_t seed, con
|
||||
const size_t device_count = ggml_backend_dev_count();
|
||||
for (size_t i = 0; i < device_count; i++) {
|
||||
ggml_backend_dev_t dev = ggml_backend_dev_get(i);
|
||||
if (target_backend != nullptr && strcmp(target_backend, ggml_backend_dev_name(dev)) != 0) {
|
||||
continue;
|
||||
}
|
||||
dev_configs.emplace_back(std::vector<ggml_backend_dev_t>{dev}, ggml_backend_dev_description(dev), LLAMA_SPLIT_MODE_LAYER);
|
||||
max_device_label_length = std::max(max_device_label_length, dev_configs.back().label.length());
|
||||
|
||||
@@ -756,7 +760,9 @@ static int test_backends(const std::string & arch_filter, const size_t seed, con
|
||||
}
|
||||
}
|
||||
|
||||
dev_configs.emplace_back(devices_meta, "Meta", LLAMA_SPLIT_MODE_TENSOR);
|
||||
if (target_backend == nullptr) {
|
||||
dev_configs.emplace_back(devices_meta, "Meta", LLAMA_SPLIT_MODE_TENSOR);
|
||||
}
|
||||
}
|
||||
|
||||
size_t max_arch_name_length = 0;
|
||||
@@ -907,6 +913,7 @@ int main(int argc, char ** argv) {
|
||||
size_t seed = rd();
|
||||
float stdev = 0.1f;
|
||||
std::string out;
|
||||
const char * target_backend = nullptr;
|
||||
|
||||
int verbosity = LOG_LEVEL_ERROR;
|
||||
|
||||
@@ -961,6 +968,19 @@ int main(int argc, char ** argv) {
|
||||
usage(argv);
|
||||
return 1;
|
||||
}
|
||||
} else if (strcmp(argv[i], "-b") == 0 || strcmp(argv[i], "--backend") == 0) {
|
||||
if (i + 1 < argc) {
|
||||
const char * backend_name = argv[++i];
|
||||
ggml_backend_dev_t dev = ggml_backend_dev_by_name(backend_name);
|
||||
if (dev == nullptr) {
|
||||
LOG_ERR("%s: unknown backend device: %s\n", __func__, backend_name);
|
||||
return 1;
|
||||
}
|
||||
target_backend = ggml_backend_dev_name(dev);
|
||||
} else {
|
||||
usage(argv);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
LOG_ERR("%s: unknown argument: %s\n", __func__, argv[i]);
|
||||
usage(argv);
|
||||
@@ -977,7 +997,7 @@ int main(int argc, char ** argv) {
|
||||
if (!out.empty()) {
|
||||
return save_models(arch_filter, seed, stdev, verbosity, out);
|
||||
}
|
||||
return test_backends(arch_filter, seed, stdev, verbosity);
|
||||
return test_backends(arch_filter, seed, stdev, verbosity, target_backend);
|
||||
} catch (const std::exception & err) {
|
||||
fprintf(stderr, "encountered runtime error: %s\n", err.what());
|
||||
return -1;
|
||||
|
||||
@@ -467,7 +467,6 @@ static std::filesystem::path get_server_exec_path() {
|
||||
}
|
||||
|
||||
static void unset_reserved_args(common_preset & preset, bool unset_model_args) {
|
||||
preset.unset_option("LLAMA_ARG_LOG_FILE");
|
||||
preset.unset_option("LLAMA_ARG_SSL_KEY_FILE");
|
||||
preset.unset_option("LLAMA_ARG_SSL_CERT_FILE");
|
||||
preset.unset_option("LLAMA_API_KEY");
|
||||
@@ -585,8 +584,12 @@ server_models::server_models(
|
||||
base_preset(ctx_preset.load_from_args(argc, argv)),
|
||||
sched(std::make_unique<server_lru_sched>(*this)),
|
||||
monitor(std::make_unique<server_monitor>(*this)) {
|
||||
// clean up base preset
|
||||
// propagate base params to child
|
||||
unset_reserved_args(base_preset, true);
|
||||
|
||||
// do not propagate these options, but allow preset to explicitly set them
|
||||
base_preset.unset_option("LLAMA_ARG_LOG_FILE");
|
||||
|
||||
// set binary path
|
||||
try {
|
||||
bin_path = get_server_exec_path().string();
|
||||
|
||||
Reference in new issue
Block a user