| from __future__ import annotations |
|
|
| import math |
| import random |
| from dataclasses import dataclass |
| from typing import Protocol, Sequence, runtime_checkable |
|
|
| from sgjm.modules.backbone import Backbone, BackboneState |
|
|
|
|
| @dataclass(frozen=True) |
| class DraftSample: |
| tokens: tuple[int, ...] |
| latent: tuple[float, ...] |
| log_prob: float |
|
|
|
|
| @runtime_checkable |
| class Drafter(Protocol): |
| def draft(self, state: BackboneState, *, k: int, block: int) -> tuple[DraftSample, ...]: ... |
|
|
|
|
| @dataclass |
| class StubDrafter: |
| backbone: Backbone |
| vocab_size: int = 32 |
| seed: int = 1 |
|
|
| def draft(self, state: BackboneState, *, k: int, block: int) -> tuple[DraftSample, ...]: |
| rng = random.Random(hash((self.seed, tuple(state.tokens), k, block))) |
| samples: list[DraftSample] = [] |
| for _ in range(k): |
| cur = state |
| tokens: list[int] = [] |
| log_prob = 0.0 |
| for _ in range(block): |
| tok = rng.randrange(self.vocab_size) |
| cur = self.backbone.step(cur, tok) |
| tokens.append(tok) |
| log_prob += -math.log(self.vocab_size) |
| samples.append( |
| DraftSample( |
| tokens=tuple(tokens), |
| latent=tuple(cur.latent), |
| log_prob=log_prob, |
| ) |
| ) |
| return tuple(samples) |
|
|