"""Build the paper's NQ + HotpotQA training data from Search-R1-compatible JSONL. Expected JSONL fields: ``question`` and ``golden_answers``. The input directory must contain ``nq/{train,test}.jsonl`` and ``hotpotqa/{train,dev}.jsonl``. """ import argparse from pathlib import Path import datasets as hf_datasets SPLITS = { "nq": ("nq", "train.jsonl", "test.jsonl"), "hotpotqa": ("hotpotqa", "train.jsonl", "dev.jsonl"), } def make_prompt(question: str) -> str: return ( "Answer the given question. You can search for external knowledge using " " query . Search results will be returned between " " and . You can search as many times as you want. " "After receiving search results, first output your current confidence in " " X (integer 1-10), then either search again or " "give your answer. When giving your final answer, write " " your answer followed by X " " (integer 1-10). " f"Question: {question}" ) def load_and_convert(source: Path, dataset_name: str, split: str): dataset = hf_datasets.load_dataset("json", data_files=str(source), split="train") def convert(example, index): question = example["question"].strip() if not question.endswith("?"): question += "?" return { "data_source": dataset_name, "prompt": [{"role": "user", "content": make_prompt(question)}], "ability": "fact-reasoning", "reward_model": {"style": "rule", "ground_truth": {"target": example["golden_answers"]}}, "extra_info": {"split": split, "index": index, "dataset": dataset_name}, } return dataset.map(convert, with_indices=True, remove_columns=dataset.column_names) def main() -> None: parser = argparse.ArgumentParser() parser.add_argument("--raw-root", type=Path, required=True, help="Directory containing NQ and HotpotQA JSONL files.") parser.add_argument("--output-dir", type=Path, default=Path("data/nq_hotpotqa")) args = parser.parse_args() converted = {"train": [], "test": []} for dataset_name, (subdir, train_name, test_name) in SPLITS.items(): for split, filename in (("train", train_name), ("test", test_name)): source = args.raw_root / subdir / filename if not source.is_file(): raise FileNotFoundError(f"Missing input file: {source}") converted[split].append(load_and_convert(source, dataset_name, split)) args.output_dir.mkdir(parents=True, exist_ok=True) for split, parts in converted.items(): combined = hf_datasets.concatenate_datasets(parts) combined.to_parquet(str(args.output_dir / f"{split}.parquet")) if __name__ == "__main__": main()