Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cpp/common/build-info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
#include <cstdio>
#include <string>

int LLAMA_BUILD_NUMBER = 9982;
char const * LLAMA_COMMIT = "99f3dc3";
int LLAMA_BUILD_NUMBER = 10054;
char const * LLAMA_COMMIT = "ac2557c";
char const * LLAMA_COMPILER = "unknown";
char const * LLAMA_BUILD_TARGET = "unknown";

Expand Down
7 changes: 6 additions & 1 deletion cpp/common/chat-auto-parser-generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ common_peg_arena autoparser::build_parser(const generation_params & inputs, cons
} else {
parser = content.build_parser(ctx);
}
return pure_content ? p.prefix(generation_prompt, reasoning.start) + parser : p.prefix(generation_prompt, reasoning.start) << parser;
const std::string reasoning_start = trim_whitespace(reasoning.start);
return pure_content ? p.prefix(generation_prompt, reasoning_start) + parser : p.prefix(generation_prompt, reasoning_start) << parser;
});
}

Expand Down Expand Up @@ -261,6 +262,10 @@ common_peg_parser analyze_tools::build_func_parser(common_chat_peg_builder & p,
bool matched_atomic = false;
common_peg_parser func_parser = p.eps();

if (!function.args_separator.empty()) {
open = open + p.space() + p.literal(function.args_separator);
}

if (!function.name_suffix.empty()) {
func_parser = open + call_id_section + p.space() + args;
matched_atomic = true;
Expand Down
7 changes: 4 additions & 3 deletions cpp/common/chat-auto-parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,10 @@ struct tool_format_analysis {
};

struct tool_function_analysis {
std::string name_prefix; // e.g., "<function=", "\"name\": \"", "functions."
std::string name_suffix; // e.g., ">", "\"", ":0"
std::string close; // e.g., "</function>", "" (for tag-based)
std::string name_prefix; // e.g., "<function=", "\"name\": \"", "functions."
std::string name_suffix; // e.g., ">", "\"", ":0"
std::string args_separator; // e.g., "<tool_sep>" (marker between function name and arguments)
std::string close; // e.g., "</function>", "" (for tag-based)
};

struct tool_arguments_analysis {
Expand Down
34 changes: 32 additions & 2 deletions cpp/common/chat-diff-analyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,16 +124,16 @@ static std::vector<std::function<void(const common_chat_template & tmpl, autopar
analysis.tools.format.section_end = "";
analysis.tools.format.per_call_start = "<TOOLCALL>";
analysis.tools.format.per_call_end = "</TOOLCALL>";
analysis.tools.format.tools_array_wrapped = true;
analysis.content.mode = content_mode::PLAIN;
analysis.content.start = "";
analysis.content.end = "";
analysis.reasoning.mode = reasoning_mode::TAG_BASED;
analysis.reasoning.start = "<think>\n\n";
analysis.reasoning.start = "<think>\n";
analysis.reasoning.end = "</think>";
analysis.assistant_start = "<SPECIAL_11>Assistant";
analysis.user_start = "<SPECIAL_11>User";
analysis.preserved_tokens.clear();
analysis.preserved_tokens.push_back("<SPECIAL_12>");
analysis.preserved_tokens.push_back("<SPECIAL_11>");
analysis.preserved_tokens.push_back("</think>");
analysis.preserved_tokens.push_back("<TOOLCALL>");
Expand Down Expand Up @@ -259,6 +259,7 @@ void autoparser::analyze_template(const common_chat_template & tmpl) {
LOG_DBG("per_call_end: '%s'\n", tools.format.per_call_end.c_str());
LOG_DBG("func_name_prefix: '%s'\n", tools.function.name_prefix.c_str());
LOG_DBG("func_name_suffix: '%s'\n", tools.function.name_suffix.c_str());
LOG_DBG("func_args_separator: '%s'\n", tools.function.args_separator.c_str());
LOG_DBG("func_close: '%s'\n", tools.function.close.c_str());
LOG_DBG("call_id_prefix: '%s'\n", tools.call_id.prefix.c_str());
LOG_DBG("call_id_suffix: '%s'\n", tools.call_id.suffix.c_str());
Expand Down Expand Up @@ -302,6 +303,7 @@ void autoparser::collect_preserved_tokens() {
add_token(tools.format.per_call_end);
add_token(tools.function.name_prefix);
add_token(tools.function.name_suffix);
add_token(tools.function.args_separator);
add_token(tools.function.close);
add_token(tools.arguments.start);
add_token(tools.arguments.end);
Expand Down Expand Up @@ -1051,6 +1053,23 @@ void analyze_tools::check_per_call_markers() {
format.section_start.clear();
format.section_end.clear();
}

if (!format.per_call_end.empty()) {
auto count_occurrences = [](const std::string & haystack, const std::string & needle) {
size_t count = 0;
for (size_t pos = haystack.find(needle); pos != std::string::npos;
pos = haystack.find(needle, pos + needle.size())) {
count++;
}
return count;
};
size_t calls_one = count_occurrences(one_vs_two->output_A, format.per_call_end);
size_t calls_two = count_occurrences(one_vs_two->output_B, format.per_call_end);
if (calls_one > 0 && calls_one == calls_two) {
format.section_end = format.per_call_end;
format.per_call_end.clear();
}
}
}

void analyze_tools::extract_function_markers() {
Expand Down Expand Up @@ -1132,6 +1151,17 @@ void analyze_tools::extract_function_markers() {
auto suf_result = suffix_parser.parse_and_extract(diff.suffix);
if (suf_result.result.success()) {
function.name_suffix += suf_result.tags["ext"];

auto arg_start = [&](common_peg_parser_builder &p) {
return p.marker() + p.space() + p.choice({ p.literal(ARG_FIRST), p.literal(ARG_SECOND) });
};
auto sep_parser = build_tagged_peg_parser([&](common_peg_parser_builder &p) {
return p.tag("sep", p.zero_or_more(p.negate(arg_start(p)) + p.any())) + arg_start(p);
});
auto sep_result = sep_parser.parse_and_extract(diff.suffix.substr(suf_result.tags["ext"].size()));
if (sep_result.result.success()) {
function.args_separator = trim_whitespace(sep_result.tags["sep"]);
}
}
}

Expand Down
15 changes: 15 additions & 0 deletions cpp/common/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ enum llama_example {
LLAMA_EXAMPLE_RESULTS,
LLAMA_EXAMPLE_EXPORT_GRAPH_OPS,
LLAMA_EXAMPLE_DOWNLOAD,
LLAMA_EXAMPLE_TOKENIZE,

LLAMA_EXAMPLE_COUNT,
};
Expand Down Expand Up @@ -635,6 +636,14 @@ struct common_params {
std::string api_prefix = ""; // NOLINT
std::string chat_template = ""; // NOLINT
bool use_jinja = true; // NOLINT

// server CORS params
std::string cors_origins = "*";
std::string cors_methods = "GET, POST, DELETE, OPTIONS";
std::string cors_headers = "*";
bool cors_credentials = true;
bool cors_origins_explicit = false; // for --agent option

bool enable_chat_template = true;
bool force_pure_content_parser = false;
common_reasoning_format reasoning_format = COMMON_REASONING_FORMAT_DEEPSEEK;
Expand Down Expand Up @@ -721,6 +730,12 @@ struct common_params {
// batched-bench params
bool batched_bench_output_jsonl = false;

// tokenize params
bool tokenize_ids = false; // if true, only print the token IDs
bool tokenize_stdin = false; // if true, read the prompt from stdin
bool tokenize_no_bos = false; // if true, do not add the BOS token
bool tokenize_show_count = false; // if true, print the total token count

// common params
std::string out_file; // output filename for all example programs
// optional callback for model loading progress and cancellation:
Expand Down
39 changes: 39 additions & 0 deletions cpp/common/jinja/value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -750,11 +750,50 @@ const func_builtins & value_string_t::get_builtins() const {
res->val_str.mark_input_based_on(args.get_pos(0)->val_str);
return res;
}},
{"format", [](const func_args & args) -> value {
value val_input = args.get_pos(0);
if (!is_val<value_string>(val_input)) {
throw raised_exception("format() first argument must be a string");
}
const jinja::string & fmt = val_input->as_string();
const bool fmt_is_input = fmt.all_parts_are_input();

const std::string str = fmt.str();
jinja::string result;
std::string literal;
auto flush_literal = [&]() {
if (!literal.empty()) {
result.parts.push_back({fmt_is_input, literal});
literal.clear();
}
};

size_t arg_idx = 1; // positional args follow the format string
for (size_t i = 0; i < str.size(); ++i) {
if (str[i] != '{') {
literal += str[i];
continue;
}
if (i + 1 >= str.size() || str[i + 1] != '}') {
throw not_implemented_exception("format() only supports simple '{}' placeholders");
}
++i;
flush_literal();
const jinja::string arg_str = args.get_pos(arg_idx++)->as_string();
result.parts.insert(result.parts.end(), arg_str.parts.begin(), arg_str.parts.end());
}
flush_literal();
return mk_val<value_string>(result);
}},
{"int", [](const func_args & args) -> value {
value val_input = args.get_pos(0);
value val_default = args.get_kwarg_or_pos("default", 1);
value val_base = args.get_kwarg_or_pos("base", 2);
const int base = val_base->is_undefined() ? 10 : val_base->as_int();
if (base != 0 && (base < 2 || base > 36)) {
// an out-of-range base makes std::stoi fail fast on the MSVC CRT instead of throwing
throw raised_exception("int() base must be 0 or between 2 and 36");
}
if (is_val<value_string>(val_input) == false) {
throw raised_exception("int() first argument must be a string");
}
Expand Down
5 changes: 4 additions & 1 deletion cpp/common/speculative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,10 @@ struct common_speculative_impl_draft_simple : public common_speculative_impl {
bool process(const llama_batch & batch) override {
auto * ctx_dft = params.ctx_dft;

const int ret = llama_decode(ctx_dft, batch);
llama_batch batch_dft = batch;
batch_dft.logits = nullptr;

const int ret = llama_decode(ctx_dft, batch_dft);

if (ret != 0) {
SPC_ERR("failed to decode draft batch, ret = %d\n", ret);
Expand Down
5 changes: 5 additions & 0 deletions cpp/ggml-backend-meta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,11 @@ static struct lm_ggml_backend_meta_split_state lm_ggml_backend_meta_get_split_st
case LM_GGML_OP_GATED_DELTA_NET: {
split_state = handle_gated_delta_net(src_ss);
} break;
case LM_GGML_OP_DSV4_HC_COMB:
case LM_GGML_OP_DSV4_HC_PRE:
case LM_GGML_OP_DSV4_HC_POST: {
split_state = handle_generic(src_ss, /*scalar_only =*/ true);
} break;
case LM_GGML_OP_UNARY: {
split_state = handle_generic(src_ss, /*scalar_only =*/ false);
} break;
Expand Down
1 change: 1 addition & 0 deletions cpp/ggml-cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ extern "C" {
LM_GGML_BACKEND_API int lm_ggml_cpu_has_sve (void);
LM_GGML_BACKEND_API int lm_ggml_cpu_get_sve_cnt (void); // sve vector length in bytes
LM_GGML_BACKEND_API int lm_ggml_cpu_has_sme (void);
LM_GGML_BACKEND_API int lm_ggml_cpu_has_sme2 (void);
// other
LM_GGML_BACKEND_API int lm_ggml_cpu_has_riscv_v (void);
LM_GGML_BACKEND_API int lm_ggml_cpu_get_rvv_vlen (void); // risc-v vector length in bytes
Expand Down
5 changes: 5 additions & 0 deletions cpp/ggml-cpu/arch/arm/cpu-feats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ struct aarch64_features {
bool has_sve2 = false;
bool has_i8mm = false;
bool has_sme = false;
bool has_sme2 = false;

aarch64_features() {
#if defined(__linux__)
Expand Down Expand Up @@ -56,6 +57,10 @@ struct aarch64_features {
has_sme = static_cast<bool>(oldp);
}

if (sysctlbyname("hw.optional.arm.FEAT_SME2", &oldp, &size, NULL, 0) == 0) {
has_sme2 = static_cast<bool>(oldp);
}

// Apple apparently does not implement SVE yet
#endif
}
Expand Down
32 changes: 31 additions & 1 deletion cpp/ggml-cpu/ggml-cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -2064,6 +2064,18 @@ static void lm_ggml_compute_forward(struct lm_ggml_compute_params * params, stru
{
lm_ggml_compute_forward_lightning_indexer(params, tensor);
} break;
case LM_GGML_OP_DSV4_HC_COMB:
{
lm_ggml_compute_forward_dsv4_hc_comb(params, tensor);
} break;
case LM_GGML_OP_DSV4_HC_PRE:
{
lm_ggml_compute_forward_dsv4_hc_pre(params, tensor);
} break;
case LM_GGML_OP_DSV4_HC_POST:
{
lm_ggml_compute_forward_dsv4_hc_post(params, tensor);
} break;
case LM_GGML_OP_MAP_CUSTOM1:
{
lm_ggml_compute_forward_map_custom1(params, tensor);
Expand Down Expand Up @@ -2244,6 +2256,9 @@ static int lm_ggml_get_n_tasks(struct lm_ggml_tensor * node, int n_threads) {
case LM_GGML_OP_COUNT_EQUAL:
case LM_GGML_OP_SOLVE_TRI:
case LM_GGML_OP_GATED_DELTA_NET:
case LM_GGML_OP_DSV4_HC_COMB:
case LM_GGML_OP_DSV4_HC_PRE:
case LM_GGML_OP_DSV4_HC_POST:
{
n_tasks = n_threads;
} break;
Expand Down Expand Up @@ -2859,7 +2874,14 @@ struct lm_ggml_cplan lm_ggml_graph_plan(
} break;
case LM_GGML_OP_OUT_PROD:
{
if (lm_ggml_is_quantized(node->src[0]->type)) {
if (lm_ggml_is_quantized(node->src[0]->type) ||
node->src[0]->type == LM_GGML_TYPE_F16) {
cur = lm_ggml_type_size(LM_GGML_TYPE_F32) * node->src[0]->ne[0] * n_tasks;
}
} break;
case LM_GGML_OP_SET_ROWS:
{
if (node->src[0]->type == LM_GGML_TYPE_F16 && node->type != LM_GGML_TYPE_F16) {
cur = lm_ggml_type_size(LM_GGML_TYPE_F32) * node->src[0]->ne[0] * n_tasks;
}
} break;
Expand Down Expand Up @@ -3785,6 +3807,14 @@ int lm_ggml_cpu_has_sme(void) {
#endif
}

int lm_ggml_cpu_has_sme2(void) {
#if defined(__ARM_ARCH) && defined(__ARM_FEATURE_SME2)
return 1;
#else
return 0;
#endif
}

void lm_ggml_cpu_init(void) {
// needed to initialize lm_ggml_time
{
Expand Down
8 changes: 6 additions & 2 deletions cpp/ggml-cpu/ggml-cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,11 +462,12 @@ static bool lm_ggml_backend_cpu_device_supports_op(lm_ggml_backend_dev_t dev, co
return max_bias == 0.0f;
}
case LM_GGML_OP_IM2COL_BACK:
return src0->type == LM_GGML_TYPE_F32 && src1->type == LM_GGML_TYPE_F32;
return src0->type == LM_GGML_TYPE_F32 && (src1->type == LM_GGML_TYPE_F32 || src1->type == LM_GGML_TYPE_F16);
case LM_GGML_OP_GET_ROWS_BACK:
return src0->type == LM_GGML_TYPE_F32 || src0->type == LM_GGML_TYPE_F16;
case LM_GGML_OP_OUT_PROD:
return (src0->type == LM_GGML_TYPE_F32 || (lm_ggml_is_quantized(src0->type) && src0->ne[2] == src1->ne[2] && src0->ne[3] == src1->ne[3])) &&
return (src0->type == LM_GGML_TYPE_F32 ||
((src0->type == LM_GGML_TYPE_F16 || lm_ggml_is_quantized(src0->type)) && src0->ne[2] == src1->ne[2] && src0->ne[3] == src1->ne[3])) &&
src1->type == LM_GGML_TYPE_F32 && op->type == LM_GGML_TYPE_F32;
default:
return true;
Expand Down Expand Up @@ -594,6 +595,9 @@ static lm_ggml_backend_feature * lm_ggml_backend_cpu_get_features(lm_ggml_backen
if (lm_ggml_cpu_has_sme()) {
features.push_back({ "SME", "1" });
}
if (lm_ggml_cpu_has_sme2()) {
features.push_back({ "SME2", "1" });
}
if (lm_ggml_cpu_has_riscv_v()) {
features.push_back({ "RISCV_V", "1" });
}
Expand Down
Loading
Loading