Records from SFTFromMRDataset have 1D tokens/labels; already grouped
records may have [rows, S]. Variable-length rows are padded, never truncated.
"""
if not isinstance(batch[0], Mapping) or "cu_seq_lens" not in batch[0]:
return default_collate(batch)
token_key = "tokens" if "tokens" in batch[0] else "input_ids"
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):
raise ValueError("cu_seq_lens must have one boundary array per token row")
for row in boundaries:
boundary_rows.append(_sft_row_boundaries(row, tokens.shape[-1]))
token_rows.extend(tokens.unbind(0))
label_rows.extend(labels.unbind(0))
sequence_length = max(row.numel() for row in token_rows)
sequence_length += (-sequence_length) % alignment_size
packed_keys = {token_key, "labels", "cu_seq_lens"}
result = default_collate([
{key: value for key, value in sample.items() if key not in packed_keys} for sample in batch
])
for key, rows, value in ((token_key, token_rows, 0), ("labels", label_rows, IGNORE_INDEX)):
result[key] = torch.stack([
torch.nn.functional.pad(row, (0, sequence_length - row.numel()), value=value) for row in rows
])
for row in boundary_rows:
if row[-1] < sequence_length:
# Isolate ignored tail padding from every real document.
row.append(sequence_length)
result["cu_seq_lens"] = boundary_rows
return result
def build_sft_collate_fn(mesh_context: Any | None = None) -> Callable[[list[Any]], Any]:
"""Build SFT collation preserving [B, S] and each row's document boundaries.