from __future__ import annotations from pathlib import Path import torch from torch.utils.data import Dataset from .tokenizer import CharacterTokenizer FALLBACK_LINES = [ "the quick brown fox jumps over the lazy dog", "machine learning models can generate text", "diffusion models gradually remove noise", "multi mask diffusion preserves more information", "language models predict clean tokens from noisy inputs", "deep learning requires data optimization and evaluation", "multiple masks retain a trace of the original token", "a small reproducible experiment is better than no result", "time conditioned transformers learn iterative denoising", "research code should save reload and evaluate checkpoints", "clean tokens are assigned to designated mask classes", "masked language modeling reconstructs hidden symbols", "simple datasets make the training pipeline dependable", "few step generation trades computation for model quality", "the model observes noisy sequences and predicts characters", "careful tests catch errors before expensive gpu training", ] def load_corpus(path: str | Path, minimum_lines: int = 512) -> list[str]: path = Path(path) if path.exists(): lines = [ line.strip().lower() for line in path.read_text(encoding="utf-8").splitlines() if line.strip() ] else: lines = list(FALLBACK_LINES) if not lines: lines = list(FALLBACK_LINES) repeats = (minimum_lines + len(lines) - 1) // len(lines) expanded = (lines * repeats)[:minimum_lines] return [f"{line}\n" for line in expanded] class TextDataset(Dataset): def __init__( self, texts: list[str], tokenizer: CharacterTokenizer, seq_len: int, ): self.texts = texts self.tokenizer = tokenizer self.seq_len = seq_len def __len__(self) -> int: return len(self.texts) def __getitem__(self, index: int) -> dict[str, torch.Tensor]: ids = torch.tensor( self.tokenizer.encode(self.texts[index], self.seq_len), dtype=torch.long, ) attention_mask = ids.ne(self.tokenizer.pad_id) return {"input_ids": ids, "attention_mask": attention_mask}