Module neuralops.data.prepare_datasets
Dataset Preparation & Preprocessing Pipeline for GPU Server Benchmark & Training.
Supports: - GLUE Suite (SST-2, MRPC, QNLI, MNLI, CoLA, RTE, STS-B, QQP) - Language Modeling (WikiText-2, WikiText-103, C4, PTB) - Question Answering & Reasoning (SQuAD v2, GSM8K subset, MMLU subset) - Fast deterministic synthetic generation when offline / air-gapped - Multi-model tokenization & dynamic padding (BERT, RoBERTa, T5, GPT-2, LLaMA) - PyTorch DataLoader serialization to disk (.pt / Arrow) for instant GPU execution
Usage -----=
Prepare GLUE datasets with default tokenizers
python prepare_datasets.py –tasks sst2,mrpc,qnli,cola –save_dir ./glue_data
Prepare all benchmark datasets for GPU server
python prepare_datasets.py –all –save_dir ./benchmark_data –batch_size 256
Test dataset loading and print batch schemas
python prepare_datasets.py –test –tasks sst2,wikitext2
Functions
def create_benchmark_dataloader(dataset: Dataset,
batch_size: int = 16,
shuffle: bool = False,
num_workers: int = 0,
pin_memory: bool = True,
device: torch.device | None = None) ‑> torch.utils.data.dataloader.DataLoader-
Expand source code
def create_benchmark_dataloader( dataset: Dataset, batch_size: int = 16, shuffle: bool = False, num_workers: int = 0, pin_memory: bool = True, device: torch.device | None = None, ) -> DataLoader: """ Creates a high-throughput PyTorch DataLoader configured for GPU training/benchmarking. """ is_cuda = (device is not None and device.type == "cuda") or torch.cuda.is_available() def collate_fn(batch: list[dict[str, Any]]) -> dict[str, torch.Tensor]: if isinstance(batch[0], dict): keys = batch[0].keys() res = {} for k in keys: vals = [b[k] for b in batch] if isinstance(vals[0], torch.Tensor): res[k] = torch.stack(vals) else: res[k] = torch.tensor(vals) return res return torch.utils.data.dataloader.default_collate(batch) return DataLoader( dataset, batch_size=batch_size, shuffle=shuffle, num_workers=num_workers, pin_memory=pin_memory and is_cuda, collate_fn=collate_fn, )Creates a high-throughput PyTorch DataLoader configured for GPU training/benchmarking.
def main() ‑> None-
Expand source code
def main() -> None: parser = argparse.ArgumentParser(description="Dataset Preparation & Preprocessing Pipeline") parser.add_argument( "--tasks", type=str, default="sst2,mrpc,qnli", help="Comma-separated dataset names", ) parser.add_argument( "--models", type=str, default=None, help="Comma-separated model families (bert,roberta,t5,distilbert,gpt2)", ) parser.add_argument("--all", action="store_true", help="Prepare all GLUE and LM benchmarks") parser.add_argument( "--tokenizer", type=str, default="bert-base-uncased", help="HuggingFace tokenizer name", ) parser.add_argument("--seq_len", type=int, default=128, help="Maximum sequence length") parser.add_argument("--batch_size", type=int, default=16, help="Batch size for DataLoader test") parser.add_argument( "--save_dir", type=str, default="./prepared_benchmark_data", help="Output directory", ) parser.add_argument("--test", action="store_true", help="Test DataLoader batch generation") args = parser.parse_args() if args.all: if args.models: model_list = [m.strip().lower() for m in args.models.split(",") if m.strip()] for m in model_list: tok = MODEL_TOKENIZER_MAPPING.get(m, m) m_save = os.path.join(args.save_dir, m) prepare_all_benchmarks( save_dir=m_save, tokenizer_name=tok, max_seq_len=args.seq_len ) else: prepare_all_benchmarks( save_dir=args.save_dir, tokenizer_name=args.tokenizer, max_seq_len=args.seq_len, ) return task_list = [t.strip().lower() for t in args.tasks.split(",") if t.strip()] tokenizers = [args.tokenizer] if args.models: tokenizers = [ MODEL_TOKENIZER_MAPPING.get(m.strip().lower(), m.strip()) for m in args.models.split(",") if m.strip() ] for tok in tokenizers: tok_short = next( (k for k, v in MODEL_TOKENIZER_MAPPING.items() if v == tok), tok.split("/")[-1], ) for t in task_list: sub_save = os.path.join(args.save_dir, tok_short) if args.models else args.save_dir if t in GLUE_TASK_CONFIG: splits = prepare_glue_dataset( t, tokenizer_name=tok, max_seq_len=args.seq_len, save_dir=sub_save ) elif t in {"wikitext2", "wikitext103", "c4", "lm"}: splits = prepare_lm_dataset( t, tokenizer_name=tok, max_seq_len=args.seq_len, save_dir=sub_save ) else: logger.warning("Unrecognized task '%s'. Using synthetic generator.", t) splits = {"train": SyntheticDataset(t, num_samples=1000, seq_len=args.seq_len)} if args.test and "train" in splits: loader = create_benchmark_dataloader(splits["train"], batch_size=args.batch_size) batch = next(iter(loader)) print(f"\n[Test Loader for {t} ({tok_short})]") for k, v in batch.items(): print(f" - {k}: shape={v.shape}, dtype={v.dtype}") def prepare_all_benchmarks(save_dir: str = './benchmark_data',
tokenizer_name: str = 'bert-base-uncased',
max_seq_len: int = 128) ‑> dict[str, dict[str, torch.utils.data.dataset.Dataset]]-
Expand source code
def prepare_all_benchmarks( save_dir: str = "./benchmark_data", tokenizer_name: str = "bert-base-uncased", max_seq_len: int = 128, ) -> dict[str, dict[str, Dataset]]: """Prepares and caches all GLUE and LM benchmarks.""" os.makedirs(save_dir, exist_ok=True) all_data: dict[str, dict[str, Dataset]] = {} # 1. GLUE for task in GLUE_TASK_CONFIG: try: splits = prepare_glue_dataset(task, tokenizer_name, max_seq_len, save_dir=save_dir) all_data[f"glue_{task}"] = splits except Exception as e: logger.error("Failed preparing GLUE task '%s': %s", task, e) # 2. LM for lm in ["wikitext2", "c4"]: try: splits = prepare_lm_dataset(lm, tokenizer_name, max_seq_len, save_dir=save_dir) all_data[f"lm_{lm}"] = splits except Exception as e: logger.error("Failed preparing LM dataset '%s': %s", lm, e) logger.info("All benchmark datasets prepared and saved to '%s'!", save_dir) return all_dataPrepares and caches all GLUE and LM benchmarks.
def prepare_glue_dataset(task_name: str,
tokenizer_name: str = 'bert-base-uncased',
max_seq_len: int = 128,
save_dir: str | None = None,
use_synthetic_fallback: bool = True) ‑> dict[str, torch.utils.data.dataset.Dataset]-
Expand source code
def prepare_glue_dataset( task_name: str, tokenizer_name: str = "bert-base-uncased", max_seq_len: int = 128, save_dir: str | None = None, use_synthetic_fallback: bool = True, ) -> dict[str, Dataset]: """ Downloads, tokenizes, and formats a GLUE benchmark task. Saves tokenized dataset tensors to disk if save_dir is specified. """ task = task_name.lower() if task not in GLUE_TASK_CONFIG: raise ValueError(f"Unknown GLUE task '{task}'. Supported: {list(GLUE_TASK_CONFIG.keys())}") config = GLUE_TASK_CONFIG[task] key1, key2 = config["keys"] logger.info("Preparing GLUE task '%s' using tokenizer '%s'...", task, tokenizer_name) # 1. Try loading HuggingFace datasets hf_dataset = None tokenizer = None try: from datasets import load_dataset from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained(tokenizer_name) if tokenizer.pad_token is None: tokenizer.pad_token = tokenizer.eos_token tokenizer.pad_token_id = tokenizer.eos_token_id hf_dataset = load_dataset("glue", task) logger.info("Successfully fetched '%s' from HuggingFace Hub.", task) except Exception as e: logger.warning("Could not download '%s' via HuggingFace Hub: %s", task, e) if not use_synthetic_fallback: raise # 2. If HF is available, process and tokenize if hf_dataset is not None and tokenizer is not None: tokenized_splits: dict[str, Dataset] = {} for split_name in ["train", "validation", "test"]: if split_name not in hf_dataset: continue raw_split = hf_dataset[split_name] def tokenize_fn(examples: dict[str, list[Any]]) -> dict[str, Any]: args = (examples[key1],) if key2 is None else (examples[key1], examples[key2]) return tokenizer( *args, padding="max_length", truncation=True, max_length=max_seq_len, return_tensors=None, ) cols_to_remove = [c for c in raw_split.column_names if c not in {"label", "labels"}] tokenized = raw_split.map(tokenize_fn, batched=True, remove_columns=cols_to_remove) if "label" in tokenized.column_names and "labels" not in tokenized.column_names: tokenized = tokenized.rename_column("label", "labels") if "t5" in tokenizer_name.lower() and "token_type_ids" in tokenized.column_names: tokenized = tokenized.remove_columns(["token_type_ids"]) cols_to_format = [ c for c in ["input_ids", "attention_mask", "token_type_ids", "labels"] if c in tokenized.column_names ] tokenized.set_format(type="torch", columns=cols_to_format) tokenized_splits[split_name] = tokenized if save_dir: out_path = Path(save_dir) / f"glue_{task}" out_path.mkdir(parents=True, exist_ok=True) for sname, sdata in tokenized_splits.items(): torch.save(sdata, out_path / f"{sname}.pt") logger.info("Saved tokenized GLUE dataset to %s", out_path) return tokenized_splits # 3. Synthetic Fallback logger.info("Generating high-fidelity synthetic benchmark data for '%s'...", task) train_ds = SyntheticDataset( task, num_samples=2000, seq_len=max_seq_len, num_labels=config["num_labels"] ) val_ds = SyntheticDataset( task, num_samples=500, seq_len=max_seq_len, num_labels=config["num_labels"], seed=100, ) test_ds = SyntheticDataset( task, num_samples=500, seq_len=max_seq_len, num_labels=config["num_labels"], seed=200, ) synthetic_splits = {"train": train_ds, "validation": val_ds, "test": test_ds} if save_dir: out_path = Path(save_dir) / f"glue_{task}" out_path.mkdir(parents=True, exist_ok=True) torch.save(train_ds, out_path / "train.pt") torch.save(val_ds, out_path / "validation.pt") torch.save(test_ds, out_path / "test.pt") logger.info("Saved synthetic GLUE dataset to %s", out_path) return synthetic_splitsDownloads, tokenizes, and formats a GLUE benchmark task. Saves tokenized dataset tensors to disk if save_dir is specified.
def prepare_lm_dataset(dataset_name: str = 'wikitext2',
tokenizer_name: str = 'bert-base-uncased',
max_seq_len: int = 128,
save_dir: str | None = None) ‑> dict[str, torch.utils.data.dataset.Dataset]-
Expand source code
def prepare_lm_dataset( dataset_name: str = "wikitext2", tokenizer_name: str = "bert-base-uncased", max_seq_len: int = 128, save_dir: str | None = None, ) -> dict[str, Dataset]: """Prepares Language Modeling benchmarks (WikiText-2, C4).""" ds_name = dataset_name.lower() logger.info("Preparing LM dataset '%s'...", ds_name) try: from datasets import load_dataset from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained(tokenizer_name) if tokenizer.pad_token is None: tokenizer.pad_token = tokenizer.eos_token tokenizer.pad_token_id = tokenizer.eos_token_id if ds_name == "wikitext2": raw = load_dataset("wikitext", "wikitext-2-raw-v1") elif ds_name == "wikitext103": raw = load_dataset("wikitext", "wikitext-103-raw-v1") else: raw = load_dataset(ds_name) def tokenize_lm(examples: dict[str, list[str]]) -> dict[str, Any]: tokens = tokenizer( examples["text"], padding="max_length", truncation=True, max_length=max_seq_len, ) tokens["labels"] = tokens["input_ids"].copy() return tokens processed = raw.map(tokenize_lm, batched=True, remove_columns=raw["train"].column_names) if "t5" in tokenizer_name.lower() and "token_type_ids" in processed["train"].column_names: processed = processed.remove_columns(["token_type_ids"]) cols = [ c for c in ["input_ids", "attention_mask", "token_type_ids", "labels"] if c in processed["train"].column_names ] processed.set_format(type="torch", columns=cols) if save_dir: out_path = Path(save_dir) / f"lm_{ds_name}" out_path.mkdir(parents=True, exist_ok=True) for sname in ["train", "validation", "test"]: if sname in processed: torch.save(processed[sname], out_path / f"{sname}.pt") logger.info("Saved LM dataset to %s", out_path) return {k: processed[k] for k in processed} except Exception as e: logger.warning( "Could not download real LM dataset '%s': %s. Falling back to synthetic.", ds_name, e, ) train_ds = SyntheticDataset("wikitext2", num_samples=2000, seq_len=max_seq_len) val_ds = SyntheticDataset("wikitext2", num_samples=500, seq_len=max_seq_len, seed=100) splits = {"train": train_ds, "validation": val_ds} if save_dir: out_path = Path(save_dir) / f"lm_{ds_name}" out_path.mkdir(parents=True, exist_ok=True) torch.save(train_ds, out_path / "train.pt") torch.save(val_ds, out_path / "validation.pt") logger.info("Saved synthetic LM dataset to %s", out_path) return splitsPrepares Language Modeling benchmarks (WikiText-2, C4).
Classes
class SyntheticDataset (task_name: str,
num_samples: int = 1000,
seq_len: int = 64,
vocab_size: int = 30522,
num_labels: int = 2,
seed: int = 42)-
Expand source code
class SyntheticDataset(Dataset): """Deterministic synthetic in-memory dataset for air-gapped or offline GPU execution.""" def __init__( self, task_name: str, num_samples: int = 1000, seq_len: int = 64, vocab_size: int = 30522, num_labels: int = 2, seed: int = 42, ): super().__init__() self.task_name = task_name.lower() self.num_samples = num_samples self.seq_len = seq_len self.vocab_size = vocab_size self.num_labels = num_labels torch.manual_seed(seed) self.input_ids = torch.randint( 100, vocab_size - 100, (num_samples, seq_len), dtype=torch.long ) self.attention_mask = torch.ones((num_samples, seq_len), dtype=torch.long) # Introduce variable length padding for i in range(num_samples): pad_len = (i * 3) % (seq_len // 4) if pad_len > 0: self.attention_mask[i, -pad_len:] = 0 self.input_ids[i, -pad_len:] = 0 if self.task_name in {"wikitext2", "c4", "lm"}: self.labels = self.input_ids.clone() elif self.task_name == "stsb": self.labels = torch.rand(num_samples, dtype=torch.float) * 5.0 else: self.labels = torch.randint(0, num_labels, (num_samples,), dtype=torch.long) def __len__(self) -> int: return self.num_samples def __getitem__(self, idx: int) -> dict[str, torch.Tensor]: return { "input_ids": self.input_ids[idx], "attention_mask": self.attention_mask[idx], "labels": self.labels[idx], }Deterministic synthetic in-memory dataset for air-gapped or offline GPU execution.
Ancestors
- torch.utils.data.dataset.Dataset
- typing.Generic