Download fractus/train/ar_loss.py from thefinalboss/fractus-cte: direct link, hf CLI and curl.
- Browser
- Download file 2.77 kB
-
https://huggingface.co/thefinalboss/fractus-cte/resolve/3ba0cfe3eab2f39a189173bfebaa19d011f2a1e9/fractus/train/ar_loss.py
- Command line
-
hf download hf://thefinalboss/fractus-cte@3ba0cfe3eab2f39a189173bfebaa19d011f2a1e9/fractus/train/ar_loss.py
-
curl -L -o ar_loss.py https://huggingface.co/thefinalboss/fractus-cte/resolve/3ba0cfe3eab2f39a189173bfebaa19d011f2a1e9/fractus/train/ar_loss.py
2.77 kB
| """AR-facing training extras: scheduled-sampling mix, SS_PROB ramp, | |
| anti-repeat log-prob (penalize echoing the last input token). | |
| Used by scripts/fast4gpu_boost_v4.py. Shapes-compatible with the v3 CE path. | |
| """ | |
| from __future__ import annotations | |
| import torch | |
| import torch.nn.functional as F | |
| from torch.utils.checkpoint import checkpoint | |
| def ss_prob_at( | |
| tokens_done: int, | |
| start: float = 0.2, | |
| end: float = 0.5, | |
| ramp_tokens: int = 50_000_000, | |
| ) -> float: | |
| """Linear ramp start → end over ramp_tokens. Clamped to [start, end].""" | |
| if ramp_tokens <= 0: | |
| return float(end) | |
| t = min(1.0, max(0.0, tokens_done / float(ramp_tokens))) | |
| return float(start + (end - start) * t) | |
| def mix_scheduled_sampling( | |
| chunk: torch.Tensor, | |
| sampled: torch.Tensor, | |
| ss_prob: float, | |
| ) -> torch.Tensor: | |
| """Replace a fraction of *previous* tokens with model samples. | |
| Position 0 is never replaced (need a real start). `sampled[:, t]` is the | |
| model's draw at t; we feed it as input at t+1 (standard SS). | |
| """ | |
| B, C = chunk.shape | |
| use_ss = torch.rand(B, C, device=chunk.device) < ss_prob | |
| use_ss[:, 0] = False | |
| prev = torch.cat([chunk[:, :1], sampled[:, :-1]], dim=1) | |
| return torch.where(use_ss, prev, chunk) | |
| def _chunk_repeat_logit(hi: torch.Tensor, weight: torch.Tensor, pi: torch.Tensor) -> torch.Tensor: | |
| # RAW logit of the echo class, not logprob. Tied-head + residual makes | |
| # p(echo)≈1 at init so log p saturates at 0 and d(log p)/dθ ≈ 0. | |
| logits = F.linear(hi, weight).float() | |
| return logits.gather(-1, pi.view(-1, 1)).sum() | |
| def chunked_repeat_logprob( | |
| h: torch.Tensor, | |
| weight: torch.Tensor, | |
| prev_ids: torch.Tensor, | |
| ce_chunk: int = 8192, | |
| ) -> torch.Tensor: | |
| """Mean logit of class prev_ids[i] at row i. | |
| Name kept for call-sites. Add λ · this to the loss to suppress | |
| last-token echo. Memory-flat like chunked CE. | |
| """ | |
| assert h.dim() == 2 and prev_ids.dim() == 1 and h.shape[0] == prev_ids.shape[0] | |
| n = h.shape[0] | |
| if n == 0: | |
| return h.new_zeros((), dtype=torch.float32) | |
| total = None | |
| for i in range(0, n, ce_chunk): | |
| hi = h[i : i + ce_chunk] | |
| pi = prev_ids[i : i + ce_chunk] | |
| if torch.is_grad_enabled() and n > ce_chunk: | |
| part = checkpoint(_chunk_repeat_logit, hi, weight, pi, use_reentrant=False) | |
| else: | |
| part = _chunk_repeat_logit(hi, weight, pi) | |
| total = part if total is None else total + part | |
| return total / n | |
| def echo_frac(generated: list[int], last_prompt_id: int) -> float: | |
| """Fraction of greedy tokens equal to the last prompt token.""" | |
| if not generated: | |
| return 0.0 | |
| return sum(1 for t in generated if t == last_prompt_id) / len(generated) | |