Bc-AI commited on
Commit
398a626
Β·
verified Β·
1 Parent(s): f92cfa5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +150 -214
app.py CHANGED
@@ -1,29 +1,40 @@
1
- # app.py β€” CodVa-2 HF Space Inference
2
-
3
  import torch
4
  import torch.nn as nn
5
  import torch.nn.functional as F
6
  import math
7
  import gradio as gr
8
- from huggingface_hub import hf_hub_download
9
  from transformers import GPT2Tokenizer
10
  import json
11
 
12
- # ── Minimal inference build (copy the primitives from your training script) ────
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
  class RMSNorm(nn.Module):
15
- def __init__(self, dim: int, eps: float = 1e-6):
16
  super().__init__()
17
  self.eps = eps
18
- self.w = nn.Parameter(torch.ones(dim))
19
  def forward(self, x):
20
  return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps) * self.w
21
 
22
- def build_rope(head_dim: int, max_len: int, theta: float, device):
23
  freqs = 1.0 / (theta ** (torch.arange(0, head_dim, 2, device=device).float() / head_dim))
24
- t = torch.arange(max_len, device=device).float()
25
- freqs = torch.outer(t, freqs)
26
- return torch.cos(freqs), torch.sin(freqs)
27
 
28
  def apply_rope(x, cos, sin):
29
  B, H, L, D = x.shape
@@ -35,7 +46,7 @@ def apply_rope(x, cos, sin):
35
  def repeat_kv(x, n_rep):
36
  if n_rep == 1: return x
37
  B, H, L, D = x.shape
38
- return x[:, :, None, :, :].expand(B, H, n_rep, L, D).reshape(B, H * n_rep, L, D)
39
 
40
  class SwiGLU(nn.Module):
41
  def __init__(self, dim, hidden):
@@ -59,7 +70,6 @@ class GQA(nn.Module):
59
  self.wo = nn.Linear(n_heads * self.hd, dim, bias=False)
60
  self.q_norm = RMSNorm(self.hd)
61
  self.k_norm = RMSNorm(self.hd)
62
-
63
  def forward(self, x, cos, sin):
64
  B, L, _ = x.shape
65
  q = self.wq(x).view(B, L, self.n_heads, self.hd).transpose(1, 2)
@@ -79,272 +89,198 @@ class TransformerBlock(nn.Module):
79
  self.attn = GQA(dim, n_heads, n_kv)
80
  self.ffn = SwiGLU(dim, ffn_dim)
81
  self.res_scale = 1.0 / math.sqrt(2.0 * max(n_layers, 1))
82
-
83
  def forward(self, x, cos, sin):
84
  x = x + self.res_scale * self.attn(self.norm1(x), cos, sin)
85
  x = x + self.res_scale * self.ffn(self.norm2(x))
86
  return x
87
 
88
  class FiLMBridge(nn.Module):
89
- def __init__(self, d_model):
90
  super().__init__()
91
- self.conv = nn.Conv1d(d_model, d_model, kernel_size=5, padding=2, groups=d_model)
92
- self.to_film = nn.Linear(d_model, d_model * 2)
93
-
94
  def forward(self, h):
95
- local = self.conv(h.transpose(1, 2)).transpose(1, 2)
96
  gamma, beta = self.to_film(local).chunk(2, dim=-1)
97
  return h * (1 + gamma) + beta
98
 
99
  class DepthTracker(nn.Module):
100
- def __init__(self, d_model, d_state=32):
101
  super().__init__()
102
- self.to_delta = nn.Linear(d_model, d_state)
103
- self.to_out = nn.Linear(d_state, d_model)
104
  self.decay = nn.Parameter(torch.ones(d_state) * 0.9)
105
-
106
  def forward(self, x):
107
- B, L, _ = x.shape
108
- delta = torch.tanh(self.to_delta(x))
109
- decay = torch.sigmoid(self.decay)
110
- depth = torch.zeros(B, delta.size(-1), device=x.device, dtype=x.dtype)
111
- outs = []
112
  for t in range(L):
