mirror of
https://github.com/ggml-org/whisper.cpp.git
synced 2026-10-06 14:31:29 +02:00
talk-llama : sync llama.cpp
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include "llama-kv-cache.h"
|
||||
#include "llama-kv-cache-iswa.h"
|
||||
#include "llama-kv-cache-dsa.h"
|
||||
#include "llama-kv-cache-dsv4.h"
|
||||
#include "llama-memory-hybrid.h"
|
||||
#include "llama-memory-hybrid-iswa.h"
|
||||
#include "llama-memory-recurrent.h"
|
||||
@@ -17,6 +18,7 @@
|
||||
#include <cstring>
|
||||
#include <numeric>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
// dedup helpers
|
||||
@@ -61,26 +63,6 @@ static bool can_reuse_kq_mask(
|
||||
|
||||
// impl
|
||||
|
||||
static ggml_tensor * ggml_mul_mat_aux(
|
||||
ggml_context * ctx,
|
||||
ggml_tensor * cur,
|
||||
ggml_tensor * rot) {
|
||||
const auto n = rot->ne[0];
|
||||
|
||||
ggml_tensor * res;
|
||||
|
||||
if (!ggml_is_contiguous(cur)) {
|
||||
res = ggml_cont_2d (ctx, cur, n, ggml_nelements(cur)/n);
|
||||
} else {
|
||||
res = ggml_reshape_2d(ctx, cur, n, ggml_nelements(cur)/n);
|
||||
}
|
||||
res = ggml_mul_mat (ctx, rot, res);
|
||||
ggml_mul_mat_set_hint(res, GGML_HINT_SRC0_IS_HADAMARD);
|
||||
res = ggml_reshape_4d(ctx, res, cur->ne[0], cur->ne[1], cur->ne[2], cur->ne[3]);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void llm_graph_input_embd::set_input(const llama_ubatch * ubatch) {
|
||||
if (ubatch->token) {
|
||||
const int64_t n_tokens = ubatch->n_tokens;
|
||||
@@ -486,13 +468,17 @@ void llm_graph_input_attn_kv::set_input(const llama_ubatch * ubatch) {
|
||||
mctx->set_input_k_idxs(self_k_idxs, ubatch);
|
||||
mctx->set_input_v_idxs(self_v_idxs, ubatch);
|
||||
|
||||
mctx->set_input_kq_mask(self_kq_mask, ubatch, cparams.causal_attn);
|
||||
// the mask is left unallocated when the graph only stores K/V without attending
|
||||
// (e.g. DFlash's KV-injection pass)
|
||||
if (self_kq_mask && self_kq_mask->buffer) {
|
||||
mctx->set_input_kq_mask(self_kq_mask, ubatch, cparams.causal_attn);
|
||||
}
|
||||
|
||||
if (self_k_rot) {
|
||||
if (self_k_rot && self_k_rot->buffer) {
|
||||
mctx->set_input_k_rot(self_k_rot);
|
||||
}
|
||||
|
||||
if (self_v_rot) {
|
||||
if (self_v_rot && self_v_rot->buffer) {
|
||||
mctx->set_input_v_rot(self_v_rot);
|
||||
}
|
||||
}
|
||||
@@ -564,7 +550,9 @@ void llm_graph_input_attn_kv_iswa::set_input(const llama_ubatch * ubatch) {
|
||||
// base tensors may not be allocated if there are no non-SWA attention layers
|
||||
if (self_k_idxs && self_k_idxs->buffer) {
|
||||
mctx->get_base()->set_input_k_idxs(self_k_idxs, ubatch);
|
||||
mctx->get_base()->set_input_v_idxs(self_v_idxs, ubatch);
|
||||
if (self_v_idxs) {
|
||||
mctx->get_base()->set_input_v_idxs(self_v_idxs, ubatch);
|
||||
}
|
||||
}
|
||||
|
||||
// the kq mask guards on its own buffer: shared cells leave idxs unbacked while the mask stays live
|
||||
@@ -575,26 +563,28 @@ void llm_graph_input_attn_kv_iswa::set_input(const llama_ubatch * ubatch) {
|
||||
// swa tensors may not be allocated if there are no SWA attention layers
|
||||
if (self_k_idxs_swa && self_k_idxs_swa->buffer) {
|
||||
mctx->get_swa()->set_input_k_idxs(self_k_idxs_swa, ubatch);
|
||||
mctx->get_swa()->set_input_v_idxs(self_v_idxs_swa, ubatch);
|
||||
if (self_v_idxs_swa) {
|
||||
mctx->get_swa()->set_input_v_idxs(self_v_idxs_swa, ubatch);
|
||||
}
|
||||
}
|
||||
|
||||
if (self_kq_mask_swa && self_kq_mask_swa->buffer) {
|
||||
mctx->get_swa()->set_input_kq_mask(self_kq_mask_swa, ubatch, cparams.causal_attn);
|
||||
}
|
||||
|
||||
if (self_k_rot) {
|
||||
if (self_k_rot && self_k_rot->buffer) {
|
||||
mctx->get_base()->set_input_k_rot(self_k_rot);
|
||||
}
|
||||
|
||||
if (self_v_rot) {
|
||||
if (self_v_rot && self_v_rot->buffer) {
|
||||
mctx->get_base()->set_input_v_rot(self_v_rot);
|
||||
}
|
||||
|
||||
if (self_k_rot_swa) {
|
||||
if (self_k_rot_swa && self_k_rot_swa->buffer) {
|
||||
mctx->get_swa()->set_input_k_rot(self_k_rot_swa);
|
||||
}
|
||||
|
||||
if (self_v_rot_swa) {
|
||||
if (self_v_rot_swa && self_v_rot_swa->buffer) {
|
||||
mctx->get_swa()->set_input_v_rot(self_v_rot_swa);
|
||||
}
|
||||
}
|
||||
@@ -629,6 +619,305 @@ bool llm_graph_input_attn_kv_iswa::can_reuse(const llm_graph_params & params) {
|
||||
return res;
|
||||
}
|
||||
|
||||
static void dsv4_set_i64(ggml_tensor * dst, const std::vector<int64_t> & src) {
|
||||
if (!dst || !dst->buffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
GGML_ASSERT(dst->ne[0] == (int64_t) src.size());
|
||||
ggml_backend_tensor_set(dst, src.data(), 0, src.size()*ggml_element_size(dst));
|
||||
}
|
||||
|
||||
static void dsv4_set_i32(ggml_tensor * dst, const std::vector<int32_t> & src) {
|
||||
if (!dst || !dst->buffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
GGML_ASSERT(dst->ne[0] == (int64_t) src.size());
|
||||
ggml_backend_tensor_set(dst, src.data(), 0, src.size()*ggml_element_size(dst));
|
||||
}
|
||||
|
||||
static void dsv4_set_kq_mask(
|
||||
ggml_tensor * dst,
|
||||
const llama_kv_cache_dsv4_context::comp_plan & plan,
|
||||
uint32_t n_tokens,
|
||||
int64_t n_stream) {
|
||||
if (!dst || !dst->buffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
GGML_ASSERT(dst->type == GGML_TYPE_F32 || dst->type == GGML_TYPE_F16);
|
||||
GGML_ASSERT(n_stream > 0);
|
||||
GGML_ASSERT(n_tokens%n_stream == 0);
|
||||
GGML_ASSERT(dst->ne[0] == plan.n_kv);
|
||||
GGML_ASSERT(dst->ne[1] == (int64_t) n_tokens/n_stream);
|
||||
GGML_ASSERT(dst->ne[2] == 1);
|
||||
GGML_ASSERT(dst->ne[3] == n_stream);
|
||||
GGML_ASSERT((int64_t) plan.n_visible.size() == (int64_t) n_tokens);
|
||||
GGML_ASSERT(ggml_backend_buffer_is_host(dst->buffer));
|
||||
|
||||
if (dst->type == GGML_TYPE_F32) {
|
||||
float * data = (float *) dst->data;
|
||||
|
||||
for (int64_t i = 0; i < (int64_t) n_tokens; ++i) {
|
||||
const int32_t n_visible = plan.n_visible[i];
|
||||
|
||||
for (int64_t j = 0; j < dst->ne[0]; ++j) {
|
||||
data[i*dst->ne[0] + j] = j < n_visible ? 0.0f : -INFINITY;
|
||||
}
|
||||
}
|
||||
} else if (dst->type == GGML_TYPE_F16) {
|
||||
ggml_fp16_t * data = (ggml_fp16_t *) dst->data;
|
||||
const ggml_fp16_t fp16_ninf = llama_cast<ggml_fp16_t>(-INFINITY);
|
||||
const ggml_fp16_t fp16_zero = llama_cast<ggml_fp16_t>(0.0f);
|
||||
|
||||
for (int64_t i = 0; i < (int64_t) n_tokens; ++i) {
|
||||
const int32_t n_visible = plan.n_visible[i];
|
||||
|
||||
for (int64_t j = 0; j < dst->ne[0]; ++j) {
|
||||
data[i*dst->ne[0] + j] = j < n_visible ? fp16_zero : fp16_ninf;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ggml_tensor * dsv4_build_raw_kq_mask(
|
||||
ggml_context * ctx,
|
||||
const llama_kv_cache_dsv4_raw_context * mctx,
|
||||
const llama_ubatch & ubatch,
|
||||
const llama_cparams & cparams,
|
||||
int64_t n_stream) {
|
||||
const auto n_kv = mctx->get_n_kv();
|
||||
const auto n_tokens = ubatch.n_tokens;
|
||||
|
||||
GGML_ASSERT(n_stream > 0);
|
||||
GGML_ASSERT(n_tokens%n_stream == 0);
|
||||
|
||||
const auto type = cparams.flash_attn ? GGML_TYPE_F16 : GGML_TYPE_F32;
|
||||
|
||||
ggml_tensor * res = ggml_new_tensor_4d(ctx, type, n_kv, n_tokens/n_stream, 1, n_stream);
|
||||
ggml_set_input(res);
|
||||
ggml_set_name(res, "attn_inp_kq_mask");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool dsv4_can_reuse_raw_kq_mask(
|
||||
ggml_tensor * kq_mask,
|
||||
const llama_kv_cache_dsv4_raw_context * mctx,
|
||||
const llama_ubatch & ubatch,
|
||||
int64_t n_stream) {
|
||||
const auto n_kv = mctx->get_n_kv();
|
||||
const auto n_tokens = ubatch.n_tokens;
|
||||
|
||||
GGML_ASSERT(n_stream > 0);
|
||||
|
||||
bool res = true;
|
||||
|
||||
res &= (kq_mask->ne[0] == n_kv);
|
||||
res &= (kq_mask->ne[1] == n_tokens/n_stream);
|
||||
res &= (kq_mask->ne[2] == 1);
|
||||
res &= (kq_mask->ne[3] == n_stream);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static std::string dsv4_plan_positions(const std::vector<int32_t> & values) {
|
||||
std::ostringstream ss;
|
||||
ss << "[";
|
||||
for (size_t i = 0; i < values.size(); ++i) {
|
||||
if (i > 0) {
|
||||
ss << ", ";
|
||||
}
|
||||
ss << values[i];
|
||||
}
|
||||
ss << "]";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
static bool dsv4_compress_debug() {
|
||||
static const bool debug = []() {
|
||||
const char * env = getenv("LLAMA_DSV4_COMPRESS_DEBUG");
|
||||
return env && atoi(env) > 0;
|
||||
}();
|
||||
|
||||
return debug;
|
||||
}
|
||||
|
||||
static void dsv4_set_comp_inputs(
|
||||
const llm_graph_input_dsv4::comp_input & inp,
|
||||
const llama_kv_cache_dsv4_context::comp_plan & plan,
|
||||
const char * name,
|
||||
bool debug,
|
||||
uint32_t n_tokens,
|
||||
int64_t n_stream) {
|
||||
dsv4_set_i32(inp.state_pos, plan.state_pos);
|
||||
dsv4_set_i32(inp.state_persist_src_idxs, plan.state_persist_src_idxs);
|
||||
dsv4_set_i32(inp.state_persist_dst_idxs, plan.state_persist_dst_idxs);
|
||||
dsv4_set_i32(inp.state_read_idxs, plan.state_read_idxs);
|
||||
dsv4_set_i64(inp.state_write_idxs, plan.state_write_idxs);
|
||||
dsv4_set_i32(inp.state_write_pos, plan.state_write_pos);
|
||||
dsv4_set_kq_mask(inp.kq_mask, plan, n_tokens, n_stream);
|
||||
|
||||
if (debug || dsv4_compress_debug()) {
|
||||
LLAMA_LOG_INFO("%s: %s n_tokens=%u, n_stream=%d, state_persist_dst=%s, state_write_pos=%s\n",
|
||||
__func__, name, n_tokens, (int) n_stream,
|
||||
dsv4_plan_positions(plan.state_persist_dst_idxs).c_str(),
|
||||
dsv4_plan_positions(plan.state_write_pos).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
static bool dsv4_can_reuse_tensor_1d(ggml_tensor * t, int64_t ne0) {
|
||||
return (t == nullptr && ne0 == 0) || (t != nullptr && t->ne[0] == ne0);
|
||||
}
|
||||
|
||||
static bool dsv4_can_reuse_kq_mask(
|
||||
ggml_tensor * t,
|
||||
const llama_kv_cache_dsv4_context::comp_plan & plan,
|
||||
uint32_t n_tokens,
|
||||
int64_t n_stream) {
|
||||
if (plan.n_kv == 0) {
|
||||
return t == nullptr;
|
||||
}
|
||||
|
||||
GGML_ASSERT(n_stream > 0);
|
||||
|
||||
return t != nullptr &&
|
||||
t->ne[0] == plan.n_kv &&
|
||||
t->ne[1] == (int64_t) n_tokens/n_stream &&
|
||||
t->ne[2] == 1 &&
|
||||
t->ne[3] == n_stream;
|
||||
}
|
||||
|
||||
static bool dsv4_can_reuse_comp_input(
|
||||
const llm_graph_input_dsv4::comp_input & inp,
|
||||
const llama_kv_cache_dsv4_context::comp_plan & plan,
|
||||
uint32_t n_tokens,
|
||||
int64_t n_stream) {
|
||||
bool res = true;
|
||||
res &= dsv4_can_reuse_tensor_1d(inp.state_pos, plan.state_pos.size());
|
||||
res &= dsv4_can_reuse_tensor_1d(inp.state_persist_src_idxs, plan.state_persist_src_idxs.size());
|
||||
res &= dsv4_can_reuse_tensor_1d(inp.state_persist_dst_idxs, plan.state_persist_dst_idxs.size());
|
||||
res &= dsv4_can_reuse_tensor_1d(inp.state_read_idxs, plan.state_read_idxs.size());
|
||||
res &= dsv4_can_reuse_tensor_1d(inp.state_write_idxs, plan.state_write_idxs.size());
|
||||
res &= dsv4_can_reuse_tensor_1d(inp.state_write_pos, plan.state_write_pos.size());
|
||||
res &= dsv4_can_reuse_kq_mask(inp.kq_mask, plan, n_tokens, n_stream);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static ggml_tensor * dsv4_build_input_1d(
|
||||
ggml_context * ctx,
|
||||
ggml_type type,
|
||||
int64_t ne0,
|
||||
const std::string & name) {
|
||||
if (ne0 == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ggml_tensor * res = ggml_new_tensor_1d(ctx, type, ne0);
|
||||
ggml_set_input(res);
|
||||
ggml_set_name(res, name.c_str());
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void dsv4_build_comp_inputs(
|
||||
ggml_context * ctx,
|
||||
llm_graph_input_dsv4::comp_input & inp,
|
||||
const llama_kv_cache_dsv4_context::comp_plan & plan,
|
||||
const char * name,
|
||||
const llama_cparams & cparams,
|
||||
int64_t n_stream) {
|
||||
inp.state_pos = dsv4_build_input_1d(ctx, GGML_TYPE_I32, plan.state_pos.size(), std::string("dsv4_") + name + "_state_pos");
|
||||
inp.state_persist_src_idxs = dsv4_build_input_1d(ctx, GGML_TYPE_I32, plan.state_persist_src_idxs.size(), std::string("dsv4_") + name + "_state_persist_src_idxs");
|
||||
inp.state_persist_dst_idxs = dsv4_build_input_1d(ctx, GGML_TYPE_I32, plan.state_persist_dst_idxs.size(), std::string("dsv4_") + name + "_state_persist_dst_idxs");
|
||||
inp.state_read_idxs = dsv4_build_input_1d(ctx, GGML_TYPE_I32, plan.state_read_idxs.size(), std::string("dsv4_") + name + "_state_read_idxs");
|
||||
inp.state_write_idxs = dsv4_build_input_1d(ctx, GGML_TYPE_I64, plan.state_write_idxs.size(), std::string("dsv4_") + name + "_state_write_idxs");
|
||||
inp.state_write_pos = dsv4_build_input_1d(ctx, GGML_TYPE_I32, plan.state_write_pos.size(), std::string("dsv4_") + name + "_state_write_pos");
|
||||
|
||||
if (plan.n_kv > 0) {
|
||||
const int64_t n_tokens = (int64_t) plan.n_visible.size();
|
||||
|
||||
GGML_ASSERT(n_stream > 0);
|
||||
GGML_ASSERT(n_tokens%n_stream == 0);
|
||||
|
||||
inp.kq_mask = ggml_new_tensor_4d(ctx, cparams.flash_attn && strcmp(name, "lid") != 0 ? GGML_TYPE_F16 : GGML_TYPE_F32, plan.n_kv, n_tokens/n_stream, 1, n_stream);
|
||||
ggml_set_input(inp.kq_mask);
|
||||
ggml_set_name(inp.kq_mask, (std::string("dsv4_") + name + "_kq_mask").c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void llm_graph_input_dsv4_raw::set_input(const llama_ubatch * ubatch) {
|
||||
if (self_k_idxs && self_k_idxs->buffer) {
|
||||
mctx->set_input_k_idxs(self_k_idxs);
|
||||
}
|
||||
|
||||
if (self_kq_mask && self_kq_mask->buffer) {
|
||||
mctx->set_input_kq_mask(self_kq_mask, ubatch, cparams.causal_attn);
|
||||
}
|
||||
|
||||
if (self_k_rot) {
|
||||
mctx->set_input_k_rot(self_k_rot);
|
||||
}
|
||||
}
|
||||
|
||||
void llm_graph_input_dsv4::set_input(const llama_ubatch * ubatch) {
|
||||
const auto & plan_csa = mctx->get_csa_plan(*ubatch);
|
||||
const auto & plan_hca = mctx->get_hca_plan(*ubatch);
|
||||
const auto & plan_lid = mctx->get_lid_plan(*ubatch);
|
||||
const int64_t n_stream = plan_csa.n_stream;
|
||||
|
||||
inp_raw->mctx = mctx->get_raw();
|
||||
inp_raw->set_input(ubatch);
|
||||
|
||||
dsv4_set_comp_inputs(inp_csa, plan_csa, "csa", debug > 0, ubatch->n_tokens, n_stream);
|
||||
dsv4_set_comp_inputs(inp_hca, plan_hca, "hca", debug > 0, ubatch->n_tokens, n_stream);
|
||||
dsv4_set_comp_inputs(inp_lid, plan_lid, "lid", debug > 0, ubatch->n_tokens, n_stream);
|
||||
|
||||
if (inp_csa.k_rot && inp_csa.k_rot->buffer) {
|
||||
mctx->get_csa()->set_input_k_rot(inp_csa.k_rot);
|
||||
}
|
||||
|
||||
if (inp_hca.k_rot && inp_hca.k_rot->buffer) {
|
||||
mctx->get_hca()->set_input_k_rot(inp_hca.k_rot);
|
||||
}
|
||||
|
||||
if (inp_lid.k_rot && inp_lid.k_rot->buffer) {
|
||||
mctx->get_lid()->set_input_k_rot(inp_lid.k_rot);
|
||||
}
|
||||
}
|
||||
|
||||
bool llm_graph_input_dsv4::can_reuse(const llm_graph_params & params) {
|
||||
const auto * mctx = static_cast<const llama_kv_cache_dsv4_context *>(params.mctx);
|
||||
|
||||
this->mctx = mctx;
|
||||
inp_raw->mctx = mctx->get_raw();
|
||||
|
||||
bool res = true;
|
||||
|
||||
const auto & plan_csa = mctx->get_csa_plan(params.ubatch);
|
||||
const auto & plan_hca = mctx->get_hca_plan(params.ubatch);
|
||||
const auto & plan_lid = mctx->get_lid_plan(params.ubatch);
|
||||
const int64_t n_stream = plan_csa.n_stream;
|
||||
|
||||
const auto * raw_ctx = mctx->get_raw();
|
||||
inp_raw->mctx = raw_ctx;
|
||||
|
||||
if (inp_raw->self_k_idxs && inp_raw->self_k_idxs->buffer) {
|
||||
res &= inp_raw->self_k_idxs->ne[0] == raw_ctx->get_n_write();
|
||||
}
|
||||
if (inp_raw->self_kq_mask && inp_raw->self_kq_mask->buffer) {
|
||||
res &= dsv4_can_reuse_raw_kq_mask(inp_raw->self_kq_mask, raw_ctx, params.ubatch, n_stream);
|
||||
}
|
||||
|
||||
res &= dsv4_can_reuse_comp_input(inp_csa, plan_csa, params.ubatch.n_tokens, n_stream);
|
||||
res &= dsv4_can_reuse_comp_input(inp_hca, plan_hca, params.ubatch.n_tokens, n_stream);
|
||||
res &= dsv4_can_reuse_comp_input(inp_lid, plan_lid, params.ubatch.n_tokens, n_stream);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void llm_graph_input_attn_cross::set_input(const llama_ubatch * ubatch) {
|
||||
GGML_ASSERT(cross_kq_mask);
|
||||
|
||||
@@ -904,6 +1193,7 @@ void llm_graph_result::reset() {
|
||||
t_logits = nullptr;
|
||||
t_embd = nullptr;
|
||||
t_embd_pooled = nullptr;
|
||||
t_h_nextn = nullptr;
|
||||
|
||||
t_layer_inp.resize(LLAMA_MAX_LAYERS);
|
||||
std::fill(t_layer_inp.begin(), t_layer_inp.end(), nullptr);
|
||||
@@ -916,6 +1206,7 @@ void llm_graph_result::reset() {
|
||||
params = {};
|
||||
|
||||
inputs.clear();
|
||||
fused_nodes.clear();
|
||||
|
||||
buf_compute_meta.resize(ggml_tensor_overhead()*max_nodes + ggml_graph_overhead_custom(max_nodes, false));
|
||||
|
||||
@@ -1017,6 +1308,10 @@ llm_graph_input_i * llm_graph_result::add_input(llm_graph_input_ptr input) {
|
||||
return inputs.back().get();
|
||||
}
|
||||
|
||||
void llm_graph_result::add_fused_node(llm_graph_fused_node result) {
|
||||
fused_nodes.push_back(result);
|
||||
}
|
||||
|
||||
void llm_graph_result::set_params(const llm_graph_params & params) {
|
||||
this->params = params;
|
||||
}
|
||||
@@ -1076,6 +1371,8 @@ void llm_graph_context::cb(ggml_tensor * cur, const char * name, int il) const {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ggml_tensor * llm_graph_context::build_cvec(
|
||||
ggml_tensor * cur,
|
||||
int il) const {
|
||||
@@ -1346,20 +1643,24 @@ ggml_tensor * llm_graph_context::build_ffn(
|
||||
switch (type_op) {
|
||||
case LLM_FFN_SILU:
|
||||
if (gate && type_gate == LLM_FFN_PAR) {
|
||||
// Step35: HF clamps gate (after SiLU) and up before multiplication
|
||||
if (arch == LLM_ARCH_STEP35 && il >= 0) {
|
||||
if (il >= 0) {
|
||||
const float limit = hparams.swiglu_clamp_shexp[il];
|
||||
constexpr float eps = 1e-6f;
|
||||
if (limit > eps) {
|
||||
ggml_tensor * gate_act = ggml_silu(ctx0, cur);
|
||||
cb(gate_act, "ffn_silu", il);
|
||||
gate_act = ggml_clamp(ctx0, gate_act, -INFINITY, limit);
|
||||
cb(gate_act, "ffn_silu_clamped", il);
|
||||
|
||||
tmp = ggml_clamp(ctx0, tmp, -limit, limit);
|
||||
cb(tmp, "ffn_up_clamped", il);
|
||||
|
||||
cur = ggml_mul(ctx0, gate_act, tmp);
|
||||
if (arch == LLM_ARCH_DEEPSEEK4) {
|
||||
cur = ggml_clamp(ctx0, cur, -INFINITY, limit);
|
||||
cb(cur, "ffn_gate_clamped", il);
|
||||
cur = ggml_swiglu_split(ctx0, cur, tmp);
|
||||
} else {
|
||||
ggml_tensor * gate_act = ggml_silu(ctx0, cur);
|
||||
cb(gate_act, "ffn_silu", il);
|
||||
gate_act = ggml_clamp(ctx0, gate_act, -INFINITY, limit);
|
||||
cb(gate_act, "ffn_silu_clamped", il);
|
||||
cur = ggml_mul(ctx0, gate_act, tmp);
|
||||
}
|
||||
cb(cur, "ffn_swiglu_limited", il);
|
||||
type_gate = LLM_FFN_SEQ;
|
||||
break;
|
||||
@@ -1469,7 +1770,8 @@ ggml_tensor * llm_graph_context::build_moe_ffn(
|
||||
ggml_tensor * gate_up_exps,
|
||||
ggml_tensor * up_exps_s,
|
||||
ggml_tensor * gate_exps_s,
|
||||
ggml_tensor * down_exps_s) const {
|
||||
ggml_tensor * down_exps_s,
|
||||
ggml_tensor * selected_experts_in) const {
|
||||
return build_moe_ffn(
|
||||
cur,
|
||||
gate_inp, /* gate_inp_b */ nullptr,
|
||||
@@ -1489,7 +1791,8 @@ ggml_tensor * llm_graph_context::build_moe_ffn(
|
||||
/* gate_up_exps_b */ nullptr,
|
||||
up_exps_s,
|
||||
gate_exps_s,
|
||||
down_exps_s
|
||||
down_exps_s,
|
||||
selected_experts_in
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1516,7 +1819,8 @@ ggml_tensor * llm_graph_context::build_moe_ffn(
|
||||
ggml_tensor * gate_up_exps_b,
|
||||
ggml_tensor * up_exps_s,
|
||||
ggml_tensor * gate_exps_s,
|
||||
ggml_tensor * down_exps_s) const {
|
||||
ggml_tensor * down_exps_s,
|
||||
ggml_tensor * selected_experts_in) const {
|
||||
const int64_t n_embd = cur->ne[0];
|
||||
const int64_t n_tokens = cur->ne[1];
|
||||
const bool weight_before_ffn = arch == LLM_ARCH_LLAMA4; // for llama4, we apply the sigmoid-ed weights before the FFN
|
||||
@@ -1525,6 +1829,9 @@ ggml_tensor * llm_graph_context::build_moe_ffn(
|
||||
|
||||
if (probs_in == nullptr) {
|
||||
logits = build_lora_mm(gate_inp, cur); // [n_expert, n_tokens]
|
||||
if (gating_op == LLAMA_EXPERT_GATING_FUNC_TYPE_SQRT_SOFTPLUS) {
|
||||
ggml_mul_mat_set_prec(logits, GGML_PREC_F32);
|
||||
}
|
||||
cb(logits, "ffn_moe_logits", il);
|
||||
} else {
|
||||
logits = probs_in;
|
||||
@@ -1549,6 +1856,10 @@ ggml_tensor * llm_graph_context::build_moe_ffn(
|
||||
{
|
||||
probs = logits; // [n_expert, n_tokens]
|
||||
} break;
|
||||
case LLAMA_EXPERT_GATING_FUNC_TYPE_SQRT_SOFTPLUS:
|
||||
{
|
||||
probs = ggml_sqrt(ctx0, ggml_softplus(ctx0, logits)); // [n_expert, n_tokens]
|
||||
} break;
|
||||
default:
|
||||
GGML_ABORT("fatal error");
|
||||
}
|
||||
@@ -1599,8 +1910,11 @@ ggml_tensor * llm_graph_context::build_moe_ffn(
|
||||
}
|
||||
|
||||
// select experts
|
||||
ggml_tensor * selected_experts = ggml_argsort_top_k(ctx0, selection_probs, n_expert_used); // [n_expert_used, n_tokens]
|
||||
cb(selected_experts->src[0], "ffn_moe_argsort", il);
|
||||
ggml_tensor * selected_experts = selected_experts_in;
|
||||
if (selected_experts == nullptr) {
|
||||
selected_experts = ggml_argsort_top_k(ctx0, selection_probs, n_expert_used); // [n_expert_used, n_tokens]
|
||||
cb(selected_experts->src[0], "ffn_moe_argsort", il);
|
||||
}
|
||||
cb(selected_experts, "ffn_moe_topk", il);
|
||||
|
||||
if (arch == LLM_ARCH_GROVEMOE && n_expert != hparams.n_expert) {
|
||||
@@ -1713,20 +2027,24 @@ ggml_tensor * llm_graph_context::build_moe_ffn(
|
||||
switch (type_op) {
|
||||
case LLM_FFN_SILU:
|
||||
if (gate_exps) {
|
||||
// Step35: per-layer clamp for routed experts
|
||||
if (arch == LLM_ARCH_STEP35 && il >= 0) {
|
||||
if (il >= 0) {
|
||||
const float limit = hparams.swiglu_clamp_exp[il];
|
||||
constexpr float eps = 1e-6f;
|
||||
if (limit > eps) {
|
||||
ggml_tensor * gate_act = ggml_silu(ctx0, cur);
|
||||
cb(gate_act, "ffn_moe_silu", il);
|
||||
gate_act = ggml_clamp(ctx0, gate_act, -INFINITY, limit);
|
||||
cb(gate_act, "ffn_moe_silu_clamped", il);
|
||||
|
||||
up = ggml_clamp(ctx0, up, -limit, limit);
|
||||
cb(up, "ffn_moe_up_clamped", il);
|
||||
|
||||
cur = ggml_mul(ctx0, gate_act, up);
|
||||
if (arch == LLM_ARCH_DEEPSEEK4) {
|
||||
cur = ggml_clamp(ctx0, cur, -INFINITY, limit);
|
||||
cb(cur, "ffn_moe_gate_clamped", il);
|
||||
cur = ggml_swiglu_split(ctx0, cur, up);
|
||||
} else {
|
||||
ggml_tensor * gate_act = ggml_silu(ctx0, cur);
|
||||
cb(gate_act, "ffn_moe_silu", il);
|
||||
gate_act = ggml_clamp(ctx0, gate_act, -INFINITY, limit);
|
||||
cb(gate_act, "ffn_moe_silu_clamped", il);
|
||||
cur = ggml_mul(ctx0, gate_act, up);
|
||||
}
|
||||
cb(cur, "ffn_moe_swiglu_limited", il);
|
||||
break;
|
||||
}
|
||||
@@ -2105,7 +2423,7 @@ ggml_tensor * llm_graph_context::build_attn_mha(
|
||||
|
||||
cur = ggml_flash_attn_ext(ctx0, q, k, v, kq_mask, kq_scale, hparams.f_max_alibi_bias,
|
||||
hparams.attn_soft_cap ? hparams.f_attn_logit_softcapping : 0.0f);
|
||||
cb(cur, LLAMA_TENSOR_NAME_FATTN, il);
|
||||
res->add_fused_node({LLM_FUSED_OP_FLASH_ATTN, cur, il});
|
||||
|
||||
ggml_flash_attn_ext_add_sinks(cur, sinks);
|
||||
ggml_flash_attn_ext_set_prec (cur, GGML_PREC_F32);
|
||||
@@ -2324,12 +2642,12 @@ ggml_tensor * llm_graph_context::build_attn(
|
||||
GGML_ASSERT(v_mla == nullptr);
|
||||
|
||||
if (inp->self_k_rot) {
|
||||
q_cur = ggml_mul_mat_aux(ctx0, q_cur, inp->self_k_rot);
|
||||
k_cur = ggml_mul_mat_aux(ctx0, k_cur, inp->self_k_rot);
|
||||
q_cur = llama_mul_mat_hadamard(ctx0, q_cur, inp->self_k_rot);
|
||||
k_cur = llama_mul_mat_hadamard(ctx0, k_cur, inp->self_k_rot);
|
||||
}
|
||||
|
||||
if (inp->self_v_rot) {
|
||||
v_cur = ggml_mul_mat_aux(ctx0, v_cur, inp->self_v_rot);
|
||||
v_cur = llama_mul_mat_hadamard(ctx0, v_cur, inp->self_v_rot);
|
||||
}
|
||||
|
||||
// these nodes are added to the graph together so that they are not reordered
|
||||
@@ -2360,7 +2678,7 @@ ggml_tensor * llm_graph_context::build_attn(
|
||||
cb(cur, "kqv_out", il);
|
||||
|
||||
if (inp->self_v_rot) {
|
||||
cur = ggml_mul_mat_aux(ctx0, cur, inp->self_v_rot);
|
||||
cur = llama_mul_mat_hadamard(ctx0, cur, inp->self_v_rot);
|
||||
}
|
||||
|
||||
if (wo) {
|
||||
@@ -2565,14 +2883,14 @@ ggml_tensor * llm_graph_context::build_attn(
|
||||
auto * v_rot = is_swa ? inp->self_v_rot_swa : inp->self_v_rot;
|
||||
|
||||
if (k_rot) {
|
||||
q_cur = ggml_mul_mat_aux(ctx0, q_cur, k_rot);
|
||||
q_cur = llama_mul_mat_hadamard(ctx0, q_cur, k_rot);
|
||||
if (k_cur) {
|
||||
k_cur = ggml_mul_mat_aux(ctx0, k_cur, k_rot);
|
||||
k_cur = llama_mul_mat_hadamard(ctx0, k_cur, k_rot);
|
||||
}
|
||||
}
|
||||
if (v_rot) {
|
||||
if (v_cur) {
|
||||
v_cur = ggml_mul_mat_aux(ctx0, v_cur, v_rot);
|
||||
v_cur = llama_mul_mat_hadamard(ctx0, v_cur, v_rot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2615,7 +2933,7 @@ ggml_tensor * llm_graph_context::build_attn(
|
||||
cb(cur, "kqv_out", il);
|
||||
|
||||
if (v_rot) {
|
||||
cur = ggml_mul_mat_aux(ctx0, cur, v_rot);
|
||||
cur = llama_mul_mat_hadamard(ctx0, cur, v_rot);
|
||||
}
|
||||
|
||||
if (wo) {
|
||||
@@ -2755,6 +3073,33 @@ llm_graph_input_attn_kv_iswa * llm_graph_context::build_attn_inp_kv_iswa() const
|
||||
return (llm_graph_input_attn_kv_iswa *) res->add_input(std::move(inp));
|
||||
}
|
||||
|
||||
llm_graph_input_dsv4 * llm_graph_context::build_inp_dsv4() const {
|
||||
const auto * mctx_cur = static_cast<const llama_kv_cache_dsv4_context *>(mctx);
|
||||
const auto * raw_ctx = mctx_cur->get_raw();
|
||||
|
||||
auto inp_raw = std::make_unique<llm_graph_input_dsv4_raw>(cparams, raw_ctx);
|
||||
|
||||
const int64_t n_stream = mctx_cur->get_csa_plan(ubatch).n_stream;
|
||||
|
||||
GGML_ASSERT(hparams.swa_type != LLAMA_SWA_TYPE_NONE && "DSV4 expects SWA raw cache");
|
||||
|
||||
inp_raw->self_k_idxs = raw_ctx->build_input_k_idxs(ctx0, ubatch);
|
||||
inp_raw->self_kq_mask = dsv4_build_raw_kq_mask(ctx0, raw_ctx, ubatch, cparams, n_stream);
|
||||
inp_raw->self_kq_mask_cnv = inp_raw->self_kq_mask;
|
||||
|
||||
inp_raw->self_k_rot = raw_ctx->build_input_k_rot(ctx0);
|
||||
auto inp = std::make_unique<llm_graph_input_dsv4>(cparams, std::move(inp_raw), mctx_cur);
|
||||
|
||||
dsv4_build_comp_inputs(ctx0, inp->inp_csa, mctx_cur->get_csa_plan(ubatch), "csa", cparams, n_stream);
|
||||
dsv4_build_comp_inputs(ctx0, inp->inp_hca, mctx_cur->get_hca_plan(ubatch), "hca", cparams, n_stream);
|
||||
dsv4_build_comp_inputs(ctx0, inp->inp_lid, mctx_cur->get_lid_plan(ubatch), "lid", cparams, n_stream);
|
||||
inp->inp_csa.k_rot = mctx_cur->get_csa()->build_input_k_rot(ctx0);
|
||||
inp->inp_hca.k_rot = mctx_cur->get_hca()->build_input_k_rot(ctx0);
|
||||
inp->inp_lid.k_rot = mctx_cur->get_lid()->build_input_k_rot(ctx0);
|
||||
|
||||
return (llm_graph_input_dsv4 *) res->add_input(std::move(inp));
|
||||
}
|
||||
|
||||
ggml_tensor * llm_graph_context::build_rs(
|
||||
ggml_tensor * s,
|
||||
ggml_tensor * state_copy_main,
|
||||
|
||||
Reference in New Issue
Block a user