kgrabko commited on
Commit
4d4035d
·
verified ·
1 Parent(s): 0759561

Create JiRackTernaryPyTorch_10b.py

Browse files
checkpoints/10b_ternary_ep5/JiRackTernaryPyTorch_10b.py ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #%%writefile JiRackTernaryPyTorch_10b.py
2
+ # =============================================================================
3
+ # COPYRIGHT © 2025 Konstantin Vladimirovich Grabko. ALL RIGHTS RESERVED.
4
+ # =============================================================================
5
+ # Rope fix and стабильного 99-го квантиля (torch.quantile).
6
+ #
7
+ import torch
8
+ import torch.nn as nn
9
+ import torch.nn.functional as F
10
+ from torch.utils.checkpoint import checkpoint
11
+
12
+ # ========================= CONFIG CONSTANTS =========================
13
+ VOCAB_SIZE = 128256
14
+ HIDDEN_SIZE = 4096
15
+ INTERMEDIATE_SIZE = 18432
16
+ NUM_LAYERS = 32
17
+ NUM_HEADS = 32 # 4096 // 32 = 128 (HEAD_DIM)
18
+ NUM_KV_HEADS = 8
19
+ HEAD_DIM = 128
20
+ MAX_SEQ_LEN = 8192
21
+ ROPE_THETA = 500000.0
22
+ RMS_EPS = 1e-5
23
+ ROPE_SCALE_FACTOR = 1.0
24
+ # =================================================================
25
+
26
+ class JiRackConfig10B:
27
+ def __init__(self):
28
+ self.vocab_size = VOCAB_SIZE
29
+ self.hidden_size = HIDDEN_SIZE
30
+ self.intermediate_size = INTERMEDIATE_SIZE
31
+ self.num_hidden_layers = NUM_LAYERS
32
+ self.num_attention_heads = NUM_HEADS
33
+ self.num_key_value_heads = NUM_KV_HEADS
34
+ self.head_dim = HEAD_DIM
35
+ self.max_seq_len = MAX_SEQ_LEN
36
+ self.rope_theta = ROPE_THETA
37
+ self.rms_norm_eps = RMS_EPS
38
+ self.rope_scale_factor = ROPE_SCALE_FACTOR
39
+
40
+ def precompute_freqs_cis(dim: int, end: int, theta: float = ROPE_THETA, scale_factor: float = ROPE_SCALE_FACTOR):
41
+ freqs = 1.0 / (theta ** (torch.arange(0, dim, 2).float() / dim))
42
+ if scale_factor > 1.0:
43
+ freqs = freqs / scale_factor
44
+
45
+ t = torch.arange(end, dtype=torch.float32)
46
+ freqs = torch.outer(t, freqs)
47
+ return torch.cos(freqs), torch.sin(freqs)
48
+
49
+ def apply_rotary_emb(xq, xk, freqs_cos, freqs_sin):
50
+ def rotate_interleaved(x):
51
+ x_even = x[..., 0::2]
52
+ x_odd = x[..., 1::2]
53
+ return torch.stack((-x_odd, x_even), dim=-1).flatten(-2)
54
+
55
+ cos = freqs_cos[None, None, :, :].repeat_interleave(2, dim=-1)
56
+ sin = freqs_sin[None, None, :, :].repeat_interleave(2, dim=-1)
57
+
58
+ xq_out = (xq * cos) + (rotate_interleaved(xq) * sin)
59
+ xk_out = (xk * cos) + (rotate_interleaved(xk) * sin)
60
+ return xq_out, xk_out
61
+
62
+ class BitLinear(nn.Linear):
63
+ def __init__(self, in_features, out_features, bias=False, ternary=True):
64
+ super().__init__(in_features, out_features, bias=bias)
65
+ self.ternary = ternary
66
+ self.eps = 1e-5
67
+
68
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
69
+ if not self.ternary:
70
+ return F.linear(x, self.weight, self.bias)
71
+
72
+ # Троичное квантование весов (Ternary Weights)
73
+ w = self.weight
74
+ gamma = w.abs().mean().clamp(min=self.eps)
75
+ w_quant = torch.clamp(torch.round(w / gamma), -1.0, 1.0)
76
+ w_effective = w + (w_quant * gamma - w).detach()
77
+
78
+ # Нормализация активаций
79
+ x_mean = x.mean(dim=-1, keepdim=True)
80
+ x_variance = x.var(dim=-1, keepdim=True, unbiased=False)
81
+ x_norm = (x - x_mean) / torch.sqrt(x_variance + self.eps)
82
+
83
+ # Стабильное квантование активаций через 99-й квантиль вместо жесткого .max()
84
+ # Извлекаем квантиль по последней размерности (или можно по всей последовательности)
85
+ x_abs = x_norm.abs()
86
+ x_quantile = torch.quantile(x_abs.float(), 0.99, dim=-1, keepdim=True).to(x_norm.dtype)
87
+ x_scale_bound = x_quantile.clamp(min=self.eps)
88
+
89
+ x_scale = 127.0 / x_scale_bound
90
+ x_quant = torch.clamp(torch.round(x_norm * x_scale), -128.0, 127.0)
91
+ x_effective = x_norm + (x_quant / x_scale - x_norm).detach()
92
+
93
+ # Линейное преобразование
94
+ out = F.linear(x_effective, w_effective, self.bias)
95
+
96
+ # Декуантование обратно
97
+ x_std = torch.sqrt(x_variance + self.eps)
98
+ return out * (x_std * gamma / 127.0)
99
+
100
+ class RMSNorm(nn.Module):
101
+ def __init__(self, dim, eps=RMS_EPS):
102
+ super().__init__()
103
+ self.eps = eps
104
+ self.weight = nn.Parameter(torch.ones(dim))
105
+
106
+ def forward(self, x):
107
+ return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps) * self.weight
108
+
109
+ class TransformerBlock(nn.Module):
110
+ def __init__(self, config, use_checkpoint=False, bias=False , ternary=False):
111
+ super().__init__()
112
+ self.ternary=ternary
113
+ self.bias=bias
114
+ self.use_checkpoint = use_checkpoint
115
+ self.n_heads = config.num_attention_heads
116
+ self.n_kv_heads = config.num_key_value_heads
117
+ self.head_dim = config.head_dim
118
+ self.n_rep = self.n_heads // self.n_kv_heads
119
+
120
+ self.norm1 = RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
121
+ self.norm2 = RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
122
+
123
+ self.q_proj = BitLinear(config.hidden_size, config.hidden_size, self.bias,self.ternary)
124
+ self.k_proj = BitLinear(config.hidden_size, self.n_kv_heads * self.head_dim, self.bias,self.ternary)
125
+ self.v_proj = BitLinear(config.hidden_size, self.n_kv_heads * self.head_dim, self.bias,self.ternary)
126
+ self.out_proj = BitLinear(config.hidden_size, config.hidden_size, self.bias,self.ternary)
127
+
128
+ self.ffn_w1 = BitLinear(config.hidden_size, config.intermediate_size, self.bias,self.ternary)
129
+ self.ffn_w3 = BitLinear(config.hidden_size, config.intermediate_size, self.bias,self.ternary)
130
+ self.ffn_w2 = BitLinear(config.intermediate_size, config.hidden_size, self.bias,self.ternary)
131
+
132
+ def forward(self, x, freqs_cos, freqs_sin):
133
+ if self.use_checkpoint and self.training:
134
+ return checkpoint(self._forward_impl, x, freqs_cos, freqs_sin, use_reentrant=False)
135
+ return self._forward_impl(x, freqs_cos, freqs_sin)
136
+
137
+ def _forward_impl(self, x, freqs_cos, freqs_sin):
138
+ h = self.norm1(x)
139
+ B, T, _ = h.shape
140
+
141
+ q = self.q_proj(h).view(B, T, self.n_heads, self.head_dim).transpose(1, 2)
142
+ k = self.k_proj(h).view(B, T, self.n_kv_heads, self.head_dim).transpose(1, 2)
143
+ v = self.v_proj(h).view(B, T, self.n_kv_heads, self.head_dim).transpose(1, 2)
144
+
145
+ q, k = apply_rotary_emb(q, k, freqs_cos, freqs_sin)
146
+
147
+ if self.n_rep > 1:
148
+ k = k.repeat_interleave(self.n_rep, dim=1)
149
+ v = v.repeat_interleave(self.n_rep, dim=1)
150
+
151
+ attn_out = F.scaled_dot_product_attention(q, k, v, is_causal=True)
152
+ attn_out = attn_out.transpose(1, 2).contiguous().view(B, T, -1)
153
+
154
+ x = x + self.out_proj(attn_out)
155
+
156
+ m = self.norm2(x)
157
+ gate = F.silu(self.ffn_w1(m))
158
+ up = self.ffn_w3(m)
159
+ x = x + self.ffn_w2(gate * up)
160
+
161
+ return x
162
+
163
+ class JiRackTransformer10B(nn.Module):
164
+ def __init__(self, config: JiRackConfig10B = None, use_checkpoint=False, bias=False , ternary=True):
165
+ super().__init__()
166
+ self.config = config if config is not None else JiRackConfig10B()
167
+ self.use_checkpoint = use_checkpoint
168
+ self.ternary=ternary
169
+ self.bias=bias
170
+
171
+ self.token_emb = nn.Embedding(self.config.vocab_size, self.config.hidden_size)
172
+ self.blocks = nn.ModuleList([
173
+ TransformerBlock(self.config, self.use_checkpoint, self.bias , self.ternary)
174
+ for _ in range(self.config.num_hidden_layers)
175
+ ])
176
+ self.ln_f = RMSNorm(self.config.hidden_size, eps=self.config.rms_norm_eps)
177
+ self.lm_head = nn.Linear(self.config.hidden_size, self.config.vocab_size, bias=False)
178
+
179
+ cos, sin = precompute_freqs_cis(
180
+ dim=self.config.head_dim,
181
+ end=self.config.max_seq_len,
182
+ theta=self.config.rope_theta,
183
+ scale_factor=self.config.rope_scale_factor
184
+ )
185
+ self.register_buffer("freqs_cos", cos, persistent=False)
186
+ self.register_buffer("freqs_sin", sin, persistent=False)
187
+
188
+ def _set_ternary(self, module):
189
+ if isinstance(module, BitLinear):
190
+ module.ternary = True
191
+
192
+ def forward(self, input_ids):
193
+ seq_len = input_ids.shape[1]
194
+ x = self.token_emb(input_ids)
195
+
196
+ # RoPE буферы приводятся к типу и девайсу входящих эмбеддингов
197
+ cos = self.freqs_cos[:seq_len].to(x)
198
+ sin = self.freqs_sin[:seq_len].to(x)
199
+
200
+ for block in self.blocks:
201
+ x = block(x, cos, sin)
202
+
203
+ return self.lm_head(self.ln_f(x))