| |
| |
| |
| |
| import sys; sys.path.insert(0, '/root/dna') |
| import torch, torch.nn as nn, torch.nn.functional as F |
| from model_dna import DnaChat, counts |
|
|
| def weight_quant_ternary(w): |
| scale = w.abs().mean().clamp_(min=1e-5) |
| w_tern = torch.round(w / scale).clamp_(-1, 1) |
| return w_tern, scale |
|
|
| def act_quant_int8(x): |
| scale = x.abs().amax(dim=-1, keepdim=True).clamp_(min=1e-5) / 127.0 |
| return torch.round(x / scale).clamp_(-128, 127), scale |
|
|
| class TernLinear(nn.Module): |
| """Drop-in for a bias-free nn.Linear: same .weight [out,in], ternary-STE forward.""" |
| def __init__(self, lin: nn.Linear): |
| super().__init__() |
| self.in_features = lin.in_features; self.out_features = lin.out_features |
| self.weight = lin.weight |
| def forward(self, x): |
| x_q, x_scale = act_quant_int8(x) |
| x_ste = x + (x_q * x_scale - x).detach() |
| w_tern, w_scale = weight_quant_ternary(self.weight) |
| w_ste = self.weight + (w_tern * w_scale - self.weight).detach() |
| return F.linear(x_ste, w_ste) |
|
|
| def ternarize_(model, skip=('head2',)): |
| """In-place: replace controller nn.Linear modules with TernLinear.""" |
| n = 0 |
| for name, mod in list(model.named_modules()): |
| for child_name, child in list(mod.named_children()): |
| if isinstance(child, nn.Linear) and child.bias is None: |
| full = f'{name}.{child_name}' if name else child_name |
| if any(s in full for s in skip): |
| continue |
| setattr(mod, child_name, TernLinear(child)); n += 1 |
| return n |
|
|
| def controller_byte_budget(model): |
| """Bytes read per token at batch-1 decode for the controller's matrix weights.""" |
| tern_params = 0; fp_params = 0 |
| for name, mod in model.named_modules(): |
| if isinstance(mod, TernLinear): |
| tern_params += mod.weight.numel() |
| elif isinstance(mod, nn.Linear) and mod.bias is None: |
| fp_params += mod.weight.numel() |
| |
| return { |
| 'tern_params': tern_params, 'fp_linear_params': fp_params, |
| 'bytes_per_token_tern': tern_params * 0.2 + fp_params * 2, |
| 'bytes_per_token_bf16': (tern_params + fp_params) * 2, |
| } |
|
|