brulee-1 commited on
Commit
f9fa117
ยท
verified ยท
1 Parent(s): 28290b4

feat: add decoding controls

Browse files
Files changed (1) hide show
  1. inference.py +53 -7
inference.py CHANGED
@@ -30,6 +30,33 @@ CTX_LEN = 2048
30
  BOS_ID, EOS_ID, EOT_ID = 0, 1, 6
31
 
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  # โ”€โ”€ Packed Linear Modules โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
34
 
35
  class Linear1bit(nn.Module):
@@ -254,23 +281,26 @@ class SSMoELMPacked(nn.Module):
254
 
255
  @torch.inference_mode()
256
  def generate(self, input_ids: list[int], max_new_tokens: int = 200,
257
- temperature: float = 0.8, top_p: float = 0.9,
 
258
  eos_ids: tuple[int, ...] = (EOS_ID, EOT_ID)) -> list[int]:
259
  ids = list(input_ids)
260
  generated = []
261
  for _ in range(max_new_tokens):
262
  x = torch.tensor([ids[-CTX_LEN:]], dtype=torch.long)
263
  logits = self(x)[0, -1]
 
 
 
264
  if temperature > 0:
265
- logits_np = logits.numpy().astype(np.float64)
266
- logits_np = (logits_np - logits_np.max()) / temperature
267
  probs = np.exp(logits_np); probs /= probs.sum()
268
  idx = np.argsort(-probs); cumsum = np.cumsum(probs[idx])
269
  cutoff = np.searchsorted(cumsum, top_p) + 1
270
  probs[idx[cutoff:]] = 0.0; probs /= probs.sum()
271
  next_id = int(np.random.choice(idx, p=probs))
272
  else:
273
- next_id = int(logits.argmax().item())
274
  if next_id in eos_ids:
275
  break
276
  generated.append(next_id)
@@ -369,8 +399,10 @@ def main():
369
  parser.add_argument("--prompt", default=None, help="Prompt for single-shot mode (--no-chat)")
370
  parser.add_argument("--no-chat", action="store_true", help="Single-shot mode")
371
  parser.add_argument("--max-tokens", type=int, default=200, help="Max new tokens to generate")
372
- parser.add_argument("--temperature", type=float, default=0.8, help="Sampling temperature")
373
  parser.add_argument("--top-p", type=float, default=0.9, help="Top-p nucleus sampling")
 
 
374
  args = parser.parse_args()
375
 
376
  print(f"Loading {args.ckpt} ...")
@@ -402,7 +434,14 @@ def main():
402
  continue
403
  ids = build_chat_prompt(tok, history, user_input)
404
  print("Assistant: ", end="", flush=True)
405
- out = model.generate(ids, args.max_tokens, args.temperature, args.top_p)
 
 
 
 
 
 
 
406
  response = tok.decode(out).strip()
407
  print(response)
408
  history.append((user_input, response))
@@ -412,7 +451,14 @@ def main():
412
  ids = [BOS_ID] + tok.encode(prompt).ids
413
  print(f"\nPrompt: {prompt}")
414
  print("Output: ", end="", flush=True)
415
- out = model.generate(ids, args.max_tokens, args.temperature, args.top_p)
 
 
 
 
 
 
 
416
  print(tok.decode(out))
417
 
418
 
 
30
  BOS_ID, EOS_ID, EOT_ID = 0, 1, 6
31
 
32
 
