Loading...
Searching...
No Matches
grouped_query_attention_layer.h
Go to the documentation of this file.
1// SPDX-License-Identifier: AGPL-3.0-only
2// Copyright (C) 2026 Artificial Intelligence Techniques, S.L. and Roberto López González
3
4#pragma once
5
8
9namespace opennn
10{
11
12void rotary_build_tables(TensorView&, TensorView&, Index sequence_length, Index rotary_dim, float base);
13void rotary_forward(const TensorView&, const TensorView&, const TensorView&,
14 TensorView&, Index head_dim, Index rotary_dim, Index position_offset);
15void grouped_attention_forward(const TensorView& query, const TensorView& key, const TensorView& value,
16 TensorView& output, Index n_query_heads, Index n_kv_heads, Index head_dim,
17 bool causal, float scale, Index query_position_offset = 0,
18 float* decode_partials = nullptr, const int* position_device = nullptr);
19Index grouped_attention_decode_scratch_floats(Index n_query_heads, Index head_dim);
20void qk_rope_cache_append(const TensorView& qkv_row, const TensorView& q_norm_weight,
21 const TensorView& k_norm_weight, const TensorView& cos_table,
22 const TensorView& sin_table, TensorView& q_out,
23 TensorView& key_cache, TensorView& value_cache,
24 Index n_query_heads, Index n_kv_heads, Index head_dim,
25 float epsilon, const int* position_device);
26void qk_norm_forward(const TensorView& input, const TensorView& weight, TensorView& output,
27 Index head_dim, float epsilon);
28
30{
31 static constexpr size_t forward_scratch_slots_count = 9;
32 struct GraphCache;
33
36
37 void set(Index new_sequence_length, Index new_hidden,
38 Index new_q_heads, Index new_kv_heads, Index new_head_dim,
39 float new_rope_theta, float new_rms_epsilon, bool new_use_qk_norm);
40
41 vector<TensorSpec> parameter_specs() const override;
42 vector<TensorSpec> forward_scratch_specs() const;
43 vector<SlotQuantization> parameter_quantization() const override;
44 void link_parameters(span<const TensorView>) override;
45 void link_parameter_scales(span<const TensorView>) override;
46 void set_parameters_random() override;
47
48 const Buffer* get_rope_tables() const noexcept { return rope_tables.get(); }
49
51 void back_propagate(ForwardPropagation&, BackPropagation&, size_t) const override;
52
53private:
54
56
57 enum ForwardSlot : size_t
58 {
59 Input,
60 Query,
61 Key,
62 Value,
63 RotatedQuery,
64 RotatedKey,
65 AttentionOutput,
66 FusedQkv,
67 DecodePartials,
68 SequenceLengths,
69 Output
70 };
71
72 Index q_dim() const { return q_heads * head_dim; }
73 Index kv_dim() const { return kv_heads * head_dim; }
74
75 void prepare_rope_tables(Device);
76 void apply_attention(const TensorView& query, const TensorView& key,
77 const TensorView& value, TensorView& output,
78 bool causal, float scale, Index query_position_offset,
79 float* decode_partials = nullptr,
80 const int* position_device = nullptr);
81 void attend_sequence_cpu(const TensorView& x_b,
82 TensorView& q_v, TensorView& k_v,
83 TensorView& v_target, TensorView& k_target,
84 TensorView& qr_v,
85 const TensorView& key_all, const TensorView& value_all,
86 TensorView& attn_v, TensorView& o_b,
87 const TensorView& cos_v, const TensorView& sin_v,
88 float scale, Index position_offset);
89
90 void forward_gpu(TensorView& input, TensorView& output, Index batch, Index past,
91 Index query_capacity, const int* position_device,
92 vector<TensorView>& forward_slots, Buffer& kv_cache,
93 device::PinnedBuffer& pinned_storage);
94
95 Index sequence_length = 0;
96 Index hidden = 0;
97 Index q_heads = 0;
98 Index kv_heads = 0;
99 Index head_dim = 0;
100 float rope_theta = 1000000.0f;
101 float rms_epsilon = 1.0e-6f;
102 bool use_qk_norm = true;
103
104 TensorView q_proj, k_proj, v_proj, o_proj, q_norm, k_norm;
105 TensorView q_scale, k_scale, v_scale, o_scale, qkv_scale;
106 bool qkv_fused = false;
107
108 shared_ptr<const Buffer> rope_tables;
109 unique_ptr<GraphCache> graph_cache;
110};
111
112class GroupedQueryAttention final : public Layer
113{
114public:
115
117 Index q_heads = 0, Index kv_heads = 0, Index head_dim = 0,
118 float rope_theta = 1000000.0f, float rms_epsilon = 1.0e-6f,
119 bool use_qk_norm = true,
120 const string& = "grouped_query_attention");
121
122 Shape get_input_shape() const noexcept override { return { sequence_length, hidden }; }
123 Shape get_output_shape() const override { return { sequence_length, hidden }; }
124
125 Index get_sequence_length() const { return sequence_length; }
126 Index get_hidden() const { return hidden; }
127 Index get_q_heads() const { return q_heads; }
128 Index get_kv_heads() const { return kv_heads; }
129 Index get_head_dim() const { return head_dim; }
130 bool get_use_qk_norm() const { return use_qk_norm; }
131
132 vector<TensorSpec> get_forward_specs(Index) const override;
133
135 bool is_forward_slot_inference_elidable(size_t, Device, Index) const noexcept;
136 bool uses_compact_inference() const noexcept;
137
145
146 void set(const Shape&, Index, Index, Index, float, float, bool new_use_qk_norm, const string&);
147 bool accepts_input_rank(Index rank) const override { return is_one_of(rank, 2, 3); }
148 bool uses_sequence_position() const noexcept override { return true; }
149
150 void apply_input_shape(const Shape&) override;
151
152 void on_compute_dtype_changed() override { attention.compute_dtype = get_compute_dtype(); }
153
154 void read_JSON_body(const Json*) override;
155 void write_JSON_body(JsonWriter&) const override;
156
157private:
158
159 friend class Qwen3;
160 void enable_compact_inference();
161
162 Index sequence_length = 0;
163 Index hidden = 0;
164 Index q_heads = 0;
165 Index kv_heads = 0;
166 Index head_dim = 0;
167 float rope_theta = 1000000.0f;
168 float rms_epsilon = 1.0e-6f;
169 bool use_qk_norm = true;
170
172};
173
174}
Index get_head_dim() const
Definition grouped_query_attention_layer.h:129
Index get_sequence_length() const
Definition grouped_query_attention_layer.h:125
friend class Qwen3
Definition grouped_query_attention_layer.h:159
bool uses_sequence_position() const noexcept override
Definition grouped_query_attention_layer.h:148
void set(const Shape &, Index, Index, Index, float, float, bool new_use_qk_norm, const string &)
Index get_hidden() const
Definition grouped_query_attention_layer.h:126
Index get_q_heads() const
Definition grouped_query_attention_layer.h:127
Shape get_output_shape() const override
Definition grouped_query_attention_layer.h:123
void apply_input_shape(const Shape &) override
Index get_kv_heads() const
Definition grouped_query_attention_layer.h:128
void write_JSON_body(JsonWriter &) const override
vector< TensorSpec > get_forward_specs(Index) const override
bool get_use_qk_norm() const
Definition grouped_query_attention_layer.h:130
ForwardSlotKind get_forward_slot_kind(size_t slot) const override
Definition grouped_query_attention_layer.h:138
bool accepts_input_rank(Index rank) const override
Definition grouped_query_attention_layer.h:147
GroupedQueryAttention(const Shape &=Shape({0, 0}), Index q_heads=0, Index kv_heads=0, Index head_dim=0, float rope_theta=1000000.0f, float rms_epsilon=1.0e-6f, bool use_qk_norm=true, const string &="grouped_query_attention")
Shape get_input_shape() const noexcept override
Definition grouped_query_attention_layer.h:122
bool uses_compact_inference() const noexcept
void on_compute_dtype_changed() override
Definition grouped_query_attention_layer.h:152
void read_JSON_body(const Json *) override
bool is_forward_slot_inference_elidable(size_t, Device, Index) const noexcept
Definition json.h:92
Definition json.h:24
virtual bool is_forward_slot_inference_elidable(size_t, Device) const noexcept
Definition layer.h:95
Type get_compute_dtype() const noexcept
Definition layer.h:157
@ Input
Definition layer.h:213
Layer(LayerType type, Trainability trainability=Trainability::Trainable)
Definition layer.h:210
Definition configuration.h:10
void rotary_build_tables(TensorView &, TensorView &, Index sequence_length, Index rotary_dim, float base)
Device
Definition configuration.h:12
void qk_norm_forward(const TensorView &input, const TensorView &weight, TensorView &output, Index head_dim, float epsilon)
constexpr bool is_one_of(const T &value, const Candidates &... candidates)
Definition opennn_types.h:273
void qk_rope_cache_append(const TensorView &qkv_row, const TensorView &q_norm_weight, const TensorView &k_norm_weight, const TensorView &cos_table, const TensorView &sin_table, TensorView &q_out, TensorView &key_cache, TensorView &value_cache, Index n_query_heads, Index n_kv_heads, Index head_dim, float epsilon, const int *position_device)
void rotary_forward(const TensorView &, const TensorView &, const TensorView &, TensorView &, Index head_dim, Index rotary_dim, Index position_offset)
Index grouped_attention_decode_scratch_floats(Index n_query_heads, Index head_dim)
void scale(const TensorView &, const TensorView &, const TensorView &, const TensorView &, const TensorView &, const TensorView &, float, float, TensorView &)
ForwardSlotKind
Definition layer.h:18
@ Transient
Definition layer.h:18
@ Pooled
Definition layer.h:18
ForwardPropagationMode
Definition forward_propagation.h:33
void grouped_attention_forward(const TensorView &query, const TensorView &key, const TensorView &value, TensorView &output, Index n_query_heads, Index n_kv_heads, Index head_dim, bool causal, float scale, Index query_position_offset=0, float *decode_partials=nullptr, const int *position_device=nullptr)
Definition back_propagation.h:19
Definition tensor_types.h:340
Definition forward_propagation.h:52
Definition grouped_query_attention_layer.h:30
void back_propagate(ForwardPropagation &, BackPropagation &, size_t) const override
void set(Index new_sequence_length, Index new_hidden, Index new_q_heads, Index new_kv_heads, Index new_head_dim, float new_rope_theta, float new_rms_epsilon, bool new_use_qk_norm)
static constexpr size_t forward_scratch_slots_count
Definition grouped_query_attention_layer.h:31
friend class GroupedQueryAttention
Definition grouped_query_attention_layer.h:55
void link_parameters(span< const TensorView >) override
vector< SlotQuantization > parameter_quantization() const override
void forward_propagate(ForwardPropagation &, size_t, ForwardPropagationMode) override
const Buffer * get_rope_tables() const noexcept
Definition grouped_query_attention_layer.h:48
void link_parameter_scales(span< const TensorView >) override
vector< TensorSpec > parameter_specs() const override
vector< TensorSpec > forward_scratch_specs() const
Definition operator.h:28
Definition tensor_types.h:172
Definition tensor_types.h:540