Spaces:
Runtime error
Runtime error
| #!/usr/bin/env python | |
| from __future__ import print_function | |
| r"""This script can launch any eval experiments from the paper. | |
| This is a script. Run with python, not bazel. | |
| Usage: | |
| ./single_task/run_eval_tasks.py \ | |
| --exp EXP --desc DESC [--tuning_tasks] [--iclr_tasks] [--task TASK] \ | |
| [--tasks TASK1 TASK2 ...] | |
| where EXP is one of the keys in `experiments`, | |
| and DESC is a string description of the set of experiments (such as "v0") | |
| Set only one of these flags: | |
| --tuning_tasks flag only runs tuning tasks. | |
| --iclr_tasks flag only runs the tasks included in the paper. | |
| --regression_tests flag runs tasks which function as regression tests. | |
| --task flag manually selects a single task to run. | |
| --tasks flag takes a custom list of tasks. | |
| Other flags: | |
| --reps N specifies N repetitions per experiment, Default is 25. | |
| --training_replicas R specifies that R workers will be launched to train one | |
| task (for neural network algorithms). These workers will update a global | |
| model stored on a parameter server. Defaults to 1. If R > 1, a parameter | |
| server will also be launched. | |
| Run everything: | |
| exps=( pg-20M pg-topk-20M topk-20M ga-20M rand-20M ) | |
| BIN_DIR="single_task" | |
| for exp in "${exps[@]}" | |
| do | |
| ./$BIN_DIR/run_eval_tasks.py \ | |
| --exp "$exp" --iclr_tasks | |
| done | |
| """ | |
| import argparse | |
| from collections import namedtuple | |
| import subprocess | |
| S = namedtuple('S', ['length']) | |
| default_length = 100 | |
| iclr_tasks = [ | |
| 'reverse', 'remove-char', 'count-char', 'add', 'bool-logic', 'print-hello', | |
| 'echo-twice', 'echo-thrice', 'copy-reverse', 'zero-cascade', 'cascade', | |
| 'shift-left', 'shift-right', 'riffle', 'unriffle', 'middle-char', | |
| 'remove-last', 'remove-last-two', 'echo-alternating', 'echo-half', 'length', | |
| 'echo-second-seq', 'echo-nth-seq', 'substring', 'divide-2', 'dedup'] | |
| regression_test_tasks = ['reverse', 'test-hill-climb'] | |
| E = namedtuple( | |
| 'E', | |
| ['name', 'method_type', 'config', 'simplify', 'batch_size', 'max_npe']) | |
| def make_experiment_settings(name, **kwargs): | |
| # Unpack experiment info from name. | |
| def split_last(string, char): | |
| i = string.rindex(char) | |
| return string[:i], string[i+1:] | |
| def si_to_int(si_string): | |
| return int( | |
| si_string.upper().replace('K', '0'*3).replace('M', '0'*6) | |
| .replace('G', '0'*9)) | |
| method_type, max_npe = split_last(name, '-') | |
| assert method_type | |
| assert max_npe | |
| return E( | |
| name=name, method_type=method_type, max_npe=si_to_int(max_npe), **kwargs) | |
| experiments_set = { | |
| make_experiment_settings( | |
| 'pg-20M', | |
| config='entropy_beta=0.05,lr=0.0001,topk_loss_hparam=0.0,topk=0,' | |
| 'pi_loss_hparam=1.0,alpha=0.0', | |
| simplify=False, | |
| batch_size=64), | |
| make_experiment_settings( | |
| 'pg-topk-20M', | |
| config='entropy_beta=0.01,lr=0.0001,topk_loss_hparam=50.0,topk=10,' | |
| 'pi_loss_hparam=1.0,alpha=0.0', | |
| simplify=False, | |
| batch_size=64), | |
| make_experiment_settings( | |
| 'topk-20M', | |
| config='entropy_beta=0.01,lr=0.0001,topk_loss_hparam=200.0,topk=10,' | |
| 'pi_loss_hparam=0.0,alpha=0.0', | |
| simplify=False, | |
| batch_size=64), | |
| make_experiment_settings( | |
| 'topk-0ent-20M', | |
| config='entropy_beta=0.000,lr=0.0001,topk_loss_hparam=200.0,topk=10,' | |
| 'pi_loss_hparam=0.0,alpha=0.0', | |
| simplify=False, | |
| batch_size=64), | |
| make_experiment_settings( | |
| 'ga-20M', | |
| config='crossover_rate=0.95,mutation_rate=0.15', | |
| simplify=False, | |
| batch_size=100), # Population size. | |
| make_experiment_settings( | |
| 'rand-20M', | |
| config='', | |
| simplify=False, | |
| batch_size=1), | |
| make_experiment_settings( | |
| 'simpl-500M', | |
| config='entropy_beta=0.05,lr=0.0001,topk_loss_hparam=0.5,topk=10,' | |
| 'pi_loss_hparam=1.0,alpha=0.0', | |
| simplify=True, | |
| batch_size=64), | |
| } | |
| experiments = {e.name: e for e in experiments_set} | |
| # pylint: disable=redefined-outer-name | |
| def parse_args(extra_args=()): | |
| """Parse arguments and extract task and experiment info.""" | |
| parser = argparse.ArgumentParser(description='Run all eval tasks.') | |
| parser.add_argument('--exp', required=True) | |
| parser.add_argument('--tuning_tasks', action='store_true') | |
| parser.add_argument('--iclr_tasks', action='store_true') | |
| parser.add_argument('--regression_tests', action='store_true') | |
| parser.add_argument('--desc', default='v0') | |
| parser.add_argument('--reps', default=25) | |
| parser.add_argument('--task') | |
| parser.add_argument('--tasks', nargs='+') | |
| for arg_string, default in extra_args: | |
| parser.add_argument(arg_string, default=default) | |
| args = parser.parse_args() | |
| print('Running experiment: %s' % (args.exp,)) | |
| if args.desc: | |
| print('Extra description: "%s"' % (args.desc,)) | |
| if args.exp not in experiments: | |
| raise ValueError('Experiment name is not valid') | |
| experiment_name = args.exp | |
| experiment_settings = experiments[experiment_name] | |
| assert experiment_settings.name == experiment_name | |
| if args.tasks: | |
| print('Launching tasks from args: %s' % (args.tasks,)) | |
| tasks = {t: S(length=default_length) for t in args.tasks} | |
| elif args.task: | |
| print('Launching single task "%s"' % args.task) | |
| tasks = {args.task: S(length=default_length)} | |
| elif args.tuning_tasks: | |
| print('Only running tuning tasks') | |
| tasks = {name: S(length=default_length) | |
| for name in ['reverse-tune', 'remove-char-tune']} | |
| elif args.iclr_tasks: | |
| print('Running eval tasks from ICLR paper.') | |
| tasks = {name: S(length=default_length) for name in iclr_tasks} | |
| elif args.regression_tests: | |
| tasks = {name: S(length=default_length) for name in regression_test_tasks} | |
| print('Tasks: %s' % tasks.keys()) | |
| print('reps = %d' % (int(args.reps),)) | |
| return args, tasks, experiment_settings | |
| def run(command_string): | |
| subprocess.call(command_string, shell=True) | |
| if __name__ == '__main__': | |
| LAUNCH_TRAINING_COMMAND = 'single_task/launch_training.sh' | |
| COMPILE_COMMAND = 'bazel build -c opt single_task:run.par' | |
| args, tasks, experiment_settings = parse_args( | |
| extra_args=(('--training_replicas', 1),)) | |
| if experiment_settings.method_type in ( | |
| 'pg', 'pg-topk', 'topk', 'topk-0ent', 'simpl'): | |
| # Runs PG and TopK. | |
| def make_run_cmd(job_name, task, max_npe, num_reps, code_length, | |
| batch_size, do_simplify, custom_config_str): | |
| """Constructs terminal command for launching NN based algorithms. | |
| The arguments to this function will be used to create config for the | |
| experiment. | |
| Args: | |
| job_name: Name of the job to launch. Should uniquely identify this | |
| experiment run. | |
| task: Name of the coding task to solve. | |
| max_npe: Maximum number of programs executed. An integer. | |
| num_reps: Number of times to run the experiment. An integer. | |
| code_length: Maximum allowed length of synthesized code. | |
| batch_size: Minibatch size for gradient descent. | |
| do_simplify: Whether to run the experiment in code simplification mode. | |
| A bool. | |
| custom_config_str: Additional config for the model config string. | |
| Returns: | |
| The terminal command that launches the specified experiment. | |
| """ | |
| config = """ | |
| env=c(task='{0}',correct_syntax=False), | |
| agent=c( | |
| algorithm='pg', | |
| policy_lstm_sizes=[35,35],value_lstm_sizes=[35,35], | |
| grad_clip_threshold=50.0,param_init_factor=0.5,regularizer=0.0, | |
| softmax_tr=1.0,optimizer='rmsprop',ema_baseline_decay=0.99, | |
| eos_token={3},{4}), | |
| timestep_limit={1},batch_size={2} | |
| """.replace(' ', '').replace('\n', '').format( | |
| task, code_length, batch_size, do_simplify, custom_config_str) | |
| num_ps = 0 if args.training_replicas == 1 else 1 | |
| return ( | |
| r'{0} --job_name={1} --config="{2}" --max_npe={3} ' | |
| '--num_repetitions={4} --num_workers={5} --num_ps={6} ' | |
| '--stop_on_success={7}' | |
| .format(LAUNCH_TRAINING_COMMAND, job_name, config, max_npe, num_reps, | |
| args.training_replicas, num_ps, str(not do_simplify).lower())) | |
| else: | |
| # Runs GA and Rand. | |
| assert experiment_settings.method_type in ('ga', 'rand') | |
| def make_run_cmd(job_name, task, max_npe, num_reps, code_length, | |
| batch_size, do_simplify, custom_config_str): | |
| """Constructs terminal command for launching GA or uniform random search. | |
| The arguments to this function will be used to create config for the | |
| experiment. | |
| Args: | |
| job_name: Name of the job to launch. Should uniquely identify this | |
| experiment run. | |
| task: Name of the coding task to solve. | |
| max_npe: Maximum number of programs executed. An integer. | |
| num_reps: Number of times to run the experiment. An integer. | |
| code_length: Maximum allowed length of synthesized code. | |
| batch_size: Minibatch size for gradient descent. | |
| do_simplify: Whether to run the experiment in code simplification mode. | |
| A bool. | |
| custom_config_str: Additional config for the model config string. | |
| Returns: | |
| The terminal command that launches the specified experiment. | |
| """ | |
| assert not do_simplify | |
| if custom_config_str: | |
| custom_config_str = ',' + custom_config_str | |
| config = """ | |
| env=c(task='{0}',correct_syntax=False), | |
| agent=c( | |
| algorithm='{4}' | |
| {3}), | |
| timestep_limit={1},batch_size={2} | |
| """.replace(' ', '').replace('\n', '').format( | |
| task, code_length, batch_size, custom_config_str, | |
| experiment_settings.method_type) | |
| num_workers = num_reps # Do each rep in parallel. | |
| return ( | |
| r'{0} --job_name={1} --config="{2}" --max_npe={3} ' | |
| '--num_repetitions={4} --num_workers={5} --num_ps={6} ' | |
| '--stop_on_success={7}' | |
| .format(LAUNCH_TRAINING_COMMAND, job_name, config, max_npe, num_reps, | |
| num_workers, 0, str(not do_simplify).lower())) | |
| print('Compiling...') | |
| run(COMPILE_COMMAND) | |
| print('Launching %d coding tasks...' % len(tasks)) | |
| for task, task_settings in tasks.iteritems(): | |
| name = 'bf_rl_iclr' | |
| desc = '{0}.{1}_{2}'.format(args.desc, experiment_settings.name, task) | |
| job_name = '{}.{}'.format(name, desc) | |
| print('Job name: %s' % job_name) | |
| reps = int(args.reps) if not experiment_settings.simplify else 1 | |
| run_cmd = make_run_cmd( | |
| job_name, task, experiment_settings.max_npe, reps, | |
| task_settings.length, experiment_settings.batch_size, | |
| experiment_settings.simplify, | |
| experiment_settings.config) | |
| print('Running command:\n' + run_cmd) | |
| run(run_cmd) | |
| print('Done.') | |
| # pylint: enable=redefined-outer-name | |