Skip to content

Commit 9811b19

Browse files
cchuterclaude
andcommitted
ggml: add DeepSeek V4 hyperconnection + KV ops (CPU)
Five new ggml ops for DeepSeek-V4-Flash with CPU reference implementations and test-backend-ops coverage: DSV4_HC_SPLIT_SINKHORN, DSV4_HC_WEIGHTED_SUM, DSV4_HC_EXPAND, DSV4_FP8_KV_QUANTIZE, DSV4_ROPE_TAIL. CPU is the reference backend. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 0253fb2 commit 9811b19

6 files changed

Lines changed: 1047 additions & 2 deletions

File tree

ggml/include/ggml.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,11 @@ extern "C" {
567567
GGML_OP_RWKV_WKV7,
568568
GGML_OP_SOLVE_TRI,
569569
GGML_OP_GATED_DELTA_NET,
570+
GGML_OP_DSV4_HC_SPLIT_SINKHORN,
571+
GGML_OP_DSV4_HC_WEIGHTED_SUM,
572+
GGML_OP_DSV4_HC_EXPAND,
573+
GGML_OP_DSV4_FP8_KV_QUANTIZE,
574+
GGML_OP_DSV4_ROPE_TAIL,
570575

571576
GGML_OP_UNARY,
572577

@@ -2555,6 +2560,61 @@ extern "C" {
25552560
struct ggml_tensor * beta,
25562561
struct ggml_tensor * state);
25572562

2563+
// DeepSeek V4 hyperconnection helper.
2564+
// Splits [mix, tokens] into pre/post/comb regions and applies the
2565+
// Sinkhorn normalization used by the reference implementation.
2566+
GGML_API struct ggml_tensor * ggml_dsv4_hc_split_sinkhorn(
2567+
struct ggml_context * ctx,
2568+
struct ggml_tensor * mixes,
2569+
struct ggml_tensor * scale,
2570+
struct ggml_tensor * base,
2571+
int n_hc,
2572+
int sinkhorn_iters,
2573+
float eps);
2574+
2575+
// DeepSeek V4 hyperconnection weighted-sum helper.
2576+
// Computes sum_hc weights[hc, token] * x[embd, hc, token].
2577+
GGML_API struct ggml_tensor * ggml_dsv4_hc_weighted_sum(
2578+
struct ggml_context * ctx,
2579+
struct ggml_tensor * x,
2580+
struct ggml_tensor * weights);
2581+
2582+
// DeepSeek V4 hyperconnection expand helper.
2583+
// Computes post * block_out + comb^T @ residual for each token.
2584+
GGML_API struct ggml_tensor * ggml_dsv4_hc_expand(
2585+
struct ggml_context * ctx,
2586+
struct ggml_tensor * block_out,
2587+
struct ggml_tensor * residual,
2588+
struct ggml_tensor * post,
2589+
struct ggml_tensor * comb);
2590+
2591+
// DeepSeek V4 FP8 KV-cache simulation helper.
2592+
// Quantizes/dequantizes the non-RoPE prefix in E4M3FN blocks and leaves
2593+
// the RoPE tail unchanged, matching the reference inference path.
2594+
GGML_API struct ggml_tensor * ggml_dsv4_fp8_kv_quantize(
2595+
struct ggml_context * ctx,
2596+
struct ggml_tensor * a,
2597+
int n_rot);
2598+
2599+
// DeepSeek V4 partial RoPE helper.
2600+
// Leaves the non-RoPE prefix unchanged and applies RoPE to the tail,
2601+
// matching ggml_concat(prefix, ggml_rope_ext(tail)).
2602+
GGML_API struct ggml_tensor * ggml_dsv4_rope_tail(
2603+
struct ggml_context * ctx,
2604+
struct ggml_tensor * a,
2605+
struct ggml_tensor * pos,
2606+
struct ggml_tensor * freq_factors,
2607+
int n_dims,
2608+
int mode,
2609+
int n_ctx_orig,
2610+
float freq_base,
2611+
float freq_scale,
2612+
float ext_factor,
2613+
float attn_factor,
2614+
float beta_fast,
2615+
float beta_slow,
2616+
bool inverse);
2617+
25582618
// custom operators
25592619

25602620
typedef void (*ggml_custom1_op_t)(struct ggml_tensor * dst , const struct ggml_tensor * a, int ith, int nth, void * userdata);

ggml/src/ggml-cpu/ggml-cpu.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,6 +2047,26 @@ static void ggml_compute_forward(struct ggml_compute_params * params, struct ggm
20472047
{
20482048
ggml_compute_forward_gated_delta_net(params, tensor);
20492049
} break;
2050+
case GGML_OP_DSV4_HC_SPLIT_SINKHORN:
2051+
{
2052+
ggml_compute_forward_dsv4_hc_split_sinkhorn(params, tensor);
2053+
} break;
2054+
case GGML_OP_DSV4_HC_WEIGHTED_SUM:
2055+
{
2056+
ggml_compute_forward_dsv4_hc_weighted_sum(params, tensor);
2057+
} break;
2058+
case GGML_OP_DSV4_HC_EXPAND:
2059+
{
2060+
ggml_compute_forward_dsv4_hc_expand(params, tensor);
2061+
} break;
2062+
case GGML_OP_DSV4_FP8_KV_QUANTIZE:
2063+
{
2064+
ggml_compute_forward_dsv4_fp8_kv_quantize(params, tensor);
2065+
} break;
2066+
case GGML_OP_DSV4_ROPE_TAIL:
2067+
{
2068+
ggml_compute_forward_dsv4_rope_tail(params, tensor);
2069+
} break;
20502070
case GGML_OP_MAP_CUSTOM1:
20512071
{
20522072
ggml_compute_forward_map_custom1(params, tensor);
@@ -2227,6 +2247,11 @@ static int ggml_get_n_tasks(struct ggml_tensor * node, int n_threads) {
22272247
case GGML_OP_COUNT_EQUAL:
22282248
case GGML_OP_SOLVE_TRI:
22292249
case GGML_OP_GATED_DELTA_NET:
2250+
case GGML_OP_DSV4_HC_SPLIT_SINKHORN:
2251+
case GGML_OP_DSV4_HC_WEIGHTED_SUM:
2252+
case GGML_OP_DSV4_HC_EXPAND:
2253+
case GGML_OP_DSV4_FP8_KV_QUANTIZE:
2254+
case GGML_OP_DSV4_ROPE_TAIL:
22302255
{
22312256
n_tasks = n_threads;
22322257
} break;
@@ -2847,6 +2872,7 @@ struct ggml_cplan ggml_graph_plan(
28472872
case GGML_OP_SOFT_MAX:
28482873
case GGML_OP_ROPE:
28492874
case GGML_OP_ROPE_BACK:
2875+
case GGML_OP_DSV4_ROPE_TAIL:
28502876
{
28512877
cur = ggml_type_size(GGML_TYPE_F32) * node->ne[0] * n_tasks;
28522878
} break;

0 commit comments

Comments
 (0)