char-fork/llama.cpp

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

Daniel Hanqwen4exp: fix seq_cp, block position keying, mtmd input, cuda abort, add tests (#27941)36b101543

char/aliceai-t5-moe
6.1 KiB160 linesraw
1#pragma once
2
3#include "llama-memory-hybrid.h"
4
5#include <memory>
6#include <vector>
7
8//
9// llama_memory_hybrid_idx
10//
11
12// llama_memory_hybrid plus a third cache with one indexer key per token, for block-sparse attention (qwen4exp QSA)
13// the indexer is a side buffer over the attention cells: same size, padding, streams and slots, so cell j is one token in both
14
15class llama_memory_hybrid_idx : public llama_memory_hybrid {
16public:
17    llama_memory_hybrid_idx(
18        const llama_model & model,
19                            /* attn */
20                ggml_type   type_k,
21                ggml_type   type_v,
22                     bool   v_trans,
23                 uint32_t   kv_size,
24                 uint32_t   n_pad,
25                 uint32_t   n_swa,
26           llama_swa_type   swa_type,
27                            /* recurrent */
28                ggml_type   type_r,
29                ggml_type   type_s,
30                 uint32_t   rs_size,
31                            /* common */
32                 uint32_t   n_seq_max,
33                 uint32_t   n_rs_seq,
34                     bool   offload,
35                     bool   unified,
36                            /* layer filters */
37    const layer_filter_cb & filter_attn,
38    const layer_filter_cb & filter_recr,
39                            /* the indexer cache exists only if this is given */
40    const layer_filter_cb & filter_idx);
41
42    ~llama_memory_hybrid_idx() = default;
43
44    //
45    // llama_memory_i
46    //
47
48    llama_memory_context_ptr init_batch(
49            llama_batch_allocr & balloc,
50            uint32_t n_ubatch,
51            bool embd_all) override;
52
53    llama_memory_context_ptr init_full() override;
54
55    llama_memory_context_ptr init_update(llama_context * lctx, bool optimize) override;
56
57    void clear(bool data) override;
58
59    bool seq_rm  (llama_seq_id seq_id,                              llama_pos p0, llama_pos p1) override;
60    void seq_cp  (llama_seq_id seq_id_src, llama_seq_id seq_id_dst, llama_pos p0, llama_pos p1) override;
61    void seq_keep(llama_seq_id seq_id)                                                          override;
62    void seq_add (llama_seq_id seq_id,                              llama_pos p0, llama_pos p1, llama_pos shift) override;
63    void seq_div (llama_seq_id seq_id,                              llama_pos p0, llama_pos p1, int d) override;
64
65    std::map<ggml_backend_buffer_type_t, size_t> memory_breakdown() const override;
66
67    // state write/load
68
69    void state_write(llama_io_write_i & io, llama_seq_id seq_id = -1, llama_state_seq_flags flags = 0) const override;
70    void state_read (llama_io_read_i  & io, llama_seq_id seq_id = -1, llama_state_seq_flags flags = 0)       override;
71
72    //
73    // llama_memory_hybrid_idx specific API
74    //
75
76    llama_kv_cache * get_mem_idx() const;   // nullptr when the model carries no indexer
77
78    // block-compressed sparse attention (qwen4exp QSA) over the cells of the indexer cache.
79    // Blocks cut the position line, not the cell array, so no caller assumes a contiguous layout:
80    //   cell_blk  I32 [n_kv, ns]           block each cell belongs to
81    //   blk_cells I32 [ratio*n_blocks, ns] cells making up each block
82    //   blk_pos   I32 [4*n_blocks*ns]      mrope position rows of each block's first token
83    //   bias      F32 [n_kv, n_tokens/ns, ns] -inf where invisible, large where always visible
84    // blk_bias asks for the bias per block instead: [n_blocks, n_tokens/ns, ns]
85    // the caller then adds the attention mask, the only part of the bias that varies within a block
86    void set_input_qsa(ggml_tensor * cell_blk, ggml_tensor * blk_cells, ggml_tensor * blk_pos,
87                       ggml_tensor * bias, const llama_ubatch * ubatch, uint32_t ratio,
88                       bool blk_bias) const;
89
90private:
91    // forget seq_id (all of it if seq_id < 0) in every cache at once, so a failed restore cannot leave the caches out of step
92    // seq_id < 0 drops the whole context, as the caches themselves do on a failed restore
93    void state_drop(llama_seq_id seq_id);
94
95    // the indexer cache holds one key head per layer, so it needs its own hparams:
96    // llama_kv_cache keeps a reference to what it is given
97    llama_hparams hparams_idx;
98
99    const std::unique_ptr<llama_kv_cache> mem_idx;
100};
101
102class llama_memory_hybrid_idx_context : public llama_memory_hybrid_context {
103public:
104    using slot_info_vec_t = llama_kv_cache::slot_info_vec_t;
105
106    // used for errors
107    explicit llama_memory_hybrid_idx_context(llama_memory_status status);
108
109    // used to create a full-cache context
110    explicit llama_memory_hybrid_idx_context(llama_memory_hybrid_idx * mem);
111
112    // used to create an update context
113    llama_memory_hybrid_idx_context(
114            llama_memory_hybrid_idx * mem,
115                      llama_context * lctx,
116                               bool   optimize);
117
118    // used to create a batch processing context from a batch
119    llama_memory_hybrid_idx_context(
120            llama_memory_hybrid_idx * mem,
121                    slot_info_vec_t   sinfos_attn,
122                    slot_info_vec_t   sinfos_idx,
123          std::vector<llama_ubatch>   ubatches);
124
125    ~llama_memory_hybrid_idx_context() = default;
126
127    //
128    // llama_memory_context_i
129    //
130
131    bool next()  override;
132    bool apply() override;
133
134    //
135    // llama_memory_hybrid_idx_context specific API
136    //
137
138    // nullptr with no indexer
139    const llama_kv_cache_context * get_idx() const;
140
141    // streams in the current slot info, the `ns` of get_k/get_v; 1 if unified
142    uint32_t get_n_stream() const;
143
144    void set_input_qsa(ggml_tensor * cell_blk, ggml_tensor * blk_cells, ggml_tensor * blk_pos,
145                       ggml_tensor * bias, const llama_ubatch * ubatch, uint32_t ratio,
146                       bool blk_bias) const;
147
148private:
149    const llama_memory_hybrid_idx * mem = nullptr;
150
151    // streams per ubatch, read from the slot infos before ctx_idx takes them
152    // declared first, so it is initialised while sinfos_idx is still intact
153    const std::vector<uint32_t> ns_ubatch;
154
155    // null unless the model has an indexer
156    const llama_memory_context_ptr ctx_idx;
157
158    // mirrors the base class's ubatch cursor, which is private there
159    size_t i_cur = 0;
160};