| |
|
|
| import json |
| from dataclasses import dataclass, field |
| from pathlib import Path |
|
|
| import torch |
| from torch.utils.data import DataLoader |
|
|
| from litgpt.data import DataModule, SFTDataset, get_sft_collate_fn |
| from litgpt.data.alpaca import download_if_missing |
| from litgpt.prompts import PromptStyle |
| from litgpt.tokenizer import Tokenizer |
|
|
| _URL = "https://huggingface.co/datasets/Muennighoff/flan/resolve/main" |
|
|
|
|
| |
| |
| @dataclass |
| class FLAN(DataModule): |
| """FLAN data module for supervised finetuning.""" |
|
|
| mask_prompt: bool = False |
| """Whether to mask the prompt section from the label (with ``ignore_index``).""" |
| prompt_style: str | PromptStyle = "flan" |
| """The style to apply to instruction prompts. See `litgpt.prompts` for a list of available styles.""" |
| ignore_index: int = -100 |
| """The index to use for elements to be ignored in the label.""" |
| seed: int = 42 |
| """The random seed for shuffling the dataset.""" |
| num_workers: int = 4 |
| """How many DataLoader processes to use for loading.""" |
| download_dir: Path = Path("./data/flan") |
| """The directory in which the downloaded dataset gets saved.""" |
| url: str = _URL |
| """The URL from where to download the dataset.""" |
| subsets: str | None = None |
| """A comma separated list of subsets to use. If None, all subsets are used.""" |
|
|
| tokenizer: Tokenizer | None = field(default=None, init=False, repr=False) |
| batch_size: int = field(default=1, init=False, repr=False) |
| max_seq_length: int = field(default=-1, init=False, repr=False) |
| train_dataset: SFTDataset | None = field(default=None, init=False, repr=False) |
| test_dataset: SFTDataset | None = field(default=None, init=False, repr=False) |
|
|
| def __post_init__(self): |
| super().__init__() |
| if isinstance(self.prompt_style, str): |
| self.prompt_style = PromptStyle.from_name(self.prompt_style) |
|
|
| supported_subsets = _supported_subsets() |
| if self.subsets is not None: |
| self.subsets = self.subsets.split(",") |
| for subset in self.subsets: |
| if subset not in supported_subsets: |
| raise ValueError(f"{subset} not in {supported_subsets}") |
| else: |
| self.subsets = list(supported_subsets) |
|
|
| def connect( |
| self, tokenizer: Tokenizer | None = None, batch_size: int = 1, max_seq_length: int | None = None |
| ) -> None: |
| self.tokenizer = tokenizer |
| self.batch_size = batch_size |
| self.max_seq_length = -1 if max_seq_length is None else max_seq_length |
|
|
| def prepare_data(self) -> None: |
| self.download_dir.mkdir(parents=True, exist_ok=True) |
| for subset in self.subsets: |
| for split in ("train", "test"): |
| data_file_path = self.download_dir / f"{subset}_{split}.jsonl" |
| data_file_url = f"{self.url}/{split}/{subset}_{split}.jsonl" |
| download_if_missing(data_file_path, data_file_url) |
|
|
| def train_dataloader(self): |
| return self._dataloader("train") |
|
|
| def val_dataloader(self): |
| return self._dataloader("test") |
|
|
| def _dataloader(self, split: str) -> DataLoader: |
| data = [] |
| for subset in self.subsets: |
| data_file_path = self.download_dir / f"{subset}_{split}.jsonl" |
| data.extend(load_jsonl(data_file_path)) |
|
|
| dataset = SFTDataset( |
| data=data, |
| tokenizer=self.tokenizer, |
| prompt_style=self.prompt_style, |
| max_seq_length=self.max_seq_length, |
| mask_prompt=self.mask_prompt, |
| ignore_index=self.ignore_index, |
| transform=_transform, |
| ) |
| return DataLoader( |
| dataset=dataset, |
| batch_size=self.batch_size, |
| shuffle=(split == "train"), |
| generator=torch.Generator().manual_seed(self.seed), |
| num_workers=self.num_workers, |
| collate_fn=get_sft_collate_fn(max_seq_length=self.max_seq_length, ignore_index=self.ignore_index), |
| ) |
|
|
|
|
| def load_jsonl(filename: Path) -> list[dict[str, str]]: |
| data = [] |
| with open(filename, encoding="utf-8") as f: |
| for line in f: |
| data.append(json.loads(line)) |
| return data |
|
|
|
|
| def _transform(item: dict) -> dict: |
| return {"instruction": item["inputs"], "input": "", "output": item["targets"]} |
|
|
|
|
| def _supported_subsets() -> set[str]: |
| return { |
| "aeslc_10templates", |
| "ag_news_subset_10templates", |
| "anli_r1_10templates", |
| "anli_r2_10templates", |
| "anli_r3_10templates", |
| "arc_challenge_10templates", |
| "arc_easy_10templates", |
| "bool_q_10templates", |
| "cb_10templates", |
| "cnn_dailymail_10templates", |
| "cola_10templates", |
| "common_gen_10templates", |
| "copa_10templates", |
| "coqa_10templates", |
| "cosmos_qa_10templates", |
| "dart_10templates", |
| "definite_pronoun_resolution_10templates", |
| "drop_10templates", |
| "e2e_nlg_10templates", |
| "fix_punct_10templates", |
| "gigaword_10templates", |
| "glue_mrpc_10templates", |
| "glue_qqp_10templates", |
| "hellaswag_10templates", |
| "imdb_reviews_10templates", |
| "math_dataset_10templates", |
| "mnli_matched_10templates", |
| "mnli_mismatched_10templates", |
| "multi_news_10templates", |
| "multirc_10templates", |
| "natural_questions_10templates", |
| "openbookqa_10templates", |
| "opinion_abstracts_idebate_10templates", |
| "opinion_abstracts_rotten_tomatoes_10templates", |
| "para_crawl_enes_10templates", |
| "paws_wiki_10templates", |
| "piqa_10templates", |
| "qnli_10templates", |
| "quac_10templates", |
| "record_10templates", |
| "rte_10templates", |
| "samsum_10templates", |
| "sentiment140_10templates", |
| "snli_10templates", |
| "squad_v1_10templates", |
| "squad_v2_10templates", |
| "sst2_10templates", |
| "story_cloze_10templates", |
| "stsb_10templates", |
| "trec_10templates", |
| "trivia_qa_10templates", |
| "true_case_10templates", |
| "web_nlg_en_10templates", |
| "wic_10templates", |
| "wiki_lingua_english_en_10templates", |
| "wmt14_enfr_10templates", |
| "wmt16_translate_csen_10templates", |
| "wmt16_translate_deen_10templates", |
| "wmt16_translate_fien_10templates", |
| "wmt16_translate_roen_10templates", |
| "wmt16_translate_ruen_10templates", |
| "wmt16_translate_tren_10templates", |
| "wnli_10templates", |
| "word_segment_10templates", |
| "wsc_10templates", |
| "yelp_polarity_reviews_10templates", |
| } |
|
|