113
  depth = depth * decay + delta[:, t]
114
  outs.append(depth)
115
  return self.to_out(torch.stack(outs, dim=1))
116
 
117
- class CNNBusContrib(nn.Module):
118
- def __init__(self, d_model):
119
  super().__init__()
120
- self.conv_n = nn.Conv1d(d_model, d_model, 3, padding=1, groups=d_model)
121
- self.conv_w = nn.Conv1d(d_model, d_model, 7, padding=3, groups=d_model)
122
- self.proj = nn.Linear(d_model * 2, d_model)
123
-
124
  def forward(self, x):
125
  t = x.transpose(1, 2)
126
  n = F.silu(self.conv_n(t)).transpose(1, 2)
127
  w = F.silu(self.conv_w(t)).transpose(1, 2)
128
  return self.proj(torch.cat([n, w], dim=-1))
129
 
130
- class RNNBusContrib(nn.Module):
131
- def __init__(self, d_model):
132
  super().__init__()
133
- self.gru = nn.GRU(d_model, d_model // 2, num_layers=1, batch_first=True)
134
- self.proj = nn.Linear(d_model // 2, d_model)
135
-
136
  def forward(self, x):
137
  out, _ = self.gru(x.float())
138
  return self.proj(out.to(x.dtype))
139
 
140
  class HighwayBus(nn.Module):
141
- def __init__(self, d_model):
142
  super().__init__()
143
- self.gate = nn.Linear(d_model * 2, d_model)
144
-
145
- def forward(self, bus, contribution):
146
- g = torch.sigmoid(self.gate(torch.cat([bus, contribution], dim=-1)))
147
- return bus + g * contribution
148
 
149
  class BusInjector(nn.Module):
150
  def __init__(self):
151
  super().__init__()
152
  self.gate = nn.Parameter(torch.zeros(1))
153
-
154
  def forward(self, h, bus):
155
  return h + torch.sigmoid(self.gate) * bus
156
 
157
- # ── CodVa-2 Inference Model ────
158
 
159
- class CodVa2Inference(nn.Module):
160
  def __init__(self, cfg):
161
  super().__init__()
162
  self.cfg = cfg
163
-
164
- self.embed = nn.Embedding(cfg['vocab_size'], cfg['d_model'])
165
- self.film = FiLMBridge(cfg['d_model'])
166
-
167
- self.blocks = nn.ModuleList([
168
- TransformerBlock(cfg['d_model'], cfg['n_heads'], cfg['n_kv_heads'],
169
- cfg['ffn_dim'], n_layers=cfg['n_layers'])
170
  for _ in range(cfg['n_layers'])
171
  ])
172
-
173
- self.bus_points = cfg['bus_points']
174
- self.highway = HighwayBus(cfg['d_model'])
175
- self.injectors = nn.ModuleList([BusInjector() for _ in self.bus_points])
176
-
177
- self.depth_tracker = DepthTracker(cfg['d_model'])
178
- self.cnn_1 = CNNBusContrib(cfg['d_model'])
179
- self.rnn = RNNBusContrib(cfg['d_model'])
180
- self.cnn_2 = CNNBusContrib(cfg['d_model'])
181
-
182
- self.norm_f = RMSNorm(cfg['d_model'])
183
- self.lm_head = nn.Linear(cfg['d_model'], cfg['vocab_size'], bias=False)
184
  self.final_injector = BusInjector()
185
-
186
- self.register_buffer("cos", torch.zeros(cfg['max_len'], cfg['d_model'] // cfg['n_heads'] // 2))
187
- self.register_buffer("sin", torch.zeros(cfg['max_len'], cfg['d_model'] // cfg['n_heads'] // 2))
188
-
189
- def _init_rope(self, device):
190
- cos, sin = build_rope(self.cfg['d_model'] // self.cfg['n_heads'],
191
- self.cfg['max_len'], 500000.0, device)
 
 
 
 
192
  self.cos.copy_(cos); self.sin.copy_(sin)
193
-
194
  @torch.no_grad()
195
- def generate(self, input_ids, max_new_tokens=100, temperature=0.7, top_p=0.9):
196
- """Generate tokens autoregressively."""
197
- device = self.embed.weight.device
198
-
199
- if self.cos.sum() == 0:
200
- self._init_rope(device)
201
-
202
- if not isinstance(input_ids, torch.Tensor):
203
- input_ids = torch.tensor([input_ids], device=device)
204
- else:
205
- input_ids = input_ids.to(device)
206
-
207
- if input_ids.dim() == 1:
208
- input_ids = input_ids.unsqueeze(0)
209
-
210
  for _ in range(max_new_tokens):
211
- L = input_ids.shape[1]
212
  if L > self.cfg['max_len']:
213
- input_ids = input_ids[:, -self.cfg['max_len']:]
214
- L = self.cfg['max_len']
215
-
216
- # Forward pass
217
- h = self.embed(input_ids)
218
- h = self.film(h)
219
  bus = torch.zeros_like(h)
220
-
221
- bp = self.bus_points
222
  for i, block in enumerate(self.blocks):
223
- h = block(h, self.cos[:L], self.sin[:L])
224
- if i == bp[0]:
225
- bus = self.highway(bus, self.depth_tracker(h))
226
- h = self.injectors[0](h, bus)
227
- elif i == bp[1]:
228
- bus = self.highway(bus, self.cnn_1(h))
229
- h = self.injectors[1](h, bus)
230
- elif i == bp[2]:
231
- h = self.injectors[2](h, bus)
232
- elif i == bp[3]:
233
- bus = self.highway(bus, self.rnn(h))
234
- h = self.injectors[3](h, bus)
235
-
236
  bus = self.highway(bus, self.cnn_2(h))
237
- h = self.final_injector(h, bus)
238
- h = self.norm_f(h)
239
-
240
- logits = self.lm_head(h[:, -1:, :])
241
- logits = 30.0 * torch.tanh(logits / 30.0)
242
-
243
- # Sample
244
- probs = F.softmax(logits / temperature, dim=-1)
245
- sorted_probs, sorted_indices = torch.sort(probs, descending=True)
246
- cumsum = torch.cumsum(sorted_probs, dim=-1)
247
- mask = cumsum <= top_p
248
- mask[..., 0] = True
249
- filtered_probs = sorted_probs * mask.float()
250
- filtered_probs /= filtered_probs.sum(dim=-1, keepdim=True) + 1e-9
251
-
252
- next_token = torch.multinomial(filtered_probs.squeeze(1), 1)
253
- input_ids = torch.cat([input_ids, next_token], dim=1)
254
-
255
- return input_ids[0].tolist()
256
-
257
- # ── Load Model & Tokenizer ────
258
-
259
- MODEL_REPO = "hugging-science/CodVa-2-session-001"
260
- CHECKPOINT = "codva2_s001_step0001680.pt"
261
-
262
- print("Loading model...")
263
- device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
264
-
265
- # Download config
266
- config_path = hf_hub_download(MODEL_REPO, "config.json")
267
- with open(config_path) as f:
268
- cfg = json.load(f)
269
-
270
- # Download checkpoint
271
- ckpt_path = hf_hub_download(MODEL_REPO, CHECKPOINT)
272
-
273
- # Build & load model
274
- model = CodVa2Inference(cfg).to(device)
275
- state = torch.load(ckpt_path, map_location=device)
276
- model.load_state_dict(state['model'], strict=False)
277
  model.eval()
 
278
 
279
- # Load GPT2 tokenizer
280
- try:
281
- tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
282
- except:
283
- tokenizer = GPT2Tokenizer.from_pretrained("openai-community/gpt2")
284
-
285
- print(f"Model loaded: {sum(p.numel() for p in model.parameters())/1e6:.1f}M params")
286
 
287
- # ── Gradio Interface ────
288
-
289
- def generate_code(prompt: str, max_tokens: int = 100, temperature: float = 0.7, top_p: float = 0.9):
290
- """Generate code from prompt."""
291
  try:
292
- # Tokenize
293
- input_ids = tokenizer.encode(prompt, return_tensors="pt")[0]
294
-
295
- # Generate
296
- output_ids = model.generate(input_ids.tolist(), max_new_tokens=max_tokens,
297
- temperature=temperature, top_p=top_p)
298
-
299
- # Decode
300
- output = tokenizer.decode(output_ids, skip_special_tokens=True)
301
-
302
- return output
303
  except Exception as e:
304
- return f"Error: {str(e)}"
305
 
306
- # Gradio UI
307
- with gr.Blocks(title="CodVa-2") as demo:
308
- gr.Markdown("# CodVa-2 β€” Deep-Narrow Code Model")
309
- gr.Markdown("221M parameters, trained on 10B tokens of code+math")
310
-
 
311
  with gr.Row():
312
  with gr.Column():
313
- prompt = gr.Textbox(
314
- label="Prompt",
315
- placeholder="def fibonacci(n):",
316
- lines=5,
317
- value="def hello():"
318
- )
319
-
320
  with gr.Row():
321
- max_tokens = gr.Slider(10, 300, value=100, step=10, label="Max Tokens")
322
- temperature = gr.Slider(0.0, 2.0, value=0.7, step=0.1, label="Temperature")
323
- top_p = gr.Slider(0.0, 1.0, value=0.9, step=0.05, label="Top-P")
324
-
325
- generate_btn = gr.Button("Generate", variant="primary")
326
-
327
  with gr.Column():
328
- output = gr.Textbox(
329
- label="Generated Code",
330
- lines=10,
331
- interactive=False
332
- )
333
-
334
- generate_btn.click(
335
- fn=generate_code,
336
- inputs=[prompt, max_tokens, temperature, top_p],
337
- outputs=output
338
- )
339
-
340
- gr.Markdown("""
341
- ## About CodVa-2
342
- - **Architecture**: 24-layer deep-narrow transformer (768d) with GQA
343
- - **Highway Bus**: FiLM bridge, DepthTracker, CNN experts, RNN expert
344
- - **Training**: 10B mixed code+math tokens (StarCoder + FineWeb)
345
- - **Stability**: Residual scaling, logit soft-cap, gradient clipping
346
- - **Status**: Early checkpoint (step 1680) β€” expect improvement
347
- """)
348
 
349
- if __name__ == "__main__":
350
- demo.launch(share=True)
 
 
 
1
  import torch
2
  import torch.nn as nn
3
  import torch.nn.functional as F
4
  import math
5
  import gradio as gr
6
+ from huggingface_hub import hf_hub_download, HfApi
7
  from transformers import GPT2Tokenizer
8
  import json
9
 
10
+ # ── Hardcoded config ──────────────────────────────────────────────────────────
11
+ CFG = {
12
+ "vocab_size": 50304,
13
+ "d_model": 768,
14
+ "n_layers": 24,
15
+ "n_heads": 12,
16
+ "n_kv_heads": 3,
17
+ "ffn_dim": 1792,
18
+ "max_len": 2048,
19
+ "bus_points": [4, 9, 15, 21],
20
+ }
21
+
22
+ MODEL_REPO = "hugging-science/CodVa-2-session-001"
23
+
24
+ # ── Primitives ────────────────────────────────────────────────────────────────
25
 
26
  class RMSNorm(nn.Module):
27
+ def __init__(self, dim, eps=1e-6):
28
  super().__init__()
29
  self.eps = eps
30
+ self.w = nn.Parameter(torch.ones(dim))
31
  def forward(self, x):
32
  return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps) * self.w
33
 
34
+ def build_rope(head_dim, max_len, theta, device):
35
  freqs = 1.0 / (theta ** (torch.arange(0, head_dim, 2, device=device).float() / head_dim))
36
+ t = torch.arange(max_len, device=device).float()
37
+ return torch.cos(torch.outer(t, freqs)), torch.sin(torch.outer(t, freqs))
 
38
 
39
  def apply_rope(x, cos, sin):
40
  B, H, L, D = x.shape
 
46
  def repeat_kv(x, n_rep):
47
  if n_rep == 1: return x
48
  B, H, L, D = x.shape
49
+ return x[:, :, None, :, :].expand(B, H, n_rep, L, D).reshape(B, H*n_rep, L, D)
50
 
51
  class SwiGLU(nn.Module):
52
  def __init__(self, dim, hidden):
 
70
  self.wo = nn.Linear(n_heads * self.hd, dim, bias=False)
71
  self.q_norm = RMSNorm(self.hd)
72
  self.k_norm = RMSNorm(self.hd)
 
73
  def forward(self, x, cos, sin):
74
  B, L, _ = x.shape
75
  q = self.wq(x).view(B, L, self.n_heads, self.hd).transpose(1, 2)
 
89
  self.attn = GQA(dim, n_heads, n_kv)
90
  self.ffn = SwiGLU(dim, ffn_dim)
91
  self.res_scale = 1.0 / math.sqrt(2.0 * max(n_layers, 1))
 
92
  def forward(self, x, cos, sin):
93
  x = x + self.res_scale * self.attn(self.norm1(x), cos, sin)
94
  x = x + self.res_scale * self.ffn(self.norm2(x))
95
  return x
96
 
97
  class FiLMBridge(nn.Module):
98
+ def __init__(self, d):
99
  super().__init__()
100
+ self.conv = nn.Conv1d(d, d, 5, padding=2, groups=d)
101
+ self.to_film = nn.Linear(d, d * 2)
 
102
  def forward(self, h):
103
+ local = self.conv(h.transpose(1,2)).transpose(1,2)
104
  gamma, beta = self.to_film(local).chunk(2, dim=-1)
105
  return h * (1 + gamma) + beta
106
 
107
  class DepthTracker(nn.Module):
108
+ def __init__(self, d, d_state=32):
109
  super().__init__()
110
+ self.to_delta = nn.Linear(d, d_state)
111
+ self.to_out = nn.Linear(d_state, d)
112
  self.decay = nn.Parameter(torch.ones(d_state) * 0.9)
 
113
  def forward(self, x):
114
+ B, L, _ = x.shape
115
+ delta = torch.tanh(self.to_delta(x))
116
+ decay = torch.sigmoid(self.decay)
117
+ depth = torch.zeros(B, delta.size(-1), device=x.device, dtype=x.dtype)
118
+ outs = []
119
  for t in range(L):
120
  depth = depth * decay + delta[:, t]
121
  outs.append(depth)
122
  return self.to_out(torch.stack(outs, dim=1))
123
 
124
+ class CNNBus(nn.Module):
125
+ def __init__(self, d):
126
  super().__init__()
127
+ self.conv_n = nn.Conv1d(d, d, 3, padding=1, groups=d)
128
+ self.conv_w = nn.Conv1d(d, d, 7, padding=3, groups=d)
129
+ self.proj = nn.Linear(d * 2, d)
 
130
  def forward(self, x):
131
  t = x.transpose(1, 2)
132
  n = F.silu(self.conv_n(t)).transpose(1, 2)
133
  w = F.silu(self.conv_w(t)).transpose(1, 2)
134
  return self.proj(torch.cat([n, w], dim=-1))
135
 
136
+ class RNNBus(nn.Module):
137
+ def __init__(self, d):
138
  super().__init__()
139
+ self.gru = nn.GRU(d, d // 2, batch_first=True)
140
+ self.proj = nn.Linear(d // 2, d)
 
141
  def forward(self, x):
142
  out, _ = self.gru(x.float())
143
  return self.proj(out.to(x.dtype))
144
 
145
  class HighwayBus(nn.Module):
146
+ def __init__(self, d):
147
  super().__init__()
148
+ self.gate = nn.Linear(d * 2, d)
149
+ def forward(self, bus, contrib):
150
+ g = torch.sigmoid(self.gate(torch.cat([bus, contrib], dim=-1)))
151
+ return bus + g * contrib
 
152
 
153
  class BusInjector(nn.Module):
154
  def __init__(self):
155
  super().__init__()
156
  self.gate = nn.Parameter(torch.zeros(1))
 
157
  def forward(self, h, bus):
158
  return h + torch.sigmoid(self.gate) * bus
159
 
160
+ # ── Model ─────────────────────────────────────────────────────────────────────
161
 
162
+ class CodVa2(nn.Module):
163
  def __init__(self, cfg):
164
  super().__init__()
165
  self.cfg = cfg
166
+ D = cfg['d_model']
167
+ self.embed = nn.Embedding(cfg['vocab_size'], D)
168
+ self.film = FiLMBridge(D)
169
+ self.blocks = nn.ModuleList([
170
+ TransformerBlock(D, cfg['n_heads'], cfg['n_kv_heads'],
171
+ cfg['ffn_dim'], cfg['n_layers'])
 
172
  for _ in range(cfg['n_layers'])
173
  ])
174
+ self.bus_points = cfg['bus_points']
175
+ self.highway = HighwayBus(D)
176
+ self.injectors = nn.ModuleList([BusInjector() for _ in self.bus_points])
177
+ self.depth_tracker = DepthTracker(D)
178
+ self.cnn_1 = CNNBus(D)
179
+ self.rnn = RNNBus(D)
180
+ self.cnn_2 = CNNBus(D)
 
 
 
 
 
181
  self.final_injector = BusInjector()
182
+ self.norm_f = RMSNorm(D)
183
+ self.lm_head = nn.Linear(D, cfg['vocab_size'], bias=False)
184
+ hd = D // cfg['n_heads']
185
+ self.register_buffer("cos", torch.zeros(cfg['max_len'], hd // 2))
186
+ self.register_buffer("sin", torch.zeros(cfg['max_len'], hd // 2))
187
+
188
+ def _init_rope(self):
189
+ cos, sin = build_rope(
190
+ self.cfg['d_model'] // self.cfg['n_heads'],
191
+ self.cfg['max_len'], 500000.0,
192
+ self.embed.weight.device)
193
  self.cos.copy_(cos); self.sin.copy_(sin)
194
+
195
  @torch.no_grad()
196
+ def generate(self, input_ids, max_new_tokens=128, temperature=0.8, top_p=0.92):
197
+ if self.cos.sum() == 0: self._init_rope()
198
+ ids = torch.tensor([input_ids]) if not isinstance(input_ids, torch.Tensor) \
199
+ else input_ids.unsqueeze(0)
200
+ bp = self.bus_points
 
 
 
 
 
 
 
 
 
 
201
  for _ in range(max_new_tokens):
202
+ L = ids.shape[1]
203
  if L > self.cfg['max_len']:
204
+ ids = ids[:, -self.cfg['max_len']:]
205
+ L = ids.shape[1]
206
+ h = self.embed(ids)
207
+ h = self.film(h)
 
 
208
  bus = torch.zeros_like(h)
209
+ cos = self.cos[:L]; sin = self.sin[:L]
 
210
  for i, block in enumerate(self.blocks):
211
+ h = block(h, cos, sin)
212
+ if i == bp[0]: bus = self.highway(bus, self.depth_tracker(h)); h = self.injectors[0](h, bus)
213
+ elif i == bp[1]: bus = self.highway(bus, self.cnn_1(h)); h = self.injectors[1](h, bus)
214
+ elif i == bp[2]: h = self.injectors[2](h, bus)
215
+ elif i == bp[3]: bus = self.highway(bus, self.rnn(h)); h = self.injectors[3](h, bus)
 
 
 
 
 
 
 
 
216
  bus = self.highway(bus, self.cnn_2(h))
217
+ h = self.final_injector(h, bus)
218
+ h = self.norm_f(h)
219
+ logits = 30.0 * torch.tanh(self.lm_head(h[:, -1, :]) / 30.0)
220
+ probs = F.softmax(logits / temperature, dim=-1)
221
+ sp, si = torch.sort(probs, descending=True)
222
+ mask = (torch.cumsum(sp, dim=-1) - sp) < top_p
223
+ sp[~mask] = 0.0
224
+ sp /= sp.sum() + 1e-9
225
+ next_tok = si[torch.multinomial(sp, 1)]
226
+ ids = torch.cat([ids, next_tok.unsqueeze(0)], dim=1)
227
+ if next_tok.item() == 50256: break # GPT2 EOS
228
+ return ids[0].tolist()
229
+
230
+ # ── Load ──────────────────────────────────────────────────────────────────────
231
+
232
+ print("Loading tokenizer...")
233
+ tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
234
+
235
+ print("Finding latest checkpoint...")
236
+ api = HfApi()
237
+ files = list(api.list_repo_files(MODEL_REPO))
238
+ ckpts = sorted([f for f in files if f.endswith(".pt") and "step" in f],
239
+ key=lambda x: int(x.split("step")[-1].split(".")[0]))
240
+ latest = ckpts[-1]
241
+ print(f"Loading {latest}...")
242
+ ckpt = torch.load(hf_hub_download(MODEL_REPO, latest), map_location="cpu")
243
+
244
+ model = CodVa2(CFG)
245
+ model.load_state_dict(ckpt['model'], strict=False)
 
 
 
 
 
 
 
 
 
 
 
246
  model.eval()
247
+ print(f"Ready! {sum(p.numel() for p in model.parameters())/1e6:.1f}M params")
248
 
249
+ # ── Gradio ────────────────────────────────────────────────────────────────────
 
 
 
 
 
 
250
 
251
+ def generate(prompt, max_tokens, temperature, top_p):
252
+ if not prompt.strip(): return "Enter a prompt."
 
 
253
  try:
254
+ ids = tokenizer.encode(prompt)[-256:]
255
+ out = model.generate(ids, int(max_tokens), float(temperature), float(top_p))
256
+ return tokenizer.decode(out, skip_special_tokens=True)
 
 
 
 
 
 
 
 
257
  except Exception as e:
258
+ return f"Error: {e}"
259
 
260
+ with gr.Blocks(title="CodVa-2", theme=gr.themes.Monochrome()) as demo:
261
+ gr.Markdown("""
262
+ # 🍰 CodVa-2 β€” Code Model
263
+ **221M params** | 24LΓ—768d | Highway Bus | GQA
264
+ ⚠️ *CPU only β€” ~30-60s per generation. Early checkpoint, still training.*
265
+ """)
266
  with gr.Row():
267
  with gr.Column():
268
+ prompt = gr.Textbox(label="Prompt", lines=5,
269
+ value="def fibonacci(n):\n ")
 
 
 
 
 
270
  with gr.Row():
271
+ max_tok = gr.Slider(10, 200, 80, step=10, label="Max Tokens")
272
+ temp = gr.Slider(0.1, 2.0, 0.8, step=0.1, label="Temperature")
273
+ topp = gr.Slider(0.1, 1.0, 0.92,step=0.05,label="Top-P")
274
+ btn = gr.Button("Generate πŸš€", variant="primary")
 
 
275
  with gr.Column():
276
+ out = gr.Textbox(label="Output", lines=10, interactive=False)
277
+
278
+ btn.click(generate, [prompt, max_tok, temp, topp], out)
279
+
280
+ gr.Examples([
281
+ ["def fibonacci(n):\n ", 100, 0.8, 0.92],
282
+ ["class Stack:\n def __init__(self):\n ", 120, 0.8, 0.92],
283
+ ["# binary search\ndef search(arr, target):\n ", 100, 0.7, 0.9],
284
+ ], [prompt, max_tok, temp, topp])
 
 
 
 
 
 
 
 
 
 
 
285
 
286
+ demo.launch()