token_rows, label_rows, boundary_rows = [], [], []
for sample in batch:
tokens, labels = torch.as_tensor(sample[token_key]), torch.as_tensor(sample["labels"])
if tokens.ndim not in (1, 2) or tokens.shape != labels.shape or not tokens.numel():
raise ValueError("SFT tokens and labels must have matching nonempty [S] or [rows, S] shapes")
boundaries = sample["cu_seq_lens"]
if tokens.ndim == 1:
tokens, labels, boundaries = tokens.unsqueeze(0), labels.unsqueeze(0), [boundaries]
if len(boundaries) != len(tokens):