Merge branch 'ggerganov:master' into master
This commit is contained in:
commit
d0375a2ea6
10 changed files with 55 additions and 58 deletions
|
@ -630,6 +630,12 @@ bool gpt_params_parse_ex(int argc, char ** argv, gpt_params & params) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
params.ppl_stride = std::stoi(argv[i]);
|
params.ppl_stride = std::stoi(argv[i]);
|
||||||
|
} else if (arg == "-stc" || arg == "--show_token_count") {
|
||||||
|
if (++i >= argc) {
|
||||||
|
invalid_param = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
params.token_interval = std::stoi(argv[i]);
|
||||||
} else if (arg == "--ppl-output-type") {
|
} else if (arg == "--ppl-output-type") {
|
||||||
if (++i >= argc) {
|
if (++i >= argc) {
|
||||||
invalid_param = true;
|
invalid_param = true;
|
||||||
|
@ -944,6 +950,8 @@ void gpt_print_usage(int /*argc*/, char ** argv, const gpt_params & params) {
|
||||||
printf(" --override-kv KEY=TYPE:VALUE\n");
|
printf(" --override-kv KEY=TYPE:VALUE\n");
|
||||||
printf(" advanced option to override model metadata by key. may be specified multiple times.\n");
|
printf(" advanced option to override model metadata by key. may be specified multiple times.\n");
|
||||||
printf(" types: int, float, bool. example: --override-kv tokenizer.ggml.add_bos_token=bool:false\n");
|
printf(" types: int, float, bool. example: --override-kv tokenizer.ggml.add_bos_token=bool:false\n");
|
||||||
|
printf(" -stc N --show_token_count N\n");
|
||||||
|
printf(" show consumed tokens every N tokens\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
#ifndef LOG_DISABLE_LOGS
|
#ifndef LOG_DISABLE_LOGS
|
||||||
log_print_usage();
|
log_print_usage();
|
||||||
|
|
|
@ -64,6 +64,7 @@ struct gpt_params {
|
||||||
int32_t n_beams = 0; // if non-zero then use beam search of given width.
|
int32_t n_beams = 0; // if non-zero then use beam search of given width.
|
||||||
int32_t grp_attn_n = 1; // group-attention factor
|
int32_t grp_attn_n = 1; // group-attention factor
|
||||||
int32_t grp_attn_w = 512; // group-attention width
|
int32_t grp_attn_w = 512; // group-attention width
|
||||||
|
int32_t token_interval = 512; // show token count every 512 tokens
|
||||||
float rope_freq_base = 0.0f; // RoPE base frequency
|
float rope_freq_base = 0.0f; // RoPE base frequency
|
||||||
float rope_freq_scale = 0.0f; // RoPE frequency scaling factor
|
float rope_freq_scale = 0.0f; // RoPE frequency scaling factor
|
||||||
float yarn_ext_factor = -1.0f; // YaRN extrapolation mix factor
|
float yarn_ext_factor = -1.0f; // YaRN extrapolation mix factor
|
||||||
|
@ -242,4 +243,3 @@ void dump_kv_cache_view(const llama_kv_cache_view & view, int row_size = 80);
|
||||||
|
|
||||||
// Dump the KV cache view showing individual sequences in each cell (long output).
|
// Dump the KV cache view showing individual sequences in each cell (long output).
|
||||||
void dump_kv_cache_view_seqs(const llama_kv_cache_view & view, int row_size = 40);
|
void dump_kv_cache_view_seqs(const llama_kv_cache_view & view, int row_size = 40);
|
||||||
|
|
||||||
|
|
|
@ -500,7 +500,7 @@ int main(int argc, char ** argv) {
|
||||||
while ((n_remain != 0 && !is_antiprompt) || params.interactive) {
|
while ((n_remain != 0 && !is_antiprompt) || params.interactive) {
|
||||||
// predict
|
// predict
|
||||||
if (!embd.empty()) {
|
if (!embd.empty()) {
|
||||||
// Note: n_ctx - 4 here is to match the logic for commandline prompt handling via
|
// Note: (n_ctx - 4) here is to match the logic for commandline prompt handling via
|
||||||
// --prompt or --file which uses the same value.
|
// --prompt or --file which uses the same value.
|
||||||
int max_embd_size = n_ctx - 4;
|
int max_embd_size = n_ctx - 4;
|
||||||
|
|
||||||
|
@ -650,6 +650,10 @@ int main(int argc, char ** argv) {
|
||||||
n_past += n_eval;
|
n_past += n_eval;
|
||||||
|
|
||||||
LOG("n_past = %d\n", n_past);
|
LOG("n_past = %d\n", n_past);
|
||||||
|
// Display total tokens alongside total time
|
||||||
|
if (n_past % params.token_interval == 0) {
|
||||||
|
printf("\n\033[31mTokens consumed so far = %d / %d \033[0m\n", n_past, n_ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!embd.empty() && !path_session.empty()) {
|
if (!embd.empty() && !path_session.empty()) {
|
||||||
|
|
|
@ -147,15 +147,15 @@ static std::vector<uint8_t> base64_decode(const std::string & encoded_string)
|
||||||
// parallel
|
// parallel
|
||||||
//
|
//
|
||||||
|
|
||||||
enum ServerState {
|
enum server_state {
|
||||||
LOADING_MODEL, // Server is starting up, model not fully loaded yet
|
SERVER_STATE_LOADING_MODEL, // Server is starting up, model not fully loaded yet
|
||||||
READY, // Server is ready and model is loaded
|
SERVER_STATE_READY, // Server is ready and model is loaded
|
||||||
ERROR // An error occurred, load_model failed
|
SERVER_STATE_ERROR // An error occurred, load_model failed
|
||||||
};
|
};
|
||||||
|
|
||||||
enum task_type {
|
enum task_type {
|
||||||
COMPLETION_TASK,
|
TASK_TYPE_COMPLETION,
|
||||||
CANCEL_TASK
|
TASK_TYPE_CANCEL,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct task_server {
|
struct task_server {
|
||||||
|
@ -1402,7 +1402,7 @@ struct llama_server_context
|
||||||
task.data = std::move(data);
|
task.data = std::move(data);
|
||||||
task.infill_mode = infill;
|
task.infill_mode = infill;
|
||||||
task.embedding_mode = embedding;
|
task.embedding_mode = embedding;
|
||||||
task.type = COMPLETION_TASK;
|
task.type = TASK_TYPE_COMPLETION;
|
||||||
task.multitask_id = multitask_id;
|
task.multitask_id = multitask_id;
|
||||||
|
|
||||||
// when a completion task's prompt array is not a singleton, we split it into multiple requests
|
// when a completion task's prompt array is not a singleton, we split it into multiple requests
|
||||||
|
@ -1524,7 +1524,7 @@ struct llama_server_context
|
||||||
std::unique_lock<std::mutex> lock(mutex_tasks);
|
std::unique_lock<std::mutex> lock(mutex_tasks);
|
||||||
task_server task;
|
task_server task;
|
||||||
task.id = id_gen++;
|
task.id = id_gen++;
|
||||||
task.type = CANCEL_TASK;
|
task.type = TASK_TYPE_CANCEL;
|
||||||
task.target_id = task_id;
|
task.target_id = task_id;
|
||||||
queue_tasks.push_back(task);
|
queue_tasks.push_back(task);
|
||||||
condition_tasks.notify_one();
|
condition_tasks.notify_one();
|
||||||
|
@ -1560,7 +1560,7 @@ struct llama_server_context
|
||||||
queue_tasks.erase(queue_tasks.begin());
|
queue_tasks.erase(queue_tasks.begin());
|
||||||
switch (task.type)
|
switch (task.type)
|
||||||
{
|
{
|
||||||
case COMPLETION_TASK: {
|
case TASK_TYPE_COMPLETION: {
|
||||||
llama_client_slot *slot = get_slot(json_value(task.data, "slot_id", -1));
|
llama_client_slot *slot = get_slot(json_value(task.data, "slot_id", -1));
|
||||||
if (slot == nullptr)
|
if (slot == nullptr)
|
||||||
{
|
{
|
||||||
|
@ -1589,7 +1589,7 @@ struct llama_server_context
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case CANCEL_TASK: { // release slot linked with the task id
|
case TASK_TYPE_CANCEL: { // release slot linked with the task id
|
||||||
for (auto & slot : slots)
|
for (auto & slot : slots)
|
||||||
{
|
{
|
||||||
if (slot.task_id == task.target_id)
|
if (slot.task_id == task.target_id)
|
||||||
|
@ -2515,7 +2515,7 @@ json oaicompat_completion_params_parse(
|
||||||
//
|
//
|
||||||
// https://platform.openai.com/docs/api-reference/chat/create
|
// https://platform.openai.com/docs/api-reference/chat/create
|
||||||
llama_sampling_params default_sparams;
|
llama_sampling_params default_sparams;
|
||||||
llama_params["model"] = json_value(body, "model", std::string("uknown"));
|
llama_params["model"] = json_value(body, "model", std::string("unknown"));
|
||||||
llama_params["prompt"] = format_chatml(body["messages"]); // OpenAI 'messages' to llama.cpp 'prompt'
|
llama_params["prompt"] = format_chatml(body["messages"]); // OpenAI 'messages' to llama.cpp 'prompt'
|
||||||
llama_params["cache_prompt"] = json_value(body, "cache_prompt", false);
|
llama_params["cache_prompt"] = json_value(body, "cache_prompt", false);
|
||||||
llama_params["temperature"] = json_value(body, "temperature", 0.0);
|
llama_params["temperature"] = json_value(body, "temperature", 0.0);
|
||||||
|
@ -2798,24 +2798,24 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
httplib::Server svr;
|
httplib::Server svr;
|
||||||
|
|
||||||
std::atomic<ServerState> server_state{LOADING_MODEL};
|
std::atomic<server_state> state{SERVER_STATE_LOADING_MODEL};
|
||||||
|
|
||||||
svr.set_default_headers({{"Server", "llama.cpp"},
|
svr.set_default_headers({{"Server", "llama.cpp"},
|
||||||
{"Access-Control-Allow-Origin", "*"},
|
{"Access-Control-Allow-Origin", "*"},
|
||||||
{"Access-Control-Allow-Headers", "content-type"}});
|
{"Access-Control-Allow-Headers", "content-type"}});
|
||||||
|
|
||||||
svr.Get("/health", [&](const httplib::Request&, httplib::Response& res) {
|
svr.Get("/health", [&](const httplib::Request&, httplib::Response& res) {
|
||||||
ServerState current_state = server_state.load();
|
server_state current_state = state.load();
|
||||||
switch(current_state) {
|
switch(current_state) {
|
||||||
case READY:
|
case SERVER_STATE_READY:
|
||||||
res.set_content(R"({"status": "ok"})", "application/json");
|
res.set_content(R"({"status": "ok"})", "application/json");
|
||||||
res.status = 200; // HTTP OK
|
res.status = 200; // HTTP OK
|
||||||
break;
|
break;
|
||||||
case LOADING_MODEL:
|
case SERVER_STATE_LOADING_MODEL:
|
||||||
res.set_content(R"({"status": "loading model"})", "application/json");
|
res.set_content(R"({"status": "loading model"})", "application/json");
|
||||||
res.status = 503; // HTTP Service Unavailable
|
res.status = 503; // HTTP Service Unavailable
|
||||||
break;
|
break;
|
||||||
case ERROR:
|
case SERVER_STATE_ERROR:
|
||||||
res.set_content(R"({"status": "error", "error": "Model failed to load"})", "application/json");
|
res.set_content(R"({"status": "error", "error": "Model failed to load"})", "application/json");
|
||||||
res.status = 500; // HTTP Internal Server Error
|
res.status = 500; // HTTP Internal Server Error
|
||||||
break;
|
break;
|
||||||
|
@ -2891,7 +2891,7 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
if (!svr.listen_after_bind())
|
if (!svr.listen_after_bind())
|
||||||
{
|
{
|
||||||
server_state.store(ERROR);
|
state.store(SERVER_STATE_ERROR);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2901,11 +2901,11 @@ int main(int argc, char **argv)
|
||||||
// load the model
|
// load the model
|
||||||
if (!llama.load_model(params))
|
if (!llama.load_model(params))
|
||||||
{
|
{
|
||||||
server_state.store(ERROR);
|
state.store(SERVER_STATE_ERROR);
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
llama.initialize();
|
llama.initialize();
|
||||||
server_state.store(READY);
|
state.store(SERVER_STATE_READY);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Middleware for API key validation
|
// Middleware for API key validation
|
||||||
|
|
|
@ -10184,8 +10184,8 @@ static void ggml_backend_cuda_buffer_set_tensor(ggml_backend_buffer_t buffer, gg
|
||||||
|
|
||||||
ggml_cuda_set_device(ctx->device);
|
ggml_cuda_set_device(ctx->device);
|
||||||
CUDA_CHECK(cudaDeviceSynchronize());
|
CUDA_CHECK(cudaDeviceSynchronize());
|
||||||
|
|
||||||
CUDA_CHECK(cudaMemcpy((char *)tensor->data + offset, data, size, cudaMemcpyHostToDevice));
|
CUDA_CHECK(cudaMemcpy((char *)tensor->data + offset, data, size, cudaMemcpyHostToDevice));
|
||||||
|
CUDA_CHECK(cudaDeviceSynchronize());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ggml_backend_cuda_buffer_get_tensor(ggml_backend_buffer_t buffer, const ggml_tensor * tensor, void * data, size_t offset, size_t size) {
|
static void ggml_backend_cuda_buffer_get_tensor(ggml_backend_buffer_t buffer, const ggml_tensor * tensor, void * data, size_t offset, size_t size) {
|
||||||
|
|
|
@ -1067,6 +1067,10 @@ bool ggml_metal_graph_compute(
|
||||||
GGML_ASSERT(!"unsupported op");
|
GGML_ASSERT(!"unsupported op");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef GGML_METAL_NDEBUG
|
||||||
|
[encoder pushDebugGroup:[NSString stringWithCString:ggml_op_desc(dst) encoding:NSUTF8StringEncoding]];
|
||||||
|
#endif
|
||||||
|
|
||||||
const int64_t ne00 = src0 ? src0->ne[0] : 0;
|
const int64_t ne00 = src0 ? src0->ne[0] : 0;
|
||||||
const int64_t ne01 = src0 ? src0->ne[1] : 0;
|
const int64_t ne01 = src0 ? src0->ne[1] : 0;
|
||||||
const int64_t ne02 = src0 ? src0->ne[2] : 0;
|
const int64_t ne02 = src0 ? src0->ne[2] : 0;
|
||||||
|
@ -2423,6 +2427,10 @@ bool ggml_metal_graph_compute(
|
||||||
GGML_ASSERT(false);
|
GGML_ASSERT(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef GGML_METAL_NDEBUG
|
||||||
|
[encoder popDebugGroup];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (encoder != nil) {
|
if (encoder != nil) {
|
||||||
|
|
32
ggml.c
32
ggml.c
|
@ -132,7 +132,7 @@ void ggml_print_backtrace(void) {
|
||||||
"-ex", "bt -frame-info source-and-location",
|
"-ex", "bt -frame-info source-and-location",
|
||||||
"-ex", "detach",
|
"-ex", "detach",
|
||||||
"-ex", "quit",
|
"-ex", "quit",
|
||||||
NULL);
|
(char *) NULL);
|
||||||
} else {
|
} else {
|
||||||
waitpid(pid, NULL, 0);
|
waitpid(pid, NULL, 0);
|
||||||
}
|
}
|
||||||
|
@ -4311,13 +4311,13 @@ struct ggml_tensor * ggml_set_2d_inplace(
|
||||||
static struct ggml_tensor * ggml_cpy_impl(
|
static struct ggml_tensor * ggml_cpy_impl(
|
||||||
struct ggml_context * ctx,
|
struct ggml_context * ctx,
|
||||||
struct ggml_tensor * a,
|
struct ggml_tensor * a,
|
||||||
struct ggml_tensor * b,
|
struct ggml_tensor * b) {
|
||||||
bool inplace) {
|
|
||||||
GGML_ASSERT(ggml_nelements(a) == ggml_nelements(b));
|
GGML_ASSERT(ggml_nelements(a) == ggml_nelements(b));
|
||||||
|
|
||||||
bool is_node = false;
|
bool is_node = false;
|
||||||
|
|
||||||
if (!inplace && (a->grad || b->grad)) {
|
if (a->grad || b->grad) {
|
||||||
|
// inplace is false and either one have a grad
|
||||||
is_node = true;
|
is_node = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4341,29 +4341,21 @@ struct ggml_tensor * ggml_cpy(
|
||||||
struct ggml_context * ctx,
|
struct ggml_context * ctx,
|
||||||
struct ggml_tensor * a,
|
struct ggml_tensor * a,
|
||||||
struct ggml_tensor * b) {
|
struct ggml_tensor * b) {
|
||||||
return ggml_cpy_impl(ctx, a, b, false);
|
return ggml_cpy_impl(ctx, a, b);
|
||||||
}
|
|
||||||
|
|
||||||
struct ggml_tensor * ggml_cpy_inplace(
|
|
||||||
struct ggml_context * ctx,
|
|
||||||
struct ggml_tensor * a,
|
|
||||||
struct ggml_tensor * b) {
|
|
||||||
return ggml_cpy_impl(ctx, a, b, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ggml_cont
|
// ggml_cont
|
||||||
|
|
||||||
static struct ggml_tensor * ggml_cont_impl(
|
static struct ggml_tensor * ggml_cont_impl(
|
||||||
struct ggml_context * ctx,
|
struct ggml_context * ctx,
|
||||||
struct ggml_tensor * a,
|
struct ggml_tensor * a) {
|
||||||
bool inplace) {
|
|
||||||
bool is_node = false;
|
bool is_node = false;
|
||||||
|
|
||||||
if (!inplace && a->grad) {
|
if (a->grad) {
|
||||||
is_node = true;
|
is_node = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ggml_tensor * result = inplace ? ggml_view_tensor(ctx, a) : ggml_dup_tensor(ctx, a);
|
struct ggml_tensor * result = ggml_dup_tensor(ctx, a);
|
||||||
ggml_format_name(result, "%s (cont)", a->name);
|
ggml_format_name(result, "%s (cont)", a->name);
|
||||||
|
|
||||||
result->op = GGML_OP_CONT;
|
result->op = GGML_OP_CONT;
|
||||||
|
@ -4376,13 +4368,7 @@ static struct ggml_tensor * ggml_cont_impl(
|
||||||
struct ggml_tensor * ggml_cont(
|
struct ggml_tensor * ggml_cont(
|
||||||
struct ggml_context * ctx,
|
struct ggml_context * ctx,
|
||||||
struct ggml_tensor * a) {
|
struct ggml_tensor * a) {
|
||||||
return ggml_cont_impl(ctx, a, false);
|
return ggml_cont_impl(ctx, a);
|
||||||
}
|
|
||||||
|
|
||||||
struct ggml_tensor * ggml_cont_inplace(
|
|
||||||
struct ggml_context * ctx,
|
|
||||||
struct ggml_tensor * a) {
|
|
||||||
return ggml_cont_impl(ctx, a, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// make contiguous, with new shape
|
// make contiguous, with new shape
|
||||||
|
|
13
ggml.h
13
ggml.h
|
@ -218,7 +218,9 @@
|
||||||
#define GGML_MAX_PARAMS 2048
|
#define GGML_MAX_PARAMS 2048
|
||||||
#define GGML_MAX_CONTEXTS 64
|
#define GGML_MAX_CONTEXTS 64
|
||||||
#define GGML_MAX_SRC 10
|
#define GGML_MAX_SRC 10
|
||||||
|
#ifndef GGML_MAX_NAME
|
||||||
#define GGML_MAX_NAME 64
|
#define GGML_MAX_NAME 64
|
||||||
|
#endif
|
||||||
#define GGML_MAX_OP_PARAMS 64
|
#define GGML_MAX_OP_PARAMS 64
|
||||||
#define GGML_DEFAULT_N_THREADS 4
|
#define GGML_DEFAULT_N_THREADS 4
|
||||||
#define GGML_DEFAULT_GRAPH_SIZE 2048
|
#define GGML_DEFAULT_GRAPH_SIZE 2048
|
||||||
|
@ -1161,22 +1163,11 @@ extern "C" {
|
||||||
struct ggml_tensor * a,
|
struct ggml_tensor * a,
|
||||||
struct ggml_tensor * b);
|
struct ggml_tensor * b);
|
||||||
|
|
||||||
// a -> b, in-place, return view(b)
|
|
||||||
GGML_API struct ggml_tensor * ggml_cpy_inplace(
|
|
||||||
struct ggml_context * ctx,
|
|
||||||
struct ggml_tensor * a,
|
|
||||||
struct ggml_tensor * b);
|
|
||||||
|
|
||||||
// make contiguous
|
// make contiguous
|
||||||
GGML_API struct ggml_tensor * ggml_cont(
|
GGML_API struct ggml_tensor * ggml_cont(
|
||||||
struct ggml_context * ctx,
|
struct ggml_context * ctx,
|
||||||
struct ggml_tensor * a);
|
struct ggml_tensor * a);
|
||||||
|
|
||||||
// make contiguous, in-place
|
|
||||||
GGML_API struct ggml_tensor * ggml_cont_inplace(
|
|
||||||
struct ggml_context * ctx,
|
|
||||||
struct ggml_tensor * a);
|
|
||||||
|
|
||||||
// make contiguous, with new shape
|
// make contiguous, with new shape
|
||||||
GGML_API struct ggml_tensor * ggml_cont_1d(
|
GGML_API struct ggml_tensor * ggml_cont_1d(
|
||||||
struct ggml_context * ctx,
|
struct ggml_context * ctx,
|
||||||
|
|
|
@ -10921,7 +10921,7 @@ void llama_print_timings(struct llama_context * ctx) {
|
||||||
__func__, timings.t_p_eval_ms, timings.n_p_eval, timings.t_p_eval_ms / timings.n_p_eval, 1e3 / timings.t_p_eval_ms * timings.n_p_eval);
|
__func__, timings.t_p_eval_ms, timings.n_p_eval, timings.t_p_eval_ms / timings.n_p_eval, 1e3 / timings.t_p_eval_ms * timings.n_p_eval);
|
||||||
LLAMA_LOG_INFO("%s: eval time = %10.2f ms / %5d runs (%8.2f ms per token, %8.2f tokens per second)\n",
|
LLAMA_LOG_INFO("%s: eval time = %10.2f ms / %5d runs (%8.2f ms per token, %8.2f tokens per second)\n",
|
||||||
__func__, timings.t_eval_ms, timings.n_eval, timings.t_eval_ms / timings.n_eval, 1e3 / timings.t_eval_ms * timings.n_eval);
|
__func__, timings.t_eval_ms, timings.n_eval, timings.t_eval_ms / timings.n_eval, 1e3 / timings.t_eval_ms * timings.n_eval);
|
||||||
LLAMA_LOG_INFO("%s: total time = %10.2f ms\n", __func__, (timings.t_end_ms - timings.t_start_ms));
|
LLAMA_LOG_INFO("%s: total time = %10.2f ms / %5d tokens\n", __func__, (timings.t_end_ms - timings.t_start_ms), (timings.n_p_eval + timings.n_eval));
|
||||||
}
|
}
|
||||||
|
|
||||||
void llama_reset_timings(struct llama_context * ctx) {
|
void llama_reset_timings(struct llama_context * ctx) {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
f96711108d55bdbbd277e6be07204dce6a94fb93
|
979cc23b345006504cfc1f67c0fdf627805e3319
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue