DeepseekV4: Add fused hyper-connection ops (#25585)
* dsv4 hc-ops * add missing files; * add cparams * update rpc version * address review comments * address review comments
This commit is contained in:
+135
-2
@@ -1080,6 +1080,9 @@ static const char * GGML_OP_NAME[GGML_OP_COUNT] = {
|
||||
"SOLVE_TRI",
|
||||
"GATED_DELTA_NET",
|
||||
"LIGHTNING_INDEXER",
|
||||
"DSV4_HC_COMB",
|
||||
"DSV4_HC_PRE",
|
||||
"DSV4_HC_POST",
|
||||
|
||||
"UNARY",
|
||||
|
||||
@@ -1097,7 +1100,7 @@ static const char * GGML_OP_NAME[GGML_OP_COUNT] = {
|
||||
"GLU",
|
||||
};
|
||||
|
||||
static_assert(GGML_OP_COUNT == 98, "GGML_OP_COUNT != 98");
|
||||
static_assert(GGML_OP_COUNT == 101, "GGML_OP_COUNT != 101");
|
||||
|
||||
static const char * GGML_OP_SYMBOL[GGML_OP_COUNT] = {
|
||||
"none",
|
||||
@@ -1192,6 +1195,9 @@ static const char * GGML_OP_SYMBOL[GGML_OP_COUNT] = {
|
||||
"A X = B, A triangular, solve X",
|
||||
"gated_delta_net(q, k, v, g, beta, s)",
|
||||
"lightning_indexer(q, k, weights, mask)",
|
||||
"dsv4_hc_comb(mixes, scale, base)",
|
||||
"dsv4_hc_pre(x, weights)",
|
||||
"dsv4_hc_post(x, residual, post, comb)",
|
||||
|
||||
"unary(x)",
|
||||
|
||||
@@ -1209,7 +1215,7 @@ static const char * GGML_OP_SYMBOL[GGML_OP_COUNT] = {
|
||||
"glu(x)",
|
||||
};
|
||||
|
||||
static_assert(GGML_OP_COUNT == 98, "GGML_OP_COUNT != 98");
|
||||
static_assert(GGML_OP_COUNT == 101, "GGML_OP_COUNT != 101");
|
||||
|
||||
static_assert(GGML_OP_POOL_COUNT == 2, "GGML_OP_POOL_COUNT != 2");
|
||||
|
||||
@@ -5437,6 +5443,7 @@ struct ggml_tensor * ggml_flash_attn_ext(
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void ggml_flash_attn_ext_set_prec(
|
||||
struct ggml_tensor * a,
|
||||
enum ggml_prec prec) {
|
||||
@@ -6337,6 +6344,132 @@ struct ggml_tensor * ggml_lightning_indexer(
|
||||
return result;
|
||||
}
|
||||
|
||||
// ggml_dsv4_hc_comb
|
||||
|
||||
struct ggml_tensor * ggml_dsv4_hc_comb(
|
||||
struct ggml_context * ctx,
|
||||
struct ggml_tensor * mixes,
|
||||
struct ggml_tensor * scale,
|
||||
struct ggml_tensor * base,
|
||||
float eps,
|
||||
int32_t n_iter) {
|
||||
GGML_ASSERT(mixes->type == GGML_TYPE_F32);
|
||||
GGML_ASSERT(scale->type == GGML_TYPE_F32);
|
||||
GGML_ASSERT(base->type == GGML_TYPE_F32);
|
||||
GGML_ASSERT(n_iter > 0);
|
||||
|
||||
const int64_t hc_mix_dim = mixes->ne[0];
|
||||
const int64_t n_tokens = mixes->ne[1];
|
||||
|
||||
int64_t hc = 0;
|
||||
for (int64_t i = 1; i*i + 2*i <= hc_mix_dim; ++i) {
|
||||
if ((2 + i)*i == hc_mix_dim) {
|
||||
hc = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GGML_ASSERT(hc > 0);
|
||||
GGML_ASSERT(hc == 4);
|
||||
GGML_ASSERT(mixes->ne[2] == 1);
|
||||
GGML_ASSERT(mixes->ne[3] == 1);
|
||||
GGML_ASSERT(scale->ne[0] >= 3);
|
||||
GGML_ASSERT(scale->ne[1] == 1);
|
||||
GGML_ASSERT(scale->ne[2] == 1);
|
||||
GGML_ASSERT(scale->ne[3] == 1);
|
||||
GGML_ASSERT(base->ne[0] == hc_mix_dim);
|
||||
GGML_ASSERT(base->ne[1] == 1);
|
||||
GGML_ASSERT(base->ne[2] == 1);
|
||||
GGML_ASSERT(base->ne[3] == 1);
|
||||
|
||||
struct ggml_tensor * result = ggml_new_tensor_3d(ctx, GGML_TYPE_F32, hc, hc, n_tokens);
|
||||
|
||||
ggml_set_op_params_f32(result, 0, eps);
|
||||
ggml_set_op_params_i32(result, 1, n_iter);
|
||||
|
||||
result->op = GGML_OP_DSV4_HC_COMB;
|
||||
result->src[0] = mixes;
|
||||
result->src[1] = scale;
|
||||
result->src[2] = base;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ggml_dsv4_hc_pre
|
||||
|
||||
struct ggml_tensor * ggml_dsv4_hc_pre(
|
||||
struct ggml_context * ctx,
|
||||
struct ggml_tensor * x,
|
||||
struct ggml_tensor * weights) {
|
||||
GGML_ASSERT(x->type == GGML_TYPE_F32);
|
||||
GGML_ASSERT(weights->type == GGML_TYPE_F32);
|
||||
|
||||
const int64_t n_embd = x->ne[0];
|
||||
const int64_t hc = x->ne[1];
|
||||
const int64_t n_tokens = x->ne[2];
|
||||
|
||||
GGML_ASSERT(hc > 0);
|
||||
GGML_ASSERT(x->ne[3] == 1);
|
||||
GGML_ASSERT(weights->ne[0] == hc);
|
||||
GGML_ASSERT(weights->ne[1] == n_tokens);
|
||||
GGML_ASSERT(weights->ne[2] == 1);
|
||||
GGML_ASSERT(weights->ne[3] == 1);
|
||||
|
||||
struct ggml_tensor * result = ggml_new_tensor_2d(ctx, GGML_TYPE_F32, n_embd, n_tokens);
|
||||
|
||||
result->op = GGML_OP_DSV4_HC_PRE;
|
||||
result->src[0] = x;
|
||||
result->src[1] = weights;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ggml_dsv4_hc_post
|
||||
|
||||
struct ggml_tensor * ggml_dsv4_hc_post(
|
||||
struct ggml_context * ctx,
|
||||
struct ggml_tensor * x,
|
||||
struct ggml_tensor * residual,
|
||||
struct ggml_tensor * post,
|
||||
struct ggml_tensor * comb) {
|
||||
GGML_ASSERT(x->type == GGML_TYPE_F32);
|
||||
GGML_ASSERT(residual->type == GGML_TYPE_F32);
|
||||
GGML_ASSERT(post->type == GGML_TYPE_F32);
|
||||
GGML_ASSERT(comb->type == GGML_TYPE_F32);
|
||||
|
||||
const int64_t n_embd = x->ne[0];
|
||||
const int64_t n_tokens = x->ne[1];
|
||||
const int64_t hc = residual->ne[1];
|
||||
|
||||
GGML_ASSERT(hc > 0);
|
||||
GGML_ASSERT(x->ne[2] == 1);
|
||||
GGML_ASSERT(x->ne[3] == 1);
|
||||
|
||||
GGML_ASSERT(residual->ne[0] == n_embd);
|
||||
GGML_ASSERT(residual->ne[2] == n_tokens);
|
||||
GGML_ASSERT(residual->ne[3] == 1);
|
||||
|
||||
GGML_ASSERT(post->ne[0] == hc);
|
||||
GGML_ASSERT(post->ne[1] == n_tokens);
|
||||
GGML_ASSERT(post->ne[2] == 1);
|
||||
GGML_ASSERT(post->ne[3] == 1);
|
||||
|
||||
GGML_ASSERT(comb->ne[0] == hc);
|
||||
GGML_ASSERT(comb->ne[1] == hc);
|
||||
GGML_ASSERT(comb->ne[2] == n_tokens);
|
||||
GGML_ASSERT(comb->ne[3] == 1);
|
||||
|
||||
struct ggml_tensor * result = ggml_new_tensor_3d(ctx, GGML_TYPE_F32, n_embd, hc, n_tokens);
|
||||
|
||||
result->op = GGML_OP_DSV4_HC_POST;
|
||||
result->src[0] = x;
|
||||
result->src[1] = residual;
|
||||
result->src[2] = post;
|
||||
result->src[3] = comb;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct ggml_hash_set ggml_hash_set_new(size_t size) {
|
||||
|
||||
Reference in New Issue
Block a user