File size: 4,368 Bytes
a92b335
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
from collections.abc import Callable

import torch
import torch.nn as nn
from transformers.modeling_utils import ALL_ATTENTION_FUNCTIONS
from transformers.models.mistral.modeling_mistral import (
    MistralAttention,
    MistralDecoderLayer,
    MistralForCausalLM,
    MistralMLP,
    MistralModel,
    MistralRMSNorm,
    apply_rotary_pos_emb,
    eager_attention_forward,
)

try:
    from .configuration_q import QConfig
except ImportError:  # запуск сгенерированного файла прямо из каталога ноутбука
    from configuration_q import QConfig


class QScalarGate(nn.Module):
    def __init__(self, hidden_size, multiplier=2.0):
        super().__init__()
        self.projection = nn.Linear(hidden_size, 1, bias=False)
        self.multiplier = multiplier

    def forward(self, branch, residual_input):
        return branch * self.multiplier * torch.sigmoid(self.projection(residual_input))


class QMLP(MistralMLP):
    def __init__(self, config):
        super().__init__(config)
        self.output_gate = (
            QScalarGate(config.hidden_size, config.gate_multiplier)
            if config.mlp_scalar_gate else None
        )

    def forward(self, hidden_states):
        output = super().forward(hidden_states)
        if self.output_gate is not None:
            output = self.output_gate(output, hidden_states)
        return output


class QAttention(MistralAttention):
    def __init__(self, config, layer_idx):
        super().__init__(config, layer_idx)
        self.use_rope = layer_idx not in config.nope_layers
        self.q_norm = MistralRMSNorm(self.head_dim, eps=config.rms_norm_eps) if config.qk_norm else None
        self.k_norm = MistralRMSNorm(self.head_dim, eps=config.rms_norm_eps) if config.qk_norm else None
        self.output_gate = (
            QScalarGate(config.hidden_size, config.gate_multiplier)
            if config.attention_scalar_gate else None
        )

    def forward(self, hidden_states, position_embeddings, attention_mask, past_key_values=None, **kwargs):
        input_shape = hidden_states.shape[:-1]
        hidden_shape = (*input_shape, -1, self.head_dim)
        query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2)
        key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2)
        value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)

        if self.q_norm is not None:
            query_states = self.q_norm(query_states)
            key_states = self.k_norm(key_states)
        if self.use_rope:
            cos, sin = position_embeddings
            query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)

        if past_key_values is not None:
            key_states, value_states = past_key_values.update(
                key_states, value_states, self.layer_idx
            )

        attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
            self.config._attn_implementation, eager_attention_forward
        )
        attn_output, attn_weights = attention_interface(
            self, query_states, key_states, value_states, attention_mask,
            dropout=0.0 if not self.training else self.attention_dropout,
            scaling=self.scaling,
            sliding_window=getattr(self.config, "sliding_window", None),
            **kwargs,
        )
        attn_output = attn_output.reshape(*input_shape, -1).contiguous()
        attn_output = self.o_proj(attn_output)
        if self.output_gate is not None:
            attn_output = self.output_gate(attn_output, hidden_states)
        return attn_output, attn_weights


class QDecoderLayer(MistralDecoderLayer):
    def __init__(self, config, layer_idx):
        super().__init__(config, layer_idx)
        self.self_attn = QAttention(config, layer_idx)
        self.mlp = QMLP(config)


class QModel(MistralModel):
    config_class = QConfig

    def __init__(self, config):
        super().__init__(config)
        self.layers = nn.ModuleList(
            [QDecoderLayer(config, i) for i in range(config.num_hidden_layers)]
        )
        self.post_init()


class QForCausalLM(MistralForCausalLM):
    config_class = QConfig

    def __init__(self, config):
        super().__init__(config)
        self.model = QModel(config)
        self.post_init()