Team Ai
Datasetpublic

echodict/llama.cpp

version https://git-lfs.github.com/spec/v1 oid sha256:cfc44b7ba25614df70e6b65e3341cae0310163bd32fd31a6b928a542df433faf size 30786

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes479downloads
llama-graph.h1065 linesDownload Raw Back to src
1#pragma once2 3#include "llama-arch.h"4#include "llama-batch.h"5#include "llama-hparams.h"6#include "llama-adapter.h"7 8#include <cstdint>9#include <vector>10#include <memory>11#include <set>12#include <functional>13#include <map>14 15struct ggml_cgraph;16struct ggml_context;17struct ggml_tensor;18 19struct llama_cparams;20struct llama_layer;21 22struct llama_memory_context_i;23 24class llama_kv_cache_context;25class llama_kv_cache_iswa_context;26class llama_memory_recurrent_context;27class llama_memory_hybrid_context;28class llama_memory_hybrid_iswa_context;29 30// certain models (typically multi-modal) can produce different types of graphs31enum llm_graph_type {32    LLM_GRAPH_TYPE_DEFAULT,33    LLM_GRAPH_TYPE_ENCODER,34    LLM_GRAPH_TYPE_DECODER,35};36 37enum llm_ffn_op_type {38    LLM_FFN_SILU,39    LLM_FFN_GELU,40    LLM_FFN_RELU,41    LLM_FFN_RELU_SQR,42    LLM_FFN_SWIGLU,43    LLM_FFN_GEGLU,44    LLM_FFN_REGLU,45    LLM_FFN_SWIGLU_OAI_MOE,46};47 48enum llm_ffn_gate_type {49    LLM_FFN_SEQ,50    LLM_FFN_PAR, // ffn_gate is parallel to ffn_up51};52 53enum llm_norm_type {54    LLM_NORM,55    LLM_NORM_RMS,56    LLM_NORM_GROUP,57};58 59// TODO: tmp - need something better to pass the data from the encoder to the decoder60struct llama_cross {61    // the output embeddings from the encoder as a ggml tensor62    // TODO: this needs more work to be correct, for now copy the embeddings data to host memory63    //       ref: https://github.com/ggml-org/llama.cpp/pull/11213#discussion_r196989252464    //ggml_tensor * t_embd = nullptr;65 66    int64_t n_embd = 0;67    int64_t n_enc  = 0;68 69    // embeddings data copied to host memory (tmp)70    std::vector<float> v_embd;71 72    // needed to construct the cross-attention mask in the decoder73    std::vector<std::set<llama_seq_id>> seq_ids_enc;74};75 76struct llm_graph_params;77 78//79// llm_graph_input80//81 82class llm_graph_input_i {83public:84    llm_graph_input_i() {85        const char * LLAMA_GRAPH_INPUT_DEBUG = getenv("LLAMA_GRAPH_INPUT_DEBUG");86        debug = LLAMA_GRAPH_INPUT_DEBUG ? atoi(LLAMA_GRAPH_INPUT_DEBUG) : 0;87    }88 89    virtual ~llm_graph_input_i() = default;90 91    virtual void set_input(const llama_ubatch * ubatch) = 0;92 93    // return true if the resulting input tensors using the provided graph parameters would be94    //   the same as the previous input tensors that we have currently stored in the object95    virtual bool can_reuse(const llm_graph_params & params) {96        // returning false here by default will prevent from reusing the graph if the check97        //   for the input type has not been implemented yet98        GGML_UNUSED(params);99        return false;100    }101protected:102    // env: LLAMA_GRAPH_INPUT_DEBUG103    int debug = 0;104};105 106using llm_graph_input_ptr = std::unique_ptr<llm_graph_input_i>;107 108class llm_graph_input_embd : public llm_graph_input_i {109public:110    llm_graph_input_embd(int64_t n_embd) : n_embd(n_embd) {}111    virtual ~llm_graph_input_embd() = default;112 113    void set_input(const llama_ubatch * ubatch) override;114 115    bool can_reuse(const llm_graph_params & params) override;116 117    ggml_tensor * tokens = nullptr; // I32 [n_batch]118    ggml_tensor * embd   = nullptr; // F32 [n_embd, n_batch]119 120    const int64_t n_embd = 0;121};122 123class llm_graph_input_pos : public llm_graph_input_i {124public:125    llm_graph_input_pos(uint32_t n_pos_per_embd) : n_pos_per_embd(n_pos_per_embd) {}126    virtual ~llm_graph_input_pos() = default;127 128    void set_input(const llama_ubatch * ubatch) override;129 130    bool can_reuse(const llm_graph_params & params) override;131 132    ggml_tensor * pos = nullptr; // I32 [n_batch]133 134    const uint32_t n_pos_per_embd = 1;135};136 137// temperature tuning, used by llama4138class llm_graph_input_attn_temp : public llm_graph_input_i {139public:140    llm_graph_input_attn_temp(uint32_t n_attn_temp_floor_scale, float f_attn_temp_scale, float f_attn_temp_offset)141        : n_attn_temp_floor_scale(n_attn_temp_floor_scale), f_attn_temp_scale(f_attn_temp_scale), f_attn_temp_offset(f_attn_temp_offset) {}142    virtual ~llm_graph_input_attn_temp() = default;143 144    void set_input(const llama_ubatch * ubatch) override;145 146    ggml_tensor * attn_scale = nullptr; // F32 [n_batch]147 148    const uint32_t n_attn_temp_floor_scale;149    const float    f_attn_temp_scale;150    const float    f_attn_temp_offset;151};152 153class llm_graph_input_pos_bucket : public llm_graph_input_i {154public:155    llm_graph_input_pos_bucket(const llama_hparams & hparams) : hparams(hparams) {}156    virtual ~llm_graph_input_pos_bucket() = default;157 158    void set_input(const llama_ubatch * ubatch) override;159 160    ggml_tensor * pos_bucket = nullptr; // I32 [n_batch, n_batch]161 162    const llama_hparams hparams;163};164 165class llm_graph_input_pos_bucket_kv : public llm_graph_input_i {166public:167    llm_graph_input_pos_bucket_kv(168            const llama_hparams & hparams,169            const llama_kv_cache_context * mctx) : hparams(hparams), mctx(mctx) {}170    virtual ~llm_graph_input_pos_bucket_kv() = default;171 172    void set_input(const llama_ubatch * ubatch) override;173 174    ggml_tensor * pos_bucket = nullptr; // I32 [n_kv, n_batch]175 176    const llama_hparams hparams;177 178    const llama_kv_cache_context * mctx;179};180 181class llm_graph_input_out_ids : public llm_graph_input_i {182public:183    llm_graph_input_out_ids(184            const llama_hparams & hparams,185            const llama_cparams & cparams,186            uint32_t n_outputs) : hparams(hparams), cparams(cparams), n_outputs(n_outputs) {}187    virtual ~llm_graph_input_out_ids() = default;188 189    void set_input(const llama_ubatch * ubatch) override;190 191    bool can_reuse(const llm_graph_params & params) override;192 193    ggml_tensor * out_ids; // I32 [n_outputs]194 195    const llama_hparams hparams;196    const llama_cparams cparams;197 198    const uint32_t n_outputs;199};200 201class llm_graph_input_mean : public llm_graph_input_i {202public:203    llm_graph_input_mean(const llama_cparams & cparams) : cparams(cparams) {}204    virtual ~llm_graph_input_mean() = default;205 206    void set_input(const llama_ubatch * ubatch) override;207 208    ggml_tensor * mean; // F32 [n_batch, n_batch]209 210    const llama_cparams cparams;211};212 213class llm_graph_input_cls : public llm_graph_input_i {214public:215    llm_graph_input_cls(const llama_cparams & cparams, const llm_arch arch) : cparams(cparams), arch(arch) {}216    virtual ~llm_graph_input_cls() = default;217 218    void set_input(const llama_ubatch * ubatch) override;219 220    ggml_tensor * cls; // I32 [n_batch]221 222    const llama_cparams cparams;223    const llm_arch arch;224};225 226class llm_graph_input_rs : public llm_graph_input_i {227public:228    llm_graph_input_rs(const llama_memory_recurrent_context * mctx) : mctx(mctx) {}229    virtual ~llm_graph_input_rs() = default;230 231    void set_input(const llama_ubatch * ubatch) override;232 233    bool can_reuse(const llm_graph_params & params) override;234 235    ggml_tensor * s_copy;  // I32 [n_rs]236 237    // views of s_copy, computed once per graph238    // and shared across layers which use build_rs239    ggml_tensor * s_copy_main;   // I32 [n_seqs]240    ggml_tensor * s_copy_extra;  // I32 [n_rs - n_seqs]241 242    const llama_memory_recurrent_context * mctx;243 244    // used in view offsets, need to match for valid graph reuse245    uint32_t head;246    int32_t rs_z;247};248 249class llm_graph_input_cross_embd : public llm_graph_input_i {250public:251    llm_graph_input_cross_embd(252            const llama_cross * cross) : cross(cross) {}253    virtual ~llm_graph_input_cross_embd() = default;254 255    void set_input(const llama_ubatch * ubatch) override;256 257    ggml_tensor * cross_embd; // F32 [n_embd, n_outputs_enc]258 259    const llama_cross * cross;260};261 262class llm_graph_input_attn_no_cache : public llm_graph_input_i {263public:264    llm_graph_input_attn_no_cache(const llama_hparams & hparams, const llama_cparams & cparams) :265        hparams(hparams),266        cparams(cparams) {267    }268    ~llm_graph_input_attn_no_cache() = default;269 270    void set_input(const llama_ubatch * ubatch) override;271 272    ggml_tensor * get_kq_mask()     const { return self_kq_mask_cnv; }273    ggml_tensor * get_kq_mask_swa() const { return self_kq_mask_swa_cnv; }274 275    // n_tokens == n_batch276    ggml_tensor * self_kq_mask         = nullptr; // F32 [n_tokens, n_batch/n_stream, 1, n_stream]277    ggml_tensor * self_kq_mask_cnv     = nullptr; //     [n_tokens, n_batch/n_stream, 1, n_stream]278    ggml_tensor * self_kq_mask_swa     = nullptr; // F32 [n_tokens, n_batch/n_stream, 1, n_stream]279    ggml_tensor * self_kq_mask_swa_cnv = nullptr; //     [n_tokens, n_batch/n_stream, 1, n_stream]280 281    const llama_hparams hparams;282    const llama_cparams cparams;283};284 285class llm_graph_input_attn_kv : public llm_graph_input_i {286public:287    llm_graph_input_attn_kv(288            const llama_hparams & hparams,289            const llama_cparams & cparams,290            const llama_kv_cache_context * mctx) :291        hparams(hparams),292        cparams(cparams),293        mctx(mctx) {294    }295    ~llm_graph_input_attn_kv() = default;296 297    void set_input(const llama_ubatch * ubatch) override;298 299    bool can_reuse(const llm_graph_params & params) override;300 301    ggml_tensor * get_k_idxs() const { return self_k_idxs; }302    ggml_tensor * get_v_idxs() const { return self_v_idxs; }303 304    ggml_tensor * get_kq_mask() const { return self_kq_mask_cnv; }305 306    ggml_tensor * self_k_idxs = nullptr; // I64 [n_batch]307    ggml_tensor * self_v_idxs = nullptr; // I64 [n_batch] or [n_batch*n_embd_v_gqa]308 309    ggml_tensor * self_kq_mask     = nullptr; // F32 [n_kv, n_batch/n_stream, 1, n_stream]310    ggml_tensor * self_kq_mask_cnv = nullptr; //     [n_kv, n_batch/n_stream, 1, n_stream]311 312    // note: assumes v_rot^2 == I313    ggml_tensor * self_k_rot = nullptr;314    ggml_tensor * self_v_rot = nullptr;315 316    // note: these have to be copies because in order to be able to reuse a graph, its inputs317    //       need to carry these parameters with them. otherwise, they can point to freed318    //       llm_graph_params from a previous batch, causing stack-use-after-return319    const llama_hparams hparams;320    const llama_cparams cparams;321 322    const llama_kv_cache_context * mctx;323};324 325// V-less input for the KV cache326// ref: https://github.com/ggml-org/llama.cpp/pull/19067327class llm_graph_input_attn_k : public llm_graph_input_i {328public:329    llm_graph_input_attn_k(330            const llama_hparams & hparams,331            const llama_cparams & cparams,332            const llama_kv_cache_context * mctx) :333        hparams(hparams),334        cparams(cparams),335        mctx(mctx) {336    }337    ~llm_graph_input_attn_k() = default;338 339    void set_input(const llama_ubatch * ubatch) override;340 341    bool can_reuse(const llm_graph_params & params) override;342 343    ggml_tensor * get_k_idxs() const { return self_k_idxs; }344 345    ggml_tensor * get_kq_mask() const { return self_kq_mask_cnv; }346 347    ggml_tensor * self_k_idxs = nullptr; // I64 [n_batch]348 349    ggml_tensor * self_kq_mask     = nullptr; // F32 [n_kv, n_batch/n_stream, 1, n_stream]350    ggml_tensor * self_kq_mask_cnv = nullptr; //     [n_kv, n_batch/n_stream, 1, n_stream]351 352    const llama_hparams hparams;353    const llama_cparams cparams;354 355    const llama_kv_cache_context * mctx;356};357 358class llm_graph_input_attn_kv_iswa : public llm_graph_input_i {359public:360    llm_graph_input_attn_kv_iswa(361            const llama_hparams & hparams,362            const llama_cparams & cparams,363            const llama_kv_cache_iswa_context * mctx) :364        hparams(hparams),365        cparams(cparams),366        mctx(mctx) {367    }368    ~llm_graph_input_attn_kv_iswa() = default;369 370    void set_input(const llama_ubatch * ubatch) override;371 372    bool can_reuse(const llm_graph_params & params) override;373 374    ggml_tensor * get_k_idxs()     const { return self_k_idxs; }375    ggml_tensor * get_v_idxs()     const { return self_v_idxs; }376    ggml_tensor * get_k_idxs_swa() const { return self_k_idxs_swa; }377    ggml_tensor * get_v_idxs_swa() const { return self_v_idxs_swa; }378 379    ggml_tensor * get_kq_mask()     const { return self_kq_mask_cnv; }380    ggml_tensor * get_kq_mask_swa() const { return self_kq_mask_swa_cnv; }381 382    ggml_tensor * self_k_idxs     = nullptr; // I64 [n_batch]383    ggml_tensor * self_v_idxs     = nullptr; // I64 [n_batch] or [n_batch*n_embd_v_gqa]384    ggml_tensor * self_k_idxs_swa = nullptr; // I64 [n_batch]385    ggml_tensor * self_v_idxs_swa = nullptr; // I64 [n_batch] or [n_batch*n_embd_v_gqa]386 387    ggml_tensor * self_kq_mask         = nullptr; // F32 [n_kv, n_batch/n_stream, 1, n_stream]388    ggml_tensor * self_kq_mask_cnv     = nullptr; //     [n_kv, n_batch/n_stream, 1, n_stream]389    ggml_tensor * self_kq_mask_swa     = nullptr; // F32 [n_kv, n_batch/n_stream, 1, n_stream]390    ggml_tensor * self_kq_mask_swa_cnv = nullptr; //     [n_kv, n_batch/n_stream, 1, n_stream]391 392    ggml_tensor * self_k_rot = nullptr;393    ggml_tensor * self_v_rot = nullptr;394 395    ggml_tensor * self_k_rot_swa = nullptr;396    ggml_tensor * self_v_rot_swa = nullptr;397 398    const llama_hparams hparams;399    const llama_cparams cparams;400 401    const llama_kv_cache_iswa_context * mctx;402};403 404class llm_graph_input_attn_cross : public llm_graph_input_i {405public:406    llm_graph_input_attn_cross(const llama_cross * cross) : cross(cross) {}407    ~llm_graph_input_attn_cross() = default;408 409    void set_input(const llama_ubatch * ubatch) override;410 411    ggml_tensor * get_kq_mask_cross() const { return cross_kq_mask_cnv; }412 413    ggml_tensor * cross_kq_mask     = nullptr; // F32 [n_outputs_enc, n_batch, 1, 1]414    ggml_tensor * cross_kq_mask_cnv = nullptr; // F32 [n_outputs_enc, n_batch, 1, 1]415 416    const llama_cross * cross = nullptr;417};418 419class llm_graph_input_mem_hybrid : public llm_graph_input_i {420public:421    llm_graph_input_mem_hybrid(422            const llama_cparams & cparams,423            std::unique_ptr<llm_graph_input_attn_kv> inp_attn,424            std::unique_ptr<llm_graph_input_rs>      inp_rs,425            const llama_memory_hybrid_context *      mctx) :426        inp_attn(std::move(inp_attn)),427        inp_rs(std::move(inp_rs)),428        cparams(cparams),429        mctx(mctx) { }430    virtual ~llm_graph_input_mem_hybrid() = default;431 432    void set_input(const llama_ubatch * ubatch) override;433 434    bool can_reuse(const llm_graph_params & params) override;435 436    std::unique_ptr<llm_graph_input_attn_kv> inp_attn;437    std::unique_ptr<llm_graph_input_rs>      inp_rs;438 439    llm_graph_input_attn_kv * get_attn() const { return inp_attn.get(); }440    llm_graph_input_rs      * get_recr() const { return inp_rs.get(); }441 442    const llama_cparams cparams;443 444    const llama_memory_hybrid_context * mctx;445};446 447class llm_graph_input_mem_hybrid_k : public llm_graph_input_i {448public:449    llm_graph_input_mem_hybrid_k(450            const llama_cparams & cparams,451            std::unique_ptr<llm_graph_input_attn_k> inp_attn,452            std::unique_ptr<llm_graph_input_rs>      inp_rs,453            const llama_memory_hybrid_context *      mctx) :454        inp_attn(std::move(inp_attn)),455        inp_rs(std::move(inp_rs)),456        cparams(cparams),457        mctx(mctx) { }458    virtual ~llm_graph_input_mem_hybrid_k() = default;459 460    void set_input(const llama_ubatch * ubatch) override;461 462    bool can_reuse(const llm_graph_params & params) override;463 464    std::unique_ptr<llm_graph_input_attn_k> inp_attn;465    std::unique_ptr<llm_graph_input_rs>      inp_rs;466 467    llm_graph_input_attn_k * get_attn() const { return inp_attn.get(); }468    llm_graph_input_rs      * get_recr() const { return inp_rs.get(); }469 470    const llama_cparams cparams;471 472    const llama_memory_hybrid_context * mctx;473};474 475class llm_graph_input_mem_hybrid_iswa : public llm_graph_input_i {476public:477    llm_graph_input_mem_hybrid_iswa(478            const llama_cparams & cparams,479            std::unique_ptr<llm_graph_input_attn_kv_iswa> inp_attn,480            std::unique_ptr<llm_graph_input_rs>          inp_rs,481            const llama_memory_hybrid_iswa_context *     mctx) :482        inp_attn(std::move(inp_attn)),483        inp_rs(std::move(inp_rs)),484        cparams(cparams),485        mctx(mctx) { }486    virtual ~llm_graph_input_mem_hybrid_iswa() = default;487 488    void set_input(const llama_ubatch * ubatch) override;489 490    bool can_reuse(const llm_graph_params & params) override;491 492    std::unique_ptr<llm_graph_input_attn_kv_iswa> inp_attn;493    std::unique_ptr<llm_graph_input_rs>          inp_rs;494 495    llm_graph_input_attn_kv_iswa * get_attn() const { return inp_attn.get(); }496    llm_graph_input_rs           * get_recr() const { return inp_rs.get(); }497 498    const llama_cparams cparams;499 500    const llama_memory_hybrid_iswa_context * mctx;501};502 503class llm_graph_input_sampling : public llm_graph_input_i {504public:505    llm_graph_input_sampling(std::map<llama_seq_id, llama_sampler *> samplers) :506        samplers(std::move(samplers)) { }507    virtual ~llm_graph_input_sampling() = default;508 509    void set_input(const llama_ubatch * ubatch) override;510    bool can_reuse(const llm_graph_params & params) override;511 512    std::map<llama_seq_id, llama_sampler *> samplers;513};514 515//516// llm_graph_result517//518 519// these objects deliver the result from the graph build process back to the llama_context520// note that the input tensors created for the graph are referenced here - the goal is to be able to populate their521//   specific data, by calling the set_inputs() method522// along with the input tensors, the object also provides commonly used outputs tensors, such as logits, embeddings, etc.523//   these are used by the llama_context to extact the relevant data, based on the compute parameters524 525// callback that allows us to apply custom logic to each tensor (e.g. ggml-alloc, offloading, etc.)526using llm_graph_cb = std::function<void(const llama_ubatch & ubatch, ggml_tensor * cur, const char * name, int il)>;527 528class llm_graph_result;529 530struct llm_graph_params {531    llm_arch arch = LLM_ARCH_UNKNOWN;532 533    llama_hparams hparams;534    llama_cparams cparams;535 536    llama_ubatch ubatch; // note: intentionally make a copy537 538    llm_graph_type gtype;539 540    ggml_backend_sched_t sched;541    ggml_backend_t backend_cpu;542 543    const llama_adapter_cvec     * cvec;544    const llama_adapter_loras    * loras;545    const llama_memory_context_i * mctx;546    const llama_cross            * cross;547 548    std::map<llama_seq_id, llama_sampler *> samplers;549 550    static bool samplers_equal(551          const std::map<llama_seq_id, llama_sampler *> & lhs,552          const std::map<llama_seq_id, llama_sampler *> & rhs) {553        if (lhs.size() != rhs.size()) {554            return false;555        }556        for (const auto & [seq_id, sampler] : lhs) {557            auto it = rhs.find(seq_id);558            if (it == rhs.end() || it->second != sampler) {559                return false;560            }561        }562        return true;563    }564 565    uint32_t n_outputs;566 567    llm_graph_cb cb;568 569    llm_graph_result * res;570 571    // return true if the "other" params would result in a graph with the same topology as with the current params572    //   having the same topology allows us to reuse the graph in some cases573    bool allow_reuse(const llm_graph_params & other) const {574        // first check the ubatch575        bool can_reuse_ubatch =576            ubatch.equal_seqs() == other.ubatch.equal_seqs() &&577            ubatch.n_tokens     == other.ubatch.n_tokens &&578            ubatch.n_seq_tokens == other.ubatch.n_seq_tokens &&579            ubatch.n_seqs       == other.ubatch.n_seqs &&580            ubatch.n_seqs_unq   == other.ubatch.n_seqs_unq &&581            (582                (!ubatch.token && !other.ubatch.token) ||583                (!ubatch.embd  && !other.ubatch.embd)584            );585 586        // when we split the batch using "equal_seqs" we have to verify that the participating sequences are the same587        //   the reason is because the set of attention streams would be different for different sequences588        if (can_reuse_ubatch && ubatch.equal_seqs()) {589            if (!ubatch.data) {590                // if the old ubatch does not own it's data, then we cannot guarantee that it is still alive, and591                //   therefore we cannot perform the sequence id check. normally should never happen592                can_reuse_ubatch = false;593            } else {594                for (uint32_t s = 0; s < ubatch.n_seqs_unq; ++s) {595                    can_reuse_ubatch &= ubatch.seq_id_unq[s] == other.ubatch.seq_id_unq[s];596                }597            }598        }599 600        if (!can_reuse_ubatch) {601            return false;602        }603 604        if (n_outputs != other.n_outputs) {605            return false;606        }607 608        if (!samplers_equal(samplers, other.samplers)) {609            return false;610        }611 612        if (samplers.size() > 0) {613            if (!ubatch.data || !other.ubatch.data) {614                return false;615            }616 617            // check that the outputs are the same for all samplers618            for (uint32_t i = 0; i < ubatch.n_tokens; ++i) {619                if (ubatch.output[i]    != other.ubatch.output[i] ||620                    ubatch.seq_id[i][0] != other.ubatch.seq_id[i][0]) {621                    return false;622                }623            }624        }625 626        return627            cparams.embeddings  == other.cparams.embeddings  &&628            cparams.causal_attn == other.cparams.causal_attn &&629            arch  == other.arch  &&630            gtype == other.gtype &&631            cvec  == other.cvec  &&632            loras == other.loras &&633            cross == other.cross;634    }635};636 637class llm_graph_result {638public:639    llm_graph_result(int64_t max_nodes);640 641    virtual ~llm_graph_result() = default;642 643    ggml_tensor * get_inp_tokens()  const { return t_inp_tokens; }644    ggml_tensor * get_logits()      const { return t_logits; }645    ggml_tensor * get_embd()        const { return t_embd; }646    ggml_tensor * get_embd_pooled() const { return t_embd_pooled; }647 648    ggml_cgraph  * get_gf()  const { return gf; }649    ggml_context * get_ctx() const { return ctx_compute.get(); }650 651    int64_t get_max_nodes() const;652 653    void reset();654 655    void set_inputs(const llama_ubatch * ubatch);656    void set_outputs();657 658    // try to update the existing graph result using the new graph parameters in order to reuse it659    // this can only be done if we determine that the resulting graph using the new graph parameters660    //   would be identical to the existing graph. in that case, we simply have to update the memory661    //   contexts of the input tensors of the graph and we can reuse it for another computation662    // return true if the graph was updated and can be reused663    bool can_reuse(const llm_graph_params & params);664 665    llm_graph_input_i * add_input(llm_graph_input_ptr input);666 667    void set_params(const llm_graph_params & params);668 669    // important graph nodes670    ggml_tensor * t_inp_tokens  = nullptr;671    ggml_tensor * t_inp_embd    = nullptr; // [n_embd_inp, n_tokens]672    ggml_tensor * t_logits      = nullptr;673    ggml_tensor * t_embd        = nullptr;674    ggml_tensor * t_embd_pooled = nullptr;675 676    std::map<llama_seq_id, ggml_tensor*> t_sampled_logits;677    std::map<llama_seq_id, ggml_tensor*> t_candidates;678    std::map<llama_seq_id, ggml_tensor*> t_sampled;679    std::map<llama_seq_id, ggml_tensor*> t_sampled_probs;680 681    std::vector<llm_graph_input_ptr> inputs;682 683    ggml_context_ptr ctx_compute;684 685    // memory buffers used to evaluate the model686    std::vector<uint8_t> buf_compute_meta;687 688    ggml_cgraph * gf;689 690    int64_t max_nodes;691 692private:693    // keep a copy of the previous graph parameters694    // we will use this to determine whether the graph can be reused by comparing them with the new parameters695    // note: these are updated after constructing the new graph696    llm_graph_params params;697 698    // env: LLAMA_GRAPH_RESULT_DEBUG699    int debug = 0;700};701 702using llm_graph_result_ptr = std::unique_ptr<llm_graph_result>;703 704//705// llm_graph_context706//707 708// used in build_rs to properly order writes and avoid unnecessary copies709using llm_graph_get_rows_fn = std::function<ggml_tensor * (ggml_context *, ggml_tensor * states, ggml_tensor * ids)>;710 711struct llm_graph_qkv {712    ggml_tensor * q; // [n_embd_head, n_head,    n_tokens]713    ggml_tensor * k; // [n_embd_head, n_head_kv, n_tokens]714    ggml_tensor * v; // [n_embd_head, n_head_kv, n_tokens]715};716 717struct llm_graph_context {718    const llm_arch arch;719 720    const llama_hparams & hparams;721    const llama_cparams & cparams;722    const llama_ubatch  & ubatch;723 724    const int64_t n_embd;725    const int64_t n_layer;726    const int64_t n_rot;727    const int64_t n_ctx;       // user-specified context size (can be different from n_ctx_train)728    const int64_t n_head;729    const int64_t n_head_kv;730    const int64_t n_embd_head_k;731    const int64_t n_embd_k_gqa;732    const int64_t n_embd_head_v;733    const int64_t n_embd_v_gqa;734    const int64_t n_expert;735    const int64_t n_expert_used;736 737    const float freq_base;738    const float freq_scale;739    const float ext_factor;740    const float attn_factor;741    const float beta_fast;742    const float beta_slow;743    const float norm_eps;744    const float norm_rms_eps;745 746    const int64_t n_tokens;747    const int64_t n_outputs;748    const int32_t n_ctx_orig; // yarn749 750    const enum llama_pooling_type pooling_type;751    const enum llama_rope_type    rope_type;752 753    ggml_backend_sched_t sched;754 755    ggml_backend_t backend_cpu; // TODO: needed by build_attn_mha, figure out a way to remove?756 757    const llama_adapter_cvec     * cvec;758    const llama_adapter_loras    * loras;759    const llama_memory_context_i * mctx;760    const llama_cross            * cross;761 762    std::map<llama_seq_id, llama_sampler *> samplers;763 764    const llm_graph_cb & cb_func;765 766    llm_graph_result * res;767 768    ggml_context * ctx0 = nullptr;769    ggml_cgraph  * gf   = nullptr;770 771    llm_graph_context(const llm_graph_params & params);772    virtual ~llm_graph_context() = default;773 774    void cb(ggml_tensor * cur, const char * name, int il) const;775 776    //777    // common778    //779 780    ggml_tensor * build_cvec(781             ggml_tensor * cur,782                     int   il) const;783 784    // do mat_mul, while optionally apply lora and per-tensor scale785    ggml_tensor * build_lora_mm(786              ggml_tensor * w,787              ggml_tensor * cur,788              ggml_tensor * w_s = nullptr) const;789 790    // do mat_mul_id, while optionally apply lora791    ggml_tensor * build_lora_mm_id(792              ggml_tensor * w,   // ggml_tensor * as793              ggml_tensor * cur, // ggml_tensor * b794              ggml_tensor * ids) const;795 796    ggml_tensor * build_norm(797             ggml_tensor * cur,798             ggml_tensor * mw,799             ggml_tensor * mb,800           llm_norm_type   type,801                     int   il) const;802 803 804    // compute Q, K, V projections with optional bias and reshape805    // supports both fused wqkv and separate wq/wk/wv paths806    llm_graph_qkv build_qkv(807        const llama_layer & layer,808              ggml_tensor * cur,809                  int64_t   n_embd_head,810                  int64_t   n_head,811                  int64_t   n_head_kv,812                      int   il) const;813 814    ggml_tensor * build_ffn(815             ggml_tensor * cur,816             ggml_tensor * up,817             ggml_tensor * up_b,818             ggml_tensor * up_s,819             ggml_tensor * gate,820             ggml_tensor * gate_b,821             ggml_tensor * gate_s,822             ggml_tensor * down,823             ggml_tensor * down_b,824             ggml_tensor * down_s,825             ggml_tensor * act_scales,826         llm_ffn_op_type   type_op,827       llm_ffn_gate_type   type_gate,828                     int   il) const;829 830    // build MoE FFN without bias tensors831    ggml_tensor * build_moe_ffn(832             ggml_tensor * cur,833             ggml_tensor * gate_inp,834             ggml_tensor * up_exps,835             ggml_tensor * gate_exps,836             ggml_tensor * down_exps,837             ggml_tensor * exp_probs_b,838                 int64_t   n_expert,839                 int64_t   n_expert_used,840         llm_ffn_op_type   type_op,841                    bool   norm_w,842                   float   w_scale,843            llama_expert_gating_func_type gating_op,844                     int   il,845             ggml_tensor * probs_in = nullptr,846             ggml_tensor * gate_up_exps = nullptr,847             ggml_tensor * up_exps_s = nullptr,848             ggml_tensor * gate_exps_s = nullptr,849             ggml_tensor * down_exps_s = nullptr) const;850 851    ggml_tensor * build_moe_ffn(852             ggml_tensor * cur,853             ggml_tensor * gate_inp,854             ggml_tensor * gate_inp_b,855             ggml_tensor * up_exps,856             ggml_tensor * up_exps_b,857             ggml_tensor * gate_exps,858             ggml_tensor * gate_exps_b,859             ggml_tensor * down_exps,860             ggml_tensor * down_exps_b,861             ggml_tensor * exp_probs_b,862                 int64_t   n_expert,863                 int64_t   n_expert_used,864         llm_ffn_op_type   type_op,865                    bool   norm_w,866                   float   w_scale,867            llama_expert_gating_func_type gating_op,868                     int   il,869             ggml_tensor * probs_in = nullptr,870             ggml_tensor * gate_up_exps = nullptr,871             ggml_tensor * gate_up_exps_b = nullptr,872             ggml_tensor * up_exps_s = nullptr,873             ggml_tensor * gate_exps_s = nullptr,874             ggml_tensor * down_exps_s = nullptr) const;875 876    //877    // inputs878    //879 880    ggml_tensor * build_inp_embd(ggml_tensor * tok_embd) const;881    ggml_tensor * build_inp_pos() const;882    ggml_tensor * build_inp_attn_scale() const;883    ggml_tensor * build_inp_out_ids() const;884    ggml_tensor * build_inp_mean() const;885    ggml_tensor * build_inp_cls() const;886 887    ggml_tensor * build_inp_cross_embd() const;888    ggml_tensor * build_inp_pos_bucket_enc() const;889    ggml_tensor * build_inp_pos_bucket_dec() const;890    ggml_tensor * build_pos_bias(ggml_tensor * pos_bucket, ggml_tensor * attn_rel_b) const;891 892    //893    // attention894    //895 896    ggml_tensor * build_attn_mha(897            ggml_tensor * q,       // [n_embd_head_q, n_head_q, n_tokens]898            ggml_tensor * k,       // [n_embd_head_k, n_head_k, n_tokens]899            ggml_tensor * v,       // [n_embd_head_v, n_head_v, n_tokens] (v_trans == false)900            ggml_tensor * kq_b,901            ggml_tensor * kq_mask,902            ggml_tensor * sinks,   // [n_head_q]903            ggml_tensor * v_mla,   // [n_embd_head_v_mla, n_embd_head_v, n_head_v]904                  float   kq_scale,905                    int   il) const;906 907    llm_graph_input_attn_no_cache * build_attn_inp_no_cache() const;908 909    ggml_tensor * build_attn(910            llm_graph_input_attn_no_cache * inp,911            ggml_tensor * wo,912            ggml_tensor * wo_b,913            ggml_tensor * wo_s,914            ggml_tensor * q_cur, // [n_embd_head_q, n_head_q, n_tokens]915            ggml_tensor * k_cur, // [n_embd_head_k, n_head_k, n_tokens]916            ggml_tensor * v_cur, // [n_embd_head_v, n_head_v, n_tokens]917            ggml_tensor * kq_b,918            ggml_tensor * sinks, // [n_head_q]919            ggml_tensor * v_mla, // [n_embd_head_v_mla, n_embd_head_v, n_head_v]920                  float   kq_scale,921                    int   il) const;922 923    llm_graph_input_attn_kv * build_attn_inp_kv() const;924 925    ggml_tensor * build_attn(926            llm_graph_input_attn_kv * inp,927            ggml_tensor * wo,928            ggml_tensor * wo_b,929            ggml_tensor * wo_s,930            ggml_tensor * q_cur, // [n_embd_head_q, n_head_q, n_tokens]931            ggml_tensor * k_cur, // [n_embd_head_k, n_head_k, n_tokens]932            ggml_tensor * v_cur, // [n_embd_head_v, n_head_v, n_tokens]933            ggml_tensor * kq_b,934            ggml_tensor * sinks, // [n_head_q]935            ggml_tensor * v_mla, // [n_embd_head_v_mla, n_embd_head_v, n_head_v] // TODO: remove936                  float   kq_scale,937                    int   il) const;938 939    llm_graph_input_attn_k  * build_attn_inp_k() const;940 941    ggml_tensor * build_attn(942            llm_graph_input_attn_k * inp,943            ggml_tensor * wo,944            ggml_tensor * wo_b,945            ggml_tensor * wo_s,946            ggml_tensor * q_cur, // [n_embd_head_q, n_head_q, n_tokens]947            ggml_tensor * k_cur, // [n_embd_head_k, n_head_k, n_tokens]948            ggml_tensor * v_cur, // [n_embd_head_v, n_head_v, n_tokens]949            ggml_tensor * kq_b,950            ggml_tensor * sinks, // [n_head_q]951            ggml_tensor * v_mla, // [n_embd_head_v_mla, n_embd_head_v, n_head_v]952                  float   kq_scale,953                    int   il) const;954 955    llm_graph_input_attn_kv_iswa * build_attn_inp_kv_iswa() const;956 957    // note: if k_cur or v_cur are not provided, they will not be stored in the memory958    ggml_tensor * build_attn(959            llm_graph_input_attn_kv_iswa * inp,960            ggml_tensor * wo,961            ggml_tensor * wo_b,962            ggml_tensor * wo_s,963            ggml_tensor * q_cur, // [n_embd_head_q, n_head_q, n_tokens]964            ggml_tensor * k_cur, // [n_embd_head_k, n_head_k, n_tokens] optional965            ggml_tensor * v_cur, // [n_embd_head_v, n_head_v, n_tokens] optional966            ggml_tensor * kq_b,967            ggml_tensor * sinks, // [n_head_q]968            ggml_tensor * v_mla, // [n_embd_head_v_mla, n_embd_head_v, n_head_v]969                  float   kq_scale,970                    int   il) const;971 972    llm_graph_input_attn_cross * build_attn_inp_cross() const;973 974    ggml_tensor * build_attn(975            llm_graph_input_attn_cross * inp,976            ggml_tensor * wo,977            ggml_tensor * wo_b,978            ggml_tensor * wo_s,979            ggml_tensor * q_cur, // [n_embd_head_q, n_head_q, n_tokens]980            ggml_tensor * k_cur, // [n_embd_head_k, n_head_k, n_tokens]981            ggml_tensor * v_cur, // [n_embd_head_v, n_head_v, n_tokens]982            ggml_tensor * kq_b,983            ggml_tensor * sinks, // [n_head_q]984            ggml_tensor * v_mla, // [n_embd_head_v_mla, n_embd_head_v, n_head_v]985                  float   kq_scale,986                    int   il) const;987 988    //989    // recurrent990    //991 992    // TODO: move this implementation to llama_memory_recurrent.993    //       this is analogous to llama_kv_cache::cpy_k / cpy_v994    //       when moving, avoid passing `ggml_cgraph` - only pass `ggml_context`. would likely need to split the995    //         implementation in 2 separate methods. the goal is to avoid calling `ggml_build_forward_expand` in996    //         `llama_memory_recurrent`997    ggml_tensor * build_rs(998            ggml_tensor * s,999            ggml_tensor * state_copy_main,1000            ggml_tensor * state_copy_extra,1001                int32_t   state_size,1002                int32_t   n_seqs,1003               uint32_t   n_rs,1004               uint32_t   rs_head,1005               uint32_t   rs_size,1006                int32_t   rs_zero,1007            const llm_graph_get_rows_fn & get_state_rows = ggml_get_rows) const;1008 1009    llm_graph_input_rs * build_rs_inp() const;1010 1011    ggml_tensor * build_rs(1012            llm_graph_input_rs * inp,1013            ggml_tensor * s,1014                int32_t   state_size,1015                int32_t   n_seqs,1016            const llm_graph_get_rows_fn & get_state_rows = ggml_get_rows) const;1017 1018    ggml_tensor * build_rwkv_token_shift_load(1019        llm_graph_input_rs * inp,1020        const llama_ubatch & ubatch,1021                       int   il) const;1022 1023    ggml_tensor * build_rwkv_token_shift_store(1024             ggml_tensor * token_shift,1025      const llama_ubatch & ubatch,1026                     int   il) const;1027    //1028    // hybrid1029    //1030 1031    llm_graph_input_mem_hybrid * build_inp_mem_hybrid() const;1032    llm_graph_input_mem_hybrid_k * build_inp_mem_hybrid_k() const;1033 1034    llm_graph_input_mem_hybrid_iswa * build_inp_mem_hybrid_iswa() const;1035 1036    //1037    // pooling1038    //1039 1040    void build_pooling(1041            ggml_tensor * cls,1042            ggml_tensor * cls_b,1043            ggml_tensor * cls_out,1044            ggml_tensor * cls_out_b,1045            ggml_tensor * cls_norm) const;1046 1047    //1048    // sampling (backend sampling)1049    //1050 1051    void build_sampling() const;1052 1053    //1054    // dense (out)1055    //1056 1057    void build_dense_out(1058            ggml_tensor * dense_2,1059            ggml_tensor * dense_2_b,1060            ggml_tensor * dense_3) const;1061};1062 1063// TODO: better name1064int32_t llama_relative_position_bucket(llama_pos x, llama_pos y, uint64_t n_buckets, bool bidirectional);1065