Loading...
Searching...
No Matches
multihead_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
10
11namespace opennn
12{
13
14class MultiHeadAttention final : public Layer
15{
16public:
17
18 MultiHeadAttention(const Shape& = Shape({0, 0}),
19 Index = 0,
20 const string& = {});
21
23 const Shape&,
24 Index = 0,
25 const string& = {});
26
27 Shape get_input_shape() const noexcept override;
28 Shape get_output_shape() const override { return get_input_shape(); }
29
30 Index get_query_sequence_length() const noexcept { return query_sequence_length; }
31 Index get_source_sequence_length() const noexcept { return source_sequence_length; }
32 Index get_embedding_dimension() const noexcept { return embedding_dimension; }
33 Index get_heads_number() const noexcept { return heads_number; }
34 Index get_head_dimension() const noexcept
35 {
36 return (heads_number == 0) ? 0 : Index(embedding_dimension / heads_number);
37 }
38 Index get_sources_number() const noexcept override { return cross_attention ? 2 : 1; }
39 vector<TensorSpec> get_forward_specs(Index) const override;
40 vector<TensorSpec> get_backward_specs(Index) const override;
41
42 ForwardSlotKind get_forward_slot_kind(size_t slot) const override
43 {
44 if (slot == TransposeScratch || slot == SdpaQkvPack)
46 if (slot == AttentionWeightsDropped
47 || slot == SdpaStats
48 || slot == SdpaDropoutState
49 || slot == DropoutMask)
52 }
53 bool backward_uses_forward_output() const noexcept override { return false; }
54 bool preserves_output_delta_during_backward() const noexcept override { return true; }
55 bool folds_input_delta_addend(size_t input) const noexcept override
56 {
57 return input == 0 || (cross_attention && input == 1);
58 }
59
60 void set(Index = 0,
61 Index = 0,
62 Index = 0,
63 Index = 0,
65 const string& = "multihead_attention_layer");
66
67 bool accepts_input_rank(Index rank) const override { return is_one_of(rank, 2); }
68
69 void apply_input_shape(const Shape&) override;
70 void on_compute_dtype_changed() override;
71
72 void set_dropout_rate(float new_dropout_rate) { attention.dropout.set_rate(new_dropout_rate); }
73
74 void set_zero_padded_queries(bool new_zero_padded_queries);
75
76 // 192 kept the fused attention path off for every sequence the transformer
77 // benchmark runs (max_tokens caps them at 128), so attention ran as three
78 // kernels -- QK^T, a softmax pass, then PV -- while PyTorch's
79 // TransformerEncoderLayer dispatches to fused scaled_dot_product_attention
80 // by default. OPENNN_SDPA_MIN_SEQUENCE overrides it so the threshold is
81 // measurable rather than assumed.
83
84 void set_sdpa_auto(bool new_sdpa_auto);
86
87 bool should_use_sdpa() const;
88
90
91 void read_JSON_body(const Json*) override;
92 void write_JSON_body(JsonWriter&) const override;
93
94private:
95
96 Index embedding_dimension = 0;
97 Index heads_number = 0;
98 Index query_sequence_length = 0;
99 Index source_sequence_length = 0;
100
101 bool sdpa_auto = true;
102 Index sdpa_min_sequence_length = default_sdpa_min_sequence_length;
103 bool cross_attention = false;
104
105 MultiHeadProjectionOperator query_projection;
106 MultiHeadProjectionOperator key_projection;
107 MultiHeadProjectionOperator value_projection;
108 CombinationOperator output_projection;
109 AttentionOperator attention;
110
111 enum Forward {Input, Query, Key, AttentionWeights, AttentionWeightsDropped,
112 ConcatenatedAttentionOutputs, Value, TransposeScratch, SdpaQkvPack,
113 SdpaStats, SdpaQueryLengths, SdpaSourceLengths, SdpaDropoutState,
114 DropoutMask, Output};
115 enum Backward {
116 OutputDelta,
117 InputQueryDelta,
118 InputSourceDelta,
119 AttentionWeightDelta,
120 ValueHeadDelta,
121 ConcatenatedOutputDelta,
122 QueryHeadDelta,
123 KeyHeadDelta,
124 SdpaOutputGradBF16,
125 SdpaQueryGradBF16,
126 SdpaKeyGradBF16,
127 SdpaValueGradBF16,
128 SdpaQueryRematBF16,
129 SdpaKeyRematBF16,
130 SdpaValueRematBF16,
131 SdpaOutputRematBF16
132 };
133};
134
135}
Definition json.h:92
Definition json.h:24
Layer(LayerType type, Trainability trainability=Trainability::Trainable)
Definition layer.h:210
Index get_head_dimension() const noexcept
Definition multihead_attention_layer.h:34
void set(Index=0, Index=0, Index=0, Index=0, CausalMask=CausalMask::No, const string &="multihead_attention_layer")
Index get_source_sequence_length() const noexcept
Definition multihead_attention_layer.h:31
void set_sdpa_min_sequence_length(Index)
void set_zero_padded_queries(bool new_zero_padded_queries)
void on_compute_dtype_changed() override
vector< TensorSpec > get_backward_specs(Index) const override
ForwardSlotKind get_forward_slot_kind(size_t slot) const override
Definition multihead_attention_layer.h:42
vector< TensorSpec > get_forward_specs(Index) const override
void set_sdpa_auto(bool new_sdpa_auto)
static const Index default_sdpa_min_sequence_length
Definition multihead_attention_layer.h:82
Shape get_output_shape() const override
Definition multihead_attention_layer.h:28
void apply_input_shape(const Shape &) override
bool accepts_input_rank(Index rank) const override
Definition multihead_attention_layer.h:67
Index get_query_sequence_length() const noexcept
Definition multihead_attention_layer.h:30
Index get_sources_number() const noexcept override
Definition multihead_attention_layer.h:38
bool backward_uses_forward_output() const noexcept override
Definition multihead_attention_layer.h:53
void read_JSON_body(const Json *) override
Index get_heads_number() const noexcept
Definition multihead_attention_layer.h:33
bool preserves_output_delta_during_backward() const noexcept override
Definition multihead_attention_layer.h:54
MultiHeadAttention(const Shape &, const Shape &, Index=0, const string &={})
bool folds_input_delta_addend(size_t input) const noexcept override
Definition multihead_attention_layer.h:55
Shape get_input_shape() const noexcept override
void set_dropout_rate(float new_dropout_rate)
Definition multihead_attention_layer.h:72
MultiHeadAttention(const Shape &=Shape({0, 0}), Index=0, const string &={})
void write_JSON_body(JsonWriter &) const override
Index get_embedding_dimension() const noexcept
Definition multihead_attention_layer.h:32
Definition configuration.h:10
constexpr bool is_one_of(const T &value, const Candidates &... candidates)
Definition opennn_types.h:273
CausalMask
Definition attention_operator.h:12
@ No
Definition attention_operator.h:12
ForwardSlotKind
Definition layer.h:18
@ Transient
Definition layer.h:18
@ TrainingOnly
Definition layer.h:18
@ Pooled
Definition layer.h:18
Definition attention_operator.h:15
Definition combination_operator.h:12
Definition multihead_projection_operator.h:16
Definition tensor_types.h:172