diff --git a/README.md b/README.md index 452c7f9..fdebb0f 100644 --- a/README.md +++ b/README.md @@ -175,7 +175,7 @@ run uv run data/generate_fw_edu_qa_v2.py --shard_pattern "000_00000" --n_qa_pair run uv run data/generate_fw_edu_qa_v2_repeat.py --shard_pattern "min_0_to_2000/000*level_0*" --n_qa_pairs=5 --vllm_model=google/gemma-3-12b-it; run uv run data/generate_fw_edu_qa_v2_repeat.py --shard_pattern "min_0_to_2000/000*level_1*" --n_qa_pairs=5 --vllm_model=google/gemma-3-12b-it; run uv run data/generate_fw_edu_qa_v2_repeat.py --shard_pattern "min_0_to_2000/000*level_2*" --n_qa_pairs=5 --vllm_model=google/gemma-3-12b-it -run uv run data/generate_fw_edu_qa_v3.py --n_qa_pairs 3 --shard_pattern '*' --debug --question_weight 1 --use_case_weight 1 --creative_weight 1 --generic_weight 1 +run uv run python data/generate_fw_edu_qa_v3.py --shard_pattern '*' --question_weight 3 --use_case_weight 1 --creative_weight 1 --generic_weight 1 ``` 2. Self-generated response QA data (depends on step 0 and 1) diff --git a/data/generate_fw_edu_qa_v3.py b/data/generate_fw_edu_qa_v3.py index e9e7717..ff00f55 100644 --- a/data/generate_fw_edu_qa_v3.py +++ b/data/generate_fw_edu_qa_v3.py @@ -16,8 +16,11 @@ from q_generation_prompts import ( # get_structuring_seed_prompt,; get_summariz ) from vllm import LLM, SamplingParams +from ctx_to_lora.data.processing import load_and_process_dataset + STOP_STRINGS = { "google/gemma-3-12b-it": ["", ""], + "google/gemma-3-4b-it": ["", ""], } @@ -112,15 +115,28 @@ if __name__ == "__main__": parser.add_argument( "--vllm_model", type=str, - default=os.environ.get("vllm_model", "google/gemma-3-12b-it"), + default=os.environ.get("vllm_model", "google/gemma-3-4b-it"), help="VLLM model to use for generation", ) parser.add_argument( "--shard_pattern", type=str, - required=True, + default=None, help="Pattern to match shard files (e.g., '000_0000*')", ) + parser.add_argument( + "--ds_names", # list of names + type=str, + nargs="+", + default=None, + help="dataset names", + ) + parser.add_argument( + "--split", + type=str, + default=None, + help="Dataset split to use (e.g., 'train', 'validation')", + ) # parser.add_argument( # "--n_qa_pairs", # type=int, @@ -176,6 +192,9 @@ if __name__ == "__main__": ) args = parser.parse_args() + assert bool(args.shard_pattern) ^ bool(args.ds_names) + if args.ds_names: + assert bool(args.split) weights = [ args.question_weight, @@ -203,17 +222,28 @@ if __name__ == "__main__": shard_pattern = args.shard_pattern # n_qa_pairs = args.n_qa_pairs - paths = glob( - f"./data/raw_datasets/fineweb_edu/sample/100BT/{shard_pattern}.parquet" - ) - - split = "train[:100]" if args.debug else "train" - for path in paths: - ds = load_dataset( - "parquet", - data_files=path, - split=split, + if args.shard_pattern is not None: + paths = glob( + f"./data/raw_datasets/fineweb_edu/sample/100BT/{shard_pattern}.parquet" ) + elif args.ds_names: + paths = args.ds_names + else: + raise ValueError("Either shard_pattern or ds_names must be provided.") + + split = "train[:100]" if args.debug else args.split or "train" + for path in paths: + if args.shard_pattern is not None: + ds = load_dataset( + "parquet", + data_files=path, + split=split, + ) + elif args.ds_names: + ds = load_and_process_dataset(path, args.split, num_proc=16) + ds = ds.rename_column("context", "text") + + print(f"Loaded {len(ds)} samples from {path}") ds = ds.filter( length_filter, fn_kwargs={"min_len": args.min_length, "max_len": args.max_length}, diff --git a/data/generate_negative_natural_questions.py b/data/generate_negative_natural_questions.py index 0e209b7..a0827f2 100644 --- a/data/generate_negative_natural_questions.py +++ b/data/generate_negative_natural_questions.py @@ -6,7 +6,7 @@ from tqdm import tqdm if __name__ == "__main__": ds = load_dataset("google-research-datasets/natural_questions") ds = ds.shuffle(seed=42) - for split in ["validation"]: + for split in ["train", "validation"]: out = [] for i, sample in enumerate(tqdm(ds[split])): ctx = " ".join( diff --git a/data/self_generate_qa.py b/data/self_generate_qa.py index 717bac8..f9f4d11 100644 --- a/data/self_generate_qa.py +++ b/data/self_generate_qa.py @@ -11,9 +11,11 @@ from vllm import LLM, SamplingParams from ctx_to_lora.data.definitions import ( CLOSED_QA_INTX_TEMPLATES, + COT_TEMPLATES, RAW_DATA_DIR, SELF_GEN_DATA_DIR, - SELF_GEN_SYSTEM_MSG, + STRUCTURING_PROMPTS, + SUMMARIZATION_PROMPTS, ) from ctx_to_lora.data.processing import ( filter_none, @@ -31,48 +33,27 @@ STOP_STRINGS = { # TODO: !!!! # see https://huggingface.co/datasets/YuxinJiang/LTE_train_data/viewer/default/train?row=97&views%5B%5D=train&sql_row=2 # based on https://arxiv.org/pdf/2402.11905 -SYSTEM_TEMPLATE = ( - "### SYSTEM INSTRUCTION ###\n" - "You are an honest and helpful assistant.\n" - # "You must use the information provided in the context for responding to the question.\n" - # "If the context does not contain enough information to answer the question, you must say so.\n" - # "If that is the case, you can answer based on your knowledge, but you must clearly state that you are doing so.\n" - "**DO NOT** hallucinate or make up information.\n" - "### END OF SYSTEM INSTRUCTION ###" +SELF_GEN_SYSTEM_MSG = ( + # "### SYSTEM INSTRUCTION ###\n" + # "You are an honest and helpful assistant.\n" + # "**DO NOT** hallucinate or make up information.\n" + # "### END OF SYSTEM INSTRUCTION ###" + "You are an honest and helpful assistant." ) -CTX_Q_SEP = "\n\n---\n\n# User\n" - SELF_QA_INTX = ( - # "---\n\n" "# System Instruction\n" - "- The information provided is up-to-date information.\n" + "- The information provided is up-to-date information and/or the user instruction.\n" "- When the provided information is not relevant to the question, ***ignore*** it and answer the question based on your knowledge.\n" - "- If the provided information is related to the question, incorporate it in your response." - + CTX_Q_SEP + "- If the provided information is related to the question, incorporate it in your response.\n" + "- If the provided information is an instruction, follow the instruction carefully.\n" + "\n---\n\n" + "# User Input\n" ) -PROMPT_TEMPLATE = "{context}" + CTX_Q_SEP + "{question}" +PRE_CTX = "# Provided Information\n" -PRE_CTX = "" -PROMPT_TEMPLATE_QA = "# Information\n{context}\n\n---\n\n" + SELF_QA_INTX + "{question}" - - -""" - ---- - -# System Instruction -- The information provided is up-to-date information. -- When the provided information is not relevant to the question, ***ignore*** it and answer the question based on your knowledge. -- If the provided information is related to the question, incorporate it in your response. - ---- -# User - -What team is Mbappe playing for? - -""" +PROMPT_TEMPLATE = PRE_CTX + "{context}\n\n---\n\n" + SELF_QA_INTX + "{question}" MODEL_CTX_LEN = { "google/gemma-2-27b-it": 8192, @@ -104,15 +85,27 @@ def truncate_middle_if_too_long( return input_ids -def get_prompt(context: str, q: str, use_qa_template: bool) -> str: - template = PROMPT_TEMPLATE_QA if use_qa_template else PROMPT_TEMPLATE - return template.format(context=context, question=q) +def get_prompt(context: str, q: str) -> str: + return PROMPT_TEMPLATE.format(context=context, question=q) -def add_closed_qa_prompt(q: str, closed_qa_prob: float = 0.1) -> str: - if random.random() <= closed_qa_prob: - q = random.choice(CLOSED_QA_INTX_TEMPLATES).format(input=q) - return q +def augment_prompt(sample, closed_qa_prob, cot_prob): + z = random.random() + should_add_closed_qa = ("type" not in sample) or (sample["type"] == "question") + if should_add_closed_qa and (z < closed_qa_prob): + sample["prompts"] = add_closed_qa_prompt(sample["prompts"]) + elif closed_qa_prob <= z < (closed_qa_prob + cot_prob): + sample["prompts"] = add_cot_prompt(sample["prompts"]) + + return sample + + +def add_cot_prompt(prompts: list[str]) -> str: + return [random.choice(COT_TEMPLATES).format(input=q) for q in prompts] + + +def add_closed_qa_prompt(prompts: list[str]) -> str: + return [random.choice(CLOSED_QA_INTX_TEMPLATES).format(input=q) for q in prompts] def load_config(config_path: str) -> dict: @@ -122,12 +115,47 @@ def load_config(config_path: str) -> dict: return config -# def check_should_skip(txt: str, vllm_model: str) -> bool: -# """Check if the response should be skipped based on stop strings.""" -# for stop in STOP_STRINGS[vllm_model]: -# if stop in txt[-len(stop) :]: -# return (txt.split(stop)[0], False) # Found a valid stop string -# return (txt, True) # No valid stop string found, skip this response +def add_paraphrasing_prompt(samples, summ_prob: float, struct_prob: float): + """Augment batch with summarization / structuring prompts given separate probabilities. + The original samples are extended (in-place) with newly created paraphrased variants. + """ + if summ_prob == 0 and struct_prob == 0: + return samples + n_samples = len(samples["ctx_ids"]) if "ctx_ids" in samples else 0 + if n_samples == 0: + return samples + + n_summ = int(n_samples * summ_prob) + n_struct = int(n_samples * struct_prob) + all_indices = list(range(n_samples)) + random.shuffle(all_indices) + summ_indices = all_indices[:n_summ] + struct_indices = all_indices[n_summ : n_summ + n_struct] + + def _add(kind_indices, prompts_source, prompt_type): + out = dict() + if not kind_indices: + return out + for k in samples: + if k == "prompts": + sampled_prompts = random.choices(prompts_source, k=len(kind_indices)) + out[k] = [[p] for p in sampled_prompts] + elif k == "type": + out[k] = [prompt_type] * len(kind_indices) + else: + out[k] = [samples[k][i] for i in kind_indices] + return out + + summ_samples = _add(summ_indices, SUMMARIZATION_PROMPTS, "summarization") + struct_samples = _add(struct_indices, STRUCTURING_PROMPTS, "structuring") + + # Extend original samples + for k in samples: + if summ_indices: + samples[k] += summ_samples[k] + if struct_indices: + samples[k] += struct_samples[k] + return samples def get_dataset_configs( @@ -178,11 +206,7 @@ def get_dataset_configs( def create_messages( - ctxs: list[str], - questions: list[list[str]], - vllm_model: str, - system_template: str, - use_qa_template: bool, + ctxs: list[str], questions: list[list[str]], vllm_model: str, system_template: str ) -> list[list[dict]]: """Create chat messages for the model.""" # if "gemma" in vllm_model: @@ -191,9 +215,7 @@ def create_messages( [ { "role": "user", - "content": system_template - + "\n\n\n" - + get_prompt(ctx, q, use_qa_template), + "content": (system_template + "\n\n\n" + get_prompt(ctx, q)).strip(), } ] for ctx, q_list in zip(ctxs, questions) @@ -218,42 +240,63 @@ def self_generate( system_template: str, parquet_file: str | None = None, do_truncate: bool = False, - use_qa_template: bool = True, - max_new_tokens: int = 1024, ) -> None: """Process a single dataset and generate QA pairs.""" shard_name = "" - # Check for conflicts between CLI args and dataset name + # Conflict checks for ds_name-derived overrides if ds_name is not None: + # temperature & closed_qa already handled later; add new ones if "_temp_" in ds_name and args.temp != 0.0: raise ValueError( - f"Multiple sources of truth for temperature: CLI arg --temp={args.temp} " - f"and dataset name contains temp specification. Please use only one." + f"Multiple sources of truth for temperature: CLI arg --temp={args.temp} and dataset name contains temp specification." ) if "_closed_qa_prob_" in ds_name and args.closed_qa_prob != 0.0: raise ValueError( - f"Multiple sources of truth for closed_qa_prob: CLI arg --closed_qa_prob={args.closed_qa_prob} " - f"and dataset name contains closed_qa_prob specification. Please use only one." + f"Multiple sources of truth for closed_qa_prob: CLI arg --closed_qa_prob={args.closed_qa_prob} and dataset name contains closed_qa_prob specification." + ) + if "_summ_prob_" in ds_name and args.summ_prob != 0.0: + raise ValueError( + f"Multiple sources of truth for summ_prob: CLI arg --summ_prob={args.summ_prob} and dataset name contains summ_prob specification." + ) + if "_struct_prob_" in ds_name and args.struct_prob != 0.0: + raise ValueError( + f"Multiple sources of truth for struct_prob: CLI arg --struct_prob={args.struct_prob} and dataset name contains struct_prob specification." ) - # Use CLI args as default, override with dataset name if present + # Base values from args temp = args.temp closed_qa_prob = args.closed_qa_prob + summ_prob = args.summ_prob + struct_prob = args.struct_prob + cot_prob = args.cot_prob + + # Overrides from ds_name pattern if present + if ds_name is not None: + if "_temp_" in ds_name: + m = re.search(r"_temp_([\d.]+)", ds_name) + if m: + temp = float(m.group(1)) + if "_closed_qa_prob_" in ds_name: + m = re.search(r"_closed_qa_prob_([\d.]+)", ds_name) + if m: + closed_qa_prob = float(m.group(1)) + if "_summ_prob_" in ds_name: + m = re.search(r"_summ_prob_([\d.]+)", ds_name) + if m: + summ_prob = float(m.group(1)) + if "_struct_prob_" in ds_name: + m = re.search(r"_struct_prob_([\d.]+)", ds_name) + if m: + struct_prob = float(m.group(1)) - if ds_name is not None and "_temp_" in ds_name: - temp_match = re.search(r"_temp_([\d.]+)", ds_name) - if temp_match: - temp = float(temp_match.group(1)) - if ds_name is not None and "_closed_qa_prob_" in ds_name: - prob_match = re.search(r"_closed_qa_prob_([\d.]+)", ds_name) - if prob_match: - closed_qa_prob = float(prob_match.group(1)) print(f"Processing dataset: {ds_name}, split: {split}") print(f"Using temperature: {temp}") print(f"Using closed QA prompt probability: {closed_qa_prob}") - print(f"Use QA template: {use_qa_template}") + print(f"Using chain-of-thought prompt probability: {cot_prob}") + print(f"Using summarization augmentation probability: {summ_prob}") + print(f"Using structuring augmentation probability: {struct_prob}") if parquet_file: print(f"Loading dataset from parquet file: {parquet_file}") @@ -272,18 +315,19 @@ def self_generate( print(f"Loading dataset: {ds_name} with split: {split}") kwargs = dict(ds_name=ds_name, split=split) - ds = load_and_process_dataset(**kwargs, num_proc=8) + ds = load_and_process_dataset(**kwargs, num_proc=8, remove_cols=False) print(f"Loaded dataset: {ds_name} with split: {split}") if args.debug: - ds = ds.take(10) + ds = ds.take(50) ds = ds.filter(filter_none, batched=False, num_proc=8) + print(f"0. {len(ds)=}") tk = get_tokenizer(args.vllm_model, train=True) - ctx_q_sep_tokens = tk(CTX_Q_SEP, add_special_tokens=False)["input_ids"] - n_qa_sep_tokens = len(ctx_q_sep_tokens) + self_qa_intx_tokens = tk(SELF_QA_INTX, add_special_tokens=False)["input_ids"] + n_self_qa_intx_tokens = len(self_qa_intx_tokens) pre_ctx_tokens = tk(PRE_CTX, add_special_tokens=False)["input_ids"] n_pre_ctx_tokens = len(pre_ctx_tokens) sys_tokens = tk(system_template.split("\n")[0], add_special_tokens=False)[ @@ -299,15 +343,46 @@ def self_generate( keep_in_memory=True, ) + ds = ds.map( + augment_prompt, + fn_kwargs={"closed_qa_prob": closed_qa_prob, "cot_prob": cot_prob}, + keep_in_memory=True, + num_proc=16, + ) + + ds = ds.map( + add_paraphrasing_prompt, + batched=True, + fn_kwargs={ + "summ_prob": summ_prob, + "struct_prob": struct_prob, + }, + batch_size=50_000, + keep_in_memory=True, + ) + ctxs = [sample["context"] for sample in ds] - questions = [ - [add_closed_qa_prompt(q, closed_qa_prob) for q in sample["prompts"] if q] - for sample in ds - ] + + questions = ds["prompts"] + # for sample in ds: + # if ("type" not in sample) or ( + # "type" in sample and sample["type"] == "question" + # ): + # # for generated qa, apply to only "question" type + # questions.append( + # [ + # add_closed_qa_prompt(q, closed_qa_prob) + # for q in sample["prompts"] + # if q + # ] + # ) + # else: + # questions.append([q for q in sample["prompts"] if q]) + print(f"Loaded {len(ctxs)} contexts and {len(questions)} questions") k = 16 - fpath = f"{SELF_GEN_DATA_DIR}/{args.vllm_model}_temp_{temp}_closed_qa_prob_{closed_qa_prob}/{ds_name}/{split}/ds{shard_name}" + fpath = f"{SELF_GEN_DATA_DIR}/{args.vllm_model}_temp_{temp}_closed_qa_prob_{closed_qa_prob}_cot_prob_{cot_prob}_summ_prob_{summ_prob}_struct_prob_{struct_prob}/{ds_name}/{split}/ds{shard_name}" chunk_size = 1_000 for chunk_idx, start in enumerate(range(0, len(ctxs), chunk_size)): @@ -316,11 +391,7 @@ def self_generate( chunk_ctxs = ctxs[start : start + chunk_size] chunk_questions = questions[start : start + chunk_size] chunk_messages = create_messages( - chunk_ctxs, - chunk_questions, - args.vllm_model, - SELF_GEN_SYSTEM_MSG, - use_qa_template, + chunk_ctxs, chunk_questions, args.vllm_model, SELF_GEN_SYSTEM_MSG ) if do_truncate: @@ -334,7 +405,7 @@ def self_generate( truncate_middle_if_too_long( ids, max_length=MODEL_CTX_LEN[args.vllm_model], - max_new_tokens=max_new_tokens, + max_new_tokens=1024, ) for ids in tokenized_contents["input_ids"] ] @@ -354,8 +425,8 @@ def self_generate( llm, temp, tk, - ctx_q_sep_tokens, - n_qa_sep_tokens, + self_qa_intx_tokens, + n_self_qa_intx_tokens, sys_tokens, n_sys_tokens, chunk_ctxs, @@ -363,7 +434,6 @@ def self_generate( chunk_questions, chunk_messages, k, - max_new_tokens, ) @@ -373,8 +443,8 @@ def execute_qa_generation( llm, temp, tk, - ctx_q_sep_tokens, - n_qa_sep_tokens, + self_qa_intx_tokens, + n_self_qa_intx_tokens, sys_tokens, n_sys_tokens, ctxs, @@ -382,12 +452,11 @@ def execute_qa_generation( questions, messages, k, - max_tokens, ): completions = llm.chat( messages, sampling_params=SamplingParams( - max_tokens=max_tokens, + max_tokens=1024, logprobs=k, temperature=temp, seed=42, @@ -395,8 +464,6 @@ def execute_qa_generation( skip_special_tokens=False, include_stop_str_in_output=True, ), - chat_template=tk.chat_template, - chat_template_content_format="string", ) self_gen_data = { @@ -459,13 +526,13 @@ def execute_qa_generation( q_start = None for ii in range( - len(prompt_ids) - n_qa_sep_tokens, + len(prompt_ids) - n_self_qa_intx_tokens, -1, -1, ): - if prompt_ids[ii : ii + n_qa_sep_tokens] == ctx_q_sep_tokens: + if prompt_ids[ii : ii + n_self_qa_intx_tokens] == self_qa_intx_tokens: # found the start of the user input - q_start = ii + n_qa_sep_tokens + q_start = ii + n_self_qa_intx_tokens break # bos + question + eos + start model turn + response + eos @@ -523,7 +590,7 @@ def execute_qa_generation( if args.debug: for sample in samples: - print(f"context={tk.decode(sample['ctx_ids'])}") + # print(f"context={tk.decode(sample['ctx_ids'])}") print(f"QA={[tk.decode(ids) for ids in sample['input_ids']]}") for input_ids, (start, end) in zip( @@ -532,12 +599,6 @@ def execute_qa_generation( print(f"start={start}, end={end}") print(f"response={tk.decode(input_ids[start:end])}") - for input_ids, (start, end) in zip( - sample["input_ids"], sample["prompt_start_end"] - ): - print(f"start={start}, end={end}") - print(f"prompt={tk.decode(input_ids[start:end])}") - print(f"logprobs_vals={[x.shape for x in sample['logprobs_vals']]}") print(f"logprobs_indices={[x.shape for x in sample['logprobs_indices']]}") for indices in sample["logprobs_indices"]: @@ -614,22 +675,29 @@ def parse_args() -> argparse.Namespace: default=0.0, help="Probability of using closed QA prompt template (default: 0.0)", ) + parser.add_argument( + "--cot_prob", + type=float, + default=0.0, + help="Probability of using chain-of-thought prompt template (default: 0.0)", + ) + parser.add_argument( + "--summ_prob", + type=float, + default=0.0, + help="Probability of adding a summarization variant (default: 0.0)", + ) + parser.add_argument( + "--struct_prob", + type=float, + default=0.0, + help="Probability of adding a structuring variant (default: 0.0)", + ) parser.add_argument( "--do_truncate", action="store_true", help="Truncate contexts to fit model context length", ) - parser.add_argument( - "--max_new_tokens", - type=int, - default=1024, - help="Maximum number of new tokens to generate (default: 1024)", - ) - parser.add_argument( - "--remove_qa_template", - action="store_true", - help="Remove the QA template from the prompt (default: False)", - ) return parser.parse_args() @@ -670,15 +738,7 @@ if __name__ == "__main__": for ds_name, split in dataset_configs: print(f"Processing dataset: {ds_name}, split: {split}") self_generate( - ds_name, - split, - args, - llm, - system_template=SYSTEM_TEMPLATE, - parquet_file=None, - do_truncate=args.do_truncate, - use_qa_template=not args.remove_qa_template, - max_new_tokens=args.max_new_tokens, + ds_name, split, args, llm, SELF_GEN_SYSTEM_MSG, args.do_truncate ) else: assert args.glob_pattern, ( @@ -693,8 +753,6 @@ if __name__ == "__main__": split=args.split, args=args, llm=llm, - system_template=SYSTEM_TEMPLATE, + system_template=SELF_GEN_SYSTEM_MSG, do_truncate=args.do_truncate, - use_qa_template=not args.remove_qa_template, - max_new_tokens=args.max_new_tokens, ) diff --git a/pyproject.toml b/pyproject.toml index 0865184..7608885 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ dependencies = [ "pandas", "plotly", "rouge-score", - "vllm==0.8.5", + "vllm==0.8.4", "huggingface-hub[hf-transfer]>=0.32.0", "opt-einsum>=3.4.0", "kagglehub[hf-datasets]>=0.3.12", @@ -37,6 +37,7 @@ dependencies = [ "bitsandbytes>=0.46.1", "google-cloud-storage>=3.2.0", "wonderwords>=2.2.0", + "tokenizers==0.21.0", ] [build-system] diff --git a/src/ctx_to_lora/data/definitions.py b/src/ctx_to_lora/data/definitions.py index 7f7effa..79f69f4 100644 --- a/src/ctx_to_lora/data/definitions.py +++ b/src/ctx_to_lora/data/definitions.py @@ -21,32 +21,72 @@ SELF_GEN_SYSTEM_MSG = ( ) -REPEAT_PROMPTS = [ - "Repeat the information.", - "Repeat the information above.", - "Repeat the above information.", - # "Repeat exactly what was written.", - "Duplicate the information.", - "Echo the information. Do not output other words.", - "Repeat the information provided.", - "Copy the information. Reply with just the information.", - "Replicate the given information precisely.", - "Repeat the entire provided information above.", - "Duplicate exactly the provided information.", - "Repeat the information that appears above.", - # "Reproduce exactly what appears above.", - # "Repeat the article.", - "Repeat verbatim the given information.", - "Output the same information as provided.", - "Output an exact copy of the information above.", - "Provide a replica of the information.", - "Output an identical copy of the information.", - "Repeat the information without any changes.", - "Repeat the provided information.", - "Repeat the provided information above.", - "Repeat precisely what is written in the information above.", +SUMMARIZATION_PROMPTS = [ + "Summarize the article." + "Provide a concise summary capturing the main idea and key detail.", + "Write a one-paragraph executive summary of the passage. Avoid fluff.", + "Create a bullet list of the core points from the text. No intro line.", + "Summarize the content for a general audience with no domain knowledge.", + "Produce a headline that best represents the passage.", + "Give a headline and a subheadline separated by a newline summarizing the article.", + "Write a tweet-length summary (max 240 characters, no hashtags).", + "Condense the passage into a plain-language abstract.", + "Explain the passage as if speaking to a 10-year-old.", + "Summarize the information presented.", + "Extract and list the three most critical facts. No extra wording.", + "Provide a neutral summary (no opinion words) in one paragraph.", + "Summarize emphasizing quantitative data only. Ignore narrative.", + "Provide a facts-only summary: list raw data points, no interpretation.", + "Summarize by extracting all key figures and associated units only.", + "Provide a brief TL;DR starting with 'TL;DR:'.", + "Summarize in exactly 25 words. If needed, rephrase to fit.", + "Produce a question-and-answer style summary with 3 Q&A pairs capturing essence.", + "Provide a summary that only uses the 600 most common English words.", + "Create a concise abstract in academic tone.", + "Write a marketing-style summary appealing to a broad audience.", + "Summarize in the form of a newspaper lead (who, what, when, where, why).", + "Write a summary that preserves all numbers and proper nouns verbatim.", + "Produce a satirical-style summary (remain respectful).", + "Summarize with a formal tone using no contractions.", + "Summarize with an informal conversational tone", + "Summarize as if reporting to a technical expert (dense, precise).", + "Summarize as if explaining to a non-technical stakeholder (clear, simplified).", + "Summarize including exactly one direct quote (short) from the text if present.", + "Summarize into a structured JSON with keys: topic, key_points (array), tone. Do not add commentary.", + "Write a poetic-style 2-line summary (no rhyme required).", + "Summarize in exactly 3 bullet points.", + "Summarize in question form: pose 2-3 questions that capture essence.", + "Summarize as a press release opening paragraph.", + "Summarize focusing on benefits to end users.", + "Summarize avoiding any jargon; replace technical terms with common words.", + "Produce a summary in exactly 2 haiku-style lines (not strict syllables).", + "Summarize as if drafting the opening line of an encyclopedia entry.", ] +COT_TEMPLATES = [ + "{input} Think out loud before giving an answer.", + "{input} Think step by step to ensure a correct final answer.", + "{input} List any assumptions, reason through the steps, then provide the final answer.", + "{input} Explain your reasoning clearly first.", + "{input} Reason carefully: identify what is known, what is needed, derive intermediate conclusions, then answer.", + "{input} Enumerate relevant facts, derive implications, eliminate alternatives, then state the answer.", + "{input} Think through possible interpretations, choose the most plausible, reason it out, then answer.", + "{input} Consider edge cases or exceptions while reasoning step by step before finalizing your answer.", + "{input} List data given, infer what is missing, derive needed values logically, then answer.", + "{input} Use logical deduction step by step; avoid jumping to the conclusion. Conclude with the answer.", + "{input} Reason transparently: gather, analyze, synthesize, conclude. Final answer after the reasoning.", +] + +STRUCTURING_PROMPTS = [ + f"Can you structure the information in the {format} format? Be sure to include precise information like any dates, times, names, and numerical values." + for format in ["JSON", "YAML", "TOML", "bullet"] +] + +STRUCTURING_PROMPTS += [ + "Can you structure the information in plain text that is easy to read? Be sure to include precise information like any dates, times, names, and numerical values." +] + + # for chunking CTX_AFFIXES = { "google/gemma-3-1b-it": { @@ -120,9 +160,9 @@ DS_KWARGS = { ), ), "hotpot_qa": dict( - train=dict(path="hotpotqa/hotpot_qa", name="fullwiki", split="train[900:]"), + train=dict(path="hotpotqa/hotpot_qa", name="fullwiki", split="train"), validation=dict( - path="hotpotqa/hotpot_qa", name="fullwiki", split="train[:900]" + path="hotpotqa/hotpot_qa", name="fullwiki", split="validation[:900]" ), test=dict(path="hotpotqa/hotpot_qa", name="fullwiki", split="validation"), ), @@ -133,16 +173,15 @@ DS_KWARGS = { ), ), "pwc": dict( - train=dict(path="sggetao/PwC", split="train[900:]"), - validation=dict(path="sggetao/PwC", split="train[:900]"), + train=dict(path="sggetao/PwC", split="train"), + validation=dict(path="sggetao/PwC", split="test[:900]"), test=dict(path="sggetao/PwC", split="test"), ), "pwc_compact": dict( train=dict( path="parquet", data_files="data/raw_datasets/pwc_compact/train/ds.parquet", - # correspond to skipping to first 900 samples in the original dataset - split="train[60:]", + split="train", ), ), "pwc_compact_tiny": dict( @@ -158,8 +197,8 @@ DS_KWARGS = { validation=dict(path="sggetao/PwC", split="train[:900]"), ), "squad": dict( - train=dict(path="data/raw_datasets/squad", split="train[900:]"), - validation=dict(path="data/raw_datasets/squad", split="train[:900]"), + train=dict(path="data/raw_datasets/squad", split="train"), + validation=dict(path="data/raw_datasets/squad", split="validation[:1000]"), test=dict(path="data/raw_datasets/squad", split="validation"), # train=dict(path="rajpurkar/squad", split="train[900:]"), # validation=dict(path="rajpurkar/squad", split="train[:900]"), @@ -565,6 +604,11 @@ DS_KWARGS = { ), # for negative training and evaluating "negative_nq": dict( + train=dict( + path="json", + data_files="data/raw_datasets/negative_natural_questions/train.jsonl", + split="train", + ), validation=dict( path="json", data_files="data/raw_datasets/negative_natural_questions/validation.jsonl", @@ -607,6 +651,44 @@ DS_KWARGS = { train=dict(path="HuggingFaceTB/smoltalk", name="systemchats-30k", split="train") ), "ctx-q-gsm": dict(train=dict(path="letta-ai/stateful-gsm-symbolic", split="train")), + "automathtext_web": dict( + dict( + train=dict( + path="math-ai/AutoMathText", name="web-0.50-to-1.00", split="train" + ) + ) + ), + "automathtext_code_python": dict( + dict( + train=dict( + path="math-ai/AutoMathText", + name="code-python-0.50-to-1.00", + split="train", + ) + ) + ), + "automathtext_code_notebook": dict( + dict( + train=dict( + path="math-ai/AutoMathText", + name="code-jupyter-notebook-0.50-to-1.00", + split="train", + ) + ) + ), + "automathtext_arxiv": dict( + dict( + train=dict( + path="math-ai/AutoMathText", name="arxiv-0.50-to-1.00", split="train" + ) + ) + ), + "codeparrot": dict( + dict(train=dict(path="transformersbook/codeparrot", split="train")) + ), + "programming_books": dict( + dict(train=dict(path="open-phi/programming_books_llama", split="train")) + ), } # add ctx_numbers diff --git a/src/ctx_to_lora/data/preprocessing_fn.py b/src/ctx_to_lora/data/preprocessing_fn.py index e7839b6..aeaf151 100644 --- a/src/ctx_to_lora/data/preprocessing_fn.py +++ b/src/ctx_to_lora/data/preprocessing_fn.py @@ -15,7 +15,7 @@ def closed_qa_prompting(prompt: str): def chat_to_str(messages: list[dict[str, str]]): - return "\n\n".join( + return "Below is the chat history from the current user.\n\n" + "\n\n".join( [ "Message from: {role}\n{content}".format( **{**m, "role": m["role"].capitalize()} @@ -97,11 +97,9 @@ def get_preprocessing_fn( elif ds_name == "negative_nq": def f(sample): - q = sample["prompt"] - prompt = closed_qa_prompting(q) if not is_eval else q return { "context": sample["context"], - "prompt": prompt, + "prompt": sample["prompt"], "response": sample["answer"], } @@ -199,6 +197,7 @@ def get_preprocessing_fn( } elif ds_name == "booksum": + # TODO: sample from SUMM_PROMPTS once improved data gen branch is merged prompt_templates = [ "Summarization the provided text.", "# Summary", @@ -299,6 +298,33 @@ def get_preprocessing_fn( response = sample["answer"] return {"context": ctx, "prompt": q, "response": response} + elif ds_name.startswith("automathtext"): + + def f(sample): + return { + "context": sample["text"], + "prompt": "PLACEHOLDER. PLEASE GENERATE QUESTIONS FOR THIS DATASET.", + "response": "PLACEHOLDER PLEASE GENERATE QUESTIONS FOR THIS DATASET.", + } + + elif "codeparrot" == ds_name: + + def f(sample): + return { + "context": sample["content"], + "prompt": "PLACEHOLDER. PLEASE GENERATE QUESTIONS FOR THIS DATASET.", + "response": "PLACEHOLDER. PLEASE GENERATE QUESTIONS FOR THIS DATASET.", + } + + elif "programming_books" == ds_name: + + def f(sample): + return { + "context": sample["markdown"], + "prompt": "PLACEHOLDER. PLEASE GENERATE QUESTIONS FOR THIS DATASET.", + "response": "PLACEHOLDER. PLEASE GENERATE QUESTIONS FOR THIS DATASET.", + } + if is_eval and (ds_name in EVAL_INTX_TEMPLATES): prompt_template = EVAL_INTX_TEMPLATES[ds_name] diff --git a/src/ctx_to_lora/data/processing.py b/src/ctx_to_lora/data/processing.py index d892efa..bc37e3e 100644 --- a/src/ctx_to_lora/data/processing.py +++ b/src/ctx_to_lora/data/processing.py @@ -20,7 +20,6 @@ from ctx_to_lora.data.definitions import ( DS_KWARGS, IGNORE_INDEX, RAW_DATA_DIR, - REPEAT_PROMPTS, SELF_GEN_DATA_DIR, TRANSFORMED_DATA_DIR, ) @@ -93,10 +92,6 @@ def load_answers(ds_name, split): return ds -def get_repeat_prompt(): - return random.choice(REPEAT_PROMPTS) - - def get_ds_kwargs(ds_name: str, split: str) -> dict[str, Any]: # custom logic for slicing iterable datasets take, skip = None, None @@ -169,6 +164,7 @@ def load_and_process_dataset( ds_name: str, split: str, num_proc: int, + remove_cols: bool = True, ): logger.info(f"Loading dataset {ds_name} with split {split}...") try: @@ -184,9 +180,11 @@ def load_and_process_dataset( raise ValueError( f"Failed to load dataset {ds_name} with split {split}. Error: {e}" ) - cols_to_remove = [ - col for col in ds.column_names if col not in COLS_TO_KEEP_PREPROCESSING - ] + cols_to_remove = None + if remove_cols: + cols_to_remove = [ + col for col in ds.column_names if col not in COLS_TO_KEEP_PREPROCESSING + ] is_eval = split != "train" ds = ds.map( get_preprocessing_fn(ds_name, is_eval), diff --git a/uv.lock b/uv.lock index 4701ac2..4d8c72d 100644 --- a/uv.lock +++ b/uv.lock @@ -719,6 +719,7 @@ dependencies = [ { name = "setuptools" }, { name = "tensorboard" }, { name = "tensorboardx" }, + { name = "tokenizers" }, { name = "torchmetrics" }, { name = "transformers" }, { name = "vllm" }, @@ -754,9 +755,10 @@ requires-dist = [ { name = "setuptools" }, { name = "tensorboard" }, { name = "tensorboardx" }, + { name = "tokenizers", specifier = "==0.21.0" }, { name = "torchmetrics" }, { name = "transformers", specifier = "==4.51.3" }, - { name = "vllm", specifier = "==0.8.5" }, + { name = "vllm", specifier = "==0.8.4" }, { name = "wandb" }, { name = "wonderwords", specifier = ">=2.2.0" }, ] @@ -5064,27 +5066,27 @@ wheels = [ [[package]] name = "tokenizers" -version = "0.21.1" +version = "0.21.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "huggingface-hub" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/92/76/5ac0c97f1117b91b7eb7323dcd61af80d72f790b4df71249a7850c195f30/tokenizers-0.21.1.tar.gz", hash = "sha256:a1bb04dc5b448985f86ecd4b05407f5a8d97cb2c0532199b2a302a604a0165ab", size = 343256, upload-time = "2025-03-13T10:51:18.189Z" } +sdist = { url = "https://files.pythonhosted.org/packages/20/41/c2be10975ca37f6ec40d7abd7e98a5213bb04f284b869c1a24e6504fd94d/tokenizers-0.21.0.tar.gz", hash = "sha256:ee0894bf311b75b0c03079f33859ae4b2334d675d4e93f5a4132e1eae2834fe4", size = 343021, upload-time = "2024-11-27T13:11:23.89Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/1f/328aee25f9115bf04262e8b4e5a2050b7b7cf44b59c74e982db7270c7f30/tokenizers-0.21.1-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:e78e413e9e668ad790a29456e677d9d3aa50a9ad311a40905d6861ba7692cf41", size = 2780767, upload-time = "2025-03-13T10:51:09.459Z" }, - { url = "https://files.pythonhosted.org/packages/ae/1a/4526797f3719b0287853f12c5ad563a9be09d446c44ac784cdd7c50f76ab/tokenizers-0.21.1-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:cd51cd0a91ecc801633829fcd1fda9cf8682ed3477c6243b9a095539de4aecf3", size = 2650555, upload-time = "2025-03-13T10:51:07.692Z" }, - { url = "https://files.pythonhosted.org/packages/4d/7a/a209b29f971a9fdc1da86f917fe4524564924db50d13f0724feed37b2a4d/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28da6b72d4fb14ee200a1bd386ff74ade8992d7f725f2bde2c495a9a98cf4d9f", size = 2937541, upload-time = "2025-03-13T10:50:56.679Z" }, - { url = "https://files.pythonhosted.org/packages/3c/1e/b788b50ffc6191e0b1fc2b0d49df8cff16fe415302e5ceb89f619d12c5bc/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:34d8cfde551c9916cb92014e040806122295a6800914bab5865deb85623931cf", size = 2819058, upload-time = "2025-03-13T10:50:59.525Z" }, - { url = "https://files.pythonhosted.org/packages/36/aa/3626dfa09a0ecc5b57a8c58eeaeb7dd7ca9a37ad9dd681edab5acd55764c/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aaa852d23e125b73d283c98f007e06d4595732104b65402f46e8ef24b588d9f8", size = 3133278, upload-time = "2025-03-13T10:51:04.678Z" }, - { url = "https://files.pythonhosted.org/packages/a4/4d/8fbc203838b3d26269f944a89459d94c858f5b3f9a9b6ee9728cdcf69161/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a21a15d5c8e603331b8a59548bbe113564136dc0f5ad8306dd5033459a226da0", size = 3144253, upload-time = "2025-03-13T10:51:01.261Z" }, - { url = "https://files.pythonhosted.org/packages/d8/1b/2bd062adeb7c7511b847b32e356024980c0ffcf35f28947792c2d8ad2288/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2fdbd4c067c60a0ac7eca14b6bd18a5bebace54eb757c706b47ea93204f7a37c", size = 3398225, upload-time = "2025-03-13T10:51:03.243Z" }, - { url = "https://files.pythonhosted.org/packages/8a/63/38be071b0c8e06840bc6046991636bcb30c27f6bb1e670f4f4bc87cf49cc/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dd9a0061e403546f7377df940e866c3e678d7d4e9643d0461ea442b4f89e61a", size = 3038874, upload-time = "2025-03-13T10:51:06.235Z" }, - { url = "https://files.pythonhosted.org/packages/ec/83/afa94193c09246417c23a3c75a8a0a96bf44ab5630a3015538d0c316dd4b/tokenizers-0.21.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:db9484aeb2e200c43b915a1a0150ea885e35f357a5a8fabf7373af333dcc8dbf", size = 9014448, upload-time = "2025-03-13T10:51:10.927Z" }, - { url = "https://files.pythonhosted.org/packages/ae/b3/0e1a37d4f84c0f014d43701c11eb8072704f6efe8d8fc2dcdb79c47d76de/tokenizers-0.21.1-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:ed248ab5279e601a30a4d67bdb897ecbe955a50f1e7bb62bd99f07dd11c2f5b6", size = 8937877, upload-time = "2025-03-13T10:51:12.688Z" }, - { url = "https://files.pythonhosted.org/packages/ac/33/ff08f50e6d615eb180a4a328c65907feb6ded0b8f990ec923969759dc379/tokenizers-0.21.1-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:9ac78b12e541d4ce67b4dfd970e44c060a2147b9b2a21f509566d556a509c67d", size = 9186645, upload-time = "2025-03-13T10:51:14.723Z" }, - { url = "https://files.pythonhosted.org/packages/5f/aa/8ae85f69a9f6012c6f8011c6f4aa1c96154c816e9eea2e1b758601157833/tokenizers-0.21.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e5a69c1a4496b81a5ee5d2c1f3f7fbdf95e90a0196101b0ee89ed9956b8a168f", size = 9384380, upload-time = "2025-03-13T10:51:16.526Z" }, - { url = "https://files.pythonhosted.org/packages/e8/5b/a5d98c89f747455e8b7a9504910c865d5e51da55e825a7ae641fb5ff0a58/tokenizers-0.21.1-cp39-abi3-win32.whl", hash = "sha256:1039a3a5734944e09de1d48761ade94e00d0fa760c0e0551151d4dd851ba63e3", size = 2239506, upload-time = "2025-03-13T10:51:20.643Z" }, - { url = "https://files.pythonhosted.org/packages/e6/b6/072a8e053ae600dcc2ac0da81a23548e3b523301a442a6ca900e92ac35be/tokenizers-0.21.1-cp39-abi3-win_amd64.whl", hash = "sha256:0f0dcbcc9f6e13e675a66d7a5f2f225a736745ce484c1a4e07476a89ccdad382", size = 2435481, upload-time = "2025-03-13T10:51:19.243Z" }, + { url = "https://files.pythonhosted.org/packages/b0/5c/8b09607b37e996dc47e70d6a7b6f4bdd4e4d5ab22fe49d7374565c7fefaf/tokenizers-0.21.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:3c4c93eae637e7d2aaae3d376f06085164e1660f89304c0ab2b1d08a406636b2", size = 2647461, upload-time = "2024-11-27T13:11:07.911Z" }, + { url = "https://files.pythonhosted.org/packages/22/7a/88e58bb297c22633ed1c9d16029316e5b5ac5ee44012164c2edede599a5e/tokenizers-0.21.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:f53ea537c925422a2e0e92a24cce96f6bc5046bbef24a1652a5edc8ba975f62e", size = 2563639, upload-time = "2024-11-27T13:11:05.908Z" }, + { url = "https://files.pythonhosted.org/packages/f7/14/83429177c19364df27d22bc096d4c2e431e0ba43e56c525434f1f9b0fd00/tokenizers-0.21.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b177fb54c4702ef611de0c069d9169f0004233890e0c4c5bd5508ae05abf193", size = 2903304, upload-time = "2024-11-27T13:10:51.315Z" }, + { url = "https://files.pythonhosted.org/packages/7e/db/3433eab42347e0dc5452d8fcc8da03f638c9accffefe5a7c78146666964a/tokenizers-0.21.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6b43779a269f4629bebb114e19c3fca0223296ae9fea8bb9a7a6c6fb0657ff8e", size = 2804378, upload-time = "2024-11-27T13:10:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/57/8b/7da5e6f89736c2ade02816b4733983fca1c226b0c42980b1ae9dc8fcf5cc/tokenizers-0.21.0-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9aeb255802be90acfd363626753fda0064a8df06031012fe7d52fd9a905eb00e", size = 3095488, upload-time = "2024-11-27T13:11:00.662Z" }, + { url = "https://files.pythonhosted.org/packages/4d/f6/5ed6711093dc2c04a4e03f6461798b12669bc5a17c8be7cce1240e0b5ce8/tokenizers-0.21.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d8b09dbeb7a8d73ee204a70f94fc06ea0f17dcf0844f16102b9f414f0b7463ba", size = 3121410, upload-time = "2024-11-27T13:10:55.674Z" }, + { url = "https://files.pythonhosted.org/packages/81/42/07600892d48950c5e80505b81411044a2d969368cdc0d929b1c847bf6697/tokenizers-0.21.0-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:400832c0904f77ce87c40f1a8a27493071282f785724ae62144324f171377273", size = 3388821, upload-time = "2024-11-27T13:10:58.401Z" }, + { url = "https://files.pythonhosted.org/packages/22/06/69d7ce374747edaf1695a4f61b83570d91cc8bbfc51ccfecf76f56ab4aac/tokenizers-0.21.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84ca973b3a96894d1707e189c14a774b701596d579ffc7e69debfc036a61a04", size = 3008868, upload-time = "2024-11-27T13:11:03.734Z" }, + { url = "https://files.pythonhosted.org/packages/c8/69/54a0aee4d576045b49a0eb8bffdc495634309c823bf886042e6f46b80058/tokenizers-0.21.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:eb7202d231b273c34ec67767378cd04c767e967fda12d4a9e36208a34e2f137e", size = 8975831, upload-time = "2024-11-27T13:11:10.32Z" }, + { url = "https://files.pythonhosted.org/packages/f7/f3/b776061e4f3ebf2905ba1a25d90380aafd10c02d406437a8ba22d1724d76/tokenizers-0.21.0-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:089d56db6782a73a27fd8abf3ba21779f5b85d4a9f35e3b493c7bbcbbf0d539b", size = 8920746, upload-time = "2024-11-27T13:11:13.238Z" }, + { url = "https://files.pythonhosted.org/packages/d8/ee/ce83d5ec8b6844ad4c3ecfe3333d58ecc1adc61f0878b323a15355bcab24/tokenizers-0.21.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:c87ca3dc48b9b1222d984b6b7490355a6fdb411a2d810f6f05977258400ddb74", size = 9161814, upload-time = "2024-11-27T13:11:16.675Z" }, + { url = "https://files.pythonhosted.org/packages/18/07/3e88e65c0ed28fa93aa0c4d264988428eef3df2764c3126dc83e243cb36f/tokenizers-0.21.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4145505a973116f91bc3ac45988a92e618a6f83eb458f49ea0790df94ee243ff", size = 9357138, upload-time = "2024-11-27T13:11:20.09Z" }, + { url = "https://files.pythonhosted.org/packages/15/b0/dc4572ca61555fc482ebc933f26cb407c6aceb3dc19c301c68184f8cad03/tokenizers-0.21.0-cp39-abi3-win32.whl", hash = "sha256:eb1702c2f27d25d9dd5b389cc1f2f51813e99f8ca30d9e25348db6585a97e24a", size = 2202266, upload-time = "2024-11-27T13:11:28.784Z" }, + { url = "https://files.pythonhosted.org/packages/44/69/d21eb253fa91622da25585d362a874fa4710be600f0ea9446d8d0217cec1/tokenizers-0.21.0-cp39-abi3-win_amd64.whl", hash = "sha256:87841da5a25a3a5f70c102de371db120f41873b854ba65e52bccd57df5a3780c", size = 2389192, upload-time = "2024-11-27T13:11:25.724Z" }, ] [[package]] @@ -5502,7 +5504,7 @@ wheels = [ [[package]] name = "vllm" -version = "0.8.5" +version = "0.8.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohttp" }, @@ -5561,9 +5563,9 @@ dependencies = [ { name = "xformers", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "xgrammar", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5c/37/7846c244e6637c15f6d5ed6d3f572eedd02ed8ab80aec8c3eb228f35b23c/vllm-0.8.5.tar.gz", hash = "sha256:c7e04d1046304397b4580334038b558fe491af155fdea508224f140172cf9a82", size = 7340498, upload-time = "2025-04-28T23:59:48.417Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e6/d6/9d412cdaa92c3ab6250cef51217d37395b2aa372c6c14f90b1668adbbf63/vllm-0.8.4.tar.gz", hash = "sha256:522b13dd16c6c773dec0cb4c42ea591623d03ef94d16db8128ece2600017e6ac", size = 6667631, upload-time = "2025-04-15T00:30:10.147Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/26/7e/08d7a75c47792fd07d02b2be6fe6adbb29dfcbd31e94784844d7f730d0bc/vllm-0.8.5-cp38-abi3-manylinux1_x86_64.whl", hash = "sha256:74bfe92953bee1269c1e1c27827bc156777751cdd6a3457ee8e27dd8ebf1e247", size = 326421025, upload-time = "2025-04-28T23:59:40.401Z" }, + { url = "https://files.pythonhosted.org/packages/8e/cb/03dc1299e0456ff3d58a11f63682ef29aaf5b1bd7f21bfe0690d7ce6fc40/vllm-0.8.4-cp38-abi3-manylinux1_x86_64.whl", hash = "sha256:e346749ee8df48cdcd935d00a7fc123a1e17d9904b064401e74fc6ad73b8104a", size = 294098962, upload-time = "2025-04-15T00:30:02.293Z" }, ] [[package]]