mirror of
https://github.com/hanzoai/open-instruct.git
synced 2026-10-30 18:26:32 +00:00
* Push evaluation results into the datalake * quick change * push changes
704 lines
32 KiB
Python
Executable File
704 lines
32 KiB
Python
Executable File
import copy
|
|
import subprocess
|
|
import yaml
|
|
import re
|
|
import itertools
|
|
from datetime import date
|
|
import argparse
|
|
import os
|
|
|
|
|
|
########################################
|
|
|
|
# Helper functions.
|
|
|
|
def adjust_batch_size(task_spec, model_name, batch_size_reduction):
|
|
"Adjust batch size using heuristics that are good for A100-size GPUs."
|
|
reduce_by_2 = ["13B"]
|
|
reduce_by_4 = ["30B", "34B", "40B", "65B", "70B", "70b", "72B", "72b"]
|
|
# If not given, choose a value based on the model name.
|
|
if batch_size_reduction is None:
|
|
if any([pattern in model_name for pattern in reduce_by_2]):
|
|
batch_size_reduction = 2
|
|
elif any([pattern in model_name for pattern in reduce_by_4]):
|
|
batch_size_reduction = 4
|
|
else:
|
|
batch_size_reduction = 1
|
|
|
|
# Reduce accordingly.
|
|
if "--eval_batch_size" in task_spec['arguments'][0]:
|
|
original_batch_size = re.search("--eval_batch_size (\d+)", task_spec['arguments'][0]).group(1)
|
|
new_batch_size = max(1, int(original_batch_size) // batch_size_reduction)
|
|
task_spec['arguments'] = [task_spec['arguments'][0].replace("--eval_batch_size {}".format(original_batch_size), "--eval_batch_size {}".format(new_batch_size))]
|
|
|
|
return task_spec
|
|
|
|
|
|
def adjust_gpus(task_spec, experiment_group, model_name, gpu_multiplier):
|
|
"Adjust GPU count using heuristics that are good for A100-size GPUs."
|
|
medium = ["30B", "34B"]
|
|
large = ["40B", "65B", "70B", "70b", "72B", "72b"]
|
|
# If not given, choose a value based on model name.
|
|
if gpu_multiplier is None:
|
|
if any([pattern in model_name for pattern in medium]):
|
|
default_multiplier = 1
|
|
codex_multiplier = 2
|
|
elif any([pattern in model_name for pattern in large]):
|
|
default_multiplier = 2
|
|
codex_multiplier = 4
|
|
else:
|
|
default_multiplier = codex_multiplier = 1
|
|
else:
|
|
default_multiplier = gpu_multiplier
|
|
# If a gpu multiplier is given, double the gpus for Codex.
|
|
codex_multiplier = 2 * gpu_multiplier
|
|
|
|
# Increase accordingly.
|
|
if "codex_eval" in experiment_group:
|
|
task_spec['resources']['gpuCount'] = codex_multiplier * task_spec['resources']['gpuCount']
|
|
else:
|
|
task_spec['resources']['gpuCount'] = default_multiplier * task_spec['resources']['gpuCount']
|
|
|
|
return task_spec
|
|
|
|
|
|
########################################
|
|
# Launcher
|
|
|
|
WEKA_CLUSTERS = [
|
|
"ai2/jupiter-cirrascale-2",
|
|
"ai2/saturn-cirrascale",
|
|
"ai2/neptune-cirrascale",
|
|
"ai2/allennlp-elara-cirrascale",
|
|
"ai2/ceres-cirrascale"
|
|
]
|
|
GCP_CLUSTERS = [
|
|
"ai2/augusta-google-1"
|
|
]
|
|
|
|
|
|
today = date.today().strftime("%m%d%Y")
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--workspace", type=str, default="oe-adapt-general")
|
|
parser.add_argument("--model_name", type=str, default="hf-opt-7B")
|
|
parser.add_argument("--hf_revision", type=str, default=None)
|
|
parser.add_argument("--location", type=str, default=None)
|
|
parser.add_argument("--beaker_image", type=str, default="nathanl/open_instruct_auto", help="If given, use this Beaker image.")
|
|
parser.add_argument("--beaker_subfolder", type=str, default=None)
|
|
parser.add_argument("--cluster", nargs='+', default=[
|
|
"ai2/allennlp-cirrascale",
|
|
"ai2/general-cirrascale",
|
|
"ai2/s2-cirrascale-l40",
|
|
"ai2/allennlp-elara-cirrascale",
|
|
"ai2/pluto-cirrascale",
|
|
"ai2/neptune-cirrascale",
|
|
"ai2/saturn-cirrascale",
|
|
"ai2/jupiter-cirrascale-2",
|
|
])
|
|
parser.add_argument("--is_tuned", action="store_true")
|
|
parser.add_argument("--use_hf_tokenizer_template", action="store_true")
|
|
parser.add_argument("--priority", type=str, default="low")
|
|
parser.add_argument("--preemptible", action="store_true", default=False, help="for using preemtipble jobs (required on some instances)")
|
|
parser.add_argument("--olmo", action="store_true", help="Pass this flag if evaluating an OLMo model and `olmo` isn't in the model name.")
|
|
parser.add_argument("--experiments", type=str, nargs="+", default=None, help="Experiments to run, e.g., '--experiments mmlu_5shot gsm_cot'")
|
|
parser.add_argument("--batch_size_reduction", type=int, default=None, help="Reduce batch size by this factor.")
|
|
parser.add_argument("--gpu_multiplier", type=int, default=None, help="Multiply the number of GPUs by this factor.")
|
|
parser.add_argument("--gsm_stop_at_double_newline", action="store_true", help="Stop GSM generation at the first double newline.")
|
|
parser.add_argument("--no-nfs", action="store_true", help="Don't mount the NFS.")
|
|
parser.add_argument("--add_stop_sequence", type=str, nargs="+", default=[], help="Additional stop sequences to use when generating completions.") # e.g. \"<|eot_id|>\" for llama 3
|
|
parser.add_argument("--upload_to_hf", type=str, default=None, help="If given, upload the eval results to the Hugging Face model hub. Provide the HF dataset and path in form <hf dataset>//<hf path>.")
|
|
parser.add_argument("--hf_upload_experiments", type=str, nargs="*", default=None, help="Upload given experiment to the Hugging Face model hub.")
|
|
parser.add_argument("--run_oe_eval_experiments", action="store_true", help="Run the OE eval tool and experiments too.")
|
|
parser.add_argument("--run_safety_evaluations", action="store_true", help="Run the OE safety evaluations too.")
|
|
parser.add_argument("--skip_oi_evals", action="store_true", help="Don't run open instruct evals.")
|
|
parser.add_argument("--oe_eval_max_length", type=int, default=4096, help="Max length for OE eval.")
|
|
parser.add_argument("--oe_eval_unseen_evals", action="store_true", help="Run unseen task evals instead of dev task evals on OE Eval.")
|
|
parser.add_argument("--use_alternate_safety_image", type=str, default=None, help="Use a different image for safety eval.")
|
|
parser.add_argument("--evaluate_on_weka", action="store_true", help="Evaluate OE eval on Beaker.")
|
|
parser.add_argument("--oe_eval_tasks", type=str, default=None, help="Evaluate OE eval on Beaker.")
|
|
parser.add_argument("--step", type=int, default=None, help="Step number for postgresql logging.")
|
|
parser.add_argument("--run_id", type=str, default=None, help="A unique run ID for postgresql logging.")
|
|
args = parser.parse_args()
|
|
|
|
|
|
workspace = args.workspace
|
|
model_type = "vanilla_lm" if not args.is_tuned else "tuned_lm"
|
|
|
|
with open("configs/beaker_configs/default_eval.yaml", 'r') as f:
|
|
default_yaml = f.read()
|
|
d1 = yaml.load(default_yaml, Loader=yaml.FullLoader)
|
|
|
|
cluster = args.cluster
|
|
if cluster[0] == "all":
|
|
cluster = [] # empty list means all clusters
|
|
d1['tasks'][0]['constraints']['cluster'] = cluster
|
|
d1['tasks'][0]['context']['priority'] = args.priority
|
|
d1['tasks'][0]['context']['preemptible'] = args.preemptible
|
|
d1['tasks'][0]['resources']['gpuCount'] = 1
|
|
|
|
# remove nfs if asked or jupiter in cluster list.
|
|
weka_available = False
|
|
if all(c in WEKA_CLUSTERS for c in cluster):
|
|
d1['tasks'][0]['datasets'].append({
|
|
'mountPath': "/weka/oe-adapt-default",
|
|
"source": {
|
|
"weka": "oe-adapt-default"
|
|
}
|
|
})
|
|
weka_available = True
|
|
|
|
|
|
# Use a different image if requested.
|
|
if args.beaker_image is not None:
|
|
d1['tasks'][0]['image']['beaker'] = args.beaker_image
|
|
|
|
# modify here, or use "--experiments", for different set of experiments
|
|
experiment_groups_default = [
|
|
"mmlu_0shot",
|
|
"mmlu_5shot",
|
|
"gsm_direct",
|
|
"gsm_cot",
|
|
"MATH_cot",
|
|
"bbh_direct",
|
|
"bbh_cot",
|
|
"tydiqa_goldp_1shot",
|
|
"tydiqa_no_context_1shot",
|
|
"codex_eval_temp_0.1",
|
|
"codex_eval_temp_0.8",
|
|
"codex_evalplus_temp_0.1",
|
|
"codex_evalplus_temp_0.8",
|
|
"mbpp_evalplus_temp_0.1",
|
|
"mbpp_evalplus_temp_0.8",
|
|
"ifeval",
|
|
"truthfulqa",
|
|
"toxigen",
|
|
"xstest",
|
|
"alpaca_eval",
|
|
"alpaca_eval_2",
|
|
]
|
|
experiment_groups = args.experiments or experiment_groups_default
|
|
|
|
# format: model name, their beaker id, checkpoint subfolder, tuned or base.
|
|
# or: name, path, None, tuned or base
|
|
model_info = (args.model_name, args.location, args.beaker_subfolder, model_type)
|
|
|
|
# --------------- experiments about number of supervision tasks -------------------------
|
|
|
|
# for experiment_group, model_info in itertools.product(experiment_groups, models):
|
|
|
|
d = copy.deepcopy(d1)
|
|
model_name = model_info[0] + f"_{model_info[2]}" if model_info[2] is not None else model_info[0]
|
|
|
|
# Create tasks for each evaluation.
|
|
eval_task_specs = []
|
|
|
|
for experiment_group in experiment_groups:
|
|
print(f"Submitting {experiment_group} for model: {model_info[0]}")
|
|
task_spec = copy.deepcopy(d1["tasks"][0])
|
|
|
|
name = f"open_instruct_eval_{experiment_group}_{model_name}_{today}"
|
|
task_spec['name'] = name
|
|
|
|
if experiment_group == "mmlu_0shot":
|
|
task_spec['arguments'][0] = '''
|
|
python -m eval.mmlu.run_eval \
|
|
--ntrain 0 \
|
|
--data_dir /data/mmlu/ \
|
|
--save_dir /output/ \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
--eval_batch_size 4 \
|
|
--use_chat_format \
|
|
--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format \
|
|
'''
|
|
elif experiment_group == "mmlu_5shot":
|
|
task_spec['arguments'][0] = '''
|
|
python -m eval.mmlu.run_eval \
|
|
--ntrain 5 \
|
|
--data_dir /data/mmlu/ \
|
|
--save_dir /output/ \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
--eval_batch_size 4 \
|
|
--use_chat_format \
|
|
--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format \
|
|
'''
|
|
elif experiment_group == "bbh_direct":
|
|
task_spec['arguments'][0] = '''
|
|
python -m eval.bbh.run_eval \
|
|
--data_dir /data/bbh \
|
|
--save_dir /output/ \
|
|
--use_vllm \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
--max_num_examples_per_task 40 \
|
|
--no_cot \
|
|
--use_chat_format \
|
|
--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format \
|
|
'''
|
|
elif experiment_group == "bbh_cot":
|
|
task_spec['arguments'][0] = '''
|
|
python -m eval.bbh.run_eval \
|
|
--data_dir /data/bbh \
|
|
--save_dir /output/ \
|
|
--use_vllm \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
--max_num_examples_per_task 40 \
|
|
--use_chat_format \
|
|
--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format \
|
|
'''
|
|
elif experiment_group == "gsm_direct":
|
|
task_spec['arguments'][0] = '''
|
|
python -m eval.gsm.run_eval \
|
|
--data_dir /data/gsm/ \
|
|
--max_num_examples 200 \
|
|
--save_dir /output/ \
|
|
--use_vllm \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
--n_shot 8 \
|
|
--no_cot \
|
|
--use_chat_format \
|
|
--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format \
|
|
'''
|
|
if args.gsm_stop_at_double_newline:
|
|
# We need to final backslash in the command above so that there isn't a
|
|
# newline between this argument and the prior part of the command.
|
|
task_spec['arguments'][0] += " --stop_at_double_newline"
|
|
elif experiment_group == "gsm_cot":
|
|
task_spec['arguments'][0] = '''
|
|
python -m eval.gsm.run_eval \
|
|
--data_dir /data/gsm/ \
|
|
--max_num_examples 200 \
|
|
--save_dir /output/ \
|
|
--use_vllm \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
--n_shot 8 \
|
|
--use_chat_format \
|
|
--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format \
|
|
'''
|
|
if args.gsm_stop_at_double_newline:
|
|
task_spec['arguments'][0] += " --stop_at_double_newline"
|
|
elif experiment_group == "MATH_cot":
|
|
task_spec['arguments'][0] = '''
|
|
python -m eval.MATH.run_eval \
|
|
--data_dir /data/MATH/ \
|
|
--max_num_examples 200 \
|
|
--save_dir /output/ \
|
|
--use_vllm \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
--n_shot 4 \
|
|
--use_chat_format \
|
|
--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format \
|
|
'''
|
|
elif experiment_group == "tydiqa_goldp_1shot":
|
|
task_spec["arguments"][0] = '''
|
|
python -m eval.tydiqa.run_eval \
|
|
--data_dir /data/tydiqa/ \
|
|
--n_shot 1 \
|
|
--max_num_examples_per_lang 100 \
|
|
--max_context_length 512 \
|
|
--save_dir /output/ \
|
|
--use_vllm \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
--use_chat_format \
|
|
--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format \
|
|
'''
|
|
elif experiment_group == "tydiqa_no_context_1shot":
|
|
task_spec["arguments"][0] = '''
|
|
python -m eval.tydiqa.run_eval \
|
|
--data_dir /data/tydiqa/ \
|
|
--no_context \
|
|
--n_shot 1 \
|
|
--max_num_examples_per_lang 100 \
|
|
--max_context_length 512 \
|
|
--save_dir /output/ \
|
|
--use_vllm \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
--use_chat_format \
|
|
--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format \
|
|
'''
|
|
elif experiment_group == "codex_eval_temp_0.1":
|
|
task_spec['arguments'][0] = '''
|
|
python -m eval.codex_humaneval.run_eval \
|
|
--data_file /data/codex_humaneval/HumanEval.jsonl.gz \
|
|
--eval_pass_at_ks 1 5 10 20 \
|
|
--unbiased_sampling_size_n 20 \
|
|
--temperature 0.1 \
|
|
--save_dir /output/ \
|
|
--use_vllm \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
'''
|
|
elif experiment_group == "codex_eval_temp_0.8":
|
|
task_spec['arguments'][0] = '''
|
|
python -m eval.codex_humaneval.run_eval \
|
|
--data_file /data/codex_humaneval/HumanEval.jsonl.gz \
|
|
--eval_pass_at_ks 1 5 10 20 \
|
|
--unbiased_sampling_size_n 20 \
|
|
--temperature 0.8 \
|
|
--save_dir /output/ \
|
|
--use_vllm \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
'''
|
|
elif experiment_group == "codex_evalplus_temp_0.1":
|
|
task_spec['arguments'][0] = '''
|
|
python -m eval.codex_humaneval.run_eval \
|
|
--data_file /data/codex_humaneval/HumanEvalPlus-OriginFmt.jsonl.gz \
|
|
--eval_pass_at_ks 1 5 10 20 \
|
|
--unbiased_sampling_size_n 20 \
|
|
--temperature 0.1 \
|
|
--save_dir /output/ \
|
|
--use_vllm \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
--use_chat_format \
|
|
--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format
|
|
'''
|
|
elif experiment_group == "codex_evalplus_temp_0.8":
|
|
task_spec['arguments'][0] = '''
|
|
python -m eval.codex_humaneval.run_eval \
|
|
--data_file /data/codex_humaneval/HumanEvalPlus-OriginFmt.jsonl.gz \
|
|
--data_file_hep data/eval/codex_humaneval/humanevalpack.jsonl \
|
|
--eval_pass_at_ks 1 5 10 20 \
|
|
--unbiased_sampling_size_n 20 \
|
|
--temperature 0.8 \
|
|
--save_dir /output/ \
|
|
--use_vllm \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
--use_chat_format \
|
|
--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format
|
|
'''
|
|
elif experiment_group == "mbpp_evalplus_temp_0.1":
|
|
task_spec['arguments'][0] = '''
|
|
HF_ALLOW_CODE_EVAL=1 python -m eval.mbpp.run_eval \
|
|
--eval_pass_at_ks 1 5 10 20 \
|
|
--unbiased_sampling_size_n 20 \
|
|
--temperature 0.1 \
|
|
--save_dir /output/ \
|
|
--use_vllm \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
--use_chat_format \
|
|
--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format
|
|
'''
|
|
elif experiment_group == "mbpp_evalplus_temp_0.8":
|
|
task_spec['arguments'][0] = '''
|
|
HF_ALLOW_CODE_EVAL=1 python -m eval.mbpp.run_eval \
|
|
--eval_pass_at_ks 1 5 10 20 \
|
|
--unbiased_sampling_size_n 20 \
|
|
--temperature 0.8 \
|
|
--save_dir /output/ \
|
|
--use_vllm \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
--use_chat_format \
|
|
--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format
|
|
'''
|
|
elif experiment_group == "ifeval":
|
|
task_spec['arguments'][0] = '''
|
|
python -m eval.ifeval.run_eval \
|
|
--data_dir /data/ifeval/ \
|
|
--save_dir /output/ \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
--use_chat_format \
|
|
--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format \
|
|
--use_vllm \
|
|
'''
|
|
elif experiment_group == "truthfulqa":
|
|
task_spec['arguments'][0] = '''
|
|
python -m eval.truthfulqa.run_eval \
|
|
--data_dir /data/truthfulqa \
|
|
--save_dir /output/ \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
--metrics truth info mc \
|
|
--preset qa \
|
|
--hf_truth_model_name_or_path allenai/truthfulqa-truth-judge-llama2-7B \
|
|
--hf_info_model_name_or_path allenai/truthfulqa-info-judge-llama2-7B \
|
|
--eval_batch_size 20 \
|
|
--use_chat_format \
|
|
--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format \
|
|
'''
|
|
elif experiment_group == "toxigen":
|
|
task_spec['arguments'][0] = '''
|
|
python -m eval.toxigen.run_eval \
|
|
--data_dir /data/toxigen/ \
|
|
--save_dir /output/ \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
--eval_batch_size 32 \
|
|
--use_vllm \
|
|
--use_chat_format \
|
|
--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format \
|
|
'''
|
|
elif experiment_group == "xstest":
|
|
task_spec['arguments'][0] = '''
|
|
python -m eval.xstest.run_eval \
|
|
--data_dir /data/xstest/ \
|
|
--save_dir /output/ \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
--eval_batch_size 32 \
|
|
--use_vllm \
|
|
--use_chat_format \
|
|
--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format \
|
|
'''
|
|
elif experiment_group == "alpaca_eval":
|
|
task_spec['arguments'][0] = '''
|
|
IS_ALPACA_EVAL_2=False python -m eval.alpaca_farm.run_eval \
|
|
--use_vllm \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
--save_dir /output/ \
|
|
--use_chat_format \
|
|
--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format \
|
|
'''
|
|
elif experiment_group == "alpaca_eval_2":
|
|
task_spec['arguments'][0] = '''
|
|
IS_ALPACA_EVAL_2=True python -m eval.alpaca_farm.run_eval \
|
|
--use_vllm \
|
|
--model_name_or_path /model \
|
|
--tokenizer_name_or_path /model \
|
|
--save_dir /output/ \
|
|
--use_chat_format \
|
|
--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format \
|
|
'''
|
|
# OLMo models can only output 2048 new tokens at most; default is 8192.
|
|
if "olmo" in model_info[0] or args.olmo:
|
|
task_spec['arguments'][0] += " --max_new_tokens 4096" # nol increased hardcode to 4096
|
|
|
|
else:
|
|
raise ValueError("experiment_group not supported")
|
|
|
|
if model_info[0].startswith("hf-"): # if it's a huggingface model, load it from the model hub
|
|
task_spec['arguments'] = [task_spec['arguments'][0].replace("--model_name_or_path /model", f"--model_name_or_path {model_info[1]} --hf_revision {args.hf_revision}")]
|
|
task_spec['arguments'] = [task_spec['arguments'][0].replace("--tokenizer_name_or_path /model", f"--tokenizer_name_or_path {model_info[1]}")]
|
|
elif model_info[1].startswith("/"): # if it's a local model, load it from the local directory
|
|
assert weka_available, "NFS / Weka is required for path-based models." # to be safe.
|
|
task_spec['arguments'] = [task_spec['arguments'][0].replace("--model_name_or_path /model", f"--model_name_or_path {model_info[1]}")]
|
|
task_spec['arguments'] = [task_spec['arguments'][0].replace("--tokenizer_name_or_path /model", f"--tokenizer_name_or_path {model_info[1]}")]
|
|
else: # if it's a beaker model, mount the beaker dataset to `/model`
|
|
task_spec['datasets'][1]['source']['beaker'] = model_info[1]
|
|
|
|
# if a specific checkpoint is specified, load model from that checkpoint
|
|
if model_info[2] is not None:
|
|
# extract existing model path
|
|
model_name_or_path = re.search("--model_name_or_path (\S+)", task_spec['arguments'][0]).group(1)
|
|
# replace the model path with the checkpoint subfolder.
|
|
task_spec['arguments'] = [task_spec['arguments'][0].replace(model_name_or_path, model_name_or_path+"/"+model_info[2], 1)]
|
|
# NOTE: We don't change the tokenizer subfolder, because by default the
|
|
# tokenizer is only saved to the top-level output dir. That's why we call
|
|
# `str.replace(..., 1)` above; this only replaces the first match.
|
|
|
|
# for vanilla_lm, remove the chat formatting function
|
|
if model_info[3] == "vanilla_lm":
|
|
task_spec['arguments'] = [task_spec['arguments'][0].replace("--use_chat_format", "")]
|
|
|
|
# Adjust batch size and gpus.
|
|
task_spec = adjust_batch_size(
|
|
task_spec=task_spec,
|
|
model_name=model_info[0],
|
|
batch_size_reduction=args.batch_size_reduction,
|
|
)
|
|
task_spec = adjust_gpus(
|
|
task_spec=task_spec,
|
|
experiment_group=experiment_group,
|
|
model_name=model_info[0],
|
|
gpu_multiplier=args.gpu_multiplier,
|
|
)
|
|
|
|
# if using huggingface tokenizer template, replace the chat formatting function with hf tokenizer one
|
|
# otherwise, try to guess what template to use based on model name
|
|
if args.use_hf_tokenizer_template:
|
|
task_spec['arguments'] = [task_spec['arguments'][0].replace(
|
|
"--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format",
|
|
"--chat_formatting_function eval.templates.create_prompt_with_huggingface_tokenizer_template")
|
|
]
|
|
elif "llama2-chat" in model_info[0]:
|
|
task_spec['arguments'] = [task_spec['arguments'][0].replace(
|
|
"--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format",
|
|
"--chat_formatting_function eval.templates.create_prompt_with_llama2_chat_format")
|
|
]
|
|
elif "code_llama_instruct" in model_info[0]:
|
|
task_spec['arguments'] = [task_spec['arguments'][0].replace(
|
|
"--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format",
|
|
"--chat_formatting_function eval.templates.create_prompt_with_llama2_chat_format")
|
|
]
|
|
elif "zephyr" in model_info[0]:
|
|
task_spec['arguments'] = [task_spec['arguments'][0].replace(
|
|
"--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format",
|
|
"--chat_formatting_function eval.templates.create_prompt_with_zephyr_chat_format")
|
|
]
|
|
elif "xwin" in model_info[0]:
|
|
task_spec['arguments'] = [task_spec['arguments'][0].replace(
|
|
"--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format",
|
|
"--chat_formatting_function eval.templates.create_prompt_with_xwin_chat_format")
|
|
]
|
|
elif "olmo" in model_info[0] or args.olmo:
|
|
task_spec['arguments'] = [task_spec['arguments'][0].replace(
|
|
"--chat_formatting_function eval.templates.create_prompt_with_tulu_chat_format",
|
|
"--chat_formatting_function eval.templates.create_prompt_with_olmo_chat_format")
|
|
]
|
|
|
|
if any([x in model_info[0] for x in ["opt", "pythia", "falcon", "olmoe"]]):
|
|
if "--use_vllm" in task_spec['arguments'][0]:
|
|
print(f"Removing --use_vllm for {model_info[0]}")
|
|
task_spec['arguments'] = [task_spec['arguments'][0].replace("--use_vllm", "")]
|
|
|
|
# Add additional stop sequences if needed.
|
|
# mainly for llama-3-instruct eot.
|
|
tasks_without_addition_stop = ["mmlu_0shot", "mmlu_5shot", "truthfulqa"]
|
|
if args.add_stop_sequence and experiment_group not in tasks_without_addition_stop:
|
|
task_spec['arguments'] = [task_spec['arguments'][0] + " --additional_stop_sequence " + " ".join(args.add_stop_sequence)]
|
|
|
|
# add HF hub upload if specified
|
|
if args.upload_to_hf:
|
|
if args.hf_upload_experiments is None or len(args.hf_upload_experiments) == 0:
|
|
# by default, we dont upload oi-evals, only safety and oe-evals.
|
|
args.hf_upload_experiments = []
|
|
if experiment_group not in args.hf_upload_experiments:
|
|
print(f"Skipping HF upload for {experiment_group}")
|
|
else:
|
|
hf_dataset = args.upload_to_hf
|
|
# to match the way oe-eval script works.
|
|
# if we prepended hf- to the model name, remove it.
|
|
if model_name.startswith("hf-"):
|
|
model_name = model_name[3:]
|
|
task_spec['arguments'] = [task_spec['arguments'][0] + f" --upload_to_hf {hf_dataset} --hf_upload_name results/{model_name}"]
|
|
|
|
eval_task_specs.append(task_spec)
|
|
|
|
|
|
# Create an experiment that runs all the eval tasks.
|
|
|
|
model_name = model_name[:100] # beaker doesn't like names longer than 128 characters, here we save for some headroom.
|
|
if not args.skip_oi_evals:
|
|
experiment_name = f"open_instruct_eval_{model_name}_{today}"
|
|
d["description"] = experiment_name
|
|
d["tasks"] = eval_task_specs
|
|
# if configs/beaker_configs/auto_created doesn't exist, create it with os
|
|
if not os.path.exists("configs/beaker_configs/auto_created"):
|
|
os.makedirs("configs/beaker_configs/auto_created")
|
|
fn = "configs/beaker_configs/auto_created/{}.yaml".format(experiment_name)
|
|
os.makedirs(os.path.dirname(fn), exist_ok=True)
|
|
with open(fn, "w") as file:
|
|
yaml.dump(d, file, default_flow_style=True)
|
|
|
|
cmd = "beaker experiment create {} --workspace ai2/{}".format(fn, workspace)
|
|
subprocess.Popen(cmd, shell=True)
|
|
|
|
if args.run_oe_eval_experiments or args.oe_eval_unseen_evals:
|
|
# if so, run oe-eval. We assume it is cloned in the top-level repo directory.
|
|
oe_eval_cmd = f"scripts/eval/oe-eval.sh --model-name {model_name}"
|
|
if args.upload_to_hf:
|
|
oe_eval_cmd += f" --upload_to_hf {args.upload_to_hf}"
|
|
## model location munging: if beaker, use beaker://. If hf, just name
|
|
if model_info[0].startswith("hf-"):
|
|
oe_eval_cmd += f" --model-location {model_info[1]}"
|
|
elif model_info[1].startswith("/"):
|
|
oe_eval_cmd += f" --model-location {model_info[1]}"
|
|
else:
|
|
oe_eval_cmd += f" --model-location beaker://{model_info[1]}"
|
|
if args.hf_revision:
|
|
oe_eval_cmd += f" --revision {args.hf_revision}"
|
|
if args.evaluate_on_weka:
|
|
oe_eval_cmd += " --evaluate_on_weka"
|
|
if args.oe_eval_tasks:
|
|
oe_eval_cmd += f" --tasks {args.oe_eval_tasks}"
|
|
if args.run_id:
|
|
oe_eval_cmd += f" --run-id {args.run_id}"
|
|
if args.step:
|
|
oe_eval_cmd += f" --step {args.step}"
|
|
# add string with number of gpus
|
|
num_gpus = task_spec['resources']['gpuCount']
|
|
# if num_gpus > 1, double it again for oe-eval configs
|
|
# open_instruct GPT adjustment wasn't quite enough
|
|
# adjusted here so the GPU configs in open-instruct eval are not impacted by the change
|
|
# tested reasonably extensively with 70B
|
|
if num_gpus > 1:
|
|
num_gpus *= 2
|
|
oe_eval_cmd += f" --num_gpus {num_gpus}"
|
|
if args.oe_eval_max_length:
|
|
oe_eval_cmd += f" --max-length {args.oe_eval_max_length}"
|
|
if args.oe_eval_unseen_evals:
|
|
oe_eval_cmd += " --unseen-evals"
|
|
# add priority
|
|
oe_eval_cmd += f" --priority {args.priority}"
|
|
print(f"Running OE eval with command: {oe_eval_cmd}")
|
|
subprocess.Popen(oe_eval_cmd, shell=True)
|
|
|
|
# create an experiment that runs the safety eval tasks
|
|
if args.run_safety_evaluations:
|
|
# just take the original spec we had, modify it for safety eval.
|
|
experiment_name = f"oi_safety_{model_name}"
|
|
experiment_name = experiment_name.replace('β', '').replace(r"{", "").replace(r"}", "") # hack: remove characters beaker doesn't like
|
|
d["description"] = experiment_name
|
|
# specific image for safety eval
|
|
d["tasks"][0]["image"]["beaker"] = "hamishivi/open-safety"
|
|
if args.use_alternate_safety_image:
|
|
d["tasks"][0]["image"]["beaker"] = args.use_alternate_safety_image
|
|
d["tasks"] = [d["tasks"][0]]
|
|
task_spec = d["tasks"][0]
|
|
task_spec["name"] = experiment_name
|
|
task_spec["arguments"][0] = f'''
|
|
VLLM_WORKER_MULTIPROC_METHOD=spawn PYTHONPATH=. python evaluation/run_all_generation_benchmarks.py \
|
|
--model_name_or_path /model \
|
|
--model_input_template_path_or_name hf \
|
|
--report_output_path /output/metrics.json \
|
|
--save_individual_results_path /output/all.json \
|
|
'''
|
|
# some copied logic
|
|
if model_info[0].startswith("hf-"): # if it's a huggingface model, load it from the model hub
|
|
task_spec['arguments'] = [task_spec['arguments'][0].replace("--model_name_or_path /model", f"--model_name_or_path {model_info[1]} --hf_revision {args.hf_revision}")]
|
|
task_spec['arguments'] = [task_spec['arguments'][0].replace("--tokenizer_name_or_path /model", f"--tokenizer_name_or_path {model_info[1]}")]
|
|
elif model_info[1].startswith("/"): # if it's a local model, load it from the local directory
|
|
assert weka_available, "NFS / Weka is required for path-based models." # to be safe.
|
|
task_spec['arguments'] = [task_spec['arguments'][0].replace("--model_name_or_path /model", "--model_name_or_path "+model_info[1])]
|
|
task_spec['arguments'] = [task_spec['arguments'][0].replace("--tokenizer_name_or_path /model", "--tokenizer_name_or_path "+model_info[1])]
|
|
else: # if it's a beaker model, mount the beaker dataset to `/model`
|
|
task_spec['datasets'][1]['source']['beaker'] = model_info[1]
|
|
|
|
task_spec = adjust_gpus(
|
|
task_spec=task_spec,
|
|
experiment_group="safety_eval",
|
|
model_name=model_info[0],
|
|
gpu_multiplier=args.gpu_multiplier,
|
|
)
|
|
|
|
# add gpu information.
|
|
# we just assume you want to use all the gpus for one task at a time
|
|
if "70B" in model_info[0]:
|
|
task_spec['resources']['gpuCount'] = 8
|
|
num_gpus = task_spec['resources']['gpuCount']
|
|
task_spec["arguments"][0]+= f" --min_gpus_per_task {num_gpus}"
|
|
|
|
if args.upload_to_hf:
|
|
hf_dataset = args.upload_to_hf
|
|
# to match the way oe-eval script works.
|
|
# if we prepended hf- to the model name, remove it.
|
|
# if model_name.startswith("hf-"):
|
|
# model_name = model_name[3:]
|
|
# Above is no longer the case, oe-eval includes hf- again
|
|
task_spec['arguments'] = [task_spec['arguments'][0] + f" --upload_to_hf {hf_dataset} --hf_upload_name results/{model_name}"]
|
|
|
|
d["tasks"] = [task_spec]
|
|
if not os.path.exists("configs/beaker_configs/auto_created"):
|
|
os.makedirs("configs/beaker_configs/auto_created")
|
|
fn = "configs/beaker_configs/auto_created/{}.yaml".format(experiment_name)
|
|
os.makedirs(os.path.dirname(fn), exist_ok=True)
|
|
with open(fn, "w") as file:
|
|
yaml.dump(d, file, default_flow_style=True)
|
|
|
|
cmd = "beaker experiment create {} --workspace ai2/{}".format(fn, workspace)
|
|
subprocess.Popen(cmd, shell=True)
|