KenteaKe11 commited on
Commit
963b91a
·
1 Parent(s): c6af2df

KenT: GeLU MLP, 12 layers, N=24 D=208 (~301M)

Browse files
Files changed (4) hide show
  1. .gitignore +0 -0
  2. README.md +10 -9
  3. config.json +4 -4
  4. model.py +11 -12
.gitignore CHANGED
Binary files a/.gitignore and b/.gitignore differ
 
README.md CHANGED
@@ -13,7 +13,8 @@ tags:
13
  - linear-time
14
  - frequency-domain
15
  - dct
16
- - swiglu
 
17
  - text-generation
18
  - custom_code
19
  - fp16
@@ -22,19 +23,19 @@ tags:
22
 
23
  # KenT
24
 
25
- KenT is a recurrent language model from the SSM family. KenT concentrates its capacity in a very wide spectral representation: few layers, each with a single transformation block, and a light learned-forgetting memory.
26
 
27
  > This repo contains `trust_remote_code` code; weights are stored in **FP16**.
28
 
29
  ## Architectural Philosophy
30
 
31
- - **Shallow stack, wide spectrum.** KenT stacks a few identical recurrent layers (8 in this ~300M model), each containing exactly
32
- one transformation block. The layers are connected in sequence through the representation stream, and the last layer produces
33
  the final output. The representation stream feeding `lm_head` is wide (1024), and each layer's Bilinear projection expands it
34
- into a large resolution axis (N = 32 DCT positions) with enough features per position (D = 240) before the DCT.
35
  - **Invest in the transformation core.** Capacity is concentrated in the "hidden" part, where features are actually transformed,
36
- rather than in the vocabulary table. Parameters were scaled from ~100M to ~300M by widening the representation stream and the
37
- spectral axes (N and D together), not by stacking more layers.
38
  - **Two streams, two roles.** One stream is a representation carrying information about the current token; the other is a memory
39
  stream that aggregates history. The two streams meet only through learned projections and are never mixed directly.
40
  - **Frequency as a fixed foundation, learning where it's needed.** Features are processed in the cosine-coefficient space using a
@@ -43,8 +44,8 @@ KenT is a recurrent language model from the SSM family. KenT concentrates its ca
43
  - **Memory with learned forgetting.** History is summarized with an exponential moving average
44
  `H_t = (1 - a) H_{t-1} + a u_t`, where `a` is a single learned scalar per layer. Its initial value decreases with depth
45
  (shallow layers forget fast, deep layers remember longer). The decoding state has **constant** size regardless of context length.
46
- - **Width is the main axis.** There is no inner chain of blocks inside a layer: each layer applies one DCT/SwiGLU block over a
47
- large N x D grid, and memory timescale still varies across the 8 layers.
48
  - **Chunk-parallelizable.** The moving average is a linear recurrence, so a long document can be split into blocks/chunks,
49
  processed concurrently, and merged with an affine scan, yielding the same result as sequential processing.
50
 
 
13
  - linear-time
14
  - frequency-domain
15
  - dct
16
+ - mlp
17
+ - gelu
18
  - text-generation
19
  - custom_code
20
  - fp16
 
23
 
24
  # KenT
25
 
26
+ KenT is a recurrent language model from the SSM family. KenT concentrates its capacity in a wide spectral representation stacked over a moderate depth: each layer has a single transformation block, plus a light learned-forgetting memory.
27
 
28
  > This repo contains `trust_remote_code` code; weights are stored in **FP16**.
29
 
30
  ## Architectural Philosophy
31
 
32
+ - **Wide spectrum, moderate depth.** KenT stacks identical recurrent layers (12 in this ~300M model), each containing exactly
33
+ one transformation block (a GeLU MLP with hidden size 4 x D). The layers are connected in sequence through the representation stream, and the last layer produces
34
  the final output. The representation stream feeding `lm_head` is wide (1024), and each layer's Bilinear projection expands it
