@@ -416,13 +416,21 @@ static ggml_tensor * rms_norm_mul(ggml_context * ctx, ggml_tensor * x,
416416 return ggml_mul (ctx, n, weight);
417417}
418418
419+ // NVFP4 scale2: if weight has a per-tensor scale, multiply the matmul result
420+ // by that scale. No-op when scale==1.0f (non-NVFP4 models).
421+ static ggml_tensor * apply_scale2 (ggml_context * ctx, ggml_tensor * mm_result,
422+ float scale) {
423+ if (scale == 1 .0f ) return mm_result;
424+ return ggml_scale (ctx, mm_result, scale);
425+ }
426+
419427static ggml_tensor * build_swiglu_ffn (ggml_context * ctx, ggml_tensor * cur,
420428 const TargetLayer & L) {
421- ggml_tensor * gate = ggml_mul_mat (ctx, L.w_gate , cur); // [inter, n_tokens]
429+ ggml_tensor * gate = apply_scale2 (ctx, ggml_mul_mat (ctx, L.w_gate , cur), L. w_gate_s ); // [inter, n_tokens]
422430 gate = ggml_silu (ctx, gate);
423- ggml_tensor * up = ggml_mul_mat (ctx, L.w_up , cur);
431+ ggml_tensor * up = apply_scale2 (ctx, ggml_mul_mat (ctx, L.w_up , cur), L. w_up_s );
424432 ggml_tensor * gu = ggml_mul (ctx, gate, up);
425- return ggml_mul_mat (ctx, L.w_down , gu); // [hidden, n_tokens]
433+ return apply_scale2 (ctx, ggml_mul_mat (ctx, L.w_down , gu), L. w_down_s ); // [hidden, n_tokens]
426434}
427435
428436// Full-attention block (matches llama.cpp's build_layer_attn for qwen35)
@@ -456,7 +464,7 @@ static ggml_tensor * build_full_attn_block(
456464 const int n_head_kv = w.n_head_kv ;
457465 const int q_dim = head_dim * n_head;
458466 // ── Q projection (packed Q || gate), shape [2*q_dim, n_tokens]
459- ggml_tensor * QG = ggml_mul_mat (ctx, L.wq , cur);
467+ ggml_tensor * QG = apply_scale2 (ctx, ggml_mul_mat (ctx, L.wq , cur), L. wq_s );
460468 // Reshape to [head_dim*2, n_head, n_tokens] so we can view the Q and gate halves
461469 QG = ggml_reshape_3d (ctx, QG , head_dim * 2 , n_head, n_tokens);
462470
@@ -478,8 +486,8 @@ static ggml_tensor * build_full_attn_block(
478486 gate = ggml_cont_2d (ctx, gate, q_dim, n_tokens); // [q_dim, n_tokens]
479487
480488 // ── K and V projections
481- ggml_tensor * Kcur = ggml_mul_mat (ctx, L.wk , cur); // [kv_dim, n_tokens]
482- ggml_tensor * Vcur = ggml_mul_mat (ctx, L.wv , cur); // [kv_dim, n_tokens]
489+ ggml_tensor * Kcur = apply_scale2 (ctx, ggml_mul_mat (ctx, L.wk , cur), L. wk_s );
490+ ggml_tensor * Vcur = apply_scale2 (ctx, ggml_mul_mat (ctx, L.wv , cur), L. wv_s );
483491
484492 Kcur = ggml_reshape_3d (ctx, Kcur, head_dim, n_head_kv, n_tokens);
485493 Kcur = rms_norm_mul (ctx, Kcur, L.k_norm , w.rms_eps );
@@ -610,7 +618,7 @@ static ggml_tensor * build_full_attn_block(
610618 attn = ggml_mul (ctx, attn, gate_sig);
611619
612620 // ── Output projection
613- attn = ggml_mul_mat (ctx, L.wo , attn); // [hidden, n_tokens]
621+ attn = apply_scale2 (ctx, ggml_mul_mat (ctx, L.wo , attn), L. wo_s );
614622 return attn;
615623}
616624
@@ -645,22 +653,22 @@ static ggml_tensor * build_delta_net_block(
645653 const int n_seq_tokens = n_tokens;
646654
647655 // ── qkv_mixed = wqkv @ cur [10240, n_tokens]
648- ggml_tensor * qkv_mixed = ggml_mul_mat (ctx, L.wqkv , cur);
656+ ggml_tensor * qkv_mixed = apply_scale2 (ctx, ggml_mul_mat (ctx, L.wqkv , cur), L. wqkv_s );
649657 qkv_mixed = ggml_reshape_3d (ctx, qkv_mixed, conv_channels, n_seq_tokens, n_seqs);
650658
651659 // ── z = wqkv_gate @ cur [inner, n_tokens]
652- ggml_tensor * z = ggml_mul_mat (ctx, L.wqkv_gate , cur);
660+ ggml_tensor * z = apply_scale2 (ctx, ggml_mul_mat (ctx, L.wqkv_gate , cur), L. wqkv_gate_s );
653661
654662 // ── beta = ssm_beta @ cur [dt_rank, n_tokens]
655- ggml_tensor * beta = ggml_mul_mat (ctx, L.ssm_beta , cur);
663+ ggml_tensor * beta = apply_scale2 (ctx, ggml_mul_mat (ctx, L.ssm_beta , cur), L. ssm_beta_s );
656664 beta = ggml_reshape_4d (ctx, beta, 1 , num_v_heads, n_seq_tokens, n_seqs);
657665 beta = ggml_sigmoid (ctx, beta);
658666
659667 // ── alpha = ssm_alpha @ cur [dt_rank, n_tokens]
660668 // alpha = alpha + ssm_dt_bias (per-head bias)
661669 // alpha = softplus(alpha)
662670 // g = alpha * ssm_a (-A_log.exp() * softplus)
663- ggml_tensor * alpha = ggml_mul_mat (ctx, L.ssm_alpha , cur);
671+ ggml_tensor * alpha = apply_scale2 (ctx, ggml_mul_mat (ctx, L.ssm_alpha , cur), L. ssm_alpha_s );
664672 alpha = ggml_reshape_3d (ctx, alpha, num_v_heads, n_seq_tokens, n_seqs);
665673 alpha = ggml_add (ctx, alpha, L.ssm_dt_bias );
666674 alpha = ggml_softplus (ctx, alpha);
@@ -885,7 +893,7 @@ static ggml_tensor * build_delta_net_block(
885893 head_v_dim * num_v_heads, n_seq_tokens, n_seqs);
886894
887895 // Output projection
888- ggml_tensor * out = ggml_mul_mat (ctx, L.ssm_out , flat);
896+ ggml_tensor * out = apply_scale2 (ctx, ggml_mul_mat (ctx, L.ssm_out , flat), L. ssm_out_s );
889897 out = ggml_reshape_2d (ctx, out, w.n_embd , n_seq_tokens * n_seqs);
890898 return out;
891899}
@@ -1462,4 +1470,5 @@ bool restore_target_cache_chain(const PrefixSnapshot * thick,
14621470 return true ;
14631471}
14641472
1473+
14651474} // namespace dflash27b
0 commit comments