glouriousgautam commited on
Commit
424a875
·
verified ·
1 Parent(s): 15ddd38

Upload lilm 16K recovery pilot

Browse files
Files changed (6) hide show
  1. README.md +9 -0
  2. config.json +16 -0
  3. model.py +434 -0
  4. model.safetensors +3 -0
  5. tokenizer.json +0 -0
  6. tokenizer_config.json +34 -0
README.md ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ pipeline_tag: text-generation
4
+ ---
5
+ # lilm1-200m 16K recovery pilot
6
+
7
+ Controlled 299.63M-token continuation from the 2K/27B base checkpoint.
8
+ The mixture is 34% document-contiguous 16K Longmino data and 66% 2K replay.
9
+ This is an experimental base checkpoint and requires the custom `model.py`.
config.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "vocab_size": 49152,
3
+ "n_layer": 16,
4
+ "n_embd": 1024,
5
+ "n_head": 16,
6
+ "kv_heads": 4,
7
+ "intermediate_size": 2752,
8
+ "kernel_size": 4,
9
+ "attn_dropout_p": 0.1,
10
+ "resid_dropout_p": 0.05,
11
+ "n_conv_layers": 10,
12
+ "max_seq_len": 16384,
13
+ "rope_theta": 10000.0,
14
+ "use_native_gqa": true,
15
+ "activation_checkpointing": true
16
+ }
model.py ADDED
@@ -0,0 +1,434 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ lilm1-200m model definition — lilm hybrid local-convolution/attention model
3
+ ═════════════════════════════════════════════════════════════════════════════
4
+
5
+ Architecture:
6
+ - 10 local causal-convolution layers + 6 attention layers (16 total)
7
+ - GQA with n_head=16, kv_heads=4 (4:1 ratio)
8
+ - SwiGLU FFN (intermediate_size=2752)
9
+ - RMSNorm (learnable, eps=1e-6)
10
+ - RoPE positional encoding
11
+ - Attention via PyTorch SDPA (FlashAttention/math backend auto-dispatch)
12
+ - Residual dropout on all residual paths
13
+ - Untied embedding / lm_head weights
14
+ - Causal depthwise 1D convolution for local token mixing
15
+
16
+ Paste this entire cell into the "PASTE YOUR MODEL DEFINITION BELOW" cell.
17
+ ═════════════════════════════════════════════════════════════════════════════
18
+ """
19
+
20
+ from dataclasses import dataclass
21
+ from typing import Optional
22
+ import math
23
+
24
+ import torch
25
+ import torch.nn as nn
26
+ import torch.nn.functional as F
27
+
28
+
29
+ # ── Config ────────────────────────────────────────────────────────────────────
30
+
31
+ @dataclass
32
+ class LilmConfig:
33
+ vocab_size: int = 49152
34
+ n_layer: int = 16 # 10 Conv + 6 Attention
35
+ n_embd: int = 1024
36
+ n_head: int = 16
37
+ kv_heads: int = 4 # GQA 4:1
38
+ intermediate_size: int = 2752 # SwiGLU hidden dim
39
+ kernel_size: int = 4 # Conv window
40
+ attn_dropout_p: float = 0.1 # Passed to PyTorch SDPA
41
+ resid_dropout_p: float = 0.05 # nn.Dropout on residual paths
42
+ n_conv_layers: int = 10 # First 10 layers are Conv
43
+ max_seq_len: int = 2048 # For RoPE precomputation
44
+ rope_theta: float = 10_000.0 # RoPE base frequency
45
+ use_native_gqa: bool = True # Use SDPA's native GQA when available
46
+ activation_checkpointing: bool = False # Recompute layer activations to save memory
47
+
48
+ @property
49
+ def head_dim(self) -> int:
50
+ return self.n_embd // self.n_head
51
+
52
+ @property
53
+ def n_attn_layers(self) -> int:
54
+ return self.n_layer - self.n_conv_layers
55
+
56
+
57
+ # ── RMSNorm ───────────────────────────────────────────────────────────────────
58
+
59
+ class RMSNorm(nn.Module):
60
+ """Root Mean Square Layer Normalization (Zhang & Sennrich, 2019)."""
61
+
62
+ def __init__(self, dim: int, eps: float = 1e-6):
63
+ super().__init__()
64
+ self.weight = nn.Parameter(torch.ones(dim))
65
+ self.eps = eps
66
+
67
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
68
+ norm = x.float().pow(2).mean(-1, keepdim=True).add(self.eps).rsqrt()
69
+ return (x.float() * norm).type_as(x) * self.weight
70
+
71
+
72
+ # ── RoPE ──────────────────────────────────────────────────────────────────────
73
+
74
+ def precompute_rope_freqs(
75
+ head_dim: int,
76
+ max_seq_len: int,
77
+ theta: float = 10_000.0,
78
+ device: Optional[torch.device] = None,
79
+ ) -> torch.Tensor:
80
+ """Precompute complex exponentials for RoPE: shape (max_seq_len, head_dim//2)."""
81
+ freqs = 1.0 / (theta ** (torch.arange(0, head_dim, 2, device=device).float() / head_dim))
82
+ t = torch.arange(max_seq_len, device=device).float()
83
+ freqs = torch.outer(t, freqs) # (T, head_dim//2)
84
+ return torch.polar(torch.ones_like(freqs), freqs) # complex64
85
+
86
+
87
+ def apply_rope(
88
+ x: torch.Tensor, # (B, T, n_head, head_dim)
89
+ freqs_cis: torch.Tensor, # (T, head_dim//2)
90
+ ) -> torch.Tensor:
91
+ """Apply rotary positional embeddings to q or k."""
92
+ B, T, H, D = x.shape
93
+ # View as pairs of (real, imag)
94
+ x_complex = torch.view_as_complex(x.float().reshape(B, T, H, D // 2, 2))
95
+ freqs = freqs_cis[:T].unsqueeze(0).unsqueeze(2) # (1, T, 1, head_dim//2)
96
+ x_rotated = x_complex * freqs
97
+ return torch.view_as_real(x_rotated).reshape(B, T, H, D).type_as(x)
98
+
99
+
100
+ # ── SwiGLU FFN ────────────────────────────────────────────────────────────────
101
+
102
+ class SwiGLUFFN(nn.Module):
103
+ """
104
+ SwiGLU Feed-Forward Network (Shazeer 2020, Touvron et al. 2023).
105
+ gate = Swish(x W_gate)
106
+ out = (gate ⊙ (x W_up)) W_down
107
+ """
108
+
109
+ def __init__(self, config: LilmConfig):
110
+ super().__init__()
111
+ self.w_gate = nn.Linear(config.n_embd, config.intermediate_size, bias=False)
112
+ self.w_up = nn.Linear(config.n_embd, config.intermediate_size, bias=False)
113
+ self.w_down = nn.Linear(config.intermediate_size, config.n_embd, bias=False)
114
+
115
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
116
+ return self.w_down(F.silu(self.w_gate(x)) * self.w_up(x))
117
+
118
+
119
+ # ── GQA Attention ────────────────────────────────────────────────────────────
120
+
121
+ class LilmAttention(nn.Module):
122
+ """
123
+ Grouped Query Attention using PyTorch scaled_dot_product_attention.
124
+
125
+ n_head=16 query heads, kv_heads=4 key/value heads → 4:1 GQA ratio.
126
+ KV heads are expanded explicitly for broad PyTorch compatibility; SDPA
127
+ still dispatches to the best available CUDA backend for the resulting
128
+ dense-head causal attention.
129
+ """
130
+
131
+ def __init__(self, config: LilmConfig):
132
+ super().__init__()
133
+ self.n_head = config.n_head
134
+ self.kv_heads = config.kv_heads
135
+ self.head_dim = config.head_dim
136
+ self.n_rep = config.n_head // config.kv_heads # 4 — repeat factor for GQA
137
+ self.attn_dropout_p = config.attn_dropout_p
138
+ self.use_native_gqa = (
139
+ config.use_native_gqa
140
+ and "enable_gqa" in (F.scaled_dot_product_attention.__doc__ or "")
141
+ )
142
+
143
+ # Projections
144
+ self.q_proj = nn.Linear(config.n_embd, config.n_head * config.head_dim, bias=False)
145
+ self.k_proj = nn.Linear(config.n_embd, config.kv_heads * config.head_dim, bias=False)
146
+ self.v_proj = nn.Linear(config.n_embd, config.kv_heads * config.head_dim, bias=False)
147
+ self.o_proj = nn.Linear(config.n_head * config.head_dim, config.n_embd, bias=False)
148
+
149
+ def _expand_kv(self, x: torch.Tensor) -> torch.Tensor:
150
+ """Repeat KV heads to match query head count: (B,T,kv_heads,D) → (B,T,n_head,D)."""
151
+ if self.n_rep == 1:
152
+ return x
153
+ B, T, H, D = x.shape
154
+ return x[:, :, :, None, :].expand(B, T, H, self.n_rep, D).reshape(B, T, H * self.n_rep, D)
155
+
156
+ def forward(
157
+ self,
158
+ x: torch.Tensor, # (B, T, n_embd)
159
+ freqs_cis: torch.Tensor, # (max_seq_len, head_dim//2)
160
+ ) -> torch.Tensor:
161
+ B, T, _ = x.shape
162
+
163
+ # Project → (B, T, n_heads, head_dim)
164
+ q = self.q_proj(x).reshape(B, T, self.n_head, self.head_dim)
165
+ k = self.k_proj(x).reshape(B, T, self.kv_heads, self.head_dim)
166
+ v = self.v_proj(x).reshape(B, T, self.kv_heads, self.head_dim)
167
+
168
+ # Apply RoPE to queries and keys
169
+ q = apply_rope(q, freqs_cis)
170
+ k = apply_rope(k, freqs_cis)
171
+
172
+ dropout_p = self.attn_dropout_p if self.training else 0.0
173
+
174
+ # Use PyTorch SDPA, which auto-dispatches to the best available
175
+ # attention backend on supported hardware.
176
+ # SDPA expects (B, H, T, D) layout
177
+ q = q.transpose(1, 2)
178
+ if self.use_native_gqa:
179
+ k = k.transpose(1, 2)
180
+ v = v.transpose(1, 2)
181
+ out = F.scaled_dot_product_attention(
182
+ q, k, v,
183
+ dropout_p=dropout_p,
184
+ is_causal=True,
185
+ enable_gqa=True,
186
+ )
187
+ else:
188
+ # Compatibility fallback for PyTorch builds without native GQA.
189
+ k = self._expand_kv(k).transpose(1, 2)
190
+ v = self._expand_kv(v).transpose(1, 2)
191
+ out = F.scaled_dot_product_attention(
192
+ q, k, v,
193
+ dropout_p=dropout_p,
194
+ is_causal=True,
195
+ )
196
+ out = out.transpose(1, 2) # back to (B, T, H, D)
197
+
198
+ # Merge heads → project out
199
+ out = out.reshape(B, T, self.n_head * self.head_dim)
200
+ return self.o_proj(out)
201
+
202
+
203
+ # ── Causal Depthwise Conv ────────────────────────────────────────────────────
204
+
205
+ class CausalDepthwiseConv1d(nn.Module):
206
+ """
207
+ Causal depthwise 1D convolution (Mamba/Hyena style).
208
+
209
+ Each channel is convolved independently with its own kernel.
210
+ Left-padded to preserve causality — output at position t depends
211
+ only on inputs at positions [t - kernel_size + 1, ..., t].
212
+ """
213
+
214
+ def __init__(self, channels: int, kernel_size: int):
215
+ super().__init__()
216
+ self.kernel_size = kernel_size
217
+ # groups=channels → depthwise (each channel has its own filter)
218
+ self.conv = nn.Conv1d(
219
+ in_channels = channels,
220
+ out_channels = channels,
221
+ kernel_size = kernel_size,
222
+ padding = 0, # We handle causal padding manually
223
+ groups = channels,
224
+ bias = True,
225
+ )
226
+
227
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
228
+ """x: (B, T, C) → (B, T, C)"""
229
+ # Transpose to (B, C, T) for Conv1d
230
+ x = x.transpose(1, 2)
231
+ # Causal left-padding: pad (kernel_size - 1) zeros on the left
232
+ x = F.pad(x, (self.kernel_size - 1, 0))
233
+ x = self.conv(x)
234
+ return x.transpose(1, 2) # Back to (B, T, C)
235
+
236
+
237
+ # ── Conv Mixer Block (for Conv layers) ───────────────────────────────────────
238
+
239
+ class ConvMixerBlock(nn.Module):
240
+ """
241
+ Conv-based block (used in layers 0–9):
242
+ x → RMSNorm → CausalDepthwiseConv → SiLU → Linear(project) → residual dropout → +x
243
+ x → RMSNorm → SwiGLU FFN → residual dropout → +x
244
+
245
+ The conv branch replaces attention with a local causal mixing mechanism.
246
+ SiLU activation after conv + a linear projection keeps dimensionality matched.
247
+ """
248
+
249
+ def __init__(self, config: LilmConfig):
250
+ super().__init__()
251
+ self.norm1 = RMSNorm(config.n_embd)
252
+ self.norm2 = RMSNorm(config.n_embd)
253
+
254
+ # Conv branch: depthwise conv → activation → pointwise projection
255
+ self.conv1d = CausalDepthwiseConv1d(config.n_embd, config.kernel_size)
256
+ self.conv_proj = nn.Linear(config.n_embd, config.n_embd, bias=False)
257
+
258
+ # FFN
259
+ self.mlp = SwiGLUFFN(config)
260
+
261
+ # Residual dropout
262
+ self.resid_drop = nn.Dropout(p=config.resid_dropout_p)
263
+
264
+ def forward(self, x: torch.Tensor, **kwargs) -> torch.Tensor:
265
+ # Conv mixing path
266
+ h = self.norm1(x)
267
+ h = self.conv1d(h)
268
+ h = F.silu(h)
269
+ h = self.conv_proj(h)
270
+ x = x + self.resid_drop(h)
271
+
272
+ # FFN path
273
+ x = x + self.resid_drop(self.mlp(self.norm2(x)))
274
+ return x
275
+
276
+
277
+ # ── Attention Block (for Attention layers) ───────────────────────────────────
278
+
279
+ class AttentionBlock(nn.Module):
280
+ """
281
+ Standard transformer block (used in layers 10–15):
282
+ x → RMSNorm → GQA Attention (SDPA) → residual dropout → +x
283
+ x → RMSNorm → SwiGLU FFN → residual dropout → +x
284
+ """
285
+
286
+ def __init__(self, config: LilmConfig):
287
+ super().__init__()
288
+ self.norm1 = RMSNorm(config.n_embd)
289
+ self.norm2 = RMSNorm(config.n_embd)
290
+
291
+ self.attn = LilmAttention(config)
292
+ self.mlp = SwiGLUFFN(config)
293
+
294
+ self.resid_drop = nn.Dropout(p=config.resid_dropout_p)
295
+
296
+ def forward(
297
+ self,
298
+ x: torch.Tensor,
299
+ freqs_cis: torch.Tensor,
300
+ ) -> torch.Tensor:
301
+ x = x + self.resid_drop(self.attn(self.norm1(x), freqs_cis))
302
+ x = x + self.resid_drop(self.mlp(self.norm2(x)))
303
+ return x
304
+
305
+
306
+ # ── Full Model ────────────────────────────────────────────────────────────────
307
+
308
+ class LilmModel(nn.Module):
309
+ """
310
+ lilm hybrid local-convolution/attention model.
311
+
312
+ - Untied embedding + lm_head
313
+ - RoPE applied only in attention layers
314
+ - Pre-norm (RMSNorm) architecture
315
+ - Final RMSNorm before lm_head
316
+
317
+ Forward returns logits: (B, T, vocab_size)
318
+ """
319
+
320
+ def __init__(self, config: LilmConfig):
321
+ super().__init__()
322
+ self.config = config
323
+
324
+ # Token embedding (untied — separate from lm_head)
325
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.n_embd)
326
+
327
+ # Hybrid layers: first n_conv_layers are Conv, rest are Attention
328
+ self.layers = nn.ModuleList()
329
+ for i in range(config.n_layer):
330
+ if i < config.n_conv_layers:
331
+ self.layers.append(ConvMixerBlock(config))
332
+ else:
333
+ self.layers.append(AttentionBlock(config))
334
+
335
+ # Final norm + output head (untied)
336
+ self.final_norm = RMSNorm(config.n_embd)
337
+ self.lm_head = nn.Linear(config.n_embd, config.vocab_size, bias=False)
338
+
339
+ # Precompute RoPE frequencies (registered as buffer — not a parameter)
340
+ freqs_cis = precompute_rope_freqs(
341
+ config.head_dim,
342
+ config.max_seq_len,
343
+ config.rope_theta,
344
+ )
345
+ self.register_buffer("freqs_cis", freqs_cis, persistent=False)
346
+
347
+ # Initialise weights
348
+ self._init_weights()
349
+
350
+ # Report parameter count
351
+ n_params = sum(p.numel() for p in self.parameters())
352
+ print(f"LilmModel — {n_params / 1e6:.2f}M parameters")
353
+ print(f" Conv layers : {config.n_conv_layers} (layers 0–{config.n_conv_layers - 1})")
354
+ print(f" Attn layers : {config.n_attn_layers} (layers {config.n_conv_layers}–{config.n_layer - 1})")
355
+ print(f" GQA ratio : {config.n_head}:{config.kv_heads}")
356
+ print(f" Head dim : {config.head_dim}")
357
+
358
+ def _init_weights(self):
359
+ """
360
+ Weight initialisation following GPT-NeoX / LLaMA conventions:
361
+ - Embeddings: N(0, 0.02)
362
+ - Linear: N(0, 0.02) with residual scaling on output projections
363
+ - Conv1d: N(0, 0.02)
364
+ - RMSNorm: ones (already default)
365
+ - Biases: zeros
366
+ """
367
+ residual_scale = 1.0 / math.sqrt(2.0 * self.config.n_layer)
368
+
369
+ for name, module in self.named_modules():
370
+ if isinstance(module, nn.Linear):
371
+ nn.init.normal_(module.weight, mean=0.0, std=0.02)
372
+ # Scale down residual-path output projections to stabilise deep nets
373
+ if any(tag in name for tag in ("o_proj", "w_down", "conv_proj")):
374
+ module.weight.data.mul_(residual_scale)
375
+ if module.bias is not None:
376
+ nn.init.zeros_(module.bias)
377
+ elif isinstance(module, nn.Embedding):
378
+ nn.init.normal_(module.weight, mean=0.0, std=0.02)
379
+ elif isinstance(module, nn.Conv1d):
380
+ nn.init.normal_(module.weight, mean=0.0, std=0.02)
381
+ if module.bias is not None:
382
+ nn.init.zeros_(module.bias)
383
+
384
+ def forward(self, input_ids: torch.Tensor) -> torch.Tensor:
385
+ """
386
+ Args:
387
+ input_ids: (B, T) token indices
388
+ Returns:
389
+ logits: (B, T, vocab_size)
390
+ """
391
+ B, T = input_ids.shape
392
+ assert T <= self.config.max_seq_len, (
393
+ f"Sequence length {T} exceeds max_seq_len {self.config.max_seq_len}"
394
+ )
395
+
396
+ # Embed tokens
397
+ x = self.embed_tokens(input_ids) # (B, T, n_embd)
398
+
399
+ # Pass through all layers
400
+ if self.config.activation_checkpointing and self.training:
401
+ from torch.utils.checkpoint import checkpoint
402
+
403
+ for layer in self.layers:
404
+ if isinstance(layer, AttentionBlock):
405
+ x = checkpoint(
406
+ lambda hidden, layer=layer: layer(hidden, freqs_cis=self.freqs_cis),
407
+ x,
408
+ use_reentrant=False,
409
+ )
410
+ else:
411
+ x = checkpoint(layer, x, use_reentrant=False)
412
+ else:
413
+ for layer in self.layers:
414
+ if isinstance(layer, AttentionBlock):
415
+ x = layer(x, freqs_cis=self.freqs_cis)
416
+ else:
417
+ x = layer(x)
418
+
419
+ # Final norm + logits
420
+ x = self.final_norm(x)
421
+ logits = self.lm_head(x) # (B, T, vocab_size)
422
+
423
+ return logits
424
+
425
+ def gradient_checkpointing_enable(self):
426
+ """Enable gradient checkpointing for memory-efficient training."""
427
+ self.config.activation_checkpointing = True
428
+
429
+
430
+ # Deprecated compatibility aliases for older notebooks/checkpoints that imported
431
+ # previous class names. New code should use LilmConfig and LilmModel.
432
+ LFMUpgradedConfig = LilmConfig
433
+ LiquidAttention = LilmAttention
434
+ LiquidUpgradedModel = LilmModel
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:94c9348432254ddb73edc622ef2bb6a43972d77573ac090feceaf149316276b1
3
+ size 1048929560
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": false,
3
+ "backend": "tokenizers",
4
+ "bos_token": "<|endoftext|>",
5
+ "clean_up_tokenization_spaces": false,
6
+ "eos_token": "<|endoftext|>",
7
+ "errors": "replace",
8
+ "extra_special_tokens": [
9
+ "<|endoftext|>",
10
+ "<|im_start|>",
11
+ "<|im_end|>",
12
+ "<repo_name>",
13
+ "<reponame>",
14
+ "<file_sep>",
15
+ "<filename>",
16
+ "<gh_stars>",
17
+ "<issue_start>",
18
+ "<issue_comment>",
19
+ "<issue_closed>",
20
+ "<jupyter_start>",
21
+ "<jupyter_text>",
22
+ "<jupyter_code>",
23
+ "<jupyter_output>",
24
+ "<jupyter_script>",
25
+ "<empty_output>"
26
+ ],
27
+ "is_local": false,
28
+ "local_files_only": false,
29
+ "model_max_length": 8192,
30
+ "pad_token": null,
31
+ "tokenizer_class": "GPT2Tokenizer",
32
+ "unk_token": "<|endoftext|>",
33
+ "vocab_size": 49152
34
+ }