char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

Charlotte Somsupport aliceai_t5_moe98a01afd9

char/aliceai-t5-moe
136.1 KiB3914 linesraw
1#include "llama-graph.h"
2
3#include "llama-impl.h"
4#include "llama-model.h"
5#include "llama-batch.h"
6#include "llama-cparams.h"
7#include "llama-sampler.h"
8
9#include "llama-kv-cache.h"
10#include "llama-kv-cache-iswa.h"
11#include "llama-kv-cache-dsa.h"
12#include "llama-kv-cache-dsa-iswa.h"
13#include "llama-kv-cache-msa.h"
14#include "llama-kv-cache-dsv4.h"
15#include "llama-memory-hybrid.h"
16#include "llama-memory-hybrid-iswa.h"
17#include "llama-memory-recurrent.h"
18
19#include <cassert>
20#include <cmath>
21#include <cstring>
22#include <numeric>
23#include <sstream>
24#include <string>
25#include <unordered_set>
26
27// dedup helpers
28
29static ggml_tensor * build_attn_inp_kq_mask(
30        ggml_context * ctx,
31        const llama_kv_cache_context * mctx,
32        const llama_ubatch & ubatch,
33        const llama_cparams & cparams) {
34    const auto n_kv     = mctx->get_n_kv();
35    const auto n_tokens = ubatch.n_tokens;
36    const auto n_stream = cparams.kv_unified ? 1 : ubatch.n_seqs_unq;
37
38    // flash attention requires an f16 mask
39    const auto type = cparams.flash_attn ? GGML_TYPE_F16 : GGML_TYPE_F32;
40
41    ggml_tensor * res = ggml_new_tensor_4d(ctx, type, n_kv, n_tokens/n_stream, 1, n_stream);
42    ggml_set_input(res);
43    ggml_set_name(res, "attn_inp_kq_mask");
44
45    return res;
46}
47
48static bool can_reuse_kq_mask(
49        ggml_tensor * kq_mask,
50        const llama_kv_cache_context * mctx,
51        const llama_ubatch & ubatch,
52        const llama_cparams & cparams) {
53    const auto n_kv     = mctx->get_n_kv();
54    const auto n_tokens = ubatch.n_tokens;
55    const auto n_stream = cparams.kv_unified ? 1 : ubatch.n_seqs_unq;
56
57    bool res = true;
58
59    res &= (kq_mask->ne[0] == n_kv);
60    res &= (kq_mask->ne[1] == n_tokens/n_stream);
61    res &= (kq_mask->ne[2] == 1);
62    res &= (kq_mask->ne[3] == n_stream);
63
64    return res;
65}
66
67// impl
68
69void llm_graph_input_embd::set_input(const llama_ubatch * ubatch) {
70    if (ubatch->token) {
71        const int64_t n_tokens = ubatch->n_tokens;
72
73        ggml_backend_tensor_set(tokens, ubatch->token, 0, n_tokens*ggml_element_size(tokens));
74    }
75
76    if (ubatch->embd) {
77        GGML_ASSERT(n_embd == embd->ne[0]);
78
79        const int64_t n_tokens = ubatch->n_tokens;
80
81        ggml_backend_tensor_set(embd, ubatch->embd, 0, n_tokens*n_embd*ggml_element_size(embd));
82    }
83}
84
85bool llm_graph_input_embd::can_reuse(const llm_graph_params & params) {
86    bool res = true;
87
88    res &= (!params.ubatch.token) || (tokens && tokens->ne[0] == params.ubatch.n_tokens);
89    res &= (!params.ubatch.embd)  || (embd   &&   embd->ne[1] == params.ubatch.n_tokens);
90
91    return res;
92}
93
94void llm_graph_input_embd_h::set_input(const llama_ubatch * ubatch) {
95    const int64_t n_tokens = ubatch->n_tokens;
96
97    if (ubatch->token) {
98        ggml_backend_tensor_set(tokens, ubatch->token, 0, n_tokens*ggml_element_size(tokens));
99    } else {
100        // note: mtmd embedding input goes through here
101        GGML_ASSERT(ubatch->embd);
102        GGML_ASSERT(n_embd == embd->ne[0]);
103
104        ggml_backend_tensor_set(embd, ubatch->embd, 0, n_tokens*n_embd*ggml_element_size(h));
105    }
106
107    // TODO: extend llama_ubatch to differentiate between token embeddings and hidden states
108    //       for now, we assume that the hidden state is always provided as an embedding
109    //       ref: https://github.com/ggml-org/llama.cpp/pull/23643
110    if (ubatch->embd) {
111        GGML_ASSERT(n_embd == h->ne[0]);
112
113        ggml_backend_tensor_set(h, ubatch->embd, 0, n_tokens*n_embd*ggml_element_size(h));
114    }
115}
116
117bool llm_graph_input_embd_h::can_reuse(const llm_graph_params & params) {
118    bool res = true;
119
120    res &= (!params.ubatch.token) || (tokens && tokens->ne[0] == params.ubatch.n_tokens);
121    res &= (!params.ubatch.embd)  || (embd   && embd->ne[1]   == params.ubatch.n_tokens);
122    res &= (!params.ubatch.embd)  || (h      && h->ne[1]      == params.ubatch.n_tokens);
123
124    return res;
125}
126
127void llm_graph_input_pos::set_input(const llama_ubatch * ubatch) {
128    if (ubatch->pos && pos) {
129        const int64_t n_tokens = ubatch->n_tokens;
130
131        if (ubatch->token && n_pos_per_embd == 4) {
132            // in case we're using M-RoPE with text tokens, convert the 1D positions to 4D
133            // the 3 first dims are the same, and 4th dim is all 0
134            std::vector<llama_pos> pos_data(n_tokens*n_pos_per_embd);
135            // copy the first dimension
136            for (int i = 0; i < n_tokens; ++i) {
137                pos_data[               i] = ubatch->pos[i];
138                pos_data[    n_tokens + i] = ubatch->pos[i];
139                pos_data[2 * n_tokens + i] = ubatch->pos[i];
140                pos_data[3 * n_tokens + i] = 0; // 4th dim is 0
141            }
142            ggml_backend_tensor_set(pos, pos_data.data(), 0, pos_data.size()*ggml_element_size(pos));
143        } else {
144            ggml_backend_tensor_set(pos, ubatch->pos, 0, n_tokens*n_pos_per_embd*ggml_element_size(pos));
145        }
146    }
147}
148
149bool llm_graph_input_pos::can_reuse(const llm_graph_params & params) {
150    bool res = true;
151
152    res &= pos->ne[0] == params.ubatch.n_tokens*n_pos_per_embd;
153
154    return res;
155}
156
157void llm_graph_input_attn_temp::set_input(const llama_ubatch * ubatch) {
158    if (ubatch->pos && attn_scale) {
159        const int64_t n_tokens = ubatch->n_tokens;
160
161        GGML_ASSERT(f_attn_temp_scale != 0.0f);
162        GGML_ASSERT(n_attn_temp_floor_scale != 0);
163
164        std::vector<float> attn_scale_data(n_tokens, 0.0f);
165        for (int i = 0; i < n_tokens; ++i) {
166            const float pos = ubatch->pos[i];
167            attn_scale_data[i] = std::log(
168                std::floor((pos + f_attn_temp_offset) / n_attn_temp_floor_scale) + 1.0
169            ) * f_attn_temp_scale + 1.0;
170        }
171
172        ggml_backend_tensor_set(attn_scale, attn_scale_data.data(), 0, n_tokens*ggml_element_size(attn_scale));
173    }
174}
175
176void llm_graph_input_pos_bucket::set_input(const llama_ubatch * ubatch) {
177    if (pos_bucket) {
178        const int64_t n_tokens = ubatch->n_tokens;
179
180        GGML_ASSERT(ggml_backend_buffer_is_host(pos_bucket->buffer));
181        GGML_ASSERT(!ubatch->equal_seqs()); // TODO: use ubatch->n_seqs instead of failing
182
183        int32_t * data = (int32_t *) pos_bucket->data;
184
185        for (int j = 0; j < n_tokens; ++j) {
186            for (int i = 0; i < n_tokens; ++i) {
187                data[j*n_tokens + i] = llama_relative_position_bucket(ubatch->pos[i], ubatch->pos[j], hparams.n_rel_attn_bkts, true);
188            }
189        }
190    }
191}
192
193void llm_graph_input_pos_bucket_kv::set_input(const llama_ubatch * ubatch) {
194    if (pos_bucket) {
195        mctx->set_input_pos_bucket(pos_bucket, ubatch);
196    }
197}
198
199void llm_graph_input_out_ids::set_input(const llama_ubatch * ubatch) {
200    GGML_ASSERT(out_ids);
201
202    const int64_t n_tokens = ubatch->n_tokens;
203
204    GGML_ASSERT(ggml_backend_buffer_is_host(out_ids->buffer));
205    int32_t * data = (int32_t *) out_ids->data;
206
207    if (n_outputs == n_tokens) {
208        for (int i = 0; i < n_tokens; ++i) {
209            data[i] = i;
210        }
211
212        return;
213    }
214
215    GGML_ASSERT(ubatch->output);
216
217    int n_outputs = 0;
218
219    for (int i = 0; i < n_tokens; ++i) {
220        if (ubatch->output[i]) {
221            data[n_outputs++] = i;
222        }
223    }
224}
225
226bool llm_graph_input_out_ids::can_reuse(const llm_graph_params & params) {
227    bool res = true;
228
229    res &= n_outputs == params.n_outputs;
230
231    return res;
232}
233
234void llm_graph_input_mean::set_input(const llama_ubatch * ubatch) {
235    if (cparams.embeddings   &&
236       (cparams.pooling_type == LLAMA_POOLING_TYPE_MEAN ||
237        cparams.pooling_type == LLAMA_POOLING_TYPE_RANK )) {
238
239        const int64_t n_tokens     = ubatch->n_tokens;
240        const int64_t n_seq_tokens = ubatch->n_seq_tokens;
241        const int64_t n_seqs_unq   = ubatch->n_seqs_unq;
242
243        GGML_ASSERT(mean);
244        GGML_ASSERT(ggml_backend_buffer_is_host(mean->buffer));
245
246        float * data = (float *) mean->data;
247        memset(mean->data, 0, n_tokens*n_seqs_unq*ggml_element_size(mean));
248
249        std::vector<uint64_t> sums(n_seqs_unq, 0);
250        for (int i = 0; i < n_tokens; i += n_seq_tokens) {
251            for (int s = 0; s < ubatch->n_seq_id[i]; ++s) {
252                const llama_seq_id seq_id  = ubatch->seq_id[i][s];
253                const int32_t      seq_idx = ubatch->seq_idx[seq_id];
254
255                sums[seq_idx] += ubatch->n_seq_tokens;
256            }
257        }
258
259        std::vector<float> div(n_seqs_unq, 0.0f);
260        for (int s = 0; s < n_seqs_unq; ++s) {
261            const uint64_t sum = sums[s];
262            if (sum > 0) {
263                div[s] = 1.0f/float(sum);
264            }
265        }
266
267        for (int i = 0; i < n_tokens; i += n_seq_tokens) {
268            for (int s = 0; s < ubatch->n_seq_id[i]; ++s) {
269                const llama_seq_id seq_id  = ubatch->seq_id[i][s];
270                const int32_t      seq_idx = ubatch->seq_idx[seq_id];
271
272                for (int j = 0; j < n_seq_tokens; ++j) {
273                    data[seq_idx*n_tokens + i + j] = div[seq_idx];
274                }
275            }
276        }
277    }
278}
279
280void llm_graph_input_cls::set_input(const llama_ubatch * ubatch) {
281    const int64_t n_tokens     = ubatch->n_tokens;
282    const int64_t n_seqs_unq   = ubatch->n_seqs_unq;
283
284    if (cparams.embeddings && (
285        cparams.pooling_type == LLAMA_POOLING_TYPE_CLS  ||
286        cparams.pooling_type == LLAMA_POOLING_TYPE_RANK ||
287        cparams.pooling_type == LLAMA_POOLING_TYPE_LAST
288    )) {
289        GGML_ASSERT(cls);
290        GGML_ASSERT(ggml_backend_buffer_is_host(cls->buffer));
291
292        uint32_t * data = (uint32_t *) cls->data;
293        memset(cls->data, 0, n_seqs_unq*ggml_element_size(cls));
294
295        std::vector<int> target_pos(n_seqs_unq, -1);
296        std::vector<int> target_row(n_seqs_unq, -1);
297
298        const bool last = (
299             cparams.pooling_type == LLAMA_POOLING_TYPE_LAST ||
300            (cparams.pooling_type == LLAMA_POOLING_TYPE_RANK && (arch == LLM_ARCH_QWEN3 || arch == LLM_ARCH_QWEN3VL)) // qwen3 reranking & embedding models use last token
301        );
302
303        for (int i = 0; i < n_tokens; ++i) {
304            const llama_pos pos = ubatch->pos[i];
305
306            for (int s = 0; s < ubatch->n_seq_id[i]; ++s) {
307                const llama_seq_id seq_id  = ubatch->seq_id[i][s];
308                const int32_t      seq_idx = ubatch->seq_idx[seq_id];
309
310                if (
311                    (target_pos[seq_idx] == -1) ||
312                    ( last && pos >= target_pos[seq_idx]) ||
313                    (!last && pos <  target_pos[seq_idx])
314                ) {
315                    target_pos[seq_idx] = pos;
316                    target_row[seq_idx] = i;
317                }
318            }
319        }
320
321        for (int s = 0; s < n_seqs_unq; ++s) {
322            if (target_row[s] >= 0) {
323                data[s] = target_row[s];
324            }
325        }
326    }
327}
328
329void llm_graph_input_rs::set_input(const llama_ubatch * ubatch) {
330    GGML_UNUSED(ubatch);
331
332    const int64_t n_rs = mctx->get_n_rs();
333
334    if (s_copy) {
335        GGML_ASSERT(ggml_backend_buffer_is_host(s_copy->buffer));
336        int32_t * data = (int32_t *) s_copy->data;
337
338        // assuming copy destinations ALWAYS happen ONLY on the cells between head and head+n
339        for (uint32_t i = 0; i < n_rs; ++i) {
340            data[i] = mctx->s_copy(i);
341        }
342    }
343}
344
345bool llm_graph_input_rs::can_reuse(const llm_graph_params & params) {
346    const auto * mctx = static_cast<const llama_memory_recurrent_context *>(params.mctx);
347
348    this->mctx = mctx;
349
350    bool res = true;
351
352    res &= s_copy->ne[0] == mctx->get_n_rs();
353
354    res &= s_copy_main->ne[0]  == params.ubatch.n_seqs;
355    res &= s_copy_extra->ne[0] == mctx->get_n_rs() - params.ubatch.n_seqs;
356
357    res &= head == mctx->get_head();
358    res &= rs_z == mctx->get_rs_z();
359
360    return res;
361}
362
363void llm_graph_input_cross_embd::set_input(const llama_ubatch * ubatch) {
364    GGML_UNUSED(ubatch);
365
366    if (cross_embd && !cross->v_embd.empty()) {
367        assert(cross_embd->type == GGML_TYPE_F32);
368
369        ggml_backend_tensor_set(cross_embd, cross->v_embd.data(), 0, ggml_nbytes(cross_embd));
370    }
371}
372
373bool llm_graph_input_cross_embd::can_reuse(const llm_graph_params & params) {
374    return cross && cross == params.cross && !cross->v_embd.empty() &&
375        cross_embd->ne[0] == cross->n_embd && cross_embd->ne[1] == cross->n_enc;
376}
377
378template <typename T>
379static void print_mask(const T * data, int64_t n_tokens, int64_t n_kv, int64_t n_swa, llama_swa_type swa_type) {
380    LLAMA_LOG_DEBUG("%s: === Attention mask ===\n", __func__);
381    const char * swa_type_str = "unknown";
382
383    switch (swa_type) {
384        case LLAMA_SWA_TYPE_NONE:      swa_type_str = "LLAMA_SWA_TYPE_NONE"; break;
385        case LLAMA_SWA_TYPE_STANDARD:  swa_type_str = "LLAMA_SWA_TYPE_STANDARD"; break;
386        case LLAMA_SWA_TYPE_CHUNKED:   swa_type_str = "LLAMA_SWA_TYPE_CHUNKED"; break;
387        case LLAMA_SWA_TYPE_SYMMETRIC: swa_type_str = "LLAMA_SWA_TYPE_SYMMETRIC"; break;
388    };
389
390    LLAMA_LOG_DEBUG("%s: n_swa : %d, n_kv: %d, swa_type: %s\n", __func__, (int)n_swa, (int)n_kv, swa_type_str);
391    LLAMA_LOG_DEBUG("%s: '0' = can attend, '∞' = masked\n", __func__);
392    LLAMA_LOG_DEBUG("%s: Rows = query tokens, Columns = key/value tokens\n\n", __func__);
393
394    LLAMA_LOG_DEBUG("    ");
395    for (int j = 0; j < std::min((int64_t)20, n_kv); ++j) {
396        LLAMA_LOG_DEBUG("%2d", j);
397    }
398    LLAMA_LOG_DEBUG("\n");
399
400    for (int i = 0; i < std::min((int64_t)20, n_tokens); ++i) {
401        LLAMA_LOG_DEBUG(" %2d ", i);
402        for (int j = 0; j < std::min((int64_t)20, n_kv); ++j) {
403            float val = llama_cast<float>(data[i * n_kv + j]);
404            if (val == -INFINITY) {
405                LLAMA_LOG_DEBUG(" ∞");
406            } else {
407                LLAMA_LOG_DEBUG(" 0");
408            }
409        }
410        LLAMA_LOG_DEBUG("\n");
411    }
412}
413
414void llm_graph_input_attn_no_cache::set_input(const llama_ubatch * ubatch) {
415    const int64_t n_kv     = ubatch->n_tokens;
416    const int64_t n_tokens = ubatch->n_tokens;
417
418    const auto fill_mask = [&](auto * data, int64_t ne, int n_swa, llama_swa_type swa_type) {
419        using T = std::remove_reference_t<decltype(*data)>;
420        std::fill(data, data + ne, llama_cast<T>(-INFINITY));
421
422        for (int i1 = 0; i1 < n_tokens; ++i1) {
423            const llama_seq_id s1 = ubatch->seq_id[i1][0];
424            const llama_pos    p1 = ubatch->pos[i1];
425
426            const uint64_t idst = i1*n_kv;
427
428            for (int i0 = 0; i0 < n_tokens; ++i0) {
429                const llama_seq_id s0 = ubatch->seq_id[i0][0];
430                const llama_pos p0    = ubatch->pos[i0];
431
432                // mask different sequences
433                if (s0 != s1) {
434                    continue;
435                }
436
437                // mask future tokens
438                if (cparams.causal_attn && p0 > p1) {
439                    continue;
440                }
441
442                // apply SWA if any
443                if (llama_hparams::is_masked_swa(n_swa, swa_type, p0, p1)) {
444                    continue;
445                }
446
447                data[idst + i0] = llama_cast<T>(hparams.use_alibi ? -std::abs(p0 - p1) : 0.0f);
448            }
449        }
450
451        if (debug) {
452            print_mask(data, n_tokens, n_kv, n_swa, swa_type);
453        }
454    };
455
456    GGML_ASSERT(self_kq_mask);
457    GGML_ASSERT(ggml_backend_buffer_is_host(self_kq_mask->buffer));
458    if (self_kq_mask->type == GGML_TYPE_F16) {
459        fill_mask((ggml_fp16_t *) self_kq_mask->data, ggml_nelements(self_kq_mask), 0, LLAMA_SWA_TYPE_NONE);
460    } else {
461        fill_mask((float       *) self_kq_mask->data, ggml_nelements(self_kq_mask), 0, LLAMA_SWA_TYPE_NONE);
462    }
463
464    if (hparams.swa_type != LLAMA_SWA_TYPE_NONE) {
465        GGML_ASSERT(self_kq_mask_swa);
466        GGML_ASSERT(ggml_backend_buffer_is_host(self_kq_mask_swa->buffer));
467        if (self_kq_mask_swa->type == GGML_TYPE_F16) {
468            fill_mask((ggml_fp16_t *) self_kq_mask_swa->data, ggml_nelements(self_kq_mask_swa), hparams.n_swa, hparams.swa_type);
469        } else {
470            fill_mask((float       *) self_kq_mask_swa->data, ggml_nelements(self_kq_mask_swa), hparams.n_swa, hparams.swa_type);
471        }
472    }
473}
474
475void llm_graph_input_attn_kv::set_input(const llama_ubatch * ubatch) {
476    mctx->set_input_k_idxs(self_k_idxs, ubatch);
477    mctx->set_input_v_idxs(self_v_idxs, ubatch);
478
479    // the mask is left unallocated when the graph only stores K/V without attending
480    // (e.g. DFlash's KV-injection pass)
481    if (self_kq_mask && self_kq_mask->buffer) {
482        mctx->set_input_kq_mask(self_kq_mask, ubatch, cparams.causal_attn);
483    }
484
485    if (self_k_rot && self_k_rot->buffer) {
486        mctx->set_input_k_rot(self_k_rot);
487    }
488
489    if (self_v_rot && self_v_rot->buffer) {
490        mctx->set_input_v_rot(self_v_rot);
491    }
492}
493
494bool llm_graph_input_attn_kv::can_reuse(const llm_graph_params & params) {
495    const auto * mctx = static_cast<const llama_kv_cache_context *>(params.mctx);
496
497    this->mctx = mctx;
498
499    bool res = true;
500
501    res &= self_k_idxs->ne[0] == params.ubatch.n_tokens;
502  //res &= self_v_idxs->ne[0] == params.ubatch.n_tokens; // TODO: need to move this to the unified cache and check there
503
504    res &= can_reuse_kq_mask(self_kq_mask, mctx, params.ubatch, params.cparams);
505
506    return res;
507}
508
509void llm_graph_input_attn_k::set_input(const llama_ubatch * ubatch) {
510    mctx->set_input_k_idxs(self_k_idxs, ubatch);
511
512    mctx->set_input_kq_mask(self_kq_mask, ubatch, cparams.causal_attn);
513}
514
515bool llm_graph_input_attn_k::can_reuse(const llm_graph_params & params) {
516    mctx = static_cast<const llama_kv_cache_context *>(params.mctx);
517
518    return can_reuse_impl(params);
519}
520
521bool llm_graph_input_attn_k::can_reuse_impl(const llm_graph_params & params) {
522    bool res = true;
523
524    res &= self_k_idxs->ne[0] == params.ubatch.n_tokens;
525
526    res &= can_reuse_kq_mask(self_kq_mask, mctx, params.ubatch, params.cparams);
527
528    return res;
529}
530
531llm_graph_input_attn_kv_msa::llm_graph_input_attn_kv_msa(
532        const llama_hparams & hparams,
533        const llama_cparams & cparams,
534        const llama_kv_cache_msa_context * mctx) :
535    llm_graph_input_attn_kv(hparams, cparams, mctx->get_base()),
536    mctx_msa(mctx) {
537}
538
539void llm_graph_input_attn_kv_msa::set_input(const llama_ubatch * ubatch) {
540    llm_graph_input_attn_kv::set_input(ubatch);
541
542    if (self_k_idxs_idx) {
543        mctx_msa->get_idx()->set_input_k_idxs(self_k_idxs_idx, ubatch);
544    }
545}
546
547bool llm_graph_input_attn_kv_msa::can_reuse(const llm_graph_params & params) {
548    mctx_msa = static_cast<const llama_kv_cache_msa_context *>(params.mctx);
549
550    // the parent class operates on the base cache context
551    this->mctx = mctx_msa->get_base();
552
553    bool res = true;
554
555    res &= self_k_idxs->ne[0] == params.ubatch.n_tokens;
556    if (self_k_idxs_idx) {
557        res &= self_k_idxs_idx->ne[0] == params.ubatch.n_tokens;
558    }
559
560    res &= can_reuse_kq_mask(self_kq_mask, this->mctx, params.ubatch, params.cparams);
561
562    return res;
563}
564
565void llm_graph_input_attn_k_dsa::set_input(const llama_ubatch * ubatch) {
566    mctx->get_mla()->set_input_k_idxs(self_k_idxs_mla, ubatch);
567
568    mctx->get_mla()->set_input_kq_mask(self_kq_mask_mla, ubatch, cparams.causal_attn);
569
570    mctx->get_lid()->set_input_k_idxs(self_k_idxs_lid, ubatch);
571
572    mctx->get_lid()->set_input_kq_mask(self_kq_mask_lid, ubatch, cparams.causal_attn);
573
574    // left unallocated when the indexer does not use the rotation
575    if (self_k_rot_lid && self_k_rot_lid->buffer) {
576        mctx->get_lid()->set_input_k_rot(self_k_rot_lid);
577    }
578}
579
580bool llm_graph_input_attn_k_dsa::can_reuse(const llm_graph_params & params) {
581    mctx = static_cast<const llama_kv_cache_dsa_context *>(params.mctx);
582
583    return can_reuse_impl(params);
584}
585
586bool llm_graph_input_attn_k_dsa::can_reuse_impl(const llm_graph_params & params) {
587    bool res = true;
588
589    res &= self_k_idxs_mla->ne[0] == params.ubatch.n_tokens;
590    res &= self_k_idxs_lid->ne[0] == params.ubatch.n_tokens;
591
592    res &= can_reuse_kq_mask(self_kq_mask_mla, mctx->get_mla(), params.ubatch, params.cparams);
593    res &= can_reuse_kq_mask(self_kq_mask_lid, mctx->get_lid(), params.ubatch, params.cparams);
594
595    return res;
596}
597
598void llm_graph_input_attn_k_dsa_iswa::set_input(const llama_ubatch * ubatch) {
599    inp_dsa->set_input(ubatch);
600    inp_swa->set_input(ubatch);
601}
602
603bool llm_graph_input_attn_k_dsa_iswa::can_reuse(const llm_graph_params & params) {
604    mctx = static_cast<const llama_kv_cache_dsa_iswa_context *>(params.mctx);
605
606    inp_dsa->mctx = mctx->get_dsa();
607    inp_swa->mctx = mctx->get_swa();
608
609    bool res = true;
610
611    res &= inp_dsa->can_reuse_impl(params);
612    res &= inp_swa->can_reuse_impl(params);
613
614    return res;
615}
616
617void llm_graph_input_attn_kv_iswa::set_input(const llama_ubatch * ubatch) {
618    // base tensors may not be allocated if there are no non-SWA attention layers
619    if (self_k_idxs && self_k_idxs->buffer) {
620        mctx->get_base()->set_input_k_idxs(self_k_idxs, ubatch);
621        if (self_v_idxs) {
622            mctx->get_base()->set_input_v_idxs(self_v_idxs, ubatch);
623        }
624    }
625
626    // the kq mask guards on its own buffer: shared cells leave idxs unbacked while the mask stays live
627    if (self_kq_mask && self_kq_mask->buffer) {
628        mctx->get_base()->set_input_kq_mask(self_kq_mask, ubatch, cparams.causal_attn);
629    }
630
631    // swa tensors may not be allocated if there are no SWA attention layers
632    if (self_k_idxs_swa && self_k_idxs_swa->buffer) {
633        mctx->get_swa()->set_input_k_idxs(self_k_idxs_swa, ubatch);
634        if (self_v_idxs_swa) {
635            mctx->get_swa()->set_input_v_idxs(self_v_idxs_swa, ubatch);
636        }
637    }
638
639    if (self_kq_mask_swa && self_kq_mask_swa->buffer) {
640        mctx->get_swa()->set_input_kq_mask(self_kq_mask_swa, ubatch, cparams.causal_attn);
641    }
642
643    if (self_k_rot && self_k_rot->buffer) {
644        mctx->get_base()->set_input_k_rot(self_k_rot);
645    }
646
647    if (self_v_rot && self_v_rot->buffer) {
648        mctx->get_base()->set_input_v_rot(self_v_rot);
649    }
650
651    if (self_k_rot_swa && self_k_rot_swa->buffer) {
652        mctx->get_swa()->set_input_k_rot(self_k_rot_swa);
653    }
654
655    if (self_v_rot_swa && self_v_rot_swa->buffer) {
656        mctx->get_swa()->set_input_v_rot(self_v_rot_swa);
657    }
658}
659
660bool llm_graph_input_attn_kv_iswa::can_reuse(const llm_graph_params & params) {
661    const auto * mctx = static_cast<const llama_kv_cache_iswa_context *>(params.mctx);
662
663    this->mctx = mctx;
664
665    bool res = true;
666
667    // base tensors may not be allocated if there are no non-SWA attention layers
668    if (self_k_idxs && self_k_idxs->buffer) {
669        res &= self_k_idxs->ne[0] == params.ubatch.n_tokens;
670      //res &= self_v_idxs->ne[0] == params.ubatch.n_tokens; // TODO: need to move this to the unified cache and check there
671    }
672
673    if (self_kq_mask && self_kq_mask->buffer) {
674        res &= can_reuse_kq_mask(self_kq_mask, mctx->get_base(), params.ubatch, params.cparams);
675    }
676
677    // swa tensors may not be allocated if there are no SWA attention layers
678    if (self_k_idxs_swa && self_k_idxs_swa->buffer) {
679        res &= self_k_idxs_swa->ne[0] == params.ubatch.n_tokens;
680      //res &= self_v_idxs_swa->ne[0] == params.ubatch.n_tokens; // TODO: need to move this to the unified cache and check there
681    }
682
683    if (self_kq_mask_swa && self_kq_mask_swa->buffer) {
684        res &= can_reuse_kq_mask(self_kq_mask_swa, mctx->get_swa(), params.ubatch, params.cparams);
685    }
686
687    return res;
688}
689
690void llm_graph_input_attn_k_iswa::set_input(const llama_ubatch * ubatch) {
691    // base tensors may not be allocated if there are no non-SWA attention layers
692    if (self_k_idxs && self_k_idxs->buffer) {
693        mctx->get_base()->set_input_k_idxs(self_k_idxs, ubatch);
694    }
695
696    // the kq mask guards on its own buffer: shared cells leave idxs unbacked while the mask stays live
697    if (self_kq_mask && self_kq_mask->buffer) {
698        mctx->get_base()->set_input_kq_mask(self_kq_mask, ubatch, cparams.causal_attn);
699    }
700
701    // swa tensors may not be allocated if there are no SWA attention layers
702    if (self_k_idxs_swa && self_k_idxs_swa->buffer) {
703        mctx->get_swa()->set_input_k_idxs(self_k_idxs_swa, ubatch);
704    }
705
706    if (self_kq_mask_swa && self_kq_mask_swa->buffer) {
707        mctx->get_swa()->set_input_kq_mask(self_kq_mask_swa, ubatch, cparams.causal_attn);
708    }
709
710    if (self_k_rot && self_k_rot->buffer) {
711        mctx->get_base()->set_input_k_rot(self_k_rot);
712    }
713
714    if (self_k_rot_swa && self_k_rot_swa->buffer) {
715        mctx->get_swa()->set_input_k_rot(self_k_rot_swa);
716    }
717}
718
719bool llm_graph_input_attn_k_iswa::can_reuse(const llm_graph_params & params) {
720    const auto * mctx = static_cast<const llama_kv_cache_iswa_context *>(params.mctx);
721
722    this->mctx = mctx;
723
724    bool res = true;
725
726    // base tensors may not be allocated if there are no non-SWA attention layers
727    if (self_k_idxs && self_k_idxs->buffer) {
728        res &= self_k_idxs->ne[0] == params.ubatch.n_tokens;
729    }
730
731    if (self_kq_mask && self_kq_mask->buffer) {
732        res &= can_reuse_kq_mask(self_kq_mask, mctx->get_base(), params.ubatch, params.cparams);
733    }
734
735    // swa tensors may not be allocated if there are no SWA attention layers
736    if (self_k_idxs_swa && self_k_idxs_swa->buffer) {
737        res &= self_k_idxs_swa->ne[0] == params.ubatch.n_tokens;
738    }
739
740    if (self_kq_mask_swa && self_kq_mask_swa->buffer) {
741        res &= can_reuse_kq_mask(self_kq_mask_swa, mctx->get_swa(), params.ubatch, params.cparams);
742    }
743
744    return res;
745}
746
747static void dsv4_set_i64(ggml_tensor * dst, const std::vector<int64_t> & src) {
748    if (!dst || !dst->buffer) {
749        return;
750    }
751
752    GGML_ASSERT(dst->ne[0] == (int64_t) src.size());
753    ggml_backend_tensor_set(dst, src.data(), 0, src.size()*ggml_element_size(dst));
754}
755
756static void dsv4_set_i32(ggml_tensor * dst, const std::vector<int32_t> & src) {
757    if (!dst || !dst->buffer) {
758        return;
759    }
760
761    GGML_ASSERT(dst->ne[0] == (int64_t) src.size());
762    ggml_backend_tensor_set(dst, src.data(), 0, src.size()*ggml_element_size(dst));
763}
764
765static void dsv4_set_kq_mask(
766        ggml_tensor * dst,
767        const llama_kv_cache_dsv4_context::comp_plan & plan,
768        uint32_t n_tokens,
769        int64_t n_stream) {
770    if (!dst || !dst->buffer) {
771        return;
772    }
773
774    GGML_ASSERT(dst->type == GGML_TYPE_F32 || dst->type == GGML_TYPE_F16);
775    GGML_ASSERT(n_stream > 0);
776    GGML_ASSERT(n_tokens%n_stream == 0);
777    GGML_ASSERT(dst->ne[0] == plan.n_kv);
778    GGML_ASSERT(dst->ne[1] == (int64_t) n_tokens/n_stream);
779    GGML_ASSERT(dst->ne[2] == 1);
780    GGML_ASSERT(dst->ne[3] == n_stream);
781    GGML_ASSERT((int64_t) plan.n_visible.size() == (int64_t) n_tokens);
782    GGML_ASSERT(ggml_backend_buffer_is_host(dst->buffer));
783
784    if (dst->type == GGML_TYPE_F32) {
785        float * data = (float *) dst->data;
786
787        for (int64_t i = 0; i < (int64_t) n_tokens; ++i) {
788            const int32_t n_visible = plan.n_visible[i];
789
790            for (int64_t j = 0; j < dst->ne[0]; ++j) {
791                data[i*dst->ne[0] + j] = j < n_visible ? 0.0f : -INFINITY;
792            }
793        }
794    } else if (dst->type == GGML_TYPE_F16) {
795        ggml_fp16_t * data = (ggml_fp16_t *) dst->data;
796        const ggml_fp16_t fp16_ninf = llama_cast<ggml_fp16_t>(-INFINITY);
797        const ggml_fp16_t fp16_zero = llama_cast<ggml_fp16_t>(0.0f);
798
799        for (int64_t i = 0; i < (int64_t) n_tokens; ++i) {
800            const int32_t n_visible = plan.n_visible[i];
801
802            for (int64_t j = 0; j < dst->ne[0]; ++j) {
803                data[i*dst->ne[0] + j] = j < n_visible ? fp16_zero : fp16_ninf;
804            }
805        }
806    }
807}
808
809static ggml_tensor * dsv4_build_raw_kq_mask(
810        ggml_context * ctx,
811        const llama_kv_cache_dsv4_raw_context * mctx,
812        const llama_ubatch & ubatch,
813        const llama_cparams & cparams,
814        int64_t n_stream) {
815    const auto n_kv     = mctx->get_n_kv();
816    const auto n_tokens = ubatch.n_tokens;
817
818    GGML_ASSERT(n_stream > 0);
819    GGML_ASSERT(n_tokens%n_stream == 0);
820
821    const auto type = cparams.flash_attn ? GGML_TYPE_F16 : GGML_TYPE_F32;
822
823    ggml_tensor * res = ggml_new_tensor_4d(ctx, type, n_kv, n_tokens/n_stream, 1, n_stream);
824    ggml_set_input(res);
825    ggml_set_name(res, "attn_inp_kq_mask");
826
827    return res;
828}
829
830static bool dsv4_can_reuse_raw_kq_mask(
831        ggml_tensor * kq_mask,
832        const llama_kv_cache_dsv4_raw_context * mctx,
833        const llama_ubatch & ubatch,
834        int64_t n_stream) {
835    const auto n_kv     = mctx->get_n_kv();
836    const auto n_tokens = ubatch.n_tokens;
837
838    GGML_ASSERT(n_stream > 0);
839
840    bool res = true;
841
842    res &= (kq_mask->ne[0] == n_kv);
843    res &= (kq_mask->ne[1] == n_tokens/n_stream);
844    res &= (kq_mask->ne[2] == 1);
845    res &= (kq_mask->ne[3] == n_stream);
846
847    return res;
848}
849
850static std::string dsv4_plan_positions(const std::vector<int32_t> & values) {
851    std::ostringstream ss;
852    ss << "[";
853    for (size_t i = 0; i < values.size(); ++i) {
854        if (i > 0) {
855            ss << ", ";
856        }
857        ss << values[i];
858    }
859    ss << "]";
860    return ss.str();
861}
862
863static bool dsv4_compress_debug() {
864    static const bool debug = []() {
865        const char * env = getenv("LLAMA_DSV4_COMPRESS_DEBUG");
866        return env && atoi(env) > 0;
867    }();
868
869    return debug;
870}
871
872static void dsv4_set_comp_inputs(
873        const llm_graph_input_dsv4::comp_input & inp,
874        const llama_kv_cache_dsv4_context::comp_plan & plan,
875        const char * name,
876        bool debug,
877        uint32_t n_tokens,
878        int64_t n_stream) {
879    dsv4_set_i32(inp.state_pos, plan.state_pos);
880    dsv4_set_i32(inp.state_persist_src_idxs, plan.state_persist_src_idxs);
881    dsv4_set_i32(inp.state_persist_dst_idxs, plan.state_persist_dst_idxs);
882    dsv4_set_i32(inp.state_restore_src_idxs, plan.state_restore_src_idxs);
883    dsv4_set_i32(inp.state_restore_dst_idxs, plan.state_restore_dst_idxs);
884    dsv4_set_i32(inp.state_snapshot_src_idxs, plan.state_snapshot_src_idxs);
885    dsv4_set_i32(inp.state_snapshot_dst_idxs, plan.state_snapshot_dst_idxs);
886    dsv4_set_i32(inp.state_read_idxs, plan.state_read_idxs);
887    dsv4_set_i64(inp.state_write_idxs, plan.state_write_idxs);
888    dsv4_set_i32(inp.state_write_pos, plan.state_write_pos);
889    dsv4_set_kq_mask(inp.kq_mask, plan, n_tokens, n_stream);
890
891    if (debug || dsv4_compress_debug()) {
892        LLAMA_LOG_INFO("%s: %s n_tokens=%u, n_stream=%d, state_persist_dst=%s, state_write_pos=%s\n",
893                __func__, name, n_tokens, (int) n_stream,
894                dsv4_plan_positions(plan.state_persist_dst_idxs).c_str(),
895                dsv4_plan_positions(plan.state_write_pos).c_str());
896    }
897}
898
899static bool dsv4_can_reuse_tensor_1d(ggml_tensor * t, int64_t ne0) {
900    return (t == nullptr && ne0 == 0) || (t != nullptr && t->ne[0] == ne0);
901}
902
903static bool dsv4_can_reuse_kq_mask(
904        ggml_tensor * t,
905        const llama_kv_cache_dsv4_context::comp_plan & plan,
906        uint32_t n_tokens,
907        int64_t n_stream) {
908    if (plan.n_kv == 0) {
909        return t == nullptr;
910    }
911
912    GGML_ASSERT(n_stream > 0);
913
914    return t != nullptr &&
915           t->ne[0] == plan.n_kv &&
916           t->ne[1] == (int64_t) n_tokens/n_stream &&
917           t->ne[2] == 1 &&
918           t->ne[3] == n_stream;
919}
920
921static bool dsv4_can_reuse_comp_input(
922        const llm_graph_input_dsv4::comp_input & inp,
923        const llama_kv_cache_dsv4_context::comp_plan & plan,
924        uint32_t n_tokens,
925        int64_t n_stream) {
926    bool res = true;
927    res &= dsv4_can_reuse_tensor_1d(inp.state_pos, plan.state_pos.size());
928    res &= dsv4_can_reuse_tensor_1d(inp.state_persist_src_idxs, plan.state_persist_src_idxs.size());
929    res &= dsv4_can_reuse_tensor_1d(inp.state_persist_dst_idxs, plan.state_persist_dst_idxs.size());
930    res &= dsv4_can_reuse_tensor_1d(inp.state_restore_src_idxs, plan.state_restore_src_idxs.size());
931    res &= dsv4_can_reuse_tensor_1d(inp.state_restore_dst_idxs, plan.state_restore_dst_idxs.size());
932    res &= dsv4_can_reuse_tensor_1d(inp.state_snapshot_src_idxs, plan.state_snapshot_src_idxs.size());
933    res &= dsv4_can_reuse_tensor_1d(inp.state_snapshot_dst_idxs, plan.state_snapshot_dst_idxs.size());
934    res &= dsv4_can_reuse_tensor_1d(inp.state_read_idxs, plan.state_read_idxs.size());
935    res &= dsv4_can_reuse_tensor_1d(inp.state_write_idxs, plan.state_write_idxs.size());
936    res &= dsv4_can_reuse_tensor_1d(inp.state_write_pos, plan.state_write_pos.size());
937    res &= dsv4_can_reuse_kq_mask(inp.kq_mask, plan, n_tokens, n_stream);
938
939    return res;
940}
941
942static ggml_tensor * dsv4_build_input_1d(
943        ggml_context * ctx,
944        ggml_type type,
945        int64_t ne0,
946        const std::string & name) {
947    if (ne0 == 0) {
948        return nullptr;
949    }
950
951    ggml_tensor * res = ggml_new_tensor_1d(ctx, type, ne0);
952    ggml_set_input(res);
953    ggml_set_name(res, name.c_str());
954
955    return res;
956}
957
958static void dsv4_build_comp_inputs(
959        ggml_context * ctx,
960        llm_graph_input_dsv4::comp_input & inp,
961        const llama_kv_cache_dsv4_context::comp_plan & plan,
962        const char * name,
963        const llama_cparams & cparams,
964        int64_t n_stream) {
965    inp.state_pos = dsv4_build_input_1d(ctx, GGML_TYPE_I32, plan.state_pos.size(), std::string("dsv4_") + name + "_state_pos");
966    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");
967    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");
968    inp.state_restore_src_idxs = dsv4_build_input_1d(ctx, GGML_TYPE_I32, plan.state_restore_src_idxs.size(), std::string("dsv4_") + name + "_state_restore_src_idxs");
969    inp.state_restore_dst_idxs = dsv4_build_input_1d(ctx, GGML_TYPE_I32, plan.state_restore_dst_idxs.size(), std::string("dsv4_") + name + "_state_restore_dst_idxs");
970    inp.state_snapshot_src_idxs = dsv4_build_input_1d(ctx, GGML_TYPE_I32, plan.state_snapshot_src_idxs.size(), std::string("dsv4_") + name + "_state_snapshot_src_idxs");
971    inp.state_snapshot_dst_idxs = dsv4_build_input_1d(ctx, GGML_TYPE_I32, plan.state_snapshot_dst_idxs.size(), std::string("dsv4_") + name + "_state_snapshot_dst_idxs");
972    inp.state_read_idxs = dsv4_build_input_1d(ctx, GGML_TYPE_I32, plan.state_read_idxs.size(), std::string("dsv4_") + name + "_state_read_idxs");
973    inp.state_write_idxs = dsv4_build_input_1d(ctx, GGML_TYPE_I64, plan.state_write_idxs.size(), std::string("dsv4_") + name + "_state_write_idxs");
974    inp.state_write_pos = dsv4_build_input_1d(ctx, GGML_TYPE_I32, plan.state_write_pos.size(), std::string("dsv4_") + name + "_state_write_pos");
975
976    if (plan.n_kv > 0) {
977        const int64_t n_tokens = (int64_t) plan.n_visible.size();
978
979        GGML_ASSERT(n_stream > 0);
980        GGML_ASSERT(n_tokens%n_stream == 0);
981
982        inp.kq_mask = ggml_new_tensor_4d(ctx, (strcmp(name, "lid") != 0 && cparams.flash_attn) || (strcmp(name, "lid") == 0 && cparams.fused_lid) ? GGML_TYPE_F16 : GGML_TYPE_F32, plan.n_kv, n_tokens/n_stream, 1, n_stream);
983        ggml_set_input(inp.kq_mask);
984        ggml_set_name(inp.kq_mask, (std::string("dsv4_") + name + "_kq_mask").c_str());
985    }
986}
987
988void llm_graph_input_dsv4_raw::set_input(const llama_ubatch * ubatch) {
989    if (self_k_idxs && self_k_idxs->buffer) {
990        mctx->set_input_k_idxs(self_k_idxs);
991    }
992
993    if (self_kq_mask && self_kq_mask->buffer) {
994        mctx->set_input_kq_mask(self_kq_mask, ubatch, cparams.causal_attn);
995    }
996
997    if (self_k_rot) {
998        mctx->set_input_k_rot(self_k_rot);
999    }
1000}
1001
1002void llm_graph_input_dsv4::set_input(const llama_ubatch * ubatch) {
1003    const auto & plan_csa = mctx->get_csa_plan(*ubatch);
1004    const auto & plan_hca = mctx->get_hca_plan(*ubatch);
1005    const auto & plan_lid = mctx->get_lid_plan(*ubatch);
1006    const int64_t n_stream = plan_csa.n_stream;
1007
1008    inp_raw->mctx = mctx->get_raw();
1009    inp_raw->set_input(ubatch);
1010
1011    dsv4_set_comp_inputs(inp_csa, plan_csa, "csa", debug > 0, ubatch->n_tokens, n_stream);
1012    dsv4_set_comp_inputs(inp_hca, plan_hca, "hca", debug > 0, ubatch->n_tokens, n_stream);
1013    dsv4_set_comp_inputs(inp_lid, plan_lid, "lid", debug > 0, ubatch->n_tokens, n_stream);
1014
1015    if (inp_csa.k_rot && inp_csa.k_rot->buffer) {
1016        mctx->get_csa()->set_input_k_rot(inp_csa.k_rot);
1017    }
1018
1019    if (inp_hca.k_rot && inp_hca.k_rot->buffer) {
1020        mctx->get_hca()->set_input_k_rot(inp_hca.k_rot);
1021    }
1022
1023    if (inp_lid.k_rot && inp_lid.k_rot->buffer) {
1024        mctx->get_lid()->set_input_k_rot(inp_lid.k_rot);
1025    }
1026}
1027
1028bool llm_graph_input_dsv4::can_reuse(const llm_graph_params & params) {
1029    const auto * mctx = static_cast<const llama_kv_cache_dsv4_context *>(params.mctx);
1030
1031    this->mctx = mctx;
1032    inp_raw->mctx = mctx->get_raw();
1033
1034    bool res = true;
1035
1036    const auto & plan_csa = mctx->get_csa_plan(params.ubatch);
1037    const auto & plan_hca = mctx->get_hca_plan(params.ubatch);
1038    const auto & plan_lid = mctx->get_lid_plan(params.ubatch);
1039    const int64_t n_stream = plan_csa.n_stream;
1040
1041    const auto * raw_ctx = mctx->get_raw();
1042    inp_raw->mctx = raw_ctx;
1043
1044    if (inp_raw->self_k_idxs && inp_raw->self_k_idxs->buffer) {
1045        res &= inp_raw->self_k_idxs->ne[0] == raw_ctx->get_n_write();
1046    }
1047    if (inp_raw->self_kq_mask && inp_raw->self_kq_mask->buffer) {
1048        res &= dsv4_can_reuse_raw_kq_mask(inp_raw->self_kq_mask, raw_ctx, params.ubatch, n_stream);
1049    }
1050
1051    res &= dsv4_can_reuse_comp_input(inp_csa, plan_csa, params.ubatch.n_tokens, n_stream);
1052    res &= dsv4_can_reuse_comp_input(inp_hca, plan_hca, params.ubatch.n_tokens, n_stream);
1053    res &= dsv4_can_reuse_comp_input(inp_lid, plan_lid, params.ubatch.n_tokens, n_stream);
1054
1055    return res;
1056}
1057
1058void llm_graph_input_attn_cross::set_input(const llama_ubatch * ubatch) {
1059    GGML_ASSERT(cross_kq_mask);
1060
1061    const int64_t n_enc    = cross_kq_mask->ne[0];
1062    const int64_t n_tokens = ubatch->n_tokens;
1063
1064    GGML_ASSERT(ggml_backend_buffer_is_host(cross_kq_mask->buffer));
1065    GGML_ASSERT(!ubatch->equal_seqs()); // TODO: use ubatch->n_seqs instead of failing
1066
1067    const auto fill_mask = [&](auto * data) {
1068        using T = std::remove_reference_t<decltype(*data)>;
1069        for (int i = 0; i < n_tokens; ++i) {
1070            GGML_ASSERT(!cross->seq_ids_enc.empty() && "llama_encode must be called first");
1071            for (int j = 0; j < n_enc; ++j) {
1072                float f = -INFINITY;
1073
1074                for (int s = 0; s < ubatch->n_seq_id[i]; ++s) {
1075                    const llama_seq_id seq_id = ubatch->seq_id[i][s];
1076
1077                    if (cross->seq_ids_enc[j].find(seq_id) != cross->seq_ids_enc[j].end()) {
1078                        f = 0.0f;
1079                    }
1080                }
1081
1082                data[i*n_enc + j] = llama_cast<T>(f);
1083            }
1084        }
1085    };
1086
1087    if (cross_kq_mask->type == GGML_TYPE_F16) {
1088        fill_mask((ggml_fp16_t *) cross_kq_mask->data);
1089    } else {
1090        fill_mask((float *) cross_kq_mask->data);
1091    }
1092}
1093
1094bool llm_graph_input_attn_cross::can_reuse(const llm_graph_params & params) {
1095    return cross && cross == params.cross && !cross->v_embd.empty() &&
1096        cross_kq_mask->ne[0] == cross->n_enc && cross_kq_mask->ne[1] == params.ubatch.n_tokens &&
1097        cross_kq_mask->type == (params.cparams.flash_attn ? GGML_TYPE_F16 : GGML_TYPE_F32);
1098}
1099
1100void llm_graph_input_mem_hybrid::set_input(const llama_ubatch * ubatch) {
1101    mctx->get_attn()->set_input_k_idxs(inp_attn->self_k_idxs, ubatch);
1102    mctx->get_attn()->set_input_v_idxs(inp_attn->self_v_idxs, ubatch);
1103
1104    mctx->get_attn()->set_input_kq_mask(inp_attn->self_kq_mask, ubatch, cparams.causal_attn);
1105
1106    if (inp_attn->self_k_rot) {
1107        mctx->get_attn()->set_input_k_rot(inp_attn->self_k_rot);
1108    }
1109
1110    if (inp_attn->self_v_rot) {
1111        mctx->get_attn()->set_input_v_rot(inp_attn->self_v_rot);
1112    }
1113
1114    const int64_t n_rs = mctx->get_recr()->get_n_rs();
1115
1116    if (inp_rs->s_copy) {
1117        GGML_ASSERT(ggml_backend_buffer_is_host(inp_rs->s_copy->buffer));
1118        int32_t * data = (int32_t *) inp_rs->s_copy->data;
1119
1120        // assuming copy destinations ALWAYS happen ONLY on the cells between head and head+n
1121        for (uint32_t i = 0; i < n_rs; ++i) {
1122            data[i] = mctx->get_recr()->s_copy(i);
1123        }
1124    }
1125}
1126
1127bool llm_graph_input_mem_hybrid::can_reuse(const llm_graph_params & params) {
1128    const auto * mctx = static_cast<const llama_memory_hybrid_context *>(params.mctx);
1129
1130    this->mctx = mctx;
1131
1132    bool res = true;
1133
1134    res &= inp_attn->self_k_idxs->ne[0] == params.ubatch.n_tokens;
1135  //res &= inp_attn->self_v_idxs->ne[0] == params.ubatch.n_tokens; // TODO: need to move this to the unified cache and check there
1136
1137    res &= can_reuse_kq_mask(inp_attn->self_kq_mask, mctx->get_attn(), params.ubatch, params.cparams);
1138
1139    res &= inp_rs->s_copy->ne[0] == mctx->get_recr()->get_n_rs();
1140
1141    res &= inp_rs->s_copy_main->ne[0]  == params.ubatch.n_seqs;
1142    res &= inp_rs->s_copy_extra->ne[0] == mctx->get_recr()->get_n_rs() - params.ubatch.n_seqs;
1143
1144    res &= inp_rs->head == mctx->get_recr()->get_head();
1145    res &= inp_rs->rs_z == mctx->get_recr()->get_rs_z();
1146
1147    return res;
1148}
1149
1150// TODO: Hybrid input classes are a bit redundant.
1151// Instead of creating a hybrid input, the graph can simply create 2 separate inputs.
1152// Refactoring is required in the future.
1153void llm_graph_input_mem_hybrid_k::set_input(const llama_ubatch * ubatch) {
1154    mctx->get_attn()->set_input_k_idxs(inp_attn->self_k_idxs, ubatch);
1155
1156    mctx->get_attn()->set_input_kq_mask(inp_attn->self_kq_mask, ubatch, cparams.causal_attn);
1157
1158    const int64_t n_rs = mctx->get_recr()->get_n_rs();
1159
1160    if (inp_rs->s_copy) {
1161        GGML_ASSERT(ggml_backend_buffer_is_host(inp_rs->s_copy->buffer));
1162        int32_t * data = (int32_t *) inp_rs->s_copy->data;
1163
1164        // assuming copy destinations ALWAYS happen ONLY on the cells between head and head+n
1165        for (uint32_t i = 0; i < n_rs; ++i) {
1166            data[i] = mctx->get_recr()->s_copy(i);
1167        }
1168    }
1169}
1170
1171bool llm_graph_input_mem_hybrid_k::can_reuse(const llm_graph_params & params) {
1172    const auto * mctx = static_cast<const llama_memory_hybrid_context *>(params.mctx);
1173
1174    this->mctx = mctx;
1175
1176    bool res = true;
1177
1178    res &= inp_attn->self_k_idxs->ne[0] == params.ubatch.n_tokens;
1179
1180    res &= can_reuse_kq_mask(inp_attn->self_kq_mask, mctx->get_attn(), params.ubatch, params.cparams);
1181
1182    res &= inp_rs->s_copy->ne[0] == mctx->get_recr()->get_n_rs();
1183
1184    res &= inp_rs->s_copy_main->ne[0]  == params.ubatch.n_seqs;
1185    res &= inp_rs->s_copy_extra->ne[0] == mctx->get_recr()->get_n_rs() - params.ubatch.n_seqs;
1186
1187    res &= inp_rs->head == mctx->get_recr()->get_head();
1188    res &= inp_rs->rs_z == mctx->get_recr()->get_rs_z();
1189
1190    return res;
1191}
1192
1193void llm_graph_input_mem_hybrid_iswa::set_input(const llama_ubatch * ubatch) {
1194    const auto * attn_ctx = mctx->get_attn();
1195
1196    // base tensors may not be allocated if there are no non-SWA attention layers
1197    if (inp_attn->self_k_idxs && inp_attn->self_k_idxs->buffer) {
1198        attn_ctx->get_base()->set_input_k_idxs(inp_attn->self_k_idxs, ubatch);
1199        attn_ctx->get_base()->set_input_v_idxs(inp_attn->self_v_idxs, ubatch);
1200    }
1201
1202    if (inp_attn->self_kq_mask && inp_attn->self_kq_mask->buffer) {
1203        attn_ctx->get_base()->set_input_kq_mask(inp_attn->self_kq_mask, ubatch, cparams.causal_attn);
1204    }
1205
1206    // swa tensors may not be allocated if there are no SWA attention layers
1207    if (inp_attn->self_k_idxs_swa && inp_attn->self_k_idxs_swa->buffer) {
1208        attn_ctx->get_swa()->set_input_k_idxs(inp_attn->self_k_idxs_swa, ubatch);
1209        attn_ctx->get_swa()->set_input_v_idxs(inp_attn->self_v_idxs_swa, ubatch);
1210    }
1211
1212    if (inp_attn->self_kq_mask_swa && inp_attn->self_kq_mask_swa->buffer) {
1213        attn_ctx->get_swa()->set_input_kq_mask(inp_attn->self_kq_mask_swa, ubatch, cparams.causal_attn);
1214    }
1215
1216    if (inp_attn->self_k_rot) {
1217        attn_ctx->get_base()->set_input_k_rot(inp_attn->self_k_rot);
1218    }
1219
1220    if (inp_attn->self_v_rot) {
1221        attn_ctx->get_base()->set_input_v_rot(inp_attn->self_v_rot);
1222    }
1223
1224    if (inp_attn->self_k_rot_swa) {
1225        attn_ctx->get_swa()->set_input_k_rot(inp_attn->self_k_rot_swa);
1226    }
1227
1228    if (inp_attn->self_v_rot_swa) {
1229        attn_ctx->get_swa()->set_input_v_rot(inp_attn->self_v_rot_swa);
1230    }
1231
1232    const int64_t n_rs = mctx->get_recr()->get_n_rs();
1233
1234    if (inp_rs->s_copy) {
1235        GGML_ASSERT(ggml_backend_buffer_is_host(inp_rs->s_copy->buffer));
1236        int32_t * data = (int32_t *) inp_rs->s_copy->data;
1237
1238        // assuming copy destinations ALWAYS happen ONLY on the cells between head and head+n
1239        for (uint32_t i = 0; i < n_rs; ++i) {
1240            data[i] = mctx->get_recr()->s_copy(i);
1241        }
1242    }
1243}
1244
1245bool llm_graph_input_mem_hybrid_iswa::can_reuse(const llm_graph_params & params) {
1246    const auto * mctx = static_cast<const llama_memory_hybrid_iswa_context *>(params.mctx);
1247
1248    this->mctx = mctx;
1249
1250    bool res = true;
1251
1252    const auto * attn_ctx = mctx->get_attn();
1253
1254    // base tensors may not be allocated if there are no non-SWA attention layers
1255    if (inp_attn->self_k_idxs && inp_attn->self_k_idxs->buffer) {
1256        res &= inp_attn->self_k_idxs->ne[0] == params.ubatch.n_tokens;
1257      //res &= inp_attn->self_v_idxs->ne[0] == params.ubatch.n_tokens; // TODO: need to move this to the unified cache and check there
1258    }
1259
1260    res &= can_reuse_kq_mask(inp_attn->self_kq_mask, attn_ctx->get_base(), params.ubatch, params.cparams);
1261
1262    // swa tensors may not be allocated if there are no SWA attention layers
1263    if (inp_attn->self_k_idxs_swa && inp_attn->self_k_idxs_swa->buffer) {
1264        res &= inp_attn->self_k_idxs_swa->ne[0] == params.ubatch.n_tokens;
1265      //res &= inp_attn->self_v_idxs_swa->ne[0] == params.ubatch.n_tokens; // TODO: need to move this to the unified cache and check there
1266    }
1267
1268    res &= can_reuse_kq_mask(inp_attn->self_kq_mask_swa, attn_ctx->get_swa(), params.ubatch, params.cparams);
1269
1270    res &= inp_rs->s_copy->ne[0] == mctx->get_recr()->get_n_rs();
1271
1272    res &= inp_rs->s_copy_main->ne[0]  == params.ubatch.n_seqs;
1273    res &= inp_rs->s_copy_extra->ne[0] == mctx->get_recr()->get_n_rs() - params.ubatch.n_seqs;
1274
1275    res &= inp_rs->head == mctx->get_recr()->get_head();
1276    res &= inp_rs->rs_z == mctx->get_recr()->get_rs_z();
1277
1278    return res;
1279}
1280
1281void llm_graph_input_sampling::set_input(const llama_ubatch * ubatch) {
1282    // set the inputs only for the active samplers in the current ubatch
1283    std::unordered_set<llama_seq_id> active_samplers;
1284    for (uint32_t i = 0; i < ubatch->n_tokens; i++) {
1285        if (ubatch->output[i]) {
1286            llama_seq_id seq_id = ubatch->seq_id[i][0];
1287            active_samplers.insert(seq_id);
1288        }
1289    }
1290
1291    for (auto seq_id : active_samplers) {
1292        if (samplers.find(seq_id) == samplers.end()) {
1293            continue;
1294        }
1295
1296        auto & sampler = samplers[seq_id];
1297
1298        if (sampler->iface->backend_set_input) {
1299            sampler->iface->backend_set_input(sampler);
1300        }
1301    }
1302}
1303
1304bool llm_graph_input_sampling::can_reuse(const llm_graph_params & params) {
1305    if (samplers.size() != params.samplers.size()) {
1306        return false;
1307    }
1308
1309    for (const auto & [seq_id, sampler] : params.samplers) {
1310        if (samplers[seq_id] != sampler) {
1311            return false;
1312        }
1313    }
1314
1315    return true;
1316}
1317
1318//
1319// llm_graph_result
1320//
1321
1322llm_graph_result::llm_graph_result(int64_t max_nodes) : max_nodes(max_nodes) {
1323    reset();
1324
1325    const char * LLAMA_GRAPH_RESULT_DEBUG = getenv("LLAMA_GRAPH_RESULT_DEBUG");
1326    debug = LLAMA_GRAPH_RESULT_DEBUG ? atoi(LLAMA_GRAPH_RESULT_DEBUG) : 0;
1327}
1328
1329int64_t llm_graph_result::get_max_nodes() const {
1330    return max_nodes;
1331}
1332
1333void llm_graph_result::reset() {
1334    t_inp_tokens  = nullptr;
1335    t_inp_embd    = nullptr;
1336    t_logits      = nullptr;
1337    t_embd        = nullptr;
1338    t_embd_pooled = nullptr;
1339    t_h_nextn     = nullptr;
1340
1341    t_layer_inp.resize(LLAMA_MAX_LAYERS + 1);
1342    std::fill(t_layer_inp.begin(), t_layer_inp.end(), nullptr);
1343
1344    t_sampled.clear();
1345    t_sampled_probs.clear();
1346    t_sampled_logits.clear();
1347    t_candidates.clear();
1348
1349    params = {};
1350
1351    inputs.clear();
1352    fused_nodes.clear();
1353
1354    buf_compute_meta.resize(ggml_tensor_overhead()*max_nodes + ggml_graph_overhead_custom(max_nodes, false));
1355
1356    ggml_init_params params = {
1357        /*.mem_size   =*/ buf_compute_meta.size(),
1358        /*.mem_buffer =*/ buf_compute_meta.data(),
1359        /*.no_alloc   =*/ true,
1360    };
1361
1362    ctx_compute.reset(ggml_init(params));
1363
1364    gf = ggml_new_graph_custom(ctx_compute.get(), max_nodes, false);
1365}
1366
1367void llm_graph_result::set_inputs(const llama_ubatch * ubatch) {
1368    for (auto & input : inputs) {
1369        input->set_input(ubatch);
1370    }
1371}
1372
1373void llm_graph_result::set_outputs(const llm_graph_params & params) {
1374    if (t_logits != nullptr) {
1375        ggml_set_output(t_logits);
1376    }
1377    if (t_embd != nullptr) {
1378        ggml_set_output(t_embd);
1379    }
1380    if (t_embd_pooled != nullptr) {
1381        ggml_set_output(t_embd_pooled);
1382    }
1383    if (t_h_nextn != nullptr) {
1384        ggml_set_output(t_h_nextn);
1385    }
1386    {
1387        const auto & embeddings_layer_inp = params.cparams.embeddings_layer_inp;
1388        for (size_t il = 0; il < embeddings_layer_inp.size(); ++il) {
1389            if (embeddings_layer_inp[il]) {
1390                GGML_ASSERT(t_layer_inp[il] != nullptr && "layer input tensor is null");
1391                ggml_set_output(t_layer_inp[il]);
1392            }
1393        }
1394    }
1395    for (auto * tensor : t_sampled) {
1396        if (tensor != nullptr) {
1397            ggml_set_output(tensor);
1398        }
1399    }
1400    for (auto * tensor : t_sampled_probs) {
1401        if (tensor != nullptr) {
1402            ggml_set_output(tensor);
1403        }
1404    }
1405    for (auto * tensor : t_sampled_logits) {
1406        if (tensor != nullptr) {
1407            ggml_set_output(tensor);
1408        }
1409    }
1410    for (auto * tensor : t_candidates) {
1411        if (tensor != nullptr) {
1412            ggml_set_output(tensor);
1413        }
1414    }
1415}
1416
1417bool llm_graph_result::can_reuse(const llm_graph_params & params) {
1418    if (!this->params.allow_reuse(params)) {
1419        if (debug > 1) {
1420            LLAMA_LOG_DEBUG("%s: cannot reuse graph due to incompatible graph parameters\n", __func__);
1421        }
1422
1423        return false;
1424    }
1425
1426    if (debug > 1) {
1427        LLAMA_LOG_DEBUG("%s: checking compatibility of %d inputs:\n", __func__, (int) inputs.size());
1428    }
1429
1430    bool res = true;
1431
1432    for (auto & input : inputs) {
1433        const bool cur = input->can_reuse(params);
1434
1435        if (debug > 1) {
1436            LLAMA_LOG_DEBUG("%s: can_reuse = %d\n", "placeholder", cur);
1437        }
1438
1439        res = res && cur;
1440    }
1441
1442    if (debug > 0) {
1443        LLAMA_LOG_DEBUG("%s: can reuse graph = %d\n", __func__, res);
1444    }
1445
1446    return res;
1447}
1448
1449llm_graph_input_i * llm_graph_result::add_input(llm_graph_input_ptr input) {
1450    inputs.emplace_back(std::move(input));
1451    return inputs.back().get();
1452}
1453
1454void llm_graph_result::add_fused_node(llm_graph_fused_node result) {
1455    fused_nodes.push_back(result);
1456}
1457
1458void llm_graph_result::set_params(const llm_graph_params & params) {
1459    this->params = params;
1460}
1461
1462//
1463// llm_graph_context
1464//
1465
1466llm_graph_context::llm_graph_context(const llm_graph_params & params) :
1467    arch             (params.arch),
1468    hparams          (params.hparams),
1469    cparams          (params.cparams),
1470    ubatch           (params.ubatch),
1471    n_embd           (hparams.n_embd),
1472    n_layer          (hparams.n_layer()),
1473    n_layer_nextn    (hparams.n_layer_nextn),
1474    n_rot            (hparams.n_rot()),
1475    n_ctx            (cparams.n_ctx),
1476    n_head           (hparams.n_head()),
1477    n_head_kv        (hparams.n_head_kv()),
1478    n_embd_head_k    (hparams.n_embd_head_k()),
1479    n_embd_k_gqa     (hparams.n_embd_k_gqa()),
1480    n_embd_head_v    (hparams.n_embd_head_v()),
1481    n_embd_v_gqa     (hparams.n_embd_v_gqa()),
1482    n_expert         (hparams.n_expert),
1483    n_expert_used    (cparams.warmup ? hparams.n_expert : hparams.n_expert_used()),
1484    freq_base        (cparams.rope_freq_base),
1485    freq_scale       (cparams.rope_freq_scale),
1486    ext_factor       (cparams.yarn_ext_factor),
1487    attn_factor      (cparams.yarn_attn_factor),
1488    beta_fast        (cparams.yarn_beta_fast),
1489    beta_slow        (cparams.yarn_beta_slow),
1490    norm_eps         (hparams.f_norm_eps),
1491    norm_rms_eps     (hparams.f_norm_rms_eps),
1492    n_tokens         (ubatch.n_tokens),
1493    n_outputs        (params.n_outputs),
1494    n_ctx_orig       (cparams.n_ctx_orig_yarn),
1495    pooling_type     (cparams.pooling_type),
1496    rope_type        (hparams.rope_type),
1497    sched            (params.sched),
1498    backend_cpu      (params.backend_cpu),
1499    cvec             (params.cvec),
1500    loras            (params.loras),
1501    mctx             (params.mctx),
1502    cross            (params.cross),
1503    samplers         (params.samplers),
1504    cb_func          (params.cb),
1505    res              (params.res),
1506    ctx0             (res->get_ctx()),
1507    gf               (res->get_gf()) {
1508        res->set_params(params);
1509    }
1510
1511void llm_graph_context::cb(ggml_tensor * cur, const char * name, int il) const {
1512    if (cb_func) {
1513        cb_func(ubatch, cur, name, il);
1514    }
1515}
1516
1517
1518
1519ggml_tensor * llm_graph_context::build_cvec(
1520         ggml_tensor * cur,
1521                 int   il) const {
1522    return cvec->apply_to(ctx0, cur, il);
1523}
1524
1525ggml_tensor * llm_graph_context::build_lora_mm(
1526          ggml_tensor * w,
1527          ggml_tensor * cur,
1528          ggml_tensor * w_s) const {
1529    ggml_tensor * res = ggml_mul_mat(ctx0, w, cur);
1530
1531    if (w_s) {
1532        res = ggml_mul(ctx0, res, w_s);
1533    }
1534
1535    for (const auto & lora : *loras) {
1536        llama_adapter_lora_weight * lw = lora.first->get_weight(w);
1537        if (lw == nullptr) {
1538            continue;
1539        }
1540
1541        const float adapter_scale = lora.second;
1542        const float scale = lw->get_scale(lora.first->alpha, adapter_scale);
1543
1544        ggml_tensor * ab_cur = ggml_mul_mat(
1545                ctx0, lw->b,
1546                ggml_mul_mat(ctx0, lw->a, cur)
1547                );
1548
1549        ab_cur = ggml_scale(ctx0, ab_cur, scale);
1550        res = ggml_add(ctx0, res, ab_cur);
1551    }
1552
1553    return res;
1554}
1555
1556ggml_tensor * llm_graph_context::build_lora_mm_id(
1557          ggml_tensor * w,   // ggml_tensor * as
1558          ggml_tensor * cur, // ggml_tensor * b
1559          ggml_tensor * ids,
1560          ggml_tensor * w_s) const {
1561    ggml_tensor * res = ggml_mul_mat_id(ctx0, w, cur, ids);
1562
1563    if (w_s) {
1564        const int64_t n_expert = w_s->ne[0];
1565        const int64_t n_tokens = cur->ne[2];
1566        ggml_tensor * s = ggml_reshape_3d(ctx0, w_s, 1, n_expert, 1);
1567        s = ggml_repeat_4d(ctx0, s, 1, n_expert, n_tokens, 1);
1568        s = ggml_get_rows(ctx0, s, ids);
1569        res = ggml_mul(ctx0, res, s);
1570    }
1571    for (const auto & lora : *loras) {
1572        llama_adapter_lora_weight * lw = lora.first->get_weight(w);
1573        if (lw == nullptr) {
1574            continue;
1575        }
1576
1577        const float alpha = lora.first->alpha;
1578        const float rank  = (float) lw->b->ne[0];
1579        const float scale = alpha ? lora.second * alpha / rank : lora.second;
1580
1581        ggml_tensor * ab_cur = ggml_mul_mat_id(
1582                ctx0, lw->b,
1583                ggml_mul_mat_id(ctx0, lw->a, cur, ids),
1584                ids
1585                );
1586
1587        ab_cur = ggml_scale(ctx0, ab_cur, scale);
1588        res = ggml_add(ctx0, res, ab_cur);
1589    }
1590
1591    return res;
1592}
1593
1594ggml_tensor * llm_graph_context::build_norm(
1595         ggml_tensor * cur,
1596         ggml_tensor * mw,
1597         ggml_tensor * mb,
1598       llm_norm_type   type,
1599                 int   il) const {
1600    switch (type) {
1601        case LLM_NORM:       cur = ggml_norm    (ctx0, cur, hparams.f_norm_eps);     break;
1602        case LLM_NORM_RMS:   cur = ggml_rms_norm(ctx0, cur, hparams.f_norm_rms_eps); break;
1603        case LLM_NORM_GROUP:
1604            {
1605                cur = ggml_reshape_3d(ctx0, cur, cur->ne[0], 1, cur->ne[1]);
1606                cur = ggml_group_norm(ctx0, cur, hparams.n_norm_groups, hparams.f_norm_group_eps);
1607                cur = ggml_reshape_2d(ctx0, cur, cur->ne[0],    cur->ne[2]);
1608            } break;
1609    }
1610
1611    if (mw || mb) {
1612        cb(cur, "norm", il);
1613    }
1614
1615    if (mw) {
1616        cur = ggml_mul(ctx0, cur, mw);
1617        if (mb) {
1618            cb(cur, "norm_w", il);
1619        }
1620    }
1621
1622    if (mb) {
1623        cur = ggml_add(ctx0, cur, mb);
1624    }
1625
1626    return cur;
1627}
1628
1629
1630llm_graph_qkv llm_graph_context::build_qkv(
1631        const llama_layer & layer,
1632              ggml_tensor * cur,
1633                  int64_t   n_embd_head,
1634                  int64_t   n_head,
1635                  int64_t   n_head_kv,
1636                      int   il) const {
1637    return build_qkv(layer, cur,
1638            n_embd_head, n_head,
1639            n_embd_head, n_head_kv,
1640            n_embd_head, n_head_kv,
1641            il);
1642}
1643
1644llm_graph_qkv llm_graph_context::build_qkv(
1645        const llama_layer & layer,
1646              ggml_tensor * cur,
1647                  int64_t   n_embd_head_q,
1648                  int64_t   n_head_q,
1649                  int64_t   n_embd_head_k,
1650                  int64_t   n_head_k,
1651                  int64_t   n_embd_head_v,
1652                  int64_t   n_head_v,
1653                      int   il,
1654                     bool   reshape) const {
1655    const int64_t n_embd_q = n_embd_head_q * n_head_q;
1656    const int64_t n_embd_k = n_embd_head_k * n_head_k;
1657
1658    ggml_tensor * Qcur, * Kcur, * Vcur;
1659
1660    if (layer.wqkv) {
1661        // fused QKV path
1662        ggml_tensor * qkv = build_lora_mm(layer.wqkv, cur, layer.wqkv_s);
1663        cb(qkv, "wqkv", il);
1664        if (layer.wqkv_b) {
1665            qkv = ggml_add(ctx0, qkv, layer.wqkv_b);
1666            cb(qkv, "wqkv_b", il);
1667        } else if (layer.wq_b && layer.wk_b && layer.wv_b) {
1668            // Fused weights may coexist with separate Q/K/V biases in legacy or custom GGUFs.
1669            ggml_tensor * qkv_b = ggml_concat(ctx0, ggml_concat(ctx0, layer.wq_b, layer.wk_b, 0), layer.wv_b, 0);
1670            qkv = ggml_add(ctx0, qkv, qkv_b);
1671            cb(qkv, "wqkv_b", il);
1672        }
1673        if (reshape && hparams.f_clamp_kqv > 0.0f) {
1674            qkv = ggml_clamp(ctx0, qkv, -hparams.f_clamp_kqv, hparams.f_clamp_kqv);
1675            cb(qkv, "wqkv_clamped", il);
1676        }
1677        if (reshape) {
1678            Qcur = ggml_view_3d(ctx0, qkv, n_embd_head_q, n_head_q, n_tokens,
1679                ggml_row_size(qkv->type, n_embd_head_q), qkv->nb[1], 0);
1680            Kcur = ggml_view_3d(ctx0, qkv, n_embd_head_k, n_head_k, n_tokens,
1681                ggml_row_size(qkv->type, n_embd_head_k), qkv->nb[1],
1682                ggml_row_size(qkv->type, n_embd_q));
1683            Vcur = ggml_view_3d(ctx0, qkv, n_embd_head_v, n_head_v, n_tokens,
1684                ggml_row_size(qkv->type, n_embd_head_v), qkv->nb[1],
1685                ggml_row_size(qkv->type, n_embd_q + n_embd_k));
1686        } else {
1687            Qcur = ggml_view_2d(ctx0, qkv, n_embd_q, n_tokens, qkv->nb[1], 0);
1688            Kcur = ggml_view_2d(ctx0, qkv, n_embd_k, n_tokens, qkv->nb[1],
1689                ggml_row_size(qkv->type, n_embd_q));
1690            Vcur = ggml_view_2d(ctx0, qkv, n_embd_head_v * n_head_v, n_tokens, qkv->nb[1],
1691                ggml_row_size(qkv->type, n_embd_q + n_embd_k));
1692        }
1693        if (!reshape) {
1694            Qcur = ggml_cont(ctx0, Qcur);
1695            Kcur = ggml_cont(ctx0, Kcur);
1696            Vcur = ggml_cont(ctx0, Vcur);
1697        }
1698    } else {
1699        // separate Q/K/V path
1700        Qcur = build_lora_mm(layer.wq, cur, layer.wq_s);
1701        if (reshape) {
1702            cb(Qcur, "Qcur", il);
1703        }
1704        if (layer.wq_b) {
1705            Qcur = ggml_add(ctx0, Qcur, layer.wq_b);
1706            if (reshape) {
1707                cb(Qcur, "Qcur", il);
1708            }
1709        }
1710        if (reshape && hparams.f_clamp_kqv > 0.0f) {
1711            Qcur = ggml_clamp(ctx0, Qcur, -hparams.f_clamp_kqv, hparams.f_clamp_kqv);
1712            cb(Qcur, "Qcur_clamped", il);
1713        }
1714        Kcur = build_lora_mm(layer.wk, cur, layer.wk_s);
1715        if (reshape) {
1716            cb(Kcur, "Kcur", il);
1717        }
1718        if (layer.wk_b) {
1719            Kcur = ggml_add(ctx0, Kcur, layer.wk_b);
1720            if (reshape) {
1721                cb(Kcur, "Kcur", il);
1722            }
1723        }
1724        if (reshape && hparams.f_clamp_kqv > 0.0f) {
1725            Kcur = ggml_clamp(ctx0, Kcur, -hparams.f_clamp_kqv, hparams.f_clamp_kqv);
1726            cb(Kcur, "Kcur_clamped", il);
1727        }
1728        Vcur = build_lora_mm(layer.wv, cur, layer.wv_s);
1729        if (reshape) {
1730            cb(Vcur, "Vcur", il);
1731        }
1732        if (layer.wv_b) {
1733            Vcur = ggml_add(ctx0, Vcur, layer.wv_b);
1734            if (reshape) {
1735                cb(Vcur, "Vcur", il);
1736            }
1737        }
1738        if (reshape && hparams.f_clamp_kqv > 0.0f) {
1739            Vcur = ggml_clamp(ctx0, Vcur, -hparams.f_clamp_kqv, hparams.f_clamp_kqv);
1740            cb(Vcur, "Vcur_clamped", il);
1741        }
1742        if (reshape) {
1743            Qcur = ggml_reshape_3d(ctx0, Qcur, n_embd_head_q, n_head_q, n_tokens);
1744            Kcur = ggml_reshape_3d(ctx0, Kcur, n_embd_head_k, n_head_k, n_tokens);
1745            Vcur = ggml_reshape_3d(ctx0, Vcur, n_embd_head_v, n_head_v, n_tokens);
1746        }
1747    }
1748
1749    if (reshape) {
1750        cb(Qcur, "Qcur", il);
1751        cb(Kcur, "Kcur", il);
1752        cb(Vcur, "Vcur", il);
1753    }
1754
1755    return { Qcur, Kcur, Vcur };
1756}
1757
1758
1759ggml_tensor * llm_graph_context::build_ffn(
1760         ggml_tensor * cur,
1761         ggml_tensor * up,
1762         ggml_tensor * up_b,
1763         ggml_tensor * up_s,
1764         ggml_tensor * gate,
1765         ggml_tensor * gate_b,
1766         ggml_tensor * gate_s,
1767         ggml_tensor * down,
1768         ggml_tensor * down_b,
1769         ggml_tensor * down_s,
1770         ggml_tensor * act_scales,
1771     llm_ffn_op_type   type_op,
1772   llm_ffn_gate_type   type_gate,
1773                 int   il) const {
1774    // NVFP4 support is currently restricted to
1775    // 1) LORA absence (*_s would be applied after LORA residual, which is incorrect)
1776    // 2) bias absense (*_s would be applied after bias addition, which is incorrect)
1777    // TODO: disambiguate LLM-architectural scales (which use *_s) from NVFP4 scale_2 (which also uses *_s currently)
1778    auto has_lora = [this](ggml_tensor * w) {
1779        if (!w) {
1780            return false;
1781        }
1782        for (const auto & lora : *loras) {
1783            if (lora.first->get_weight(w) != nullptr) {
1784                return true;
1785            }
1786        }
1787        return false;
1788    };
1789
1790    GGML_ASSERT(!up_s   || !up_b   || !up   || up->type   != GGML_TYPE_NVFP4);
1791    GGML_ASSERT(!gate_s || !gate_b || !gate || gate->type != GGML_TYPE_NVFP4);
1792    GGML_ASSERT(!down_s || !down_b || !down || down->type != GGML_TYPE_NVFP4);
1793    GGML_ASSERT(!up_s   || !up   || up->type   != GGML_TYPE_NVFP4 || !has_lora(up));
1794    GGML_ASSERT(!gate_s || !gate || gate->type != GGML_TYPE_NVFP4 || !has_lora(gate));
1795    GGML_ASSERT(!down_s || !down || down->type != GGML_TYPE_NVFP4 || !has_lora(down));
1796
1797    ggml_tensor * tmp = up ? build_lora_mm(up, cur) : cur;
1798    cb(tmp, "ffn_up", il);
1799
1800    if (up_b) {
1801        tmp = ggml_add(ctx0, tmp, up_b);
1802        cb(tmp, "ffn_up_b", il);
1803    }
1804
1805    if (up_s) {
1806        tmp = ggml_mul(ctx0, tmp, up_s);
1807        cb(tmp, "ffn_up_s", il);
1808    }
1809
1810    if (gate) {
1811        switch (type_gate) {
1812            case LLM_FFN_SEQ:
1813                {
1814                    cur = build_lora_mm(gate, tmp);
1815                    cb(cur, "ffn_gate", il);
1816                } break;
1817            case LLM_FFN_PAR:
1818                {
1819                    cur = build_lora_mm(gate, cur);
1820                    cb(cur, "ffn_gate", il);
1821                } break;
1822        }
1823
1824        if (gate_b) {
1825            cur = ggml_add(ctx0, cur, gate_b);
1826            cb(cur, "ffn_gate_b", il);
1827        }
1828
1829        if (gate_s) {
1830            cur = ggml_mul(ctx0, cur, gate_s);
1831            cb(cur, "ffn_gate_s", il);
1832        }
1833
1834    } else {
1835        cur = tmp;
1836    }
1837
1838    switch (type_op) {
1839        case LLM_FFN_SILU:
1840            if (gate && type_gate == LLM_FFN_PAR) {
1841                if (il >= 0) {
1842                    const float limit = hparams.swiglu_clamp_shexp[il];
1843                    constexpr float eps = 1e-6f;
1844                    if (limit > eps) {
1845                        if (arch == LLM_ARCH_DEEPSEEK4 || (arch == LLM_ARCH_DFLASH && hparams.dsv4_hc_mult > 0)) {
1846                            cur = ggml_swiglu_clamp(ctx0, cur, tmp, limit);
1847                        } else {
1848                            tmp = ggml_clamp(ctx0, tmp, -limit, limit);
1849                            cb(tmp, "ffn_up_clamped", il);
1850                            ggml_tensor * gate_act = ggml_silu(ctx0, cur);
1851                            cb(gate_act, "ffn_silu", il);
1852                            gate_act = ggml_clamp(ctx0, gate_act, -INFINITY, limit);
1853                            cb(gate_act, "ffn_silu_clamped", il);
1854                            cur = ggml_mul(ctx0, gate_act, tmp);
1855                        }
1856                        cb(cur, "ffn_swiglu_limited", il);
1857                        type_gate = LLM_FFN_SEQ;
1858                        break;
1859                    }
1860                }
1861
1862                cur = ggml_swiglu_split(ctx0, cur, tmp);
1863                cb(cur, "ffn_swiglu", il);
1864                type_gate = LLM_FFN_SEQ;
1865            } else {
1866                cur = ggml_silu(ctx0, cur);
1867                cb(cur, "ffn_silu", il);
1868            } break;
1869        case LLM_FFN_GELU:
1870            if (gate && type_gate == LLM_FFN_PAR) {
1871                cur = ggml_geglu_split(ctx0, cur, tmp);
1872                cb(cur, "ffn_geglu", il);
1873                type_gate = LLM_FFN_SEQ;
1874            } else {
1875                cur = ggml_gelu(ctx0, cur);
1876                cb(cur, "ffn_gelu", il);
1877                if (act_scales != NULL) {
1878                    cur = ggml_div(ctx0, cur, act_scales);
1879                    cb(cur, "ffn_act", il);
1880                }
1881            } break;
1882        case LLM_FFN_RELU:
1883            if (gate && type_gate == LLM_FFN_PAR) {
1884                cur = ggml_reglu_split(ctx0, cur, tmp);
1885                cb(cur, "ffn_reglu", il);
1886                type_gate = LLM_FFN_SEQ;
1887            } else {
1888                cur = ggml_relu(ctx0, cur);
1889                cb(cur, "ffn_relu", il);
1890            } break;
1891        case LLM_FFN_RELU_SQR:
1892            {
1893                cur = ggml_relu(ctx0, cur);
1894                cb(cur, "ffn_relu", il);
1895
1896                cur = ggml_sqr(ctx0, cur);
1897                cb(cur, "ffn_sqr(relu)", il);
1898            } break;
1899        case LLM_FFN_SWIGLU:
1900            {
1901                cur = ggml_swiglu(ctx0, cur);
1902                cb(cur, "ffn_swiglu", il);
1903            } break;
1904        case LLM_FFN_SWIGLU_OAI_MOE:
1905            if (gate && type_gate == LLM_FFN_PAR) {
1906                // same alpha/limit constants as gpt-oss
1907                const float alpha = 1.702f;
1908                const float limit = 7.0f;
1909                cur = ggml_swiglu_oai(ctx0, cur, tmp, alpha, limit);
1910                cb(cur, "ffn_swiglu_oai", il);
1911                type_gate = LLM_FFN_SEQ;
1912            } else {
1913                GGML_ABORT("LLM_FFN_SWIGLU_OAI_MOE requires a parallel gate");
1914            } break;
1915        case LLM_FFN_GEGLU:
1916            {
1917                cur = ggml_geglu(ctx0, cur);
1918                cb(cur, "ffn_geglu", il);
1919            } break;
1920        case LLM_FFN_REGLU:
1921            {
1922                cur = ggml_reglu(ctx0, cur);
1923                cb(cur, "ffn_reglu", il);
1924            } break;
1925        case LLM_FFN_SITU:
1926            GGML_ABORT("not yet supported");
1927        default:
1928            GGML_ABORT("fatal error");
1929    }
1930
1931    if (gate && type_gate == LLM_FFN_PAR) {
1932        cur = ggml_mul(ctx0, cur, tmp);
1933        cb(cur, "ffn_gate_par", il);
1934    }
1935
1936    if (down) {
1937        cur = build_lora_mm(down, cur);
1938        if (arch == LLM_ARCH_GLM4 || arch == LLM_ARCH_GLM4_MOE || arch == LLM_ARCH_JAIS2) {
1939            // GLM4, GLM4_MOE, and JAIS2 seem to have numerical issues with half-precision accumulators
1940            ggml_prec_set_acc(cur, GGML_PREC_F32);
1941        }
1942    }
1943
1944    if (down_b) {
1945        cb(cur, "ffn_down", il);
1946    }
1947
1948    if (down_b) {
1949        cur = ggml_add(ctx0, cur, down_b);
1950    }
1951
1952    if (down_s) {
1953        cur = ggml_mul(ctx0, cur, down_s);
1954        cb(cur, "ffn_down_s", il);
1955    }
1956
1957    return cur;
1958}
1959
1960ggml_tensor * llm_graph_context::build_moe_ffn(
1961         ggml_tensor * cur,
1962         ggml_tensor * gate_inp,
1963         ggml_tensor * up_exps,
1964         ggml_tensor * gate_exps,
1965         ggml_tensor * down_exps,
1966         ggml_tensor * exp_probs_b,
1967             int64_t   n_expert,
1968             int64_t   n_expert_used,
1969     llm_ffn_op_type   type_op,
1970                bool   norm_w,
1971               float   w_scale,
1972         llama_expert_gating_func_type gating_op,
1973                 int   il,
1974         ggml_tensor * probs_in,
1975         ggml_tensor * gate_up_exps,
1976         ggml_tensor * up_exps_s,
1977         ggml_tensor * gate_exps_s,
1978         ggml_tensor * down_exps_s,
1979         ggml_tensor * selected_experts_in) const {
1980    return build_moe_ffn(
1981        cur,
1982        gate_inp,  /* gate_inp_b  */ nullptr,
1983        up_exps,   /* up_exps_b   */ nullptr,
1984        gate_exps, /* gate_exps_b */ nullptr,
1985        down_exps, /* down_exps_b */ nullptr,
1986        exp_probs_b,
1987        n_expert,
1988        n_expert_used,
1989        type_op,
1990        norm_w,
1991        w_scale,
1992        gating_op,
1993        il,
1994        probs_in,
1995        gate_up_exps,
1996        /* gate_up_exps_b */ nullptr,
1997        up_exps_s,
1998        gate_exps_s,
1999        down_exps_s,
2000        selected_experts_in
2001    );
2002}
2003
2004ggml_tensor * llm_graph_context::build_moe_ffn(
2005         ggml_tensor * cur,
2006         ggml_tensor * gate_inp,
2007         ggml_tensor * gate_inp_b,
2008         ggml_tensor * up_exps,
2009         ggml_tensor * up_exps_b,
2010         ggml_tensor * gate_exps,
2011         ggml_tensor * gate_exps_b,
2012         ggml_tensor * down_exps,
2013         ggml_tensor * down_exps_b,
2014         ggml_tensor * exp_probs_b,
2015             int64_t   n_expert,
2016             int64_t   n_expert_used,
2017     llm_ffn_op_type   type_op,
2018                bool   norm_w,
2019               float   w_scale,
2020        llama_expert_gating_func_type gating_op,
2021                 int   il,
2022         ggml_tensor * probs_in,
2023         ggml_tensor * gate_up_exps,
2024         ggml_tensor * gate_up_exps_b,
2025         ggml_tensor * up_exps_s,
2026         ggml_tensor * gate_exps_s,
2027         ggml_tensor * down_exps_s,
2028         ggml_tensor * selected_experts_in) const {
2029    const int64_t n_embd   = cur->ne[0];
2030    const int64_t n_tokens = cur->ne[1];
2031    const bool weight_before_ffn = arch == LLM_ARCH_LLAMA4; // for llama4, we apply the sigmoid-ed weights before the FFN
2032
2033    ggml_tensor * logits = nullptr;
2034
2035    if (probs_in == nullptr) {
2036        logits = build_lora_mm(gate_inp, cur); // [n_expert, n_tokens]
2037        if (gating_op == LLAMA_EXPERT_GATING_FUNC_TYPE_SQRT_SOFTPLUS) {
2038            ggml_prec_set_acc(logits, GGML_PREC_F32);
2039        }
2040        cb(logits, "ffn_moe_logits", il);
2041    } else {
2042        logits = probs_in;
2043    }
2044
2045    if (gate_inp_b) {
2046        logits = ggml_add(ctx0, logits, gate_inp_b);
2047        cb(logits, "ffn_moe_logits_biased", il);
2048    }
2049
2050    ggml_tensor * probs = nullptr;
2051    switch (gating_op) {
2052        case LLAMA_EXPERT_GATING_FUNC_TYPE_SOFTMAX:
2053            {
2054                probs = ggml_soft_max(ctx0, logits); // [n_expert, n_tokens]
2055            } break;
2056        case LLAMA_EXPERT_GATING_FUNC_TYPE_SIGMOID:
2057            {
2058                probs = ggml_sigmoid(ctx0, logits); // [n_expert, n_tokens]
2059            } break;
2060        case LLAMA_EXPERT_GATING_FUNC_TYPE_SOFTMAX_WEIGHT:
2061            {
2062                probs = logits; // [n_expert, n_tokens]
2063            } break;
2064        case LLAMA_EXPERT_GATING_FUNC_TYPE_SQRT_SOFTPLUS:
2065            {
2066                probs = ggml_sqrt(ctx0, ggml_softplus(ctx0, logits)); // [n_expert, n_tokens]
2067            } break;
2068        default:
2069            GGML_ABORT("fatal error");
2070    }
2071    cb(probs, "ffn_moe_probs", il);
2072
2073    // add experts selection bias - introduced in DeepSeek V3
2074    // leave probs unbiased as it's later used to get expert weights
2075    ggml_tensor * selection_probs = probs;
2076    if (exp_probs_b != nullptr) {
2077        selection_probs = ggml_add(ctx0, probs, exp_probs_b);
2078        cb(selection_probs, "ffn_moe_probs_biased", il);
2079    }
2080
2081    // llama4 doesn't have exp_probs_b, and sigmoid is only used after top_k
2082    // see: https://github.com/meta-llama/llama-models/blob/699a02993512fb36936b1b0741e13c06790bcf98/models/llama4/moe.py#L183-L198
2083    if (arch == LLM_ARCH_LLAMA4) {
2084        selection_probs = logits;
2085    }
2086
2087    if (arch == LLM_ARCH_GROVEMOE) {
2088        selection_probs = ggml_sigmoid(ctx0, logits); // [n_expert, n_tokens]
2089        cb(selection_probs, "ffn_moe_probs_biased", il);
2090    }
2091
2092    // select top n_group_used expert groups
2093    // https://huggingface.co/deepseek-ai/DeepSeek-V3/blob/e815299b0bcbac849fa540c768ef21845365c9eb/modeling_deepseek.py#L440-L457
2094    if (hparams.n_expert_groups > 1 && n_tokens > 0) {
2095        const int64_t n_exp_per_group = n_expert / hparams.n_expert_groups;
2096
2097        // organize experts into n_expert_groups
2098        ggml_tensor * selection_groups = ggml_reshape_3d(ctx0, selection_probs, n_exp_per_group, hparams.n_expert_groups, n_tokens); // [n_exp_per_group, n_expert_groups, n_tokens]
2099
2100        ggml_tensor * group_scores = ggml_argsort_top_k(ctx0, selection_groups, 2); // [2, n_expert_groups, n_tokens]
2101        group_scores = ggml_get_rows(ctx0, ggml_reshape_4d(ctx0, selection_groups, 1, selection_groups->ne[0], selection_groups->ne[1], selection_groups->ne[2]), group_scores); // [1, 2, n_expert_groups, n_tokens]
2102
2103        // get top n_group_used expert groups
2104        group_scores = ggml_sum_rows(ctx0, ggml_reshape_3d(ctx0, group_scores, group_scores->ne[1], group_scores->ne[2], group_scores->ne[3])); // [1, n_expert_groups, n_tokens]
2105        group_scores = ggml_reshape_2d(ctx0, group_scores, group_scores->ne[1], group_scores->ne[2]); // [n_expert_groups, n_tokens]
2106
2107        ggml_tensor * expert_groups = ggml_argsort_top_k(ctx0, group_scores, hparams.n_group_used); // [n_group_used, n_tokens]
2108        cb(expert_groups, "ffn_moe_group_topk", il);
2109
2110        // mask out the other groups
2111        selection_probs = ggml_get_rows(ctx0, selection_groups, expert_groups); // [n_exp_per_group, n_group_used, n_tokens]
2112        selection_probs = ggml_set_rows(ctx0, ggml_fill(ctx0, selection_groups, -INFINITY), selection_probs, expert_groups); // [n_exp_per_group, n_expert_groups, n_tokens]
2113        selection_probs = ggml_reshape_2d(ctx0, selection_probs, n_expert, n_tokens); // [n_expert, n_tokens]
2114        cb(selection_probs, "ffn_moe_probs_masked", il);
2115    }
2116
2117    // select experts
2118    ggml_tensor * selected_experts = selected_experts_in;
2119    if (selected_experts == nullptr) {
2120        selected_experts = ggml_argsort_top_k(ctx0, selection_probs, n_expert_used); // [n_expert_used, n_tokens]
2121        cb(selected_experts->src[0], "ffn_moe_argsort", il);
2122    }
2123    cb(selected_experts, "ffn_moe_topk", il);
2124
2125    if (arch == LLM_ARCH_GROVEMOE && n_expert != hparams.n_expert) {
2126        // TODO: Use scalar div instead when/if implemented
2127        ggml_tensor * f_sel = ggml_cast(ctx0, selected_experts, GGML_TYPE_F32);
2128        selected_experts = ggml_cast(ctx0, ggml_scale(ctx0, f_sel, 1.0f / float(hparams.n_group_experts)), GGML_TYPE_I32);
2129        probs = ggml_reshape_3d(ctx0, probs, 1, hparams.n_expert, n_tokens);
2130    } else {
2131        probs = ggml_reshape_3d(ctx0, probs, 1, n_expert, n_tokens);
2132    }
2133
2134    ggml_tensor * weights = ggml_get_rows(ctx0, probs, selected_experts); // [1, n_expert_used, n_tokens]
2135    cb(weights, "ffn_moe_weights", il);
2136
2137
2138    if (gating_op == LLAMA_EXPERT_GATING_FUNC_TYPE_SOFTMAX_WEIGHT) {
2139        weights = ggml_reshape_2d(ctx0, weights, n_expert_used, n_tokens);
2140        weights = ggml_soft_max(ctx0, weights); // [n_expert_used, n_tokens]
2141        weights = ggml_reshape_3d(ctx0, weights, 1, n_expert_used, n_tokens);
2142        cb(weights, "ffn_moe_weights_softmax", il);
2143    }
2144
2145    if (norm_w) {
2146        weights = ggml_reshape_2d(ctx0, weights, n_expert_used, n_tokens);
2147
2148        ggml_tensor * weights_sum = ggml_sum_rows(ctx0, weights); // [1, n_tokens]
2149        cb(weights_sum, "ffn_moe_weights_sum", il);
2150
2151        // Avoid division by zero, clamp to smallest number representable by F16
2152        weights_sum = ggml_clamp(ctx0, weights_sum, 6.103515625e-5, INFINITY);
2153        cb(weights_sum, "ffn_moe_weights_sum_clamped", il);
2154
2155        weights = ggml_div(ctx0, weights, weights_sum); // [n_expert_used, n_tokens]
2156        cb(weights, "ffn_moe_weights_norm", il);
2157
2158        weights = ggml_reshape_3d(ctx0, weights, 1, n_expert_used, n_tokens);
2159    }
2160    if (w_scale != 0.0f && w_scale != 1.0f) {
2161        weights = ggml_scale(ctx0, weights, w_scale);
2162        cb(weights, "ffn_moe_weights_scaled", il);
2163    }
2164
2165    //call early so that topk-moe can be used
2166    ggml_build_forward_expand(gf, weights);
2167
2168    cur = ggml_reshape_3d(ctx0, cur, n_embd, 1, n_tokens);
2169
2170    if (weight_before_ffn) {
2171        // repeat cur to [n_embd, n_expert_used, n_tokens]
2172        ggml_tensor * repeated = ggml_repeat_4d(ctx0, cur, n_embd, n_expert_used, n_tokens, 1);
2173        cur = ggml_mul(ctx0, repeated, weights);
2174        cb(cur, "ffn_moe_weighted", il);
2175    }
2176
2177    ggml_tensor * up = nullptr;
2178    ggml_tensor * experts = nullptr;
2179
2180    if (gate_up_exps) {
2181        // merged gate_up path: one mul_mat_id, then split into gate and up views
2182        ggml_tensor * gate_up = build_lora_mm_id(gate_up_exps, cur, selected_experts, up_exps_s); // [n_ff*2, n_expert_used, n_tokens]
2183        cb(gate_up, "ffn_moe_gate_up", il);
2184
2185        if (up_exps_s) {
2186            cb(gate_up, "ffn_moe_gate_up_scaled", il);
2187        }
2188
2189        if (gate_up_exps_b) {
2190            gate_up = ggml_add_id(ctx0, gate_up, gate_up_exps_b, selected_experts);
2191            cb(gate_up, "ffn_moe_gate_up_biased", il);
2192        }
2193
2194        const int64_t n_ff = gate_up->ne[0] / 2;
2195        cur = ggml_view_3d(ctx0, gate_up, n_ff, gate_up->ne[1], gate_up->ne[2], gate_up->nb[1], gate_up->nb[2], 0);
2196        cb(cur, "ffn_moe_gate", il);
2197        up  = ggml_view_3d(ctx0, gate_up, n_ff, gate_up->ne[1], gate_up->ne[2], gate_up->nb[1], gate_up->nb[2], n_ff * gate_up->nb[0]);
2198        cb(up, "ffn_moe_up", il);
2199    } else {
2200        // separate gate and up path
2201        up = build_lora_mm_id(up_exps, cur, selected_experts, up_exps_s); // [n_ff, n_expert_used, n_tokens]
2202        cb(up, "ffn_moe_up", il);
2203
2204        if (up_exps_s) {
2205            cb(up, "ffn_moe_up_scaled", il);
2206        }
2207
2208        if (up_exps_b) {
2209            up = ggml_add_id(ctx0, up, up_exps_b, selected_experts);
2210            cb(up, "ffn_moe_up_biased", il);
2211        }
2212
2213        if (gate_exps) {
2214            cur = build_lora_mm_id(gate_exps, cur, selected_experts, gate_exps_s); // [n_ff, n_expert_used, n_tokens]
2215            cb(cur, "ffn_moe_gate", il);
2216        } else {
2217            cur = up;
2218        }
2219
2220        if (gate_exps_s) {
2221            cb(cur, "ffn_moe_gate_scaled", il);
2222        }
2223
2224        if (gate_exps_b) {
2225            cur = ggml_add_id(ctx0, cur, gate_exps_b, selected_experts);
2226            cb(cur, "ffn_moe_gate_biased", il);
2227        }
2228    }
2229
2230    const bool has_gate = gate_exps || gate_up_exps;
2231
2232    switch (type_op) {
2233        case LLM_FFN_SILU:
2234            if (gate_exps) {
2235                if (il >= 0) {
2236                    const float limit = hparams.swiglu_clamp_exp[il];
2237                    constexpr float eps = 1e-6f;
2238                    if (limit > eps) {
2239                        if (arch == LLM_ARCH_MAPLE || arch == LLM_ARCH_DEEPSEEK4 || (arch == LLM_ARCH_DFLASH && hparams.dsv4_hc_mult > 0) || arch == LLM_ARCH_HY_V4) {
2240                            cur = ggml_swiglu_clamp(ctx0, cur, up, limit);
2241                        } else {
2242                            up = ggml_clamp(ctx0, up, -limit, limit);
2243                            cb(up, "ffn_moe_up_clamped", il);
2244                            ggml_tensor * gate_act = ggml_silu(ctx0, cur);
2245                            cb(gate_act, "ffn_moe_silu", il);
2246                            gate_act = ggml_clamp(ctx0, gate_act, -INFINITY, limit);
2247                            cb(gate_act, "ffn_moe_silu_clamped", il);
2248                            cur = ggml_mul(ctx0, gate_act, up);
2249                        }
2250                        cb(cur, "ffn_moe_swiglu_limited", il);
2251                        break;
2252                    }
2253                }
2254            }
2255
2256            if (has_gate) {
2257                cur = ggml_swiglu_split(ctx0, cur, up);
2258                cb(cur, "ffn_moe_swiglu", il);
2259            } else {
2260                cur = ggml_silu(ctx0, cur);
2261                cb(cur, "ffn_moe_silu", il);
2262            } break;
2263        case LLM_FFN_SITU:
2264            {
2265                // situ(gate, up) = beta*tanh(gate/beta)*sigmoid(gate) * lb*tanh(up/lb)
2266                GGML_ASSERT(has_gate);
2267                const float beta = hparams.situ_beta;
2268                const float lb   = hparams.situ_linear_beta;
2269
2270                ggml_tensor * act = ggml_scale(ctx0, ggml_tanh(ctx0, ggml_scale(ctx0, cur, 1.0f/beta)), beta);
2271                act = ggml_mul(ctx0, act, ggml_sigmoid(ctx0, cur));
2272                if (lb > 0.0f) {
2273                    up = ggml_scale(ctx0, ggml_tanh(ctx0, ggml_scale(ctx0, up, 1.0f/lb)), lb);
2274                }
2275                cur = ggml_mul(ctx0, act, up);
2276                cb(cur, "ffn_moe_situ", il);
2277            } break;
2278        case LLM_FFN_GELU:
2279            if (has_gate) {
2280                cur = ggml_geglu_split(ctx0, cur, up);
2281                cb(cur, "ffn_moe_geglu", il);
2282            } else {
2283                cur = ggml_gelu(ctx0, cur);
2284                cb(cur, "ffn_moe_gelu", il);
2285            } break;
2286        case LLM_FFN_SWIGLU_OAI_MOE:
2287            {
2288                // TODO: move to hparams?
2289                constexpr float alpha = 1.702f;
2290                constexpr float limit = 7.0f;
2291                cur = ggml_swiglu_oai(ctx0, cur, up, alpha, limit);
2292                cb(cur, "ffn_moe_swiglu_oai", il);
2293            } break;
2294        case LLM_FFN_RELU:
2295            if (has_gate) {
2296                cur = ggml_reglu_split(ctx0, cur, up);
2297                cb(cur, "ffn_moe_reglu", il);
2298            } else {
2299                cur = ggml_relu(ctx0, cur);
2300                cb(cur, "ffn_moe_relu", il);
2301            } break;
2302        case LLM_FFN_RELU_SQR:
2303            if (has_gate) {
2304                // TODO: add support for gated squared relu
2305                GGML_ABORT("fatal error: gated squared relu not implemented");
2306            } else {
2307                cur = ggml_relu(ctx0, cur);
2308                cur = ggml_sqr(ctx0, cur);
2309                cb(cur, "ffn_moe_relu_sqr", il);
2310            } break;
2311        default:
2312            GGML_ABORT("fatal error");
2313    }
2314
2315    experts = build_lora_mm_id(down_exps, cur, selected_experts, down_exps_s); // [n_embd, n_expert_used, n_tokens]
2316    cb(experts, "ffn_moe_down", il);
2317
2318    if (down_exps_s) {
2319        cb(experts, "ffn_moe_down_scaled", il);
2320    }
2321
2322    if (down_exps_b) {
2323        experts = ggml_add_id(ctx0, experts, down_exps_b, selected_experts);
2324        cb(experts, "ffn_moe_down_biased", il);
2325    }
2326
2327    if (!weight_before_ffn) {
2328        experts = ggml_mul(ctx0, experts, weights);
2329        cb(experts, "ffn_moe_weighted", il);
2330    }
2331
2332    ggml_build_forward_expand(gf, experts);
2333
2334    ggml_tensor * cur_experts[LLAMA_MAX_EXPERTS] = { nullptr };
2335
2336    assert(n_expert_used > 0);
2337
2338    // order the views before the adds
2339    // Use per-layer n_expert_used to bound the graph even during warmup (avoids
2340    // the large-add-nodes issue for uniform arches; for Puzzle the per-layer
2341    // value is correct). ref: https://github.com/ggml-org/llama.cpp/pull/14753
2342    const uint32_t n_expert_used_il = hparams.n_expert_used(il);
2343    for (uint32_t i = 0; i < n_expert_used_il; ++i) {
2344        cur_experts[i] = ggml_view_2d(ctx0, experts, n_embd, n_tokens, experts->nb[2], i*experts->nb[1]);
2345
2346        ggml_build_forward_expand(gf, cur_experts[i]);
2347    }
2348
2349    // aggregate experts
2350    ggml_tensor * moe_out = cur_experts[0];
2351
2352    for (uint32_t i = 1; i < n_expert_used_il; ++i) {
2353        moe_out = ggml_add(ctx0, moe_out, cur_experts[i]);
2354
2355        ggml_build_forward_expand(gf, moe_out);
2356    }
2357
2358    if (n_expert_used_il == 1) {
2359        // avoid returning a non-contiguous tensor
2360        moe_out = ggml_cont(ctx0, moe_out);
2361    }
2362
2363    cb(moe_out, "ffn_moe_out", il);
2364
2365    return moe_out;
2366}
2367
2368// input embeddings with optional lora
2369ggml_tensor * llm_graph_context::build_inp_embd(ggml_tensor * tok_embd) const {
2370    const int64_t n_embd_inp = hparams.n_embd_inp();
2371    const int64_t n_embd     = hparams.n_embd;
2372
2373    assert(n_embd_inp >= n_embd);
2374
2375    auto inp = std::make_unique<llm_graph_input_embd>(n_embd_inp);
2376
2377    inp->tokens = ggml_new_tensor_1d(ctx0, GGML_TYPE_I32, ubatch.n_tokens);
2378    cb(inp->tokens, "inp_tokens", -1);
2379    ggml_set_input(inp->tokens);
2380    res->t_inp_tokens = inp->tokens;
2381
2382    inp->embd = ggml_new_tensor_2d(ctx0, GGML_TYPE_F32, n_embd_inp, ubatch.n_tokens);
2383    cb(inp->embd, "inp_embd", -1);
2384    ggml_set_input(inp->embd);
2385
2386    // select one of the 2 inputs, based on the batch contents
2387    // ref: https://github.com/ggml-org/llama.cpp/pull/18550
2388    std::array<ggml_tensor *, 2> inps;
2389
2390    // token embeddings path (ubatch.token != nullptr)
2391    {
2392        auto & cur = inps[0];
2393
2394        cur = ggml_get_rows(ctx0, tok_embd, inp->tokens);
2395
2396        // apply lora for embedding tokens if needed
2397        for (const auto & lora : *loras) {
2398            llama_adapter_lora_weight * lw = lora.first->get_weight(tok_embd);
2399            if (lw == nullptr) {
2400                continue;
2401            }
2402
2403            const float adapter_scale = lora.second;
2404            const float scale = lw->get_scale(lora.first->alpha, adapter_scale);
2405
2406            ggml_tensor * inpL_delta = ggml_scale(ctx0, ggml_mul_mat(
2407                        ctx0, lw->b, // non-transposed lora_b
2408                        ggml_get_rows(ctx0, lw->a, inp->tokens)
2409                        ), scale);
2410
2411            cur = ggml_add(ctx0, cur, inpL_delta);
2412        }
2413
2414        if (n_embd_inp != n_embd) {
2415            cur = ggml_pad(ctx0, cur, hparams.n_embd_inp() - n_embd, 0, 0, 0);
2416        }
2417    }
2418
2419    // vector embeddings path (ubatch.embd != nullptr)
2420    {
2421        auto & cur = inps[1];
2422
2423        cur = inp->embd;
2424    }
2425
2426    assert(ggml_are_same_shape (inps[0], inps[1]));
2427    assert(ggml_are_same_stride(inps[0], inps[1]));
2428
2429    ggml_tensor * cur = ggml_build_forward_select(gf, inps.data(), inps.size(), ubatch.token ? 0 : 1);
2430
2431    if (n_embd_inp != n_embd) {
2432        cur = ggml_view_2d(ctx0, cur, n_embd, n_tokens, cur->nb[1], 0);
2433    }
2434
2435    res->t_inp_embd = cur;
2436
2437    // For Granite architecture
2438    // NOTE: For deepstack models, only apply scale to token inputs (ie text-only input).
2439    //  Raw embeddings are assumed to be multimodal inputs that should not be scaled.
2440    if (hparams.f_embedding_scale != 0.0f && (ubatch.token || hparams.n_deepstack_layers == 0)) {
2441        if (!ggml_is_contiguous(cur)) {
2442            cur = ggml_cont(ctx0, cur);
2443        }
2444        cur = ggml_scale(ctx0, cur, hparams.f_embedding_scale);
2445    }
2446
2447    cb(cur, "embd", -1);
2448
2449    res->add_input(std::move(inp));
2450
2451    // make sure the produced embeddings are immediately materialized in the ggml graph
2452    // ref: https://github.com/ggml-org/llama.cpp/pull/18599
2453    ggml_build_forward_expand(gf, cur);
2454
2455    return cur;
2456}
2457
2458ggml_tensor * llm_graph_context::build_inp_pos() const {
2459    auto inp = std::make_unique<llm_graph_input_pos>(hparams.n_pos_per_embd());
2460
2461    auto & cur = inp->pos;
2462
2463    cur = ggml_new_tensor_1d(ctx0, GGML_TYPE_I32, (int64_t)n_tokens*hparams.n_pos_per_embd());
2464    ggml_set_input(cur);
2465
2466    res->add_input(std::move(inp));
2467
2468    return cur;
2469}
2470
2471ggml_tensor * llm_graph_context::build_inp_attn_scale() const {
2472    auto inp = std::make_unique<llm_graph_input_attn_temp>(hparams.n_attn_temp_floor_scale, hparams.f_attn_temp_scale, hparams.f_attn_temp_offset);
2473
2474    auto & cur = inp->attn_scale;
2475
2476    // this need to be 1x1xN for broadcasting
2477    cur = ggml_new_tensor_3d(ctx0, GGML_TYPE_F32, 1, 1, n_tokens);
2478    ggml_set_input(cur);
2479    ggml_set_name(cur, "attn_scale");
2480
2481    res->add_input(std::move(inp));
2482
2483    return cur;
2484}
2485
2486ggml_tensor * llm_graph_context::build_inp_out_ids() const {
2487    // note: when all tokens are output, we could skip this optimization to spare the ggml_get_rows() calls,
2488    //       but this would make the graph topology depend on the number of output tokens, which can interfere with
2489    //       features that require constant topology such as pipeline parallelism
2490    //       ref: https://github.com/ggml-org/llama.cpp/pull/14275#issuecomment-2987424471
2491    //if (n_outputs < n_tokens) {
2492    //    return nullptr;
2493    //}
2494
2495    auto inp = std::make_unique<llm_graph_input_out_ids>(hparams, cparams, n_outputs);
2496
2497    auto & cur = inp->out_ids;
2498
2499    cur = ggml_new_tensor_1d(ctx0, GGML_TYPE_I32, n_outputs);
2500    ggml_set_input(cur);
2501
2502    res->add_input(std::move(inp));
2503
2504    return cur;
2505}
2506
2507ggml_tensor * llm_graph_context::build_inp_mean() const {
2508    auto inp = std::make_unique<llm_graph_input_mean>(cparams);
2509
2510    auto & cur = inp->mean;
2511
2512    cur = ggml_new_tensor_2d(ctx0, GGML_TYPE_F32, n_tokens, ubatch.n_seqs_unq);
2513    ggml_set_input(cur);
2514
2515    res->add_input(std::move(inp));
2516
2517    return cur;
2518}
2519
2520ggml_tensor * llm_graph_context::build_inp_cls() const {
2521    auto inp = std::make_unique<llm_graph_input_cls>(cparams, arch);
2522
2523    auto & cur = inp->cls;
2524
2525    cur = ggml_new_tensor_1d(ctx0, GGML_TYPE_I32, ubatch.n_seqs_unq);
2526    ggml_set_input(cur);
2527
2528    res->add_input(std::move(inp));
2529
2530    return cur;
2531}
2532
2533ggml_tensor * llm_graph_context::build_inp_cross_embd() const {
2534    auto inp = std::make_unique<llm_graph_input_cross_embd>(cross);
2535
2536    auto & cur = inp->cross_embd;
2537
2538    // if we have the output embeddings from the encoder, use them directly
2539    // TODO: needs more work to be correct, for now just use the tensor shape
2540    //if (cross->t_embd) {
2541    //    cur = ggml_view_tensor(ctx0, cross->t_embd);
2542
2543    //    return cur;
2544    //}
2545
2546    const auto n_embd = !cross->v_embd.empty() ? cross->n_embd : hparams.n_embd_inp();
2547    // Encoding must fit in one ubatch; do not reserve the full training context.
2548    const auto n_enc  = !cross->v_embd.empty() ? cross->n_enc  : cparams.n_ubatch;
2549
2550    cur = ggml_new_tensor_2d(ctx0, GGML_TYPE_F32, n_embd, n_enc);
2551    ggml_set_input(cur);
2552
2553    res->add_input(std::move(inp));
2554
2555    return cur;
2556}
2557
2558ggml_tensor * llm_graph_context::build_inp_pos_bucket_enc() const {
2559    auto inp = std::make_unique<llm_graph_input_pos_bucket>(hparams);
2560
2561    auto & cur = inp->pos_bucket;
2562
2563    cur = ggml_new_tensor_2d(ctx0, GGML_TYPE_I32, n_tokens, n_tokens);
2564    ggml_set_input(cur);
2565
2566    res->add_input(std::move(inp));
2567
2568    return cur;
2569}
2570
2571ggml_tensor * llm_graph_context::build_inp_pos_bucket_dec() const {
2572    const auto * mctx_cur = static_cast<const llama_kv_cache_context *>(mctx);
2573
2574    auto inp = std::make_unique<llm_graph_input_pos_bucket_kv>(hparams, mctx_cur);
2575
2576    const auto n_kv = mctx_cur->get_n_kv();
2577
2578    auto & cur = inp->pos_bucket;
2579
2580    cur = ggml_new_tensor_2d(ctx0, GGML_TYPE_I32, n_kv, n_tokens);
2581    ggml_set_input(cur);
2582
2583    res->add_input(std::move(inp));
2584
2585    return cur;
2586}
2587
2588ggml_tensor * llm_graph_context::build_pos_bias(ggml_tensor * pos_bucket, ggml_tensor * attn_rel_b) const {
2589    ggml_tensor * pos_bucket_1d = ggml_reshape_1d(ctx0, pos_bucket, pos_bucket->ne[0] * pos_bucket->ne[1]);
2590    cb(pos_bucket_1d, "pos_bucket_1d", -1);
2591
2592    ggml_tensor * pos_bias = ggml_get_rows(ctx0, attn_rel_b, pos_bucket_1d);
2593
2594    pos_bias = ggml_reshape_3d(ctx0, pos_bias, pos_bias->ne[0], pos_bucket->ne[0], pos_bucket->ne[1]);
2595    pos_bias = ggml_permute   (ctx0, pos_bias, 2, 0, 1, 3);
2596    pos_bias = ggml_cont      (ctx0, pos_bias);
2597
2598    cb(pos_bias, "pos_bias", -1);
2599
2600    return pos_bias;
2601}
2602
2603ggml_tensor * llm_graph_context::build_attn_mha(
2604         ggml_tensor * q,
2605         ggml_tensor * k,
2606         ggml_tensor * v,
2607         ggml_tensor * kq_b,
2608         ggml_tensor * kq_mask,
2609         ggml_tensor * sinks,
2610         ggml_tensor * v_mla,
2611             int64_t   n_kv_max,
2612               float   kq_scale,
2613                 int   il) const {
2614    const bool v_trans = v->nb[1] > v->nb[2];
2615
2616    // split the batch into streams if needed
2617    const auto n_stream = k->ne[3];
2618
2619    q = ggml_view_4d(ctx0, q, q->ne[0], q->ne[1], q->ne[2]/n_stream, n_stream, q->nb[1], q->nb[2], q->nb[3]/n_stream, 0);
2620
2621    q = ggml_permute(ctx0, q, 0, 2, 1, 3);
2622    k = ggml_permute(ctx0, k, 0, 2, 1, 3);
2623    v = ggml_permute(ctx0, v, 0, 2, 1, 3);
2624
2625    ggml_tensor * cur;
2626
2627    const bool use_flash_attn = cparams.flash_attn && kq_b == nullptr;
2628    if (use_flash_attn) {
2629        GGML_ASSERT(kq_b == nullptr && "Flash attention does not support KQ bias yet");
2630
2631        if (v_trans) {
2632            v = ggml_transpose(ctx0, v);
2633        }
2634
2635        // this can happen when KV cache is not used (e.g. an embedding model with non-causal attn)
2636        if (k->type == GGML_TYPE_F32) {
2637            k = ggml_cast(ctx0, k, GGML_TYPE_F16);
2638        }
2639
2640        if (v->type == GGML_TYPE_F32) {
2641            v = ggml_cast(ctx0, v, GGML_TYPE_F16);
2642        }
2643
2644        cur = ggml_flash_attn_ext(ctx0, q, k, v, kq_mask, kq_scale, hparams.f_max_alibi_bias,
2645                                  hparams.attn_soft_cap ? hparams.f_attn_logit_softcapping : 0.0f);
2646        res->add_fused_node({LLM_FUSED_OP_FLASH_ATTN, cur, il});
2647
2648        ggml_flash_attn_ext_add_sinks(cur, sinks);
2649        GGML_ASSERT(n_kv_max >= 0 && n_kv_max <= INT32_MAX);
2650        ggml_flash_attn_ext_set_n_kv_max(cur, static_cast<int32_t>(n_kv_max));
2651        ggml_prec_set_acc(cur, GGML_PREC_F32);
2652
2653        if (v_mla) {
2654#if 0
2655            // v_mla can be applied as a matrix-vector multiplication with broadcasting across dimension 3 == n_tokens.
2656            // However, the code is optimized for dimensions 0 and 1 being large, so this is inefficient.
2657            cur = ggml_reshape_4d(ctx0, cur, v_mla->ne[0], 1, n_head, n_tokens);
2658            cur = ggml_mul_mat(ctx0, v_mla, cur);
2659#else
2660            // It's preferable to do the calculation as a matrix-matrix multiplication with n_tokens in dimension 1.
2661            // The permutations are noops and only change how the tensor data is interpreted.
2662            cur = ggml_permute(ctx0, cur, 0, 2, 1, 3);
2663            cur = ggml_mul_mat(ctx0, v_mla, cur);
2664            cb(cur, "fattn_mla", il);
2665            cur = ggml_permute(ctx0, cur, 0, 2, 1, 3);
2666            cur = ggml_cont(ctx0, cur); // Needed because ggml_reshape_2d expects contiguous inputs.
2667#endif
2668        }
2669
2670        cur = ggml_reshape_2d(ctx0, cur, cur->ne[0]*cur->ne[1], cur->ne[2]*cur->ne[3]);
2671    } else {
2672        ggml_tensor * kq = ggml_mul_mat(ctx0, k, q);
2673        cb(kq, "kq", il);
2674
2675        // note: this op tends to require high floating point range
2676        //       while for some models F16 is enough, for others it is not, so we default to F32 here
2677        ggml_prec_set_acc(kq, GGML_PREC_F32);
2678
2679        if (arch == LLM_ARCH_GROK) {
2680            // need to do the following:
2681            // multiply by attn_output_multiplier
2682            // and then :
2683            // kq = 30 * tanh(kq / 30)
2684            // before the softmax below
2685
2686            kq = ggml_tanh(ctx0, ggml_scale(ctx0, kq, hparams.f_attn_out_scale / hparams.f_attn_logit_softcapping));
2687            cb(kq, "kq_tanh", il);
2688            kq = ggml_scale(ctx0, kq, hparams.f_attn_logit_softcapping);
2689            cb(kq, "kq_scaled", il);
2690        }
2691
2692        if (hparams.attn_soft_cap) {
2693            kq = ggml_scale(ctx0, kq, 1.0f / hparams.f_attn_logit_softcapping);
2694            cb(kq, "kq_scaled_1", il);
2695            kq = ggml_tanh (ctx0, kq);
2696            cb(kq, "kq_tanh", il);
2697            kq = ggml_scale(ctx0, kq, hparams.f_attn_logit_softcapping);
2698            cb(kq, "kq_scaled_2", il);
2699        }
2700
2701        if (kq_b) {
2702            kq = ggml_add(ctx0, kq, kq_b);
2703            cb(kq, "kq_plus_kq_b", il);
2704        }
2705
2706        kq = ggml_soft_max_ext(ctx0, kq, kq_mask, kq_scale, hparams.f_max_alibi_bias);
2707        ggml_soft_max_add_sinks(kq, sinks);
2708        cb(kq, "kq_soft_max", il);
2709
2710        if (!v_trans) {
2711            // note: avoid this branch
2712            v = ggml_cont(ctx0, ggml_transpose(ctx0, v));
2713            cb(v, "v_cont", il);
2714        }
2715
2716        ggml_tensor * kqv = ggml_mul_mat(ctx0, v, kq);
2717        cb(kqv, "kqv", il);
2718
2719        // for MLA with the absorption optimization, we need to "decompress" from MQA back to MHA
2720        if (v_mla) {
2721            kqv = ggml_mul_mat(ctx0, v_mla, kqv);
2722            cb(kqv, "kqv_mla", il);
2723        }
2724
2725        cur = ggml_permute(ctx0, kqv, 0, 2, 1, 3);
2726
2727        // recombine streams
2728        cur = ggml_cont_2d(ctx0, cur, cur->ne[0]*cur->ne[1], cur->ne[2]*cur->ne[3]);
2729
2730        if (!cparams.offload_kqv) {
2731            // all nodes between the KV store and the attention output are run on the CPU
2732            ggml_backend_sched_set_tensor_backend(sched, cur, backend_cpu);
2733        }
2734    }
2735
2736    ggml_build_forward_expand(gf, cur);
2737
2738    return cur;
2739}
2740
2741llm_graph_input_attn_no_cache * llm_graph_context::build_attn_inp_no_cache() const {
2742    auto inp = std::make_unique<llm_graph_input_attn_no_cache>(hparams, cparams);
2743
2744    // flash attention requires an f16 mask
2745    const auto type_mask = cparams.flash_attn ? GGML_TYPE_F16 : GGML_TYPE_F32;
2746
2747    // note: there is no KV cache, so the number of KV values is equal to the number of tokens in the batch
2748    inp->self_kq_mask = ggml_new_tensor_4d(ctx0, type_mask, n_tokens, n_tokens, 1, 1);
2749    ggml_set_input(inp->self_kq_mask);
2750
2751    inp->self_kq_mask_cnv = inp->self_kq_mask;
2752
2753    if (hparams.swa_type != LLAMA_SWA_TYPE_NONE) {
2754        inp->self_kq_mask_swa = ggml_new_tensor_4d(ctx0, type_mask, n_tokens, n_tokens, 1, 1);
2755        ggml_set_input(inp->self_kq_mask_swa);
2756
2757        inp->self_kq_mask_swa_cnv = inp->self_kq_mask_swa;
2758    } else {
2759        inp->self_kq_mask_swa     = nullptr;
2760        inp->self_kq_mask_swa_cnv = nullptr;
2761    }
2762
2763    return (llm_graph_input_attn_no_cache *) res->add_input(std::move(inp));
2764}
2765
2766ggml_tensor * llm_graph_context::build_attn(
2767        llm_graph_input_attn_no_cache * inp,
2768        ggml_tensor * wo,
2769        ggml_tensor * wo_b,
2770        ggml_tensor * wo_s,
2771        ggml_tensor * q_cur,
2772        ggml_tensor * k_cur,
2773        ggml_tensor * v_cur,
2774        ggml_tensor * kq_b,
2775        ggml_tensor * sinks,
2776        ggml_tensor * v_mla,
2777            float     kq_scale,
2778            int       il) const {
2779    GGML_UNUSED(n_tokens);
2780
2781    // these nodes are added to the graph together so that they are not reordered
2782    // by doing so, the number of splits in the graph is reduced
2783    ggml_build_forward_expand(gf, q_cur);
2784    ggml_build_forward_expand(gf, k_cur);
2785    ggml_build_forward_expand(gf, v_cur);
2786
2787    const bool is_swa = hparams.is_swa(il);
2788
2789    const auto & kq_mask = is_swa ? inp->get_kq_mask_swa() : inp->get_kq_mask();
2790
2791    // [TAG_NO_CACHE_PAD]
2792    // TODO: if ubatch.equal_seqs() == true, we can split the three tensors below into ubatch.n_seqs_unq streams
2793    //       but it might not be worth it: https://github.com/ggml-org/llama.cpp/pull/15636
2794    //assert(!ubatch.equal_seqs() || (k_cur->ne[3] == 1 && k_cur->ne[3] == ubatch.n_seqs_unq));
2795
2796    ggml_tensor * q = q_cur;
2797    ggml_tensor * k = k_cur;
2798    ggml_tensor * v = v_cur;
2799
2800    ggml_tensor * cur = build_attn_mha(q, k, v, kq_b, kq_mask, sinks, v_mla, 0, kq_scale, il);
2801    cb(cur, "kqv_out", il);
2802
2803    if (wo) {
2804        cur = build_lora_mm(wo, cur, wo_s);
2805    }
2806
2807    if (wo_b) {
2808        //cb(cur, "kqv_wo", il);
2809    }
2810
2811    if (wo_b) {
2812        cur = ggml_add(ctx0, cur, wo_b);
2813    }
2814
2815    return cur;
2816}
2817
2818static std::unique_ptr<llm_graph_input_attn_kv> build_attn_inp_kv_impl(
2819           ggml_context * ctx0,
2820     const llama_ubatch & ubatch,
2821    const llama_hparams & hparams,
2822    const llama_cparams & cparams,
2823    const llama_kv_cache_context * mctx_cur) {
2824
2825    auto inp = std::make_unique<llm_graph_input_attn_kv>(hparams, cparams, mctx_cur);
2826
2827    {
2828        GGML_ASSERT(hparams.swa_type == LLAMA_SWA_TYPE_NONE && "Use llama_kv_cache_iswa for SWA");
2829
2830        inp->self_k_idxs = mctx_cur->build_input_k_idxs(ctx0, ubatch);
2831        inp->self_v_idxs = mctx_cur->build_input_v_idxs(ctx0, ubatch);
2832
2833        inp->self_kq_mask = build_attn_inp_kq_mask(ctx0, mctx_cur, ubatch, cparams);
2834        inp->self_kq_mask_cnv = inp->self_kq_mask;
2835    }
2836
2837    inp->self_k_rot = mctx_cur->build_input_k_rot(ctx0);
2838    inp->self_v_rot = mctx_cur->build_input_v_rot(ctx0);
2839
2840    return inp;
2841}
2842
2843llm_graph_input_attn_kv * llm_graph_context::build_attn_inp_kv() const {
2844    const auto * mctx_cur = static_cast<const llama_kv_cache_context *>(mctx);
2845
2846    auto inp = build_attn_inp_kv_impl(ctx0, ubatch, hparams, cparams, mctx_cur);
2847
2848    return (llm_graph_input_attn_kv *) res->add_input(std::move(inp));
2849}
2850
2851ggml_tensor * llm_graph_context::build_attn(
2852        llm_graph_input_attn_kv * inp,
2853        ggml_tensor * wo,
2854        ggml_tensor * wo_b,
2855        ggml_tensor * wo_s,
2856        ggml_tensor * q_cur,
2857        ggml_tensor * k_cur,
2858        ggml_tensor * v_cur,
2859        ggml_tensor * kq_b,
2860        ggml_tensor * sinks,
2861        ggml_tensor * v_mla, // TODO: remove
2862            float     kq_scale,
2863            int       il) const {
2864    GGML_ASSERT(v_mla == nullptr);
2865
2866    if (inp->self_k_rot) {
2867        q_cur = llama_mul_mat_hadamard(ctx0, q_cur, inp->self_k_rot);
2868        k_cur = llama_mul_mat_hadamard(ctx0, k_cur, inp->self_k_rot);
2869    }
2870
2871    if (inp->self_v_rot) {
2872        v_cur = llama_mul_mat_hadamard(ctx0, v_cur, inp->self_v_rot);
2873    }
2874
2875    // these nodes are added to the graph together so that they are not reordered
2876    // by doing so, the number of splits in the graph is reduced
2877    // expand k later to enable rope fusion which directly writes into k-v cache
2878    ggml_build_forward_expand(gf, q_cur);
2879    ggml_build_forward_expand(gf, v_cur);
2880    ggml_build_forward_expand(gf, k_cur);
2881
2882    const auto * mctx_cur = inp->mctx;
2883
2884    // store to KV cache
2885    {
2886        const auto & k_idxs = inp->get_k_idxs();
2887        const auto & v_idxs = inp->get_v_idxs();
2888
2889        ggml_build_forward_expand(gf, mctx_cur->cpy_k(ctx0, k_cur, k_idxs, il));
2890        ggml_build_forward_expand(gf, mctx_cur->cpy_v(ctx0, v_cur, v_idxs, il));
2891    }
2892
2893    ggml_tensor * kq_mask = inp->get_kq_mask();
2894
2895    ggml_tensor * q = q_cur;
2896    ggml_tensor * k = mctx_cur->get_k(ctx0, il);
2897    ggml_tensor * v = mctx_cur->get_v(ctx0, il);
2898
2899    ggml_tensor * cur = build_attn_mha(q, k, v, kq_b, kq_mask, sinks, v_mla, 0, kq_scale, il);
2900    cb(cur, "kqv_out", il);
2901
2902    if (inp->self_v_rot) {
2903        cur = llama_mul_mat_hadamard(ctx0, cur, inp->self_v_rot);
2904    }
2905
2906    if (wo) {
2907        if (arch == LLM_ARCH_GLM4 || arch == LLM_ARCH_GLM4_MOE || arch == LLM_ARCH_JAIS2) {
2908            // GLM4, GLM4_MOE, and JAIS2 seem to have numerical issues with half-precision accumulators
2909            cur = build_lora_mm(wo, cur);
2910            ggml_prec_set_acc(cur, GGML_PREC_F32);
2911            if (wo_s) {
2912                cur = ggml_mul(ctx0, cur, wo_s);
2913            }
2914        } else {
2915            cur = build_lora_mm(wo, cur, wo_s);
2916        }
2917    }
2918
2919    if (wo_b) {
2920        cur = ggml_add(ctx0, cur, wo_b);
2921    }
2922
2923    return cur;
2924}
2925
2926static std::unique_ptr<llm_graph_input_attn_k> build_attn_inp_k_impl(
2927           ggml_context * ctx0,
2928     const llama_ubatch & ubatch,
2929    const llama_hparams & hparams,
2930    const llama_cparams & cparams,
2931    const llama_kv_cache_context * mctx_cur) {
2932
2933    auto inp = std::make_unique<llm_graph_input_attn_k>(hparams, cparams, mctx_cur);
2934
2935    {
2936        GGML_ASSERT(hparams.swa_type == LLAMA_SWA_TYPE_NONE && "Use llama_kv_cache_iswa for SWA");
2937
2938        inp->self_k_idxs = mctx_cur->build_input_k_idxs(ctx0, ubatch);
2939
2940        inp->self_kq_mask = build_attn_inp_kq_mask(ctx0, mctx_cur, ubatch, cparams);
2941        inp->self_kq_mask_cnv = inp->self_kq_mask;
2942    }
2943
2944    return inp;
2945}
2946
2947llm_graph_input_attn_k * llm_graph_context::build_attn_inp_k() const {
2948    const auto * mctx_cur = static_cast<const llama_kv_cache_context *>(mctx);
2949
2950    auto inp = build_attn_inp_k_impl(ctx0, ubatch, hparams, cparams, mctx_cur);
2951
2952    return (llm_graph_input_attn_k *) res->add_input(std::move(inp));
2953}
2954
2955ggml_tensor * llm_graph_context::build_attn(
2956        llm_graph_input_attn_k * inp,
2957        ggml_tensor * wo,
2958        ggml_tensor * wo_b,
2959        ggml_tensor * wo_s,
2960        ggml_tensor * q_cur,
2961        ggml_tensor * k_cur,
2962        ggml_tensor * v_cur,
2963        ggml_tensor * kq_b,
2964        ggml_tensor * sinks,
2965        ggml_tensor * v_mla,
2966            float     kq_scale,
2967            int       il) const {
2968    // these nodes are added to the graph together so that they are not reordered
2969    // by doing so, the number of splits in the graph is reduced
2970    // expand k later to enable rope fusion which directly writes into k-v cache
2971    ggml_build_forward_expand(gf, q_cur);
2972    ggml_build_forward_expand(gf, v_cur);
2973    ggml_build_forward_expand(gf, k_cur);
2974
2975    const auto * mctx_cur = inp->mctx;
2976
2977    // store to KV cache
2978    {
2979        const auto & k_idxs = inp->get_k_idxs();
2980
2981        ggml_build_forward_expand(gf, mctx_cur->cpy_k(ctx0, k_cur, k_idxs, il));
2982    }
2983
2984    const auto & kq_mask = inp->get_kq_mask();
2985
2986    ggml_tensor * q = q_cur;
2987    ggml_tensor * k = mctx_cur->get_k(ctx0, il);
2988    ggml_tensor * v = ggml_view_4d(ctx0, k, v_cur->ne[0], k->ne[1], k->ne[2], k->ne[3], k->nb[1], k->nb[2], k->nb[3], 0);
2989
2990    ggml_tensor * cur = build_attn_mha(q, k, v, kq_b, kq_mask, sinks, v_mla, 0, kq_scale, il);
2991    cb(cur, "kqv_out", il);
2992
2993    if (wo) {
2994        if (arch == LLM_ARCH_GLM4 || arch == LLM_ARCH_GLM4_MOE) {
2995            // GLM4 and GLM4_MOE seem to have numerical issues with half-precision accumulators
2996            cur = build_lora_mm(wo, cur);
2997            ggml_prec_set_acc(cur, GGML_PREC_F32);
2998            if (wo_s) {
2999                cur = ggml_mul(ctx0, cur, wo_s);
3000            }
3001        } else {
3002            cur = build_lora_mm(wo, cur, wo_s);
3003        }
3004    }
3005
3006    if (wo_b) {
3007        cur = ggml_add(ctx0, cur, wo_b);
3008    }
3009
3010    return cur;
3011}
3012
3013ggml_tensor * llm_graph_context::build_attn(
3014        llm_graph_input_attn_k_dsa * inp,
3015        ggml_tensor * wo,
3016        ggml_tensor * wo_b,
3017        ggml_tensor * wo_s,
3018        ggml_tensor * q_cur,
3019        ggml_tensor * k_cur,
3020        ggml_tensor * v_cur,
3021        ggml_tensor * kq_b,
3022        ggml_tensor * sinks,
3023        ggml_tensor * v_mla,
3024        ggml_tensor * top_k,
3025            float     kq_scale,
3026            int       il) const {
3027    // these nodes are added to the graph together so that they are not reordered
3028    // by doing so, the number of splits in the graph is reduced
3029    // expand k later to enable rope fusion which directly writes into k-v cache
3030    ggml_build_forward_expand(gf, q_cur);
3031    ggml_build_forward_expand(gf, v_cur);
3032    ggml_build_forward_expand(gf, k_cur);
3033
3034    const auto * mctx_cur = inp->mctx->get_mla();
3035
3036    // store to KV cache
3037    {
3038        const auto & k_idxs = inp->get_k_idxs_mla();
3039
3040        ggml_build_forward_expand(gf, mctx_cur->cpy_k(ctx0, k_cur, k_idxs, il));
3041    }
3042
3043    const auto & kq_mask = inp->get_kq_mask_mla();
3044
3045    // prepare new kq mask - starts filled with -INFINITY
3046    ggml_tensor * kq_mask_all = ggml_fill(ctx0, kq_mask, -INFINITY);
3047
3048    // reshape KQ mask into tensor with rows of size 1:
3049    // [n_kv, n_batch, 1, n_stream] -> [1, n_kv, n_batch, n_stream]
3050    kq_mask_all = ggml_view_4d(ctx0, kq_mask_all, 1, kq_mask_all->ne[0], kq_mask_all->ne[1], kq_mask_all->ne[3], kq_mask_all->nb[0], kq_mask_all->nb[1], kq_mask_all->nb[2], 0);
3051
3052    // reshape top_k indices: [n_top_k, n_batch, 1, n_stream] -> [n_top_k, n_batch, n_stream, 1]
3053    ggml_tensor * top_k_3d = ggml_view_4d(ctx0, top_k, top_k->ne[0], top_k->ne[1], top_k->ne[3], 1, top_k->nb[1], top_k->nb[2], top_k->ne[3]*top_k->nb[3], 0);
3054
3055    // prepare zero-filled tensor with rows of size 1: [1, n_top_k, n_batch, n_stream]
3056    // this will be our source of zero values for unmasking top k mask elements
3057    ggml_tensor * zeros = ggml_new_tensor_4d(ctx0, GGML_TYPE_F32, 1, top_k_3d->ne[0], top_k_3d->ne[1], top_k_3d->ne[2]);
3058    zeros = ggml_fill(ctx0, zeros, 0.0f);
3059
3060    // modify KQ mask by unmasking elements that are in top_k indices
3061    // ggml_set_rows([1, n_kv, n_batch, n_stream], [1, n_top_k, n_batch, n_stream], [n_top_k, n_batch, n_stream, 1])
3062    ggml_tensor * kq_mask_top_k = ggml_set_rows(ctx0, kq_mask_all, zeros, top_k_3d);
3063
3064    // reshape to restore the original shape of KQ mask:
3065    // [1, n_kv, n_batch, n_stream] -> [n_kv, n_batch, 1, n_stream]
3066    kq_mask_top_k = ggml_view_4d(ctx0, kq_mask_top_k, kq_mask_top_k->ne[1], kq_mask_top_k->ne[2], 1, kq_mask_top_k->ne[3], kq_mask_top_k->nb[2], kq_mask_top_k->nb[3], kq_mask_top_k->nb[3], 0);
3067
3068    // combine with the original kq mask
3069    kq_mask_top_k = ggml_add(ctx0, kq_mask_top_k, kq_mask);
3070
3071    ggml_tensor * q = q_cur;
3072    ggml_tensor * k = mctx_cur->get_k(ctx0, il);
3073    ggml_tensor * v = ggml_view_4d(ctx0, k, v_cur->ne[0], k->ne[1], k->ne[2], k->ne[3], k->nb[1], k->nb[2], k->nb[3], 0);
3074
3075    ggml_tensor * cur = build_attn_mha(q, k, v, kq_b, kq_mask_top_k, sinks, v_mla, top_k->ne[0], kq_scale, il);
3076    cb(cur, "kqv_out", il);
3077
3078    if (wo) {
3079        cur = build_lora_mm(wo, cur, wo_s);
3080    }
3081
3082    if (wo_b) {
3083        cur = ggml_add(ctx0, cur, wo_b);
3084    }
3085
3086    return cur;
3087}
3088
3089ggml_tensor * llm_graph_context::build_attn(
3090        llm_graph_input_attn_kv_iswa * inp,
3091        ggml_tensor * wo,
3092        ggml_tensor * wo_b,
3093        ggml_tensor * wo_s,
3094        ggml_tensor * q_cur,
3095        ggml_tensor * k_cur,
3096        ggml_tensor * v_cur,
3097        ggml_tensor * kq_b,
3098        ggml_tensor * sinks,
3099        ggml_tensor * v_mla,
3100            float     kq_scale,
3101            int       il) const {
3102    const bool is_swa = hparams.is_swa(il);
3103
3104    auto * k_rot = is_swa ? inp->self_k_rot_swa : inp->self_k_rot;
3105    auto * v_rot = is_swa ? inp->self_v_rot_swa : inp->self_v_rot;
3106
3107    if (k_rot) {
3108        q_cur = llama_mul_mat_hadamard(ctx0, q_cur, k_rot);
3109        if (k_cur) {
3110            k_cur = llama_mul_mat_hadamard(ctx0, k_cur, k_rot);
3111        }
3112    }
3113    if (v_rot) {
3114        if (v_cur) {
3115            v_cur = llama_mul_mat_hadamard(ctx0, v_cur, v_rot);
3116        }
3117    }
3118
3119    // these nodes are added to the graph together so that they are not reordered
3120    // by doing so, the number of splits in the graph is reduced
3121    ggml_build_forward_expand(gf, q_cur);
3122
3123    if (k_cur) {
3124        ggml_build_forward_expand(gf, k_cur);
3125    }
3126
3127    if (v_cur) {
3128        ggml_build_forward_expand(gf, v_cur);
3129    }
3130
3131    const auto * mctx_iswa = inp->mctx;
3132
3133    const auto * mctx_cur = is_swa ? mctx_iswa->get_swa() : mctx_iswa->get_base();
3134
3135    // optionally store to KV cache
3136    if (k_cur) {
3137        const auto & k_idxs = is_swa ? inp->get_k_idxs_swa() : inp->get_k_idxs();
3138
3139        ggml_build_forward_expand(gf, mctx_cur->cpy_k(ctx0, k_cur, k_idxs, il));
3140    }
3141
3142    if (v_cur) {
3143        const auto & v_idxs = is_swa ? inp->get_v_idxs_swa() : inp->get_v_idxs();
3144
3145        ggml_build_forward_expand(gf, mctx_cur->cpy_v(ctx0, v_cur, v_idxs, il));
3146    }
3147
3148    const auto & kq_mask = is_swa ? inp->get_kq_mask_swa() : inp->get_kq_mask();
3149
3150    ggml_tensor * q = q_cur;
3151    ggml_tensor * k = mctx_cur->get_k(ctx0, il);
3152    ggml_tensor * v = mctx_cur->get_v(ctx0, il);
3153
3154    ggml_tensor * cur = build_attn_mha(q, k, v, kq_b, kq_mask, sinks, v_mla, 0, kq_scale, il);
3155    cb(cur, "kqv_out", il);
3156
3157    if (v_rot) {
3158        cur = llama_mul_mat_hadamard(ctx0, cur, v_rot);
3159    }
3160
3161    if (wo) {
3162        cur = build_lora_mm(wo, cur, wo_s);
3163    }
3164
3165    if (wo_b) {
3166        //cb(cur, "kqv_wo", il);
3167    }
3168
3169    if (wo_b) {
3170        cur = ggml_add(ctx0, cur, wo_b);
3171    }
3172
3173    return cur;
3174}
3175
3176ggml_tensor * llm_graph_context::build_attn(
3177        llm_graph_input_attn_k_iswa * inp,
3178        ggml_tensor * wo,
3179        ggml_tensor * wo_b,
3180        ggml_tensor * wo_s,
3181        ggml_tensor * q_cur,
3182        ggml_tensor * k_cur,
3183        ggml_tensor * v_cur,
3184        ggml_tensor * kq_b,
3185        ggml_tensor * sinks,
3186        ggml_tensor * v_mla,
3187            float     kq_scale,
3188            int       il) const {
3189    const bool is_swa = hparams.is_swa(il);
3190
3191    auto * k_rot = is_swa ? inp->self_k_rot_swa : inp->self_k_rot;
3192
3193    if (k_rot) {
3194        q_cur = llama_mul_mat_hadamard(ctx0, q_cur, k_rot);
3195        if (k_cur) {
3196            k_cur = llama_mul_mat_hadamard(ctx0, k_cur, k_rot);
3197        }
3198    }
3199
3200    // these nodes are added to the graph together so that they are not reordered
3201    // by doing so, the number of splits in the graph is reduced
3202    ggml_build_forward_expand(gf, q_cur);
3203
3204    if (k_cur) {
3205        ggml_build_forward_expand(gf, k_cur);
3206    }
3207
3208    const auto * mctx_iswa = inp->mctx;
3209    const auto * mctx_cur = is_swa ? mctx_iswa->get_swa() : mctx_iswa->get_base();
3210
3211    // optionally store to KV cache
3212    if (k_cur) {
3213        const auto & k_idxs = is_swa ? inp->get_k_idxs_swa() : inp->get_k_idxs();
3214
3215        ggml_build_forward_expand(gf, mctx_cur->cpy_k(ctx0, k_cur, k_idxs, il));
3216    }
3217
3218    const auto & kq_mask = is_swa ? inp->get_kq_mask_swa() : inp->get_kq_mask();
3219
3220    // MLA-style attention: the cached K is used as V
3221    ggml_tensor * q = q_cur;
3222    ggml_tensor * k = mctx_cur->get_k(ctx0, il);
3223    ggml_tensor * v = ggml_view_4d(ctx0, k, v_cur->ne[0], k->ne[1], k->ne[2], k->ne[3], k->nb[1], k->nb[2], k->nb[3], 0);
3224
3225    ggml_tensor * cur = build_attn_mha(q, k, v, kq_b, kq_mask, sinks, v_mla, 0, kq_scale, il);
3226    cb(cur, "kqv_out", il);
3227
3228    if (k_rot) {
3229        cur = llama_mul_mat_hadamard(ctx0, cur, k_rot);
3230    }
3231
3232    if (wo) {
3233        cur = build_lora_mm(wo, cur, wo_s);
3234    }
3235
3236    if (wo_b) {
3237        cur = ggml_add(ctx0, cur, wo_b);
3238    }
3239
3240    return cur;
3241}
3242
3243llm_graph_input_attn_cross * llm_graph_context::build_attn_inp_cross() const {
3244    auto inp = std::make_unique<llm_graph_input_attn_cross>(cross);
3245
3246    const int32_t n_enc = !cross->v_embd.empty() ? cross->n_enc : cparams.n_ubatch;
3247
3248    // flash attention requires an f16 mask
3249    const auto type_mask = cparams.flash_attn ? GGML_TYPE_F16 : GGML_TYPE_F32;
3250
3251    inp->cross_kq_mask = ggml_new_tensor_4d(ctx0, type_mask, n_enc, n_tokens, 1, 1);
3252    ggml_set_input(inp->cross_kq_mask);
3253
3254    inp->cross_kq_mask_cnv = inp->cross_kq_mask;
3255
3256    return (llm_graph_input_attn_cross *) res->add_input(std::move(inp));
3257}
3258
3259ggml_tensor * llm_graph_context::build_attn(
3260        llm_graph_input_attn_cross * inp,
3261        ggml_tensor * wo,
3262        ggml_tensor * wo_b,
3263        ggml_tensor * wo_s,
3264        ggml_tensor * q_cur,
3265        ggml_tensor * k_cur,
3266        ggml_tensor * v_cur,
3267        ggml_tensor * kq_b,
3268        ggml_tensor * sinks,
3269        ggml_tensor * v_mla,
3270            float     kq_scale,
3271            int       il) const {
3272    // these nodes are added to the graph together so that they are not reordered
3273    // by doing so, the number of splits in the graph is reduced
3274    ggml_build_forward_expand(gf, q_cur);
3275    ggml_build_forward_expand(gf, k_cur);
3276    ggml_build_forward_expand(gf, v_cur);
3277
3278    const auto & kq_mask = inp->get_kq_mask_cross();
3279
3280    ggml_tensor * q = q_cur;
3281    ggml_tensor * k = k_cur;
3282    ggml_tensor * v = v_cur;
3283
3284    ggml_tensor * cur = build_attn_mha(q, k, v, kq_b, kq_mask, sinks, v_mla, 0, kq_scale, il);
3285    cb(cur, "kqv_out", il);
3286
3287    if (wo) {
3288        cur = build_lora_mm(wo, cur, wo_s);
3289    }
3290
3291    if (wo_b) {
3292        //cb(cur, "kqv_wo", il);
3293    }
3294
3295    if (wo_b) {
3296        cur = ggml_add(ctx0, cur, wo_b);
3297    }
3298
3299    return cur;
3300}
3301
3302static std::unique_ptr<llm_graph_input_attn_k_dsa> build_attn_inp_k_dsa_impl(
3303           ggml_context * ctx0,
3304     const llama_ubatch & ubatch,
3305    const llama_hparams & hparams,
3306    const llama_cparams & cparams,
3307    const llama_kv_cache_dsa_context * mctx_cur) {
3308
3309    auto inp = std::make_unique<llm_graph_input_attn_k_dsa>(hparams, cparams, mctx_cur);
3310
3311    {
3312        inp->self_k_idxs_mla = mctx_cur->get_mla()->build_input_k_idxs(ctx0, ubatch);
3313
3314        inp->self_kq_mask_mla = build_attn_inp_kq_mask(ctx0, mctx_cur->get_mla(), ubatch, cparams);
3315        inp->self_kq_mask_mla_cnv = inp->self_kq_mask_mla;
3316    }
3317
3318    {
3319        inp->self_k_idxs_lid = mctx_cur->get_lid()->build_input_k_idxs(ctx0, ubatch);
3320
3321        // ensure that mask type matches fused lightning indexer use (requires f16 mask)
3322        auto cparams_copy = cparams;
3323        cparams_copy.flash_attn = cparams.fused_lid;
3324
3325        inp->self_kq_mask_lid = build_attn_inp_kq_mask(ctx0, mctx_cur->get_lid(), ubatch, cparams_copy);
3326        inp->self_kq_mask_lid_cnv = inp->self_kq_mask_lid;
3327
3328        inp->self_k_rot_lid = mctx_cur->get_lid()->build_input_k_rot(ctx0);
3329    }
3330
3331    return inp;
3332}
3333
3334llm_graph_input_attn_k_dsa * llm_graph_context::build_attn_inp_k_dsa() const {
3335    const auto * mctx_cur = static_cast<const llama_kv_cache_dsa_context *>(mctx);
3336
3337    auto inp = build_attn_inp_k_dsa_impl(ctx0, ubatch, hparams, cparams, mctx_cur);
3338
3339    return (llm_graph_input_attn_k_dsa *) res->add_input(std::move(inp));
3340}
3341
3342llm_graph_input_attn_k_dsa_iswa * llm_graph_context::build_attn_inp_k_dsa_iswa() const {
3343    const auto * mctx_cur = static_cast<const llama_kv_cache_dsa_iswa_context *>(mctx);
3344
3345    auto inp_dsa = build_attn_inp_k_dsa_impl(ctx0, ubatch, hparams, cparams, mctx_cur->get_dsa());
3346
3347    // build_attn_inp_k_impl rejects SWA caches, so construct the input directly
3348    auto inp_swa = std::make_unique<llm_graph_input_attn_k>(hparams, cparams, mctx_cur->get_swa());
3349
3350    inp_swa->self_k_idxs = mctx_cur->get_swa()->build_input_k_idxs(ctx0, ubatch);
3351
3352    inp_swa->self_kq_mask = build_attn_inp_kq_mask(ctx0, mctx_cur->get_swa(), ubatch, cparams);
3353    inp_swa->self_kq_mask_cnv = inp_swa->self_kq_mask;
3354
3355    auto inp = std::make_unique<llm_graph_input_attn_k_dsa_iswa>(std::move(inp_dsa), std::move(inp_swa), mctx_cur);
3356
3357    return (llm_graph_input_attn_k_dsa_iswa *) res->add_input(std::move(inp));
3358}
3359
3360llm_graph_input_attn_kv_msa * llm_graph_context::build_attn_inp_kv_msa(bool msa_enabled) const {
3361    const auto * mctx_cur = static_cast<const llama_kv_cache_msa_context *>(mctx);
3362
3363    auto inp = std::make_unique<llm_graph_input_attn_kv_msa>(hparams, cparams, mctx_cur);
3364
3365    const auto * mctx_base = mctx_cur->get_base();
3366    const auto * mctx_idx  = mctx_cur->get_idx();
3367
3368    {
3369        GGML_ASSERT(hparams.swa_type == LLAMA_SWA_TYPE_NONE && "Use llama_kv_cache_iswa for SWA");
3370
3371        inp->self_k_idxs = mctx_base->build_input_k_idxs(ctx0, ubatch);
3372        inp->self_v_idxs = mctx_base->build_input_v_idxs(ctx0, ubatch);
3373
3374        inp->self_kq_mask = build_attn_inp_kq_mask(ctx0, mctx_base, ubatch, cparams);
3375        inp->self_kq_mask_cnv = inp->self_kq_mask;
3376    }
3377
3378    inp->self_k_rot = mctx_base->build_input_k_rot(ctx0);
3379    inp->self_v_rot = mctx_base->build_input_v_rot(ctx0);
3380
3381    if (msa_enabled) {
3382        inp->self_k_idxs_idx = mctx_idx->build_input_k_idxs(ctx0, ubatch);
3383    }
3384
3385    return (llm_graph_input_attn_kv_msa *) res->add_input(std::move(inp));
3386}
3387
3388// TODO: maybe separate the inner implementation into a separate function
3389//       like with the non-sliding window equivalent
3390//       once sliding-window hybrid caches are a thing.
3391llm_graph_input_attn_kv_iswa * llm_graph_context::build_attn_inp_kv_iswa() const {
3392    const auto * mctx_cur = static_cast<const llama_kv_cache_iswa_context *>(mctx);
3393
3394    auto inp = std::make_unique<llm_graph_input_attn_kv_iswa>(hparams, cparams, mctx_cur);
3395
3396    {
3397        inp->self_k_idxs = mctx_cur->get_base()->build_input_k_idxs(ctx0, ubatch);
3398        inp->self_v_idxs = mctx_cur->get_base()->build_input_v_idxs(ctx0, ubatch);
3399
3400        inp->self_kq_mask = build_attn_inp_kq_mask(ctx0, mctx_cur->get_base(), ubatch, cparams);
3401        inp->self_kq_mask_cnv = inp->self_kq_mask;
3402    }
3403
3404    {
3405        GGML_ASSERT(hparams.swa_type != LLAMA_SWA_TYPE_NONE && "Use llama_kv_cache for non-SWA");
3406
3407        inp->self_k_idxs_swa = mctx_cur->get_swa()->build_input_k_idxs(ctx0, ubatch);
3408        inp->self_v_idxs_swa = mctx_cur->get_swa()->build_input_v_idxs(ctx0, ubatch);
3409
3410        inp->self_kq_mask_swa = build_attn_inp_kq_mask(ctx0, mctx_cur->get_swa(), ubatch, cparams);
3411        inp->self_kq_mask_swa_cnv = inp->self_kq_mask_swa;
3412    }
3413
3414    inp->self_k_rot = mctx_cur->get_base()->build_input_k_rot(ctx0);
3415    inp->self_v_rot = mctx_cur->get_base()->build_input_v_rot(ctx0);
3416
3417    inp->self_k_rot_swa = mctx_cur->get_swa()->build_input_k_rot(ctx0);
3418    inp->self_v_rot_swa = mctx_cur->get_swa()->build_input_v_rot(ctx0);
3419
3420    return (llm_graph_input_attn_kv_iswa *) res->add_input(std::move(inp));
3421}
3422
3423llm_graph_input_attn_k_iswa * llm_graph_context::build_attn_inp_k_iswa() const {
3424    const auto * mctx_cur = static_cast<const llama_kv_cache_iswa_context *>(mctx);
3425
3426    auto inp = std::make_unique<llm_graph_input_attn_k_iswa>(hparams, cparams, mctx_cur);
3427
3428    {
3429        inp->self_k_idxs = mctx_cur->get_base()->build_input_k_idxs(ctx0, ubatch);
3430
3431        inp->self_kq_mask = build_attn_inp_kq_mask(ctx0, mctx_cur->get_base(), ubatch, cparams);
3432        inp->self_kq_mask_cnv = inp->self_kq_mask;
3433    }
3434
3435    {
3436        GGML_ASSERT(hparams.swa_type != LLAMA_SWA_TYPE_NONE && "Use llama_kv_cache for non-SWA");
3437
3438        inp->self_k_idxs_swa = mctx_cur->get_swa()->build_input_k_idxs(ctx0, ubatch);
3439
3440        inp->self_kq_mask_swa = build_attn_inp_kq_mask(ctx0, mctx_cur->get_swa(), ubatch, cparams);
3441        inp->self_kq_mask_swa_cnv = inp->self_kq_mask_swa;
3442    }
3443
3444    inp->self_k_rot = mctx_cur->get_base()->build_input_k_rot(ctx0);
3445
3446    inp->self_k_rot_swa = mctx_cur->get_swa()->build_input_k_rot(ctx0);
3447
3448    return (llm_graph_input_attn_k_iswa *) res->add_input(std::move(inp));
3449}
3450
3451llm_graph_input_dsv4 * llm_graph_context::build_inp_dsv4() const {
3452    const auto * mctx_cur = static_cast<const llama_kv_cache_dsv4_context *>(mctx);
3453    const auto * raw_ctx  = mctx_cur->get_raw();
3454
3455    auto inp_raw = std::make_unique<llm_graph_input_dsv4_raw>(cparams, raw_ctx);
3456
3457    const int64_t n_stream = mctx_cur->get_csa_plan(ubatch).n_stream;
3458
3459    GGML_ASSERT(hparams.swa_type != LLAMA_SWA_TYPE_NONE && "DSV4 expects SWA raw cache");
3460
3461    inp_raw->self_k_idxs = raw_ctx->build_input_k_idxs(ctx0, ubatch);
3462    inp_raw->self_kq_mask = dsv4_build_raw_kq_mask(ctx0, raw_ctx, ubatch, cparams, n_stream);
3463    inp_raw->self_kq_mask_cnv = inp_raw->self_kq_mask;
3464
3465    inp_raw->self_k_rot = raw_ctx->build_input_k_rot(ctx0);
3466    auto inp = std::make_unique<llm_graph_input_dsv4>(cparams, std::move(inp_raw), mctx_cur);
3467
3468    dsv4_build_comp_inputs(ctx0, inp->inp_csa, mctx_cur->get_csa_plan(ubatch), "csa", cparams, n_stream);
3469    dsv4_build_comp_inputs(ctx0, inp->inp_hca, mctx_cur->get_hca_plan(ubatch), "hca", cparams, n_stream);
3470    dsv4_build_comp_inputs(ctx0, inp->inp_lid, mctx_cur->get_lid_plan(ubatch), "lid", cparams, n_stream);
3471    inp->inp_csa.k_rot = mctx_cur->get_csa()->build_input_k_rot(ctx0);
3472    inp->inp_hca.k_rot = mctx_cur->get_hca()->build_input_k_rot(ctx0);
3473    inp->inp_lid.k_rot = mctx_cur->get_lid()->build_input_k_rot(ctx0);
3474
3475    return (llm_graph_input_dsv4 *) res->add_input(std::move(inp));
3476}
3477
3478ggml_tensor * llm_graph_context::build_rs(
3479        ggml_tensor * s,
3480        ggml_tensor * state_copy_main,
3481        ggml_tensor * state_copy_extra,
3482            int32_t   state_size,
3483            int32_t   n_seqs,
3484           uint32_t   n_rs,
3485           uint32_t   rs_head,
3486           uint32_t   rs_size,
3487            int32_t   rs_zero,
3488        const llm_graph_get_rows_fn & get_state_rows) const {
3489
3490    GGML_UNUSED(rs_size);
3491    ggml_tensor * states = ggml_reshape_2d(ctx0, s, state_size, s->ne[1]);
3492
3493    // Clear a single state which will then be copied to the other cleared states.
3494    // Note that this is a no-op when the view is zero-sized.
3495    ggml_tensor * state_zero = ggml_view_1d(ctx0, states, state_size*(rs_zero >= 0), rs_zero*states->nb[1]*(rs_zero >= 0));
3496    ggml_build_forward_expand(gf, ggml_scale_inplace(ctx0, state_zero, 0));
3497
3498    // copy states
3499    // NOTE: assuming the copy destinations are ALL contained between rs_head and rs_head + n_rs
3500    // {state_size, rs_size} -> {state_size, n_seqs}
3501    ggml_tensor * output_states = get_state_rows(ctx0, states, state_copy_main);
3502    ggml_build_forward_expand(gf, output_states);
3503
3504    // copy extra states which won't be changed further (between n_seqs and n_rs)
3505    ggml_tensor * states_extra = ggml_get_rows(ctx0, states, state_copy_extra);
3506    ggml_build_forward_expand(gf,
3507        ggml_cpy(ctx0,
3508            states_extra,
3509            ggml_view_2d(ctx0, s, state_size, (n_rs - n_seqs), s->nb[1], (rs_head + n_seqs)*s->nb[1])));
3510
3511    return output_states;
3512}
3513
3514static std::unique_ptr<llm_graph_input_rs> build_rs_inp_impl(
3515           ggml_context * ctx0,
3516     const llama_ubatch & ubatch,
3517    const llama_memory_recurrent_context * mctx_cur) {
3518
3519    auto inp = std::make_unique<llm_graph_input_rs>(mctx_cur);
3520
3521    const int64_t n_rs   = mctx_cur->get_n_rs();
3522    const int64_t n_seqs = ubatch.n_seqs;
3523
3524    inp->s_copy = ggml_new_tensor_1d(ctx0, GGML_TYPE_I32, n_rs);
3525    ggml_set_input(inp->s_copy);
3526
3527    inp->s_copy_main  = ggml_view_1d(ctx0, inp->s_copy, n_seqs, 0);
3528    inp->s_copy_extra = ggml_view_1d(ctx0, inp->s_copy, n_rs - n_seqs, n_seqs * inp->s_copy->nb[0]);
3529
3530    inp->head = mctx_cur->get_head();
3531    inp->rs_z = mctx_cur->get_rs_z();
3532
3533    return inp;
3534}
3535
3536llm_graph_input_rs * llm_graph_context::build_rs_inp() const {
3537    const auto * mctx_cur = static_cast<const llama_memory_recurrent_context *>(mctx);
3538
3539    auto inp = build_rs_inp_impl(ctx0, ubatch, mctx_cur);
3540
3541    return (llm_graph_input_rs *) res->add_input(std::move(inp));
3542}
3543
3544ggml_tensor * llm_graph_context::build_rs(
3545        llm_graph_input_rs * inp,
3546        ggml_tensor * s,
3547            int32_t   state_size,
3548            int32_t   n_seqs,
3549        const llm_graph_get_rows_fn & get_state_rows) const {
3550    const auto * kv_state = inp->mctx;
3551
3552    return build_rs(s, inp->s_copy_main, inp->s_copy_extra, state_size, n_seqs,
3553                    kv_state->get_n_rs(), kv_state->get_head(), kv_state->get_size(), kv_state->get_rs_z(),
3554                    get_state_rows);
3555}
3556
3557ggml_tensor * llm_graph_context::build_rwkv_token_shift_load(
3558    llm_graph_input_rs * inp,
3559    const llama_ubatch & ubatch,
3560                   int   il) const {
3561    const auto * mctx_cur = static_cast<const llama_memory_recurrent_context *>(mctx);
3562
3563    const auto token_shift_count = hparams.token_shift_count;
3564
3565    const int64_t n_seqs  = ubatch.n_seqs;
3566
3567    ggml_tensor * token_shift_all = mctx_cur->get_r_l(il);
3568
3569    ggml_tensor * token_shift = build_rs(
3570            inp, token_shift_all,
3571            hparams.n_embd_r(), n_seqs);
3572
3573    token_shift = ggml_reshape_3d(ctx0, token_shift, hparams.n_embd, token_shift_count, n_seqs);
3574
3575    return token_shift;
3576}
3577
3578ggml_tensor * llm_graph_context::build_rwkv_token_shift_store(
3579         ggml_tensor * token_shift,
3580  const llama_ubatch & ubatch,
3581                 int   il) const {
3582    const auto * mctx_cur = static_cast<const llama_memory_recurrent_context *>(mctx);
3583
3584    const auto token_shift_count = hparams.token_shift_count;
3585    const auto n_embd = hparams.n_embd;
3586
3587    const int64_t n_seqs = ubatch.n_seqs;
3588
3589    const auto kv_head = mctx_cur->get_head();
3590
3591    return ggml_cpy(
3592        ctx0,
3593        ggml_view_1d(ctx0, token_shift, n_embd * n_seqs * token_shift_count, 0),
3594        ggml_view_1d(ctx0, mctx_cur->get_r_l(il), hparams.n_embd_r()*n_seqs, hparams.n_embd_r()*kv_head*ggml_element_size(mctx_cur->get_r_l(il)))
3595    );
3596}
3597
3598llm_graph_input_mem_hybrid * llm_graph_context::build_inp_mem_hybrid() const {
3599    const auto * mctx_cur = static_cast<const llama_memory_hybrid_context *>(mctx);
3600
3601    auto inp_rs   = build_rs_inp_impl     (ctx0, ubatch, mctx_cur->get_recr());
3602    auto inp_attn = build_attn_inp_kv_impl(ctx0, ubatch, hparams, cparams, mctx_cur->get_attn());
3603
3604    auto inp = std::make_unique<llm_graph_input_mem_hybrid>(cparams, std::move(inp_attn), std::move(inp_rs), mctx_cur);
3605
3606    return (llm_graph_input_mem_hybrid *) res->add_input(std::move(inp));
3607}
3608
3609llm_graph_input_mem_hybrid_k * llm_graph_context::build_inp_mem_hybrid_k() const {
3610    const auto * mctx_cur = static_cast<const llama_memory_hybrid_context *>(mctx);
3611
3612    auto inp_rs   = build_rs_inp_impl     (ctx0, ubatch, mctx_cur->get_recr());
3613    auto inp_attn = build_attn_inp_k_impl(ctx0, ubatch, hparams, cparams, mctx_cur->get_attn());
3614
3615    auto inp = std::make_unique<llm_graph_input_mem_hybrid_k>(cparams, std::move(inp_attn), std::move(inp_rs), mctx_cur);
3616
3617    return (llm_graph_input_mem_hybrid_k *) res->add_input(std::move(inp));
3618}
3619
3620llm_graph_input_mem_hybrid_iswa * llm_graph_context::build_inp_mem_hybrid_iswa() const {
3621    const auto * mctx_cur = static_cast<const llama_memory_hybrid_iswa_context *>(mctx);
3622
3623    auto inp_rs = build_rs_inp_impl(ctx0, ubatch, mctx_cur->get_recr());
3624
3625    // build iswa attention input
3626    const auto * attn_ctx = mctx_cur->get_attn();
3627
3628    auto inp_attn = std::make_unique<llm_graph_input_attn_kv_iswa>(hparams, cparams, attn_ctx);
3629
3630    {
3631        inp_attn->self_k_idxs = attn_ctx->get_base()->build_input_k_idxs(ctx0, ubatch);
3632        inp_attn->self_v_idxs = attn_ctx->get_base()->build_input_v_idxs(ctx0, ubatch);
3633
3634        inp_attn->self_kq_mask = build_attn_inp_kq_mask(ctx0, attn_ctx->get_base(), ubatch, cparams);
3635        inp_attn->self_kq_mask_cnv = inp_attn->self_kq_mask;
3636    }
3637
3638    {
3639        inp_attn->self_k_idxs_swa = attn_ctx->get_swa()->build_input_k_idxs(ctx0, ubatch);
3640        inp_attn->self_v_idxs_swa = attn_ctx->get_swa()->build_input_v_idxs(ctx0, ubatch);
3641
3642        inp_attn->self_kq_mask_swa = build_attn_inp_kq_mask(ctx0, attn_ctx->get_swa(), ubatch, cparams);
3643        inp_attn->self_kq_mask_swa_cnv = inp_attn->self_kq_mask_swa;
3644    }
3645
3646    auto inp = std::make_unique<llm_graph_input_mem_hybrid_iswa>(cparams, std::move(inp_attn), std::move(inp_rs), mctx_cur);
3647
3648    return (llm_graph_input_mem_hybrid_iswa *) res->add_input(std::move(inp));
3649}
3650
3651void llm_graph_context::build_dense_out(
3652    ggml_tensor * dense_2,
3653    ggml_tensor * dense_2_b,
3654    ggml_tensor * dense_3) const {
3655    if (!cparams.embeddings || !(dense_2 || dense_2_b || dense_3)) {
3656        return;
3657    }
3658    ggml_tensor * cur = res->t_embd_pooled != nullptr ? res->t_embd_pooled : res->t_embd;
3659    GGML_ASSERT(cur != nullptr && "missing t_embd_pooled/t_embd");
3660
3661    if (dense_2) {
3662        cur = ggml_mul_mat(ctx0, dense_2, cur);
3663    }
3664    if (dense_2_b) {
3665        cur = ggml_add(ctx0, cur, dense_2_b);
3666    }
3667    if (dense_3) {
3668        cur = ggml_mul_mat(ctx0, dense_3, cur);
3669    }
3670    cb(cur, "result_embd_pooled", -1);
3671    res->t_embd_pooled = cur;
3672    ggml_build_forward_expand(gf, cur);
3673}
3674
3675
3676void llm_graph_context::build_pooling(
3677        ggml_tensor * cls,
3678        ggml_tensor * cls_b,
3679        ggml_tensor * cls_out,
3680        ggml_tensor * cls_out_b,
3681        ggml_tensor * cls_norm) const {
3682    if (!cparams.embeddings) {
3683        return;
3684    }
3685
3686    ggml_tensor * inp = res->t_embd;
3687
3688    //// find result_norm tensor for input
3689    //for (int i = ggml_graph_n_nodes(gf) - 1; i >= 0; --i) {
3690    //    inp = ggml_graph_node(gf, i);
3691    //    if (strcmp(inp->name, "result_norm") == 0 || strcmp(inp->name, "result_embd") == 0) {
3692    //        break;
3693    //    }
3694
3695    //    inp = nullptr;
3696    //}
3697
3698    GGML_ASSERT(inp != nullptr && "missing result_norm/result_embd tensor");
3699
3700    ggml_tensor * cur;
3701
3702    switch (pooling_type) {
3703        case LLAMA_POOLING_TYPE_NONE:
3704            {
3705                cur = inp;
3706            } break;
3707        case LLAMA_POOLING_TYPE_MEAN:
3708            {
3709                ggml_tensor * inp_mean = build_inp_mean();
3710                cur = ggml_mul_mat(ctx0, ggml_cont(ctx0, ggml_transpose(ctx0, inp)), inp_mean);
3711            } break;
3712        case LLAMA_POOLING_TYPE_CLS:
3713        case LLAMA_POOLING_TYPE_LAST:
3714            {
3715                ggml_tensor * inp_cls = build_inp_cls();
3716                cur = ggml_get_rows(ctx0, inp, inp_cls);
3717            } break;
3718        case LLAMA_POOLING_TYPE_RANK:
3719            {
3720                if (arch == LLM_ARCH_MODERN_BERT) {
3721                    // modern bert gte reranker builds mean first then applies prediction head and classifier
3722                    // https://github.com/huggingface/transformers/blob/main/src/transformers/models/modernbert/modular_modernbert.py#L1404-1411
3723                    ggml_tensor * inp_mean = build_inp_mean();
3724                    cur = ggml_mul_mat(ctx0, ggml_cont(ctx0, ggml_transpose(ctx0, inp)), inp_mean);
3725                } else {
3726                    ggml_tensor * inp_cls = build_inp_cls();
3727                    cur = ggml_get_rows(ctx0, inp, inp_cls);
3728                }
3729
3730                // classification head
3731                // https://github.com/huggingface/transformers/blob/5af7d41e49bbfc8319f462eb45253dcb3863dfb7/src/transformers/models/roberta/modeling_roberta.py#L1566
3732                if (cls) {
3733                    cur = ggml_mul_mat(ctx0, cls, cur);
3734                    if (cls_b) {
3735                        cur = ggml_add(ctx0, cur, cls_b);
3736                    }
3737                    if (arch == LLM_ARCH_MODERN_BERT) {
3738                        cur = ggml_gelu(ctx0, cur);
3739                    } else {
3740                        cur = ggml_tanh(ctx0, cur);
3741                    }
3742                    if (cls_norm) {
3743                        // head norm
3744                        cur = build_norm(cur, cls_norm, NULL, LLM_NORM, -1);
3745                    }
3746                }
3747
3748                // some models don't have `cls_out`, for example: https://huggingface.co/jinaai/jina-reranker-v1-tiny-en
3749                // https://huggingface.co/jinaai/jina-reranker-v1-tiny-en/blob/cb5347e43979c3084a890e3f99491952603ae1b7/modeling_bert.py#L884-L896
3750                // Single layer classification head (direct projection)
3751                // https://github.com/huggingface/transformers/blob/f4fc42216cd56ab6b68270bf80d811614d8d59e4/src/transformers/models/bert/modeling_bert.py#L1476
3752                if (cls_out) {
3753                    cur = ggml_mul_mat(ctx0, cls_out, cur);
3754                    if (cls_out_b) {
3755                        cur = ggml_add(ctx0, cur, cls_out_b);
3756                    }
3757                }
3758
3759                // softmax for qwen3 reranker
3760                if (arch == LLM_ARCH_QWEN3 || arch == LLM_ARCH_QWEN3VL) {
3761                    cur = ggml_soft_max(ctx0, cur);
3762                }
3763            } break;
3764        default:
3765            {
3766                GGML_ABORT("unknown pooling type");
3767            }
3768    }
3769
3770    cb(cur, "result_embd_pooled", -1);
3771    res->t_embd_pooled = cur;
3772
3773    ggml_build_forward_expand(gf, cur);
3774}
3775
3776void llm_graph_context::build_sampling() const {
3777    if (samplers.empty() || !res->t_logits) {
3778        return;
3779    }
3780
3781    std::array<ggml_tensor *, 2> outs;
3782    outs[0] = res->t_logits;
3783
3784    auto inp_sampling = std::make_unique<llm_graph_input_sampling>(samplers);
3785    res->add_input(std::move(inp_sampling));
3786
3787    std::map<llama_seq_id, std::vector<uint32_t>> sampling_rows;
3788    uint32_t n_rows = 0;
3789    for (uint32_t i = 0; i < ubatch.n_tokens; ++i) {
3790        if (ubatch.output[i]) {
3791            sampling_rows[ubatch.seq_id[i][0]].push_back(n_rows++);
3792        }
3793    }
3794
3795    res->t_sampled.resize(n_rows, nullptr);
3796    res->t_sampled_probs.resize(n_rows, nullptr);
3797    res->t_sampled_logits.resize(n_rows, nullptr);
3798    res->t_candidates.resize(n_rows, nullptr);
3799
3800    // res->t_logits will contain logits for all tokens that want the logits calculated (logits=1 or output=1)
3801    GGML_ASSERT(res->t_logits != nullptr && "missing t_logits tensor");
3802
3803    // add a dummy row to keep the single-output graph static regardless of active samplers
3804    // multi-output graphs can still vary with the number of output rows
3805    ggml_tensor * logits_t = ggml_pad(ctx0, res->t_logits, 0, 1, 0, 0);
3806
3807    for (const auto & entry : samplers) {
3808        if (entry.second->iface->backend_reset) {
3809            entry.second->iface->backend_reset(entry.second);
3810        }
3811    }
3812
3813    static const std::vector<uint32_t> dummy_row = { 0 };
3814
3815    for (const auto & [seq_id, sampler] : samplers) {
3816        const auto it = sampling_rows.find(seq_id);
3817
3818        // inactive samplers always work on the first row
3819        const bool active = it != sampling_rows.end();
3820        const auto & rows = active ? it->second : dummy_row;
3821        const int i_out   = active ? 1          : 0;
3822
3823        for (uint32_t i = 0; i < rows.size(); ++i) {
3824            ggml_tensor * logits_seq = ggml_view_1d(ctx0, logits_t, logits_t->ne[0], rows[i] * logits_t->nb[1]);
3825            ggml_format_name(logits_seq, "logits_seq_%d_%u", seq_id, i);
3826
3827            struct llama_sampler_data data = {
3828                /*.logits       =*/ logits_seq,
3829                /*.probs        =*/ nullptr,
3830                /*.sampled      =*/ nullptr,
3831                /*.candidates   =*/ nullptr,
3832            };
3833
3834            assert(sampler->iface->backend_apply);
3835            sampler->iface->backend_apply(sampler, ctx0, gf, &data);
3836
3837            if (data.sampled != nullptr) {
3838                if (active) {
3839                    res->t_sampled[rows[i]] = data.sampled;
3840                }
3841                outs[1] = data.sampled;
3842                ggml_build_forward_select(gf, outs.data(), outs.size(), i_out);
3843            }
3844
3845            if (data.probs != nullptr) {
3846                if (active) {
3847                    res->t_sampled_probs[rows[i]] = data.probs;
3848                }
3849                outs[1] = data.probs;
3850                ggml_build_forward_select(gf, outs.data(), outs.size(), i_out);
3851            }
3852
3853            if (data.logits != nullptr) {
3854                if (active) {
3855                    res->t_sampled_logits[rows[i]] = data.logits;
3856                }
3857                outs[1] = data.logits;
3858                ggml_build_forward_select(gf, outs.data(), outs.size(), i_out);
3859            }
3860
3861            if (data.candidates != nullptr) {
3862                if (active) {
3863                    res->t_candidates[rows[i]] = data.candidates;
3864                }
3865                outs[1] = data.candidates;
3866                ggml_build_forward_select(gf, outs.data(), outs.size(), i_out);
3867            }
3868        }
3869    }
3870
3871    // TODO: Call backend_accept after all samplers have been applied.
3872    /*
3873    for (const auto & [seq_id, sampler] : samplers) {
3874        const auto it = sampling_rows.find(seq_id);
3875        if (it == sampling_rows.end()) {
3876            continue;
3877        }
3878
3879        for (uint32_t row : it->second) {
3880            ggml_tensor * selected_token = res->t_sampled[row];
3881            if (selected_token != nullptr && sampler->iface->backend_accept) {
3882                sampler->iface->backend_accept(sampler, ctx0, gf, selected_token);
3883            }
3884        }
3885    }
3886    */
3887}
3888
3889int32_t llama_relative_position_bucket(llama_pos x, llama_pos y, uint64_t n_buckets, bool bidirectional) {
3890    // TODO move to hparams if a T5 variant appears that uses a different value
3891    const int64_t max_distance = 128;
3892
3893    if (bidirectional) {
3894        n_buckets >>= 1;
3895    }
3896
3897    const int64_t max_exact = n_buckets >> 1;
3898
3899    int32_t relative_position = x - y;
3900    int32_t relative_bucket = 0;
3901
3902    if (bidirectional) {
3903        relative_bucket += (relative_position > 0) * n_buckets;
3904        relative_position = std::abs(relative_position);
3905    } else {
3906        relative_position = -std::min<int32_t>(relative_position, 0);
3907    }
3908
3909    int32_t relative_position_if_large = floorf(max_exact + logf(1.0 * relative_position / max_exact) * (n_buckets - max_exact) / log(1.0 * max_distance / max_exact));
3910    relative_position_if_large = std::min<int32_t>(relative_position_if_large, n_buckets - 1);
3911    relative_bucket += (relative_position < max_exact ? relative_position : relative_position_if_large);
3912
3913    return relative_bucket;
3914}