35
+ into a large resolution axis (N = 24 DCT positions) with enough features per position (D = 208) before the DCT.
36
  - **Invest in the transformation core.** Capacity is concentrated in the "hidden" part, where features are actually transformed,
37
+ rather than in the vocabulary table. Parameters were scaled from ~100M by widening the representation stream and the spectral
38
+ axes (N and D together) and then by adding layers; the MLP inside each block is kept small.
39
  - **Two streams, two roles.** One stream is a representation carrying information about the current token; the other is a memory
40
  stream that aggregates history. The two streams meet only through learned projections and are never mixed directly.
41
  - **Frequency as a fixed foundation, learning where it's needed.** Features are processed in the cosine-coefficient space using a
 
44
  - **Memory with learned forgetting.** History is summarized with an exponential moving average
45
  `H_t = (1 - a) H_{t-1} + a u_t`, where `a` is a single learned scalar per layer. Its initial value decreases with depth
46
  (shallow layers forget fast, deep layers remember longer). The decoding state has **constant** size regardless of context length.
47
+ - **Width and depth together.** There is no inner chain of blocks inside a layer: each layer applies one DCT/MLP block over a
48
+ large N x D grid, and memory timescale varies across the 12 layers.
49
  - **Chunk-parallelizable.** The moving average is a linear recurrence, so a long document can be split into blocks/chunks,
50
  processed concurrently, and merged with an affine scan, yielding the same result as sequential processing.
51
 
config.json CHANGED
@@ -10,10 +10,10 @@
10
  },
11
  "vocab_size": 50257,
12
  "hidden_size": 1024,
13
- "num_hidden_layers": 8,
14
- "resolution_size": 32,
15
- "feature_dim": 240,
16
- "intermediate_size": 960,
17
  "rms_norm_eps": 1e-05,
18
  "use_bias": true,
19
  "initializer_range": 0.02,
 
10
  },
11
  "vocab_size": 50257,
12
  "hidden_size": 1024,
13
+ "num_hidden_layers": 12,
14
+ "resolution_size": 24,
15
+ "feature_dim": 208,
16
+ "intermediate_size": 832,
17
  "rms_norm_eps": 1e-05,
18
  "use_bias": true,
19
  "initializer_range": 0.02,
model.py CHANGED
@@ -5,7 +5,7 @@ Mỗi KenT layer thực hiện một bước, với ĐÚNG MỘT WNN Block:
5
 
6
  V = B_in(Norm_X(X)) # (…, N, d_h)
7
  Z = A_N V # DCT-II cố định trên trục N
8
- u = A_N [ Z + SwiGLU(Norm(Z)) ] # một WNN Block
9
  H_t = (1 - a) H_{t-1} + a u_t # EMA, a = a_layer học được, riêng từng layer
10
  X' = X + B_out(Norm_H(H_t))
11
 
@@ -47,9 +47,9 @@ class KentConfig(PretrainedConfig):
47
  num_hidden_layers: số KenT layer xếp chồng (mỗi layer có đúng một WNN Block).
48
  resolution_size: N, độ dài trục mà DCT-II tác động lên.
49
  feature_dim: d_h, số chiều đặc trưng trên mỗi vị trí resolution.
50
- intermediate_size: kích thước hidden của SwiGLU (trên trục d_h).
51
  rms_norm_eps: epsilon của RMSNorm.
52
- use_bias: dùng bias trong Bilinear / SwiGLU.
53
  initializer_range: độ lệch chuẩn khởi tạo trọng số.
54
  ema_alpha_first: a_layer khởi tạo của layer đầu (quên nhanh).
55
  ema_alpha_last: a_layer khởi tạo của layer cuối (nhớ lâu); các layer ở giữa nội suy
@@ -265,29 +265,28 @@ class KentBilinear(nn.Module):
265
  return a * b
266
 
267
 
