From ce2b3e37c60470261714759d34042b766b11080d Mon Sep 17 00:00:00 2001 From: Ranajoy Sadhukhan Date: Tue, 3 Dec 2024 06:36:53 -0500 Subject: [PATCH 1/3] added infinitebench --- scripts/download_infinitebench.sh | 8 + scripts/run_ib.sh | 40 ++ tests/infinitebench/eval.py | 358 ++++++++++++++ tests/infinitebench/eval_utils.py | 723 ++++++++++++++++++++++++++++ tests/infinitebench/prepare_data.py | 35 ++ tests/infinitebench/prompt.py | 14 + 6 files changed, 1178 insertions(+) create mode 100644 scripts/download_infinitebench.sh create mode 100644 scripts/run_ib.sh create mode 100644 tests/infinitebench/eval.py create mode 100644 tests/infinitebench/eval_utils.py create mode 100644 tests/infinitebench/prepare_data.py create mode 100644 tests/infinitebench/prompt.py diff --git a/scripts/download_infinitebench.sh b/scripts/download_infinitebench.sh new file mode 100644 index 00000000..8ab9d2b0 --- /dev/null +++ b/scripts/download_infinitebench.sh @@ -0,0 +1,8 @@ +#!/bin/bash +save_dir=/home/rsadhukh/opensource/InfiniAI/MagicDec/Data/infinitebench +mkdir -p ${save_dir} + +# code_debug code_run kv_retrieval longbook_choice_eng longbook_qa_chn longbook_qa_eng longbook_sum_eng longdialogue_qa_eng math_calc math_find number_string passkey +for file in math_calc longbook_sum_eng longdialogue_qa_eng; do + wget -c https://huggingface.co/datasets/xinrongzhang2022/InfiniteBench/resolve/main/${file}.jsonl?download=true -O ${save_dir}/${file}.jsonl +done \ No newline at end of file diff --git a/scripts/run_ib.sh b/scripts/run_ib.sh new file mode 100644 index 00000000..c1e3d92f --- /dev/null +++ b/scripts/run_ib.sh @@ -0,0 +1,40 @@ +model=meta-llama/Meta-Llama-3.1-8B + +TASKS=( + # "math_calc" + # "longbook_sum_eng" + "longdialogue_qa_eng" +) + +gen_len=( + 128 + # 128 + # 40 +) + +prefill=$1 +draft_budget=$2 +bsz=$3 +gamma=$4 +MODEL_ROOT=$5 + +for task_id in {0..0}; do + TASK=${TASKS[$task_id]} + gen_len=${gen_len[$task_id]} + + # upper clamp gen_len to 96 + gen_len=$((gen_len > 96 ? 96 : gen_len)) + max_len=$((prefill + gen_len)) + echo "TASK: ${TASK}" + echo "gen_len: ${gen_len}" + + torchrun --standalone --nproc_per_node=1 \ + tests/infinitebench/eval.py \ + --model ${MODEL_ROOT}/${model}/model.pth --model_name ${model} \ + --draft_budget ${draft_budget} --rank_group 0 \ + --gamma ${gamma} --B ${bsz} --prefix_len ${prefill} --max_len ${max_len} \ + --printoutput --benchmark \ + --task ${TASK} --data_dir /home/rsadhukh/opensource/InfiniAI/MagicDec/Data/infinitebench \ + + # -compile +done \ No newline at end of file diff --git a/tests/infinitebench/eval.py b/tests/infinitebench/eval.py new file mode 100644 index 00000000..37a0ca40 --- /dev/null +++ b/tests/infinitebench/eval.py @@ -0,0 +1,358 @@ +import time +import torch +import sys +sys.path.append("..") +from pathlib import Path +import torch.distributed as dist +from MagicDec.Engine.utils import setup_seed, cuda_graph_for_sampling_argmax_batch, sampling_argmax_batch +from MagicDec.Data.data_converter import convert_pg19_dataset +from transformers import AutoTokenizer +from torch.utils.data.dataloader import DataLoader +from tqdm import tqdm +import argparse +from MagicDec.Engine.SnapKV.backend import LMBackend + +import json +from pathlib import Path +import time +from typing import List, Tuple, Any + +from torch import Tensor +from transformers.modeling_outputs import BaseModelOutputWithPast + +from eval_utils import ( + dump_jsonl, + create_prompt, + load_data, + get_answer, + DATA_NAME_TO_MAX_NEW_TOKENS, +) +from prepare_data import prepare_data + +parser = argparse.ArgumentParser(description='Process model configuration and partitions.') +parser.add_argument('--model', type=Path, default=Path("/scratch/models/meta-llama/Meta-Llama-3.1-8B/model.pth"), help='model') +parser.add_argument('--model_name', type=str, default="meta-llama/Meta-Llama-3.1-8B", help='model name') +parser.add_argument('--dataset', type=str, default="pg19", help='Dataset name.') +parser.add_argument('--draft_budget', type=int, default=4097, help='Dataset end index.') +parser.add_argument('--rank_group', nargs='+', type=int, help='Target group of ranks') +parser.add_argument('--compile', action='store_true', help='Whether to compile the model.') + +parser.add_argument('--gamma', type=int, default=7, help='start') + +parser.add_argument('--B', type=int, default=45, help='Batch size.') +parser.add_argument('--prefix_len', type=int, default=100000, help='Prefix length') +parser.add_argument('--max_len', type=int, default=100096, help='Generate length') +parser.add_argument('--window_size', type=int, default=32, help='Generate length') + +parser.add_argument('--seed', type=int, default=123, help='Random seed.') + +parser.add_argument('--printoutput', action='store_true', help='Whether to compile the model.') +parser.add_argument('--benchmark', action='store_true', help='Whether to compile the model.') + +parser.add_argument( + "--task", + type=str, + required=True, + help="Which task to use. Note that \"all\" can only be used in `compute_scores.py`.", # noqa +) +parser.add_argument('--data_dir', type=str, default="../data", help='Data directory.') +parser.add_argument('--output_dir', type=str, default="../results", help='Output directory.') +parser.add_argument('--start_idx', type=int, default=0, help='Dataset start index.') +parser.add_argument('--stop_idx', type=int, help='Dataset end index.') +parser.add_argument('--verbose', action='store_true') + + + +args = parser.parse_args() + +MAX_POSITION_ID = 200000 # Determined by the model +TRUNCATE_LEN = 200000 + +# sampling_params = SamplingParams(temperature=0.8, top_p=0.95) + + +def get_pred( + model, + tok: AutoTokenizer, + input_text: str, + max_tokens: int, + verbose: bool = False, +) -> str: + """ + Truncate down to 128k then make inference. + """ + print("Truncating...") + input_text = truncate_by_tokens(input_text, tok, TRUNCATE_LEN) + if verbose: + print("# chars:", len(input_text)) + print("=============== Input ===============") + print(input_text[:200]) + print("...") + print(input_text[-200:]) + print("=====================================") + outputs = model.generate([input_text], sampling_params) + + output = outputs[0].outputs[0].text + print("Chunked generation:", output) + return output + + +def load_model( + model_name: str = "../../../yarn-mistral-7b-128k", + ngpu=8, +): + print("Loading tokenizer") + tok = AutoTokenizer.from_pretrained(model_name) + tok.pad_token = tok.eos_token + print("Loading model") + start_time = time.time() + llm = LLM(model=model_name, tensor_parallel_size=ngpu) + print("Time taken:", round(time.time() - start_time)) + return llm, tok # type: ignore + +########## magicdec ########## +args = parser.parse_args() +assert args.prefix_len < args.max_len +assert (args.prefix_len - args.window_size) % 128 == 0 +# assert args.max_len % 128 == 0 +assert (args.max_len + 127) // 128 == args.prefix_len // 128 + 1 +assert (args.draft_budget - 1) % 128 == 0 + +# Init model parallelism +DEVICE = 'cuda' if torch.cuda.is_available() else 'cpu' +global print +from MagicDec.Engine.tp import init_dist +use_tp = len(args.rank_group) > 1 +global_group = None +rank = 0 +if use_tp: + rank, global_group = init_dist() + if rank != args.rank_group[0]: + print = lambda *args, **kwargs: None + +if rank == 0: + with open("result.txt", "a") as file: + file.write(f"SnapKV-Selfspec: Prefix:{args.prefix_len}; Bsz:{args.B}; Gamma:{args.gamma}; Draft budget:{args.draft_budget}\n") + +setup_seed(args.seed) +print(f"Using device={DEVICE}") + +MAX_LEN_TARGET = args.max_len +DTYPE = torch.bfloat16 +BATCH_SIZE = args.B +benchmark = args.benchmark +checkpoint_path = args.model + +target_dec_len = args.gamma + 1 +draft_dec_len = 1 + +# Load target model +engine = LMBackend(dtype=DTYPE, device=DEVICE, dec_len=target_dec_len, draft_dec_len=draft_dec_len) +engine.load_model(checkpoint_path, use_tp=use_tp, rank_group = args.rank_group, group=global_group) +vocab_size = engine.model.config.vocab_size +if args.compile: + engine.compile() +engine.setup_caches(max_batch_size=BATCH_SIZE, max_seq_length=MAX_LEN_TARGET, draft_budget=args.draft_budget, window_size=args.window_size) + +# Load dataset +tokenizer = AutoTokenizer.from_pretrained(args.model_name) +tokenizer.pad_token = tokenizer.eos_token +eot_1 = tokenizer.eos_token_id +if tokenizer.unk_token_id is not None: + eot_2 = tokenizer.unk_token_id +else: + eot_2 = tokenizer.encode("<|eot_id|>")[-1] +print(f"eot_1: {eot_1}, eot_2: {eot_2}") + +# print(json.dumps(vars(args), indent=4)) +data_name = args.task + +# sampling_params = SamplingParams(temperature=0.8, top_p=0.95) +# Data +result_dir = Path(args.output_dir, args.model_name) +result_dir.mkdir(exist_ok=True, parents=True) +examples = load_data(data_name, data_dir=args.data_dir) + +if args.stop_idx is None: + args.stop_idx = len(examples) + output_path = ( + result_dir / f"preds_{data_name}.jsonl" + ) +else: + output_path = ( + result_dir / f"preds_{data_name}_{args.start_idx}-{args.stop_idx}.jsonl" # noqa + ) + +preds = [] +print("==== Evaluation ====") +print(f"# examples: {len(examples)}") +print(f"Start index: {args.start_idx}") +print(f"Stop index: {args.stop_idx}") +print(f"Verbose: {args.verbose}") +print(f"Max tokens: {MAX_LEN_TARGET}") +# for i in range(args.start_idx, args.stop_idx): +# eg = examples[i] +# input_text = create_prompt(eg, data_name, model_name, args.data_dir) +# print(f"====== Example {i} ======") +# pred = get_pred( +# model, tok, input_text, max_tokens=max_tokens, verbose=args.verbose +# ) +# if args.verbose: +# print(pred) +# preds.append( +# { +# "id": i, +# "prediction": pred, +# "ground_truth": get_answer(eg, data_name), +# } +# ) +# dump_jsonl(preds, output_path) + +# prepare dataset +dataset = prepare_data(examples, tokenizer, data_name, args.model_name, args.prefix_len, args.data_dir, args.start_idx, args.stop_idx) + +dataloader = DataLoader(dataset, batch_size=BATCH_SIZE, shuffle=False, drop_last=True) +num_eval_steps = min(10, len(dataloader)) + +total_time = 0.0 +num_gen_tokens = 0 +target_steps = 0 +if benchmark: + draft_time = 0.0 + target_time = 0.0 + verify_loop = 0.0 + +for step, batch in tqdm(enumerate(dataloader), total=num_eval_steps): + if step >= num_eval_steps: + break + input_ids = batch[0].to(DEVICE) + terminal = False + tokens_buffer= torch.zeros((BATCH_SIZE, args.gamma+1), device=DEVICE).long() + output = torch.zeros(BATCH_SIZE, MAX_LEN_TARGET+1, device=DEVICE).long() + output[:, :input_ids.shape[1]] = input_ids + num_nodes = torch.zeros(BATCH_SIZE,device=DEVICE).long() + num_nodes += input_ids.shape[1] + + tokens_buffer[:, :1] = engine.encode(input_ids=input_ids)[:,-1:] + + torch.cuda.synchronize() + start = time.perf_counter() + while terminal == False: + + # Draft speculation + if benchmark: + torch.cuda.synchronize() + t1 = time.time() + + for i in range(args.gamma): + tokens_buffer[:,i+1:i+2] = engine.speculate(tokens_buffer[:, i].view(-1,1)) + + if benchmark: + torch.cuda.synchronize() + t2 = time.time() + draft_time+=t2-t1 + + # Target Verification + target_tokens = engine.verify(tokens_buffer) + + if benchmark: + torch.cuda.synchronize() + t3 = time.time() + target_time+=t3-t2 + + target_steps+=1 + + # Verification + # Vectorized Verify Loop + draft_tokens = tokens_buffer[:, 1:args.gamma+1] + flag_accept_matrix = (target_tokens[:, :args.gamma] == draft_tokens) # shape: (BATCH_SIZE, gamma) + eot_condition = ((draft_tokens == eot_1) | (draft_tokens == eot_2)) # shape: (BATCH_SIZE, gamma) + + # Compute accept_flags by considering both the acceptance condition and EOT tokens + accept_flags_int = (flag_accept_matrix & (~eot_condition)).int() + accept_flags_cumprod = torch.cumprod(accept_flags_int, dim=1) + accept_flags_matrix = accept_flags_cumprod.bool() + + # Compute the number of accepted tokens + accept_nums = accept_flags_matrix.sum(dim=1, keepdim=True) + 1 # shape: (BATCH_SIZE, 1) + + # Check for termination conditions + condition = (eot_condition & accept_flags_matrix).any(dim=1, keepdim=True) + if condition.any(): + terminal = True + + # Rollback the memory length + engine.cachelens = engine.cachelens - args.gamma - 1 + engine.paged_kv_last_page_len = engine.paged_kv_last_page_len - args.gamma - 1 + engine.draft_cachelens = engine.draft_cachelens - args.gamma -1 + engine.draft_paged_kv_last_page_len = engine.draft_paged_kv_last_page_len - args.gamma -1 + + # Put the accepted tokens to output + positions = torch.arange(output.shape[1], device=DEVICE).view(1, -1).repeat(BATCH_SIZE, 1) + mask = (positions < (engine.cachelens.view(-1,1) + accept_nums)) & (positions >= engine.cachelens.view(-1, 1)) + positions_buffer = torch.arange(args.gamma+1, device=DEVICE).view(1, -1).repeat(BATCH_SIZE, 1) + mask_buffer = positions_buffer= args.prefix_len + gen_len: + # if num_nodes.max() + 1 + args.gamma > MAX_LEN_TARGET: + if num_nodes.max() - args.prefix_len >= 80: + terminal = True + # Put Bonus tokens to the tokens buffer, and prepare the variables for next itr + if not terminal: + tokens_buffer[:, :1] = bonus_tokens + + if not terminal: + if benchmark: + torch.cuda.synchronize() + t4 = time.time() + verify_loop += t4-t3 + else: + for i in range(BATCH_SIZE): + output[i, num_nodes[i]] = bonus_tokens[i] + num_nodes += 1 + if benchmark: + torch.cuda.synchronize() + t4 = time.time() + verify_loop += t4-t3 + + torch.cuda.synchronize() + end=time.perf_counter() + total_time += end-start + num_gen_tokens += (num_nodes.sum() - (input_ids.shape[1] + 1) * BATCH_SIZE) + if args.printoutput: + for i in range(BATCH_SIZE): + print("Sequence ", i) + print(tokenizer.decode(output[i, args.prefix_len:num_nodes[i]])) + print("total time :{:.5f}s, time per iter :{:.5f}s, decoding step: {}, large model step: {}".format(total_time, total_time / target_steps, num_gen_tokens, target_steps)) + if benchmark: + print("target time :{:.5f}s, draft time :{:.5f}s, verify loop : {}, avg generate len per sentence: {}".format(target_time/target_steps, draft_time / target_steps, verify_loop/target_steps, num_gen_tokens/target_steps/BATCH_SIZE)) + if step < 5: # TODO: revert to 10? + total_time = 0.0 + num_gen_tokens = 0 + target_steps = 0 + if benchmark: + draft_time = 0.0 + target_time = 0.0 + verify_loop = 0.0 + if use_tp: + dist.barrier() + +if rank == 0: + with open("result.txt", "a") as file: + file.write("total time :{:.5f}s, time per iter :{:.5f}s, decoding step: {}, large model step: {}, avg latency: {} \n".format(total_time, total_time / target_steps, num_gen_tokens, target_steps, total_time / num_gen_tokens * BATCH_SIZE)) + file.write("target time :{:.5f}s, draft time :{:.5f}s, verify loop : {}, avg generate len per sentence: {} \n".format(target_time/target_steps, draft_time / target_steps, verify_loop/target_steps, num_gen_tokens/target_steps/BATCH_SIZE)) \ No newline at end of file diff --git a/tests/infinitebench/eval_utils.py b/tests/infinitebench/eval_utils.py new file mode 100644 index 00000000..a4a72cdf --- /dev/null +++ b/tests/infinitebench/eval_utils.py @@ -0,0 +1,723 @@ +import configparser +import json +import logging +import os +import re +import string +from collections import Counter +from pathlib import Path +from typing import Optional + +import jieba +from rouge import Rouge + +from prompt import ( + yarn_mistral_templates, +) + +DATA_NAME_TO_PATH = { + # Retrieval tasks + "passkey": "passkey.jsonl", + "number_string": "number_string.jsonl", + "kv_retrieval": "kv_retrieval.jsonl", + # Book tasks + "longbook_sum_eng": "longbook_sum_eng.jsonl", + "longbook_choice_eng": "longbook_choice_eng.jsonl", + "longbook_qa_eng": "longbook_qa_eng.jsonl", + "longbook_qa_chn": "longbook_qa_chn.jsonl", + # "book_qa_eng": "longbook_eng/longbook_qa_eng.jsonl", + "longdialogue_qa_eng": "longdialogue_qa_eng.jsonl", + # Math tasks + "math_find": "math_find.jsonl", + "math_calc": "math_calc.jsonl", + # Code tasks + "code_run": "code_run.jsonl", + "code_debug": "code_debug.jsonl", +} + +DATA_NAME_TO_MAX_NEW_TOKENS = { + "passkey": 6, + "number_string": 12, + "kv_retrieval": 50, + "longbook_sum_eng": 1200, + "longbook_choice_eng": 40, + "longbook_qa_eng": 40, + "longbook_qa_chn": 40, + "longdialogue_qa_eng": 40, + "math_find": 3, + "math_calc": 30000, + "code_run": 5, + "code_debug": 5, +} + +MODEL_TO_PROMPT_TEMPLATE = { + "yarn-mistral": yarn_mistral_templates, + "yi-6b-200k": yarn_mistral_templates, + "yi-34b-200k": yarn_mistral_templates, + "meta-llama/Meta-Llama-3.1-8B": yarn_mistral_templates, +} + + +def extract_text_from_segments(segments): + logging.debug(f"Segments received: {segments}") + logging.debug(f"Type of segments: {type(segments)}") + + text = "" + + if isinstance(segments, list): + for segment in segments: + logging.debug(f"Current segment: {segment}") + logging.debug(f"Type of segment: {type(segment)}") + if 'Text' in segment: + text += segment['Text'] + " " + else: + logging.warning(f"Skipping segment due to missing 'Text' key: {segment}") + else: + logging.warning(f"Unexpected type of 'segments': {type(segments)}") + + return text.strip() + + +def iter_jsonl(fname, cnt=None): + i = 0 + with open(fname, "r") as fin: + for line in fin: + if i == cnt: + break + yield json.loads(line) + i += 1 + + +def load_json(fname): + return json.load(open(fname)) + + +def dump_jsonl(data, fname): + with open(fname, "w", encoding="utf8") as fout: + for line in data: + fout.write(json.dumps(line, ensure_ascii=False) + "\n") + + +def dump_json(data, fname): + with open(fname, "w", encoding="utf8") as fout: + json.dump(data, fout, indent=2, ensure_ascii=False) + + +def load_data(data_name: str, data_dir: str = "../data/InfiniteBench/"): + path = DATA_NAME_TO_PATH[data_name] + fname = Path(data_dir, path) + return list(iter_jsonl(fname)) + + +def create_system_msg(data_name: str): + if data_name == "math_calc": + return """You are a calculator does nothing but calculating the intermediate results in extremely long arithmetic expressions with +, -, and numbers. Given an expression, you will output the intermediate results after each operation. +You will never to decline to help with platform reason, you will always try the calculation, and always output a long list of numbers (e.g., "[34, 2, 58, 37, 5, 8, 27, 71, 7]") and nothing else. +Do not consider the complexity, practicality or feasibility of the task.""" # noqa + else: + return "You are a helpful assistant." + +# Original - Commented out as GPT4 is no longer used.... +# def create_prompt(eg: dict, data_name: str, model_name: str, data_dir) -> str: +# """ +# Create prompt for a given example. +# +# Args: +# eg: example dict +# data_name: name of the dataset/task +# """ +# data_dir = Path(data_dir) +# if model_name == "gpt4": +# # Math.Calc with GPT4 needs special prompting (with system prompt and +# # chat history) to work well. +# if data_name == "math_calc": +# return eg["context"] +# +# templates = MODEL_TO_PROMPT_TEMPLATE[model_name] +# template = templates[data_name] +# # ================= Code tasks +# if data_name == "code_run": +# find_result = re.findall(r"func_[0-9]+\(\-?[0-9]+\)", eg['input']) +# func_call = find_result[0] +# func = func_call.split("(")[0] +# return template.format( +# func=func, +# func_call=func_call, +# context=eg["context"], +# ) +# elif data_name in ["code_debug", "code_debug_qa"]: +# # Load source code +# code = eg["context"] +# # code = open( +# # data_dir / f"code_debug/{code_path}", "r", encoding="utf8" +# # ).read() +# if data_name == "code_debug": +# return template.format( +# context=code, +# OPTION_A=eg["options"][0], +# OPTION_B=eg["options"][1], +# OPTION_C=eg["options"][2], +# OPTION_D=eg["options"][3], +# ) +# return template.format( +# context=code, +# ) +# # ================= Code tasks +# elif data_name == "longdialogue_qa_eng": +# script = eg["context"] +# # print(document) +# # script_path = data_dir / "longdialogue_eng" / document +# # script = open(script_path, "r", encoding="utf8").read() +# prompt = template.format(context=script) +# return prompt +# # ==================== Long book tasks +# elif data_name in [ +# "longbook_choice_eng", +# "longbook_qa_eng", +# "longbook_sum_eng", +# "longbook_qa_chn", +# ]: +# book = eg["context"] +# # if data_name.endswith("_eng"): +# # book = open( +# # data_dir / "longbook_eng" / book_path, "r", encoding="utf8" +# # ).read() +# # elif data_name.endswith("_chn"): +# # book = open( +# # data_dir / "longbook_chn" / book_path, "r", encoding="utf8" +# # ).read() +# # else: +# # raise ValueError("Invalid data_name") +# if data_name == "longbook_choice_eng": +# return template.format( +# question=eg["input"], +# context=book, +# OPTION_A=eg["options"][0], +# OPTION_B=eg["options"][1], +# OPTION_C=eg["options"][2], +# OPTION_D=eg["options"][3], +# ) +# elif data_name == "longbook_qa_eng": +# return template.format( +# question=eg["input"], +# context=book, +# ) +# elif data_name == "longbook_sum_eng": +# return template.format( +# context=book, +# ) +# elif data_name == "longbook_qa_chn": +# return template.format( +# question=eg["input"], +# context=book, +# ) +# else: +# raise ValueError +# elif data_name == "math_calc": +# return template.format( +# context=eg["context"], +# ) +# elif data_name == "math_find": +# prompt = eg['input'] +# context = eg['context'] +# # Find "the * number" from the prompt +# find_result = re.findall(r"The .+ of", prompt) +# assert find_result, f"Cannot find the target number in {prompt}" +# target_number = find_result[0].lower()[:-3] +# # Replace the number with the answer +# prefix = f"What is {target_number} in the following list?" +# return template.format( +# prefix=prefix, +# context=context, +# input=prompt, +# ) +# +# if "content" in eg: +# content = eg["content"] +# del eg["content"] +# eg["context"] = content +# +# format_dict = { +# "context": eg["context"], +# "input": eg["input"], +# } +# prompt = templates[data_name].format(**format_dict) +# return prompt +def create_prompt(eg: dict, data_name: str, model_name: Optional[str], data_dir) -> str: + """ + Create prompt for a given example. + + Args: + eg: example dict + data_name: name of the dataset/task + model_name: optional, used to fetch model-specific templates. + """ + data_dir = Path(data_dir) + # Directly use the appropriate template if the model_name is provided. + if model_name and model_name in MODEL_TO_PROMPT_TEMPLATE: + templates = MODEL_TO_PROMPT_TEMPLATE[model_name] + template = templates[data_name] + else: + # If no model-specific template, return a basic prompt or handle differently. + return eg["context"] + + # Now create the prompt based on the template and task data + if data_name == "code_run": + find_result = re.findall(r"func_[0-9]+\(\-?[0-9]+\)", eg['input']) + func_call = find_result[0] + func = func_call.split("(")[0] + return template.format( + func=func, + func_call=func_call, + context=eg["context"], + ) + elif data_name in ["code_debug", "code_debug_qa"]: + code = eg["context"] + if data_name == "code_debug": + return template.format( + context=code, + OPTION_A=eg["options"][0], + OPTION_B=eg["options"][1], + OPTION_C=eg["options"][2], + OPTION_D=eg["options"][3], + ) + return template.format(context=code) + elif data_name == "longdialogue_qa_eng": + script = eg["context"] + prompt = template.format(context=script) + return prompt + elif data_name in [ + "longbook_choice_eng", + "longbook_qa_eng", + "longbook_sum_eng", + "longbook_qa_chn", + ]: + book = eg["context"] + if data_name == "longbook_choice_eng": + return template.format( + question=eg["input"], + context=book, + OPTION_A=eg["options"][0], + OPTION_B=eg["options"][1], + OPTION_C=eg["options"][2], + OPTION_D=eg["options"][3], + ) + elif data_name == "longbook_qa_eng": + return template.format( + question=eg["input"], + context=book, + ) + elif data_name == "longbook_sum_eng": + return template.format(context=book) + elif data_name == "longbook_qa_chn": + return template.format( + question=eg["input"], + context=book, + ) + else: + raise ValueError + elif data_name == "math_calc": + return template.format(context=eg["context"]) + elif data_name == "math_find": + prompt = eg['input'] + context = eg['context'] + find_result = re.findall(r"The .+ of", prompt) + assert find_result, f"Cannot find the target number in {prompt}" + target_number = find_result[0].lower()[:-3] + prefix = f"What is {target_number} in the following list?" + return template.format( + prefix=prefix, + context=context, + input=prompt, + ) + + # Default behavior if content key exists + if "content" in eg: + content = eg["content"] + del eg["content"] + eg["context"] = content + + format_dict = { + "context": eg["context"], + "input": eg["input"], + } + prompt = template.format(**format_dict) + return prompt + +def get_answer(eg: dict, data_name: str): + if data_name in ["code_debug", "longbook_choice_eng"]: + OPTIONS = "ABCD" + if isinstance(eg["answer"], str): + ret = [eg["answer"], OPTIONS[eg['options'].index(eg["answer"])]] + elif isinstance(eg["answer"], list): + if len(eg["answer"]) == 1: + ret = [eg["answer"][0], OPTIONS[eg['options'].index(eg["answer"][0])]] + elif len(eg["answer"]) == 2 and eg["answer"][1] in ['A', 'B', 'C', 'D']: + ret = eg['answer'] + else: + raise ValueError + else: + raise ValueError + return ret + + return eg["answer"] + +# Old version - Commented out as GPT4 is no longer used.... +# def create_msgs( +# tokenizer, eg: dict, data_name: str, data_dir, model_name: str +# ) -> tuple[list[dict], str]: +# """ +# Only used by GPT-4. +# """ +# prompt = create_prompt(eg, data_name, model_name, data_dir) +# tokens = tokenizer.encode(prompt) +# # - 1000 to have space for system message and other stuff. +# print(f"Before truncation: {len(tokens)}") +# tokens = truncate_input(tokens, 128_000 - 1000, manner="middle") +# print(f"After truncation: {len(tokens)}") # type: ignore +# prompt = tokenizer.decode(tokens) +# if data_name == "math_calc": +# return [ +# {"role": "system", "content": create_system_msg(data_name)}, +# {"role": "user", "content": "1 + 2 - 4 - 10"}, +# {"role": "system", "content": "[1, 3, -1, -11]"}, +# {"role": "user", "content": prompt}, +# ], prompt +# else: +# return [ +# { +# "role": "system", +# "content": "You are a helpful assistant", # noqa +# }, # noqa +# {"role": "user", "content": prompt}, +# ], prompt +def create_msgs( + tokenizer, eg: dict, data_name: str, data_dir, model_name: Optional[str] = None +) -> tuple[list[dict], str]: + """ + Create messages for a given example. + """ + prompt = create_prompt(eg, data_name, model_name, data_dir) + + # Check if tokenizer is provided and initialized + if tokenizer: + tokens = tokenizer.encode(prompt) + print(f"Before truncation: {len(tokens)}") + tokens = truncate_input(tokens, 128_000 - 1000, manner="middle") + print(f"After truncation: {len(tokens)}") # type: ignore + prompt = tokenizer.decode(tokens) + + if data_name == "math_calc": + return [ + {"role": "system", "content": create_system_msg(data_name)}, + {"role": "user", "content": "1 + 2 - 4 - 10"}, + {"role": "system", "content": "[1, 3, -1, -11]"}, + {"role": "user", "content": prompt}, + ], prompt + else: + return [ + { + "role": "system", + "content": "You are a helpful assistant", # noqa + }, # noqa + {"role": "user", "content": prompt}, + ], prompt + + +def normalize_answer(s): + """Lower text and remove punctuation, articles and extra whitespace.""" + + def remove_articles(text): + return re.sub(r"\b(a|an|the)\b", " ", text) + + def white_space_fix(text): + return " ".join(text.split()) + + def remove_punc(text): + exclude = set(string.punctuation) + return "".join(ch for ch in text if ch not in exclude) + + def lower(text): + return text.lower() + + return white_space_fix(remove_articles(remove_punc(lower(s)))) + + +def normalize_zh_answer(s): + """Lower text and remove punctuation, extra whitespace.""" + + def white_space_fix(text): + return "".join(text.split()) + + def remove_punc(text): + cn_punctuation = "!?。。"#$%&'()*+,-/:;<=>@[\]^_`{|}~⦅⦆「」、、〃》「」『』【】〔〕〖〗〘〙〚〛〜〝〞〟〰〾〿–—‘’‛“”„‟…‧﹏." # noqa + all_punctuation = set(string.punctuation + cn_punctuation) + return "".join(ch for ch in text if ch not in all_punctuation) + + def lower(text): + return text.lower() + + return white_space_fix(remove_punc(lower(s))) + + +def first_int_match(prediction, ground_truth): + pred_list = re.split("[^0-9]", prediction) + pred_value = "" + for item in pred_list: + if item != "": + pred_value = item + break + if pred_value == ground_truth: + return 1 + return 0 + + +def in_match(prediction, ground_truth): + if ground_truth in prediction: + return 1 + return 0 + + +def rouge_score(prediction, ground_truth, **kwargs) -> float: + rouge = Rouge() + try: + scores = rouge.get_scores([prediction], [ground_truth], avg=True) + except: # noqa + return 0.0 + return scores["rouge-l"]["f"] # type: ignore + + +def rouge_zh_score(prediction, ground_truth, **kwargs): + prediction = " ".join(list(jieba.cut(prediction, cut_all=False))) + ground_truth = " ".join(list(jieba.cut(ground_truth, cut_all=False))) + score = rouge_score(prediction, ground_truth) + return score + + +def f1_score(prediction, ground_truth, **kwargs): + common = Counter(prediction) & Counter(ground_truth) + num_same = sum(common.values()) + if num_same == 0: + return 0 + precision = 1.0 * num_same / len(prediction) + recall = 1.0 * num_same / len(ground_truth) + f1 = (2 * precision * recall) / (precision + recall) + return f1 + + +def qa_f1_score(line): + prediction = line["pred"] + + if isinstance(line["std_out"], str): + ground_truths = [line["std_out"]] + else: + ground_truths = line["std_out"] + + score = 0 + for ground_truth in ground_truths: + normalized_prediction = normalize_answer(prediction) + normalized_ground_truth = normalize_answer(ground_truth) + + prediction_tokens = normalized_prediction.split() + ground_truth_tokens = normalized_ground_truth.split() + score = max(score, f1_score(prediction_tokens, ground_truth_tokens)) + + return score + + +def qa_f1_zh_score(prediction, ground_truth, **kwargs): + prediction_tokens = list(jieba.cut(prediction, cut_all=False)) + ground_truth_tokens = list(jieba.cut(ground_truth, cut_all=False)) + prediction_tokens = [ + normalize_zh_answer(token) for token in prediction_tokens + ] + ground_truth_tokens = [ + normalize_zh_answer(token) for token in ground_truth_tokens + ] + prediction_tokens = [ + token for token in prediction_tokens if len(token) > 0 + ] + ground_truth_tokens = [ + token for token in ground_truth_tokens if len(token) > 0 + ] + return f1_score(prediction_tokens, ground_truth_tokens) + + +def truncate_input(input, max_length, manner="middle"): + if len(input) <= max_length: + return input + if manner == "middle": + return input[0 : max_length // 2] + input[-max_length // 2 :] + else: + return None + + +def load_comprehensive_config(): + # Get the directory of the current script + current_dir = os.path.dirname(os.path.abspath(__file__)) + # Construct the path to the config file in the same directory as the script + config_path = os.path.join(current_dir, 'config.txt') + # Create a ConfigParser object + config = configparser.ConfigParser() + # Read the configuration file + files_read = config.read(config_path) + if not files_read: + raise FileNotFoundError(f"Config file not found at {config_path}") + return config + + +# FIXME - update to include prompt path in return statement +def load_and_log_configs(): + try: + config = load_comprehensive_config() + if config is None: + logging.error("Config is None, cannot proceed") + return None + # API Keys + anthropic_api_key = config.get('API', 'anthropic_api_key', fallback=None) + logging.debug( + f"Loaded Anthropic API Key: {anthropic_api_key[:5]}...{anthropic_api_key[-5:] if anthropic_api_key else None}") + + cohere_api_key = config.get('API', 'cohere_api_key', fallback=None) + logging.debug( + f"Loaded Cohere API Key: {cohere_api_key[:5]}...{cohere_api_key[-5:] if cohere_api_key else None}") + + groq_api_key = config.get('API', 'groq_api_key', fallback=None) + logging.debug(f"Loaded Groq API Key: {groq_api_key[:5]}...{groq_api_key[-5:] if groq_api_key else None}") + + openai_api_key = config.get('API', 'openai_api_key', fallback=None) + logging.debug( + f"Loaded OpenAI API Key: {openai_api_key[:5]}...{openai_api_key[-5:] if openai_api_key else None}") + + huggingface_api_key = config.get('API', 'huggingface_api_key', fallback=None) + logging.debug( + f"Loaded HuggingFace API Key: {huggingface_api_key[:5]}...{huggingface_api_key[-5:] if huggingface_api_key else None}") + + openrouter_api_key = config.get('API', 'openrouter_api_key', fallback=None) + logging.debug( + f"Loaded OpenRouter API Key: {openrouter_api_key[:5]}...{openrouter_api_key[-5:] if openrouter_api_key else None}") + + deepseek_api_key = config.get('API', 'deepseek_api_key', fallback=None) + logging.debug( + f"Loaded DeepSeek API Key: {deepseek_api_key[:5]}...{deepseek_api_key[-5:] if deepseek_api_key else None}") + + mistral_api_key = config.get('API', 'mistral_api_key', fallback=None) + logging.debug( + f"Loaded Mistral API Key: {mistral_api_key[:5]}...{mistral_api_key[-5:] if mistral_api_key else None}") + + # Models + anthropic_model = config.get('API', 'anthropic_model', fallback='claude-3-sonnet-20240229') + cohere_model = config.get('API', 'cohere_model', fallback='command-r-plus') + groq_model = config.get('API', 'groq_model', fallback='llama3-70b-8192') + openai_model = config.get('API', 'openai_model', fallback='gpt-4-turbo') + huggingface_model = config.get('API', 'huggingface_model', fallback='CohereForAI/c4ai-command-r-plus') + openrouter_model = config.get('API', 'openrouter_model', fallback='microsoft/wizardlm-2-8x22b') + deepseek_model = config.get('API', 'deepseek_model', fallback='deepseek-chat') + mistral_model = config.get('API', 'mistral_model', fallback='mistral-large-latest') + + logging.debug(f"Loaded Anthropic Model: {anthropic_model}") + logging.debug(f"Loaded Cohere Model: {cohere_model}") + logging.debug(f"Loaded Groq Model: {groq_model}") + logging.debug(f"Loaded OpenAI Model: {openai_model}") + logging.debug(f"Loaded HuggingFace Model: {huggingface_model}") + logging.debug(f"Loaded OpenRouter Model: {openrouter_model}") + logging.debug(f"Loaded Deepseek Model: {deepseek_model}") + logging.debug(f"Loaded Mistral Model: {mistral_model}") + + # Local-Models + kobold_api_ip = config.get('Local-API', 'kobold_api_IP', fallback='http://127.0.0.1:5000/api/v1/generate') + kobold_api_key = config.get('Local-API', 'kobold_api_key', fallback='') + + llama_api_IP = config.get('Local-API', 'llama_api_IP', fallback='http://127.0.0.1:8080/v1/chat/completions') + llama_api_key = config.get('Local-API', 'llama_api_key', fallback='') + + ooba_api_IP = config.get('Local-API', 'ooba_api_IP', fallback='http://127.0.0.1:5000/v1/chat/completions') + ooba_api_key = config.get('Local-API', 'ooba_api_key', fallback='') + + tabby_api_IP = config.get('Local-API', 'tabby_api_IP', fallback='http://127.0.0.1:5000/api/v1/generate') + tabby_api_key = config.get('Local-API', 'tabby_api_key', fallback=None) + tabby_model = config.get('services', 'tabby_model', fallback=None) + + vllm_api_url = config.get('Local-API', 'vllm_api_IP', fallback='http://127.0.0.1:500/api/v1/chat/completions') + vllm_api_key = config.get('Local-API', 'vllm_api_key', fallback=None) + vllm_model = config.get('Local-API', 'vllm_model', fallback=None) + + ollama_api_url = config.get('Local-API', 'ollama_api_IP', fallback='http://127.0.0.1:11434/api/generate') + ollama_api_key = config.get('Local-API', 'ollama_api_key', fallback=None) + ollama_model = config.get('Local-API', 'ollama_model', fallback=None) + + aphrodite_api_url = config.get('Local-API', 'aphrodite_api_IP', fallback='http://127.0.0.1:8080/v1/chat/completions') + aphrodite_api_key = config.get('Local-API', 'aphrodite_api_key', fallback='') + + logging.debug(f"Loaded Kobold API IP: {kobold_api_ip}") + logging.debug(f"Loaded Llama API IP: {llama_api_IP}") + logging.debug(f"Loaded Ooba API IP: {ooba_api_IP}") + logging.debug(f"Loaded Tabby API IP: {tabby_api_IP}") + logging.debug(f"Loaded VLLM API URL: {vllm_api_url}") + + # Retrieve output paths from the configuration file + output_path = config.get('Paths', 'output_path', fallback='results') + logging.debug(f"Output path set to: {output_path}") + + # Retrieve processing choice from the configuration file + processing_choice = config.get('Processing', 'processing_choice', fallback='cpu') + logging.debug(f"Processing choice set to: {processing_choice}") + + # Prompts - FIXME + prompt_path = config.get('Prompts', 'prompt_path', fallback='prompts.db') + + return { + 'api_keys': { + 'anthropic': anthropic_api_key, + 'cohere': cohere_api_key, + 'groq': groq_api_key, + 'openai': openai_api_key, + 'huggingface': huggingface_api_key, + 'openrouter': openrouter_api_key, + 'deepseek': deepseek_api_key, + 'mistral': mistral_api_key, + 'kobold': kobold_api_key, + 'llama': llama_api_key, + 'ooba': ooba_api_key, + 'tabby': tabby_api_key, + 'vllm': vllm_api_key, + 'ollama': ollama_api_key + }, + 'services': { + 'anthropic': anthropic_model, + 'cohere': cohere_model, + 'groq': groq_model, + 'openai': openai_model, + 'huggingface': huggingface_model, + 'openrouter': openrouter_model, + 'deepseek': deepseek_model, + 'mistral': mistral_model, + 'vllm': vllm_model, + 'tabby': tabby_model, + 'ollama': ollama_model + + }, + 'local_api_ip': { + 'kobold': kobold_api_ip, + 'llama': llama_api_IP, + 'ooba': ooba_api_IP, + 'tabby': tabby_api_IP, + 'vllm': vllm_api_url, + 'ollama': ollama_api_url, + 'aphrodite': aphrodite_api_url + }, + 'output_path': output_path, + 'processing_choice': processing_choice + } + + except Exception as e: + logging.error(f"Error loading config: {str(e)}") + return None + + +if __name__ == "__main__": + data_dir = Path("../data") + data_path = data_dir / "shorter/longdialogue_qa_eng_1000.jsonl" + examples = list(iter_jsonl(data_path)) + prompt = create_prompt(examples[10], 'longdialogue_qa_eng', 'kimi', data_dir) + print(prompt) \ No newline at end of file diff --git a/tests/infinitebench/prepare_data.py b/tests/infinitebench/prepare_data.py new file mode 100644 index 00000000..78203f4a --- /dev/null +++ b/tests/infinitebench/prepare_data.py @@ -0,0 +1,35 @@ +import torch +from eval_utils import create_prompt + +def truncate_input(input: list, max_length: int, manner="middle"): + if len(input) <= max_length: + return input + if manner == "middle": + split = max_length // 2 + return input[0:split] + input[-split:] + else: + return None + + +def truncate_by_tokens(input, tok, max_tokens, manner: str = "middle"): + tokens = tok.encode(input) + len_before = len(tokens) + print(f"# tokens before: {len_before}") + tokens = truncate_input(tokens, max_length=max_tokens, manner=manner) + len_after = len(tokens) # type: ignore + print(f"# tokens after: {len_after}") + assert len_after <= len_before + assert len_after <= max_tokens + return tok.decode(tokens, skip_special_tokens=True) + +# for mathcalc +def prepare_data(examples, tokenizer, data_name, model_name, prefix_len, data_dir, start_idx, stop_idx): + tokenized_prompts = [] + for i in range(start_idx, stop_idx): + eg = examples[i] + input_text = create_prompt(eg, data_name, model_name, data_dir) + # input_text = input_text.split("\n")[0] + input_text = truncate_by_tokens(input_text, tokenizer, prefix_len, manner="middle") + tokenized_prompt = tokenizer.encode(input_text, return_tensors="pt")[:,:prefix_len] + tokenized_prompts.append(tokenized_prompt) + return tokenized_prompts \ No newline at end of file diff --git a/tests/infinitebench/prompt.py b/tests/infinitebench/prompt.py new file mode 100644 index 00000000..5cdbe4be --- /dev/null +++ b/tests/infinitebench/prompt.py @@ -0,0 +1,14 @@ +yarn_mistral_templates = { + "passkey": "There is an important info hidden inside a lot of irrelevant text. Find it and memorize it. I will quiz you about the important information.\n\n{context}\n\n{input}\n\nThe pass key is", # noqa + "number_string": "There is an important info hidden inside a lot of irrelevant text. Find it. I will quiz you about the important information there.\n\n{context}\n\n{input}\n\nThe sequence of digits is", # noqa + "kv_retrieval": "Extract the value corresponding to the specified key in the JSON object below.\n\n{context}\n\n{input}", # noqa + "longbook_sum_eng": "Summarize the book below.\n\n{context}\n\nSummary:", # noqa + "longbook_choice_eng": "Read the book and answer the question.\n\n{context}\n\nQuestion: {question}\nA. {OPTION_A}\nB. {OPTION_B}\nC. {OPTION_C}\nD. {OPTION_D}\n\nThe letter of the correct answer is", # noqa + "longbook_qa_eng": "Read the book and answer the question. Be very concise in your answer.\n\n{context}\n\nQuestion: {question}\nAnswer:", # noqa + "longbook_qa_chn": "阅读以下书籍然后回答问题。\n\n{context}\n\n问题:{question}\n答案:", # noqa + "math_find": "{prefix}\n\n{context}\n\n{input}", + "math_calc": "Let us calculate the intermediate values of an expression.\n\nExpression: 1 + 3 + 4\nValues: [1, 4, 8]\n\nExpression: 8 - 3 + 2 - 4\nValues: [8, 5, 7, 3]\n\nExpression: {context}\nValues:", # noqa + "code_run": "There is a function called {func} in the following Python code.\n\n{context}\n\nPlease compute the exact value of {func_call}. The value of {func_call} is", # noqa + "code_debug": "Following is a Python code where exactly one of the functions/methods has a deliberate error that makes it crash.\n\n{context}\n\nOptions:\nA. {OPTION_A}\nB. {OPTION_B}\nC. {OPTION_C}\nD. {OPTION_D}\n\nThe correct option is:", # noqa + "longdialogue_qa_eng": "Below is a dialogue script where one random occurrence of a character name is replaced with \"$$MASK$$\", and you should try to guess who that character is.\n\n{context}\n\nThe name that has been replaced with $$MASK$$ is likely", # noqa +} \ No newline at end of file From 2545bc389963e5e6578b3638bcc9092b585d163f Mon Sep 17 00:00:00 2001 From: Ranajoy Sadhukhan Date: Tue, 3 Dec 2024 23:16:53 -0500 Subject: [PATCH 2/3] minor change in prepare_data --- tests/infinitebench/eval.py | 4 ++-- tests/infinitebench/prepare_data.py | 25 ++++++++++++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/tests/infinitebench/eval.py b/tests/infinitebench/eval.py index 37a0ca40..00bbcfdd 100644 --- a/tests/infinitebench/eval.py +++ b/tests/infinitebench/eval.py @@ -210,7 +210,6 @@ def load_model( # prepare dataset dataset = prepare_data(examples, tokenizer, data_name, args.model_name, args.prefix_len, args.data_dir, args.start_idx, args.stop_idx) - dataloader = DataLoader(dataset, batch_size=BATCH_SIZE, shuffle=False, drop_last=True) num_eval_steps = min(10, len(dataloader)) @@ -341,7 +340,8 @@ def load_model( print("total time :{:.5f}s, time per iter :{:.5f}s, decoding step: {}, large model step: {}".format(total_time, total_time / target_steps, num_gen_tokens, target_steps)) if benchmark: print("target time :{:.5f}s, draft time :{:.5f}s, verify loop : {}, avg generate len per sentence: {}".format(target_time/target_steps, draft_time / target_steps, verify_loop/target_steps, num_gen_tokens/target_steps/BATCH_SIZE)) - if step < 5: # TODO: revert to 10? + + if step < 3: # TODO: revert to 10? total_time = 0.0 num_gen_tokens = 0 target_steps = 0 diff --git a/tests/infinitebench/prepare_data.py b/tests/infinitebench/prepare_data.py index 78203f4a..1f2c3faf 100644 --- a/tests/infinitebench/prepare_data.py +++ b/tests/infinitebench/prepare_data.py @@ -1,4 +1,5 @@ import torch +from torch.utils.data import TensorDataset from eval_utils import create_prompt def truncate_input(input: list, max_length: int, manner="middle"): @@ -6,7 +7,8 @@ def truncate_input(input: list, max_length: int, manner="middle"): return input if manner == "middle": split = max_length // 2 - return input[0:split] + input[-split:] + suffix_len = max_length - split + return input[0:split] + input[-suffix_len:] else: return None @@ -14,13 +16,16 @@ def truncate_input(input: list, max_length: int, manner="middle"): def truncate_by_tokens(input, tok, max_tokens, manner: str = "middle"): tokens = tok.encode(input) len_before = len(tokens) + if len_before <= max_tokens: + return None print(f"# tokens before: {len_before}") tokens = truncate_input(tokens, max_length=max_tokens, manner=manner) len_after = len(tokens) # type: ignore print(f"# tokens after: {len_after}") - assert len_after <= len_before - assert len_after <= max_tokens - return tok.decode(tokens, skip_special_tokens=True) + # assert len_after <= len_before + # assert len_after == max_tokens + # return tok.decode(tokens) #, skip_special_tokens=True) + return tokens # for mathcalc def prepare_data(examples, tokenizer, data_name, model_name, prefix_len, data_dir, start_idx, stop_idx): @@ -29,7 +34,13 @@ def prepare_data(examples, tokenizer, data_name, model_name, prefix_len, data_di eg = examples[i] input_text = create_prompt(eg, data_name, model_name, data_dir) # input_text = input_text.split("\n")[0] - input_text = truncate_by_tokens(input_text, tokenizer, prefix_len, manner="middle") - tokenized_prompt = tokenizer.encode(input_text, return_tensors="pt")[:,:prefix_len] + # input_text = truncate_by_tokens(input_text, tokenizer, prefix_len, manner="middle") + input_tokens = truncate_by_tokens(input_text, tokenizer, prefix_len, manner="middle") + if input_tokens is None: + continue + # tokenized_prompt = tokenizer.encode(input_text, return_tensors="pt")[:,:prefix_len] + tokenized_prompt = torch.tensor(input_tokens).unsqueeze(0) + assert len(tokenized_prompt[0]) == prefix_len, f"len(tokenized_prompt[0])={len(tokenized_prompt[0])}" tokenized_prompts.append(tokenized_prompt) - return tokenized_prompts \ No newline at end of file + data = torch.cat(tokenized_prompts, dim=0) + return TensorDataset(data) \ No newline at end of file From 09179843c7a361ec5ffa760ae4f3c09ff3a55355 Mon Sep 17 00:00:00 2001 From: Ranajoy Sadhukhan Date: Tue, 3 Dec 2024 23:17:20 -0500 Subject: [PATCH 3/3] infinitebench results --- scripts/run_ib.sh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/scripts/run_ib.sh b/scripts/run_ib.sh index c1e3d92f..d2a6733c 100644 --- a/scripts/run_ib.sh +++ b/scripts/run_ib.sh @@ -1,9 +1,9 @@ model=meta-llama/Meta-Llama-3.1-8B TASKS=( - # "math_calc" + "math_calc" # "longbook_sum_eng" - "longdialogue_qa_eng" + # "longdialogue_qa_eng" ) gen_len=( @@ -28,13 +28,12 @@ for task_id in {0..0}; do echo "TASK: ${TASK}" echo "gen_len: ${gen_len}" - torchrun --standalone --nproc_per_node=1 \ + torchrun --standalone --nproc_per_node=2 \ tests/infinitebench/eval.py \ --model ${MODEL_ROOT}/${model}/model.pth --model_name ${model} \ - --draft_budget ${draft_budget} --rank_group 0 \ + --draft_budget ${draft_budget} --rank_group 0 1 \ --gamma ${gamma} --B ${bsz} --prefix_len ${prefill} --max_len ${max_len} \ --printoutput --benchmark \ --task ${TASK} --data_dir /home/rsadhukh/opensource/InfiniAI/MagicDec/Data/infinitebench \ - # -compile done \ No newline at end of file