33
+ def apply_repetition_penalty(
34
+ logits: np.ndarray,
35
+ token_ids: list[int],
36
+ penalty: float,
37
+ ) -> np.ndarray:
38
+ """ๆ—ขๅ‡บใƒˆใƒผใ‚ฏใƒณใฎ logit ใซ repetition penalty ใ‚’้ฉ็”จใ™ใ‚‹ใ€‚"""
39
+ if penalty <= 1.0 or not token_ids:
40
+ return logits
41
+ adjusted = logits.copy()
42
+ for token_id in set(token_ids):
43
+ if adjusted[token_id] > 0:
44
+ adjusted[token_id] /= penalty
45
+ else:
46
+ adjusted[token_id] *= penalty
47
+ return adjusted
48
+
49
+
50
+ def filter_top_k(logits: np.ndarray, top_k: int) -> np.ndarray:
51
+ """top_k ไปฅๅค–ใฎ logit ใ‚’ -inf ใซใ™ใ‚‹ใ€‚top_k<=0 ใชใ‚‰ๅค‰ๆ›ดใ—ใชใ„ใ€‚"""
52
+ if top_k <= 0 or top_k >= logits.shape[-1]:
53
+ return logits
54
+ filtered = np.full_like(logits, -np.inf)
55
+ top_indices = np.argpartition(logits, -top_k)[-top_k:]
56
+ filtered[top_indices] = logits[top_indices]
57
+ return filtered
58
+
59
+
60
  # โ”€โ”€ Packed Linear Modules โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
61
 
62
  class Linear1bit(nn.Module):
 
281
 
282
  @torch.inference_mode()
283
  def generate(self, input_ids: list[int], max_new_tokens: int = 200,
284
+ temperature: float = 0.0, top_p: float = 0.9,
285
+ top_k: int = 1, repetition_penalty: float = 1.3,
286
  eos_ids: tuple[int, ...] = (EOS_ID, EOT_ID)) -> list[int]:
287
  ids = list(input_ids)
288
  generated = []
289
  for _ in range(max_new_tokens):
290
  x = torch.tensor([ids[-CTX_LEN:]], dtype=torch.long)
291
  logits = self(x)[0, -1]
292
+ logits_np = logits.numpy().astype(np.float64)
293
+ logits_np = apply_repetition_penalty(logits_np, ids, repetition_penalty)
294
+ logits_np = filter_top_k(logits_np, top_k)
295
  if temperature > 0:
296
+ logits_np = (logits_np - np.nanmax(logits_np)) / temperature
 
297
  probs = np.exp(logits_np); probs /= probs.sum()
298
  idx = np.argsort(-probs); cumsum = np.cumsum(probs[idx])
299
  cutoff = np.searchsorted(cumsum, top_p) + 1
300
  probs[idx[cutoff:]] = 0.0; probs /= probs.sum()
301
  next_id = int(np.random.choice(idx, p=probs))
302
  else:
303
+ next_id = int(np.nanargmax(logits_np))
304
  if next_id in eos_ids:
305
  break
306
  generated.append(next_id)
 
399
  parser.add_argument("--prompt", default=None, help="Prompt for single-shot mode (--no-chat)")
400
  parser.add_argument("--no-chat", action="store_true", help="Single-shot mode")
401
  parser.add_argument("--max-tokens", type=int, default=200, help="Max new tokens to generate")
402
+ parser.add_argument("--temperature", type=float, default=0.0, help="Sampling temperature (0 = greedy; recommended for this model)")
403
  parser.add_argument("--top-p", type=float, default=0.9, help="Top-p nucleus sampling")
404
+ parser.add_argument("--top-k", type=int, default=1, help="Keep only top-k logits before sampling (0 disables)")
405
+ parser.add_argument("--repetition-penalty", type=float, default=1.3, help="Penalty for tokens already present in the prompt/output")
406
  args = parser.parse_args()
407
 
408
  print(f"Loading {args.ckpt} ...")
 
434
  continue
435
  ids = build_chat_prompt(tok, history, user_input)
436
  print("Assistant: ", end="", flush=True)
437
+ out = model.generate(
438
+ ids,
439
+ args.max_tokens,
440
+ args.temperature,
441
+ args.top_p,
442
+ args.top_k,
443
+ args.repetition_penalty,
444
+ )
445
  response = tok.decode(out).strip()
446
  print(response)
447
  history.append((user_input, response))
 
451
  ids = [BOS_ID] + tok.encode(prompt).ids
452
  print(f"\nPrompt: {prompt}")
453
  print("Output: ", end="", flush=True)
454
+ out = model.generate(
455
+ ids,
456
+ args.max_tokens,
457
+ args.temperature,
458
+ args.top_p,
459
+ args.top_k,
460
+ args.repetition_penalty,
461
+ )
462
  print(tok.decode(out))
463
 
464