268
- class KentSwiGLU(nn.Module):
269
- """SwiGLU(x) = (SiLU(x W_g + b_g) ⊙ (x W_v + b_v)) W_o + b_o."""
270
 
271
  def __init__(self, dim: int, hidden: int, bias: bool = True):
272
  super().__init__()
273
- self.gate_value = nn.Linear(dim, 2 * hidden, bias=bias)
274
- self.out = nn.Linear(hidden, dim, bias=bias)
275
 
276
  def forward(self, x: torch.Tensor) -> torch.Tensor:
277
- g, v = self.gate_value(x).chunk(2, dim=-1)
278
- return self.out(F.silu(g) * v)
279
 
280
 
281
  class KentWNNBlock(nn.Module):
282
- """Z' = A_N [ Z + SwiGLU(Norm(Z)) ] (residual trước DCT-II)."""
283
 
284
  def __init__(self, config: KentConfig):
285
  super().__init__()
286
  self.norm = KentRMSNorm(config.feature_dim, config.rms_norm_eps)
287
- self.swiglu = KentSwiGLU(config.feature_dim, config.intermediate_size, config.use_bias)
288
 
289
  def forward(self, z: torch.Tensor) -> torch.Tensor:
290
- return dct2(z + self.swiglu(self.norm(z)))
291
 
292
 
293
  class KentLayer(nn.Module):
 
5
 
6
  V = B_in(Norm_X(X)) # (…, N, d_h)
7
  Z = A_N V # DCT-II cố định trên trục N
8
+ u = A_N [ Z + MLP(Norm(Z)) ] # một WNN Block, MLP = Linear -> GeLU -> Linear
9
  H_t = (1 - a) H_{t-1} + a u_t # EMA, a = a_layer học được, riêng từng layer
10
  X' = X + B_out(Norm_H(H_t))
11
 
 
47
  num_hidden_layers: số KenT layer xếp chồng (mỗi layer có đúng một WNN Block).
48
  resolution_size: N, độ dài trục mà DCT-II tác động lên.
49
  feature_dim: d_h, số chiều đặc trưng trên mỗi vị trí resolution.
50
+ intermediate_size: kích thước hidden của MLP GeLU (trên trục d_h).
51
  rms_norm_eps: epsilon của RMSNorm.
52
+ use_bias: dùng bias trong Bilinear / MLP.
53
  initializer_range: độ lệch chuẩn khởi tạo trọng số.
54
  ema_alpha_first: a_layer khởi tạo của layer đầu (quên nhanh).
55
  ema_alpha_last: a_layer khởi tạo của layer cuối (nhớ lâu); các layer ở giữa nội suy
 
265
  return a * b
266
 
267
 
268
+ class KentMLP(nn.Module):
269
+ """MLP(x) = GeLU(x W_1 + b_1) W_2 + b_2."""
270
 
271
  def __init__(self, dim: int, hidden: int, bias: bool = True):
272
  super().__init__()
273
+ self.fc_in = nn.Linear(dim, hidden, bias=bias)
274
+ self.fc_out = nn.Linear(hidden, dim, bias=bias)
275
 
276
  def forward(self, x: torch.Tensor) -> torch.Tensor:
277
+ return self.fc_out(F.gelu(self.fc_in(x)))
 
278
 
279
 
280
  class KentWNNBlock(nn.Module):
281
+ """Z' = A_N [ Z + MLP(Norm(Z)) ] (residual trước DCT-II)."""
282
 
283
  def __init__(self, config: KentConfig):
284
  super().__init__()
285
  self.norm = KentRMSNorm(config.feature_dim, config.rms_norm_eps)
286
+ self.mlp = KentMLP(config.feature_dim, config.intermediate_size, config.use_bias)
287
 
288
  def forward(self, z: torch.Tensor) -> torch.Tensor:
289
+ return dct2(z + self.mlp(self.norm(z)))
290
 
291
 
292
  class KentLayer(nn.Module):