From 1aa0eb90e5e1282a3214a120b624d8ea657d8fb8 Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Wed, 6 Oct 2021 17:51:49 -0700 Subject: [PATCH 01/26] anyof --- wikipedia/config.yml | 1 + wikipedia/preprocessing/wiki_api_data.py | 2 +- wikipedia/simulate.py | 81 +++++++++++++++--------- 3 files changed, 52 insertions(+), 32 deletions(-) diff --git a/wikipedia/config.yml b/wikipedia/config.yml index 74128ff..9d082b7 100644 --- a/wikipedia/config.yml +++ b/wikipedia/config.yml @@ -6,6 +6,7 @@ parsed_doc_dir = %(data_dir)s/doc_pkl/ parsed_tmp_dir = %(data_dir)s/parsed_tmp/ diff_dir = %(data_dir)s/diffs/ embedding_dir = %(data_dir)s/embeddings/ +exp_dir = %(data_dir)s/simulation_output/ [files] data_dir = /data/wooders/wikipedia diff --git a/wikipedia/preprocessing/wiki_api_data.py b/wikipedia/preprocessing/wiki_api_data.py index 67235c5..8a3efe1 100644 --- a/wikipedia/preprocessing/wiki_api_data.py +++ b/wikipedia/preprocessing/wiki_api_data.py @@ -15,7 +15,6 @@ from multiprocessing import Pool # from concurrent.futures import ProcessPoolExecutor -from bs4 import BeautifulSoup # from generate diffs file (originally from DPR repo... sorry kevin) from generate_diffs import generate_sentence_level_diffs @@ -23,6 +22,7 @@ def query_recentchanges(start_time, end_time, revision_file): + from bs4 import BeautifulSoup pass diff --git a/wikipedia/simulate.py b/wikipedia/simulate.py index 7b11339..2a0500c 100644 --- a/wikipedia/simulate.py +++ b/wikipedia/simulate.py @@ -45,15 +45,16 @@ class WeightedLoadBalancer(CrossKeyLoadBalancer): # self.key_weights = key_weights def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: - chosen_key = None max_len = 0 + total_len = 0 for key in per_key_queues.keys(): - if per_key_queues[key].size() > max_len: + size = per_key_queues[key].size() + if size > max_len: chosen_key = key - max_len = per_key_queues[key].size() - # print("choose", chosen_key, max_len) - return chosen_key + max_len = size + total_len += size + return chosen_key, total_len class WikiMapper(RalfMapper): @@ -68,6 +69,7 @@ def __init__( super().__init__(env, source_queues, key_selection_policy_cls, model_run_time_s) self.keys = keys + self.source_queues = source_queues # self.env = env # self.source_queues = source_queues @@ -75,34 +77,50 @@ def __init__( # self.model_runtime_s = model_run_time_s # self.env.process(self.run()) - # self.ready_time_to_batch: Dict[float, List[Tuple[int, float]]] = {} + self.ready_time_to_batch: Dict[float, List[Tuple[int, float]]] = {} + + def run(self, replica_id: int): - def run(self): + #this_shard_source_queues = { + # key: self.total_source_queues[key] for key in self.sharded_keys[replica_id] + #} + while True: if self.env.now > 387: break - # windows = yield self.source_queue.get() - chosen_key = self.key_selection_policy.choose(self.source_queues) - - if chosen_key is not None: - - # for chosen_key in self.keys: - windows = yield self.source_queues[chosen_key].get() - print( - f"at time {self.env.now:.2f}, RalfMapper should work on {windows} (last timestamp)" - ) - edits = [(val, chosen_key) for val in windows.window[0].value] - print("edits", edits) - - if self.env.now in self.ready_time_to_batch: - self.ready_time_to_batch[self.env.now] += edits - else: - self.ready_time_to_batch[self.env.now] = edits - - yield self.env.timeout(self.model_runtime_s) - else: # nothing to do - yield self.env.timeout(0.01) + _, total_size_orig = self.key_selection_policy.choose(self.source_queues) + trigger = yield simpy.AnyOf(self.env, [q.get() for q in self.source_queues.values()]) + print("keys", list(trigger.keys())) + print("values", list(trigger.values())) + + + # Add back items to queue (since trigger gets them) + for event in trigger.keys(): + print("add back", event.value.key, event.value) + yield self.source_queues[event.value.key].put(event.value) + + # choose key + chosen_key, total_size = self.key_selection_policy.choose(self.source_queues) + assert chosen_key is not None + + # make sure queue size OK - jk doesn't work with dropping + #assert total_size_orig == 0 or total_size == total_size_orig, f"Bad queue size {total_size_orig} -> {total_size}" + + # get chosen key + windows = yield self.source_queues[chosen_key].get() + print( + f"at time {self.env.now:.2f}, RalfMapper should work on {windows} (last timestamp), queue size {total_size}, wait time {self.model_runtime_s}" + ) + edits = [(val, windows.key) for val in windows.window[0].value] + print("edits", edits) + + if self.env.now in self.ready_time_to_batch: + self.ready_time_to_batch[self.env.now] += edits + else: + self.ready_time_to_batch[self.env.now] = edits + + yield self.env.timeout(self.model_runtime_s) policies = { @@ -188,9 +206,9 @@ def run_once( # policies prioritization_policies = ["fifo", "lifo"] - load_shedding_policies = ["always_process"] - model_runtimes = [0.000001, 0.00001, 0.0000001, 0.000000001, 0] - records_per_second = [100] + load_shedding_policies = ["always_process", "sample_half"] + model_runtimes = [1, 10, 0.01, 0, 0.1, 0.001] + records_per_second = [10] output_files = [] @@ -215,3 +233,4 @@ def run_once( print("DONE", out_path) for f in output_files: print(f) + open("plans.txt", "w").write('\n'.join(output_files)) From ce03916eda685a382952adf35494a907fe4847c8 Mon Sep 17 00:00:00 2001 From: simon-mo Date: Thu, 7 Oct 2021 01:08:57 +0000 Subject: [PATCH 02/26] fix --- wikipedia/config.yml | 12 +++++----- wikipedia/simulate.py | 51 +++++++++++++++++-------------------------- 2 files changed, 26 insertions(+), 37 deletions(-) diff --git a/wikipedia/config.yml b/wikipedia/config.yml index 9d082b7..b13c221 100644 --- a/wikipedia/config.yml +++ b/wikipedia/config.yml @@ -1,5 +1,5 @@ [directory] -data_dir = /data/wooders/wikipedia +data_dir = /home/ubuntu/experiments/wikipedia/result/wikipedia revisions_dir = %(data_dir)s/recentchanges raw_doc_dir = %(data_dir)s/doc_xml/ parsed_doc_dir = %(data_dir)s/doc_pkl/ @@ -9,19 +9,19 @@ embedding_dir = %(data_dir)s/embeddings/ exp_dir = %(data_dir)s/simulation_output/ [files] -data_dir = /data/wooders/wikipedia -raw_questions_file = %(data_dir)s/10052021_questions_revid.csv +data_dir = /home/ubuntu/experiments/wikipedia/result/wikipedia +raw_questions_file = %(data_dir)s/10052021_questions_revid.csv model_file = %(data_dir)s/bert-base-encoder.cp changes_file = %(data_dir)s/changes.csv titles_file = %(data_dir)s/top_titles.csv revisions_file = %(data_dir)s/title_revisions_timestamps.json -edits_file = %(data_dir)s/edits.csv +edits_file = %(data_dir)s/edits.csv questions_file = %(data_dir)s/questions.csv pageview_file = %(data_dir)s/top_title_views.csv [simulation] -data_dir = /data/wooders/wikipedia -plan_dir = /data/wooders/wiki-plans +data_dir = /home/ubuntu/experiments/wikipedia/result/wikipedia +plan_dir = /home/ubuntu/experiments/wikipedia/result/wiki-plans init_data_file = %(data_dir)s/init_data.json stream_edits_file = %(data_dir)s/edit_stream.json stream_questions_file = %(data_dir)s/question_stream.json diff --git a/wikipedia/simulate.py b/wikipedia/simulate.py index 2a0500c..05c75cd 100644 --- a/wikipedia/simulate.py +++ b/wikipedia/simulate.py @@ -81,39 +81,28 @@ def __init__( def run(self, replica_id: int): - #this_shard_source_queues = { - # key: self.total_source_queues[key] for key in self.sharded_keys[replica_id] - #} - + self.source_queues = { + key: self.total_source_queues[key] for key in self.sharded_keys[replica_id] + } + while True: - if self.env.now > 387: - break - - _, total_size_orig = self.key_selection_policy.choose(self.source_queues) - trigger = yield simpy.AnyOf(self.env, [q.get() for q in self.source_queues.values()]) - print("keys", list(trigger.keys())) - print("values", list(trigger.values())) - - - # Add back items to queue (since trigger gets them) - for event in trigger.keys(): - print("add back", event.value.key, event.value) - yield self.source_queues[event.value.key].put(event.value) - + yield simpy.AnyOf(self.env, [q.wait() for q in self.source_queues.values()]) + # choose key - chosen_key, total_size = self.key_selection_policy.choose(self.source_queues) + chosen_key, total_size = self.key_selection_policy.choose( + self.source_queues + ) assert chosen_key is not None # make sure queue size OK - jk doesn't work with dropping - #assert total_size_orig == 0 or total_size == total_size_orig, f"Bad queue size {total_size_orig} -> {total_size}" - - # get chosen key + # assert total_size_orig == 0 or total_size == total_size_orig, f"Bad queue size {total_size_orig} -> {total_size}" + + # get chosen key windows = yield self.source_queues[chosen_key].get() - print( - f"at time {self.env.now:.2f}, RalfMapper should work on {windows} (last timestamp), queue size {total_size}, wait time {self.model_runtime_s}" - ) + # print( + # f"at time {self.env.now:.2f}, RalfMapper should work on {windows} (last timestamp), queue size {total_size}, wait time {self.model_runtime_s}" + # ) edits = [(val, windows.key) for val in windows.window[0].value] - print("edits", edits) if self.env.now in self.ready_time_to_batch: self.ready_time_to_batch[self.env.now] += edits @@ -205,10 +194,10 @@ def run_once( keys = list(init_data.keys()) # policies - prioritization_policies = ["fifo", "lifo"] - load_shedding_policies = ["always_process", "sample_half"] - model_runtimes = [1, 10, 0.01, 0, 0.1, 0.001] - records_per_second = [10] + prioritization_policies = ["fifo"] # ["fifo", "lifo"] + load_shedding_policies = ["always_process"] + model_runtimes = [0] # [0.000001, 0.00001, 0.0000001, 0.000000001, 0] + records_per_second = [100] output_files = [] @@ -233,4 +222,4 @@ def run_once( print("DONE", out_path) for f in output_files: print(f) - open("plans.txt", "w").write('\n'.join(output_files)) + open("plans.txt", "w").write("\n".join(output_files)) From cf0ece14abc38307c16270b75b0dd5212c223030 Mon Sep 17 00:00:00 2001 From: simon-mo Date: Thu, 7 Oct 2021 01:09:30 +0000 Subject: [PATCH 03/26] add aws confg --- wikipedia/config_aws.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 wikipedia/config_aws.yml diff --git a/wikipedia/config_aws.yml b/wikipedia/config_aws.yml new file mode 100644 index 0000000..b13c221 --- /dev/null +++ b/wikipedia/config_aws.yml @@ -0,0 +1,29 @@ +[directory] +data_dir = /home/ubuntu/experiments/wikipedia/result/wikipedia +revisions_dir = %(data_dir)s/recentchanges +raw_doc_dir = %(data_dir)s/doc_xml/ +parsed_doc_dir = %(data_dir)s/doc_pkl/ +parsed_tmp_dir = %(data_dir)s/parsed_tmp/ +diff_dir = %(data_dir)s/diffs/ +embedding_dir = %(data_dir)s/embeddings/ +exp_dir = %(data_dir)s/simulation_output/ + +[files] +data_dir = /home/ubuntu/experiments/wikipedia/result/wikipedia +raw_questions_file = %(data_dir)s/10052021_questions_revid.csv +model_file = %(data_dir)s/bert-base-encoder.cp +changes_file = %(data_dir)s/changes.csv +titles_file = %(data_dir)s/top_titles.csv +revisions_file = %(data_dir)s/title_revisions_timestamps.json +edits_file = %(data_dir)s/edits.csv +questions_file = %(data_dir)s/questions.csv +pageview_file = %(data_dir)s/top_title_views.csv + +[simulation] +data_dir = /home/ubuntu/experiments/wikipedia/result/wikipedia +plan_dir = /home/ubuntu/experiments/wikipedia/result/wiki-plans +init_data_file = %(data_dir)s/init_data.json +stream_edits_file = %(data_dir)s/edit_stream.json +stream_questions_file = %(data_dir)s/question_stream.json + + From 25046b00f8629b9ea96ed39e9d53ae2ddbe4b55f Mon Sep 17 00:00:00 2001 From: simon-mo Date: Thu, 7 Oct 2021 01:10:10 +0000 Subject: [PATCH 04/26] revert --- wikipedia/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wikipedia/config.yml b/wikipedia/config.yml index b13c221..fb35c24 100644 --- a/wikipedia/config.yml +++ b/wikipedia/config.yml @@ -1,5 +1,5 @@ [directory] -data_dir = /home/ubuntu/experiments/wikipedia/result/wikipedia +data_dir = /data/wooders/wikipedia revisions_dir = %(data_dir)s/recentchanges raw_doc_dir = %(data_dir)s/doc_xml/ parsed_doc_dir = %(data_dir)s/doc_pkl/ @@ -9,7 +9,7 @@ embedding_dir = %(data_dir)s/embeddings/ exp_dir = %(data_dir)s/simulation_output/ [files] -data_dir = /home/ubuntu/experiments/wikipedia/result/wikipedia +data_dir = /data/wooders/wikipedia raw_questions_file = %(data_dir)s/10052021_questions_revid.csv model_file = %(data_dir)s/bert-base-encoder.cp changes_file = %(data_dir)s/changes.csv @@ -20,8 +20,8 @@ questions_file = %(data_dir)s/questions.csv pageview_file = %(data_dir)s/top_title_views.csv [simulation] -data_dir = /home/ubuntu/experiments/wikipedia/result/wikipedia -plan_dir = /home/ubuntu/experiments/wikipedia/result/wiki-plans +data_dir = /data/wooders/wikipedia +plan_dir = /data/wooders/wiki-plans init_data_file = %(data_dir)s/init_data.json stream_edits_file = %(data_dir)s/edit_stream.json stream_questions_file = %(data_dir)s/question_stream.json From 2b1b2c0d7edb6335afdc057d6df0d9a0136887b4 Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Wed, 6 Oct 2021 22:15:45 -0700 Subject: [PATCH 05/26] add initial key policies --- wikipedia/config.yml | 3 +- wikipedia/preprocessing/wiki_api_data.py | 24 ++++++ wikipedia/simulate.py | 99 ++++++++++++++++++------ 3 files changed, 101 insertions(+), 25 deletions(-) diff --git a/wikipedia/config.yml b/wikipedia/config.yml index fb35c24..26fbd66 100644 --- a/wikipedia/config.yml +++ b/wikipedia/config.yml @@ -17,7 +17,8 @@ titles_file = %(data_dir)s/top_titles.csv revisions_file = %(data_dir)s/title_revisions_timestamps.json edits_file = %(data_dir)s/edits.csv questions_file = %(data_dir)s/questions.csv -pageview_file = %(data_dir)s/top_title_views.csv +raw_pageview_file = %(data_dir)s/top_title_views.csv +pageview_file = %(data_dir)s/pageviews.csv [simulation] data_dir = /data/wooders/wikipedia diff --git a/wikipedia/preprocessing/wiki_api_data.py b/wikipedia/preprocessing/wiki_api_data.py index 8a3efe1..fa1ce90 100644 --- a/wikipedia/preprocessing/wiki_api_data.py +++ b/wikipedia/preprocessing/wiki_api_data.py @@ -116,6 +116,24 @@ def get_questions(raw_questions_file, questions_file): questions_df.to_csv(questions_file) return questions_df +def get_pageviews(raw_pageview_file, pageview_file, edits_file): + + edits_df = pd.read_csv(edits_file) + pageview_df = pd.read_csv(raw_pageview_file) + + # map title -> id + title_to_id = edits_df.set_index("title")["pageid"].to_dict() + open("title_to_id.json", "w").write(json.dumps(title_to_id)) + + # calculate page weights + total_views = pageview_df.iloc[:, 2:].sum(axis=1).sum() + weights = pageview_df.iloc[:, 2:].sum(axis=1) / total_views + pageview_df['weights'] = weights + pageview_df['doc_id'] = pageview_df['title'].apply(lambda x: title_to_id[x]) + pageview_df.to_csv(pageview_file) + + return pageview_df + # create diff JSON file from valid list of revision pairs, doc pkl def create_diff_json(doc_pkl, rev_pairs, diff_dir): @@ -578,6 +596,7 @@ def check_dataset( "--run_parse_docs", action="store_true", default=False ) # re-parse document versions parser.add_argument("--run_get_questions", action="store_true", default=False) + parser.add_argument("--run_get_pageviews", action="store_true", default=False) parser.add_argument( "--run_generate_diffs", action="store_true", default=False ) # re-process generating diffs @@ -605,6 +624,7 @@ def check_dataset( edits_file = config["files"]["edits_file"] raw_questions_file = config["files"]["raw_questions_file"] questions_file = config["files"]["questions_file"] + raw_pageview_file = config["files"]["raw_pageview_file"] pageview_file = config["files"]["pageview_file"] # simulation data @@ -647,6 +667,10 @@ def check_dataset( questions_df = get_questions(raw_questions_file, questions_file) print("Generated questions file", questions_file) + # generate pageviews / compute page weights + if args.run_get_pageviews: + get_pageviews(raw_pageview_file, pageview_file, edits_file) + # generate diffs between document versions if args.run_generate_diffs: # if not os.path.isdir(diff_dir): diff --git a/wikipedia/simulate.py b/wikipedia/simulate.py index 05c75cd..fc5193f 100644 --- a/wikipedia/simulate.py +++ b/wikipedia/simulate.py @@ -3,6 +3,7 @@ from collections import defaultdict from dataclasses import dataclass from functools import cmp_to_key +import random import configparser @@ -40,9 +41,53 @@ class WeightedLoadBalancer(CrossKeyLoadBalancer): - # def __init__(self, keys, key_weights): - # self.keys = keys - # self.key_weights = key_weights + def __init__(self, pageview_file): + pageview_df = pd.read_csv(pageview_file) + self.weights = pageview_df.set_index("doc_id")["weights"].to_dict() + print(self.weights) + + def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: + chosen_key = None + max_len = 0 + total_len = 0 + keys = [] + weights = [] + for key in per_key_queues.keys(): + size = per_key_queues[key].size() + if size >= 1 and int(key) in self.weights: + keys.append(key) + weights.append(self.weights[int(key)]) + total_len += size + + chosen_key = random.choices(keys, weights, k=1)[0] + #print("choose", chosen_key, keys, weights) + return chosen_key, total_len + +class WeightedLongestQueueLoadBalancer(CrossKeyLoadBalancer): + + def __init__(self, pageview_file): + pageview_df = pd.read_csv(pageview_file) + self.weights = pageview_df.set_index("doc_id")["weights"].to_dict() + print(self.weights) + + def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: + chosen_key = None + max_len = 0 + total_len = 0 + for key in per_key_queues.keys(): + size = per_key_queues[key].size() + if int(key) not in self.weights: + continue + weighted_size = self.weights[int(key)] + if weighted_size > max_len: + chosen_key = key + max_len = size + total_len += size + print(chosen_key, max_len, self.weights[int(chosen_key)]) + return chosen_key, total_len + + +class LongestQueueLoadBalancer(CrossKeyLoadBalancer): def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: chosen_key = None @@ -129,6 +174,7 @@ def run_once( total_runtime_s: float, model_runtime_constant: float, data_file: str = None, + weights_file: str = None ): env = simpy.Environment() @@ -164,7 +210,7 @@ def run_once( env, source_queues=windows_to_mapper_queue, model_run_time_s=model_runtime_constant, - key_selection_policy_cls=WeightedLoadBalancer, + key_selection_policy_cls=WeightedLongestQueueLoadBalancer(weights_file), keys=keys, ) env.run(until=total_runtime_s) @@ -187,6 +233,7 @@ def run_once( init_data_file = config["simulation"]["init_data_file"] stream_edits_file = config["simulation"]["stream_edits_file"] stream_questions_file = config["simulation"]["stream_questions_file"] + pageview_file = config["files"]["pageview_file"] # load simulation data edits = json.load(open(stream_edits_file)) @@ -195,31 +242,35 @@ def run_once( # policies prioritization_policies = ["fifo"] # ["fifo", "lifo"] + key_selection_policies = ["pageview"] load_shedding_policies = ["always_process"] - model_runtimes = [0] # [0.000001, 0.00001, 0.0000001, 0.000000001, 0] + model_runtimes = [0.1] # [0.000001, 0.00001, 0.0000001, 0.000000001, 0] records_per_second = [100] output_files = [] - for prio_policy in prioritization_policies: - for load_shed_policy in load_shedding_policies: - for runtime in model_runtimes: - for rate in records_per_second: - - out_path = f"{plan_dir}/plan-{prio_policy}-{load_shed_policy}-{runtime}-{rate}.json" - print("running", out_path, runtime) - run_once( - out_path, - prio_policy, - load_shed_policy, - keys, - per_key_records_per_second=rate, - total_runtime_s=len(edits), - model_runtime_constant=runtime, - data_file=stream_edits_file, - ) - output_files.append(out_path) - print("DONE", out_path) + for key_selection in key_selection_policies: + for prio_policy in prioritization_policies: + for load_shed_policy in load_shedding_policies: + for runtime in model_runtimes: + for rate in records_per_second: + + out_path = f"{plan_dir}/plan-{key_selection}_{prio_policy}-{load_shed_policy}-{runtime}-{rate}.json" + print("running", out_path, runtime) + run_once( + out_path, + prio_policy, + load_shed_policy, + keys, + per_key_records_per_second=rate, + total_runtime_s=len(edits), + model_runtime_constant=runtime, + data_file=stream_edits_file, + weights_file=pageview_file, + ) + + output_files.append(out_path) + print("DONE", out_path) for f in output_files: print(f) open("plans.txt", "w").write("\n".join(output_files)) From 63c52239bc2be4c7513f2765f9f6b38071c127fd Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Thu, 7 Oct 2021 13:30:57 -0700 Subject: [PATCH 06/26] add key selection policy options --- stl/scratch.ipynb | 32 ++++---- wikipedia/config.yml | 2 +- wikipedia/preprocessing/wiki_api_data.py | 2 +- wikipedia/simulate.py | 96 +++++++++++++++++------- 4 files changed, 87 insertions(+), 45 deletions(-) diff --git a/stl/scratch.ipynb b/stl/scratch.ipynb index 962bf16..2334fd9 100644 --- a/stl/scratch.ipynb +++ b/stl/scratch.ipynb @@ -3,33 +3,33 @@ { "cell_type": "code", "execution_count": null, - "source": [], + "metadata": {}, "outputs": [], - "metadata": {} + "source": [] } ], "metadata": { - "orig_nbformat": 4, + "interpreter": { + "hash": "a10b01f403a1542ddbe951c0fc128eb6a019580013b1191ba1a82a0d150f03e0" + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, "language_info": { - "name": "python", - "version": "3.7.10", - "mimetype": "text/x-python", "codemirror_mode": { "name": "ipython", "version": 3 }, - "pygments_lexer": "ipython3", + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", "nbconvert_exporter": "python", - "file_extension": ".py" - }, - "kernelspec": { - "name": "python3", - "display_name": "Python 3.7.10 64-bit ('ralf': conda)" - }, - "interpreter": { - "hash": "a10b01f403a1542ddbe951c0fc128eb6a019580013b1191ba1a82a0d150f03e0" + "pygments_lexer": "ipython3", + "version": "3.7.10" } }, "nbformat": 4, "nbformat_minor": 2 -} \ No newline at end of file +} diff --git a/wikipedia/config.yml b/wikipedia/config.yml index 26fbd66..78d42d8 100644 --- a/wikipedia/config.yml +++ b/wikipedia/config.yml @@ -10,7 +10,7 @@ exp_dir = %(data_dir)s/simulation_output/ [files] data_dir = /data/wooders/wikipedia -raw_questions_file = %(data_dir)s/10052021_questions_revid.csv +raw_questions_file = %(data_dir)s/10062021_filtered_questions.csv model_file = %(data_dir)s/bert-base-encoder.cp changes_file = %(data_dir)s/changes.csv titles_file = %(data_dir)s/top_titles.csv diff --git a/wikipedia/preprocessing/wiki_api_data.py b/wikipedia/preprocessing/wiki_api_data.py index fa1ce90..2a1a718 100644 --- a/wikipedia/preprocessing/wiki_api_data.py +++ b/wikipedia/preprocessing/wiki_api_data.py @@ -665,7 +665,7 @@ def check_dataset( # get questions if args.run_get_questions: questions_df = get_questions(raw_questions_file, questions_file) - print("Generated questions file", questions_file) + print("Generated questions file", raw_questions_file, questions_file) # generate pageviews / compute page weights if args.run_get_pageviews: diff --git a/wikipedia/simulate.py b/wikipedia/simulate.py index fc5193f..11e477f 100644 --- a/wikipedia/simulate.py +++ b/wikipedia/simulate.py @@ -44,7 +44,7 @@ class WeightedLoadBalancer(CrossKeyLoadBalancer): def __init__(self, pageview_file): pageview_df = pd.read_csv(pageview_file) self.weights = pageview_df.set_index("doc_id")["weights"].to_dict() - print(self.weights) + #print(self.weights) def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: chosen_key = None @@ -63,12 +63,29 @@ def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: #print("choose", chosen_key, keys, weights) return chosen_key, total_len +class RandomLoadBalancer(CrossKeyLoadBalancer): + + def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: + chosen_key = None + max_len = 0 + total_len = 0 + keys = [] + for key in per_key_queues.keys(): + size = per_key_queues[key].size() + if size >= 1: + keys.append(key) + total_len += size + + chosen_key = random.choices(keys, k=1)[0] + return chosen_key, total_len + + class WeightedLongestQueueLoadBalancer(CrossKeyLoadBalancer): def __init__(self, pageview_file): pageview_df = pd.read_csv(pageview_file) self.weights = pageview_df.set_index("doc_id")["weights"].to_dict() - print(self.weights) + #print(self.weights) def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: chosen_key = None @@ -83,9 +100,32 @@ def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: chosen_key = key max_len = size total_len += size - print(chosen_key, max_len, self.weights[int(chosen_key)]) + #print(chosen_key, max_len, self.weights[int(chosen_key)]) return chosen_key, total_len +class WeightedLoadBalancer(CrossKeyLoadBalancer): + + def __init__(self, pageview_file): + pageview_df = pd.read_csv(pageview_file) + self.weights = pageview_df.set_index("doc_id")["weights"].to_dict() + #print(self.weights) + + def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: + chosen_key = None + max_len = 0 + total_len = 0 + keys = [] + weights = [] + for key in per_key_queues.keys(): + size = per_key_queues[key].size() + if size >= 1 and int(key) in self.weights: + keys.append(key) + weights.append(self.weights[int(key)]) + total_len += size + + chosen_key = random.choices(keys, weights, k=1)[0] + #print("choose", chosen_key, keys, weights) + return chosen_key, total_len class LongestQueueLoadBalancer(CrossKeyLoadBalancer): @@ -157,11 +197,30 @@ def run(self, replica_id: int): yield self.env.timeout(self.model_runtime_s) +# configuration file +config = configparser.ConfigParser() +config.read("config.yml") +plan_dir = config["simulation"]["plan_dir"] +init_data_file = config["simulation"]["init_data_file"] +stream_edits_file = config["simulation"]["stream_edits_file"] +stream_questions_file = config["simulation"]["stream_questions_file"] +pageview_file = config["files"]["pageview_file"] + +# load simulation data +edits = json.load(open(stream_edits_file)) +init_data = json.load(open(init_data_file)) +keys = list(init_data.keys()) + policies = { "fifo": fifo, "lifo": lifo, "always_process": always_process, "sample_half": make_sampling_policy(0.5), + "weighted_random": WeightedLoadBalancer(pageview_file), + "weighted_longest_queue": WeightedLongestQueueLoadBalancer(pageview_file), + "longest_queue": LongestQueueLoadBalancer(), + "random": RandomLoadBalancer(), + "round_robin": RoundRobinLoadBalancer() } @@ -173,8 +232,7 @@ def run_once( per_key_records_per_second: int, total_runtime_s: float, model_runtime_constant: float, - data_file: str = None, - weights_file: str = None + key_selection_policy: str ): env = simpy.Environment() @@ -195,7 +253,7 @@ def run_once( num_keys=len(keys), next_queue=source_to_window_queue, total_run_time=total_runtime_s, - data_file=data_file, + data_file=stream_edits_file, ) WindowOperator( @@ -210,7 +268,7 @@ def run_once( env, source_queues=windows_to_mapper_queue, model_run_time_s=model_runtime_constant, - key_selection_policy_cls=WeightedLongestQueueLoadBalancer(weights_file), + key_selection_policy_cls=policies[key_selection_policy], keys=keys, ) env.run(until=total_runtime_s) @@ -225,26 +283,11 @@ def run_once( # load sheding: random, drop short edits # prioritization: prioritize most recent version # cross-key prioritzation: historical page views, - - # configuration file - config = configparser.ConfigParser() - config.read("config.yml") - plan_dir = config["simulation"]["plan_dir"] - init_data_file = config["simulation"]["init_data_file"] - stream_edits_file = config["simulation"]["stream_edits_file"] - stream_questions_file = config["simulation"]["stream_questions_file"] - pageview_file = config["files"]["pageview_file"] - - # load simulation data - edits = json.load(open(stream_edits_file)) - init_data = json.load(open(init_data_file)) - keys = list(init_data.keys()) - # policies - prioritization_policies = ["fifo"] # ["fifo", "lifo"] - key_selection_policies = ["pageview"] + prioritization_policies = ["lifo", "fifo"] # ["fifo", "lifo"] + key_selection_policies = ["weighted_random", "weighted_longest_queue", "longest_queue", "random", "round_robin"] load_shedding_policies = ["always_process"] - model_runtimes = [0.1] # [0.000001, 0.00001, 0.0000001, 0.000000001, 0] + model_runtimes = [0.01, 0.1, 1, 5, 10] # [0.000001, 0.00001, 0.0000001, 0.000000001, 0] records_per_second = [100] output_files = [] @@ -265,8 +308,7 @@ def run_once( per_key_records_per_second=rate, total_runtime_s=len(edits), model_runtime_constant=runtime, - data_file=stream_edits_file, - weights_file=pageview_file, + key_selection_policy=key_selection, ) output_files.append(out_path) From 60c75f51c2ed8fd73ebf0e3ccaba3880fb98ff60 Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Thu, 7 Oct 2021 13:37:43 -0700 Subject: [PATCH 07/26] only return key --- wikipedia/simulate.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/wikipedia/simulate.py b/wikipedia/simulate.py index 11e477f..d7361ce 100644 --- a/wikipedia/simulate.py +++ b/wikipedia/simulate.py @@ -61,7 +61,7 @@ def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: chosen_key = random.choices(keys, weights, k=1)[0] #print("choose", chosen_key, keys, weights) - return chosen_key, total_len + return chosen_key class RandomLoadBalancer(CrossKeyLoadBalancer): @@ -77,7 +77,7 @@ def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: total_len += size chosen_key = random.choices(keys, k=1)[0] - return chosen_key, total_len + return chosen_key class WeightedLongestQueueLoadBalancer(CrossKeyLoadBalancer): @@ -101,7 +101,7 @@ def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: max_len = size total_len += size #print(chosen_key, max_len, self.weights[int(chosen_key)]) - return chosen_key, total_len + return chosen_key class WeightedLoadBalancer(CrossKeyLoadBalancer): @@ -125,7 +125,7 @@ def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: chosen_key = random.choices(keys, weights, k=1)[0] #print("choose", chosen_key, keys, weights) - return chosen_key, total_len + return chosen_key class LongestQueueLoadBalancer(CrossKeyLoadBalancer): @@ -139,7 +139,7 @@ def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: chosen_key = key max_len = size total_len += size - return chosen_key, total_len + return chosen_key class WikiMapper(RalfMapper): @@ -174,7 +174,7 @@ def run(self, replica_id: int): yield simpy.AnyOf(self.env, [q.wait() for q in self.source_queues.values()]) # choose key - chosen_key, total_size = self.key_selection_policy.choose( + chosen_key = self.key_selection_policy.choose( self.source_queues ) assert chosen_key is not None From 1220cdd2a38d5b313e97279bc8050bb8937b4393 Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Thu, 7 Oct 2021 22:45:12 -0700 Subject: [PATCH 08/26] start implementing time-specific weights --- stl/offline/evaluation.py | 34 ++++++++-- stl/offline/run_2_eval_yahoo_keys.sh | 11 ++- stl/offline/simulation.py | 24 +++++-- wikipedia/config.yml | 1 + wikipedia/preprocessing/wiki_api_data.py | 19 +++++- wikipedia/simulate.py | 85 ++++++++++++++++++++++-- wikipedia/wiki_eval.py | 17 +++-- 7 files changed, 158 insertions(+), 33 deletions(-) diff --git a/stl/offline/evaluation.py b/stl/offline/evaluation.py index 92ff30b..067003e 100644 --- a/stl/offline/evaluation.py +++ b/stl/offline/evaluation.py @@ -37,14 +37,10 @@ def predict(event, model): SEASONALITY = 24 * 7 -def offline_eval(yahoo_csv_path, plan_json_path): +def offline_eval(yahoo_csv_path, plan_df): df = pd.read_csv(yahoo_csv_path) df["timestamp"] = list(range(len(df))) - # Headers - # processing_time window_start_seq_id window_end_seq_id key - plan_df = pd.read_json(plan_json_path) - # Given our model versions from offline plan, run training on corresponding # events. offline_stl = {} @@ -98,6 +94,24 @@ def find_freshest_model_version(event_time, model_versions): df[new_col] = add_df[new_col] return df +def offline_eval_all(yahoo_path): + + policy_plan_path = "/data/wooders/eurosys-results/10-05/stl-offline/result/offline_1_slide/min_loss_plan.json" + policy_params = json.load(open(policy_plan_path)) + plan_df = pd.read_csv(plan_json_path) + + # loop through each key + for key in policy_params.keys(): + output_file = "output_{key}.csv" + print(key, output_file) + plan_df_key = plan_df[plan_df["key"] == key] + csv_path = f"{key}.csv" + df = offline_eval(csv_path, plan_df_key) + df.to_csv(output_file) + + return + + def offline_oracle(yahoo_csv_path): df = pd.read_csv(yahoo_csv_path) @@ -117,8 +131,16 @@ def offline_oracle(yahoo_csv_path): def run_exp(csv_path, plan_path, output_path, run_oracle=False): if run_oracle: df = offline_oracle(csv_path) + elif run_policy: + offline_eval_all(csv_path) else: - df = offline_eval(csv_path, plan_path) + + # Headers + # processing_time window_start_seq_id window_end_seq_id key + plan_df = pd.read_json(plan_json_path) + + df = offline_eval(csv_path, plan_df) + df.to_csv(output_path, index=None) diff --git a/stl/offline/run_2_eval_yahoo_keys.sh b/stl/offline/run_2_eval_yahoo_keys.sh index 1d9865e..444da55 100644 --- a/stl/offline/run_2_eval_yahoo_keys.sh +++ b/stl/offline/run_2_eval_yahoo_keys.sh @@ -1,17 +1,14 @@ set -ex -data_dir="/home/ubuntu/ydata-labeled-time-series-anomalies-v1_0/A4Benchmark/" +data_dir="/data/wooders/stl/yahoo" -tmp_script=`mktemp` -for data in `ls $data_dir/A4Benchmark-TS*` +for data in `ls $data_dir/A4/*` do key=`basename $data` for slide in 6 12 18 24 48 96 168 192 336 672 do - echo python evaluation.py --offline-yahoo-csv-path $data \ + python evaluation.py --offline-yahoo-csv-path $data \ --offline-plan-path ./result/offline_1_slide/plan/slide_${slide}_plan.json \ - --output-path ./result/offline_1_slide/plan_eval/slide_${slide}_key_${key} >> $tmp_script + --output-path ./result/offline_1_slide/plan_eval/slide_${slide}_key_${key} done done - -cat $tmp_script | parallel --bar bash -l -c \ No newline at end of file diff --git a/stl/offline/simulation.py b/stl/offline/simulation.py index 41461bb..2039983 100644 --- a/stl/offline/simulation.py +++ b/stl/offline/simulation.py @@ -63,7 +63,7 @@ None, "path to generated per key's window slide size config.", ) -flags.DEFINE_integer("num_mapper_replicas", None, "number of replicas for mapper") +flags.DEFINE_integer("num_mapper_replicas", 1, "number of replicas for mapper") def _get_config() -> Dict: @@ -74,14 +74,22 @@ def _get_config() -> Dict: def main(argv): env = simpy.Environment() # source --source_to_window_queue--> window --windows_to_mapper_queue--> mapper + + policy_plan_path = "/data/wooders/eurosys-results/10-05/stl-offline/result/offline_1_slide/min_loss_plan.json" + policy_params = json.load(open(policy_plan_path)) + + keys = policy_params.keys() + print(keys) + source_to_window_queue = simpy.Store(env) windows_to_mapper_queue = { - i: PerKeyPriorityQueue( + key: PerKeyPriorityQueue( env, processing_policy=prio_policies[FLAGS.key_prio_policy], load_shedding_policy=load_shed_policies[FLAGS.key_load_shed_policy], ) - for i in range(FLAGS.num_keys) + #for i in range(FLAGS.num_keys) + for key in keys } Source( env, @@ -89,13 +97,15 @@ def main(argv): num_keys=FLAGS.num_keys, next_queue=source_to_window_queue, total_run_time=FLAGS.total_runtime_s, - data_file=FLAGS.source_data_path, + keys=keys, + data_dir="/data/wooders/stl/yahoo/A4", + #data_file=FLAGS.source_data_path, ) WindowOperator( env, window_size=FLAGS.window_size, slide_size=FLAGS.slide_size, - per_key_slide_size_path=FLAGS.per_key_slide_size_plan, + per_key_slide_size_path=policy_plan_path, source_queue=source_to_window_queue, next_queues=windows_to_mapper_queue, ) @@ -104,7 +114,7 @@ def main(argv): source_queues=windows_to_mapper_queue, model_run_time_s=FLAGS.model_runtime_s, # TODO(simon): customize this once we want different key selection policy - key_selection_policy_cls=RoundRobinLoadBalancer, + key_selection_policy_cls=RoundRobinLoadBalancer(), num_replicas=FLAGS.num_mapper_replicas, ) env.run(until=FLAGS.total_runtime_s) @@ -112,7 +122,7 @@ def main(argv): plan = m.plan config = _get_config() if FLAGS.output_path: - os.makedirs(os.path.split(FLAGS.output_path)[0], exist_ok=True) + #os.makedirs(os.path.split(FLAGS.output_path)[0], exist_ok=True) with open(FLAGS.output_path, "w") as f: json.dump(plan, f, indent=2) with open(FLAGS.output_path + ".config.json", "w") as f: diff --git a/wikipedia/config.yml b/wikipedia/config.yml index 78d42d8..c6bb8a1 100644 --- a/wikipedia/config.yml +++ b/wikipedia/config.yml @@ -19,6 +19,7 @@ edits_file = %(data_dir)s/edits.csv questions_file = %(data_dir)s/questions.csv raw_pageview_file = %(data_dir)s/top_title_views.csv pageview_file = %(data_dir)s/pageviews.csv +timestamp_weights_file = %(data_dir)s/timestamp_weights_file.json [simulation] data_dir = /data/wooders/wikipedia diff --git a/wikipedia/preprocessing/wiki_api_data.py b/wikipedia/preprocessing/wiki_api_data.py index 2a1a718..4928566 100644 --- a/wikipedia/preprocessing/wiki_api_data.py +++ b/wikipedia/preprocessing/wiki_api_data.py @@ -4,6 +4,7 @@ import json from tqdm import tqdm from collections import defaultdict +from datetime import datetime import subprocess import configparser @@ -116,7 +117,7 @@ def get_questions(raw_questions_file, questions_file): questions_df.to_csv(questions_file) return questions_df -def get_pageviews(raw_pageview_file, pageview_file, edits_file): +def get_pageviews(raw_pageview_file, pageview_file, edits_file, timestamp_weights_file): edits_df = pd.read_csv(edits_file) pageview_df = pd.read_csv(raw_pageview_file) @@ -132,6 +133,19 @@ def get_pageviews(raw_pageview_file, pageview_file, edits_file): pageview_df['doc_id'] = pageview_df['title'].apply(lambda x: title_to_id[x]) pageview_df.to_csv(pageview_file) + # page weights per timestamp + ts_to_weights = {} + dates = pageview_df.columns[2:-2] + for date in dates: + print(date) + dt = datetime.strptime(date[:-2], '%Y%m%d') + ts = dt.timestamp() * 1000000000 + ts_min = assign_timestamps_min(ts) + view_counts = pageview_df[date].tolist() + id_to_count = pageview_df.set_index("doc_id")[date].to_dict() + ts_to_weights[ts_min] = id_to_count + open(timestamp_weights_file, "w").write(json.dumps(ts_to_weights)) + print("Generated ts weights file", timestamp_weights_file) return pageview_df @@ -626,6 +640,7 @@ def check_dataset( questions_file = config["files"]["questions_file"] raw_pageview_file = config["files"]["raw_pageview_file"] pageview_file = config["files"]["pageview_file"] + timestamp_weights_file = config["files"]["timestamp_weights_file"] # simulation data init_data_file = config["simulation"]["init_data_file"] @@ -669,7 +684,7 @@ def check_dataset( # generate pageviews / compute page weights if args.run_get_pageviews: - get_pageviews(raw_pageview_file, pageview_file, edits_file) + get_pageviews(raw_pageview_file, pageview_file, edits_file, timestamp_weights_file) # generate diffs between document versions if args.run_generate_diffs: diff --git a/wikipedia/simulate.py b/wikipedia/simulate.py index d7361ce..92e71fc 100644 --- a/wikipedia/simulate.py +++ b/wikipedia/simulate.py @@ -1,4 +1,5 @@ import json +import itertools from typing import DefaultDict, Dict, List, Optional, Tuple from collections import defaultdict from dataclasses import dataclass @@ -38,6 +39,62 @@ from typing import Dict, List, Tuple, Type +class RoundRobinLoadBalancerFix(CrossKeyLoadBalancer): + """Simple policy that cycle through all the keys fairly""" + + def __init__(self): + self.cur_key_set = set() + self.cur_key_iter = None + + def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: + key_set = set(per_key_queues.keys()) + if key_set != self.cur_key_set: + self.cur_key_set = key_set + self.cur_key_iter = itertools.cycle(key_set) + + key = next(self.cur_key_iter) + while per_key_queues[key].size() == 0: + key = next(self.cur_key_iter) + # TODO(simon): maybe do a "peak" here to trigger eviction policies + return key + + +class WeightedRoundRobin(CrossKeyLoadBalancer): + """Simple policy that cycle through all the keys fairly""" + + def __init__(self, pageview_file, all_keys): + self.cur_key_set = [] + self.cur_key_iter = None + pageview_df = pd.read_csv(pageview_file) + self.raw_weights = pageview_df.set_index("doc_id")["weights"].to_dict() + self.weights = {} + for key in self.raw_weights.keys(): + if str(key) not in all_keys: + continue + + self.weights[key] = int(self.raw_weights[key]*1000) + assert self.weights[key] > 0, f"Too small {key}, {self.raw_weights[key]}" + print(self.weights) + + + for key in self.weights.keys(): + for i in range(self.weights[key]): + self.cur_key_set.append(str(key)) + random.shuffle(self.cur_key_set) + print(self.cur_key_set) + print("size", len(self.cur_key_set)) + self.cur_key_iter = itertools.cycle(self.cur_key_set) + + + def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: + + key = next(self.cur_key_iter) + while per_key_queues[key].size() == 0: + key = next(self.cur_key_iter) + # TODO(simon): maybe do a "peak" here to trigger eviction policies + return key + + class WeightedLoadBalancer(CrossKeyLoadBalancer): @@ -95,12 +152,14 @@ def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: size = per_key_queues[key].size() if int(key) not in self.weights: continue - weighted_size = self.weights[int(key)] + weighted_size = self.weights[int(key)]*self.weights[int(key)] if weighted_size > max_len: chosen_key = key max_len = size total_len += size #print(chosen_key, max_len, self.weights[int(chosen_key)]) + per_key_queues[chosen_key].clear() + print("clear", chosen_key, total_len, per_key_queues[chosen_key].size()) return chosen_key class WeightedLoadBalancer(CrossKeyLoadBalancer): @@ -139,6 +198,9 @@ def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: chosen_key = key max_len = size total_len += size + per_key_queues[chosen_key].clear() + print("clear", chosen_key, total_len, per_key_queues[chosen_key].size()) + return chosen_key @@ -210,6 +272,7 @@ def run(self, replica_id: int): edits = json.load(open(stream_edits_file)) init_data = json.load(open(init_data_file)) keys = list(init_data.keys()) +ts_to_weights = json.load(open(config["files"]["weights"])) policies = { "fifo": fifo, @@ -220,10 +283,22 @@ def run(self, replica_id: int): "weighted_longest_queue": WeightedLongestQueueLoadBalancer(pageview_file), "longest_queue": LongestQueueLoadBalancer(), "random": RandomLoadBalancer(), - "round_robin": RoundRobinLoadBalancer() + "round_robin": RoundRobinLoadBalancer(), + "round_robin_fix": RoundRobinLoadBalancerFix(), + "weighted_round_robin": WeightedRoundRobin(pageview_file, keys) } +def current_weights(ts): + min_dist = max(list(ts_to_weights.keys())) + weights = None + + for key in ts_to_weights.keys(): + if abs(ts - key) <= min_dist: + min_dist = abs(ts - key) + weights = ts_to_weights[key] + return weights + def run_once( out_path: str, prioritization_policy: str, @@ -284,10 +359,10 @@ def run_once( # prioritization: prioritize most recent version # cross-key prioritzation: historical page views, # policies - prioritization_policies = ["lifo", "fifo"] # ["fifo", "lifo"] - key_selection_policies = ["weighted_random", "weighted_longest_queue", "longest_queue", "random", "round_robin"] + prioritization_policies = ["lifo"] # ["fifo", "lifo"] + key_selection_policies = ["weighted_round_robin", "weighted_random", "weighted_longest_queue", "longest_queue", "random", "round_robin", "round_robin_fix"] load_shedding_policies = ["always_process"] - model_runtimes = [0.01, 0.1, 1, 5, 10] # [0.000001, 0.00001, 0.0000001, 0.000000001, 0] + model_runtimes = [5] #, 1, 5, 10] # [0.000001, 0.00001, 0.0000001, 0.000000001, 0] records_per_second = [100] output_files = [] diff --git a/wikipedia/wiki_eval.py b/wikipedia/wiki_eval.py index c47d2ff..cdb587d 100644 --- a/wikipedia/wiki_eval.py +++ b/wikipedia/wiki_eval.py @@ -170,6 +170,7 @@ def offline_eval(plan_json_path, exp_id, compute_embeddings=True): # compute initial passage embeddings for each document init_data = json.load(open(init_data_file)) init_state = {} + staleness = [] for key in tqdm(init_data.keys()): if filter_keys and key not in keys: @@ -210,7 +211,7 @@ def offline_eval(plan_json_path, exp_id, compute_embeddings=True): for version in tqdm(embed_version_keys): state = {} for task in plan[version]: - print("task", task, version) + #print("task", task, version) rev_file = task[0] doc_id = task[1] # doc_id = task[2] @@ -266,7 +267,7 @@ def get_latest_embedding(timestep, doc_id): and doc_id in embed_versions[str(version)] ): latest = version - print(doc_id, "latest", timestep, latest, timestep - latest) + #print(doc_id, "latest", timestep, latest, timestep - latest) assert ( doc_id in embed_versions[str(latest)] ), f"Missing doc id {doc_id} {latest} {doc_id in init_data}" @@ -305,6 +306,11 @@ def get_latest_embedding(timestep, doc_id): # print(init_data.keys()) continue + # get current embedding and write + passage_texts, passage_embeddings, version, latest = get_latest_embedding( + timestep, doc_id + ) + # loop through questions doc_questions = questions[ts][doc_id] queries = [] @@ -319,10 +325,8 @@ def get_latest_embedding(timestep, doc_id): ), f"time mismatch {q['ts_min']}, {timestep}, {ts}" queries.append([question, [answer], doc_id]) - # get current embedding and write - passage_texts, passage_embeddings, version, latest = get_latest_embedding( - timestep, doc_id - ) + # append per query + staleness.append(timestep - latest) # dump CTX/question script contex_file = f"{directory}/dpr_ctx_after_{int(ts)}_{doc_id}" @@ -349,6 +353,7 @@ def get_latest_embedding(timestep, doc_id): assert len(passage_embeddings) == len(passage_texts) print("done processing queries!", len(questions)) + print("staleness", np.array(staleness).mean()) return directory From 754ccc82f2633a03c1642ee89028d424a2b31a5e Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Fri, 8 Oct 2021 14:16:22 -0700 Subject: [PATCH 09/26] plan-level simulation --- stl/offline/config_gen.py | 2 +- stl/offline/evaluation.py | 46 +++++++++++----- stl/offline/simulation.py | 4 +- wikipedia/simulate.py | 112 ++++++++++++++++++++++++++++++-------- 4 files changed, 124 insertions(+), 40 deletions(-) diff --git a/stl/offline/config_gen.py b/stl/offline/config_gen.py index 6e52b11..0248638 100644 --- a/stl/offline/config_gen.py +++ b/stl/offline/config_gen.py @@ -95,7 +95,7 @@ def run_lp(df: pd.DataFrame, max_n_fits=None, max_loss=None, objective="min_loss return plan_output, optimal_loss -def get_loss_per_key(key: int, csv_dir): +def get_loss_per_key(key: int, csv_dir) key_one = glob(f"{csv_dir}/slide_*_key_A4Benchmark-TS{key}.csv") assert len(key_one) > 0 diff --git a/stl/offline/evaluation.py b/stl/offline/evaluation.py index 067003e..a0cbde2 100644 --- a/stl/offline/evaluation.py +++ b/stl/offline/evaluation.py @@ -1,7 +1,8 @@ import argparse +import json import os import bisect - +from tqdm import tqdm import numpy as np import pandas as pd from statsmodels.tsa.seasonal import STL @@ -38,14 +39,16 @@ def predict(event, model): def offline_eval(yahoo_csv_path, plan_df): + print(yahoo_csv_path) df = pd.read_csv(yahoo_csv_path) df["timestamp"] = list(range(len(df))) # Given our model versions from offline plan, run training on corresponding # events. offline_stl = {} - for _, row in plan_df.iterrows(): - records = df.iloc[row.window_start_seq_id : row.window_end_seq_id + 1].to_dict( + print(plan_df) + for _, row in tqdm(plan_df.iterrows()): # note: doesn't preserve types + records = df.iloc[int(row.window_start_seq_id) : int(row.window_end_seq_id) + 1].to_dict( orient="records" ) @@ -54,6 +57,8 @@ def offline_eval(yahoo_csv_path, plan_df): trained = train(records, window_size=len(records), seasonality=SEASONALITY) offline_stl[row.processing_time] = trained + print(offline_stl) + # Assign the trained model with every events in the source file. def find_freshest_model_version(event_time, model_versions): model_loc = bisect.bisect_left(model_versions, event_time) - 1 @@ -66,6 +71,7 @@ def find_freshest_model_version(event_time, model_versions): for et in df["timestamp"] ] + # Run prediction! predicted = [] for _, row in df.iterrows(): @@ -94,19 +100,28 @@ def find_freshest_model_version(event_time, model_versions): df[new_col] = add_df[new_col] return df -def offline_eval_all(yahoo_path): +def offline_eval_all(yahoo_path, plan_json_path): - policy_plan_path = "/data/wooders/eurosys-results/10-05/stl-offline/result/offline_1_slide/min_loss_plan.json" - policy_params = json.load(open(policy_plan_path)) - plan_df = pd.read_csv(plan_json_path) + param_path = "/data/wooders/eurosys-results/10-05/stl-offline/result/offline_1_slide/min_loss_plan.json" + print(param_path) + policy_params = json.load(open(param_path)) + plan_df = pd.read_json(plan_json_path) + plan_df.to_csv("plan.csv") + print("plan index", plan_df.index) # loop through each key for key in policy_params.keys(): - output_file = "output_{key}.csv" + output_file = f"output_{key}.csv" print(key, output_file) - plan_df_key = plan_df[plan_df["key"] == key] - csv_path = f"{key}.csv" + plan_df_key = plan_df[plan_df["key"] == int(key)] + print("key index", plan_df_key.index) + plan_df_key.index = pd.RangeIndex(start=0, stop=len(plan_df_key.index)) + print(plan_df_key) + print("key index", plan_df_key.index) + #plan_df_key = plan_df + csv_path = f"{yahoo_path}/{key}.csv" df = offline_eval(csv_path, plan_df_key) + plan_df_key.to_csv(f"{key}_plan.csv") df.to_csv(output_file) return @@ -128,20 +143,20 @@ def offline_oracle(yahoo_csv_path): return df -def run_exp(csv_path, plan_path, output_path, run_oracle=False): +def run_exp(csv_path, plan_path, output_path, run_policy=False, run_oracle=False): if run_oracle: df = offline_oracle(csv_path) elif run_policy: - offline_eval_all(csv_path) + offline_eval_all(csv_path, plan_path) else: # Headers # processing_time window_start_seq_id window_end_seq_id key - plan_df = pd.read_json(plan_json_path) + plan_df = pd.read_json(plan_path) df = offline_eval(csv_path, plan_df) - df.to_csv(output_path, index=None) + df.to_csv(output_path, index=None) def _ensure_dir(path): @@ -160,13 +175,14 @@ def main(): assert args.offline_yahoo_csv_path if not args.offline_run_oracle: assert args.offline_plan_path - _ensure_dir(args.output_path) + #_ensure_dir(args.output_path) run_exp( csv_path=args.offline_yahoo_csv_path, plan_path=args.offline_plan_path, output_path=args.output_path, run_oracle=args.offline_run_oracle, + run_policy=True ) diff --git a/stl/offline/simulation.py b/stl/offline/simulation.py index 2039983..17df84f 100644 --- a/stl/offline/simulation.py +++ b/stl/offline/simulation.py @@ -45,7 +45,7 @@ flags.DEFINE_float("total_runtime_s", 14, "When to end the simulation.") flags.DEFINE_float( "model_runtime_s", - 0.2, + 0.01, "The latency for the map function (when processing a single record).", ) flags.DEFINE_integer("window_size", 24 * 7, "The sliding window size.") @@ -63,7 +63,7 @@ None, "path to generated per key's window slide size config.", ) -flags.DEFINE_integer("num_mapper_replicas", 1, "number of replicas for mapper") +flags.DEFINE_integer("num_mapper_replicas", 10, "number of replicas for mapper") def _get_config() -> Dict: diff --git a/wikipedia/simulate.py b/wikipedia/simulate.py index 92e71fc..1ff24a7 100644 --- a/wikipedia/simulate.py +++ b/wikipedia/simulate.py @@ -39,6 +39,18 @@ from typing import Dict, List, Tuple, Type +def current_weights(ts, ts_to_weights): + ts = int(ts) + min_dist = max(list(ts_to_weights.keys())) + + index = 0 + for key in ts_to_weights.keys(): + if key >= ts: + break + index = key + + return ts_to_weights[key] + class RoundRobinLoadBalancerFix(CrossKeyLoadBalancer): """Simple policy that cycle through all the keys fairly""" @@ -46,7 +58,7 @@ def __init__(self): self.cur_key_set = set() self.cur_key_iter = None - def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: + def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: key_set = set(per_key_queues.keys()) if key_set != self.cur_key_set: self.cur_key_set = key_set @@ -86,7 +98,7 @@ def __init__(self, pageview_file, all_keys): self.cur_key_iter = itertools.cycle(self.cur_key_set) - def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: + def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: key = next(self.cur_key_iter) while per_key_queues[key].size() == 0: @@ -94,6 +106,70 @@ def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: # TODO(simon): maybe do a "peak" here to trigger eviction policies return key +class AdaptiveWeightedRoundRobin(CrossKeyLoadBalancer): + """Simple policy that cycle through all the keys fairly""" + + def __init__(self, timestamp_weights_file): + self.cur_key_set = [] + self.cur_key_iter = None + + pageview_df = pd.read_csv(pageview_file) + self.raw_weights = pageview_df.set_index("doc_id")["weights"].to_dict() + self.weights = {} + for key in self.raw_weights.keys(): + if str(key) not in all_keys: + continue + + self.weights[key] = int(self.raw_weights[key]*1000) + assert self.weights[key] > 0, f"Too small {key}, {self.raw_weights[key]}" + print(self.weights) + + + for key in self.weights.keys(): + for i in range(self.weights[key]): + self.cur_key_set.append(str(key)) + random.shuffle(self.cur_key_set) + print(self.cur_key_set) + print("size", len(self.cur_key_set)) + self.cur_key_iter = itertools.cycle(self.cur_key_set) + + + def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: + + key = next(self.cur_key_iter) + while per_key_queues[key].size() == 0: + key = next(self.cur_key_iter) + # TODO(simon): maybe do a "peak" here to trigger eviction policies + return key + + +class AdaptiveWeightedLoadBalancer(CrossKeyLoadBalancer): + + def __init__(self, timestamp_weights_file): + data = json.load(open(timestamp_weights_file)) + self.timestamp_weights = {} + for key in data.keys(): + self.timestamp_weights[int(key)] = data[key] + + def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], timestamp: int) -> str: + weights_map = current_weights(timestamp, self.timestamp_weights) + + chosen_key = None + max_len = 0 + total_len = 0 + keys = [] + weights = [] + for key in per_key_queues.keys(): + size = per_key_queues[key].size() + if size >= 1 and key in weights_map: + keys.append(key) + weights.append(weights_map[key]) + total_len += size + print(weights) + print(keys) + chosen_key = random.choices(keys, weights, k=1)[0] + print("choose", chosen_key, keys, weights) + return chosen_key class WeightedLoadBalancer(CrossKeyLoadBalancer): @@ -103,7 +179,7 @@ def __init__(self, pageview_file): self.weights = pageview_df.set_index("doc_id")["weights"].to_dict() #print(self.weights) - def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: + def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: chosen_key = None max_len = 0 total_len = 0 @@ -122,7 +198,7 @@ def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: class RandomLoadBalancer(CrossKeyLoadBalancer): - def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: + def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: chosen_key = None max_len = 0 total_len = 0 @@ -144,7 +220,7 @@ def __init__(self, pageview_file): self.weights = pageview_df.set_index("doc_id")["weights"].to_dict() #print(self.weights) - def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: + def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: chosen_key = None max_len = 0 total_len = 0 @@ -169,7 +245,7 @@ def __init__(self, pageview_file): self.weights = pageview_df.set_index("doc_id")["weights"].to_dict() #print(self.weights) - def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: + def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: chosen_key = None max_len = 0 total_len = 0 @@ -188,7 +264,7 @@ def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: class LongestQueueLoadBalancer(CrossKeyLoadBalancer): - def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue]) -> str: + def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: chosen_key = None max_len = 0 total_len = 0 @@ -236,8 +312,10 @@ def run(self, replica_id: int): yield simpy.AnyOf(self.env, [q.wait() for q in self.source_queues.values()]) # choose key + print("env time", self.env.now) chosen_key = self.key_selection_policy.choose( - self.source_queues + self.source_queues, + self.env.now*100 ) assert chosen_key is not None @@ -267,12 +345,12 @@ def run(self, replica_id: int): stream_edits_file = config["simulation"]["stream_edits_file"] stream_questions_file = config["simulation"]["stream_questions_file"] pageview_file = config["files"]["pageview_file"] +timestamp_weights_file = config["files"]["timestamp_weights_file"] # load simulation data edits = json.load(open(stream_edits_file)) init_data = json.load(open(init_data_file)) keys = list(init_data.keys()) -ts_to_weights = json.load(open(config["files"]["weights"])) policies = { "fifo": fifo, @@ -280,6 +358,7 @@ def run(self, replica_id: int): "always_process": always_process, "sample_half": make_sampling_policy(0.5), "weighted_random": WeightedLoadBalancer(pageview_file), + "adaptive_weighted_random": AdaptiveWeightedLoadBalancer(timestamp_weights_file), "weighted_longest_queue": WeightedLongestQueueLoadBalancer(pageview_file), "longest_queue": LongestQueueLoadBalancer(), "random": RandomLoadBalancer(), @@ -288,17 +367,6 @@ def run(self, replica_id: int): "weighted_round_robin": WeightedRoundRobin(pageview_file, keys) } - -def current_weights(ts): - min_dist = max(list(ts_to_weights.keys())) - weights = None - - for key in ts_to_weights.keys(): - if abs(ts - key) <= min_dist: - min_dist = abs(ts - key) - weights = ts_to_weights[key] - return weights - def run_once( out_path: str, prioritization_policy: str, @@ -360,9 +428,9 @@ def run_once( # cross-key prioritzation: historical page views, # policies prioritization_policies = ["lifo"] # ["fifo", "lifo"] - key_selection_policies = ["weighted_round_robin", "weighted_random", "weighted_longest_queue", "longest_queue", "random", "round_robin", "round_robin_fix"] + key_selection_policies = ["adaptive_weighted_random", "weighted_round_robin", "weighted_random", "weighted_longest_queue", "longest_queue", "random", "round_robin", "round_robin_fix"] load_shedding_policies = ["always_process"] - model_runtimes = [5] #, 1, 5, 10] # [0.000001, 0.00001, 0.0000001, 0.000000001, 0] + model_runtimes = [0.01, 0.05, 0.1, 1, 5, 10] # [0.000001, 0.00001, 0.0000001, 0.000000001, 0] records_per_second = [100] output_files = [] From 9de4f9a64872e8975f219f44da43ed01a99ba098 Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Fri, 8 Oct 2021 21:42:56 -0700 Subject: [PATCH 10/26] add policy evaluation script --- stl/offline/evaluation.py | 73 ++++++++++++++------------- stl/offline/run_4_generate_plan.sh | 2 +- stl/offline/run_5_simulate_lp_plan.sh | 24 +++++++-- stl/offline/simulation.py | 16 +++--- wikipedia/simulate.py | 18 ++++--- wikipedia/wiki_eval.py | 1 + 6 files changed, 80 insertions(+), 54 deletions(-) diff --git a/stl/offline/evaluation.py b/stl/offline/evaluation.py index a0cbde2..3305a31 100644 --- a/stl/offline/evaluation.py +++ b/stl/offline/evaluation.py @@ -1,10 +1,12 @@ import argparse +from multiprocessing import Pool import json import os import bisect from tqdm import tqdm import numpy as np import pandas as pd +import time from statsmodels.tsa.seasonal import STL @@ -38,7 +40,16 @@ def predict(event, model): SEASONALITY = 24 * 7 -def offline_eval(yahoo_csv_path, plan_df): +def offline_eval(yahoo_csv_path, plan_json_path, key, output_path): + + # get plan DF for key + param_path = "/data/wooders/eurosys-results/10-05/stl-offline/result/offline_1_slide/min_loss_plan.json" + policy_params = json.load(open(param_path)) + plan_df = pd.read_json(plan_json_path) + plan_df_key = plan_df[plan_df["key"] == int(key)] + plan_df_key.index = pd.RangeIndex(start=0, stop=len(plan_df_key.index)) + + # get original data print(yahoo_csv_path) df = pd.read_csv(yahoo_csv_path) df["timestamp"] = list(range(len(df))) @@ -46,15 +57,19 @@ def offline_eval(yahoo_csv_path, plan_df): # Given our model versions from offline plan, run training on corresponding # events. offline_stl = {} - print(plan_df) - for _, row in tqdm(plan_df.iterrows()): # note: doesn't preserve types + print(plan_df_key) + for _, row in tqdm(plan_df_key.iterrows()): # note: doesn't preserve types + st = time.time() records = df.iloc[int(row.window_start_seq_id) : int(row.window_end_seq_id) + 1].to_dict( orient="records" ) + #print("find time", time.time() - st) # The yahoo dataset seasonaly can be 12hr, daily, and weekly. # Each record is an hourly record. Here we chose weekly seasonality. + st = time.time() trained = train(records, window_size=len(records), seasonality=SEASONALITY) + #print("fit time", time.time() - st) offline_stl[row.processing_time] = trained print(offline_stl) @@ -67,11 +82,10 @@ def find_freshest_model_version(event_time, model_versions): return model_versions[model_loc] df["model_version"] = [ - find_freshest_model_version(et, plan_df["processing_time"]) + find_freshest_model_version(et, plan_df_key["processing_time"]) for et in df["timestamp"] ] - # Run prediction! predicted = [] for _, row in df.iterrows(): @@ -98,37 +112,27 @@ def find_freshest_model_version(event_time, model_versions): add_df = pd.DataFrame(predicted) for new_col in add_df.columns: df[new_col] = add_df[new_col] - return df + df.to_csv(output_file) + return -def offline_eval_all(yahoo_path, plan_json_path): +def offline_eval_all(yahoo_path, plan_json_path, output_path, param_path): - param_path = "/data/wooders/eurosys-results/10-05/stl-offline/result/offline_1_slide/min_loss_plan.json" - print(param_path) policy_params = json.load(open(param_path)) - plan_df = pd.read_json(plan_json_path) - plan_df.to_csv("plan.csv") - print("plan index", plan_df.index) # loop through each key + inputs = [] for key in policy_params.keys(): - output_file = f"output_{key}.csv" - print(key, output_file) - plan_df_key = plan_df[plan_df["key"] == int(key)] - print("key index", plan_df_key.index) - plan_df_key.index = pd.RangeIndex(start=0, stop=len(plan_df_key.index)) - print(plan_df_key) - print("key index", plan_df_key.index) - #plan_df_key = plan_df - csv_path = f"{yahoo_path}/{key}.csv" - df = offline_eval(csv_path, plan_df_key) - plan_df_key.to_csv(f"{key}_plan.csv") - df.to_csv(output_file) + key_output_path = f"{output_path}/{key}.csv" + inputs.append((f"{yahoo_path}/{key}.csv", plan_json_path, key, key_output_path)) + p = Pool(100) + p.starmap(offline_eval, inputs) + p.close() return -def offline_oracle(yahoo_csv_path): +def offline_oracle(yahoo_csv_path, output_path): df = pd.read_csv(yahoo_csv_path) df["timestamp"] = list(range(len(df))) df["model_version"] = "oracle" @@ -140,22 +144,20 @@ def offline_oracle(yahoo_csv_path): df["pred_seasonality"] = oracle_model["stl_result"].seasonal df["pred_staleness"] = 0 - return df + df.to_csv(output_path) -def run_exp(csv_path, plan_path, output_path, run_policy=False, run_oracle=False): +def run_exp(csv_path, plan_path, output_path, run_policy=False, run_oracle=False, param_path=None): if run_oracle: - df = offline_oracle(csv_path) + df = offline_oracle(csv_path, output_path) elif run_policy: - offline_eval_all(csv_path, plan_path) + offline_eval_all(csv_path, plan_path, output_path, param_path) else: # Headers # processing_time window_start_seq_id window_end_seq_id key plan_df = pd.read_json(plan_path) - - df = offline_eval(csv_path, plan_df) - + offline_eval(csv_path, plan_df, output_path) df.to_csv(output_path, index=None) @@ -169,7 +171,9 @@ def main(): parser.add_argument("--offline-yahoo-csv-path", type=str) parser.add_argument("--offline-plan-path", type=str) parser.add_argument("--output-path", type=str) - parser.add_argument("--offline-run-oracle", type=bool, default=False) + parser.add_argument("--offline-run-oracle", default=False, action='store_true') + parser.add_argument("--run-policy", default=False, action='store_true') + parser.add_argument("--param-path", type=str, default=None) args = parser.parse_args() assert args.offline_yahoo_csv_path @@ -182,7 +186,8 @@ def main(): plan_path=args.offline_plan_path, output_path=args.output_path, run_oracle=args.offline_run_oracle, - run_policy=True + run_policy=args.run_policy, + param_path=args.param_path, ) diff --git a/stl/offline/run_4_generate_plan.sh b/stl/offline/run_4_generate_plan.sh index 0d06e8d..442cf98 100644 --- a/stl/offline/run_4_generate_plan.sh +++ b/stl/offline/run_4_generate_plan.sh @@ -5,4 +5,4 @@ set -ex python config_gen.py \ --csv_dir "./result/offline_1_slide/plan_eval" \ - --output_path "./result/offline_1_slide/min_loss_plan.json" \ No newline at end of file + --output_path "./result/offline_1_slide/min_loss_plan.json" diff --git a/stl/offline/run_5_simulate_lp_plan.sh b/stl/offline/run_5_simulate_lp_plan.sh index 7e353f0..bc67ae1 100644 --- a/stl/offline/run_5_simulate_lp_plan.sh +++ b/stl/offline/run_5_simulate_lp_plan.sh @@ -1,8 +1,26 @@ set -ex +PARAM_PATH=result/offline_1_slide/min_loss_plan.json +PLAN_PATH=result/offline_1_slide/lp_eval/varying_slide_size_trace.json +SOURCE_PATH=/data/wooders/stl/yahoo/A4 +OUTPUT_CSV_PATH=result/offline_1_slide/ +# re-run simulation with lp-generated weights python simulation.py --model_runtime_s 0.02 --total_runtime_s 150 \ --per_key_records_per_second 100 \ - --num_mapper_replicas 2 --num_keys 100 \ + --num_mapper_replicas 2 \ --window_size 672 --slide_size 0 \ - --per_key_slide_size_plan result/offline_1_slide/min_loss_plan.json \ - --output_path result/offline_1_slide/lp_eval/varying_slide_size_trace.json \ No newline at end of file + --per_key_slide_size_plan $PARAM_PATH \ + --output_path $PLAN_PATH \ + --source_data_path $SOURCE_PATH + +# run evaluation with simulation results +python evaluation.py --offline-yahoo-csv-path $SOURCE_PATH \ + --offline-plan-path $PLAN_PATH \ + --output-path $OUTPUT_CSV_PATH \ + --param-path $PARAM_PATH \ + --run-policy + +# get final results +python evaluate_loss.py --offline-yahoo-csv-path $SOURCE_PATH --predicted-csv-path $OUTPUT_CSV_PATH --output-path + + diff --git a/stl/offline/simulation.py b/stl/offline/simulation.py index 17df84f..33a16b0 100644 --- a/stl/offline/simulation.py +++ b/stl/offline/simulation.py @@ -75,11 +75,11 @@ def main(argv): env = simpy.Environment() # source --source_to_window_queue--> window --windows_to_mapper_queue--> mapper - policy_plan_path = "/data/wooders/eurosys-results/10-05/stl-offline/result/offline_1_slide/min_loss_plan.json" - policy_params = json.load(open(policy_plan_path)) - - keys = policy_params.keys() - print(keys) + if FLAGS.per_key_slide_size_plan is not None: + policy_params = json.load(open(FLAGS.per_key_slide_size_plan)) + keys = policy_params.keys() + else: + keys = [i in range(FLAGS.num_keys)] source_to_window_queue = simpy.Store(env) windows_to_mapper_queue = { @@ -88,7 +88,6 @@ def main(argv): processing_policy=prio_policies[FLAGS.key_prio_policy], load_shedding_policy=load_shed_policies[FLAGS.key_load_shed_policy], ) - #for i in range(FLAGS.num_keys) for key in keys } Source( @@ -98,14 +97,13 @@ def main(argv): next_queue=source_to_window_queue, total_run_time=FLAGS.total_runtime_s, keys=keys, - data_dir="/data/wooders/stl/yahoo/A4", - #data_file=FLAGS.source_data_path, + data_dir=FLAGS.source_data_path, ) WindowOperator( env, window_size=FLAGS.window_size, slide_size=FLAGS.slide_size, - per_key_slide_size_path=policy_plan_path, + per_key_slide_size_path=FLAGS.per_key_slide_size_plan, source_queue=source_to_window_queue, next_queues=windows_to_mapper_queue, ) diff --git a/wikipedia/simulate.py b/wikipedia/simulate.py index 1ff24a7..d636647 100644 --- a/wikipedia/simulate.py +++ b/wikipedia/simulate.py @@ -1,4 +1,4 @@ -import json +import json import itertools from typing import DefaultDict, Dict, List, Optional, Tuple from collections import defaultdict @@ -78,14 +78,17 @@ def __init__(self, pageview_file, all_keys): self.cur_key_set = [] self.cur_key_iter = None pageview_df = pd.read_csv(pageview_file) - self.raw_weights = pageview_df.set_index("doc_id")["weights"].to_dict() + #self.raw_weights = pageview_df.set_index("doc_id")["weights"].to_dict() + self.raw_weights = pageview_df.set_index("doc_id")["2021090300"].to_dict() self.weights = {} for key in self.raw_weights.keys(): if str(key) not in all_keys: continue self.weights[key] = int(self.raw_weights[key]*1000) - assert self.weights[key] > 0, f"Too small {key}, {self.raw_weights[key]}" + #assert self.weights[key] > 0, f"Too small {key}, {self.raw_weights[key]}" + if self.weights[key] == 0: + self.weights[key] = 1 print(self.weights) @@ -362,8 +365,7 @@ def run(self, replica_id: int): "weighted_longest_queue": WeightedLongestQueueLoadBalancer(pageview_file), "longest_queue": LongestQueueLoadBalancer(), "random": RandomLoadBalancer(), - "round_robin": RoundRobinLoadBalancer(), - "round_robin_fix": RoundRobinLoadBalancerFix(), + "round_robin": RoundRobinLoadBalancerFix(), "weighted_round_robin": WeightedRoundRobin(pageview_file, keys) } @@ -428,9 +430,11 @@ def run_once( # cross-key prioritzation: historical page views, # policies prioritization_policies = ["lifo"] # ["fifo", "lifo"] - key_selection_policies = ["adaptive_weighted_random", "weighted_round_robin", "weighted_random", "weighted_longest_queue", "longest_queue", "random", "round_robin", "round_robin_fix"] + #key_selection_policies = ["adaptive_weighted_random", "weighted_round_robin", "weighted_random", "weighted_longest_queue", "longest_queue", "random", "round_robin"] + key_selection_policies = ["round_robin"] load_shedding_policies = ["always_process"] - model_runtimes = [0.01, 0.05, 0.1, 1, 5, 10] # [0.000001, 0.00001, 0.0000001, 0.000000001, 0] + #model_runtimes = [0.01, 0.05, 0.1, 1, 5, 10] # [0.000001, 0.00001, 0.0000001, 0.000000001, 0] + model_runtimes = [0.02, 0.05, 0.07] # [0.000001, 0.00001, 0.0000001, 0.000000001, 0] records_per_second = [100] output_files = [] diff --git a/wikipedia/wiki_eval.py b/wikipedia/wiki_eval.py index cdb587d..1214cfb 100644 --- a/wikipedia/wiki_eval.py +++ b/wikipedia/wiki_eval.py @@ -326,6 +326,7 @@ def get_latest_embedding(timestep, doc_id): queries.append([question, [answer], doc_id]) # append per query + print("staleness", timestep - latest) staleness.append(timestep - latest) # dump CTX/question script From b897fa4e9a474639a89d6f263f93d28f73825486 Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Sat, 9 Oct 2021 15:11:27 -0700 Subject: [PATCH 11/26] add wandb logging + wikipedia plot notebook --- stl/offline/config_gen.py | 2 +- wikipedia/config.yml | 1 + wikipedia/log_data.py | 51 +++++ wikipedia/notebooks/Wikipedia Plots.ipynb | 263 ++++++++++++++++++++++ 4 files changed, 316 insertions(+), 1 deletion(-) create mode 100644 wikipedia/log_data.py create mode 100644 wikipedia/notebooks/Wikipedia Plots.ipynb diff --git a/stl/offline/config_gen.py b/stl/offline/config_gen.py index 0248638..6e52b11 100644 --- a/stl/offline/config_gen.py +++ b/stl/offline/config_gen.py @@ -95,7 +95,7 @@ def run_lp(df: pd.DataFrame, max_n_fits=None, max_loss=None, objective="min_loss return plan_output, optimal_loss -def get_loss_per_key(key: int, csv_dir) +def get_loss_per_key(key: int, csv_dir): key_one = glob(f"{csv_dir}/slide_*_key_A4Benchmark-TS{key}.csv") assert len(key_one) > 0 diff --git a/wikipedia/config.yml b/wikipedia/config.yml index c6bb8a1..ea0ee7a 100644 --- a/wikipedia/config.yml +++ b/wikipedia/config.yml @@ -7,6 +7,7 @@ parsed_tmp_dir = %(data_dir)s/parsed_tmp/ diff_dir = %(data_dir)s/diffs/ embedding_dir = %(data_dir)s/embeddings/ exp_dir = %(data_dir)s/simulation_output/ +dpr_dir = /home/eecs/wooders/DPR [files] data_dir = /data/wooders/wikipedia diff --git a/wikipedia/log_data.py b/wikipedia/log_data.py new file mode 100644 index 0000000..1d8969f --- /dev/null +++ b/wikipedia/log_data.py @@ -0,0 +1,51 @@ +import wandb +import configparser +import os + + + + +if __name__ == "__main__": + + print("Running wandb logging on data") + run = wandb.init(job_type="dataset-creation", project="wiki-workload") + + # configuration file + config = configparser.ConfigParser() + config.read("config.yml") + + # log files + artifact = wandb.Artifact("files", type='dataset') + artifact.add_file(config["files"]["changes_file"]) + artifact.add_file(config["files"]["titles_file"]) + artifact.add_file(config["files"]["edits_file"]) + run.log_artifact(artifact) + + # log pageview + artifact = wandb.Artifact("pageviews", type='dataset') + artifact.add_file(config["files"]["raw_pageview_file"]) + artifact.add_file(config["files"]["pageview_file"]) + artifact.add_file(config["files"]["timestamp_weights_file"]) + run.log_artifact(artifact) + + # log questions file + artifact = wandb.Artifact("questions", type='dataset') + artifact.add_file(config["files"]["raw_questions_file"]) + artifact.add_file(config["files"]["questions_file"]) + run.log_artifact(artifact) + + # log simulation data + artifact = wandb.Artifact("simulation", type='dataset') + artifact.add_file(config["simulation"]["stream_edits_file"]) + artifact.add_file(config["simulation"]["stream_questions_file"]) + artifact.add_file(config["simulation"]["init_data_file"]) + run.log_artifact(artifact) + + + # log experiment output + artifact = wandb.Artifact("prediction_results", type='dataset') + files = os.listdir(config["directory"]["dpr_dir"]) + for filename in files: + if "plan-" in filename and '.json' in filename: + artifact.add_file(os.path.join(config["directory"]["dpr_dir"], filename)) + run.log_artifact(artifact) diff --git a/wikipedia/notebooks/Wikipedia Plots.ipynb b/wikipedia/notebooks/Wikipedia Plots.ipynb new file mode 100644 index 0000000..ca4eab8 --- /dev/null +++ b/wikipedia/notebooks/Wikipedia Plots.ipynb @@ -0,0 +1,263 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "e0030940", + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "import matplotlib.pyplot as plt\n", + "import pandas as pd\n", + "import wandb\n", + "import os" + ] + }, + { + "cell_type": "markdown", + "id": "1e071d8f", + "metadata": {}, + "source": [ + "# Plot Wikipedia Dataset" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "95457b57", + "metadata": {}, + "outputs": [], + "source": [ + "run = wandb.init(job_type=\"evaluation\", project=\"wiki-workload\")\n", + "pageview_dir = run.use_artifact('pageviews:latest').download()\n", + "questions_dir = run.use_artifact('questions:latest').download()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3f5bc6ae", + "metadata": {}, + "outputs": [], + "source": [ + "pageview_df = pd.read_csv(f\"{pageview_dir}/pageviews.csv\")\n", + "pageview_df" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "38782d70", + "metadata": {}, + "outputs": [], + "source": [ + "df = pd.DataFrame({\n", + " \"edit_frequency\": pageview_df.edit_count / pageview_df.edit_count.sum(),\n", + " \"query_frequency\": pageview_df[\"2021080600\"] / pageview_df[\"2021080600\"].sum()\n", + "})\n", + "\n", + "df.plot()" + ] + }, + { + "cell_type": "markdown", + "id": "e2e430fe", + "metadata": {}, + "source": [ + "# Plot DPR Model Accuracy Results " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c15f88fd", + "metadata": {}, + "outputs": [], + "source": [ + "run = wandb.init(job_type=\"evaluation\", project=\"wiki-workload\")\n", + "artifact = run.use_artifact('prediction_results:latest')\n", + "artifact_dir = artifact.download()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "43f6adb3", + "metadata": {}, + "outputs": [], + "source": [ + "artifact_dir" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eaf30e01", + "metadata": {}, + "outputs": [], + "source": [ + "constants = [0.01, 0.05, 0.1, 1, 5, 10]\n", + "policies = [\"lifo\"]\n", + "key_policies = [\"weighted_round_robin\", \"weighted_random\", \"random\", \"round_robin\"]\n", + "d = artifact_dir\n", + "metric = 'top5'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d3b31501", + "metadata": {}, + "outputs": [], + "source": [ + "all_results = {}\n", + "for policy in policies: \n", + " for key_policy in key_policies: \n", + " scores = []\n", + " name = f\"plan-{key_policy}_{policy}-always_process\"\n", + " for constant in constants: \n", + " with open(f'{d}/{name}-{constant}-100.json') as results_file:\n", + " results = json.load(results_file)\n", + " scores.append(results[metric])\n", + " all_results[name] = scores\n", + "all_results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b479a2bc", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "all_results.keys()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "332c0ff6", + "metadata": {}, + "outputs": [], + "source": [ + "plan_weighted_random_lifo = []\n", + "for constant in constants:\n", + " with open(f'{d}/plan-weighted_random_lifo-always_process-{constant}-100.json') as results_file:\n", + " results = json.load(results_file)\n", + " plan_weighted_random_lifo.append(results[metric])\n", + "print(plan_weighted_random_lifo)\n", + " \n", + "plan_weighted_longest_queue_lifo = []\n", + "for constant in constants:\n", + " with open(f'{d}/plan-weighted_longest_queue_lifo-always_process-{constant}-100.json') as results_file:\n", + " results = json.load(results_file)\n", + " plan_weighted_longest_queue_lifo.append(results[metric])\n", + "print(plan_weighted_longest_queue_lifo)\n", + "\n", + "plan_longest_queue_lifo = []\n", + "for constant in constants:\n", + " with open(f'{d}/plan-longest_queue_lifo-always_process-{constant}-100.json') as results_file:\n", + " results = json.load(results_file)\n", + " plan_longest_queue_lifo.append(results[metric])\n", + "print(plan_longest_queue_lifo)\n", + "\n", + "plan_random_lifo = []\n", + "for constant in constants:\n", + " with open(f'{d}/plan-random_lifo-always_process-{constant}-100.json') as results_file:\n", + " results = json.load(results_file)\n", + " plan_random_lifo.append(results[metric])\n", + "print(plan_random_lifo)\n", + "\n", + "plan_round_robin_lifo = []\n", + "for constant in constants:\n", + " with open(f'{d}/plan-round_robin_lifo-always_process-{constant}-100.json') as results_file:\n", + " results = json.load(results_file)\n", + " plan_round_robin_lifo.append(results[metric])\n", + "print(plan_round_robin_lifo)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6d536763", + "metadata": {}, + "outputs": [], + "source": [ + "from pylab import rcParams\n", + "rcParams['figure.figsize'] = 12, 10" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1e07c3e9", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import seaborn\n", + "\n", + "df = pd.DataFrame({\n", + " 'Factor': resources, \n", + " **all_results\n", + "})\n", + "fig, ax1 = plt.subplots(figsize=(10, 5))\n", + "tidy = df.melt(id_vars='Factor').rename(columns=str.title)\n", + "seaborn.barplot(x='Factor', y='Value', hue='Variable', data=tidy, ax=ax1)\n", + "seaborn.despine(fig)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "61d517d0", + "metadata": {}, + "outputs": [], + "source": [ + "fig, ax = plt.subplots()\n", + "ax.set_xscale('log')\n", + "#resources = [10/c for c in constants]\n", + "resources = constants \n", + "print(resources)\n", + "ax.plot(resources, plan_weighted_longest_queue_lifo, label=\"LIFO Weighted Queue\", c='coral', marker='.')\n", + "ax.plot(resources, plan_longest_queue_lifo, label=\"LIFO Queue\", c='coral', marker='.', linestyle='dashed')\n", + "\n", + "ax.plot(resources, plan_weighted_random_lifo, label=\"LIFO Weighted Random\", c='red', marker='.')\n", + "ax.plot(resources, plan_random_lifo, label=\"LIFO Random\", c='red', marker='.', linestyle='dashed')\n", + "\n", + "#ax.plot(resources, plan_lifo_sample_half, label=\"LIFO Sample Half\", c='dodgerblue', marker='.', linestyle='dashed')\n", + "#ax.plot(resources, plan_lifo_always_process, label=\"LIFO Always\", c='dodgerblue', marker='.')\n", + "\n", + "#ax.plot(resources, plan_round_robin_lifo, label=\"LIFO Round Robin\", c='blue', marker='.', linestyle='dashed')\n", + "\n", + "ax.grid()\n", + "ax.set(xlabel='resource constraint', ylabel=f'{metric} accuracy', title='Passage Retriever')\n", + "plt.legend()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.8" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 01dc41b4204f878b1aa5e14ee02df1ae77daadbb Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Mon, 11 Oct 2021 22:14:01 -0700 Subject: [PATCH 12/26] change to scripts --- stl/offline/evaluation.py | 4 - wikipedia/config.yml | 3 +- wikipedia/log_data.py | 51 - wikipedia/notebooks/Wikipedia Plots.ipynb | 1737 +++++++++++++++++++- wikipedia/preprocessing/wiki_api_data.py | 10 +- wikipedia/run_0_generate_data.sh | 1 + wikipedia/run_1_generate_plan.sh | 16 + wikipedia/run_2_prepare_data.sh | 18 + wikipedia/run_3_run_predictions.sh | 26 + wikipedia/run_4_run_optimal_predictions.sh | 8 + wikipedia/simulate.py | 114 +- 11 files changed, 1850 insertions(+), 138 deletions(-) delete mode 100644 wikipedia/log_data.py create mode 100644 wikipedia/run_0_generate_data.sh create mode 100644 wikipedia/run_1_generate_plan.sh create mode 100644 wikipedia/run_2_prepare_data.sh create mode 100644 wikipedia/run_3_run_predictions.sh create mode 100644 wikipedia/run_4_run_optimal_predictions.sh diff --git a/stl/offline/evaluation.py b/stl/offline/evaluation.py index 3305a31..a32aab5 100644 --- a/stl/offline/evaluation.py +++ b/stl/offline/evaluation.py @@ -43,14 +43,11 @@ def predict(event, model): def offline_eval(yahoo_csv_path, plan_json_path, key, output_path): # get plan DF for key - param_path = "/data/wooders/eurosys-results/10-05/stl-offline/result/offline_1_slide/min_loss_plan.json" - policy_params = json.load(open(param_path)) plan_df = pd.read_json(plan_json_path) plan_df_key = plan_df[plan_df["key"] == int(key)] plan_df_key.index = pd.RangeIndex(start=0, stop=len(plan_df_key.index)) # get original data - print(yahoo_csv_path) df = pd.read_csv(yahoo_csv_path) df["timestamp"] = list(range(len(df))) @@ -72,7 +69,6 @@ def offline_eval(yahoo_csv_path, plan_json_path, key, output_path): #print("fit time", time.time() - st) offline_stl[row.processing_time] = trained - print(offline_stl) # Assign the trained model with every events in the source file. def find_freshest_model_version(event_time, model_versions): diff --git a/wikipedia/config.yml b/wikipedia/config.yml index ea0ee7a..ad09cc0 100644 --- a/wikipedia/config.yml +++ b/wikipedia/config.yml @@ -11,7 +11,7 @@ dpr_dir = /home/eecs/wooders/DPR [files] data_dir = /data/wooders/wikipedia -raw_questions_file = %(data_dir)s/10062021_filtered_questions.csv +raw_questions_file = %(data_dir)s/10042021_questions_revid_filtered.csv model_file = %(data_dir)s/bert-base-encoder.cp changes_file = %(data_dir)s/changes.csv titles_file = %(data_dir)s/top_titles.csv @@ -26,6 +26,7 @@ timestamp_weights_file = %(data_dir)s/timestamp_weights_file.json data_dir = /data/wooders/wikipedia plan_dir = /data/wooders/wiki-plans init_data_file = %(data_dir)s/init_data.json +optimal_plan_file = %(data_dir)s/optimal_plan.json stream_edits_file = %(data_dir)s/edit_stream.json stream_questions_file = %(data_dir)s/question_stream.json diff --git a/wikipedia/log_data.py b/wikipedia/log_data.py deleted file mode 100644 index 1d8969f..0000000 --- a/wikipedia/log_data.py +++ /dev/null @@ -1,51 +0,0 @@ -import wandb -import configparser -import os - - - - -if __name__ == "__main__": - - print("Running wandb logging on data") - run = wandb.init(job_type="dataset-creation", project="wiki-workload") - - # configuration file - config = configparser.ConfigParser() - config.read("config.yml") - - # log files - artifact = wandb.Artifact("files", type='dataset') - artifact.add_file(config["files"]["changes_file"]) - artifact.add_file(config["files"]["titles_file"]) - artifact.add_file(config["files"]["edits_file"]) - run.log_artifact(artifact) - - # log pageview - artifact = wandb.Artifact("pageviews", type='dataset') - artifact.add_file(config["files"]["raw_pageview_file"]) - artifact.add_file(config["files"]["pageview_file"]) - artifact.add_file(config["files"]["timestamp_weights_file"]) - run.log_artifact(artifact) - - # log questions file - artifact = wandb.Artifact("questions", type='dataset') - artifact.add_file(config["files"]["raw_questions_file"]) - artifact.add_file(config["files"]["questions_file"]) - run.log_artifact(artifact) - - # log simulation data - artifact = wandb.Artifact("simulation", type='dataset') - artifact.add_file(config["simulation"]["stream_edits_file"]) - artifact.add_file(config["simulation"]["stream_questions_file"]) - artifact.add_file(config["simulation"]["init_data_file"]) - run.log_artifact(artifact) - - - # log experiment output - artifact = wandb.Artifact("prediction_results", type='dataset') - files = os.listdir(config["directory"]["dpr_dir"]) - for filename in files: - if "plan-" in filename and '.json' in filename: - artifact.add_file(os.path.join(config["directory"]["dpr_dir"], filename)) - run.log_artifact(artifact) diff --git a/wikipedia/notebooks/Wikipedia Plots.ipynb b/wikipedia/notebooks/Wikipedia Plots.ipynb index ca4eab8..29bf8cb 100644 --- a/wikipedia/notebooks/Wikipedia Plots.ipynb +++ b/wikipedia/notebooks/Wikipedia Plots.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 237, "id": "e0030940", "metadata": {}, "outputs": [], @@ -16,7 +16,7 @@ }, { "cell_type": "markdown", - "id": "1e071d8f", + "id": "594d6d4e", "metadata": {}, "source": [ "# Plot Wikipedia Dataset" @@ -24,10 +24,58 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "95457b57", + "execution_count": 238, + "id": "016e13bb", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "Finishing last run (ID:1i504fr1) before initializing another..." + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Successfully finished last run (ID:1i504fr1). Initializing new run:
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[34m\u001b[1mwandb\u001b[0m: wandb version 0.12.4 is available! To upgrade, please run:\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: $ pip install wandb --upgrade\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " Syncing run resilient-planet-72 to Weights & Biases (docs).
\n", + "\n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "run = wandb.init(job_type=\"evaluation\", project=\"wiki-workload\")\n", "pageview_dir = run.use_artifact('pageviews:latest').download()\n", @@ -36,10 +84,385 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "3f5bc6ae", + "execution_count": 239, + "id": "7690f6d7", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Unnamed: 0titleedit_count2021080500202108060020210807002021080800202108090020210810002021081100...20210828002021082900202108300020210831002021090100202109020020210903002021090400weightsdoc_id
00Deaths in 20211877383536313496656...69506368505239460.02851165984422
112021 Atlantic hurricane season14381151689714...820285121150.00380557798785
22Neeraj Chopra11563732434...560492130.00217051150040
33Fall of Kabul (2021)10091891212161012...11169920155100.00487668481047
44Great Britain at the 2020 Summer Paralympics989135641689...3868107470.00339760043578
..................................................................
211211List of fungi of South Africa203897132149...10761135560.00346768354495
212212Mister Supranational 2021203897132149...10761135560.00346767918135
2132132021–22 FC Barcelona season20219292927282723...21262916272043180.01269867089631
214214Hamid Karzai International Airport20114261517261417...1910251326142270.007258487602
215215Characters of the Marvel Cinematic Universe20114261517261417...1910251326142270.00725862372638
\n", + "

216 rows × 36 columns

\n", + "
" + ], + "text/plain": [ + " Unnamed: 0 title edit_count \\\n", + "0 0 Deaths in 2021 1877 \n", + "1 1 2021 Atlantic hurricane season 1438 \n", + "2 2 Neeraj Chopra 1156 \n", + "3 3 Fall of Kabul (2021) 1009 \n", + "4 4 Great Britain at the 2020 Summer Paralympics 989 \n", + ".. ... ... ... \n", + "211 211 List of fungi of South Africa 203 \n", + "212 212 Mister Supranational 2021 203 \n", + "213 213 2021–22 FC Barcelona season 202 \n", + "214 214 Hamid Karzai International Airport 201 \n", + "215 215 Characters of the Marvel Cinematic Universe 201 \n", + "\n", + " 2021080500 2021080600 2021080700 2021080800 2021080900 2021081000 \\\n", + "0 38 35 36 31 349 66 \n", + "1 11 5 16 8 9 7 \n", + "2 3 7 3 2 4 3 \n", + "3 18 9 12 12 16 10 \n", + "4 13 5 6 4 16 8 \n", + ".. ... ... ... ... ... ... \n", + "211 8 9 7 13 21 4 \n", + "212 8 9 7 13 21 4 \n", + "213 19 29 29 27 28 27 \n", + "214 14 26 15 17 26 14 \n", + "215 14 26 15 17 26 14 \n", + "\n", + " 2021081100 ... 2021082800 2021082900 2021083000 2021083100 \\\n", + "0 56 ... 69 50 63 68 \n", + "1 14 ... 8 20 2 8 \n", + "2 4 ... 5 6 0 4 \n", + "3 12 ... 11 16 9 9 \n", + "4 9 ... 3 8 6 8 \n", + ".. ... ... ... ... ... ... \n", + "211 9 ... 10 7 6 1 \n", + "212 9 ... 10 7 6 1 \n", + "213 23 ... 21 26 29 16 \n", + "214 17 ... 19 10 25 13 \n", + "215 17 ... 19 10 25 13 \n", + "\n", + " 2021090100 2021090200 2021090300 2021090400 weights doc_id \n", + "0 50 52 39 46 0.028511 65984422 \n", + "1 5 12 11 5 0.003805 57798785 \n", + "2 9 2 1 3 0.002170 51150040 \n", + "3 20 15 5 10 0.004876 68481047 \n", + "4 10 7 4 7 0.003397 60043578 \n", + ".. ... ... ... ... ... ... \n", + "211 13 5 5 6 0.003467 68354495 \n", + "212 13 5 5 6 0.003467 67918135 \n", + "213 27 20 43 18 0.012698 67089631 \n", + "214 26 14 22 7 0.007258 487602 \n", + "215 26 14 22 7 0.007258 62372638 \n", + "\n", + "[216 rows x 36 columns]" + ] + }, + "execution_count": 239, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "pageview_df = pd.read_csv(f\"{pageview_dir}/pageviews.csv\")\n", "pageview_df" @@ -47,10 +470,31 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "38782d70", + "execution_count": 240, + "id": "5b5d1edc", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 240, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAs0AAAFoCAYAAACsdsZBAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAABpNUlEQVR4nO3deXhU1f0/8Pe9d9ZshAQSEhIIRIGwCQRFRRERCZVocAEsShctfm1dWm1tta0sSq1Yf21da8W6FVfUgkREBBdAlCUgEMImBMISEpIQss527/n9cWcmGbJMkhmYZHi/noeHZObOzJnkJnnPmc/5HEkIIUBERERERC2SQz0AIiIiIqLOjqGZiIiIiMgPhmYiIiIiIj8YmomIiIiI/GBoJiIiIiLywxDqAfijaRpqa2thNBohSVKoh0NEREREYUoIAafTicjISMiy79xypw/NtbW12LdvX6iHQURERETniQEDBiA6Otrnsk4fmo1GIwB98CaT6Zw/fn5+PoYOHXrOH5e6Lp4z1BE8b6i9eM5QR/C8aZ3D4cC+ffu8+bOxTh+aPSUZJpMJZrM5JGMI1eNS18VzhjqC5w21F88Z6gieN/41VxLMhYBERERERH4wNBMRERER+cHQTERERETkR6evaSYiIiIKBqfTiaNHj8Jms4V6KCFjMBiwe/fuUA8j5CwWC1JSUppd8NcShmYiIiI6Lxw9ehTR0dFIS0s7b/d+qK2tRWRkZKiHEVJCCJSXl+Po0aPo169fm2/H8gwiIiI6L9hsNsTHx5+3gZl0kiQhPj6+3e84MDQTERHReYOBmYCOnQcMzUREREREfjA0ExEREXVSR48exZgxYwAAJSUlmDVrlve65557Dg6Hw+99vP3225g8eTKmTp2K2traszbWcMfQTERERNQFJCYm4r///a/38+effx5Op9Pv7f773//iqaeewtKlS5ssAnS5XEEfZ7hi9wwiIiI676zeWoFVWyrOyn1PGh2HiaPi/B63fft2PP30097Z3/vvvx/jx4/HW2+9hddffx09e/bEJZdc4j3+6NGjuPnmm7Fx40bMnz8fAHDrrbdClmX897//RUxMTJPH+M1vfoMjR47g97//PYYMGYK7774bt99+O26//XZs2LABN9xwA6655hosWLAAx48fh91ux5QpU3D33XcDALZs2YL58+fDbDZjxIgRWLNm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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "df = pd.DataFrame({\n", " \"edit_frequency\": pageview_df.edit_count / pageview_df.edit_count.sum(),\n", @@ -62,7 +506,7 @@ }, { "cell_type": "markdown", - "id": "e2e430fe", + "id": "1ca13ffa", "metadata": {}, "source": [ "# Plot DPR Model Accuracy Results " @@ -70,10 +514,106 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "c15f88fd", + "execution_count": 241, + "id": "39b1975e", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "Finishing last run (ID:h5pqozf8) before initializing another..." + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Waiting for W&B process to finish, PID 38831... (success)." + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "VBox(children=(Label(value=' 0.68MB of 0.68MB uploaded (0.00MB deduped)\\r'), FloatProgress(value=1.0, max=1.0)…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "
\n", + "
\n", + "
\n", + "Synced 6 W&B file(s), 0 media file(s), 0 artifact file(s) and 1 other file(s)\n", + "
Synced resilient-planet-72: https://wandb.ai/ucb-ralf/wiki-workload%20/runs/h5pqozf8
\n", + "Find logs at: ./wandb/run-20211011_174530-h5pqozf8/logs
\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Successfully finished last run (ID:h5pqozf8). Initializing new run:
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[34m\u001b[1mwandb\u001b[0m: wandb version 0.12.4 is available! To upgrade, please run:\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: $ pip install wandb --upgrade\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " Syncing run stoic-blaze-73 to Weights & Biases (docs).
\n", + "\n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "run = wandb.init(job_type=\"evaluation\", project=\"wiki-workload\")\n", "artifact = run.use_artifact('prediction_results:latest')\n", @@ -82,34 +622,146 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "43f6adb3", + "execution_count": 242, + "id": "101571e2", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'./artifacts/prediction_results:v1'" + ] + }, + "execution_count": 242, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "artifact_dir" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 289, + "id": "c106b186", + "metadata": {}, + "outputs": [], + "source": [ + "artifact_dir = \"/home/eecs/wooders/DPR\"" + ] + }, + { + "cell_type": "code", + "execution_count": 290, "id": "eaf30e01", "metadata": {}, "outputs": [], "source": [ - "constants = [0.01, 0.05, 0.1, 1, 5, 10]\n", + "constants = [0.01, 0.05, 0.1, 1, 5]\n", "policies = [\"lifo\"]\n", - "key_policies = [\"weighted_round_robin\", \"weighted_random\", \"random\", \"round_robin\"]\n", + "key_policies = [\"random\", \"weighted_random\"]\n", "d = artifact_dir\n", "metric = 'top5'" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 291, + "id": "25eb4c0d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/home/eecs/wooders/DPR/plan-random_lifo-always_process-0.01-100.json\n", + "/home/eecs/wooders/DPR/plan-random_lifo-always_process-0.05-100.json\n", + "/home/eecs/wooders/DPR/plan-random_lifo-always_process-0.1-100.json\n", + "/home/eecs/wooders/DPR/plan-random_lifo-always_process-1-100.json\n", + "/home/eecs/wooders/DPR/plan-random_lifo-always_process-5-100.json\n", + "/home/eecs/wooders/DPR/plan-weighted_random_lifo-always_process-0.01-100.json\n", + "/home/eecs/wooders/DPR/plan-weighted_random_lifo-always_process-0.05-100.json\n", + "/home/eecs/wooders/DPR/plan-weighted_random_lifo-always_process-0.1-100.json\n", + "/home/eecs/wooders/DPR/plan-weighted_random_lifo-always_process-1-100.json\n", + "/home/eecs/wooders/DPR/plan-weighted_random_lifo-always_process-5-100.json\n" + ] + }, + { + "data": { + "text/plain": [ + "{'plan-random_lifo-always_process': [0.41722204591135087,\n", + " 0.41605839416058393,\n", + " 0.3628477731936951,\n", + " 0.19216121866074262,\n", + " 0.20681265206812652],\n", + " 'plan-weighted_random_lifo-always_process': [0.4166931132973659,\n", + " 0.4052681688352904,\n", + " 0.3899820162911245,\n", + " 0.256373637998519,\n", + " 0.17237913889770443]}" + ] + }, + "execution_count": 291, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all_results = {}\n", + "for policy in policies: \n", + " for key_policy in key_policies: \n", + " scores = []\n", + " name = f\"plan-{key_policy}_{policy}-always_process\"\n", + " for constant in constants: \n", + " print(f'{d}/{name}-{constant}-100.json')\n", + " with open(f'{d}/{name}-{constant}-100.json') as results_file:\n", + " results = json.load(results_file)\n", + " scores.append(results[metric])\n", + " all_results[name] = scores\n", + "all_results" + ] + }, + { + "cell_type": "code", + "execution_count": 228, "id": "d3b31501", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'plan-weighted_round_robin_lifo-always_process': [0.7134603189515466,\n", + " 0.14824122570088702,\n", + " 0.13923792971165966,\n", + " 0.14143003656121067,\n", + " 0.1144984381238697,\n", + " 0.12701693402541278],\n", + " 'plan-weighted_random_lifo-always_process': [0.7100077506635037,\n", + " 0.1506368853293249,\n", + " 0.15045681940954037,\n", + " 0.13972332479977453,\n", + " 0.11063093532501898,\n", + " 0.12261706242024253],\n", + " 'plan-random_lifo-always_process': [0.699352545584079,\n", + " 0.14759142259905583,\n", + " 0.15119274099474678,\n", + " 0.12415936616796236,\n", + " 0.11849120417126617,\n", + " 0.11131988319202073],\n", + " 'plan-round_robin_lifo-always_process': [0.6862547071580117,\n", + " 0.14121082587625558,\n", + " 0.14572030282390336,\n", + " 0.12318857599173262,\n", + " 0.11423225372070993,\n", + " 0.11082665915087175]}" + ] + }, + "execution_count": 228, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "all_results = {}\n", "for policy in policies: \n", @@ -126,22 +778,45 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 229, "id": "b479a2bc", "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "dict_keys(['plan-weighted_round_robin_lifo-always_process', 'plan-weighted_random_lifo-always_process', 'plan-random_lifo-always_process', 'plan-round_robin_lifo-always_process'])" + ] + }, + "execution_count": 229, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "all_results.keys()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 230, "id": "332c0ff6", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0.7100077506635037, 0.1506368853293249, 0.15045681940954037, 0.13972332479977453, 0.11063093532501898, 0.12261706242024253]\n", + "[0.11061527741895076, 0.11378600339776562, 0.11060744846591665, 0.11156258073607817, 0.11068573799625776, 0.11357462166584463]\n", + "[0.11424008267374404, 0.11315185820200264, 0.127032591931481, 0.11396606931755017, 0.11010639547173356, 0.11089711972817876]\n", + "[0.699352545584079, 0.14759142259905583, 0.15119274099474678, 0.12415936616796236, 0.11849120417126617, 0.11131988319202073]\n", + "[0.6862547071580117, 0.14121082587625558, 0.14572030282390336, 0.12318857599173262, 0.11423225372070993, 0.11082665915087175]\n" + ] + } + ], "source": [ "plan_weighted_random_lifo = []\n", "for constant in constants:\n", @@ -181,25 +856,36 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 231, "id": "6d536763", "metadata": {}, "outputs": [], "source": [ "from pylab import rcParams\n", - "rcParams['figure.figsize'] = 12, 10" + "rcParams['figure.figsize'] = 12, 6" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 232, "id": "1e07c3e9", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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s037duzYwYQJE4iJiSE5OZnIyEjmz59PTEwMzz//POPHjwdur/v9n//8h2+//ZbVq1czZ84c7Ozs2LFjB+vWrWPRokWsWLGCAQMG8P777wO3l6bs27cv0dHRxMbG0rx5cwCmTp3Kl19+SXR0NMuXL6d8+fJ3v2hmUA+aiMh96t69OwBVqlShevXq7Nq1i9atW2crs3nzZhYvXkxKSkqOIbLixYvz4osvAph6UXLzwgsvMHToUFJTU0lISGDUqFH88MMPuLm5UbVqVYoVK8bPP//MiRMnePXVV02fS09P56+//spW1/bt22nRogUuLi4AdO3aldWrVxc4ppSUFLZv386FCxdM265fv05iYiKurq4UK1bM9BxThw4dCA0NzaMVs59nxYoVAfj999+pVq0azz33nCnOcePGce3aNbPqcXd3B6B27dqm5Cc+Pp5OnTrh6OiIo6MjHTt2JCEh4a71derUyfTztm3beP/99zEYDDg7O+Pn58e2bdto0aKFqayDgwMODg506NCBuLg4U3veqU2bNhQpUgSA6tWrc+LECZo0aXLXWPJz9OhRHB0dady4MXA7uXJ0dOTo0aN4enrmKJ/fvZnl2Wef5datW5w5c4Zt27YxfPhw5syZQ0BAgKm3DG4PtcbExJCWlkZKSgqVKlUCoFmzZkyePJnExEQATp48aWqPypUr889//pNmzZrRsmVLnJ2d8z2/li1b8tRTTwHQrVs3JkyYYNrXvHlz0z0dHx9PixYtKFu2LAC9evUiMDAQgA0bNvDKK6+YjvXkk08C8J///IcDBw6Y/ps2Go1cuXIFgIYNGzJ37lxOnz5NkyZNqF27NgC+vr6EhITQunVrWrZsSYUKFfKN31xK0ERELMhoNOYYovrzzz+ZPHkyy5Yto0KFCiQkJGTrBXJycjL9bGdnZ/ojOWfOHNavXw9ASEgIvr6+eHp6smbNGsqUKYOvry8RERGUK1cu28PczZo1Y+rUqTliy/rjmFecd8orpr/LzMzEYDCwbNkyHB0ds+07cOBAnvXnp0SJEmbFaW9vT2Zmpun3W7duZduflfhklc16nu1en026s2cnt7jyijO/c8grxvuR1/EMBgM///yzqYcsICCA9u3b53tv3snX15eNGzdy/vx5GjRoQHh4OBs3bjTdezt27ODbb79lyZIluLi4EBMTw/fff2869quvvsri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mLVr1/Lkk0+aXYc5z6CJ+ZTQiq05evQoN2/exNXVVUmaiNg0o9FIWloaycnJPPnkk1SsWNHsz1olQXN3dyc5Odn0NkhGRgZnz541vW6cpUyZMqafmzRpgru7O3/88Ydp0j0RkWeeeYZTp04VaNkfEZGHxcHBgVKlSpkmZzb7cw8onmxcXV1Nr/4GBgYSGxuLl5dXjuHN5ORk3NzcgNvPO/z555+myfpERAAcHR31vSAijzyrDXGOHTuW4OBgZs+eTcmSJU0L4gYFBTFkyBBq1qzJ9OnT+e9//4udnR2Ojo5MnTo1W6+aiIiIyOPAagmah4cHS5cuzbF93rx5pp+zkjYRERGRx5kWSxcRERGxMUrQRERERGyMEjQRERERG6METURERMTGKEETERERsTFK0ERERERsjBI0ERERERujBE1ERETExihBExEREbExStBEREREbIwSNBEREREbowRNRERExMYoQRMRERGxMUrQRERERGyMEjQRERERG6METURERMTGKEETERERsTFK0ERERERsjBI0ERERERujBE1ERETExihBExEREbExStBEREREbIwSNBEREREbowRNRERExMYoQRMRERGxMUrQRERERGyMg7kFExMTWb9+PX/99RdhYWEkJiaSlpZGtWrVHmR8IiIiIo8ds3rQ1q1bx2uvvUZycjLR0dEApKSkMGXKFLMPdPToUXr27Enbtm3p2bMnx44dy7PskSNHqF27NhEREWbXLyIiIvKoMCtBmzlzJl9++SXh4eHY29sDUK1aNQ4cOGD2gcLCwujduzc//PADvXv3JjQ0NNdyGRkZhIWF0aZNG7PrFhEREXmUmJWgXbhwwTSUaTAYTP+f9fPdnD9/nn379uHv7w+Av78/+/bt48KFCznKzp07l5YtW1KpUiWz6hYRERF51Jj1DFqNGjWIjo6mU6dOpm1r1qyhVq1aZh0kKSkJNzc3U++bvb09ZcuWJSkpCRcXF1O5AwcO8Msvv/D1118ze/bsApzG/+zduzff/XXr1r2neh9XO3fufNghiIiIPJLyy0nMStDGjBnDgAEDWLZsGSkpKQwYMICjR4/y5ZdfWizItLQ0PvzwQyZPnmxK5O6Ft7c3RYoUsVhcjzsltCIiItZnVoLm4eHBunXr2LBhAy1btsTd3Z2WLVtSokQJsw7i7u5OcnIyGRkZ2Nvbk5GR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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "import matplotlib.pyplot as plt\n", "import seaborn\n", - "\n", + "resources = constants \n", "df = pd.DataFrame({\n", " 'Factor': resources, \n", " **all_results\n", @@ -212,10 +898,38 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 233, "id": "61d517d0", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0.01, 0.05, 0.1, 1, 5, 10]\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 233, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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A7i7w+zZcOqUoysSERGRQkDhWiQ7r7wC8fHm8uqrjq5GRERECgGFa5HsNGtmZg0pUQLefRf+/tvRFYmIiEgBp3Atcj1vvw2bNpnbr7zi2FpERESkwFO4FrmeKlWgSRMYOBA++ACOHHF0RSIiIlKAKVyL3EhSEvz8M1itMHmyo6sRERGRAkzhWuRGXFwgKMjc/ugjOHjQsfWIiIhIgaVwLZIT48eDszNYLDBxoqOrERERkQJK4VokJypXhiefhJQU+OQT+OMPR1ckIiIiBZDCtUhOjR5tpuVzdYUJExxdjYiIiBRACtciOVWhAqxbB8OHw+efw86djq5IREREChiFa5GbcdddMGIElCplxmGLiIiIZKBwLXKz0ua6XrECtm1zbC0iIiJSoChci9ys22830/O5uqr3WkREROwoXIvcLG9vePllSEyENWvghx8cXZGIiIgUEArXIrfimWcgIMD0Xo8d6+hqREREpIDIt3B95MgRevXqRadOnejVqxdHjx7NtM4777zDAw88QLdu3XjwwQf5/vvv86s8kZtTogSMG2d6rzdtgu++c3RFIiIiUgDkW7gOCwujT58+rFmzhj59+jA+i7GqQUFBfP7553z11VdMnTqVF154gbi4uPwqUeTmDBxopuS77TYTtK1WR1ckIiIiDpYv4frcuXPs2bOHkJAQAEJCQtizZw/nz5+3W69169aUKFECgFq1amG1Wrl48WJ+lChy89zcoEcPMyzkf/+D1asdXZGIiIg4WL6E68jISMqXL4+zszMAzs7O+Pv7ExkZme02y5cvp3LlylSoUCE/ShS5dcnJJmir91pERKTYK5AHNG7bto233nqLmTNnOroUkRsrXx4SEuDnn+GrrxxdjYiIiDhQvoTrgIAATp8+TXJyMgDJyclERUUREBCQad1ff/2Vl156iXfeeYfq1avnR3ki/8yDD0KjRmbu6zFjICXF0RWJiIiIg+RLuPbz86NOnTqsXLkSgJUrV1KnTh18fX3t1vv999954YUXePvtt6lXr15+lCbyzzk5wSuvQFIS/PGHOchRREREiiWL1Zo/g0QPHTrEqFGjuHTpEj4+PkyfPp3q1aszaNAghgwZQoMGDejRowcnTpygfPnytu1mzJhBrVq1brj/+Ph4du/eTf369XF3d8/LpyKSmdUKd99tTodeo4YJ2anHGIiIiEjRcr3c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A3O0bq1atTh27Ng/fkwRkZxSuBYRyaGkpCRHlwAUnDryQlF+biJSPChci4hcR7t27Zg/fz5du3alUaNGJCUlsXPnTnr37k2TJk3o1q0bW7duta3/xRdf0L59e4KDg2nXrh1fffUVACkpKbz77ru0bduWli1bMmLECC5fvgxk3aPbrl07/ve//wEwe/ZshgwZwvDhw2ncuDFffvklFy9e5OWXX+buu++madOmPPPMM7ZtN2zYQGhoKE2aNKF3797s27cv2+d38OBB+vfvT7NmzbjrrruYN28eAAkJCbzyyivcfffd3H333bzyyiskJCTY1btgwQJatmzJ3XffzbJly2z73LRpE126dCE4OJjWrVvz4YcfEhsby6BBg4iKiiI4OJjg4GBOnz6d5XP7/fff6dWrF02aNOHuu+9m0qRJtscG+97oUaNGMXHiRJ544gmCg4N56KGH+OuvvwD4z3/+A0BoaCjBwcF8/fXXN/OjFxG5NVYREclW27Ztrd26dbOePHnSevXqVeupU6eszZo1s27cuNGanJxs/eGHH6zNmjWznjt3znrlyhVrcHCw9dChQ1ar1Wo9ffq09cCBA1ar1Wr97LPPrB06dLD+9ddf1piYGOvgwYOtw4cPt1qtVutPP/1kbd26dabH/fHHH61Wq9X69ttvW+vWrWtdt26dNTk52Xr16lXroEGDrEOHDrVevHjRmpCQYN26davVarVad+/ebW3RooV1586d1qSkJOsXX3xhbdu2rTU+Pj7Tc7t8+bK1VatW1g8//NAaFxdnvXz5snXnzp1Wq9VqffPNN60PPfSQ9ezZs9Zz585Ze/XqZZ01a5at3jp16ljffPNNa0JCgnXjxo3WoKAg68WLF61Wq9XaqlUr6/bt261Wq9V68eJF6+7du7N9nlk9t127dll//fVXa2JiovX48ePWzp07WxcuXGjbpmbNmtajR49arVardeTIkdamTZtaf/vtN2tiYqJ12LBh1ueffz7LdUVE8oN6rkVEbqBfv34EBATg4eFBREQEbdq04Z577sHJyYlWrVpRv359Nm3aBICTkxMHDx4kLi4Of39/7rjjDgBWrFjBY489RmBgIJ6engwbNoyvv/46x8MgGjVqRIcOHXBycuLSpUts3ryZiRMnUqpUKVxdXWnWrBkA//3vf+nVqxcNGzbE2dmZf/3rX7i6urJz585M+9y4cSNly5ZlwIABuLu74+XlRcOGDW31Dh48GD8/P3x9fRk8eLCtFx7AxcWFwYMH4+rqyj333EPJkiU5cuSIre3PP/8kJiaGUqVKUa9evRw/Nw8PD+rXr0+jRo1wcXGhUqVK9OrVi+3bt2e7fceOHQkKCsLFxYVu3bqxd+/eHL2mIiJ5wcXRBYiIFHQBAQG22ydPnmT16tVs2LDBtiwpKYnmzZtTsmRJZs2axYIFCxgzZgyNGzdm5MiR1KhRg6ioKG677TbbNrfddhtJSUmcO3cuRzVUqFDBdvvUqVOUKlWKUqVKZVrv5MmTLF++nPDwcNuyxMREoqKiMq0bGRlJ5cqVs3y8qKgoKlasaLtfsWJFu32ULl0aF5f0fyElSpQgNjYWgLfffpu5c+cyc+ZMatWqxYsvvkhwcHCOnhvAkSNHePXVV9m9ezdXr14lOTn5ugG9bNmyttseHh62OkREHEHhWkTkBiwWi+12QEAAoaGhTJkyJct1W7duTevWrYmLi+PNN99k3LhxLFmyBH9/f06cOGFb7+TJk7i4uODn58fp06eJi4uztSUnJ3P+/Plsa6hQoQLR0dFcunQJHx8fu/UCAgJ46qmnePrpp2/4vAICAli1alWWbf7+/pw8edLW8x4ZGYm/v/8N9wkQFBTE3LlzSUxM5JNPPuH5559n06ZNds8hu+cGMGHCBOrWrcvMmTPx8vJi0aJFrFmzJkePLSLiaBoWIiJyE7p168aGDRv4/vvvSU5OJj4+nq1bt3Lq1CnOnj3L+vXriY2Nxc3NjZIlS+Ls7AxASEgIH330EcePH+fKlSvMmjWL+++/HxcXF6pVq0Z8fDwbN24kMTGRuXPn2h3Ady1/f3/atGnDxIkTiY6OJjEx0TZs4qGHHmLp0qX89ttvWK1WYmNj2bhxIzExMZn2c++993L27FkWLVpEQkICMTEx/PbbbwA88MADzJ07l/Pnz3P+/HneeecdunbtesPXJyEhga+++orLly/j6uqKp6en7TXw8/Pj4sWLtgM5s3PlyhU8PT3x9PTk0KFD/N///d8NHzc7ZcuW1ZzYIpKvFK5FRG5CQEAA7777Lu+99x4tW7bknnvu4cMPPyQlJYWUlBQWLlxI69atadasGdu3bycsLAyAHj160K1bN/r27Uv79u1xc3Nj3LhxAHh7exMWFsbYsWNp06YNJUqUyDRU4lozZszAxcWF+++/n7vuuouPPvoIgAYNGjB58mQmTZpE06ZNue+++/jiiy+y3IeXlxcLFixgw4YNtGrVik6dOtlmPnnmmWeoX78+3bp1o1u3btSrV89uRpLriYiIoF27djRu3JilS5cyY8YMAGrUqMEDDzxAhw4daNKkCadPn85y+5EjR7Jy5UoaN27MuHHj6NKlS44eNyvPPvsso0aNokmTJpotRETyhcVqtVodXYSIiIiISFGgnmsRERERkVyicC0iIiIikksUrkVEREREconCtYiIiIhILlG4FhERERHJJQrXIiIiIiK5ROFaRERERCSXKFyLiIiIiOSS/wemq0hnq0BtUAAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "fig, ax = plt.subplots()\n", "ax.set_xscale('log')\n", @@ -237,6 +951,961 @@ "ax.set(xlabel='resource constraint', ylabel=f'{metric} accuracy', title='Passage Retriever')\n", "plt.legend()" ] + }, + { + "cell_type": "markdown", + "id": "cdf98fa5", + "metadata": {}, + "source": [ + "## Observe how often each key was updated " + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "91736ad0", + "metadata": {}, + "outputs": [], + "source": [ + "plan_dir = '/data/wooders/wiki-plans'\n", + "diff_dir = '/data/wooders/wikipedia/diffs'" + ] + }, + { + "cell_type": "code", + "execution_count": 162, + "id": "2cdeefee", + "metadata": {}, + "outputs": [], + "source": [ + "from collections import defaultdict \n", + "\n", + "def evaluate_plan(plan_file, optimal_file, start_ts=0, end_ts=37000): \n", + " plan = json.load(open(plan_file))\n", + " optimal_plan = json.load(open(optimal_file))\n", + " \n", + "\n", + " title_counts = defaultdict(lambda: 0)\n", + " title_counts_opt = defaultdict(lambda: 0)\n", + "\n", + " for ts in plan.keys(): \n", + " if float(ts) < start_ts or float(ts) > end_ts: continue \n", + " for edit in plan[ts]: \n", + " edit_file = edit[0]\n", + " edit_data = json.load(open(f\"{diff_dir}/{edit_file}\"))\n", + " title = edit_data['title']\n", + " title_counts[title] += 1\n", + " \n", + " for ts in optimal_plan.keys(): \n", + " if float(ts) < start_ts or float(ts) > end_ts: continue \n", + " for edit in optimal_plan[ts]: \n", + " edit_file = edit[0]\n", + " edit_data = json.load(open(f\"{diff_dir}/{edit_file}\"))\n", + " title = edit_data['title']\n", + " title_counts_opt[title] += 1\n", + " \n", + " #assert title_counts_opt != title_counts\n", + " \n", + " title_counts_df = pd.DataFrame({\"title\": title_counts.keys(), \"updates\": title_counts.values()})\n", + " title_counts_opt_df = pd.DataFrame({\"title\": title_counts_opt.keys(), \"optimal_updates\": title_counts_opt.values()})\n", + " \n", + " plan_data_df = title_counts_df.merge(pageview_df, on=\"title\")\n", + " plan_data_df = plan_data_df.merge(title_counts_opt_df, on=\"title\")\n", + " plan_data_df[\"pageviews\"] = plan_data_df[\"2021090300\"]\n", + " return plan_data_df" + ] + }, + { + "cell_type": "code", + "execution_count": 153, + "id": "d6440018", + "metadata": {}, + "outputs": [], + "source": [ + "plan_names = [\n", + " 'plan-round_robin_lifo-always_process-5-100',\n", + " 'plan-weighted_round_robin_lifo-always_process-5-100',\n", + " 'plan-random_lifo-always_process-5-100',\n", + " 'plan-weighted_random_lifo-always_process-5-100' \n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 154, + "id": "523bf657", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "plan-round_robin_lifo-always_process-5-100\n", + "plan-weighted_round_robin_lifo-always_process-5-100\n", + "plan-random_lifo-always_process-5-100\n", + "plan-weighted_random_lifo-always_process-5-100\n" + ] + } + ], + "source": [ + "results = {}\n", + "end_ts = 1000\n", + "for plan_name in plan_names:\n", + " print(plan_name)\n", + " plan_file = f'{plan_dir}/{plan_name}.json'\n", + " plan_data_df = evaluate_plan(plan_file, f'/home/eecs/wooders/experiments/wikipedia/optimal_plan.json', end_ts=end_ts)\n", + " results[plan_name] = plan_data_df\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 155, + "id": "d1958139", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 155, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "results['plan-round_robin_lifo-always_process-5-100'].set_index(\"title\").sort_values(by=\"pageviews\").tail(10)[[\"updates\", \"optimal_updates\", \"pageviews\"]].plot(kind=\"bar\", title=\"Updates for Top Documents (Weighted Round Robin)\")" + ] + }, + { + "cell_type": "code", + "execution_count": 156, + "id": "3ea99ccb", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 156, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "results['plan-round_robin_lifo-always_process-5-100'].set_index(\"title\").sort_values(by=\"pageviews\").head(10)[[\"updates\", \"optimal_updates\", \"pageviews\"]].plot(kind=\"bar\", title=\"Updates for Least Queried Documents (Round Robin)\")" + ] + }, + { + "cell_type": "code", + "execution_count": 157, + "id": "999fc591", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 157, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "results['plan-round_robin_lifo-always_process-5-100'].plot(x=\"pageviews\", y=\"updates\", kind=\"hist\")" + ] + }, + { + "cell_type": "code", + "execution_count": 158, + "id": "00d43d3f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 158, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYUAAAD7CAYAAACFfIhNAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAel0lEQVR4nO3dfVRUdeIG8Ge4MCAUDS8yjS9Jy0md4qQtvhz3uEfDVjYdxd2Oh5pTnS2395IsT+JLDEpWo7a+E/amp5V1z7IV6mjhSXs5vcrOthYOSSUS5AQySCG5A965vz/8eVcE5AIz917g+ZzTOc2Fud9nZrw8c98NkiRJICIiAhCmdQAiItIPlgIREclYCkREJGMpEBGRjKVARESycK0D9EUgEEBLSwsiIiJgMBi0jkNE1C9IkoS2tjbExMQgLKz9ukG/LoWWlhZUVlZqHYOIqF8aPXo0rrzyynbT+nUpREREADj/woxGo8ZpgPLycqSmpmod47L0nlHv+QBmDAa95wP0n7Ev+VpbW1FZWSn/Db1Yvy6FC5uMjEYjIiMjNU5znl5yXI7eM+o9H8CMwaD3fID+M/Y1X2eb3bmjmYiIZCwFIiKS9evNR10JBAKora1FS0uLquOGh4ejoqJC1TF7qqcZY2JiMGLEiA5HKBDRwDQgS6GhoQEGgwFjxoxR9Y9ZS0sLYmJiVBuvN3qSMRAI4IcffkBDQwOSkpJCnIyI9GBAfv1ramqC2Wzmt9s+CgsLg9lsxk8//aR1FCJSyYD8qymKYqeHWlHPRURE4Ny5c1rHICKVDMhSADo/1Ip6ju8j0eAyYEvhUq1tgX4130vV1tZi8uTJ3f5eRUUF9u/fr0Iioo6ULg9paWmajEvdG5A7mjtjjAjDrUuPBH2+bz83Lujz7IuKigq8//77mDVrltZRaBAK1XLWHb0th/3ZoCkFLdXW1uK2227D559/3u7xG2+8gdtuuw1//OMfUVZWBr/fD4fDgQkTJgAAioqKsGPHDgwdOhSTJk2S53fu3Dk88MADOH36NPx+P2688UasXLkSLS0t2LRpE86cOYPMzExMnDgRK1aswJEjR7Bu3Tq0tLRAFEUsWrQI06dPh8/nw5NPPgmfzwcAmDJlCpYtW6b+G0REusFS0FhTUxPGjBmDJUuW4PDhw3jiiSfw7rvv4vjx43jxxRdRUlKCxMRE5OXlyc8RBAHr1q1DXFwcJEnCkiVL8MYbb+COO+7AwoUL8f7772PTpk0AgJ9//hkOhwMvvfQSkpKScOLECdx9991wuVzYu3cvhg0bhh07dgAAjzIiIpaC1iIiIjB37lwAwKRJkxAVFYXjx4/j8OHDmD59OhITEwEAWVlZePvttwGcP3/gtddew4cffohAIICffvoJUVFRnc7/iy++QG1tLe677z75uQaDAdXV1Rg3bhy2b98Op9OJSZMmYerUqSq8YiLSM5aCCsLDwyFJkvzY7/d3+buSJMFgMLT7/Uvt3bsXbrcbRUVFuOKKK1BYWIgTJ050Ob8xY8agqKgIQMeT10pKSvDJJ59g9+7deOmll7Br164evjoiGkgGzdFHWkpMTERbWxuqq6sBAC6XS/5ZW1sb9u7dCwD417/+Bb/fj2uvvRaTJ0/GBx98IG/v/+c//yk/p7m5GXFxcbjiiivQ3Nzcbn4Xpl1w0003obq6Gp999pk87csvv4QkSaipqcEVV1yB2bNnY+nSpTh69CgCAR7FQTSYcU1BBeHh4Vi+fDnuueceDB8+vN2hpSaTCdXV1Zg/fz7++9//4i9/+QuMRiPGjh2LBx98EHfccQcSExMxffp0+Tnz5s3DwYMHMXv2bJjNZqSlpclrH1OmTMFrr72GuXPnYtKkSVixYgUKCgqwdu1aPPvss/D7/Rg1ahQKCwtx+PBhbN++HYIgIBAIYOXKlTwLnGiQM0iX206hc36/X77RxMXXFa+oqIDVam33u61tARgjgv8H7+L59vTaR5celaSG3lyfqbP3M1TcbnfQj2EPNma8vIFySKreP+e+5OvqbycwiDYfhaIQQjlfIiIt8C+ahkaMGKHqWgIRUXdYCkREJBuwpdCPd5XoCt9HosFFlaOPamtr8cgjj8iPm5ubcebMGRw+fBhVVVXIyclBU1MTTCYTnE4nkpOT+zReVFQUfD4fEhISeJXPPpAkCT6fr8sT44ho4FGlFEaMGIHdu3fLj1evXg1RFAEADocDdrsdmZmZ2L17N3Jzc/H666/3ebza2lqcOnWqT/PpqdbWVhiNRlXH7KmeZoyKisKIESNCmIiI9ET18xRaW1uxd+9evPrqq/D5fPB4PNi+fTsAwGazIT8/H42NjYiPj+/1GBEREbj22muDFVkxt9uNceP0fbXG/pCRiLSj+j6FQ4cOwWw244YbboDX64XZbIYgCADOX+gtKSkJXq9X7VhERAQN1hQuXC46mMrLy4M6v75wu91aR+iW3jPqPR/AjF3R8mSvULxevX/OocinainU1dWhrKwMa9asAQBYLBbU1dVBFEUIggBRFFFfXw+LxdKj+XZ2Vp4W9H4GJKD/jHrPBzCjXgX79er9PQzGGc2dUXXz0VtvvYVp06YhLi4OAJCQkACr1Spf0M3lcsFqtfZpfwIREfWe6qVw6aajvLw87Ny5ExkZGdi5cydWrlypZiQiIrqIqpuPSktLO0xLSUlBcXGxmjGIiKgLA/aMZiIi6jmWAhERyVgKREQkYykQUb/X2hb828gqPdwzFGNribfjJKJ+zxgRpskd34DQ3PVNS1xTICIiGUuBiIhkLAUiIpKxFIiISMZSICIiGUuBiIhkLAUiIpKxFIiISMZSICIiGUuBiIhkLAUiIpKxFIiISMZSICIimWpXSfX7/Xj22Wfx6aefIjIyEuPHj0d+fj6qqqqQk5ODpqYmmEwmOJ1OJCcnqxWLiIguoloprF27FpGRkSgtLYXBYEBDQwMAwOFwwG63IzMzE7t370Zubi5ef/11tWIREdFFVNl81NLSgpKSEmRnZ8NgMAAAEhMT4fP54PF4YLPZAAA2mw0ejweNjY1qxCIiokuosqZQU1MDk8mELVu24PPPP0dMTAyys7MRFRUFs9kMQRAAAIIgICkpCV6vF/Hx8WpEIyKii6hSCufOnUNNTQ2uv/56LFmyBEeOHMGDDz6IjRs3BmX+5eXlQZlPMLjdbq0jdEvvGfWeD2DGrii9heVAo9W/h1CMq0opDBs2DOHh4fJmonHjxiEuLg5RUVGoq6uDKIoQBAGiKKK+vh4Wi6VH809NTUVkZGQooveI2+3W/UKh94x6zwcwI3WkxXvdl8/Y7/d3+WValX0K8fHxmDx5Mj7++GMAQFVVFXw+H5KTk2G1WuFyuQAALpcLVquVm46IiDSi2tFHK1euxLJly+B0OhEeHo41a9YgNjYWeXl5yMnJQUFBAWJjY+F0OtWKREREl1CtFEaOHIm//vWvHaanpKSguLhYrRhERHQZPKOZiIhkLAUiIpKxFIiISMZSICIiGUuBiIhkLAUiIpKxFIiISMZSICIiGUuBiIhkLAUiIpKxFIiISMZSICIiGUuBiIhkLAUiIpKxFIiISMZSICIiGUuBiIhkLAUiIpKpdjvO9PR0GI1GREZGAgAWL16M3/72t6iqqkJOTg6amppgMpngdDqRnJysViwiIrqIaqUAAJs2bcLo0aPbTXM4HLDb7cjMzMTu3buRm5uL119/Xc1YRET0/zTdfOTz+eDxeGCz2QAANpsNHo8HjY2NWsYiIhq0VF1TWLx4MSRJQlpaGp544gl4vV6YzWYIggAAEAQBSUlJ8Hq9iI+PVzMaERGhB6Vw8OBBTJs2DeHhveuRoqIiWCwWtLa2YvXq1Vi1ahX+9Kc/9WpelyovLw/KfILB7XZrHaFbes+o93wAM3YlLS1N9TH1QKt/D6EYV/Ff+I0bN2L58uWYNWsWMjMzMW7cuB4NZLFYAABGoxF2ux0PPfQQli5dirq6OoiiCEEQIIoi6uvr5d9VKjU1Vd6BrSW32637hULvGfWeD2BG6kiL97ovn7Hf7+/yy7TifQp79uzBjh07EBkZicceewwZGRkoKChAbW1tt8/95Zdf0NzcDACQJAn79++H1WpFQkICrFYrXC4XAMDlcsFqtXLTERGRRnq0LWjs2LEYO3YsnnrqKXz66ad4/vnnsXnzZvz6179GVlYWbDYbwsI69ozP58Njjz0GURQRCASQkpICh8MBAMjLy0NOTg4KCgoQGxsLp9MZnFdGREQ91uMdBN9//z327NmDPXv2wGAwYOHChbBYLCgqKsKBAwewZcuWDs8ZOXIkSkpKOp1fSkoKiouLexyciIiCT3EpFBUVYffu3aiursatt96KNWvWYPz48fLPMzIy8Jvf/CYUGYmISCWKS+HDDz/EPffcgxkzZsBoNHb4+ZAhQ7B58+aghiMiInUpLoVNmzYhLCwMERER8rS2tjZIkiSXxNSpU4OfkIiIVKP46KN7770XR48ebTft6NGjWLBgQdBDERGRNhSXwrFjxzqcm3DjjTfi66+/DnooIiLShuJSiI2NRUNDQ7tpDQ0NGDJkSNBDERGRNhSXwsyZM/Hkk0+isrISZ8+exbFjx7BkyRLceuutocxHREQqUlwKixYtQkpKCubPny+frHbttdfiiSeeCGU+IiJSkeKjjyIjI+FwOJCbm4vTp08jLi4OBoMhlNmIiEhlPTqjubm5GVVVVWhpaWk3fcqUKUENRURE2lBcCm+++SZWrVqF6OhoREVFydMNBgMOHjwYknBERKQuxaWwfv16bNy4EdOmTQtlHiIi0pDiHc2iKPKMZSKiAU5xKdx333148cUXEQgEQpmHiIg0pHjz0Y4dO9DQ0IBXXnkFJpOp3c/ef//9IMciIiItKC6FtWvXhjIHERHpgOJSmDRpUihzEBGRDijep9Da2or169djxowZ8s2iP/roI+zcuTNk4YiISF2KS+HZZ59FZWUl1q1bJ5/JfN1112HXrl0hC0dEROpSXArvvvsuXnjhBdx0000ICzv/NLPZjLq6uh4NuGXLFowZMwaVlZUAgKqqKmRlZSEjIwNZWVk4ceJEj+ZHRETBo7gUIiIiIIpiu2mNjY0djkS6nKNHj+I///kPhg0bJk9zOByw2+0oLS2F3W5Hbm6u4vkREVFwKS6F3//+91iyZAlqamoAAPX19Vi1ahVmz56t6Pmtra1YtWoVHA6HvPnJ5/PB4/HAZrMBAGw2GzweDxobG3v6OoiIKAgUH320aNEirF27FnPnzsXZs2eRkZGB+fPn45FHHlH0/I0bN2Lu3LkYOXKkPM3r9cJsNkMQBACAIAhISkqC1+tFfHy84hdRXl6u+HdDze12ax2hW3rPqPd8ADN25cJBKIONVv8eQjGu4lIwGo1Yvnw5li9fjsbGxh5dOvuLL77AV199hcWLF/c66OWkpqYiMjIyJPPuCbfbrfuFQu8Z9Z4PYEbqSIv3ui+fsd/v7/LLtOJSuLDZ6IKLL5998bf/zpSVleH48eOYMWMGAODHH3/EggULsHTpUtTV1UEURQiCAFEUUV9fD4vFojQWEREFkeJS+N3vfgeDwQBJkuRpF9YUKioqLvvc+++/H/fff7/8OD09HYWFhRg9ejR27doFl8uFzMxMuFwuWK3WHm06IiKi4FFcCl9//XW7x6dOncKWLVswYcKEPgXIy8tDTk4OCgoKEBsbC6fT2af5ERFR7/XozmsXGzp0KJYvX46MjAzMmTOnR889dOiQ/P8pKSkoLi7ubQwiIgoixYekdub48eM4e/ZssLIQEZHGFK8p2O32dkcbnT17Ft9++63iQ1KJiEj/FJfC/Pnz2z0eMmQIxo4di+Tk5GBnIiIijSguhT/84Q+hzEFERDqguBQ2btyo6Peys7N7HYaIiLSluBSqq6tx4MABpKamYvjw4Th58iS++uorzJw5UxdnExMRUd8pLgVJkvDCCy8gIyNDnnbgwAG88847eO6550ISjoiI1KX4kNQPP/wQt9xyS7tpM2bMwAcffBD0UEREpA3FpTBq1CgUFRW1m/a3v/0N11xzTdBDERGRNhRvPnrmmWfw6KOP4pVXXpHvuBYeHo7NmzeHMh8REalIcSlcf/31KC0txZEjR1BfX4+hQ4di/PjxiIiICGU+IiJSUa8vczFx4kS0tbXhl19+CWYeIiLSkOI1hWPHjuGhhx6C0WhEXV0dZs2ahbKyMrz11lvYsGFDCCMSEZFaFK8p5OXlYeHChXjnnXcQHn6+SyZOnNgvbktIRETKKC6Fb7/9FpmZmQD+d3Od6Oho+P3+0CQjIiLVKS6F4cOHd7in55dffslDUomIBhDF+xSys7PxwAMP4Pbbb0dbWxu2bduGv//978jPzw9lPiIiUpHiNYWbb74ZL7/8MhobGzFx4kT88MMP2Lx5M6ZOnRrKfEREpCJFawqiKCIjIwP79+9HXl5erwZ6+OGHUVtbi7CwMERHR+Ppp5+G1WpFVVUVcnJy0NTUBJPJBKfTyXs0EBFpRNGagiAIEAShTzuVnU4n9uzZg5KSEtx7771YtmwZAMDhcMBut6O0tBR2ux25ubm9HoOIiPpG8eaju+++G48//jgOHz6M77//HjU1NfJ/Slx55ZXy/585cwYGgwE+nw8ejwc2mw0AYLPZ4PF40NjY2MOXQUREwdDt5qNTp05h6NCh8g7lTz75BJIkyT83GAyoqKhQNNjy5cvx8ccfQ5IkvPLKK/B6vTCbzRAEAcD5NZKkpCR4vV7Ex8f35vUQEVEfdFsKGRkZ+Pe//42vv/4aAPDII49g69atvRps9erVAICSkhKsWbMmaHdpu/RQWS31h5P59J5R7/kAZuxKWlqa6mPqgVb/HkIxbrelcPFaAQCUlZX1edB58+YhNzcXV199Nerq6iCKIgRBgCiKqK+vh8Vi6dH8UlNTdXH3N7fbrfuFQu8Z9Z4PYEbqSIv3ui+fsd/v7/LLdLf7FC6cvXzBpSWhREtLC7xer/z40KFDuOqqq5CQkACr1QqXywUAcLlcsFqt3HRERKSRbtcURFHEZ599JpfBpY8BYMqUKZedx9mzZ5GdnY2zZ88iLCwMV111FQoLC2EwGJCXl4ecnBwUFBQgNjYWTqezjy+JiIh6q9tSSEhIkA8fBQCTydTuscFgwMGDBy87j8TERPzjH//o9GcpKSkoLi5WmpeIiEKo21I4dOiQGjmIiEgHen2THSIiGnhYCkREJGMpEBGRjKVAREQylgIREclYCkREJGMpEBGRjKVAREQylgIREclYCkREJGMpEBGRjKVAREQylgIREclYCkREJGMpEBGRjKVAREQylgIREcm6vfNaMJw+fRpPPfUUvv/+exiNRowaNQqrVq1CfHw8qqqqkJOTg6amJphMJjidTiQnJ6sRi4iILqHKmoLBYMCf//xnlJaWYu/evRg5ciTWrVsHAHA4HLDb7SgtLYXdbkdubq4akYiIqBOqlILJZMLkyZPlx+PHj8fJkyfh8/ng8Xhgs9kAADabDR6PB42NjWrEIiKiS6i+TyEQCGDXrl1IT0+H1+uF2WyGIAgAAEEQkJSUBK/Xq3YsIiKCSvsULpafn4/o6Gjceeed8Hg8QZlneXl5UOYTDG63W+sI3dJ7Rr3nA5ixK2lpaaqPqQda/XsIxbiqloLT6UR1dTUKCwsRFhYGi8WCuro6iKIIQRAgiiLq6+thsVh6NN/U1FRERkaGKLVybrdb9wuF3jPqPR/AjNSRFu91Xz5jv9/f5Zdp1TYfrV+/HuXl5di6dSuMRiMAICEhAVarFS6XCwDgcrlgtVoRHx+vViwiIrqIKmsK33zzDQoLC5GcnIzbb78dADBixAhs3boVeXl5yMnJQUFBAWJjY+F0OtWIREREnVClFK677jocO3as05+lpKSguLhYjRhERNQNntFMREQylgIREclYCkREJGMpEBGRjKVAREQylgIREclYCkREJGMpEBGRjKVAREQylgIREclYCkREJGMpEBGRjKVAREQylgIREckGdSm0tgWCOj+ld0EK9rhERMGi+j2a9cQYEYZblx5Rfdy3nxun+phEREoM6jUFIiJqj6VAREQyVUrB6XQiPT0dY8aMQWVlpTy9qqoKWVlZyMjIQFZWFk6cOKFGHCIi6oIqpTBjxgwUFRVh+PDh7aY7HA7Y7XaUlpbCbrcjNzdXjThERNQFVUphwoQJsFgs7ab5fD54PB7YbDYAgM1mg8fjQWNjoxqRiIioE5rtU/B6vTCbzRAEAQAgCAKSkpLg9Xq1ikRENOgNiENSy8vLe/U8pecVhILb7R6UYyuh93wAM3ZFy2VKS1r9ewjFuJqVgsViQV1dHURRhCAIEEUR9fX1HTYzKZGamorIyMgQpAwdrRYet9ut6wVX7/kAZqSOtHiv+/IZ+/3+Lr9Ma7b5KCEhAVarFS6XCwDgcrlgtVoRHx+vVSQiokFPlTWFZ555BgcOHEBDQwPuuecemEwm7Nu3D3l5ecjJyUFBQQFiY2PhdDrViENERF1QpRRWrFiBFStWdJiekpKC4uJiNSIQEZECPKOZiIhkLIVBZqw1VZNxeWVYov5hQBySSsrFREfyyrBE1CWuKZAqlK4phOLQPq6lECnHNQVShVb3rgC4lkLUE1xTICIiGUuBiIhkLAUiIpKxFIiISMZSICLqA62ObgvVOUc8+oiIqA+0OrIuVEfVcU2BBrxgf5NTei6FludHaHXmOvV/XFOgAW+gfZNTgmeuU29xTYGIiGQsBQ3wsguDAz9n6o+4+UgDvOTD4MDPmfojrikQEZGMpUBERDKWAhERyXRRClVVVcjKykJGRgaysrJw4sQJrSMREQ1KuigFh8MBu92O0tJS2O125Obmah2JiGhQ0vzoI5/PB4/Hg+3btwMAbDYb8vPz0djYiPj4+Ms+V5IkAEBra2uvxzdFS71+bm/5/X5NxtVybL7mwTH2YBtXy7H9fn+vn3vhb+aFv6EXM0idTVVReXk5lixZgn379snTZs2ahbVr1+KGG2647HObm5tRWVkZ6ohERAPS6NGjceWVV7abpvmaQl/ExMRg9OjRiIiIgMFg0DoOEVG/IEkS2traEBMT0+FnmpeCxWJBXV0dRFGEIAgQRRH19fWwWCzdPjcsLKxDyxERUfeioqI6na75juaEhARYrVa4XC4AgMvlgtVq7XZ/AhERBZ/m+xQA4LvvvkNOTg5+/vlnxMbGwul04le/+pXWsYiIBh1dlAIREemD5puPiIhIP1gKREQkYykQEZGMpUBERDKWQhCcPn0a9913HzIyMjBnzhw8+uijaGxs1DpWp7Zs2YIxY8bo8kxwv98Ph8OBmTNnYs6cOXj66ae1jtTOe++9h3nz5iEzMxNz5szBgQMHtI4Ep9OJ9PT0Dp+pXi4y2Vk+vS0vXb2HF2i9zHSVL2TLi0R9dvr0aemzzz6THz///PPS0qVLNUzUufLycmnBggXS9OnTpWPHjmkdp4P8/Hxp9erVUiAQkCRJkk6dOqVxov8JBALShAkT5PetoqJCGj9+vCSKoqa5ysrKpJMnT0o333xzu8/0rrvukkpKSiRJkqSSkhLprrvu0k0+vS0vXb2HkqSPZaarfKFaXrimEAQmkwmTJ0+WH48fPx4nT57UMFFHra2tWLVqFRwOhy4vCdLS0oKSkhJkZ2fL+RITEzVO1V5YWBiam5sBnL/uVlJSEsLCtF2EJkyY0OHs/wsXmbTZbADOX2TS4/Fo8m28s3x6W146ywjoZ5npLF8olxfNL3Mx0AQCAezatQvp6elaR2ln48aNmDt3LkaOHKl1lE7V1NTAZDJhy5Yt+PzzzxETE4Ps7GxMmDBB62gAAIPBgA0bNuDhhx9GdHQ0WlpasG3bNq1jdcrr9cJsNkMQBACAIAhISkqC1+vV3ZUC9Lq8APpeZkK5vHBNIcjy8/MRHR2NO++8U+sosi+++AJfffUV7Ha71lG6dO7cOdTU1OD666/Hm2++icWLF+Oxxx7DmTNntI4G4Hy+bdu2oaCgAO+99x5efPFFLFq0CC0tLVpH69f0uLwA+l9mQrm8sBSCyOl0orq6Ghs2bNB8s8LFysrKcPz4ccyYMQPp6en48ccfsWDBAnz00UdaR5MNGzYM4eHh8iaPcePGIS4uDlVVVRonO6+iogL19fVIS0sDAKSlpWHIkCH47rvvNE7W0cUXmQTQo4tMqkmvywug/2UmlMuLvj6Jfmz9+vUoLy/H1q1bYTQatY7Tzv3334+PPvoIhw4dwqFDh3D11Vfj1VdfxdSpU7WOJouPj8fkyZPx8ccfAzh/9IzP58OoUaM0Tnbe1VdfjR9//BHHjx8HcP56XQ0NDbjmmms0TtZRf7jIpJ6XF0D/y0wolxde+ygIvvnmG9hsNiQnJ8uXox0xYgS2bt2qcbLOpaeno7CwEKNHj9Y6Sjs1NTVYtmwZmpqaEB4ejscffxzTpk3TOpZsz549ePnll+UdewsXLsQtt9yiaaZnnnkGBw4cQENDA+Li4mAymbBv3z7dXGSys3wbNmzQ1fLS1Xt4MS2Xma7yhWp5YSkQEZGMm4+IiEjGUiAiIhlLgYiIZCwFIiKSsRSIiEjGUiAiIhlLgYiIZCwFIiKS/R/K3ZjVO4do9AAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "results['plan-round_robin_lifo-always_process-5-100'].plot(x=\"pageviews\", y=\"updates\", kind=\"hist\")" + ] + }, + { + "cell_type": "code", + "execution_count": 159, + "id": "7af47144", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 159, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "results['plan-round_robin_lifo-always_process-5-100'].plot(x=\"pageviews\", y=\"optimal_updates\", kind=\"hist\")" + ] + }, + { + "cell_type": "code", + "execution_count": 163, + "id": "4d55378e", + "metadata": {}, + "outputs": [], + "source": [ + "optimal_plan_df = evaluate_plan(f'/home/eecs/wooders/experiments/wikipedia/optimal_plan.json', f'/home/eecs/wooders/experiments/wikipedia/optimal_plan.json', end_ts=end_ts)" + ] + }, + { + "cell_type": "code", + "execution_count": 208, + "id": "739fdc68", + "metadata": {}, + "outputs": [], + "source": [ + "n_fits = np.array(range(0, 250, 1)) #optimal_plan_df[\"updates\"].unique()\n", + "n_fits.sort()\n", + "n_fits_map = {v: i for i, v in enumerate(n_fits)}\n", + "n_fits_ticks = {i: v for i, v in enumerate(n_fits)}" + ] + }, + { + "cell_type": "code", + "execution_count": 209, + "id": "c34cc7c0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{0: 0,\n", + " 1: 1,\n", + " 2: 2,\n", + " 3: 3,\n", + " 4: 4,\n", + " 5: 5,\n", + " 6: 6,\n", + " 7: 7,\n", + " 8: 8,\n", + " 9: 9,\n", + " 10: 10,\n", + " 11: 11,\n", + " 12: 12,\n", + " 13: 13,\n", + " 14: 14,\n", + " 15: 15,\n", + " 16: 16,\n", + " 17: 17,\n", + " 18: 18,\n", + " 19: 19,\n", + " 20: 20,\n", + " 21: 21,\n", + " 22: 22,\n", + " 23: 23,\n", + " 24: 24,\n", + " 25: 25,\n", + " 26: 26,\n", + " 27: 27,\n", + " 28: 28,\n", + " 29: 29,\n", + " 30: 30,\n", + " 31: 31,\n", + " 32: 32,\n", + " 33: 33,\n", + " 34: 34,\n", + " 35: 35,\n", + " 36: 36,\n", + " 37: 37,\n", + " 38: 38,\n", + " 39: 39,\n", + " 40: 40,\n", + " 41: 41,\n", + " 42: 42,\n", + " 43: 43,\n", + " 44: 44,\n", + " 45: 45,\n", + " 46: 46,\n", + " 47: 47,\n", + " 48: 48,\n", + " 49: 49,\n", + " 50: 50,\n", + " 51: 51,\n", + " 52: 52,\n", + " 53: 53,\n", + " 54: 54,\n", + " 55: 55,\n", + " 56: 56,\n", + " 57: 57,\n", + " 58: 58,\n", + " 59: 59,\n", + " 60: 60,\n", + " 61: 61,\n", + " 62: 62,\n", + " 63: 63,\n", + " 64: 64,\n", + " 65: 65,\n", + " 66: 66,\n", + " 67: 67,\n", + " 68: 68,\n", + " 69: 69,\n", + " 70: 70,\n", + " 71: 71,\n", + " 72: 72,\n", + " 73: 73,\n", + " 74: 74,\n", + " 75: 75,\n", + " 76: 76,\n", + " 77: 77,\n", + " 78: 78,\n", + " 79: 79,\n", + " 80: 80,\n", + " 81: 81,\n", + " 82: 82,\n", + " 83: 83,\n", + " 84: 84,\n", + " 85: 85,\n", + " 86: 86,\n", + " 87: 87,\n", + " 88: 88,\n", + " 89: 89,\n", + " 90: 90,\n", + " 91: 91,\n", + " 92: 92,\n", + " 93: 93,\n", + " 94: 94,\n", + " 95: 95,\n", + " 96: 96,\n", + " 97: 97,\n", + " 98: 98,\n", + " 99: 99,\n", + " 100: 100,\n", + " 101: 101,\n", + " 102: 102,\n", + " 103: 103,\n", + " 104: 104,\n", + " 105: 105,\n", + " 106: 106,\n", + " 107: 107,\n", + " 108: 108,\n", + " 109: 109,\n", + " 110: 110,\n", + " 111: 111,\n", + " 112: 112,\n", + " 113: 113,\n", + " 114: 114,\n", + " 115: 115,\n", + " 116: 116,\n", + " 117: 117,\n", + " 118: 118,\n", + " 119: 119,\n", + " 120: 120,\n", + " 121: 121,\n", + " 122: 122,\n", + " 123: 123,\n", + " 124: 124,\n", + " 125: 125,\n", + " 126: 126,\n", + " 127: 127,\n", + " 128: 128,\n", + " 129: 129,\n", + " 130: 130,\n", + " 131: 131,\n", + " 132: 132,\n", + " 133: 133,\n", + " 134: 134,\n", + " 135: 135,\n", + " 136: 136,\n", + " 137: 137,\n", + " 138: 138,\n", + " 139: 139,\n", + " 140: 140,\n", + " 141: 141,\n", + " 142: 142,\n", + " 143: 143,\n", + " 144: 144,\n", + " 145: 145,\n", + " 146: 146,\n", + " 147: 147,\n", + " 148: 148,\n", + " 149: 149,\n", + " 150: 150,\n", + " 151: 151,\n", + " 152: 152,\n", + " 153: 153,\n", + " 154: 154,\n", + " 155: 155,\n", + " 156: 156,\n", + " 157: 157,\n", + " 158: 158,\n", + " 159: 159,\n", + " 160: 160,\n", + " 161: 161,\n", + " 162: 162,\n", + " 163: 163,\n", + " 164: 164,\n", + " 165: 165,\n", + " 166: 166,\n", + " 167: 167,\n", + " 168: 168,\n", + " 169: 169,\n", + " 170: 170,\n", + " 171: 171,\n", + " 172: 172,\n", + " 173: 173,\n", + " 174: 174,\n", + " 175: 175,\n", + " 176: 176,\n", + " 177: 177,\n", + " 178: 178,\n", + " 179: 179,\n", + " 180: 180,\n", + " 181: 181,\n", + " 182: 182,\n", + " 183: 183,\n", + " 184: 184,\n", + " 185: 185,\n", + " 186: 186,\n", + " 187: 187,\n", + " 188: 188,\n", + " 189: 189,\n", + " 190: 190,\n", + " 191: 191,\n", + " 192: 192,\n", + " 193: 193,\n", + " 194: 194,\n", + " 195: 195,\n", + " 196: 196,\n", + " 197: 197,\n", + " 198: 198,\n", + " 199: 199,\n", + " 200: 200,\n", + " 201: 201,\n", + " 202: 202,\n", + " 203: 203,\n", + " 204: 204,\n", + " 205: 205,\n", + " 206: 206,\n", + " 207: 207,\n", + " 208: 208,\n", + " 209: 209,\n", + " 210: 210,\n", + " 211: 211,\n", + " 212: 212,\n", + " 213: 213,\n", + " 214: 214,\n", + " 215: 215,\n", + " 216: 216,\n", + " 217: 217,\n", + " 218: 218,\n", + " 219: 219,\n", + " 220: 220,\n", + " 221: 221,\n", + " 222: 222,\n", + " 223: 223,\n", + " 224: 224,\n", + " 225: 225,\n", + " 226: 226,\n", + " 227: 227,\n", + " 228: 228,\n", + " 229: 229,\n", + " 230: 230,\n", + " 231: 231,\n", + " 232: 232,\n", + " 233: 233,\n", + " 234: 234,\n", + " 235: 235,\n", + " 236: 236,\n", + " 237: 237,\n", + " 238: 238,\n", + " 239: 239,\n", + " 240: 240,\n", + " 241: 241,\n", + " 242: 242,\n", + " 243: 243,\n", + " 244: 244,\n", + " 245: 245,\n", + " 246: 246,\n", + " 247: 247,\n", + " 248: 248,\n", + " 249: 249}" + ] + }, + "execution_count": 209, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "n_fits_map" + ] + }, + { + "cell_type": "code", + "execution_count": 195, + "id": "c768b43d", + "metadata": {}, + "outputs": [], + "source": [ + "import seaborn as sns\n", + "import numpy as np\n", + "sns.set(style=\"whitegrid\", palette=\"muted\")" + ] + }, + { + "cell_type": "code", + "execution_count": 200, + "id": "fc803fd4", + "metadata": {}, + "outputs": [], + "source": [ + "max_fits = 60 " + ] + }, + { + "cell_type": "code", + "execution_count": 211, + "id": "cfe761f5", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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E8XFxYiNjcWUKVOwYMGCOzpeHx8fXLp0Cc8//zyysrIQEBCABx54AC+99BIAwMvLC1999RUWL16Ml19+GTdu3EBgYCDatWuHmJgY2W3as05QUBC++eYbvP322xg/fjyKi4sRHByMF154AQDQrl07jB07Fq+88gqysrIwePBgvPHGGxb7evjhh3Hr1i0sXboU8+bNQ7169fDCCy9gxIgRd3ReiIio/KgEg6yJiKqEli1b4s0338SgQYMqdD/r1q3D7Nmzcfz48QrdDxERkTtgyB8REREREZGD2KAiIiIiIiJyEEP+iIiIiIiIHMQeKiIiIiIiIgexQUVEREREROQgNqiIiIiIiIgcxAYVERERERGRg9igIiIiIiIichAbVERERERERA5ig4qIiIiIiMhBbFARERERERE5iA2qSm7v3r3o1q2bq4tRIeLi4vDXX3+V6zaXLFmCadOmKc7v378/9u7de0f7MC730qVLMWvWLGneL7/8gu7duyM0NBTHjx+/o/2Ys3VsRFR1uXtdkZqaitDQUJSUlNhc9sqVK2jZsiWKi4srpCwVvf3yUFGfp7V6NzExEX369Lmj7ZuX27jOFULg5ZdfRkREBIYPH35H+5FTEfcURAZsUBEZ2bJlC6KiosptexMnTsRrr70m/b5o0SLMmTMHBw8exH333Vdu+yHnWrJkCdq0aYPQ0FDp3+XLlxWX37NnD8aMGYOwsDDExcVZzL9y5QrGjBmD9u3bo2/fvhaV/ubNmxEbG4sOHTpg0qRJyM7OLu9DInKpBg0a4ODBg9BoNHe8LT5cqhjh4eH46aefynWbxnXu/v378eeff+L333/H999/X677IeeKi4tDu3btpPrxscces7r84sWLMXDgQNx3331YsmSJxXxrdWBRURFefvlldOzYEV27dsWKFSvK+3DswgYV2c2dn9YZuHsZU1NT0aJFC1cXo1Kw50m1K8XHx+PgwYPSv8aNGysu6+vri2HDhuHFF1+Unf/CCy/gvvvuw969e/Hcc89h6tSpyMrKAgCcOXMGc+fOxZtvvok///wTPj4+mDdvXoUcExE5RggBvV7v6mJY5e71Y0pKCho2bAhfX19XF8XtuftnCZRG6Bjqx88//9zqssHBwZg2bRq6d+9uMc9WHbhkyRJcunQJO3bswMqVK7Fs2TLs2rWr3I/HFjaoKom4uDh88skn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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = plt.figure(figsize=(12, 12))\n", + "for i, plan_name in enumerate(results.keys()):\n", + " plan_file = f'{plan_dir}/{plan_name}.json'\n", + " plan_data_df = results[plan_name]\n", + " plt.subplot(4, 2, i + 1)\n", + " #plan, loss = run_lp(df, max_n_fits=max_n_fits)\n", + " #arr = np.array([(key, n_fits_map[fits]) for (key, fits) in plan.items()])\n", + " vals = plan_data_df[\"updates\"].tolist()\n", + " arr = np.array([(i, vals[i]) for i in range(len(vals))])\n", + " plt.scatter(arr[:, 0], arr[:, 1], label=max_n_fits)\n", + " plt.yticks(ticks=list(n_fits_ticks.keys()), labels=list(n_fits_ticks.values()))\n", + " plt.xlabel(\"key\")\n", + " plt.ylabel(\"n_fits\")\n", + " plt.legend()\n", + " plt.title(plan_name)\n", + "plt.suptitle(\"Sample plan selection\")\n", + "plt.tight_layout()" + ] + }, + { + "cell_type": "code", + "execution_count": 318, + "id": "ac3582ce", + "metadata": {}, + "outputs": [], + "source": [ + "df = pd.read_csv(\"/data/wooders/wikipedia/10042021_questions_revid_filtered.csv\", sep=\"\\t\")\n", + "df.columns = [\"question\", \"answer\", \"doc_id\", \"timestamp\", \"revid\", \"oldrevid\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 319, + "id": "e7485904", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
questionanswerdoc_idtimestamprevidoldrevid
0what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 00:16:27.42857210372125321037212489
1what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 00:32:54.85714410372125321037212489
2what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 00:49:22.28571610372125321037212489
3what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 01:05:49.71428810372125321037212489
4what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 01:22:17.14286010372125321037212489
.....................
127727who is the ayo??????Hunter B-15 (portrayed by Wunmi Mosaku) is an ...623726382021-09-01 20:46:09.23070010416509361041650818
127728who is the ayo??????Hunter B-15 (portrayed by Wunmi Mosaku) is an ...623726382021-09-01 21:30:27.69223610416509361041650818
127729who is the ayo??????Hunter B-15 (portrayed by Wunmi Mosaku) is an ...623726382021-09-01 22:14:46.15377210416509361041650818
127730who is the ayo??????Hunter B-15 (portrayed by Wunmi Mosaku) is an ...623726382021-09-01 22:59:04.61530810416509361041650818
127731who is the ayo??????Hunter B-15 (portrayed by Wunmi Mosaku) is an ...623726382021-09-01 23:43:23.07684410416509361041650818
\n", + "

127732 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " question \\\n", + "0 what is the most common death in 2021??????? \n", + "1 what is the most common death in 2021??????? \n", + "2 what is the most common death in 2021??????? \n", + "3 what is the most common death in 2021??????? \n", + "4 what is the most common death in 2021??????? \n", + "... ... \n", + "127727 who is the ayo?????? \n", + "127728 who is the ayo?????? \n", + "127729 who is the ayo?????? \n", + "127730 who is the ayo?????? \n", + "127731 who is the ayo?????? \n", + "\n", + " answer doc_id \\\n", + "0 A typical entry reports information in the fol... 65984422 \n", + "1 A typical entry reports information in the fol... 65984422 \n", + "2 A typical entry reports information in the fol... 65984422 \n", + "3 A typical entry reports information in the fol... 65984422 \n", + "4 A typical entry reports information in the fol... 65984422 \n", + "... ... ... \n", + "127727 Hunter B-15 (portrayed by Wunmi Mosaku) is an ... 62372638 \n", + "127728 Hunter B-15 (portrayed by Wunmi Mosaku) is an ... 62372638 \n", + "127729 Hunter B-15 (portrayed by Wunmi Mosaku) is an ... 62372638 \n", + "127730 Hunter B-15 (portrayed by Wunmi Mosaku) is an ... 62372638 \n", + "127731 Hunter B-15 (portrayed by Wunmi Mosaku) is an ... 62372638 \n", + "\n", + " timestamp revid oldrevid \n", + "0 2021-08-06 00:16:27.428572 1037212532 1037212489 \n", + "1 2021-08-06 00:32:54.857144 1037212532 1037212489 \n", + "2 2021-08-06 00:49:22.285716 1037212532 1037212489 \n", + "3 2021-08-06 01:05:49.714288 1037212532 1037212489 \n", + "4 2021-08-06 01:22:17.142860 1037212532 1037212489 \n", + "... ... ... ... \n", + "127727 2021-09-01 20:46:09.230700 1041650936 1041650818 \n", + "127728 2021-09-01 21:30:27.692236 1041650936 1041650818 \n", + "127729 2021-09-01 22:14:46.153772 1041650936 1041650818 \n", + "127730 2021-09-01 22:59:04.615308 1041650936 1041650818 \n", + "127731 2021-09-01 23:43:23.076844 1041650936 1041650818 \n", + "\n", + "[127732 rows x 6 columns]" + ] + }, + "execution_count": 319, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 320, + "id": "2d5a778a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "332667 32284\n", + "1305297 10610\n", + "66304621 5330\n", + "17888363 3900\n", + "67089631 3621\n", + "Name: doc_id, dtype: int64" + ] + }, + "execution_count": 320, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.doc_id.value_counts().head()" + ] + }, + { + "cell_type": "code", + "execution_count": 308, + "id": "f7546f77", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "60043578 590\n", + "51150040 510\n", + "68187748 470\n", + "66187257 450\n", + "64783122 370\n", + "Name: doc_id, dtype: int64" + ] + }, + "execution_count": 308, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.doc_id.value_counts().tail()" + ] + }, + { + "cell_type": "code", + "execution_count": 309, + "id": "5823be22", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "332667 5090\n", + "65984422 3769\n", + "68553225 1740\n", + "57798785 1410\n", + "56185392 1360\n", + "68294454 1200\n", + "66293350 1040\n", + "57817558 930\n", + "60043578 590\n", + "51150040 510\n", + "68187748 470\n", + "66187257 450\n", + "64783122 370\n", + "Name: doc_id, dtype: int64" + ] + }, + "execution_count": 309, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.doc_id.value_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": 310, + "id": "a8154736", + "metadata": {}, + "outputs": [], + "source": [ + "weights = df.doc_id.value_counts().to_dict()" + ] + }, + { + "cell_type": "code", + "execution_count": 311, + "id": "48960f20", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{332667: 5090,\n", + " 65984422: 3769,\n", + " 68553225: 1740,\n", + " 57798785: 1410,\n", + " 56185392: 1360,\n", + " 68294454: 1200,\n", + " 66293350: 1040,\n", + " 57817558: 930,\n", + " 60043578: 590,\n", + " 51150040: 510,\n", + " 68187748: 470,\n", + " 66187257: 450,\n", + " 64783122: 370}" + ] + }, + "execution_count": 311, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "weights" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2ade5579", + "metadata": {}, + "outputs": [], + "source": [ + "we" + ] } ], "metadata": { diff --git a/wikipedia/preprocessing/wiki_api_data.py b/wikipedia/preprocessing/wiki_api_data.py index 4928566..fc4b01d 100644 --- a/wikipedia/preprocessing/wiki_api_data.py +++ b/wikipedia/preprocessing/wiki_api_data.py @@ -15,12 +15,16 @@ from multiprocessing import Pool +import wandb + # from concurrent.futures import ProcessPoolExecutor # from generate diffs file (originally from DPR repo... sorry kevin) from generate_diffs import generate_sentence_level_diffs from embedding import generate_embeddings +from log_data import log_files, log_pageview, log_simulation, log_questions + def query_recentchanges(start_time, end_time, revision_file): from bs4 import BeautifulSoup @@ -589,7 +593,7 @@ def check_dataset( if __name__ == "__main__": - print("starting script") + run = wandb.init(job_type="dataset-creation", project="wiki-workload") # configuration file config = configparser.ConfigParser() @@ -662,6 +666,7 @@ def check_dataset( print("Generated titles file", titles_file) edits_df = get_edits(edits_file, changes_file, titles_file) print("Generated edits file", edits_file) + log_files(run, config) # query document versions for list of titles if args.run_query_doc_versions: @@ -681,10 +686,12 @@ def check_dataset( if args.run_get_questions: questions_df = get_questions(raw_questions_file, questions_file) print("Generated questions file", raw_questions_file, questions_file) + log_questions(run, config) # generate pageviews / compute page weights if args.run_get_pageviews: get_pageviews(raw_pageview_file, pageview_file, edits_file, timestamp_weights_file) + log_pageview(run, config) # generate diffs between document versions if args.run_generate_diffs: @@ -704,6 +711,7 @@ def check_dataset( stream_edits_file, stream_questions_file, ) + log_simulation(run, config) # run tests to validate simulation data if args.run_check_dataset: diff --git a/wikipedia/run_0_generate_data.sh b/wikipedia/run_0_generate_data.sh new file mode 100644 index 0000000..5d92ff6 --- /dev/null +++ b/wikipedia/run_0_generate_data.sh @@ -0,0 +1 @@ +python preprocessing/wiki_api_data.py --run_generate_simulation_data --run_get_questions diff --git a/wikipedia/run_1_generate_plan.sh b/wikipedia/run_1_generate_plan.sh new file mode 100644 index 0000000..debb1e6 --- /dev/null +++ b/wikipedia/run_1_generate_plan.sh @@ -0,0 +1,16 @@ +set -xe + +for key_policy in "random" "weighted_random" "round_robin" "weighted_round_robin" +do + for event_policy in "fifo" "lifo" + do + for load_shedding_policy in "always_process" + do + for model_runtime in 0.01 0.05 0.1 1 5 10 + do + python simulate.py --model_runtime $model_runtime --send_rate 100 \ + --event_policy $event_policy --key_policy $key_policy --load_shedding_policy $load_shedding_policy + done + done + done +done diff --git a/wikipedia/run_2_prepare_data.sh b/wikipedia/run_2_prepare_data.sh new file mode 100644 index 0000000..ff2b74e --- /dev/null +++ b/wikipedia/run_2_prepare_data.sh @@ -0,0 +1,18 @@ +set -xe + +plan_dir=/data/wooders/wiki-plans + +for key_policy in "round_robin" "weighted_round_robin" #"random" "weighted_random" +do + for event_policy in "lifo" "fifo" + do + for load_shedding_policy in "always_process" + do + for model_runtime in 0.01 0.05 0.1 1 5 10 + do + python wiki_eval.py --offline-plan-path ${plan_dir}/plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100.json + done + done + done +done +p diff --git a/wikipedia/run_3_run_predictions.sh b/wikipedia/run_3_run_predictions.sh new file mode 100644 index 0000000..6655996 --- /dev/null +++ b/wikipedia/run_3_run_predictions.sh @@ -0,0 +1,26 @@ +set -xe + +plan_dir=/data/wooders/wiki-plans +dpr_dir=~/DPR + +cd $dpr_dir + +for key_policy in "round_robin" "weighted_round_robin" +#for key_policy in "random" "weighted_random" +do + for event_policy in "lifo" + do + for load_shedding_policy in "always_process" + do + for model_runtime in 0.01 0.05 0.1 1 5 + do + plan_file=plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100 + echo $plan_file + CUDA_VISIBLE_DEVICES=1,2,5 bash ${dpr_dir}/evaluate_retrieval_single_doc_stream.sh $plan_file & + pid=$! + done + #wait $pid + done + done +done +p diff --git a/wikipedia/run_4_run_optimal_predictions.sh b/wikipedia/run_4_run_optimal_predictions.sh new file mode 100644 index 0000000..542d828 --- /dev/null +++ b/wikipedia/run_4_run_optimal_predictions.sh @@ -0,0 +1,8 @@ +set -xe + +plan_dir=/data/wooders/wiki-plans +dpr_dir=~/DPR +cd $dpr_dir +plan_file="optimal_plan" +echo $plan_file +CUDA_VISIBLE_DEVICES=5 bash ${dpr_dir}/evaluate_retrieval_single_doc_stream.sh $plan_file diff --git a/wikipedia/simulate.py b/wikipedia/simulate.py index d636647..5162e99 100644 --- a/wikipedia/simulate.py +++ b/wikipedia/simulate.py @@ -7,9 +7,12 @@ import random import configparser +import argparse import pandas as pd +import wandb + import simpy from ralf.state import Record from ralf.policies.load_shedding_policy import ( @@ -39,6 +42,8 @@ from typing import Dict, List, Tuple, Type +from preprocessing.log_data import log_plans + def current_weights(ts, ts_to_weights): ts = int(ts) min_dist = max(list(ts_to_weights.keys())) @@ -89,15 +94,12 @@ def __init__(self, pageview_file, all_keys): #assert self.weights[key] > 0, f"Too small {key}, {self.raw_weights[key]}" if self.weights[key] == 0: self.weights[key] = 1 - print(self.weights) for key in self.weights.keys(): for i in range(self.weights[key]): self.cur_key_set.append(str(key)) random.shuffle(self.cur_key_set) - print(self.cur_key_set) - print("size", len(self.cur_key_set)) self.cur_key_iter = itertools.cycle(self.cur_key_set) @@ -125,15 +127,12 @@ def __init__(self, timestamp_weights_file): self.weights[key] = int(self.raw_weights[key]*1000) assert self.weights[key] > 0, f"Too small {key}, {self.raw_weights[key]}" - print(self.weights) for key in self.weights.keys(): for i in range(self.weights[key]): self.cur_key_set.append(str(key)) random.shuffle(self.cur_key_set) - print(self.cur_key_set) - print("size", len(self.cur_key_set)) self.cur_key_iter = itertools.cycle(self.cur_key_set) @@ -168,10 +167,7 @@ def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], timestamp: int) keys.append(key) weights.append(weights_map[key]) total_len += size - print(weights) - print(keys) chosen_key = random.choices(keys, weights, k=1)[0] - print("choose", chosen_key, keys, weights) return chosen_key @@ -180,7 +176,6 @@ class WeightedLoadBalancer(CrossKeyLoadBalancer): def __init__(self, pageview_file): pageview_df = pd.read_csv(pageview_file) self.weights = pageview_df.set_index("doc_id")["weights"].to_dict() - #print(self.weights) def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: chosen_key = None @@ -278,7 +273,6 @@ def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: max_len = size total_len += size per_key_queues[chosen_key].clear() - print("clear", chosen_key, total_len, per_key_queues[chosen_key].size()) return chosen_key @@ -372,7 +366,7 @@ def run(self, replica_id: int): def run_once( out_path: str, prioritization_policy: str, - load_sheeding_policy: str, + load_shedding_policy: str, keys: List[str], per_key_records_per_second: int, total_runtime_s: float, @@ -387,7 +381,7 @@ def run_once( key: PerKeyPriorityQueue( env, processing_policy=policies[prioritization_policy], - load_shedding_policy=policies[load_sheeding_policy], + load_shedding_policy=policies[load_shedding_policy], ) for key in keys } @@ -425,41 +419,67 @@ def run_once( if __name__ == "__main__": + # argument flags + parser = argparse.ArgumentParser() + parser.add_argument("--send_rate", type=int) + parser.add_argument("--model_runtime", type=float) + parser.add_argument("--total_runtime", type=float, default=len(edits)) + parser.add_argument("--event_policy", type=str) + parser.add_argument("--key_policy", type=str) + parser.add_argument("--load_shedding_policy", type=str) + args = parser.parse_args() + + out_path = f"{plan_dir}/plan-{args.key_policy}_{args.event_policy}-{args.load_shedding_policy}-{args.model_runtime}-{args.send_rate}.json" + print(out_path) + run_once( + out_path=out_path, + prioritization_policy=args.event_policy, + load_shedding_policy=args.load_shedding_policy, + keys=keys, + per_key_records_per_second=args.send_rate, + total_runtime_s=args.total_runtime, + model_runtime_constant=args.model_runtime, + key_selection_policy=args.key_policy, + ) + run = wandb.init(job_type="dataset-creation", project="wiki-workload") + log_plans(run, config, out_path) + + # load sheding: random, drop short edits # prioritization: prioritize most recent version # cross-key prioritzation: historical page views, # policies - prioritization_policies = ["lifo"] # ["fifo", "lifo"] - #key_selection_policies = ["adaptive_weighted_random", "weighted_round_robin", "weighted_random", "weighted_longest_queue", "longest_queue", "random", "round_robin"] - key_selection_policies = ["round_robin"] - load_shedding_policies = ["always_process"] - #model_runtimes = [0.01, 0.05, 0.1, 1, 5, 10] # [0.000001, 0.00001, 0.0000001, 0.000000001, 0] - model_runtimes = [0.02, 0.05, 0.07] # [0.000001, 0.00001, 0.0000001, 0.000000001, 0] - records_per_second = [100] - - output_files = [] - - for key_selection in key_selection_policies: - for prio_policy in prioritization_policies: - for load_shed_policy in load_shedding_policies: - for runtime in model_runtimes: - for rate in records_per_second: - - out_path = f"{plan_dir}/plan-{key_selection}_{prio_policy}-{load_shed_policy}-{runtime}-{rate}.json" - print("running", out_path, runtime) - run_once( - out_path, - prio_policy, - load_shed_policy, - keys, - per_key_records_per_second=rate, - total_runtime_s=len(edits), - model_runtime_constant=runtime, - key_selection_policy=key_selection, - ) - - output_files.append(out_path) - print("DONE", out_path) - for f in output_files: - print(f) - open("plans.txt", "w").write("\n".join(output_files)) + #prioritization_policies = ["lifo"] # ["fifo", "lifo"] + ##key_selection_policies = ["adaptive_weighted_random", "weighted_round_robin", "weighted_random", "weighted_longest_queue", "longest_queue", "random", "round_robin"] + #key_selection_policies = ["round_robin"] + #load_shedding_policies = ["always_process"] + ##model_runtimes = [0.01, 0.05, 0.1, 1, 5, 10] # [0.000001, 0.00001, 0.0000001, 0.000000001, 0] + #model_runtimes = [0.02, 0.05, 0.07] # [0.000001, 0.00001, 0.0000001, 0.000000001, 0] + #records_per_second = [100] + + #output_files = [] + + #for key_selection in key_selection_policies: + # for prio_policy in prioritization_policies: + # for load_shed_policy in load_shedding_policies: + # for runtime in model_runtimes: + # for rate in records_per_second: + + # out_path = f"{plan_dir}/plan-{key_selection}_{prio_policy}-{load_shed_policy}-{runtime}-{rate}.json" + # print("running", out_path, runtime) + # run_once( + # out_path, + # prio_policy, + # load_shed_policy, + # keys, + # per_key_records_per_second=rate, + # total_runtime_s=len(edits), + # model_runtime_constant=runtime, + # key_selection_policy=key_selection, + # ) + + # output_files.append(out_path) + # print("DONE", out_path) + #for f in output_files: + # print(f) + #open("plans.txt", "w").write("\n".join(output_files)) From 7728c353930d300ca67c31ce14d75a40f31a99ed Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Tue, 12 Oct 2021 15:58:39 -0700 Subject: [PATCH 13/26] parallelize preprocessing --- wikipedia/notebooks/Wikipedia Plots.ipynb | 1540 ++------------------ wikipedia/preprocessing/log_data.py | 72 + wikipedia/run_1_generate_plan.sh | 4 +- wikipedia/run_2_prepare_data.sh | 2 +- wikipedia/run_3_run_predictions.sh | 6 +- wikipedia/run_4_run_optimal_predictions.sh | 4 +- wikipedia/run_5_pipeline_predict.sh | 30 + wikipedia/simulate.py | 56 +- wikipedia/wiki_eval.py | 213 +-- 9 files changed, 353 insertions(+), 1574 deletions(-) create mode 100644 wikipedia/preprocessing/log_data.py create mode 100644 wikipedia/run_5_pipeline_predict.sh diff --git a/wikipedia/notebooks/Wikipedia Plots.ipynb b/wikipedia/notebooks/Wikipedia Plots.ipynb index 29bf8cb..08f0f5a 100644 --- a/wikipedia/notebooks/Wikipedia Plots.ipynb +++ b/wikipedia/notebooks/Wikipedia Plots.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 237, + "execution_count": null, "id": "e0030940", "metadata": {}, "outputs": [], @@ -24,58 +24,10 @@ }, { "cell_type": "code", - "execution_count": 238, + "execution_count": null, "id": "016e13bb", "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "Finishing last run (ID:1i504fr1) before initializing another..." - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "Successfully finished last run (ID:1i504fr1). Initializing new run:
" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[34m\u001b[1mwandb\u001b[0m: wandb version 0.12.4 is available! To upgrade, please run:\n", - "\u001b[34m\u001b[1mwandb\u001b[0m: $ pip install wandb --upgrade\n" - ] - }, - { - "data": { - "text/html": [ - "\n", - " Syncing run resilient-planet-72 to Weights & Biases (docs).
\n", - "\n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "run = wandb.init(job_type=\"evaluation\", project=\"wiki-workload\")\n", "pageview_dir = run.use_artifact('pageviews:latest').download()\n", @@ -84,385 +36,10 @@ }, { "cell_type": "code", - "execution_count": 239, + "execution_count": null, "id": "7690f6d7", "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Unnamed: 0titleedit_count2021080500202108060020210807002021080800202108090020210810002021081100...20210828002021082900202108300020210831002021090100202109020020210903002021090400weightsdoc_id
00Deaths in 20211877383536313496656...69506368505239460.02851165984422
112021 Atlantic hurricane season14381151689714...820285121150.00380557798785
22Neeraj Chopra11563732434...560492130.00217051150040
33Fall of Kabul (2021)10091891212161012...11169920155100.00487668481047
44Great Britain at the 2020 Summer Paralympics989135641689...3868107470.00339760043578
..................................................................
211211List of fungi of South Africa203897132149...10761135560.00346768354495
212212Mister Supranational 2021203897132149...10761135560.00346767918135
2132132021–22 FC Barcelona season20219292927282723...21262916272043180.01269867089631
214214Hamid Karzai International Airport20114261517261417...1910251326142270.007258487602
215215Characters of the Marvel Cinematic Universe20114261517261417...1910251326142270.00725862372638
\n", - "

216 rows × 36 columns

\n", - "
" - ], - "text/plain": [ - " Unnamed: 0 title edit_count \\\n", - "0 0 Deaths in 2021 1877 \n", - "1 1 2021 Atlantic hurricane season 1438 \n", - "2 2 Neeraj Chopra 1156 \n", - "3 3 Fall of Kabul (2021) 1009 \n", - "4 4 Great Britain at the 2020 Summer Paralympics 989 \n", - ".. ... ... ... \n", - "211 211 List of fungi of South Africa 203 \n", - "212 212 Mister Supranational 2021 203 \n", - "213 213 2021–22 FC Barcelona season 202 \n", - "214 214 Hamid Karzai International Airport 201 \n", - "215 215 Characters of the Marvel Cinematic Universe 201 \n", - "\n", - " 2021080500 2021080600 2021080700 2021080800 2021080900 2021081000 \\\n", - "0 38 35 36 31 349 66 \n", - "1 11 5 16 8 9 7 \n", - "2 3 7 3 2 4 3 \n", - "3 18 9 12 12 16 10 \n", - "4 13 5 6 4 16 8 \n", - ".. ... ... ... ... ... ... \n", - "211 8 9 7 13 21 4 \n", - "212 8 9 7 13 21 4 \n", - "213 19 29 29 27 28 27 \n", - "214 14 26 15 17 26 14 \n", - "215 14 26 15 17 26 14 \n", - "\n", - " 2021081100 ... 2021082800 2021082900 2021083000 2021083100 \\\n", - "0 56 ... 69 50 63 68 \n", - "1 14 ... 8 20 2 8 \n", - "2 4 ... 5 6 0 4 \n", - "3 12 ... 11 16 9 9 \n", - "4 9 ... 3 8 6 8 \n", - ".. ... ... ... ... ... ... \n", - "211 9 ... 10 7 6 1 \n", - "212 9 ... 10 7 6 1 \n", - "213 23 ... 21 26 29 16 \n", - "214 17 ... 19 10 25 13 \n", - "215 17 ... 19 10 25 13 \n", - "\n", - " 2021090100 2021090200 2021090300 2021090400 weights doc_id \n", - "0 50 52 39 46 0.028511 65984422 \n", - "1 5 12 11 5 0.003805 57798785 \n", - "2 9 2 1 3 0.002170 51150040 \n", - "3 20 15 5 10 0.004876 68481047 \n", - "4 10 7 4 7 0.003397 60043578 \n", - ".. ... ... ... ... ... ... \n", - "211 13 5 5 6 0.003467 68354495 \n", - "212 13 5 5 6 0.003467 67918135 \n", - "213 27 20 43 18 0.012698 67089631 \n", - "214 26 14 22 7 0.007258 487602 \n", - "215 26 14 22 7 0.007258 62372638 \n", - "\n", - "[216 rows x 36 columns]" - ] - }, - "execution_count": 239, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "pageview_df = pd.read_csv(f\"{pageview_dir}/pageviews.csv\")\n", "pageview_df" @@ -470,31 +47,10 @@ }, { "cell_type": "code", - "execution_count": 240, + "execution_count": null, "id": "5b5d1edc", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 240, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAs0AAAFoCAYAAACsdsZBAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAABpNUlEQVR4nO3deXhU1f0/8Pe9d9ZshAQSEhIIRIGwCQRFRRERCZVocAEsShctfm1dWm1tta0sSq1Yf21da8W6FVfUgkREBBdAlCUgEMImBMISEpIQss527/n9cWcmGbJMkhmYZHi/noeHZObOzJnkJnnPmc/5HEkIIUBERERERC2SQz0AIiIiIqLOjqGZiIiIiMgPhmYiIiIiIj8YmomIiIiI/GBoJiIiIiLywxDqAfijaRpqa2thNBohSVKoh0NEREREYUoIAafTicjISMiy79xypw/NtbW12LdvX6iHQURERETniQEDBiA6Otrnsk4fmo1GIwB98CaT6Zw/fn5+PoYOHXrOH5e6Lp4z1BE8b6i9eM5QR/C8aZ3D4cC+ffu8+bOxTh+aPSUZJpMJZrM5JGMI1eNS18VzhjqC5w21F88Z6gieN/41VxLMhYBERERERH4wNBMRERER+cHQTERERETkR6evaSYiIiIKBqfTiaNHj8Jms4V6KCFjMBiwe/fuUA8j5CwWC1JSUppd8NcShmYiIiI6Lxw9ehTR0dFIS0s7b/d+qK2tRWRkZKiHEVJCCJSXl+Po0aPo169fm2/H8gwiIiI6L9hsNsTHx5+3gZl0kiQhPj6+3e84MDQTERHReYOBmYCOnQcMzUREREREfjA0ExEREXVSR48exZgxYwAAJSUlmDVrlve65557Dg6Hw+99vP3225g8eTKmTp2K2traszbWcMfQTERERNQFJCYm4r///a/38+effx5Op9Pv7f773//iqaeewtKlS5ssAnS5XEEfZ7hi9wwiIiI676zeWoFVWyrOyn1PGh2HiaPi/B63fft2PP30097Z3/vvvx/jx4/HW2+9hddffx09e/bEJZdc4j3+6NGjuPnmm7Fx40bMnz8fAHDrrbdClmX897//RUxMTJPH+M1vfoMjR47g97//PYYMGYK7774bt99+O26//XZs2LABN9xwA6655hosWLAAx48fh91ux5QpU3D33XcDALZs2YL58+fDbDZjxIgRWLNm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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "df = pd.DataFrame({\n", " \"edit_frequency\": pageview_df.edit_count / pageview_df.edit_count.sum(),\n", @@ -514,106 +70,10 @@ }, { "cell_type": "code", - "execution_count": 241, + "execution_count": null, "id": "39b1975e", "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "Finishing last run (ID:h5pqozf8) before initializing another..." - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
Waiting for W&B process to finish, PID 38831... (success)." - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "VBox(children=(Label(value=' 0.68MB of 0.68MB uploaded (0.00MB deduped)\\r'), FloatProgress(value=1.0, max=1.0)…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - "
\n", - "
\n", - "
\n", - "Synced 6 W&B file(s), 0 media file(s), 0 artifact file(s) and 1 other file(s)\n", - "
Synced resilient-planet-72: https://wandb.ai/ucb-ralf/wiki-workload%20/runs/h5pqozf8
\n", - "Find logs at: ./wandb/run-20211011_174530-h5pqozf8/logs
\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "Successfully finished last run (ID:h5pqozf8). Initializing new run:
" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[34m\u001b[1mwandb\u001b[0m: wandb version 0.12.4 is available! To upgrade, please run:\n", - "\u001b[34m\u001b[1mwandb\u001b[0m: $ pip install wandb --upgrade\n" - ] - }, - { - "data": { - "text/html": [ - "\n", - " Syncing run stoic-blaze-73 to Weights & Biases (docs).
\n", - "\n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "run = wandb.init(job_type=\"evaluation\", project=\"wiki-workload\")\n", "artifact = run.use_artifact('prediction_results:latest')\n", @@ -622,29 +82,18 @@ }, { "cell_type": "code", - "execution_count": 242, + "execution_count": null, "id": "101571e2", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'./artifacts/prediction_results:v1'" - ] - }, - "execution_count": 242, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "artifact_dir" ] }, { "cell_type": "code", - "execution_count": 289, - "id": "c106b186", + "execution_count": null, + "id": "03e14929", "metadata": {}, "outputs": [], "source": [ @@ -653,60 +102,24 @@ }, { "cell_type": "code", - "execution_count": 290, + "execution_count": null, "id": "eaf30e01", "metadata": {}, "outputs": [], "source": [ "constants = [0.01, 0.05, 0.1, 1, 5]\n", "policies = [\"lifo\"]\n", - "key_policies = [\"random\", \"weighted_random\"]\n", + "key_policies = [\"random\", \"weighted_random\", \"round_robin\", \"weighted_round_robin\"]\n", "d = artifact_dir\n", - "metric = 'top5'" + "metric = 'top10'" ] }, { "cell_type": "code", - "execution_count": 291, - "id": "25eb4c0d", + "execution_count": null, + "id": "96209574", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/home/eecs/wooders/DPR/plan-random_lifo-always_process-0.01-100.json\n", - "/home/eecs/wooders/DPR/plan-random_lifo-always_process-0.05-100.json\n", - "/home/eecs/wooders/DPR/plan-random_lifo-always_process-0.1-100.json\n", - "/home/eecs/wooders/DPR/plan-random_lifo-always_process-1-100.json\n", - "/home/eecs/wooders/DPR/plan-random_lifo-always_process-5-100.json\n", - "/home/eecs/wooders/DPR/plan-weighted_random_lifo-always_process-0.01-100.json\n", - "/home/eecs/wooders/DPR/plan-weighted_random_lifo-always_process-0.05-100.json\n", - "/home/eecs/wooders/DPR/plan-weighted_random_lifo-always_process-0.1-100.json\n", - "/home/eecs/wooders/DPR/plan-weighted_random_lifo-always_process-1-100.json\n", - "/home/eecs/wooders/DPR/plan-weighted_random_lifo-always_process-5-100.json\n" - ] - }, - { - "data": { - "text/plain": [ - "{'plan-random_lifo-always_process': [0.41722204591135087,\n", - " 0.41605839416058393,\n", - " 0.3628477731936951,\n", - " 0.19216121866074262,\n", - " 0.20681265206812652],\n", - " 'plan-weighted_random_lifo-always_process': [0.4166931132973659,\n", - " 0.4052681688352904,\n", - " 0.3899820162911245,\n", - " 0.256373637998519,\n", - " 0.17237913889770443]}" - ] - }, - "execution_count": 291, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "all_results = {}\n", "for policy in policies: \n", @@ -724,44 +137,10 @@ }, { "cell_type": "code", - "execution_count": 228, + "execution_count": null, "id": "d3b31501", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'plan-weighted_round_robin_lifo-always_process': [0.7134603189515466,\n", - " 0.14824122570088702,\n", - " 0.13923792971165966,\n", - " 0.14143003656121067,\n", - " 0.1144984381238697,\n", - " 0.12701693402541278],\n", - " 'plan-weighted_random_lifo-always_process': [0.7100077506635037,\n", - " 0.1506368853293249,\n", - " 0.15045681940954037,\n", - " 0.13972332479977453,\n", - " 0.11063093532501898,\n", - " 0.12261706242024253],\n", - " 'plan-random_lifo-always_process': [0.699352545584079,\n", - " 0.14759142259905583,\n", - " 0.15119274099474678,\n", - " 0.12415936616796236,\n", - " 0.11849120417126617,\n", - " 0.11131988319202073],\n", - " 'plan-round_robin_lifo-always_process': [0.6862547071580117,\n", - " 0.14121082587625558,\n", - " 0.14572030282390336,\n", - " 0.12318857599173262,\n", - " 0.11423225372070993,\n", - " 0.11082665915087175]}" - ] - }, - "execution_count": 228, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "all_results = {}\n", "for policy in policies: \n", @@ -770,6 +149,7 @@ " name = f\"plan-{key_policy}_{policy}-always_process\"\n", " for constant in constants: \n", " with open(f'{d}/{name}-{constant}-100.json') as results_file:\n", + " print(f'{d}/{name}-{constant}-100.json')\n", " results = json.load(results_file)\n", " scores.append(results[metric])\n", " all_results[name] = scores\n", @@ -778,45 +158,22 @@ }, { "cell_type": "code", - "execution_count": 229, + "execution_count": null, "id": "b479a2bc", "metadata": { "scrolled": true }, - "outputs": [ - { - "data": { - "text/plain": [ - "dict_keys(['plan-weighted_round_robin_lifo-always_process', 'plan-weighted_random_lifo-always_process', 'plan-random_lifo-always_process', 'plan-round_robin_lifo-always_process'])" - ] - }, - "execution_count": 229, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "all_results.keys()" ] }, { "cell_type": "code", - "execution_count": 230, + "execution_count": null, "id": "332c0ff6", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[0.7100077506635037, 0.1506368853293249, 0.15045681940954037, 0.13972332479977453, 0.11063093532501898, 0.12261706242024253]\n", - "[0.11061527741895076, 0.11378600339776562, 0.11060744846591665, 0.11156258073607817, 0.11068573799625776, 0.11357462166584463]\n", - "[0.11424008267374404, 0.11315185820200264, 0.127032591931481, 0.11396606931755017, 0.11010639547173356, 0.11089711972817876]\n", - "[0.699352545584079, 0.14759142259905583, 0.15119274099474678, 0.12415936616796236, 0.11849120417126617, 0.11131988319202073]\n", - "[0.6862547071580117, 0.14121082587625558, 0.14572030282390336, 0.12318857599173262, 0.11423225372070993, 0.11082665915087175]\n" - ] - } - ], + "outputs": [], "source": [ "plan_weighted_random_lifo = []\n", "for constant in constants:\n", @@ -856,7 +213,7 @@ }, { "cell_type": "code", - "execution_count": 231, + "execution_count": null, "id": "6d536763", "metadata": {}, "outputs": [], @@ -867,21 +224,10 @@ }, { "cell_type": "code", - "execution_count": 232, + "execution_count": null, "id": "1e07c3e9", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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s037duzYwYQJE4iJiSE5OZnIyEjmz59PTEwMzz//POPHjwdur/v9n//8h2+//ZbVq1czZ84c7Ozs2LFjB+vWrWPRokWsWLGCAQMG8P777wO3l6bs27cv0dHRxMbG0rx5cwCmTp3Kl19+SXR0NMuXL6d8+fJ3v2hmUA+aiMh96t69OwBVqlShevXq7Nq1i9atW2crs3nzZhYvXkxKSkqOIbLixYvz4osvAph6UXLzwgsvMHToUFJTU0lISGDUqFH88MMPuLm5UbVqVYoVK8bPP//MiRMnePXVV02fS09P56+//spW1/bt22nRogUuLi4AdO3aldWrVxc4ppSUFLZv386FCxdM265fv05iYiKurq4UK1bM9BxThw4dCA0NzaMVs59nxYoVAfj999+pVq0azz33nCnOcePGce3aNbPqcXd3B6B27dqm5Cc+Pp5OnTrh6OiIo6MjHTt2JCEh4a71derUyfTztm3beP/99zEYDDg7O+Pn58e2bdto0aKFqayDgwMODg506NCBuLg4U3veqU2bNhQpUgSA6tWrc+LECZo0aXLXWPJz9OhRHB0dady4MXA7uXJ0dOTo0aN4enrmKJ/fvZnl2Wef5datW5w5c4Zt27YxfPhw5syZQ0BAgKm3DG4PtcbExJCWlkZKSgqVKlUCoFmzZkyePJnExEQATp48aWqPypUr889//pNmzZrRsmVLnJ2d8z2/li1b8tRTTwHQrVs3JkyYYNrXvHlz0z0dHx9PixYtKFu2LAC9evUiMDAQgA0bNvDKK6+YjvXkk08C8J///IcDBw6Y/ps2Go1cuXIFgIYNGzJ37lxOnz5NkyZNqF27NgC+vr6EhITQunVrWrZsSYUKFfKN31xK0ERELMhoNOYYovrzzz+ZPHkyy5Yto0KFCiQkJGTrBXJycjL9bGdnZ/ojOWfOHNavXw9ASEgIvr6+eHp6smbNGsqUKYOvry8RERGUK1cu28PczZo1Y+rUqTliy/rjmFecd8orpr/LzMzEYDCwbNkyHB0ds+07cOBAnvXnp0SJEmbFaW9vT2Zmpun3W7duZduflfhklc16nu1en026s2cnt7jyijO/c8grxvuR1/EMBgM///yzqYcsICCA9u3b53tv3snX15eNGzdy/vx5GjRoQHh4OBs3bjTdezt27ODbb79lyZIluLi4EBMTw/fff2869quvvsri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mLVr1/Lkk0+aXYc5z6CJ+ZTQiq05evQoN2/exNXVVUmaiNg0o9FIWloaycnJPPnkk1SsWNHsz1olQXN3dyc5Odn0NkhGRgZnz541vW6cpUyZMqafmzRpgru7O3/88Ydp0j0RkWeeeYZTp04VaNkfEZGHxcHBgVKlSpkmZzb7cw8onmxcXV1Nr/4GBgYSGxuLl5dXjuHN5ORk3NzcgNvPO/z555+myfpERAAcHR31vSAijzyrDXGOHTuW4OBgZs+eTcmSJU0L4gYFBTFkyBBq1qzJ9OnT+e9//4udnR2Ojo5MnTo1W6+aiIiIyOPAagmah4cHS5cuzbF93rx5pp+zkjYRERGRx5kWSxcRERGxMUrQRERERGyMEjQRERERG6METURERMTGKEETERERsTFK0ERERERsjBI0ERERERujBE1ERETExihBExEREbExStBEREREbIwSNBEREREbowRNRERExMYoQRMRERGxMUrQRERERGyMEjQRERERG6METURERMTGKEETERERsTFK0ERERERsjBI0ERERERujBE1ERETExihBExEREbExStBEREREbIwSNBEREREbowRNRERExMYoQRMRERGxMUrQRERERGyMg7kFExMTWb9+PX/99RdhYWEkJiaSlpZGtWrVHmR8IiIiIo8ds3rQ1q1bx2uvvUZycjLR0dEApKSkMGXKFLMPdPToUXr27Enbtm3p2bMnx44dy7PskSNHqF27NhEREWbXLyIiIvKoMCtBmzlzJl9++SXh4eHY29sDUK1aNQ4cOGD2gcLCwujduzc//PADvXv3JjQ0NNdyGRkZhIWF0aZNG7PrFhEREXmUmJWgXbhwwTSUaTAYTP+f9fPdnD9/nn379uHv7w+Av78/+/bt48KFCznKzp07l5YtW1KpUiWz6hYRERF51Jj1DFqNGjWIjo6mU6dOpm1r1qyhVq1aZh0kKSkJNzc3U++bvb09ZcuWJSkpCRcXF1O5AwcO8Msvv/D1118ze/bsApzG/+zduzff/XXr1r2neh9XO3fufNghiIiIPJLyy0nMStDGjBnDgAEDWLZsGSkpKQwYMICjR4/y5ZdfWizItLQ0PvzwQyZPnmxK5O6Ft7c3RYoUsVhcjzsltCIiItZnVoLm4eHBunXr2LBhAy1btsTd3Z2WLVtSokQJsw7i7u5OcnIyGRkZ2Nvbk5GR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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import seaborn\n", @@ -898,38 +244,10 @@ }, { "cell_type": "code", - "execution_count": 233, + "execution_count": null, "id": "61d517d0", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[0.01, 0.05, 0.1, 1, 5, 10]\n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 233, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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A7i7w+zZcOqUoysSERGRQkDhWiQ7r7wC8fHm8uqrjq5GRERECgGFa5HsNGtmZg0pUQLefRf+/tvRFYmIiEgBp3Atcj1vvw2bNpnbr7zi2FpERESkwFO4FrmeKlWgSRMYOBA++ACOHHF0RSIiIlKAKVyL3EhSEvz8M1itMHmyo6sRERGRAkzhWuRGXFwgKMjc/ugjOHjQsfWIiIhIgaVwLZIT48eDszNYLDBxoqOrERERkQJK4VokJypXhiefhJQU+OQT+OMPR1ckIiIiBZDCtUhOjR5tpuVzdYUJExxdjYiIiBRACtciOVWhAqxbB8OHw+efw86djq5IREREChiFa5GbcdddMGIElCplxmGLiIiIZKBwLXKz0ua6XrECtm1zbC0iIiJSoChci9ys22830/O5uqr3WkREROwoXIvcLG9vePllSEyENWvghx8cXZGIiIgUEArXIrfimWcgIMD0Xo8d6+hqREREpIDIt3B95MgRevXqRadOnejVqxdHjx7NtM4777zDAw88QLdu3XjwwQf5/vvv86s8kZtTogSMG2d6rzdtgu++c3RFIiIiUgDkW7gOCwujT58+rFmzhj59+jA+i7GqQUFBfP7553z11VdMnTqVF154gbi4uPwqUeTmDBxopuS77TYTtK1WR1ckIiIiDpYv4frcuXPs2bOHkJAQAEJCQtizZw/nz5+3W69169aUKFECgFq1amG1Wrl48WJ+lChy89zcoEcPMyzkf/+D1asdXZGIiIg4WL6E68jISMqXL4+zszMAzs7O+Pv7ExkZme02y5cvp3LlylSoUCE/ShS5dcnJJmir91pERKTYK5AHNG7bto233nqLmTNnOroUkRsrXx4SEuDnn+GrrxxdjYiIiDhQvoTrgIAATp8+TXJyMgDJyclERUUREBCQad1ff/2Vl156iXfeeYfq1avnR3ki/8yDD0KjRmbu6zFjICXF0RWJiIiIg+RLuPbz86NOnTqsXLkSgJUrV1KnTh18fX3t1vv999954YUXePvtt6lXr15+lCbyzzk5wSuvQFIS/PGHOchRREREiiWL1Zo/g0QPHTrEqFGjuHTpEj4+PkyfPp3q1aszaNAghgwZQoMGDejRowcnTpygfPnytu1mzJhBrVq1brj/+Ph4du/eTf369XF3d8/LpyKSmdUKd99tTodeo4YJ2anHGIiIiEjRcr3c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A3O0bq1atTh27Ng/fkwRkZxSuBYRyaGkpCRHlwAUnDryQlF+biJSPChci4hcR7t27Zg/fz5du3alUaNGJCUlsXPnTnr37k2TJk3o1q0bW7duta3/xRdf0L59e4KDg2nXrh1fffUVACkpKbz77ru0bduWli1bMmLECC5fvgxk3aPbrl07/ve//wEwe/ZshgwZwvDhw2ncuDFffvklFy9e5OWXX+buu++madOmPPPMM7ZtN2zYQGhoKE2aNKF3797s27cv2+d38OBB+vfvT7NmzbjrrruYN28eAAkJCbzyyivcfffd3H333bzyyiskJCTY1btgwQJatmzJ3XffzbJly2z73LRpE126dCE4OJjWrVvz4YcfEhsby6BBg4iKiiI4OJjg4GBOnz6d5XP7/fff6dWrF02aNOHuu+9m0qRJtscG+97oUaNGMXHiRJ544gmCg4N56KGH+OuvvwD4z3/+A0BoaCjBwcF8/fXXN/OjFxG5NVYREclW27Ztrd26dbOePHnSevXqVeupU6eszZo1s27cuNGanJxs/eGHH6zNmjWznjt3znrlyhVrcHCw9dChQ1ar1Wo9ffq09cCBA1ar1Wr97LPPrB06dLD+9ddf1piYGOvgwYOtw4cPt1qtVutPP/1kbd26dabH/fHHH61Wq9X69ttvW+vWrWtdt26dNTk52Xr16lXroEGDrEOHDrVevHjRmpCQYN26davVarVad+/ebW3RooV1586d1qSkJOsXX3xhbdu2rTU+Pj7Tc7t8+bK1VatW1g8//NAaFxdnvXz5snXnzp1Wq9VqffPNN60PPfSQ9ezZs9Zz585Ze/XqZZ01a5at3jp16ljffPNNa0JCgnXjxo3WoKAg68WLF61Wq9XaqlUr6/bt261Wq9V68eJF6+7du7N9nlk9t127dll//fVXa2JiovX48ePWzp07WxcuXGjbpmbNmtajR49arVardeTIkdamTZtaf/vtN2tiYqJ12LBh1ueffz7LdUVE8oN6rkVEbqBfv34EBATg4eFBREQEbdq04Z577sHJyYlWrVpRv359Nm3aBICTkxMHDx4kLi4Of39/7rjjDgBWrFjBY489RmBgIJ6engwbNoyvv/46x8MgGjVqRIcOHXBycuLSpUts3ryZiRMnUqpUKVxdXWnWrBkA//3vf+nVqxcNGzbE2dmZf/3rX7i6urJz585M+9y4cSNly5ZlwIABuLu74+XlRcOGDW31Dh48GD8/P3x9fRk8eLCtFx7AxcWFwYMH4+rqyj333EPJkiU5cuSIre3PP/8kJiaGUqVKUa9evRw/Nw8PD+rXr0+jRo1wcXGhUqVK9OrVi+3bt2e7fceOHQkKCsLFxYVu3bqxd+/eHL2mIiJ5wcXRBYiIFHQBAQG22ydPnmT16tVs2LDBtiwpKYnmzZtTsmRJZs2axYIFCxgzZgyNGzdm5MiR1KhRg6ioKG677TbbNrfddhtJSUmcO3cuRzVUqFDBdvvUqVOUKlWKUqVKZVrv5MmTLF++nPDwcNuyxMREoqKiMq0bGRlJ5cqVs3y8qKgoKlasaLtfsWJFu32ULl0aF5f0fyElSpQgNjYWgLfffpu5c+cyc+ZMatWqxYsvvkhwcHCOnhvAkSNHePXVV9m9ezdXr14lOTn5ugG9bNmyttseHh62OkREHEHhWkTkBiwWi+12QEAAoaGhTJkyJct1W7duTevWrYmLi+PNN99k3LhxLFmyBH9/f06cOGFb7+TJk7i4uODn58fp06eJi4uztSUnJ3P+/Plsa6hQoQLR0dFcunQJHx8fu/UCAgJ46qmnePrpp2/4vAICAli1alWWbf7+/pw8edLW8x4ZGYm/v/8N9wkQFBTE3LlzSUxM5JNPPuH5559n06ZNds8hu+cGMGHCBOrWrcvMmTPx8vJi0aJFrFmzJkePLSLiaBoWIiJyE7p168aGDRv4/vvvSU5OJj4+nq1bt3Lq1CnOnj3L+vXriY2Nxc3NjZIlS+Ls7AxASEgIH330EcePH+fKlSvMmjWL+++/HxcXF6pVq0Z8fDwbN24kMTGRuXPn2h3Ady1/f3/atGnDxIkTiY6OJjEx0TZs4qGHHmLp0qX89ttvWK1WYmNj2bhxIzExMZn2c++993L27FkWLVpEQkICMTEx/PbbbwA88MADzJ07l/Pnz3P+/HneeecdunbtesPXJyEhga+++orLly/j6uqKp6en7TXw8/Pj4sWLtgM5s3PlyhU8PT3x9PTk0KFD/N///d8NHzc7ZcuW1ZzYIpKvFK5FRG5CQEAA7777Lu+99x4tW7bknnvu4cMPPyQlJYWUlBQWLlxI69atadasGdu3bycsLAyAHj160K1bN/r27Uv79u1xc3Nj3LhxAHh7exMWFsbYsWNp06YNJUqUyDRU4lozZszAxcWF+++/n7vuuouPPvoIgAYNGjB58mQmTZpE06ZNue+++/jiiy+y3IeXlxcLFixgw4YNtGrVik6dOtlmPnnmmWeoX78+3bp1o1u3btSrV89uRpLriYiIoF27djRu3JilS5cyY8YMAGrUqMEDDzxAhw4daNKkCadPn85y+5EjR7Jy5UoaN27MuHHj6NKlS44eNyvPPvsso0aNokmTJpotRETyhcVqtVodXYSIiIiISFGgnmsRERERkVyicC0iIiIikksUrkVEREREconCtYiIiIhILlG4FhERERHJJQrXIiIiIiK5ROFaRERERCSXKFyLiIiIiOSS/wemq0hnq0BtUAAAAABJRU5ErkJggg==\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "fig, ax = plt.subplots()\n", "ax.set_xscale('log')\n", @@ -962,7 +280,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "id": "91736ad0", "metadata": {}, "outputs": [], @@ -973,7 +291,7 @@ }, { "cell_type": "code", - "execution_count": 162, + "execution_count": null, "id": "2cdeefee", "metadata": {}, "outputs": [], @@ -1017,39 +335,26 @@ }, { "cell_type": "code", - "execution_count": 153, + "execution_count": null, "id": "d6440018", "metadata": {}, "outputs": [], "source": [ "plan_names = [\n", - " 'plan-round_robin_lifo-always_process-5-100',\n", - " 'plan-weighted_round_robin_lifo-always_process-5-100',\n", - " 'plan-random_lifo-always_process-5-100',\n", - " 'plan-weighted_random_lifo-always_process-5-100' \n", + " 'plan-weighted_random_lifo-always_process-0.01-100',\n", + " 'plan-weighted_random_lifo-always_process-0.1-100' \n", "]" ] }, { "cell_type": "code", - "execution_count": 154, + "execution_count": null, "id": "523bf657", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "plan-round_robin_lifo-always_process-5-100\n", - "plan-weighted_round_robin_lifo-always_process-5-100\n", - "plan-random_lifo-always_process-5-100\n", - "plan-weighted_random_lifo-always_process-5-100\n" - ] - } - ], + "outputs": [], "source": [ "results = {}\n", - "end_ts = 1000\n", + "end_ts = 37000\n", "for plan_name in plan_names:\n", " print(plan_name)\n", " plan_file = f'{plan_dir}/{plan_name}.json'\n", @@ -1060,162 +365,78 @@ }, { "cell_type": "code", - "execution_count": 155, - "id": "d1958139", + "execution_count": null, + "id": "592a8b2e", + "metadata": {}, + "outputs": [], + "source": [ + "results[\"plan-weighted_random_lifo-always_process-0.1-100\"].sort_values(by=\"updates\", ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "98907ae3", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 155, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ - "results['plan-round_robin_lifo-always_process-5-100'].set_index(\"title\").sort_values(by=\"pageviews\").tail(10)[[\"updates\", \"optimal_updates\", \"pageviews\"]].plot(kind=\"bar\", title=\"Updates for Top Documents (Weighted Round Robin)\")" + "\n", + "df1 = results[\"plan-weighted_random_lifo-always_process-0.01-100\"]\n", + "df2 = results[\"plan-weighted_random_lifo-always_process-0.1-100\"]\n", + "for title in results[\"plan-weighted_random_lifo-always_process-0.01-100\"].title.tolist(): \n", + " u1 = df1[df1[\"title\"] == title].updates.tolist()\n", + " u2 = df2[df1[\"title\"] == title].updates.tolist()\n", + " if u1 != u2:\n", + " print(title)\n", + " print(u1)\n", + " print(u2)\n", + " \n", + " " ] }, { "cell_type": "code", - "execution_count": 156, + "execution_count": null, "id": "3ea99ccb", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 156, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "results['plan-round_robin_lifo-always_process-5-100'].set_index(\"title\").sort_values(by=\"pageviews\").head(10)[[\"updates\", \"optimal_updates\", \"pageviews\"]].plot(kind=\"bar\", title=\"Updates for Least Queried Documents (Round Robin)\")" ] }, { "cell_type": "code", - "execution_count": 157, + "execution_count": null, "id": "999fc591", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 157, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "results['plan-round_robin_lifo-always_process-5-100'].plot(x=\"pageviews\", y=\"updates\", kind=\"hist\")" ] }, { "cell_type": "code", - "execution_count": 158, + "execution_count": null, "id": "00d43d3f", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 158, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "results['plan-round_robin_lifo-always_process-5-100'].plot(x=\"pageviews\", y=\"updates\", kind=\"hist\")" ] }, { "cell_type": "code", - "execution_count": 159, + "execution_count": null, "id": "7af47144", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 159, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "results['plan-round_robin_lifo-always_process-5-100'].plot(x=\"pageviews\", y=\"optimal_updates\", kind=\"hist\")" ] }, { "cell_type": "code", - "execution_count": 163, + "execution_count": null, "id": "4d55378e", "metadata": {}, "outputs": [], @@ -1225,7 +446,7 @@ }, { "cell_type": "code", - "execution_count": 208, + "execution_count": null, "id": "739fdc68", "metadata": {}, "outputs": [], @@ -1238,277 +459,17 @@ }, { "cell_type": "code", - "execution_count": 209, + "execution_count": null, "id": "c34cc7c0", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{0: 0,\n", - " 1: 1,\n", - " 2: 2,\n", - " 3: 3,\n", - " 4: 4,\n", - " 5: 5,\n", - " 6: 6,\n", - " 7: 7,\n", - " 8: 8,\n", - " 9: 9,\n", - " 10: 10,\n", - " 11: 11,\n", - " 12: 12,\n", - " 13: 13,\n", - " 14: 14,\n", - " 15: 15,\n", - " 16: 16,\n", - " 17: 17,\n", - " 18: 18,\n", - " 19: 19,\n", - " 20: 20,\n", - " 21: 21,\n", - " 22: 22,\n", - " 23: 23,\n", - " 24: 24,\n", - " 25: 25,\n", - " 26: 26,\n", - " 27: 27,\n", - " 28: 28,\n", - " 29: 29,\n", - " 30: 30,\n", - " 31: 31,\n", - " 32: 32,\n", - " 33: 33,\n", - " 34: 34,\n", - " 35: 35,\n", - " 36: 36,\n", - " 37: 37,\n", - " 38: 38,\n", - " 39: 39,\n", - " 40: 40,\n", - " 41: 41,\n", - " 42: 42,\n", - " 43: 43,\n", - " 44: 44,\n", - " 45: 45,\n", - " 46: 46,\n", - " 47: 47,\n", - " 48: 48,\n", - " 49: 49,\n", - " 50: 50,\n", - " 51: 51,\n", - " 52: 52,\n", - " 53: 53,\n", - " 54: 54,\n", - " 55: 55,\n", - " 56: 56,\n", - " 57: 57,\n", - " 58: 58,\n", - " 59: 59,\n", - " 60: 60,\n", - " 61: 61,\n", - " 62: 62,\n", - " 63: 63,\n", - " 64: 64,\n", - " 65: 65,\n", - " 66: 66,\n", - " 67: 67,\n", - " 68: 68,\n", - " 69: 69,\n", - " 70: 70,\n", - " 71: 71,\n", - " 72: 72,\n", - " 73: 73,\n", - " 74: 74,\n", - " 75: 75,\n", - " 76: 76,\n", - " 77: 77,\n", - " 78: 78,\n", - " 79: 79,\n", - " 80: 80,\n", - " 81: 81,\n", - " 82: 82,\n", - " 83: 83,\n", - " 84: 84,\n", - " 85: 85,\n", - " 86: 86,\n", - " 87: 87,\n", - " 88: 88,\n", - " 89: 89,\n", - " 90: 90,\n", - " 91: 91,\n", - " 92: 92,\n", - " 93: 93,\n", - " 94: 94,\n", - " 95: 95,\n", - " 96: 96,\n", - " 97: 97,\n", - " 98: 98,\n", - " 99: 99,\n", - " 100: 100,\n", - " 101: 101,\n", - " 102: 102,\n", - " 103: 103,\n", - " 104: 104,\n", - " 105: 105,\n", - " 106: 106,\n", - " 107: 107,\n", - " 108: 108,\n", - " 109: 109,\n", - " 110: 110,\n", - " 111: 111,\n", - " 112: 112,\n", - " 113: 113,\n", - " 114: 114,\n", - " 115: 115,\n", - " 116: 116,\n", - " 117: 117,\n", - " 118: 118,\n", - " 119: 119,\n", - " 120: 120,\n", - " 121: 121,\n", - " 122: 122,\n", - " 123: 123,\n", - " 124: 124,\n", - " 125: 125,\n", - " 126: 126,\n", - " 127: 127,\n", - " 128: 128,\n", - " 129: 129,\n", - " 130: 130,\n", - " 131: 131,\n", - " 132: 132,\n", - " 133: 133,\n", - " 134: 134,\n", - " 135: 135,\n", - " 136: 136,\n", - " 137: 137,\n", - " 138: 138,\n", - " 139: 139,\n", - " 140: 140,\n", - " 141: 141,\n", - " 142: 142,\n", - " 143: 143,\n", - " 144: 144,\n", - " 145: 145,\n", - " 146: 146,\n", - " 147: 147,\n", - " 148: 148,\n", - " 149: 149,\n", - " 150: 150,\n", - " 151: 151,\n", - " 152: 152,\n", - " 153: 153,\n", - " 154: 154,\n", - " 155: 155,\n", - " 156: 156,\n", - " 157: 157,\n", - " 158: 158,\n", - " 159: 159,\n", - " 160: 160,\n", - " 161: 161,\n", - " 162: 162,\n", - " 163: 163,\n", - " 164: 164,\n", - " 165: 165,\n", - " 166: 166,\n", - " 167: 167,\n", - " 168: 168,\n", - " 169: 169,\n", - " 170: 170,\n", - " 171: 171,\n", - " 172: 172,\n", - " 173: 173,\n", - " 174: 174,\n", - " 175: 175,\n", - " 176: 176,\n", - " 177: 177,\n", - " 178: 178,\n", - " 179: 179,\n", - " 180: 180,\n", - " 181: 181,\n", - " 182: 182,\n", - " 183: 183,\n", - " 184: 184,\n", - " 185: 185,\n", - " 186: 186,\n", - " 187: 187,\n", - " 188: 188,\n", - " 189: 189,\n", - " 190: 190,\n", - " 191: 191,\n", - " 192: 192,\n", - " 193: 193,\n", - " 194: 194,\n", - " 195: 195,\n", - " 196: 196,\n", - " 197: 197,\n", - " 198: 198,\n", - " 199: 199,\n", - " 200: 200,\n", - " 201: 201,\n", - " 202: 202,\n", - " 203: 203,\n", - " 204: 204,\n", - " 205: 205,\n", - " 206: 206,\n", - " 207: 207,\n", - " 208: 208,\n", - " 209: 209,\n", - " 210: 210,\n", - " 211: 211,\n", - " 212: 212,\n", - " 213: 213,\n", - " 214: 214,\n", - " 215: 215,\n", - " 216: 216,\n", - " 217: 217,\n", - " 218: 218,\n", - " 219: 219,\n", - " 220: 220,\n", - " 221: 221,\n", - " 222: 222,\n", - " 223: 223,\n", - " 224: 224,\n", - " 225: 225,\n", - " 226: 226,\n", - " 227: 227,\n", - " 228: 228,\n", - " 229: 229,\n", - " 230: 230,\n", - " 231: 231,\n", - " 232: 232,\n", - " 233: 233,\n", - " 234: 234,\n", - " 235: 235,\n", - " 236: 236,\n", - " 237: 237,\n", - " 238: 238,\n", - " 239: 239,\n", - " 240: 240,\n", - " 241: 241,\n", - " 242: 242,\n", - " 243: 243,\n", - " 244: 244,\n", - " 245: 245,\n", - " 246: 246,\n", - " 247: 247,\n", - " 248: 248,\n", - " 249: 249}" - ] - }, - "execution_count": 209, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "n_fits_map" ] }, { "cell_type": "code", - "execution_count": 195, + "execution_count": null, "id": "c768b43d", "metadata": {}, "outputs": [], @@ -1520,7 +481,7 @@ }, { "cell_type": "code", - "execution_count": 200, + "execution_count": null, "id": "fc803fd4", "metadata": {}, "outputs": [], @@ -1530,21 +491,10 @@ }, { "cell_type": "code", - "execution_count": 211, + "execution_count": null, "id": "cfe761f5", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1QAAAHGCAYAAABzUMo8AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAADBIUlEQVR4nOzdeVxUVf8H8M/MwLCIAi64i1qipqnI5gIauOKSu/krtccWNVPbtMytXHrK6inLFivNsp4yzT21xdK0RQV33HcUBBQEWRQG5vz+4JnbLPfODCPMDPJ5v16+hLuee+cy5557vud7VUIIASIiIiIiIioztasLQEREREREVFmxQUVEREREROQgNqiIiIiIiIgcxAYVERERERGRg9igIiIiIiIichAbVERERERERA5ig4qIiCRxcXH46KOPKnw/e/fuRcuWLZGWllbh+7pTV65cQcuWLZGYmFjh+5oxYwb+9a9/Vfh+iIio/Hi4ugBERFXF7du3sXTpUmzduhVpaWnw8fFBo0aNMGjQIIwdO9bVxSMn2rhxI1588UWcOnXKZPqsWbOg1+tdVCoiInIEG1RERE7y6quvYu/evZg1axZatmyJ/Px8HD9+HKmpqa4uGrmJ6tWru7oIRERURgz5IyJyku3bt+Pxxx9Hz5490bhxY7Rq1QpDhw7F5MmTpWWOHTuGJ554Ap07d0ZoaCiGDRuGXbt2mWwnLi4OixcvxiuvvIKwsDB07twZX3/9NYqKirBgwQJEREQgJiYGX3/9tcl6LVu2xJdffokpU6agQ4cOiI6OxooVK6yWubi4GEuWLEFcXBzuv/9+9O/fH6tWrbK6zrp163Dffffhr7/+Qv/+/XH//fdj+PDhOHbsmOI6QgjMnj0bPXv2RLt27dCjRw+88847KCoqkpZZsmQJevXqhe3bt6Nv377o0KEDxowZg+TkZKvlSUxMxKhRoxAaGorQ0FA8+OCD2L17tzT/+vXrmDFjBjp16oTQ0FCMGjUKCQkJVrdpzzrJycmYOnUqIiMj0b59ewwcOBA7duzA3r178eKLLwIo/UxatmyJGTNmALAM+RNCYPny5ejRowfatm2Lnj174osvvjDZT1xcHN577z0sXLgQkZGR6NKlCxYtWoSSkhKrx0BEROWDDSoiIiepU6cOdu/ejezsbMVl8vLy0L9/f3z11VdYt24doqOjMWnSJFy4cMFkua+//hpNmzbFunXrMGbMGCxcuBBPP/00GjVqhO+//x6jR4/GwoULcfbsWZP1PvzwQ0RGRmL9+vV48skn8dZbb+Hnn39WLM/s2bPx888/Y/78+di6dSuefvppvP3221izZo3VY9Xr9XjrrbfwyiuvYM2aNahVqxYmTJiAW7duyS4vhECtWrXwn//8B1u3bsXMmTOxbt06LF261GS5a9eu4dtvv8Xbb7+NVatWITc3FzNnzlQsR0lJCSZNmoT27dtj/fr1WL9+PaZMmQIfHx8ApWGYY8eORX5+Pj777DNs2LAB3bt3x7hx43Du3DnZbdqzzrVr1zBq1CjcvHkTH330ETZv3oxnnnkGarUaoaGhmDt3LgDgjz/+wB9//IFZs2bJ7uubb77Be++9h/Hjx+OHH37A448/jv/85z8W5//rr79GUFAQVq9ejdmzZ+PLL7/Ehg0bFM8LERGVI0FERE6RmJgoHnjgAdGqVSsxYMAAMXv2bPHLL78IvV5vdb2BAweKjz76SPo9NjZWPPXUU9LvJSUlIjQ0VEyYMMFkWnh4uPjqq6+kaSEhIWLatGkm237++efFqFGjTLb94YcfCiGESE5OFi1bthRnz541WWfJkiXiwQcfVCzv2rVrRUhIiPjrr7+kadnZ2aJDhw5i9erVQggh9uzZI0JCQsTVq1cVt7NixQrRq1cv6ff3339ftG7dWmRmZkrTfvjhB9GyZUtx+/Zt2W1kZ2eLkJAQsWfPHsWyxsTECJ1OZzJ9zJgxYuHChUIIIS5fvixCQkJEQkKC3eu8++67okuXLiI/P192vxs2bBAhISEW01966SXx6KOPSr9369ZNLFq0yGSZ1157TcTFxUm/x8bGmnz2Qgjx2GOPieeee05230REVL44hoqIyEnCwsLwyy+/4MiRIzh06BASEhIwdepUdOvWDR9//DFUKhWysrLw/vvvY8+ePbh+/TpKSkpQWFhoMc6qVatW0s9qtRo1a9ZEy5YtLaZlZmaarNehQweT3zt27GgS/mYsKSkJQggMHz7cZHpxcTE0Go3N4zXel7+/P5o3b27RY2Zs9erVWLNmDVJSUnDr1i0UFxdDCGGyTFBQEGrWrCn9XrduXQghkJmZiQYNGlhs09/fHyNGjMDjjz+OTp06ITIyEj179kTz5s0BAEePHsX169cRERFhsl5RURG8vb1ly2nPOseOHUNoaCh8fX0Vj9eWvLw8pKWlWewnMjISK1euxK1bt6SettatW5ssU7duXVy5csXhfRMRkf3YoCIiciIPDw907NgRHTt2xGOPPSZle0tISEBkZCRmzJiBq1evYvr06WjUqBG8vb3x3HPPQafTWWzHmEqlkp1mK2OceYNFbt63334r3bgbb7usrO1r27ZtmD9/Pl544QVERETAz88PP/74I959912T5Tw9PWXXt3acCxcuxNixY/Hnn3/izz//xHvvvYc5c+Zg1KhR0Ov1uOeee/DBBx9YrKfUoLJ3HUfOkRzz7cidR/PzolKprJ5vIiIqPxxDRUTkQvfccw8ASD1JCQkJ+L//+z/06NEDLVu2RJ06dcq1p+Hw4cMmvx88eFDqrTHXpk0bAMDVq1cRHBxs8q9JkyY293Xo0CHp55s3b+LChQvS8ZpLTExE69atMW7cOLRt2xZNmzZFSkqKnUdlW0hICMaNG4dly5Zh2LBhWL16NQCgbdu2uHz5Mvz8/CyOsW7durLbsmedNm3a4MCBAygoKJDdhqEBZC1xhJ+fH+rVq4d9+/aZTE9ISECjRo0sGrlEROQabFARETnJ6NGj8e233+Lo0aNISUnB33//jXnz5qFGjRqIiooCADRr1gybN2/GqVOncOLECTz//PPlmq1t586d+Prrr3Hx4kV89dVX2LZtm+KLZIODgzFs2DDMmTMHGzZswKVLl3Dy5El8//33+PTTT63uR6VS4a233kJCQgJOnTqFF198ET4+PhgwYIDs8s2aNcPp06exfft2JCcn48svv7SaLMNely5dwltvvYXExESkpKTg4MGD2L9/v9Swe/DBB9GoUSOMHz8ef/zxB65cuYLDhw/jk08+wfbt22W3ac86Dz/8MPR6PSZNmoT9+/fj8uXL2LFjB37//XcAQKNGjQAAv/32G7KyspCfny+7r/Hjx+Prr7/G6tWrcfHiRaxatQrffvstJkyYcMfnhoiIygdD/oiInKRbt27YvHkz3n//feTl5aFWrVoIDw/H66+/Lo0Lev311/HKK69gxIgRqF27Nh5//HHcvn273MowadIk/PXXX3jrrbdQvXp1PP/88+jbt6/i8gsWLMDnn3+OpUuX4sqVK6hWrRpatGiBRx55xOp+1Go1nn/+ecydOxeXL19Gy5Yt8cknnyiOKXrooYdw+vRpzJw5E8XFxYiNjcWUKVOwYMGCOzpeHx8fXLp0Cc8//zyysrIQEBCABx54AC+99BIAwMvLC1999RUWL16Ml19+GTdu3EBgYCDatWuHmJgY2W3as05QUBC++eYbvP322xg/fjyKi4sRHByMF154AQDQrl07jB07Fq+88gqysrIwePBgvPHGGxb7evjhh3Hr1i0sXboU8+bNQ7169fDCCy9gxIgRd3ReiIio/KgEg6yJiKqEli1b4s0338SgQYMqdD/r1q3D7Nmzcfz48QrdDxERkTtgyB8REREREZGD2KAiIiIiIiJyEEP+iIiIiIiIHMQeKiIiIiIiIgexQUVEREREROQgNqiIiIiIiIgcxAYVERERERGRg9igIiIiIiIichAbVERERERERA5ig4qIiIiIiMhBbFARERERERE5iA2qSm7v3r3o1q2bq4tRIeLi4vDXX3+V6zaXLFmCadOmKc7v378/9u7de0f7MC730qVLMWvWLGneL7/8gu7duyM0NBTHjx+/o/2Ys3VsRFR1uXtdkZqaitDQUJSUlNhc9sqVK2jZsiWKi4srpCwVvf3yUFGfp7V6NzExEX369Lmj7ZuX27jOFULg5ZdfRkREBIYPH35H+5FTEfcURAZsUBEZ2bJlC6KiosptexMnTsRrr70m/b5o0SLMmTMHBw8exH333Vdu+yHnWrJkCdq0aYPQ0FDp3+XLlxWX37NnD8aMGYOwsDDExcVZzL9y5QrGjBmD9u3bo2/fvhaV/ubNmxEbG4sOHTpg0qRJyM7OLu9DInKpBg0a4ODBg9BoNHe8LT5cqhjh4eH46aefynWbxnXu/v378eeff+L333/H999/X677IeeKi4tDu3btpPrxscces7r84sWLMXDgQNx3331YsmSJxXxrdWBRURFefvlldOzYEV27dsWKFSvK+3DswgYV2c2dn9YZuHsZU1NT0aJFC1cXo1Kw50m1K8XHx+PgwYPSv8aNGysu6+vri2HDhuHFF1+Unf/CCy/gvvvuw969e/Hcc89h6tSpyMrKAgCcOXMGc+fOxZtvvok///wTPj4+mDdvXoUcExE5RggBvV7v6mJY5e71Y0pKCho2bAhfX19XF8XtuftnCZRG6Bjqx88//9zqssHBwZg2bRq6d+9uMc9WHbhkyRJcunQJO3bswMqVK7Fs2TLs2rWr3I/HFjaoKom4uDh88skn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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "fig = plt.figure(figsize=(12, 12))\n", "for i, plan_name in enumerate(results.keys()):\n", @@ -1567,297 +517,59 @@ }, { "cell_type": "code", - "execution_count": 318, + "execution_count": null, "id": "ac3582ce", "metadata": {}, "outputs": [], "source": [ - "df = pd.read_csv(\"/data/wooders/wikipedia/10042021_questions_revid_filtered.csv\", sep=\"\\t\")\n", - "df.columns = [\"question\", \"answer\", \"doc_id\", \"timestamp\", \"revid\", \"oldrevid\"]" + "df = pd.read_csv(\"/data/wooders/wikipedia/questions.csv\")\n", + "#df.columns = [\"question\", \"answer\", \"doc_id\", \"timestamp\", \"revid\", \"oldrevid\"]" ] }, { "cell_type": "code", - "execution_count": 319, - "id": "e7485904", + "execution_count": null, + "id": "ce16ddda", "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
questionanswerdoc_idtimestamprevidoldrevid
0what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 00:16:27.42857210372125321037212489
1what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 00:32:54.85714410372125321037212489
2what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 00:49:22.28571610372125321037212489
3what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 01:05:49.71428810372125321037212489
4what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 01:22:17.14286010372125321037212489
.....................
127727who is the ayo??????Hunter B-15 (portrayed by Wunmi Mosaku) is an ...623726382021-09-01 20:46:09.23070010416509361041650818
127728who is the ayo??????Hunter B-15 (portrayed by Wunmi Mosaku) is an ...623726382021-09-01 21:30:27.69223610416509361041650818
127729who is the ayo??????Hunter B-15 (portrayed by Wunmi Mosaku) is an ...623726382021-09-01 22:14:46.15377210416509361041650818
127730who is the ayo??????Hunter B-15 (portrayed by Wunmi Mosaku) is an ...623726382021-09-01 22:59:04.61530810416509361041650818
127731who is the ayo??????Hunter B-15 (portrayed by Wunmi Mosaku) is an ...623726382021-09-01 23:43:23.07684410416509361041650818
\n", - "

127732 rows × 6 columns

\n", - "
" - ], - "text/plain": [ - " question \\\n", - "0 what is the most common death in 2021??????? \n", - "1 what is the most common death in 2021??????? \n", - "2 what is the most common death in 2021??????? \n", - "3 what is the most common death in 2021??????? \n", - "4 what is the most common death in 2021??????? \n", - "... ... \n", - "127727 who is the ayo?????? \n", - "127728 who is the ayo?????? \n", - "127729 who is the ayo?????? \n", - "127730 who is the ayo?????? \n", - "127731 who is the ayo?????? \n", - "\n", - " answer doc_id \\\n", - "0 A typical entry reports information in the fol... 65984422 \n", - "1 A typical entry reports information in the fol... 65984422 \n", - "2 A typical entry reports information in the fol... 65984422 \n", - "3 A typical entry reports information in the fol... 65984422 \n", - "4 A typical entry reports information in the fol... 65984422 \n", - "... ... ... \n", - "127727 Hunter B-15 (portrayed by Wunmi Mosaku) is an ... 62372638 \n", - "127728 Hunter B-15 (portrayed by Wunmi Mosaku) is an ... 62372638 \n", - "127729 Hunter B-15 (portrayed by Wunmi Mosaku) is an ... 62372638 \n", - "127730 Hunter B-15 (portrayed by Wunmi Mosaku) is an ... 62372638 \n", - "127731 Hunter B-15 (portrayed by Wunmi Mosaku) is an ... 62372638 \n", - "\n", - " timestamp revid oldrevid \n", - "0 2021-08-06 00:16:27.428572 1037212532 1037212489 \n", - "1 2021-08-06 00:32:54.857144 1037212532 1037212489 \n", - "2 2021-08-06 00:49:22.285716 1037212532 1037212489 \n", - "3 2021-08-06 01:05:49.714288 1037212532 1037212489 \n", - "4 2021-08-06 01:22:17.142860 1037212532 1037212489 \n", - "... ... ... ... \n", - "127727 2021-09-01 20:46:09.230700 1041650936 1041650818 \n", - "127728 2021-09-01 21:30:27.692236 1041650936 1041650818 \n", - "127729 2021-09-01 22:14:46.153772 1041650936 1041650818 \n", - "127730 2021-09-01 22:59:04.615308 1041650936 1041650818 \n", - "127731 2021-09-01 23:43:23.076844 1041650936 1041650818 \n", - "\n", - "[127732 rows x 6 columns]" - ] - }, - "execution_count": 319, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "df" ] }, { "cell_type": "code", - "execution_count": 320, - "id": "2d5a778a", + "execution_count": null, + "id": "07d5672a", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "332667 32284\n", - "1305297 10610\n", - "66304621 5330\n", - "17888363 3900\n", - "67089631 3621\n", - "Name: doc_id, dtype: int64" - ] - }, - "execution_count": 320, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "df.doc_id.value_counts().head()" + "df.doc_id.value_counts()" ] }, { "cell_type": "code", - "execution_count": 308, - "id": "f7546f77", + "execution_count": null, + "id": "d9dab1e5", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "60043578 590\n", - "51150040 510\n", - "68187748 470\n", - "66187257 450\n", - "64783122 370\n", - "Name: doc_id, dtype: int64" - ] - }, - "execution_count": 308, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "df.doc_id.value_counts().tail()" + "df.question.value_counts()" ] }, { "cell_type": "code", - "execution_count": 309, - "id": "5823be22", + "execution_count": null, + "id": "ea220f3d", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "332667 5090\n", - "65984422 3769\n", - "68553225 1740\n", - "57798785 1410\n", - "56185392 1360\n", - "68294454 1200\n", - "66293350 1040\n", - "57817558 930\n", - "60043578 590\n", - "51150040 510\n", - "68187748 470\n", - "66187257 450\n", - "64783122 370\n", - "Name: doc_id, dtype: int64" - ] - }, - "execution_count": 309, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "df.doc_id.value_counts()" ] }, { "cell_type": "code", - "execution_count": 310, - "id": "a8154736", + "execution_count": null, + "id": "86c3ebf2", "metadata": {}, "outputs": [], "source": [ @@ -1866,33 +578,23 @@ }, { "cell_type": "code", - "execution_count": 311, - "id": "48960f20", + "execution_count": null, + "id": "af72ae1a", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{332667: 5090,\n", - " 65984422: 3769,\n", - " 68553225: 1740,\n", - " 57798785: 1410,\n", - " 56185392: 1360,\n", - " 68294454: 1200,\n", - " 66293350: 1040,\n", - " 57817558: 930,\n", - " 60043578: 590,\n", - " 51150040: 510,\n", - " 68187748: 470,\n", - " 66187257: 450,\n", - " 64783122: 370}" - ] - }, - "execution_count": 311, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], + "source": [ + "for key in weights: \n", + " weights[key] = int(weights[key]/10)\n", + " if weights[key] == 0: \n", + " weights[key] = 1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "500bd6ec", + "metadata": {}, + "outputs": [], "source": [ "weights" ] @@ -1900,12 +602,20 @@ { "cell_type": "code", "execution_count": null, - "id": "2ade5579", + "id": "db8ae3c9", "metadata": {}, "outputs": [], "source": [ - "we" + "open(\"/home/eecs/wooders/experiments/wikipedia/weights.json\", \"w\").write(json.dumps(weights))" ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0901f729", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/wikipedia/preprocessing/log_data.py b/wikipedia/preprocessing/log_data.py new file mode 100644 index 0000000..2e8cca4 --- /dev/null +++ b/wikipedia/preprocessing/log_data.py @@ -0,0 +1,72 @@ +import wandb +import configparser +import os + + +def log_questions(run, config): + # log questions file + artifact = wandb.Artifact("questions", type='dataset') + artifact.add_file(config["files"]["raw_questions_file"]) + artifact.add_file(config["files"]["questions_file"]) + run.log_artifact(artifact) + +def log_files(run, config): + # log files + artifact = wandb.Artifact("files", type='dataset') + artifact.add_file(config["files"]["changes_file"]) + artifact.add_file(config["files"]["titles_file"]) + artifact.add_file(config["files"]["edits_file"]) + run.log_artifact(artifact) + +def log_pageview(run, config): + # log pageview + artifact = wandb.Artifact("pageviews", type='dataset') + artifact.add_file(config["files"]["raw_pageview_file"]) + artifact.add_file(config["files"]["pageview_file"]) + artifact.add_file(config["files"]["timestamp_weights_file"]) + run.log_artifact(artifact) + +def log_simulation(run, config): + # log simulation data + artifact = wandb.Artifact("simulation", type='dataset') + artifact.add_file(config["simulation"]["stream_edits_file"]) + artifact.add_file(config["simulation"]["stream_questions_file"]) + artifact.add_file(config["simulation"]["init_data_file"]) + run.log_artifact(artifact) + +def log_plans(run, config, plan_dir): + artifact = wandb.Artifact("plans", type='dataset') + artifact.add_file(config["simulation"]["optimal_plan_file"]) + artifact.add_dir(plan_dir) + run.log_artifact(artifact) + +def log_plan_data(run, config, plan_name, plan_path): + artifact = wandb.Artifact(plan_name, type='dataset') + artifact.add_folder(plan_path) + run.log_artifact + + +def log_experiment(run, config): + # log experiment output + artifact = wandb.Artifact("prediction_results", type='dataset') + files = os.listdir(config["directory"]["dpr_dir"]) + for filename in files: + if "plan-" in filename and '.json' in filename: + artifact.add_file(os.path.join(config["directory"]["dpr_dir"], filename)) + run.log_artifact(artifact) + +if __name__ == "__main__": + + print("Running wandb logging on data") + run = wandb.init(job_type="dataset-creation", project="wiki-workload") + + # configuration file + config = configparser.ConfigParser() + config.read("config.yml") + + log_questions(run, config) + log_files(run, config) + log_pageview(run, config) + log_simulation(run, config) + log_experiment(run, config) + diff --git a/wikipedia/run_1_generate_plan.sh b/wikipedia/run_1_generate_plan.sh index debb1e6..0334ade 100644 --- a/wikipedia/run_1_generate_plan.sh +++ b/wikipedia/run_1_generate_plan.sh @@ -1,8 +1,8 @@ set -xe -for key_policy in "random" "weighted_random" "round_robin" "weighted_round_robin" +for key_policy in "weighted_random" "weighted_round_robin" do - for event_policy in "fifo" "lifo" + for event_policy in "lifo" do for load_shedding_policy in "always_process" do diff --git a/wikipedia/run_2_prepare_data.sh b/wikipedia/run_2_prepare_data.sh index ff2b74e..ceaf249 100644 --- a/wikipedia/run_2_prepare_data.sh +++ b/wikipedia/run_2_prepare_data.sh @@ -10,7 +10,7 @@ do do for model_runtime in 0.01 0.05 0.1 1 5 10 do - python wiki_eval.py --offline-plan-path ${plan_dir}/plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100.json + python wiki_eval.py --offline-plan-path ${plan_dir}/plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100.json --wandb done done done diff --git a/wikipedia/run_3_run_predictions.sh b/wikipedia/run_3_run_predictions.sh index 6655996..3f0713b 100644 --- a/wikipedia/run_3_run_predictions.sh +++ b/wikipedia/run_3_run_predictions.sh @@ -5,7 +5,7 @@ dpr_dir=~/DPR cd $dpr_dir -for key_policy in "round_robin" "weighted_round_robin" +for key_policy in "weighted_round_robin" #"round_robin" #for key_policy in "random" "weighted_random" do for event_policy in "lifo" @@ -16,10 +16,10 @@ do do plan_file=plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100 echo $plan_file - CUDA_VISIBLE_DEVICES=1,2,5 bash ${dpr_dir}/evaluate_retrieval_single_doc_stream.sh $plan_file & + CUDA_VISIBLE_DEVICES=3,4,5 bash ${dpr_dir}/evaluate_retrieval_single_doc_stream.sh $plan_file & pid=$! done - #wait $pid + wait $pid done done done diff --git a/wikipedia/run_4_run_optimal_predictions.sh b/wikipedia/run_4_run_optimal_predictions.sh index 542d828..14abe91 100644 --- a/wikipedia/run_4_run_optimal_predictions.sh +++ b/wikipedia/run_4_run_optimal_predictions.sh @@ -2,7 +2,7 @@ set -xe plan_dir=/data/wooders/wiki-plans dpr_dir=~/DPR +python wiki_eval.py --offline-plan-path optimal_plan.json cd $dpr_dir -plan_file="optimal_plan" echo $plan_file -CUDA_VISIBLE_DEVICES=5 bash ${dpr_dir}/evaluate_retrieval_single_doc_stream.sh $plan_file +CUDA_VISIBLE_DEVICES=5 bash ${dpr_dir}/evaluate_retrieval_single_doc_stream.sh optimal_plan diff --git a/wikipedia/run_5_pipeline_predict.sh b/wikipedia/run_5_pipeline_predict.sh new file mode 100644 index 0000000..f6aee15 --- /dev/null +++ b/wikipedia/run_5_pipeline_predict.sh @@ -0,0 +1,30 @@ +set -xe + +plan_dir=/data/wooders/wiki-plans +dpr_dir=/home/eecs/wooders/DPR +wiki_dir=/home/eecs/wooders/experiments/wikipedia + + +#for key_policy in "weighted_random" "weighted_round_robin" +#for key_policy in "random" "weighted_random" +for key_policy in "round_robin" "weighted_round_robin" +do + for event_policy in "lifo" + do + for load_shedding_policy in "always_process" + do + for model_runtime in 0.01 0.05 0.1 1 5 + do + cd $wiki_dir + plan_file=plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100 + echo $plan_file + python wiki_eval.py --offline-plan-path ${plan_dir}/${plan_file}.json + cd $dpr_dir + CUDA_VISIBLE_DEVICES=0,1,2,3,4,5 bash ${dpr_dir}/evaluate_retrieval_single_doc_stream.sh $plan_file & + pid=$! + done + #wait $pid + done + done +done +p diff --git a/wikipedia/simulate.py b/wikipedia/simulate.py index 5162e99..5dba7d1 100644 --- a/wikipedia/simulate.py +++ b/wikipedia/simulate.py @@ -83,16 +83,24 @@ def __init__(self, pageview_file, all_keys): self.cur_key_set = [] self.cur_key_iter = None pageview_df = pd.read_csv(pageview_file) - #self.raw_weights = pageview_df.set_index("doc_id")["weights"].to_dict() - self.raw_weights = pageview_df.set_index("doc_id")["2021090300"].to_dict() - self.weights = {} - for key in self.raw_weights.keys(): - if str(key) not in all_keys: - continue - self.weights[key] = int(self.raw_weights[key]*1000) - #assert self.weights[key] > 0, f"Too small {key}, {self.raw_weights[key]}" - if self.weights[key] == 0: + self.weights = json.load(open("weights.json")) + + ##self.raw_weights = pageview_df.set_index("doc_id")["weights"].to_dict() + #self.raw_weights = pageview_df.set_index("doc_id")["2021090300"].to_dict() + #self.weights = {} + #for key in self.raw_weights.keys(): + # if str(key) not in all_keys: + # continue + + # self.weights[key] = int(self.raw_weights[key]*1000) + # #assert self.weights[key] > 0, f"Too small {key}, {self.raw_weights[key]}" + # if self.weights[key] == 0: + # self.weights[key] = 1 + + + for key in all_keys: + if key not in self.weights: self.weights[key] = 1 @@ -175,7 +183,8 @@ class WeightedLoadBalancer(CrossKeyLoadBalancer): def __init__(self, pageview_file): pageview_df = pd.read_csv(pageview_file) - self.weights = pageview_df.set_index("doc_id")["weights"].to_dict() + #self.weights = pageview_df.set_index("doc_id")["weights"].to_dict() + self.weights = json.load(open("weights.json")) def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: chosen_key = None @@ -338,11 +347,22 @@ def run(self, replica_id: int): config = configparser.ConfigParser() config.read("config.yml") plan_dir = config["simulation"]["plan_dir"] -init_data_file = config["simulation"]["init_data_file"] -stream_edits_file = config["simulation"]["stream_edits_file"] -stream_questions_file = config["simulation"]["stream_questions_file"] -pageview_file = config["files"]["pageview_file"] -timestamp_weights_file = config["files"]["timestamp_weights_file"] +#init_data_file = config["simulation"]["init_data_file"] +#stream_edits_file = config["simulation"]["stream_edits_file"] +#stream_questions_file = config["simulation"]["stream_questions_file"] +#pageview_file = config["files"]["pageview_file"] +#timestamp_weights_file = config["files"]["timestamp_weights_file"] + +run = wandb.init(job_type="dataset-creation", project="wiki-workload") +question_dir = run.use_artifact('ucb-ralf/wiki-workload /questions:v2', type='dataset').download() +simulation_dir = run.use_artifact('ucb-ralf/wiki-workload /simulation:v2', type='dataset').download() +pageview_dir = run.use_artifact('ucb-ralf/wiki-workload /pageviews:v0', type='dataset').download() + +init_data_file = f"{simulation_dir}/init_data.json" +stream_edits_file = f"{simulation_dir}/edit_stream.json" +stream_questions_file = f"{simulation_dir}/question_stream.json" +pageview_file = f"{pageview_dir}/pageviews.csv" +timestamp_weights_file = f"{pageview_dir}/timestamp_weights_file.json" # load simulation data edits = json.load(open(stream_edits_file)) @@ -429,7 +449,8 @@ def run_once( parser.add_argument("--load_shedding_policy", type=str) args = parser.parse_args() - out_path = f"{plan_dir}/plan-{args.key_policy}_{args.event_policy}-{args.load_shedding_policy}-{args.model_runtime}-{args.send_rate}.json" + plan_name = f"{plan_dir}/plan-{args.key_policy}_{args.event_policy}-{args.load_shedding_policy}-{args.model_runtime}-{args.send_rate}" + out_path = f"{plan_name}.json" print(out_path) run_once( out_path=out_path, @@ -441,8 +462,7 @@ def run_once( model_runtime_constant=args.model_runtime, key_selection_policy=args.key_policy, ) - run = wandb.init(job_type="dataset-creation", project="wiki-workload") - log_plans(run, config, out_path) + log_plans(run, config, plan_dir) # load sheding: random, drop short edits diff --git a/wikipedia/wiki_eval.py b/wikipedia/wiki_eval.py index 1214cfb..048a97b 100644 --- a/wikipedia/wiki_eval.py +++ b/wikipedia/wiki_eval.py @@ -31,6 +31,7 @@ ) from dpr.utils.data_utils import Tensorizer +from preprocessing.log_data import log_plan_data """ @@ -47,14 +48,21 @@ """ # simulation data +import wandb +run = wandb.init(project='wiki-workload', job_type="dataset-creation") +simulation_dir = run.use_artifact('ucb-ralf/wiki-workload /simulation:v2', type='dataset').download() +question_dir = run.use_artifact('ucb-ralf/wiki-workload /questions:v2', type='dataset').download() + +init_data_file = f"{simulation_dir}/init_data.json" +stream_edits_file = f"{simulation_dir}/edit_stream.json" +stream_questions_file = f"{simulation_dir}/question_stream.json" + config = configparser.ConfigParser() config.read("config.yml") -plan_dir = config["simulation"]["plan_dir"] -init_data_file = config["simulation"]["init_data_file"] -stream_edits_file = config["simulation"]["stream_edits_file"] -stream_questions_file = config["simulation"]["stream_questions_file"] - -data_dir = config['files']['data_dir'] +#plan_dir = config["simulation"]["plan_dir"] +#init_data_file = config["simulation"]["init_data_file"] +#stream_edits_file = config["simulation"]["stream_edits_file"] +#stream_questions_file = config["simulation"]["stream_questions_file"] rev_dir = config['directory']['diff_dir'] embedding_dir = config['directory']['embedding_dir'] exp_dir = config['directory']['exp_dir'] @@ -64,87 +72,10 @@ parser = argparse.ArgumentParser(description="Specify experiment config") parser.add_argument("--offline-plan-path", type=str) parser.add_argument("--embed", default=False, action="store_true") +parser.add_argument("--wandb", default=False, action="store_true") args = parser.parse_args() - -class Retriever: - def __init__(self): - - # parser = argparse.ArgumentParser(description="") - add_encoder_params(parser) - add_tokenizer_params(parser) - add_cuda_params(parser) - args = parser.parse_args() - - setup_args_gpu(args) - - saved_state = load_states_from_checkpoint(model_file) - set_encoder_params_from_state(saved_state.encoder_params, args) - - self.tensorizer, self.encoder, _ = init_biencoder_components( - args.encoder_model_type, args, inference_only=True - ) - - self.encoder = self.encoder.ctx_model - - self.encoder, _ = setup_for_distributed_mode( - self.encoder, - None, - args.device, - args.n_gpu, - args.local_rank, - args.fp16, - args.fp16_opt_level, - ) - self.encoder.eval() - - model_to_load = get_model_obj(self.encoder) - - prefix_len = len("ctx_model.") - ctx_state = { - key[prefix_len:]: value - for (key, value) in saved_state.model_dict.items() - if key.startswith("ctx_model.") - } - model_to_load.load_state_dict(ctx_state) - self.device = args.device - - def predict(self, text): - - st = time.time() - batch_token_tensors = [self.tensorizer.text_to_tensor(text)] - - ctx_ids_batch = move_to_device( - torch.stack(batch_token_tensors, dim=0), self.device - ) - ctx_seg_batch = move_to_device(torch.zeros_like(ctx_ids_batch), self.device) - ctx_attn_mask = move_to_device( - self.tensorizer.get_attn_mask(ctx_ids_batch), self.device - ) - with torch.no_grad(): - _, embedding, _ = self.encoder(ctx_ids_batch, ctx_seg_batch, ctx_attn_mask) - embedding = embedding.cpu().numpy() - return embedding - - -def assign_timestamps_min(ts): - # take in unix timestamp - covert to integer - start_ts = 1628131044000000000 # don't change - delta = ts - start_ts - if delta < 0: - return None - - return int(delta / (60 * 1000000000)) - - -def embed_passages(sents, retriever_model, num_sent_in_pass=10): - passages = [] - embeddings = [] - for i in range(0, len(sents), num_sent_in_pass): - passages.append(" ".join(sents[i : i + num_sent_in_pass])) - embeddings.append(retriever_model.predict(passages[-1])) - return passages, embeddings - +run.config.update(vars(args)) def sents_to_passages(sents, num_sent_in_pass=10): passages = [] @@ -164,13 +95,10 @@ def offline_eval(plan_json_path, exp_id, compute_embeddings=True): keys = ["51150040"] filter_keys = False - # retriever_model = Retriever() - # print("Created retriever") # compute initial passage embeddings for each document init_data = json.load(open(init_data_file)) init_state = {} - staleness = [] for key in tqdm(init_data.keys()): if filter_keys and key not in keys: @@ -255,31 +183,36 @@ def offline_eval(plan_json_path, exp_id, compute_embeddings=True): print("EMBED", embed_versions.keys()) print("Num refits", count, len(missing)) - # returns latest version of document embeddings for timestep/key - def get_latest_embedding(timestep, doc_id): - - latest = 0 - for version in embed_versions.keys(): - version = float(version) - if ( - float(timestep) >= version - and version > latest - and doc_id in embed_versions[str(version)] - ): - latest = version - #print(doc_id, "latest", timestep, latest, timestep - latest) - assert ( - doc_id in embed_versions[str(latest)] - ), f"Missing doc id {doc_id} {latest} {doc_id in init_data}" - doc_version = embed_versions[str(latest)][doc_id] - assert latest <= timestep - return ( - doc_version["passages"], - doc_version["embeddings"], - doc_version["rev"], - latest, - ) - + embed_filename = "embed_versions.pkl" + pickle.dump(embed_versions, open(embed_filename, "wb")) + return embed_filename + +# returns latest version of document embeddings for timestep/key +def get_latest_embedding(timestep, doc_id, embed_versions): + + latest = 0 + for version in embed_versions.keys(): + version = float(version) + if ( + float(timestep) >= version + and version > latest + and doc_id in embed_versions[str(version)] + ): + latest = version + #print(doc_id, "latest", timestep, latest, timestep - latest) + assert ( + doc_id in embed_versions[str(latest)] + ), f"Missing doc id {doc_id} {latest} {doc_id in init_data}" + doc_version = embed_versions[str(latest)][doc_id] + assert latest <= timestep + return ( + doc_version["passages"], + doc_version["embeddings"], + doc_version["rev"], + latest, + ) + +def generate_question_data_all(exp_id, embed_filename): # create experiment directory directory = os.path.join(exp_dir, exp_id) if os.path.isdir(directory): @@ -290,16 +223,35 @@ def get_latest_embedding(timestep, doc_id): # get simulation data questions questions = json.load(open(stream_questions_file)) + + for ts in range(len(questions)): + questions[ts]["ts"] = ts + print("processing questions", len(questions)) print("directory", directory) - # Get embedding version for each query, write outputs - for ts in tqdm(range(len(questions))): - timestep = ts / 100 # TODO: Watch out!! can change and mess up experiment - # print(ts, timestep) + chunk_size = 1000 + chunks = [(questions[i:i+chunk_size], embed_filename, directory) for i in range(0, len(questions), chunk_size)] + p = Pool(128) + staleness_all = p.starmap(generate_question_data, chunks) + p.close() + staleness_all = [item for sublist in staleness_all for item in sublist] + staleness = np.array(staleness_all).mean() + print("all staleness", staleness) + wandb.log({"staleness": staleness}) + return directory + - for doc_id in questions[ts].keys(): +def generate_question_data(questions, embed_filename, directory): + embed_versions = pickle.load(open(embed_filename, "rb")) + init_data = json.load(open(init_data_file)) + staleness = [] + for ts_questions in questions: + ts = ts_questions["ts"] + timestep = ts / 100 # TODO: Watch out!! can change and mess up experiment + for doc_id in ts_questions.keys(): + if doc_id == "ts": continue # not considered in edits if doc_id not in init_data: print("missing", doc_id) @@ -308,11 +260,11 @@ def get_latest_embedding(timestep, doc_id): # get current embedding and write passage_texts, passage_embeddings, version, latest = get_latest_embedding( - timestep, doc_id + timestep, doc_id, embed_versions ) # loop through questions - doc_questions = questions[ts][doc_id] + doc_questions = ts_questions[doc_id] queries = [] for q in doc_questions: question = q["question"] @@ -326,7 +278,6 @@ def get_latest_embedding(timestep, doc_id): queries.append([question, [answer], doc_id]) # append per query - print("staleness", timestep - latest) staleness.append(timestep - latest) # dump CTX/question script @@ -352,11 +303,7 @@ def get_latest_embedding(timestep, doc_id): assert len(passage_ctx) == len(passage_texts) assert len(passage_embeddings) == len(passage_texts) - - print("done processing queries!", len(questions)) - print("staleness", np.array(staleness).mean()) - return directory - + return staleness def main(): @@ -365,14 +312,14 @@ def main(): ) # "wiki-plans/plan-fifo-always_process-1-0.001-60.json" exp_id = os.path.basename(plan_file).replace(".json", "") - output_dir = offline_eval(plan_file, exp_id, compute_embeddings=args.embed) - log_wandb = False - if log_wandb: - import wandb + #embed_filename = offline_eval(plan_file, exp_id, compute_embeddings=args.embed) - run = wandb.init(job_type="create_simulation_output") - artifact = wandb.Artifact(exp_id, type="dataset") - artifact.add_folder(output_dir) + embed_filename = "embed_versions.pkl" + generate_question_data_all(exp_id, embed_filename) + if args.wandb: + import wandb + run = wandb.init(job_type="dataset-creation", project="wiki-workload") + log_plan_data(run, config, exp_id, output_dir) if __name__ == "__main__": From 7422f944e97410e918918f25e289402b3e107bf0 Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Tue, 12 Oct 2021 18:01:08 -0700 Subject: [PATCH 14/26] add benchmark script to get realistic inference numbers --- wikipedia/benchmark_bert.py | 7 + wikipedia/notebooks/Wikipedia Plots.ipynb | 703 +++++++++++++++++++++- wikipedia/run_1_generate_plan.sh | 2 +- wikipedia/wiki_eval.py | 13 +- 4 files changed, 691 insertions(+), 34 deletions(-) create mode 100644 wikipedia/benchmark_bert.py diff --git a/wikipedia/benchmark_bert.py b/wikipedia/benchmark_bert.py new file mode 100644 index 0000000..fb9f602 --- /dev/null +++ b/wikipedia/benchmark_bert.py @@ -0,0 +1,7 @@ +from transformers import PyTorchBenchmark, PyTorchBenchmarkArguments +from pprint import pprint + +args = PyTorchBenchmarkArguments(models=["bert-base-uncased"], batch_sizes=[1], sequence_lengths=[100]) +benchmark = PyTorchBenchmark(args) +results = benchmark.run() +pprint(results) diff --git a/wikipedia/notebooks/Wikipedia Plots.ipynb b/wikipedia/notebooks/Wikipedia Plots.ipynb index 08f0f5a..0ef7d3e 100644 --- a/wikipedia/notebooks/Wikipedia Plots.ipynb +++ b/wikipedia/notebooks/Wikipedia Plots.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 410, "id": "e0030940", "metadata": {}, "outputs": [], @@ -24,10 +24,113 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 411, "id": "016e13bb", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "Finishing last run (ID:3mmrfkbb) before initializing another..." + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Waiting for W&B process to finish, PID 74125... (success)." + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "VBox(children=(Label(value=' 0.41MB of 0.41MB uploaded (0.00MB deduped)\\r'), FloatProgress(value=1.0, max=1.0)…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "
\n", + "
\n", + "
\n", + "Synced 7 W&B file(s), 0 media file(s), 0 artifact file(s) and 1 other file(s)\n", + "
Synced woven-sea-93: https://wandb.ai/ucb-ralf/wiki-workload%20/runs/3mmrfkbb
\n", + "Find logs at: ./wandb/run-20211012_125219-3mmrfkbb/logs
\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Successfully finished last run (ID:3mmrfkbb). Initializing new run:
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[34m\u001b[1mwandb\u001b[0m: wandb version 0.12.4 is available! To upgrade, please run:\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: $ pip install wandb --upgrade\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " Syncing run trim-microwave-115 to Weights & Biases (docs).
\n", + "\n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[34m\u001b[1mwandb\u001b[0m: Downloading large artifact questions:latest, 60.97MB. 2 files... Done. 0:0:0\n" + ] + } + ], "source": [ "run = wandb.init(job_type=\"evaluation\", project=\"wiki-workload\")\n", "pageview_dir = run.use_artifact('pageviews:latest').download()\n", @@ -36,10 +139,385 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 412, "id": "7690f6d7", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Unnamed: 0titleedit_count2021080500202108060020210807002021080800202108090020210810002021081100...20210828002021082900202108300020210831002021090100202109020020210903002021090400weightsdoc_id
00Deaths in 20211877383536313496656...69506368505239460.02851165984422
112021 Atlantic hurricane season14381151689714...820285121150.00380557798785
22Neeraj Chopra11563732434...560492130.00217051150040
33Fall of Kabul (2021)10091891212161012...11169920155100.00487668481047
44Great Britain at the 2020 Summer Paralympics989135641689...3868107470.00339760043578
..................................................................
211211List of fungi of South Africa203897132149...10761135560.00346768354495
212212Mister Supranational 2021203897132149...10761135560.00346767918135
2132132021–22 FC Barcelona season20219292927282723...21262916272043180.01269867089631
214214Hamid Karzai International Airport20114261517261417...1910251326142270.007258487602
215215Characters of the Marvel Cinematic Universe20114261517261417...1910251326142270.00725862372638
\n", + "

216 rows × 36 columns

\n", + "
" + ], + "text/plain": [ + " Unnamed: 0 title edit_count \\\n", + "0 0 Deaths in 2021 1877 \n", + "1 1 2021 Atlantic hurricane season 1438 \n", + "2 2 Neeraj Chopra 1156 \n", + "3 3 Fall of Kabul (2021) 1009 \n", + "4 4 Great Britain at the 2020 Summer Paralympics 989 \n", + ".. ... ... ... \n", + "211 211 List of fungi of South Africa 203 \n", + "212 212 Mister Supranational 2021 203 \n", + "213 213 2021–22 FC Barcelona season 202 \n", + "214 214 Hamid Karzai International Airport 201 \n", + "215 215 Characters of the Marvel Cinematic Universe 201 \n", + "\n", + " 2021080500 2021080600 2021080700 2021080800 2021080900 2021081000 \\\n", + "0 38 35 36 31 349 66 \n", + "1 11 5 16 8 9 7 \n", + "2 3 7 3 2 4 3 \n", + "3 18 9 12 12 16 10 \n", + "4 13 5 6 4 16 8 \n", + ".. ... ... ... ... ... ... \n", + "211 8 9 7 13 21 4 \n", + "212 8 9 7 13 21 4 \n", + "213 19 29 29 27 28 27 \n", + "214 14 26 15 17 26 14 \n", + "215 14 26 15 17 26 14 \n", + "\n", + " 2021081100 ... 2021082800 2021082900 2021083000 2021083100 \\\n", + "0 56 ... 69 50 63 68 \n", + "1 14 ... 8 20 2 8 \n", + "2 4 ... 5 6 0 4 \n", + "3 12 ... 11 16 9 9 \n", + "4 9 ... 3 8 6 8 \n", + ".. ... ... ... ... ... ... \n", + "211 9 ... 10 7 6 1 \n", + "212 9 ... 10 7 6 1 \n", + "213 23 ... 21 26 29 16 \n", + "214 17 ... 19 10 25 13 \n", + "215 17 ... 19 10 25 13 \n", + "\n", + " 2021090100 2021090200 2021090300 2021090400 weights doc_id \n", + "0 50 52 39 46 0.028511 65984422 \n", + "1 5 12 11 5 0.003805 57798785 \n", + "2 9 2 1 3 0.002170 51150040 \n", + "3 20 15 5 10 0.004876 68481047 \n", + "4 10 7 4 7 0.003397 60043578 \n", + ".. ... ... ... ... ... ... \n", + "211 13 5 5 6 0.003467 68354495 \n", + "212 13 5 5 6 0.003467 67918135 \n", + "213 27 20 43 18 0.012698 67089631 \n", + "214 26 14 22 7 0.007258 487602 \n", + "215 26 14 22 7 0.007258 62372638 \n", + "\n", + "[216 rows x 36 columns]" + ] + }, + "execution_count": 412, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "pageview_df = pd.read_csv(f\"{pageview_dir}/pageviews.csv\")\n", "pageview_df" @@ -47,10 +525,31 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 413, "id": "5b5d1edc", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 413, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAs0AAAFoCAYAAACsdsZBAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAABpNUlEQVR4nO3deXhU1f0/8Pe9d9ZshAQSEhIIRIGwCQRFRRERCZVocAEsShctfm1dWm1tta0sSq1Yf21da8W6FVfUgkREBBdAlCUgEMImBMISEpIQss527/n9cWcmGbJMkhmYZHi/noeHZObOzJnkJnnPmc/5HEkIIUBERERERC2SQz0AIiIiIqLOjqGZiIiIiMgPhmYiIiIiIj8YmomIiIiI/GBoJiIiIiLywxDqAfijaRpqa2thNBohSVKoh0NEREREYUoIAafTicjISMiy79xypw/NtbW12LdvX6iHQURERETniQEDBiA6Otrnsk4fmo1GIwB98CaT6Zw/fn5+PoYOHXrOH5e6Lp4z1BE8b6i9eM5QR/C8aZ3D4cC+ffu8+bOxTh+aPSUZJpMJZrM5JGMI1eNS18VzhjqC5w21F88Z6gieN/41VxLMhYBERERERH4wNBMRERER+cHQTERERETkR6evaSYiIiIKBqfTiaNHj8Jms4V6KCFjMBiwe/fuUA8j5CwWC1JSUppd8NcShmYiIiI6Lxw9ehTR0dFIS0s7b/d+qK2tRWRkZKiHEVJCCJSXl+Po0aPo169fm2/H8gwiIiI6L9hsNsTHx5+3gZl0kiQhPj6+3e84MDQTERHReYOBmYCOnQcMzUREREREfjA0ExEREXVSR48exZgxYwAAJSUlmDVrlve65557Dg6Hw+99vP3225g8eTKmTp2K2traszbWcMfQTERERNQFJCYm4r///a/38+effx5Op9Pv7f773//iqaeewtKlS5ssAnS5XEEfZ7hi9wwiIiI676zeWoFVWyrOyn1PGh2HiaPi/B63fft2PP30097Z3/vvvx/jx4/HW2+9hddffx09e/bEJZdc4j3+6NGjuPnmm7Fx40bMnz8fAHDrrbdClmX897//RUxMTJPH+M1vfoMjR47g97//PYYMGYK7774bt99+O26//XZs2LABN9xwA6655hosWLAAx48fh91ux5QpU3D33XcDALZs2YL58+fDbDZjxIgRWLNm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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "df = pd.DataFrame({\n", " \"edit_frequency\": pageview_df.edit_count / pageview_df.edit_count.sum(),\n", @@ -70,10 +569,106 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 414, "id": "39b1975e", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "Finishing last run (ID:1t9orwj8) before initializing another..." + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Waiting for W&B process to finish, PID 14934... (success)." + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "VBox(children=(Label(value=' 0.07MB of 0.07MB uploaded (0.00MB deduped)\\r'), FloatProgress(value=1.0, max=1.0)…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "
\n", + "
\n", + "
\n", + "Synced 6 W&B file(s), 0 media file(s), 0 artifact file(s) and 1 other file(s)\n", + "
Synced trim-microwave-115: https://wandb.ai/ucb-ralf/wiki-workload%20/runs/1t9orwj8
\n", + "Find logs at: ./wandb/run-20211012_160227-1t9orwj8/logs
\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Successfully finished last run (ID:1t9orwj8). Initializing new run:
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[34m\u001b[1mwandb\u001b[0m: wandb version 0.12.4 is available! To upgrade, please run:\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: $ pip install wandb --upgrade\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " Syncing run fluent-mountain-116 to Weights & Biases (docs).
\n", + "\n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "run = wandb.init(job_type=\"evaluation\", project=\"wiki-workload\")\n", "artifact = run.use_artifact('prediction_results:latest')\n", @@ -82,17 +677,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 415, "id": "101571e2", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'./artifacts/prediction_results:v1997'" + ] + }, + "execution_count": 415, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "artifact_dir" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 416, "id": "03e14929", "metadata": {}, "outputs": [], @@ -102,24 +708,55 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 453, "id": "eaf30e01", "metadata": {}, "outputs": [], "source": [ - "constants = [0.01, 0.05, 0.1, 1, 5]\n", + "constants = [0.01, 0.05]\n", "policies = [\"lifo\"]\n", "key_policies = [\"random\", \"weighted_random\", \"round_robin\", \"weighted_round_robin\"]\n", "d = artifact_dir\n", - "metric = 'top10'" + "metric = 'top5'" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 454, "id": "96209574", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/home/eecs/wooders/DPR/plan-random_lifo-always_process-0.01-100.json\n", + "/home/eecs/wooders/DPR/plan-random_lifo-always_process-0.05-100.json\n", + "/home/eecs/wooders/DPR/plan-weighted_random_lifo-always_process-0.01-100.json\n", + "/home/eecs/wooders/DPR/plan-weighted_random_lifo-always_process-0.05-100.json\n", + "/home/eecs/wooders/DPR/plan-round_robin_lifo-always_process-0.01-100.json\n", + "/home/eecs/wooders/DPR/plan-round_robin_lifo-always_process-0.05-100.json\n", + "/home/eecs/wooders/DPR/plan-weighted_round_robin_lifo-always_process-0.01-100.json\n", + "/home/eecs/wooders/DPR/plan-weighted_round_robin_lifo-always_process-0.05-100.json\n" + ] + }, + { + "data": { + "text/plain": [ + "{'plan-random_lifo-always_process': [0.41722204591135087, 0.41605839416058393],\n", + " 'plan-weighted_random_lifo-always_process': [0.508879315080318,\n", + " 0.44467986596668],\n", + " 'plan-round_robin_lifo-always_process': [0.5089891784573612,\n", + " 0.37384957156458265],\n", + " 'plan-weighted_round_robin_lifo-always_process': [0.5088165360077218,\n", + " 0.46732741640574116]}" + ] + }, + "execution_count": 454, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "all_results = {}\n", "for policy in policies: \n", @@ -213,7 +850,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 421, "id": "6d536763", "metadata": {}, "outputs": [], @@ -224,21 +861,35 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 455, "id": "1e07c3e9", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "import matplotlib.pyplot as plt\n", "import seaborn\n", "resources = constants \n", "df = pd.DataFrame({\n", - " 'Factor': resources, \n", + " 'Model Runtime Const': resources, \n", " **all_results\n", "})\n", - "fig, ax1 = plt.subplots(figsize=(10, 5))\n", - "tidy = df.melt(id_vars='Factor').rename(columns=str.title)\n", - "seaborn.barplot(x='Factor', y='Value', hue='Variable', data=tidy, ax=ax1)\n", + "fig, ax1 = plt.subplots(figsize=(5, 5),)\n", + "tidy = df.melt(id_vars='Model Runtime Const').rename(columns=str.title)\n", + "seaborn.barplot(x='Model Runtime Const', y='Value', hue='Variable', data=tidy, ax=ax1)\n", + "ax1.set(xlabel='Model Runtime Const', ylabel=f'{metric} Accuracy')\n", + "ax1.legend_.remove()\n", + "plt.legend(loc='lower center')\n", "seaborn.despine(fig)" ] }, @@ -366,7 +1017,7 @@ { "cell_type": "code", "execution_count": null, - "id": "592a8b2e", + "id": "a958fee2", "metadata": {}, "outputs": [], "source": [ @@ -376,7 +1027,7 @@ { "cell_type": "code", "execution_count": null, - "id": "98907ae3", + "id": "87453791", "metadata": {}, "outputs": [], "source": [ diff --git a/wikipedia/run_1_generate_plan.sh b/wikipedia/run_1_generate_plan.sh index 0334ade..a0689fe 100644 --- a/wikipedia/run_1_generate_plan.sh +++ b/wikipedia/run_1_generate_plan.sh @@ -1,6 +1,6 @@ set -xe -for key_policy in "weighted_random" "weighted_round_robin" +for key_policy in "random" "round_robin" do for event_policy in "lifo" do diff --git a/wikipedia/wiki_eval.py b/wikipedia/wiki_eval.py index 048a97b..a556403 100644 --- a/wikipedia/wiki_eval.py +++ b/wikipedia/wiki_eval.py @@ -75,7 +75,9 @@ parser.add_argument("--wandb", default=False, action="store_true") args = parser.parse_args() +exp_id = os.path.basename(args.offline_plan_path).replace(".json", "") run.config.update(vars(args)) +run.config.update({"plan": exp_id}) def sents_to_passages(sents, num_sent_in_pass=10): passages = [] @@ -303,18 +305,15 @@ def generate_question_data(questions, embed_filename, directory): assert len(passage_ctx) == len(passage_texts) assert len(passage_embeddings) == len(passage_texts) + print("staleness", np.array(staleness).mean()) return staleness def main(): + - plan_file = ( - args.offline_plan_path - ) # "wiki-plans/plan-fifo-always_process-1-0.001-60.json" - exp_id = os.path.basename(plan_file).replace(".json", "") - - #embed_filename = offline_eval(plan_file, exp_id, compute_embeddings=args.embed) + embed_filename = offline_eval(args.offline_plan_path, exp_id, compute_embeddings=args.embed) - embed_filename = "embed_versions.pkl" + #embed_filename = "embed_versions.pkl" generate_question_data_all(exp_id, embed_filename) if args.wandb: import wandb From 16a5dca1c6fb63dc4b2585f6482bcc372e7a3e59 Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Wed, 13 Oct 2021 21:44:52 -0700 Subject: [PATCH 15/26] semi wokring simulator - about to implement new policies and more replicas --- stl/offline/config_gen.py | 27 +- stl/offline/evaluation.py | 22 +- stl/offline/extend_data.py | 57 + stl/offline/run_1_simulate_windows.sh | 28 +- stl/offline/run_2_eval_yahoo_keys.sh | 32 +- stl/offline/run_3_eval_oracle.sh | 16 +- stl/offline/run_4_generate_plan.sh | 11 +- stl/offline/run_5_simulate_lp_plan.sh | 52 +- stl/offline/simulation.py | 10 +- wikipedia/benchmark_bert.py | 2 +- wikipedia/notebooks/Wikipedia Plots.ipynb | 1153 ++++++++++++++++++--- wikipedia/preprocessing/log_data.py | 3 + wikipedia/preprocessing/wiki_api_data.py | 2 + wikipedia/run_1_generate_plan.sh | 6 +- wikipedia/run_2_prepare_data.sh | 8 +- wikipedia/run_3_run_predictions.sh | 15 +- wikipedia/run_5_pipeline_predict.sh | 10 +- wikipedia/simulate.py | 20 +- wikipedia/wiki_eval.py | 10 +- 19 files changed, 1237 insertions(+), 247 deletions(-) create mode 100644 stl/offline/extend_data.py diff --git a/stl/offline/config_gen.py b/stl/offline/config_gen.py index 6e52b11..58ebca5 100644 --- a/stl/offline/config_gen.py +++ b/stl/offline/config_gen.py @@ -6,7 +6,6 @@ import numpy as np import pandas as pd from absl import app, flags -from ortools.linear_solver import pywraplp from sktime.performance_metrics.forecasting import mean_squared_scaled_error FLAGS = flags.FLAGS @@ -23,8 +22,30 @@ required=True, ) +# TODO(simon): add flags for lp solver constraint +flags.DEFINE_integer( + "max_n_fits", + default=None, + help="Max fits for LP", + required=False, +) + +flags.DEFINE_integer( + "max_loss", + default=None, + help="Max loss for LP", + required=False, +) + +flags.DEFINE_string( + "objective", + default="min_loss", + help="LP optimization goal", + required=False, +) -def run_lp(df: pd.DataFrame, max_n_fits=None, max_loss=None, objective="min_loss"): +def run_lp(df: pd.DataFrame, objective="min_loss"): + from ortools.linear_solver import pywraplp """Run through mixed integer program to generate the best plan. Input: @@ -35,6 +56,8 @@ def run_lp(df: pd.DataFrame, max_n_fits=None, max_loss=None, objective="min_loss Output: plan(Dict[str, int]): a dictionary mapping key -> optimal n_fits such that loss is minimal. """ + max_n_fits = FLAGS.max_n_fits + max_loss = FLAGS.max_loss assert all(df.columns == ["key", "n_fits", "loss"]) assert objective in {"min_loss", "min_fits"} diff --git a/stl/offline/evaluation.py b/stl/offline/evaluation.py index a32aab5..f3a47ac 100644 --- a/stl/offline/evaluation.py +++ b/stl/offline/evaluation.py @@ -1,4 +1,5 @@ import argparse +import time from multiprocessing import Pool import json import os @@ -13,7 +14,9 @@ def train(data, window_size, seasonality): window = data[-window_size:] values = [r["value"] for r in window] + st = time.time() stl_result = STL(values, period=seasonality, robust=True).fit() + print(time.time() - st) timestamp = data[-1]["timestamp"] return { "timestamp": timestamp, @@ -42,9 +45,14 @@ def predict(event, model): def offline_eval(yahoo_csv_path, plan_json_path, key, output_path): + print(output_path) + # get plan DF for key plan_df = pd.read_json(plan_json_path) - plan_df_key = plan_df[plan_df["key"] == int(key)] + if key is not None: + plan_df_key = plan_df[plan_df["key"] == int(key)] + else: + plan_df_key = plan_df plan_df_key.index = pd.RangeIndex(start=0, stop=len(plan_df_key.index)) # get original data @@ -69,6 +77,8 @@ def offline_eval(yahoo_csv_path, plan_json_path, key, output_path): #print("fit time", time.time() - st) offline_stl[row.processing_time] = trained + print(offline_stl.keys()) + # Assign the trained model with every events in the source file. def find_freshest_model_version(event_time, model_versions): @@ -84,6 +94,7 @@ def find_freshest_model_version(event_time, model_versions): # Run prediction! predicted = [] + print("running prediction") for _, row in df.iterrows(): model_version = row["model_version"] if np.isnan(model_version): @@ -108,8 +119,8 @@ def find_freshest_model_version(event_time, model_versions): add_df = pd.DataFrame(predicted) for new_col in add_df.columns: df[new_col] = add_df[new_col] - df.to_csv(output_file) - return + print("writing", output_path) + df.to_csv(output_path, index=None) def offline_eval_all(yahoo_path, plan_json_path, output_path, param_path): @@ -152,9 +163,8 @@ def run_exp(csv_path, plan_path, output_path, run_policy=False, run_oracle=False # Headers # processing_time window_start_seq_id window_end_seq_id key - plan_df = pd.read_json(plan_path) - offline_eval(csv_path, plan_df, output_path) - df.to_csv(output_path, index=None) + #plan_df = pd.read_json(plan_path) + offline_eval(csv_path, plan_path, None, output_path) def _ensure_dir(path): diff --git a/stl/offline/extend_data.py b/stl/offline/extend_data.py new file mode 100644 index 0000000..98ce1bc --- /dev/null +++ b/stl/offline/extend_data.py @@ -0,0 +1,57 @@ +import numpy as np +import pandas as pd +import random +import statistics +import glob +import os + +max_length = 1680 # double length +noise = 2 +max_seasonality = 24*7 +# over_sampling_rate = 1 +path = "yahoo_train_data/" +output_path = "yahoo_eval_data/" +input_path = "yahoo_train_data/*" +files = glob.glob(input_path) +print(files) +for filename in files: + df = pd.read_csv(filename) + + max_outlier_value, min_outlier_value = max(df['noise']), min(df['noise']) + mean, stddev = statistics.mean(df['noise']), statistics.stdev(df['noise']) + + initial_trend = df['trend'][0] + last_trend = df['trend'].iloc[-1] + trend_subtracted_series = df['trend'] - initial_trend + # trend_subtracted_series = np.repeat(trend_subtracted_series, over_sampling_rate) + + seasonality = df['seasonality1'] + df['seasonality2'] + df['seasonality3'] + # seasonality = np.repeat(seasonality, over_sampling_rate) + + repeat_length = (len(trend_subtracted_series) // max_seasonality) * max_seasonality + + count = 0 + generated_trend = [last_trend] * max_length + generated_noise = [0] * max_length + generated_outlier = [0] * max_length + generated_seasonality = [0] * max_length + + for i in range(max_length): + if count >= repeat_length: + count = 0 + last_trend = generated_trend[i-1] + generated_trend[i] = last_trend + trend_subtracted_series[count] + generated_seasonality[i] = seasonality[count] + generated_noise[i] = random.gauss(mean, stddev) + generated_outlier[i] = 0 + if random.randint(0, 100) > 100 - noise: + if random.randint(0, 100) > 50: + generated_outlier[i] = max_outlier_value * random.randint(70,100) // 100 + else: + generated_outlier[i] = min_outlier_value * random.randint(70,100) // 100 + count += 1 + + new_df = pd.DataFrame({"trend": generated_trend, "noise": generated_noise, "outlier": generated_outlier, "seasonality": generated_seasonality }) + new_df['value'] = new_df['trend'] + new_df['noise'] + new_df['outlier'] + new_df['seasonality'] + print(os.path.basename(filename)) + new_df.to_csv(os.path.join(output_path, os.path.basename(filename))) diff --git a/stl/offline/run_1_simulate_windows.sh b/stl/offline/run_1_simulate_windows.sh index 70dc721..e195c39 100644 --- a/stl/offline/run_1_simulate_windows.sh +++ b/stl/offline/run_1_simulate_windows.sh @@ -1,7 +1,27 @@ -set -xe +set -ex -for slide in 1 6 12 18 24 48 96 168 192 336 672 +data_dir="./yahoo_train_data" +tmp_script=`mktemp` + +for key_prio in "lifo" "fifo" +do +for data in `ls $data_dir/*` do - python simulation.py --model_runtime_s 0 --total_runtime_s 2000 --per_key_records_per_second 1 \ - --window_size 672 --slide_size ${slide} --output_path result/offline_1_slide/plan/slide_${slide}_plan.json + key=`basename $data` + for slide in 6 12 18 24 48 96 168 192 336 672 + do + echo \" python simulation.py --model_runtime_s 1.5 --total_runtime_s 2000 --per_key_records_per_second 1 --key_prio_policy ${key_prio} --window_size 672 --slide_size ${slide} --output_path offline_1_slide/plan/${key_prio}_slide_${slide}_plan.json --num_mapper_replicas 1\" >> $tmp_script + done +done done + +cat $tmp_script | xargs -n 1 -P 36 bash -l -c + +#set -xe +# +#for replicas in +#for slide in 1 6 12 18 24 48 96 168 192 336 672 +#do +# python simulation.py --model_runtime_s 0 --total_runtime_s 2000 --per_key_records_per_second 1 \ +# --window_size 672 --slide_size ${slide} --output_path result/offline_1_slide/plan/slide_${slide}_plan.json +#done diff --git a/stl/offline/run_2_eval_yahoo_keys.sh b/stl/offline/run_2_eval_yahoo_keys.sh index 444da55..c5f106d 100644 --- a/stl/offline/run_2_eval_yahoo_keys.sh +++ b/stl/offline/run_2_eval_yahoo_keys.sh @@ -1,14 +1,36 @@ set -ex -data_dir="/data/wooders/stl/yahoo" +data_dir="./yahoo_train_data" -for data in `ls $data_dir/A4/*` +tmp_script=`mktemp` +for key_prio in "lifo" "fifo" +do +for data in `ls $data_dir/*` do key=`basename $data` for slide in 6 12 18 24 48 96 168 192 336 672 do - python evaluation.py --offline-yahoo-csv-path $data \ - --offline-plan-path ./result/offline_1_slide/plan/slide_${slide}_plan.json \ - --output-path ./result/offline_1_slide/plan_eval/slide_${slide}_key_${key} + echo \" python evaluation.py --offline-yahoo-csv-path $data \ + --offline-plan-path ./offline_1_slide/plan/${key_prio}_slide_${slide}_plan.json \ + --output-path ./offline_1_slide/single_key/${key_prio}_slide_${slide}_key_${key} \" >> $tmp_script done done +done + +cat $tmp_script | xargs -n 1 -P 36 bash -l -c + + +#set -ex +# +#data_dir="/data/wooders/stl/yahoo" +# +#for data in `ls $data_dir/A4/*` +#do +# key=`basename $data` +# for slide in 6 12 18 24 48 96 168 192 336 672 +# do +# python evaluation.py --offline-yahoo-csv-path $data \ +# --offline-plan-path ./result/offline_1_slide/plan/slide_${slide}_plan.json \ +# --output-path ./result/offline_1_slide/plan_eval/slide_${slide}_key_${key} +# done +#done diff --git a/stl/offline/run_3_eval_oracle.sh b/stl/offline/run_3_eval_oracle.sh index 9262e2a..5fdbef5 100644 --- a/stl/offline/run_3_eval_oracle.sh +++ b/stl/offline/run_3_eval_oracle.sh @@ -1,14 +1,18 @@ set -ex -data_dir="/home/ubuntu/ydata-labeled-time-series-anomalies-v1_0/A4Benchmark/" +#data_dir="/home/ubuntu/ydata-labeled-time-series-anomalies-v1_0/A4Benchmark/" +data_dir="./yahoo_eval_data" +output_path="./oracle" tmp_script=`mktemp` -for data in `ls $data_dir/A4Benchmark-TS*` +#for data in `ls $data_dir/A4Benchmark-TS*` +for data in `ls $data_dir/*` do key=`basename $data` - echo python evaluation.py --offline-yahoo-csv-path $data \ - --offline-run-oracle true \ - --output-path ./result/offline_1_slide/plan_eval/oracle_key_${key} >> $tmp_script + echo \" python evaluation.py --offline-yahoo-csv-path $data \ + --offline-run-oracle \ + --output-path ${output_path}/${key} \" >> $tmp_script done -cat $tmp_script | parallel --bar bash -l -c \ No newline at end of file +cat $tmp_script | xargs -n 1 -P 36 bash -l -c +#cat $tmp_script | parallel --bar bash -l -c diff --git a/stl/offline/run_4_generate_plan.sh b/stl/offline/run_4_generate_plan.sh index 442cf98..0769b1f 100644 --- a/stl/offline/run_4_generate_plan.sh +++ b/stl/offline/run_4_generate_plan.sh @@ -3,6 +3,13 @@ set -ex # TODO(simon): use a workflow engine for step tracking # e.g. https://dagster.io/ +#python config_gen.py \ +# --csv_dir "./result/offline_1_slide/plan_eval" \ +# --output_path "./result/offline_1_slide/min_loss_plan.json" + +MAX_FITS=8400 python config_gen.py \ - --csv_dir "./result/offline_1_slide/plan_eval" \ - --output_path "./result/offline_1_slide/min_loss_plan.json" + --csv_dir "./offline_1_slide/plan_eval" \ + --output_path "./offline_1_slide/max_fits_${MAX_FITS}.json" \ + --max_n_fits ${MAX_FITS} + diff --git a/stl/offline/run_5_simulate_lp_plan.sh b/stl/offline/run_5_simulate_lp_plan.sh index bc67ae1..bf9daeb 100644 --- a/stl/offline/run_5_simulate_lp_plan.sh +++ b/stl/offline/run_5_simulate_lp_plan.sh @@ -1,26 +1,36 @@ set -ex -PARAM_PATH=result/offline_1_slide/min_loss_plan.json -PLAN_PATH=result/offline_1_slide/lp_eval/varying_slide_size_trace.json -SOURCE_PATH=/data/wooders/stl/yahoo/A4 -OUTPUT_CSV_PATH=result/offline_1_slide/ +PARAM_DIR="offline_1_slide" +PLAN_DIR="offline_1_slide" +OUTPUT_CSV_PATH="offline_1_slide/lp_plan_eval" +TRAIN_PATH="./yahoo_train_data" +EVAL_PATH="./yahoo_eval_data" -# re-run simulation with lp-generated weights -python simulation.py --model_runtime_s 0.02 --total_runtime_s 150 \ - --per_key_records_per_second 100 \ - --num_mapper_replicas 2 \ - --window_size 672 --slide_size 0 \ - --per_key_slide_size_plan $PARAM_PATH \ - --output_path $PLAN_PATH \ - --source_data_path $SOURCE_PATH -# run evaluation with simulation results -python evaluation.py --offline-yahoo-csv-path $SOURCE_PATH \ - --offline-plan-path $PLAN_PATH \ - --output-path $OUTPUT_CSV_PATH \ - --param-path $PARAM_PATH \ - --run-policy - -# get final results -python evaluate_loss.py --offline-yahoo-csv-path $SOURCE_PATH --predicted-csv-path $OUTPUT_CSV_PATH --output-path +for replicas in 8 +do +for plan in "max_fits_1100" "max_fits_2100" "max_fits_4200" "max_fits_8400" +do + mkdir -p ${PLAN_DIR}/replica_${replicas} + # re-run simulation with lp-generated weights + python simulation.py --model_runtime_s 1.5 --total_runtime_s 2000 \ + --per_key_records_per_second 1 \ + --num_mapper_replicas ${replicas} \ + --window_size 672 --slide_size 0 \ + --per_key_slide_size_plan ${PARAM_DIR}/${plan}.json \ + --output_path ${PLAN_DIR}/replica_${replicas}/plan_${plan}.json \ + --source_data_path ${TRAIN_PATH} + + mkdir -p ${PLAN_DIR}/replica_${replicas}/${plan} + # run evaluation with simulation results + python evaluation.py --offline-yahoo-csv-path $EVAL_PATH \ + --offline-plan-path ${PLAN_DIR}/replica_${replicas}/plan_${plan}.json \ + --output-path ${PLAN_DIR}/replica_${replicas}/${plan} \ + --param-path ${PARAM_DIR}/${plan}.json \ + --run-policy + + # get final results + #python evaluate_loss.py --offline-yahoo-csv-path $SOURCE_PATH --predicted-csv-path $OUTPUT_CSV_PATH --output-path +done +done diff --git a/stl/offline/simulation.py b/stl/offline/simulation.py index 33a16b0..476167d 100644 --- a/stl/offline/simulation.py +++ b/stl/offline/simulation.py @@ -26,7 +26,7 @@ flags.DEFINE_enum( "key_prio_policy", - "fifo", + "lifo", list(prio_policies.keys()), "The prioritization policy for a given key.", ) @@ -63,7 +63,7 @@ None, "path to generated per key's window slide size config.", ) -flags.DEFINE_integer("num_mapper_replicas", 10, "number of replicas for mapper") +flags.DEFINE_integer("num_mapper_replicas", 1, "number of replicas for mapper") def _get_config() -> Dict: @@ -79,7 +79,9 @@ def main(argv): policy_params = json.load(open(FLAGS.per_key_slide_size_plan)) keys = policy_params.keys() else: - keys = [i in range(FLAGS.num_keys)] + keys = [i+1 for i in range(FLAGS.num_keys)] + + print("keys", keys) source_to_window_queue = simpy.Store(env) windows_to_mapper_queue = { @@ -112,7 +114,7 @@ def main(argv): source_queues=windows_to_mapper_queue, model_run_time_s=FLAGS.model_runtime_s, # TODO(simon): customize this once we want different key selection policy - key_selection_policy_cls=RoundRobinLoadBalancer(), + key_selection_policy_cls=RoundRobinLoadBalancer(FLAGS.num_mapper_replicas), num_replicas=FLAGS.num_mapper_replicas, ) env.run(until=FLAGS.total_runtime_s) diff --git a/wikipedia/benchmark_bert.py b/wikipedia/benchmark_bert.py index fb9f602..4a636c0 100644 --- a/wikipedia/benchmark_bert.py +++ b/wikipedia/benchmark_bert.py @@ -1,7 +1,7 @@ from transformers import PyTorchBenchmark, PyTorchBenchmarkArguments from pprint import pprint -args = PyTorchBenchmarkArguments(models=["bert-base-uncased"], batch_sizes=[1], sequence_lengths=[100]) +args = PyTorchBenchmarkArguments(models=["bert-base-uncased"], batch_sizes=[1], sequence_lengths=[100], no_multi_process=True) benchmark = PyTorchBenchmark(args) results = benchmark.run() pprint(results) diff --git a/wikipedia/notebooks/Wikipedia Plots.ipynb b/wikipedia/notebooks/Wikipedia Plots.ipynb index 0ef7d3e..9213239 100644 --- a/wikipedia/notebooks/Wikipedia Plots.ipynb +++ b/wikipedia/notebooks/Wikipedia Plots.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 410, + "execution_count": 184, "id": "e0030940", "metadata": {}, "outputs": [], @@ -24,86 +24,15 @@ }, { "cell_type": "code", - "execution_count": 411, + "execution_count": 2, "id": "016e13bb", "metadata": {}, "outputs": [ - { - "data": { - "text/html": [ - "Finishing last run (ID:3mmrfkbb) before initializing another..." - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
Waiting for W&B process to finish, PID 74125... (success)." - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "VBox(children=(Label(value=' 0.41MB of 0.41MB uploaded (0.00MB deduped)\\r'), FloatProgress(value=1.0, max=1.0)…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - "
\n", - "
\n", - "
\n", - "Synced 7 W&B file(s), 0 media file(s), 0 artifact file(s) and 1 other file(s)\n", - "
Synced woven-sea-93: https://wandb.ai/ucb-ralf/wiki-workload%20/runs/3mmrfkbb
\n", - "Find logs at: ./wandb/run-20211012_125219-3mmrfkbb/logs
\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "Successfully finished last run (ID:3mmrfkbb). Initializing new run:
" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, { "name": "stderr", "output_type": "stream", "text": [ + "\u001b[34m\u001b[1mwandb\u001b[0m: Currently logged in as: \u001b[33mucb-ralf\u001b[0m (use `wandb login --relogin` to force relogin)\n", "\u001b[34m\u001b[1mwandb\u001b[0m: wandb version 0.12.4 is available! To upgrade, please run:\n", "\u001b[34m\u001b[1mwandb\u001b[0m: $ pip install wandb --upgrade\n" ] @@ -112,7 +41,7 @@ "data": { "text/html": [ "\n", - " Syncing run trim-microwave-115 to Weights & Biases (docs).
\n", + " Syncing run royal-planet-167 to Weights & Biases (docs).
\n", "\n", " " ], @@ -139,7 +68,7 @@ }, { "cell_type": "code", - "execution_count": 412, + "execution_count": 3, "id": "7690f6d7", "metadata": {}, "outputs": [ @@ -513,7 +442,7 @@ "[216 rows x 36 columns]" ] }, - "execution_count": 412, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -525,7 +454,7 @@ }, { "cell_type": "code", - "execution_count": 413, + "execution_count": 4, "id": "5b5d1edc", "metadata": {}, "outputs": [ @@ -535,18 +464,20 @@ "" ] }, - "execution_count": 413, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAs0AAAFoCAYAAACsdsZBAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAABpNUlEQVR4nO3deXhU1f0/8Pe9d9ZshAQSEhIIRIGwCQRFRRERCZVocAEsShctfm1dWm1tta0sSq1Yf21da8W6FVfUgkREBBdAlCUgEMImBMISEpIQss527/n9cWcmGbJMkhmYZHi/noeHZObOzJnkJnnPmc/5HEkIIUBERERERC2SQz0AIiIiIqLOjqGZiIiIiMgPhmYiIiIiIj8YmomIiIiI/GBoJiIiIiLywxDqAfijaRpqa2thNBohSVKoh0NEREREYUoIAafTicjISMiy79xypw/NtbW12LdvX6iHQURERETniQEDBiA6Otrnsk4fmo1GIwB98CaT6Zw/fn5+PoYOHXrOH5e6Lp4z1BE8b6i9eM5QR/C8aZ3D4cC+ffu8+bOxTh+aPSUZJpMJZrM5JGMI1eNS18VzhjqC5w21F88Z6gieN/41VxLMhYBERERERH4wNBMRERER+cHQTERERETkR6evaSYiIiIKBqfTiaNHj8Jms4V6KCFjMBiwe/fuUA8j5CwWC1JSUppd8NcShmYiIiI6Lxw9ehTR0dFIS0s7b/d+qK2tRWRkZKiHEVJCCJSXl+Po0aPo169fm2/H8gwiIiI6L9hsNsTHx5+3gZl0kiQhPj6+3e84MDQTERHReYOBmYCOnQcMzUREREREfjA0ExEREXVSR48exZgxYwAAJSUlmDVrlve65557Dg6Hw+99vP3225g8eTKmTp2K2traszbWcMfQTERERNQFJCYm4r///a/38+effx5Op9Pv7f773//iqaeewtKlS5ssAnS5XEEfZ7hi9wwiIiI676zeWoFVWyrOyn1PGh2HiaPi/B63fft2PP30097Z3/vvvx/jx4/HW2+9hddffx09e/bEJZdc4j3+6NGjuPnmm7Fx40bMnz8fAHDrrbdClmX897//RUxMTJPH+M1vfoMjR47g97//PYYMGYK7774bt99+O26//XZs2LABN9xwA6655hosWLAAx48fh91ux5QpU3D33XcDALZs2YL58+fDbDZjxIgRWLNm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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAD4CAYAAADiry33AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAA4nklEQVR4nO3dd3xUVd7H8c9vZlKA0BOQJgSlGDpEsCyoYAELiIJlBRVFREFRl11xXR/xeXTX3XXXtSAsCrKsuKgoKyIqNYpSQ5EqRWqkhd7S5zx/nEkyCRNyA2k3/N6vV5iZW88MM9977rnn3ivGGJRSSlVcnrIugFJKqZKlQa+UUhWcBr1SSlVwGvRKKVXBadArpVQF5yvrAoQSHR1tmjRpUtbFUEop11ixYsVBY0xMqHHlMuibNGlCYmJiWRdDKaVcQ0R2FjROm26UUqqC06BXSqkKToNeKaUquHLZRq+UOj8ZGRkkJSWRmppa1kVRxSwyMpKGDRsSFhbmeB4NeqUqoKSkJKpWrUqTJk0QkbIujiomxhgOHTpEUlISsbGxjufTphulKqDU1FRq166tIV/BiAi1a9cu8p6aBr1SFZSGfMV0Lv+vGvRFsS0BDv1c1qVQSqki0aAvis+Hw6I3y7oUSilVJBr0RZGVDlmZZV0KpSqMSZMmMXz4cADGjRvH5MmTc4bv2bPnrPMuXLiQVq1a0b59e1JSUkq8rG6mvW6Kwvjtn1Kq2A0dOjTn+aRJk2jdujX169cvcPopU6YwcuRIBg0alGd4VlYWXq+3xMrpRhr0RaFBr1zopS/Ws2HP8WJdZlz9arx4W6tCp/vggw948803SU9Pp0uXLrzzzjtMnjyZP/3pT9SrV4/mzZsTEREBwOjRo4mKisq51tV9991HpUqVWLx4MZUqVcqz3Pfee4+PP/6Yb775hrlz5/LII4/w0ksvUa9ePVavXs3atWsZNWoUCQkJpKWlMWzYMB599FGMMTzxxBPMnz+f2NhYjDE89NBD9OvXL2e90dHRJCYmMnLkSBISEjh16hRPPPEEa9euJTMzk9GjR9OnTx8mTZrEjBkzOH36ND///DN9+/blL3/5CwBff/01v//978nKyiI6Opo5c+bQokULFi1aRExMDH6/n+bNm7NkyRKio6OL9f8mFA36otCgV8qxjRs38tFHH/HDDz8QFhbG448/zgcffMCLL77IihUrqF69Otdddx0dOnTIM1+/fv14++23ee2114iPjw+57MGDB/P9999z66230q9fPxISEli2bBnr1q0jNjaW8ePHU716dZYvX05aWhpXX301N954I6tWrWLTpk2sXbuW/fv3ExcXx0MPPXTW9/HKK6/QvXt3Jk6cyNGjR+ncuTPXX389AKtXr2bVqlVERETQokULnnjiCSIjI3nkkUf47rvviI2N5fDhw3g8HgYMGMCUKVN46qmnmDt3Lu3atSuVkAcN+qLRoFcu5KTmXRLmzZvHihUruPzyywFISUlh0aJFXHvttcTE2Kvp3n333WzevLlY1te5c+eck4hmz57NmjVrmDZtGgDHjh1jy5YtfPfdd9x77714vV7q169P9+7dC13u7NmzmTFjBq+99hpgz1HYtWsXAD169KB69eoAxMXFsXPnTo4cOUK3bt1yylKrVi0AHnroIfr06cNTTz3FxIkTz2hyKkka9EVhcv5RShXCGMMDDzzAn/70p5xh//3vf5k+fXqJrK9KlSp51v3WW29x00035Zlm1qxZBfZD9/l8+P22Ihd8QpIxhk8//ZQWLVrkmX7p0qU5zU4AXq+XzMxMjDEh19GoUSPq1q3L/PnzWbp0KVOmTCn6mzxH2uumKLRGr5RjPXr0YNq0aRw4cACAw4cP06FDBxISEjh06BAZGRl88sknIeetWrUqJ06cOOd133TTTYwdO5aMjAwANm/ezKlTp+jWrRtTp04lKyuLvXv3smDBgpx5mjRpwooVKwD49NNP8yzrrbfewhhbyVu1atVZ133llVfy7bffsn379pz3nW3w4MEMGDCAu+66q1QPGGvQF4UGvVKOxcXF8fLLL3PjjTfStm1bbrjhBvbu3cvo0aO58soruf766+nYsWPIeR988EGGDh16zl0nBw8eTFxcHB07dqR169Y8+uijZGZm0rdvX5o1a0abNm147LHHuOaaa3LmefHFFxkxYgRdu3bNE8IvvPACGRkZtG3bltatW/PCCy+cdd0xMTGMHz+eO+64g3bt2nH33XfnjOvduzcnT54s1WYbAMneSpUn8fHxplzeYerli6DZ9XD3B2VdEqXOauPGjVx22WVlXYxy78EHH8w5oFsaEhMTefrpp1m4cOF5LSfU/6+IrDDGhDx6rW30RWH8UA43jEqp8u/VV19l7Nixpdo2n02Dvii06UapUte3b9+c9u5sf/7zn8840HouJk2adN7LcGrUqFGMGjWq1NYXTIO+KDTolSp1JdVL50Li6GCsiPQUkU0islVEztgkiUhLEVksImkiMjLEeK+IrBKRmcVR6DKjQa+UcqFCg15EvMAYoBcQB9wrInH5JjsMPAm8VsBiRgAbz6Oc5YTRoFdKuY6TGn1nYKsxZpsxJh2YCvQJnsAYc8AYsxzIyD+ziDQEbgHeK4bylp3sg7B6MFYp5TJOgr4BsDvodVJgmFP/AH4HnLUqLCJDRCRRRBKTk5OLsPhSkl2T1xq9UsplnAR9qPOFHVVrReRW4IAxZkVh0xpjxhtj4o0x8dnXwShXNOiVcqXf/va3tGrVit/+9rdlXZQy46TXTRLQKOh1Q+DsdwTIdTXQW0RuBiKBaiLygTFmQNGKWQ5o0CtV5s7lWvP//Oc/SU5OznNdGoDMzEx8vguj46GTd7kcaCYiscAvwD3Ar50s3BjzHPAcgIhcC4x0ZchDUNBrG71yma9Gwb61xbvMi9pAr1cLneyVV15h8uTJNGrUiJiYGDp16sTMmTNzLkF88OBB4uPj2bFjB1lZWSGvIZ+QkJDnWvN33nkn0dHRjBgxAoDnn3+eunXr8uSTT56x/t69e3Pq1Cm6dOnCc889x1dffUWtWrVYtWoVHTt25PHHH2fYsGEkJydTuXJl3n33XVq2bMn27dv59a9/TWZmJj179uT111/n5MmTJCQk8NprrzFzpu1AOHz4cOLj43nwwQdZsWIFzzzzDCdPniQ6OppJkyZRr149rr32Wrp06cKCBQs4evQoEyZMoGvXrmRlZfHss8/yzTffICI88sgjxMXF8fbbb+d0KZ0zZw5jx47ls88+O6//rkKD3hiTKSLDgW8ALzDRGLNeRIYGxo8TkYuARKAa4BeRp4A4Y0zx3u2gLGmNXqkiWbFiBVOnTmXVqlVkZmbSsWNHOnXqVOD0EyZMCHkNeSDPteZ37NjBHXfcwYgRI/D7/UydOpVly5aFXOaMGTOIiopi9erVAHz11Vds3ryZuXPn4vV66dGjB+PGjaNZs2YsXbqUxx9/nPnz5zNixAgee+wx7r//fsaMGVPoe83IyOCJJ57g888/JyYmho8++ojnn3+eiRMnAnbvYdmyZcyaNYuXXnqJuXPnMn78eLZv386qVavw+XwcPnyYmjVr5mx4YmJieP/994vlujiO9luMMbOAWfmGjQt6vg/bpHO2ZSQACUUuYXmhQa/cykHNuyQsXLiQvn37UrlyZcDWrs+moGvIh4eH57nWfJMmTahduzarVq1i//79dOjQgdq1azsuV//+/fF6vZw8eZJFixbRv3//nHFpaWkA/PDDDzlXsBw4cCDPPvvsWZe5adMm1q1bxw033ADYJqZ69erljL/jjjsA6NSpEzt27ABg7ty5DB06NKf5KPu69QMHDuSDDz5g0KBBLF68OOc+uufjwmigKg4a9EoVWajrsp/tuu+hriGfkJCQ51rzYK9OOWnSJPbt21foHaLyy16W3++nRo0aObX9opY9uPzGGFq1asXixYtDLiv7+ED2Neuz5wm1jkGDBnHbbbcRGRlJ//79i+U4gl6m2CkNeqWKpFu3bkyfPp2UlBROnDjBF198AeS97nt27R0KvoZ8KH379uXrr79m+fLl53zNm2rVqhEbG5tzTXxjDD/++CMAV199NVOnTgXIcxGyxo0bs2HDBtLS0jh27Bjz5s0DoEWLFiQnJ+cEfUZGBuvXrz/r+m+88UbGjRuXE/zZ162vX78+9evX5+WXX+bBBx88p/eWnwa9UzknTGnQK+VEx44dufvuu2nfvj133nknXbt2BWDkyJGMHTuWq666ioMHD+ZMX9A15EMJDw/nuuuuO+8beEyZMoUJEybQrl07WrVqxeeffw7AG2+8wZgxY7j88ss5duxYzvSNGjXirrvuom3bttx3330597sNDw9n2rRpPPvss7Rr14727duzaNGis6578ODBXHzxxbRt25Z27drx4Ycf5oy77777aNSoEXFx+S9CcG70evROnToEf20K9TvAkISyLo1SZ1Uer0c/evRooqKiGDnyjMthFZnf76djx4588sknNGvWrBhKd3ZRUVGcPHmyxNeTbfjw4XTo0IGHH3445PiiXo9ea/ROadONUuXChg0buPTSS+nRo0ephHxp69SpE2vWrGHAgOLria4HY53SoFfqvIwePbpYlhMXF8e2bdvyDFu7di0DBw7MMywiIoKlS5cWyzpLszafffyiOGnQO6UnTCmXKahXR0XUpk2bAnvPVDTn0tyuTTdOaY1euUhkZCSHDh06p1BQ5ZcxhkOHDhEZGVmk+bRG75QGvXKRhg0bkpSURLm8Eqw6L5GRkTRseNbzU8+gQe+UBr1y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\n", "text/plain": [ - "
" + "
" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" } ], @@ -569,14 +500,14 @@ }, { "cell_type": "code", - "execution_count": 414, + "execution_count": 24, "id": "39b1975e", "metadata": {}, "outputs": [ { "data": { "text/html": [ - "Finishing last run (ID:1t9orwj8) before initializing another..." + "Finishing last run (ID:2s3jbe1y) before initializing another..." ], "text/plain": [ "" @@ -588,7 +519,7 @@ { "data": { "text/html": [ - "
Waiting for W&B process to finish, PID 14934... (success)." + "
Waiting for W&B process to finish, PID 34365... (success)." ], "text/plain": [ "" @@ -605,7 +536,7 @@ "version_minor": 0 }, "text/plain": [ - "VBox(children=(Label(value=' 0.07MB of 0.07MB uploaded (0.00MB deduped)\\r'), FloatProgress(value=1.0, max=1.0)…" + "VBox(children=(Label(value=' 0.22MB of 0.22MB uploaded (0.00MB deduped)\\r'), FloatProgress(value=1.0, max=1.0)…" ] }, "metadata": {}, @@ -622,9 +553,9 @@ "
\n", "
\n", "
\n", - "Synced 6 W&B file(s), 0 media file(s), 0 artifact file(s) and 1 other file(s)\n", - "
Synced trim-microwave-115: https://wandb.ai/ucb-ralf/wiki-workload%20/runs/1t9orwj8
\n", - "Find logs at: ./wandb/run-20211012_160227-1t9orwj8/logs
\n" + "Synced 7 W&B file(s), 0 media file(s), 0 artifact file(s) and 1 other file(s)\n", + "
Synced divine-shadow-168: https://wandb.ai/ucb-ralf/wiki-workload%20/runs/2s3jbe1y
\n", + "Find logs at: ./wandb/run-20211012_194624-2s3jbe1y/logs
\n" ], "text/plain": [ "" @@ -636,7 +567,7 @@ { "data": { "text/html": [ - "Successfully finished last run (ID:1t9orwj8). Initializing new run:
" + "Successfully finished last run (ID:2s3jbe1y). Initializing new run:
" ], "text/plain": [ "" @@ -657,7 +588,7 @@ "data": { "text/html": [ "\n", - " Syncing run fluent-mountain-116 to Weights & Biases (docs).
\n", + " Syncing run breezy-cloud-170 to Weights & Biases (docs).
\n", "\n", " " ], @@ -677,17 +608,17 @@ }, { "cell_type": "code", - "execution_count": 415, + "execution_count": 25, "id": "101571e2", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "'./artifacts/prediction_results:v1997'" + "'./artifacts/prediction_results:v3620'" ] }, - "execution_count": 415, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -698,7 +629,7 @@ }, { "cell_type": "code", - "execution_count": 416, + "execution_count": 180, "id": "03e14929", "metadata": {}, "outputs": [], @@ -708,21 +639,24 @@ }, { "cell_type": "code", - "execution_count": 453, + "execution_count": 181, "id": "eaf30e01", "metadata": {}, "outputs": [], "source": [ - "constants = [0.01, 0.05]\n", + "#constants = [0.01, 0.05, 1.0, 10.0]\n", + "constants = [0.25]\n", "policies = [\"lifo\"]\n", "key_policies = [\"random\", \"weighted_random\", \"round_robin\", \"weighted_round_robin\"]\n", + "#key_policies = [\"random\", \"round_robin\"]\n", + "#key_policies = [\"weighted_random\", \"weighted_round_robin\"]\n", "d = artifact_dir\n", - "metric = 'top5'" + "metric = 'top10'" ] }, { "cell_type": "code", - "execution_count": 454, + "execution_count": 182, "id": "96209574", "metadata": {}, "outputs": [ @@ -730,29 +664,22 @@ "name": "stdout", "output_type": "stream", "text": [ - "/home/eecs/wooders/DPR/plan-random_lifo-always_process-0.01-100.json\n", - "/home/eecs/wooders/DPR/plan-random_lifo-always_process-0.05-100.json\n", - "/home/eecs/wooders/DPR/plan-weighted_random_lifo-always_process-0.01-100.json\n", - "/home/eecs/wooders/DPR/plan-weighted_random_lifo-always_process-0.05-100.json\n", - "/home/eecs/wooders/DPR/plan-round_robin_lifo-always_process-0.01-100.json\n", - "/home/eecs/wooders/DPR/plan-round_robin_lifo-always_process-0.05-100.json\n", - "/home/eecs/wooders/DPR/plan-weighted_round_robin_lifo-always_process-0.01-100.json\n", - "/home/eecs/wooders/DPR/plan-weighted_round_robin_lifo-always_process-0.05-100.json\n" + "/home/eecs/wooders/DPR/plan-random_lifo-always_process-0.25-100.json\n", + "/home/eecs/wooders/DPR/plan-weighted_random_lifo-always_process-0.25-100.json\n", + "/home/eecs/wooders/DPR/plan-round_robin_lifo-always_process-0.25-100.json\n", + "/home/eecs/wooders/DPR/plan-weighted_round_robin_lifo-always_process-0.25-100.json\n" ] }, { "data": { "text/plain": [ - "{'plan-random_lifo-always_process': [0.41722204591135087, 0.41605839416058393],\n", - " 'plan-weighted_random_lifo-always_process': [0.508879315080318,\n", - " 0.44467986596668],\n", - " 'plan-round_robin_lifo-always_process': [0.5089891784573612,\n", - " 0.37384957156458265],\n", - " 'plan-weighted_round_robin_lifo-always_process': [0.5088165360077218,\n", - " 0.46732741640574116]}" + "{'plan-random_lifo-always_process': [0.7078732804419647],\n", + " 'plan-weighted_random_lifo-always_process': [0.6361795795371613],\n", + " 'plan-round_robin_lifo-always_process': [0.6167886934890254],\n", + " 'plan-weighted_round_robin_lifo-always_process': [0.5987554048857813]}" ] }, - "execution_count": 454, + "execution_count": 182, "metadata": {}, "output_type": "execute_result" } @@ -767,40 +694,30 @@ " print(f'{d}/{name}-{constant}-100.json')\n", " with open(f'{d}/{name}-{constant}-100.json') as results_file:\n", " results = json.load(results_file)\n", - " scores.append(results[metric])\n", + " scores.append(1-results[metric])\n", " all_results[name] = scores\n", "all_results" ] }, { "cell_type": "code", - "execution_count": null, - "id": "d3b31501", - "metadata": {}, - "outputs": [], - "source": [ - "all_results = {}\n", - "for policy in policies: \n", - " for key_policy in key_policies: \n", - " scores = []\n", - " name = f\"plan-{key_policy}_{policy}-always_process\"\n", - " for constant in constants: \n", - " with open(f'{d}/{name}-{constant}-100.json') as results_file:\n", - " print(f'{d}/{name}-{constant}-100.json')\n", - " results = json.load(results_file)\n", - " scores.append(results[metric])\n", - " all_results[name] = scores\n", - "all_results" - ] - }, - { - "cell_type": "code", - "execution_count": null, + "execution_count": 106, "id": "b479a2bc", "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "dict_keys(['plan-random_lifo-always_process', 'plan-weighted_random_lifo-always_process', 'plan-round_robin_lifo-always_process', 'plan-weighted_round_robin_lifo-always_process', 'plan-random_fifo-always_process', 'plan-weighted_random_fifo-always_process', 'plan-round_robin_fifo-always_process', 'plan-weighted_round_robin_fifo-always_process'])" + ] + }, + "execution_count": 106, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "all_results.keys()" ] @@ -850,7 +767,7 @@ }, { "cell_type": "code", - "execution_count": 421, + "execution_count": 12, "id": "6d536763", "metadata": {}, "outputs": [], @@ -861,15 +778,49 @@ }, { "cell_type": "code", - "execution_count": 455, + "execution_count": 183, + "id": "89abf373", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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l19+mU2bNlGuXDlu375NuXLl+PLLL2nUqNHTrk9EREQkx3ngDJrRaKRq1aocPnyYPn36ZEVNIiIiIjma9uIUERERMTPai1NERETEzGgvThEREREz88CAlpyczIcffkj16tWxsbHJippEREREcrQHnoNmaWlJnz59FM5EREREskimbrPh6+tLSEjIUy5FRERERCCT56A5OzvTo0cPGjZsSLFixdJs+fTee+9laqBz584xbNgwrl+/TsGCBQkKCsLFxSXDtmfPnuXVV18lICCAoUOHZqp/ERERkedFpmbQ4uPjadSoERYWFkRFRXHlypXU/2XWmDFjCAgIYMeOHQQEBDB69OgM2xmNRsaMGaOb4IqIiEiOlakZtMmTJz/WINHR0YSFhbF8+XIA/P39mTBhAjExMdjb26dpu3jxYurXr09cXBxxcXGPNa6IiIjIs+i+Ae2bb76hWbNmqT+fPXsWV1fX1J9XrFhBly5dHjhIZGQkRYsWxWAwACk3v3V0dCQyMjJNQDt16hR79+5l5cqVLFiw4GHfCwChoaGP9LpnQfXq1bO7BBERkSx15MiR7C7hqbnf3/X7BrSRI0emCWgdOnTg4MGDqT/PmTMnUwEtMxITExk1ahSTJ09ODXKPwtPTk1y5cj2RmkRERCR75dTJifsGNJPJ9FA/34uTkxNRUVEYjUYMBgNGo5GrV6/i5OSU2ubPP//kwoULvPPOOwDcvHkTk8lEbGwsEyZMyNQ4IiIiIs+D+wa0/16tmZmf76Vw4cJ4eHgQHBxMq1atCA4OxsPDI83yprOzMwcOHEj9ee7cucTFxekqThEREclxHngVp8lkIjk5GaPRmOHPmTV27FhWrVqFn58fq1atYty4cQD06NGDEydOPELpIiIiIs+n+86gxcXFUbFixdSfTSZT6s8mkynTM2gAbm5urF+/Pt3zS5YsybD9u+++m+m+RURERJ4n9w1o2ghdREREJOvdN6AVL148q+oQERERkb9laicBEREREck6CmgiIiIiZkYBTURERMTMKKCJiIiImJkHbpa+du1aNm3axO+//05cXBy2traUK1eONm3a8Prrr2dFjSIiIiI5yn0D2rRp09i9ezddu3alQoUK5MuXj9jYWE6ePMmKFSu4ePEiAwcOzKpaRURERHKE+wa0jRs38tVXX+Ho6Jjm+UqVKlG3bl1atmypgCYi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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import seaborn\n", + "resources = [int(10 / c) for c in constants] \n", + "df = pd.DataFrame({\n", + " 'Model Runtime Const': resources, \n", + " **all_results\n", + "})\n", + "fig, ax1 = plt.subplots(figsize=(10, 5))\n", + "tidy = df.melt(id_vars='Model Runtime Const').rename(columns=str.title)\n", + "seaborn.barplot(x='Model Runtime Const', y='Value', hue='Variable', data=tidy, ax=ax1)\n", + "ax1.set(xlabel='Resources', ylabel=f'{metric} Error')\n", + "ax1.legend_.remove()\n", + "plt.legend(loc='lower left')\n", + "seaborn.despine(fig)" + ] + }, + { + "cell_type": "code", + "execution_count": 150, "id": "1e07c3e9", "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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rl27pnoBIiIiIpKQ1uIUERERsTBai1NERETEwmgtThEREREL89SAFhMTw6hRoyhbtix2dnbmqElEREQkXXvqOWjW1tZ07dpV4UxERETETFJ0o9ry5ctz8ODBNC5FRERERCCF56Dlzp0bPz8/atasSa5cuRIs+dTdjPcZEREREUkPUhTQIiMjqVWrFgBXrlxJ04JERERE0rsUBbSvv/46resQERERkceSPQdt06ZNCR6fPn06weN58+alekEiIiIi6V2yAe2rr75K8PiDDz5I8Hjy5MmpX5GIiIhIOpdsQIuNjX2mxyIiIiLy4pINaP++WjMlj0VERETkxT31IoHY2Nj4/yX1WERERERSV7IB7eHDh5QoUSL+cWxsbPzj2NhYzaCJiIiIpIFkA5oWQhcRERExv2QDWp48ecxVh4iIiIg8lqK1OEVERETEfBTQRERERCyMApqIiIiIhVFAExEREbEwT70P2rJly1izZg1//vknDx8+xNHRkaJFi/Lee+/RokULc9QoIiIikq4kG9DGjh3L9u3b+eijjyhevDiZMmXi/v37HD9+nHnz5nHhwgV69eplrlpFRERE0oVkA9qqVatYt24dLi4uCZ4vWbIkVapUoXHjxgpoIiIiIqnsmRZLFxEREZG0l+wMWrNmzWjfvj0dO3bE3d09/hDniRMnmDdvHs2bNzdXnSIiIiLpRrIB7csvvyRfvnysWrWKv/76K/4igSJFitC2bVs++OADc9UpIiIikm489SrODz74QEFMRERExIxe6D5oly5dSq06REREROSx5w5oRqORmjVrpmYtIiIiIsJTDnHu3bv3iduMRmOqFyMiIiIiTwlobdu2JUeOHFhba0UoEREREXNJNqDlzp2bcePGUaZMmUTbIiMj8fb2Tqu6RERERNKtZKfGPD09CQ0NTXKblZUVrq6uaVKUiIiISHqWbEAbP348rVq1SnKbnZ0dP/74Y4o7OnPmDC1btqRu3bq0bNmSs2fPPrHt6dOn8fLyYsyYMSnev4iIiMjrItmAZmtri62tbap0NGTIEFq3bs2WLVto3bo1gwcPTrKdyWRiyJAh1KpVK1X6FREREXnVpOjsf6PRSGBgIHXq1MHb25s6deowadIkIiMjU9TJjRs3OHbsGA0bNgSgYcOGHDt2jJs3byZqO2PGDKpXr07BggVT/i5EREREXiMpCmhD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\n", "text/plain": [ - "
" + "
" ] }, "metadata": {}, @@ -879,17 +830,17 @@ "source": [ "import matplotlib.pyplot as plt\n", "import seaborn\n", - "resources = constants \n", + "resources = [int(1 / c) for c in constants] \n", "df = pd.DataFrame({\n", " 'Model Runtime Const': resources, \n", " **all_results\n", "})\n", - "fig, ax1 = plt.subplots(figsize=(5, 5),)\n", + "fig, ax1 = plt.subplots(figsize=(10, 5))\n", "tidy = df.melt(id_vars='Model Runtime Const').rename(columns=str.title)\n", "seaborn.barplot(x='Model Runtime Const', y='Value', hue='Variable', data=tidy, ax=ax1)\n", - "ax1.set(xlabel='Model Runtime Const', ylabel=f'{metric} Accuracy')\n", + "ax1.set(xlabel='Resources', ylabel=f'{metric} Error')\n", "ax1.legend_.remove()\n", - "plt.legend(loc='lower center')\n", + "plt.legend(loc='lower left')\n", "seaborn.despine(fig)" ] }, @@ -1017,7 +968,7 @@ { "cell_type": "code", "execution_count": null, - "id": "a958fee2", + "id": "d2775834", "metadata": {}, "outputs": [], "source": [ @@ -1027,7 +978,7 @@ { "cell_type": "code", "execution_count": null, - "id": "87453791", + "id": "41a032ee", "metadata": {}, "outputs": [], "source": [ @@ -1120,7 +1071,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "id": "c768b43d", "metadata": {}, "outputs": [], @@ -1168,7 +1119,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 185, "id": "ac3582ce", "metadata": {}, "outputs": [], @@ -1179,57 +1130,782 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 186, "id": "ce16ddda", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Unnamed: 0questionanswerdoc_iddatetimerevidoldrevidts_min
00what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 00:16:27.428572103721253210372124891299.0
11what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 00:32:54.857144103721253210372124891315.0
22what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 00:49:22.285716103721253210372124891331.0
33what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 01:05:49.714288103721253210372124891348.0
44what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 01:22:17.142860103721253210372124891364.0
...........................
127727127727who is the ayo??????Hunter B-15 (portrayed by Wunmi Mosaku) is an ...623726382021-09-01 20:46:09.2307001041650936104165081839968.0
127728127728who is the ayo??????Hunter B-15 (portrayed by Wunmi Mosaku) is an ...623726382021-09-01 21:30:27.6922361041650936104165081840013.0
127729127729who is the ayo??????Hunter B-15 (portrayed by Wunmi Mosaku) is an ...623726382021-09-01 22:14:46.1537721041650936104165081840057.0
127730127730who is the ayo??????Hunter B-15 (portrayed by Wunmi Mosaku) is an ...623726382021-09-01 22:59:04.6153081041650936104165081840101.0
127731127731who is the ayo??????Hunter B-15 (portrayed by Wunmi Mosaku) is an ...623726382021-09-01 23:43:23.0768441041650936104165081840145.0
\n", + "

127732 rows × 8 columns

\n", + "
" + ], + "text/plain": [ + " Unnamed: 0 question \\\n", + "0 0 what is the most common death in 2021??????? \n", + "1 1 what is the most common death in 2021??????? \n", + "2 2 what is the most common death in 2021??????? \n", + "3 3 what is the most common death in 2021??????? \n", + "4 4 what is the most common death in 2021??????? \n", + "... ... ... \n", + "127727 127727 who is the ayo?????? \n", + "127728 127728 who is the ayo?????? \n", + "127729 127729 who is the ayo?????? \n", + "127730 127730 who is the ayo?????? \n", + "127731 127731 who is the ayo?????? \n", + "\n", + " answer doc_id \\\n", + "0 A typical entry reports information in the fol... 65984422 \n", + "1 A typical entry reports information in the fol... 65984422 \n", + "2 A typical entry reports information in the fol... 65984422 \n", + "3 A typical entry reports information in the fol... 65984422 \n", + "4 A typical entry reports information in the fol... 65984422 \n", + "... ... ... \n", + "127727 Hunter B-15 (portrayed by Wunmi Mosaku) is an ... 62372638 \n", + "127728 Hunter B-15 (portrayed by Wunmi Mosaku) is an ... 62372638 \n", + "127729 Hunter B-15 (portrayed by Wunmi Mosaku) is an ... 62372638 \n", + "127730 Hunter B-15 (portrayed by Wunmi Mosaku) is an ... 62372638 \n", + "127731 Hunter B-15 (portrayed by Wunmi Mosaku) is an ... 62372638 \n", + "\n", + " datetime revid oldrevid ts_min \n", + "0 2021-08-06 00:16:27.428572 1037212532 1037212489 1299.0 \n", + "1 2021-08-06 00:32:54.857144 1037212532 1037212489 1315.0 \n", + "2 2021-08-06 00:49:22.285716 1037212532 1037212489 1331.0 \n", + "3 2021-08-06 01:05:49.714288 1037212532 1037212489 1348.0 \n", + "4 2021-08-06 01:22:17.142860 1037212532 1037212489 1364.0 \n", + "... ... ... ... ... \n", + "127727 2021-09-01 20:46:09.230700 1041650936 1041650818 39968.0 \n", + "127728 2021-09-01 21:30:27.692236 1041650936 1041650818 40013.0 \n", + "127729 2021-09-01 22:14:46.153772 1041650936 1041650818 40057.0 \n", + "127730 2021-09-01 22:59:04.615308 1041650936 1041650818 40101.0 \n", + "127731 2021-09-01 23:43:23.076844 1041650936 1041650818 40145.0 \n", + "\n", + "[127732 rows x 8 columns]" + ] + }, + "execution_count": 186, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df" ] }, { "cell_type": "code", - "execution_count": null, - "id": "07d5672a", + "execution_count": 191, + "id": "76fa4e4f", "metadata": {}, "outputs": [], "source": [ - "df.doc_id.value_counts()" + "thresh = 20000" ] }, { "cell_type": "code", - "execution_count": null, - "id": "d9dab1e5", + "execution_count": 192, + "id": "fe3f87bc", "metadata": {}, "outputs": [], "source": [ - "df.question.value_counts()" + "train_df = df[df.ts_min < thresh]\n", + "test_df = df[df.ts_min < thresh]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 193, + "id": "63a1c934", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Unnamed: 0questionanswerdoc_iddatetimerevidoldrevidts_min
00what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 00:16:27.428572103721253210372124891299.0
11what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 00:32:54.857144103721253210372124891315.0
22what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 00:49:22.285716103721253210372124891331.0
33what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 01:05:49.714288103721253210372124891348.0
44what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 01:22:17.142860103721253210372124891364.0
...........................
127210127210What is the story of Soren??He first appears in the film \"Iron Man 3\" late...623726382021-08-18 23:18:001039252299103925226619960.0
127211127211What is the story of Soren??He first appears in the film \"Iron Man 3\" and ...623726382021-08-18 23:24:001039252266103923801419966.0
127212127212What is the story of Soren??He first appears in the film \"Iron Man 3.\" He ...623726382021-08-18 23:30:001039264480103925805919972.0
127213127213What is the story of Soren??He first appears in the film \"Iron Man 3\" late...623726382021-08-18 23:48:001039252299103925226619990.0
127214127214What is the story of Soren??He first appears in the film \"Iron Man 3\" and ...623726382021-08-18 23:54:001039252266103923801419996.0
\n", + "

48653 rows × 8 columns

\n", + "
" + ], + "text/plain": [ + " Unnamed: 0 question \\\n", + "0 0 what is the most common death in 2021??????? \n", + "1 1 what is the most common death in 2021??????? \n", + "2 2 what is the most common death in 2021??????? \n", + "3 3 what is the most common death in 2021??????? \n", + "4 4 what is the most common death in 2021??????? \n", + "... ... ... \n", + "127210 127210 What is the story of Soren?? \n", + "127211 127211 What is the story of Soren?? \n", + "127212 127212 What is the story of Soren?? \n", + "127213 127213 What is the story of Soren?? \n", + "127214 127214 What is the story of Soren?? \n", + "\n", + " answer doc_id \\\n", + "0 A typical entry reports information in the fol... 65984422 \n", + "1 A typical entry reports information in the fol... 65984422 \n", + "2 A typical entry reports information in the fol... 65984422 \n", + "3 A typical entry reports information in the fol... 65984422 \n", + "4 A typical entry reports information in the fol... 65984422 \n", + "... ... ... \n", + "127210 He first appears in the film \"Iron Man 3\" late... 62372638 \n", + "127211 He first appears in the film \"Iron Man 3\" and ... 62372638 \n", + "127212 He first appears in the film \"Iron Man 3.\" He ... 62372638 \n", + "127213 He first appears in the film \"Iron Man 3\" late... 62372638 \n", + "127214 He first appears in the film \"Iron Man 3\" and ... 62372638 \n", + "\n", + " datetime revid oldrevid ts_min \n", + "0 2021-08-06 00:16:27.428572 1037212532 1037212489 1299.0 \n", + "1 2021-08-06 00:32:54.857144 1037212532 1037212489 1315.0 \n", + "2 2021-08-06 00:49:22.285716 1037212532 1037212489 1331.0 \n", + "3 2021-08-06 01:05:49.714288 1037212532 1037212489 1348.0 \n", + "4 2021-08-06 01:22:17.142860 1037212532 1037212489 1364.0 \n", + "... ... ... ... ... \n", + "127210 2021-08-18 23:18:00 1039252299 1039252266 19960.0 \n", + "127211 2021-08-18 23:24:00 1039252266 1039238014 19966.0 \n", + "127212 2021-08-18 23:30:00 1039264480 1039258059 19972.0 \n", + "127213 2021-08-18 23:48:00 1039252299 1039252266 19990.0 \n", + "127214 2021-08-18 23:54:00 1039252266 1039238014 19996.0 \n", + "\n", + "[48653 rows x 8 columns]" + ] + }, + "execution_count": 193, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "train_df" + ] + }, + { + "cell_type": "code", + "execution_count": 195, + "id": "d3343738", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Unnamed: 0questionanswerdoc_iddatetimerevidoldrevidts_min
00what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 00:16:27.428572103721253210372124891299.0
11what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 00:32:54.857144103721253210372124891315.0
22what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 00:49:22.285716103721253210372124891331.0
33what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 01:05:49.714288103721253210372124891348.0
44what is the most common death in 2021???????A typical entry reports information in the fol...659844222021-08-06 01:22:17.142860103721253210372124891364.0
...........................
127210127210What is the story of Soren??He first appears in the film \"Iron Man 3\" late...623726382021-08-18 23:18:001039252299103925226619960.0
127211127211What is the story of Soren??He first appears in the film \"Iron Man 3\" and ...623726382021-08-18 23:24:001039252266103923801419966.0
127212127212What is the story of Soren??He first appears in the film \"Iron Man 3.\" He ...623726382021-08-18 23:30:001039264480103925805919972.0
127213127213What is the story of Soren??He first appears in the film \"Iron Man 3\" late...623726382021-08-18 23:48:001039252299103925226619990.0
127214127214What is the story of Soren??He first appears in the film \"Iron Man 3\" and ...623726382021-08-18 23:54:001039252266103923801419996.0
\n", + "

48653 rows × 8 columns

\n", + "
" + ], + "text/plain": [ + " Unnamed: 0 question \\\n", + "0 0 what is the most common death in 2021??????? \n", + "1 1 what is the most common death in 2021??????? \n", + "2 2 what is the most common death in 2021??????? \n", + "3 3 what is the most common death in 2021??????? \n", + "4 4 what is the most common death in 2021??????? \n", + "... ... ... \n", + "127210 127210 What is the story of Soren?? \n", + "127211 127211 What is the story of Soren?? \n", + "127212 127212 What is the story of Soren?? \n", + "127213 127213 What is the story of Soren?? \n", + "127214 127214 What is the story of Soren?? \n", + "\n", + " answer doc_id \\\n", + "0 A typical entry reports information in the fol... 65984422 \n", + "1 A typical entry reports information in the fol... 65984422 \n", + "2 A typical entry reports information in the fol... 65984422 \n", + "3 A typical entry reports information in the fol... 65984422 \n", + "4 A typical entry reports information in the fol... 65984422 \n", + "... ... ... \n", + "127210 He first appears in the film \"Iron Man 3\" late... 62372638 \n", + "127211 He first appears in the film \"Iron Man 3\" and ... 62372638 \n", + "127212 He first appears in the film \"Iron Man 3.\" He ... 62372638 \n", + "127213 He first appears in the film \"Iron Man 3\" late... 62372638 \n", + "127214 He first appears in the film \"Iron Man 3\" and ... 62372638 \n", + "\n", + " datetime revid oldrevid ts_min \n", + "0 2021-08-06 00:16:27.428572 1037212532 1037212489 1299.0 \n", + "1 2021-08-06 00:32:54.857144 1037212532 1037212489 1315.0 \n", + "2 2021-08-06 00:49:22.285716 1037212532 1037212489 1331.0 \n", + "3 2021-08-06 01:05:49.714288 1037212532 1037212489 1348.0 \n", + "4 2021-08-06 01:22:17.142860 1037212532 1037212489 1364.0 \n", + "... ... ... ... ... \n", + "127210 2021-08-18 23:18:00 1039252299 1039252266 19960.0 \n", + "127211 2021-08-18 23:24:00 1039252266 1039238014 19966.0 \n", + "127212 2021-08-18 23:30:00 1039264480 1039258059 19972.0 \n", + "127213 2021-08-18 23:48:00 1039252299 1039252266 19990.0 \n", + "127214 2021-08-18 23:54:00 1039252266 1039238014 19996.0 \n", + "\n", + "[48653 rows x 8 columns]" + ] + }, + "execution_count": 195, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test_df" + ] + }, + { + "cell_type": "code", + "execution_count": 196, + "id": "07d5672a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1305297 8677\n", + "332667 4300\n", + "66304621 3720\n", + "17888363 3569\n", + "3259011 1581\n", + " ... \n", + "67959451 15\n", + "49474213 12\n", + "66135952 12\n", + "66074428 8\n", + "40713040 2\n", + "Name: doc_id, Length: 118, dtype: int64" + ] + }, + "execution_count": 196, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "train_df.doc_id.value_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": 197, + "id": "d9dab1e5", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "What is the name of the company?? 4339\n", + "what is the name of the company?????? 4018\n", + "what is the u.s. open???????? 1201\n", + "What is the best tennis tournament in the world?? 1090\n", + "what is the std?????? 1035\n", + " ... \n", + "What are the main factors that affect the success of the high speed railway system?? 1\n", + "What did the government do?? 1\n", + "What is the purpose of the evacuation?? 1\n", + "what is a christian name?? 1\n", + "How many corridors are under construction?? 1\n", + "Name: question, Length: 3219, dtype: int64" + ] + }, + "execution_count": 197, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "train_df.question.value_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": 198, "id": "ea220f3d", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "1305297 8677\n", + "332667 4300\n", + "66304621 3720\n", + "17888363 3569\n", + "3259011 1581\n", + " ... \n", + "67959451 15\n", + "49474213 12\n", + "66135952 12\n", + "66074428 8\n", + "40713040 2\n", + "Name: doc_id, Length: 118, dtype: int64" + ] + }, + "execution_count": 198, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "df.doc_id.value_counts()" + "train_df.doc_id.value_counts()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 199, "id": "86c3ebf2", "metadata": {}, "outputs": [], "source": [ - "weights = df.doc_id.value_counts().to_dict()" + "weights = train_df.doc_id.value_counts().to_dict()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 200, "id": "af72ae1a", "metadata": {}, "outputs": [], @@ -1242,20 +1918,159 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 201, "id": "500bd6ec", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{1305297: 867,\n", + " 332667: 430,\n", + " 66304621: 372,\n", + " 17888363: 356,\n", + " 3259011: 158,\n", + " 58112801: 125,\n", + " 68507348: 120,\n", + " 62808792: 109,\n", + " 66052432: 98,\n", + " 62372638: 87,\n", + " 67089631: 86,\n", + " 67569553: 82,\n", + " 60476189: 82,\n", + " 68553225: 80,\n", + " 1425939: 77,\n", + " 66187257: 68,\n", + " 65521767: 58,\n", + " 67946554: 55,\n", + " 68498551: 45,\n", + " 442785: 44,\n", + " 734845: 40,\n", + " 487602: 38,\n", + " 66883576: 37,\n", + " 68294454: 36,\n", + " 61250187: 36,\n", + " 50170924: 36,\n", + " 61236755: 34,\n", + " 12936708: 30,\n", + " 1027173: 30,\n", + " 46754025: 27,\n", + " 58542318: 25,\n", + " 61258486: 24,\n", + " 66753136: 24,\n", + " 5575754: 24,\n", + " 65871303: 23,\n", + " 12202928: 22,\n", + " 60600284: 22,\n", + " 51150040: 22,\n", + " 34075129: 22,\n", + " 58385279: 21,\n", + " 61049392: 21,\n", + " 60203476: 21,\n", + " 66341639: 21,\n", + " 63129286: 21,\n", + " 26833: 21,\n", + " 24689651: 20,\n", + " 66629866: 20,\n", + " 33385984: 20,\n", + " 58113491: 20,\n", + " 63170193: 20,\n", + " 63395714: 19,\n", + " 55055575: 19,\n", + " 67918135: 19,\n", + " 68284887: 18,\n", + " 65984422: 18,\n", + " 66040815: 18,\n", + " 57798785: 16,\n", + " 67131229: 16,\n", + " 53943680: 16,\n", + " 20304678: 16,\n", + " 64783122: 16,\n", + " 51345275: 15,\n", + " 39734558: 15,\n", + " 65666080: 14,\n", + " 31243078: 14,\n", + " 36567599: 14,\n", + " 67742925: 14,\n", + " 67674654: 14,\n", + " 6063379: 14,\n", + " 66293350: 13,\n", + " 912080: 13,\n", + " 2514174: 13,\n", + " 67843993: 13,\n", + " 26000816: 12,\n", + " 67037597: 12,\n", + " 67903070: 11,\n", + " 65760352: 11,\n", + " 67711917: 11,\n", + " 404323: 11,\n", + " 68107833: 11,\n", + " 57817558: 10,\n", + " 49632909: 10,\n", + " 65770543: 10,\n", + " 67928132: 10,\n", + " 68207325: 10,\n", + " 25743896: 10,\n", + " 68475822: 10,\n", + " 21537193: 9,\n", + " 67334964: 9,\n", + " 68187748: 9,\n", + " 66461741: 9,\n", + " 56185392: 9,\n", + " 68315181: 8,\n", + " 61293820: 7,\n", + " 2656208: 7,\n", + " 60070859: 7,\n", + " 68076456: 7,\n", + " 65708437: 6,\n", + " 68420852: 6,\n", + " 61243245: 6,\n", + " 68463873: 4,\n", + " 60043578: 4,\n", + " 49588: 3,\n", + " 68229696: 3,\n", + " 737: 3,\n", + " 18097883: 3,\n", + " 66459202: 3,\n", + " 66128424: 3,\n", + " 58542328: 3,\n", + " 66916437: 3,\n", + " 67688633: 2,\n", + " 63417935: 2,\n", + " 20306953: 2,\n", + " 67959451: 1,\n", + " 49474213: 1,\n", + " 66135952: 1,\n", + " 66074428: 1,\n", + " 40713040: 1}" + ] + }, + "execution_count": 201, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "weights" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 202, "id": "db8ae3c9", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "1834" + ] + }, + "execution_count": 202, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "open(\"/home/eecs/wooders/experiments/wikipedia/weights.json\", \"w\").write(json.dumps(weights))" ] diff --git a/wikipedia/preprocessing/log_data.py b/wikipedia/preprocessing/log_data.py index 2e8cca4..23522a0 100644 --- a/wikipedia/preprocessing/log_data.py +++ b/wikipedia/preprocessing/log_data.py @@ -53,6 +53,9 @@ def log_experiment(run, config): for filename in files: if "plan-" in filename and '.json' in filename: artifact.add_file(os.path.join(config["directory"]["dpr_dir"], filename)) + if "plan-" in filename and '.pkl' in filename: + artifact.add_file(os.path.join(config["directory"]["dpr_dir"], filename)) + run.log_artifact(artifact) if __name__ == "__main__": diff --git a/wikipedia/preprocessing/wiki_api_data.py b/wikipedia/preprocessing/wiki_api_data.py index fc4b01d..06b9b7b 100644 --- a/wikipedia/preprocessing/wiki_api_data.py +++ b/wikipedia/preprocessing/wiki_api_data.py @@ -424,6 +424,8 @@ def generate_simulation_data( row["old_revid"] ), f"Invalid id {filename}, id {data['orig_id']} row {row['revid']}" + # get length of passage + if key not in init_data: diffs = data["diffs"][0] init_data[key] = { diff --git a/wikipedia/run_1_generate_plan.sh b/wikipedia/run_1_generate_plan.sh index a0689fe..36ac40b 100644 --- a/wikipedia/run_1_generate_plan.sh +++ b/wikipedia/run_1_generate_plan.sh @@ -1,12 +1,12 @@ set -xe -for key_policy in "random" "round_robin" +for key_policy in "random" "weighted_random" "round_robin" "weighted_round_robin" do - for event_policy in "lifo" + for event_policy in "lifo" "fifo" do for load_shedding_policy in "always_process" do - for model_runtime in 0.01 0.05 0.1 1 5 10 + for model_runtime in 0.25 0.005 do python simulate.py --model_runtime $model_runtime --send_rate 100 \ --event_policy $event_policy --key_policy $key_policy --load_shedding_policy $load_shedding_policy diff --git a/wikipedia/run_2_prepare_data.sh b/wikipedia/run_2_prepare_data.sh index ceaf249..e863f05 100644 --- a/wikipedia/run_2_prepare_data.sh +++ b/wikipedia/run_2_prepare_data.sh @@ -2,15 +2,15 @@ set -xe plan_dir=/data/wooders/wiki-plans -for key_policy in "round_robin" "weighted_round_robin" #"random" "weighted_random" +for model_runtime in 0.005 do - for event_policy in "lifo" "fifo" + for event_policy in "lifo" do for load_shedding_policy in "always_process" do - for model_runtime in 0.01 0.05 0.1 1 5 10 + for key_policy in "round_robin" "weighted_round_robin" "random" "weighted_random" do - python wiki_eval.py --offline-plan-path ${plan_dir}/plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100.json --wandb + python wiki_eval_tmp.py --offline-plan-path ${plan_dir}/plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100.json --workers 32 done done done diff --git a/wikipedia/run_3_run_predictions.sh b/wikipedia/run_3_run_predictions.sh index 3f0713b..e0e8f13 100644 --- a/wikipedia/run_3_run_predictions.sh +++ b/wikipedia/run_3_run_predictions.sh @@ -5,21 +5,22 @@ dpr_dir=~/DPR cd $dpr_dir -for key_policy in "weighted_round_robin" #"round_robin" -#for key_policy in "random" "weighted_random" +for event_policy in "lifo" do - for event_policy in "lifo" + for model_runtime in 0.25 0.005 + #for model_runtime in 0.01 0.05 0.1 1.0 10.0 0.25 0.005 do for load_shedding_policy in "always_process" do - for model_runtime in 0.01 0.05 0.1 1 5 + for key_policy in "weighted_round_robin" "round_robin" "random" "weighted_random" do plan_file=plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100 echo $plan_file - CUDA_VISIBLE_DEVICES=3,4,5 bash ${dpr_dir}/evaluate_retrieval_single_doc_stream.sh $plan_file & - pid=$! + CUDA_VISIBLE_DEVICES=0,1,4 bash ${dpr_dir}/evaluate_retrieval_single_doc_stream.sh $plan_file & + + #pid=$! done - wait $pid + #wait $pid done done done diff --git a/wikipedia/run_5_pipeline_predict.sh b/wikipedia/run_5_pipeline_predict.sh index f6aee15..ea36102 100644 --- a/wikipedia/run_5_pipeline_predict.sh +++ b/wikipedia/run_5_pipeline_predict.sh @@ -7,23 +7,23 @@ wiki_dir=/home/eecs/wooders/experiments/wikipedia #for key_policy in "weighted_random" "weighted_round_robin" #for key_policy in "random" "weighted_random" -for key_policy in "round_robin" "weighted_round_robin" +for model_runtime in 0.01 0.05 0.1 1 10 0.25 0.005 do - for event_policy in "lifo" + for event_policy in "lifo" "fifo" do for load_shedding_policy in "always_process" do - for model_runtime in 0.01 0.05 0.1 1 5 + for key_policy in "round_robin" "weighted_round_robin" "random" "weighted_random" do cd $wiki_dir plan_file=plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100 echo $plan_file python wiki_eval.py --offline-plan-path ${plan_dir}/${plan_file}.json cd $dpr_dir - CUDA_VISIBLE_DEVICES=0,1,2,3,4,5 bash ${dpr_dir}/evaluate_retrieval_single_doc_stream.sh $plan_file & + CUDA_VISIBLE_DEVICES=3 bash ${dpr_dir}/evaluate_retrieval_single_doc_stream.sh $plan_file pid=$! done - #wait $pid + wait $pid done done done diff --git a/wikipedia/simulate.py b/wikipedia/simulate.py index 5dba7d1..fd2dc11 100644 --- a/wikipedia/simulate.py +++ b/wikipedia/simulate.py @@ -294,9 +294,10 @@ def __init__( key_selection_policy_cls: Type[CrossKeyLoadBalancer], model_run_time_s: float, keys: List[str], + num_replicas: int = 1, ) -> None: - super().__init__(env, source_queues, key_selection_policy_cls, model_run_time_s) + super().__init__(env, source_queues, key_selection_policy_cls, model_run_time_s, num_replicas) self.keys = keys self.source_queues = source_queues @@ -340,6 +341,14 @@ def run(self, replica_id: int): else: self.ready_time_to_batch[self.env.now] = edits + # TODO: Add variable runtime + + filename = f"{diff_dir}/{edits[0][0]}" + data = json.load(open(filename)) + num_passages = int(len(data["diffs"][0]) / 10) + runtime = self.model_runtime_s * num_passages + #print(runtime, num_passages) + yield self.env.timeout(self.model_runtime_s) @@ -347,6 +356,7 @@ def run(self, replica_id: int): config = configparser.ConfigParser() config.read("config.yml") plan_dir = config["simulation"]["plan_dir"] +diff_dir = config["directory"]["diff_dir"] #init_data_file = config["simulation"]["init_data_file"] #stream_edits_file = config["simulation"]["stream_edits_file"] #stream_questions_file = config["simulation"]["stream_questions_file"] @@ -391,7 +401,8 @@ def run_once( per_key_records_per_second: int, total_runtime_s: float, model_runtime_constant: float, - key_selection_policy: str + key_selection_policy: str, + num_replicas: int, ): env = simpy.Environment() @@ -429,6 +440,7 @@ def run_once( model_run_time_s=model_runtime_constant, key_selection_policy_cls=policies[key_selection_policy], keys=keys, + num_replicas=num_replicas, ) env.run(until=total_runtime_s) @@ -447,9 +459,10 @@ def run_once( parser.add_argument("--event_policy", type=str) parser.add_argument("--key_policy", type=str) parser.add_argument("--load_shedding_policy", type=str) + parser.add_argument("--num_replicas", type=int) args = parser.parse_args() - plan_name = f"{plan_dir}/plan-{args.key_policy}_{args.event_policy}-{args.load_shedding_policy}-{args.model_runtime}-{args.send_rate}" + plan_name = f"{plan_dir}/plan-{args.key_policy}_{args.event_policy}-{args.load_shedding_policy}-{args.model_runtime}-{args.send_rate}_replicas_{args.num_replicas}" out_path = f"{plan_name}.json" print(out_path) run_once( @@ -461,6 +474,7 @@ def run_once( total_runtime_s=args.total_runtime, model_runtime_constant=args.model_runtime, key_selection_policy=args.key_policy, + num_replicas=args.num_replicas, ) log_plans(run, config, plan_dir) diff --git a/wikipedia/wiki_eval.py b/wikipedia/wiki_eval.py index a556403..ddc6604 100644 --- a/wikipedia/wiki_eval.py +++ b/wikipedia/wiki_eval.py @@ -234,7 +234,7 @@ def generate_question_data_all(exp_id, embed_filename): chunk_size = 1000 chunks = [(questions[i:i+chunk_size], embed_filename, directory) for i in range(0, len(questions), chunk_size)] - p = Pool(128) + p = Pool(64) staleness_all = p.starmap(generate_question_data, chunks) p.close() staleness_all = [item for sublist in staleness_all for item in sublist] @@ -315,10 +315,10 @@ def main(): #embed_filename = "embed_versions.pkl" generate_question_data_all(exp_id, embed_filename) - if args.wandb: - import wandb - run = wandb.init(job_type="dataset-creation", project="wiki-workload") - log_plan_data(run, config, exp_id, output_dir) + #if args.wandb: + # import wandb + # run = wandb.init(job_type="dataset-creation", project="wiki-workload") + # log_plan_data(run, config, exp_id, output_dir) if __name__ == "__main__": From b342494a728583a4aa212b7127ca888ed3234a77 Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Thu, 14 Oct 2021 02:54:43 -0700 Subject: [PATCH 16/26] add notbeook --- stl/notebooks/STL Offline Plots.ipynb | 948 ++++++++++++++++++++++ stl/offline/run_6_simulate_baseline.sh | 37 + wikipedia/config.yml | 2 + wikipedia/notebooks/Wikipedia Plots.ipynb | 250 +++++- wikipedia/preprocessing/log_data.py | 2 + wikipedia/run_1_generate_plan.sh | 19 +- wikipedia/run_2_prepare_data.sh | 10 +- wikipedia/simulate.py | 546 ++++++++----- 8 files changed, 1549 insertions(+), 265 deletions(-) create mode 100644 stl/notebooks/STL Offline Plots.ipynb create mode 100644 stl/offline/run_6_simulate_baseline.sh diff --git a/stl/notebooks/STL Offline Plots.ipynb b/stl/notebooks/STL Offline Plots.ipynb new file mode 100644 index 0000000..4b561e5 --- /dev/null +++ b/stl/notebooks/STL Offline Plots.ipynb @@ -0,0 +1,948 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 232, + "id": "642f67ca", + "metadata": {}, + "outputs": [], + "source": [ + "import wandb\n", + "import os\n", + "import pandas as pd\n", + "import sys\n", + "import json\n", + "\n", + "import seaborn as sns\n", + "import numpy as np\n", + "sns.set(style=\"whitegrid\", palette=\"muted\")\n", + "\n", + "sys.path.insert(1, \"/home/eecs/wooders/experiments/stl/offline\")" + ] + }, + { + "cell_type": "code", + "execution_count": 252, + "id": "0df714c8", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "Finishing last run (ID:2od4u8d0) before initializing another..." + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Waiting for W&B process to finish, PID 80915... (success)." + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "VBox(children=(Label(value=' 0.26MB of 0.26MB uploaded (0.00MB deduped)\\r'), FloatProgress(value=1.0, max=1.0)…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "
\n", + "
\n", + "
\n", + "Synced 7 W&B file(s), 0 media file(s), 0 artifact file(s) and 1 other file(s)\n", + "
Synced restful-butterfly-20: https://wandb.ai/ucb-ralf/experiments-stl_notebooks/runs/2od4u8d0
\n", + "Find logs at: ./wandb/run-20211014_021333-2od4u8d0/logs
\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Successfully finished last run (ID:2od4u8d0). Initializing new run:
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[34m\u001b[1mwandb\u001b[0m: wandb version 0.12.4 is available! To upgrade, please run:\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: $ pip install wandb --upgrade\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " Syncing run avid-flower-21 to Weights & Biases (docs).
\n", + "\n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[34m\u001b[1mwandb\u001b[0m: Downloading large artifact results:v11, 1446.02MB. 6579 files... Done. 0:0:0\n" + ] + } + ], + "source": [ + "run = wandb.init()\n", + "results_dir = run.use_artifact('ucb-ralf/stl/results:v11', type='dataset').download()\n", + "yahoo_train_dir = run.use_artifact('ucb-ralf/stl/yahoo_train_data:v0', type='dataset').download()\n", + "yahoo_eval_dir = run.use_artifact('ucb-ralf/stl/yahoo_eval_data:v0', type='dataset').download()\n", + "oracle_dir = run.use_artifact('ucb-ralf/stl/oracle:v0', type='dataset').download()" + ] + }, + { + "cell_type": "markdown", + "id": "b5a8aea6", + "metadata": {}, + "source": [ + "# Check Train / Eval Data" + ] + }, + { + "cell_type": "code", + "execution_count": 253, + "id": "0eedb687", + "metadata": {}, + "outputs": [], + "source": [ + "key = 3" + ] + }, + { + "cell_type": "code", + "execution_count": 254, + "id": "975d3b68", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 254, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "df_train = pd.read_csv(f\"{yahoo_train_dir}/{key}.csv\")\n", + "plt.plot(np.arange(len(df_train)), df_train[\"value\"])" + ] + }, + { + "cell_type": "code", + "execution_count": 256, + "id": "c37f7834", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 256, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "df_eval = pd.read_csv(f\"{yahoo_eval_dir}/{key}.csv\")\n", + "plt.plot(np.arange(len(df_eval)), df_eval[\"value\"])" + ] + }, + { + "cell_type": "code", + "execution_count": 257, + "id": "b3c30d2e", + "metadata": {}, + "outputs": [], + "source": [ + "df_all = pd.concat([df_train[\"value\"], df_eval[\"value\"]], axis = 0)" + ] + }, + { + "cell_type": "code", + "execution_count": 258, + "id": "93a15c67", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 258, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(np.arange(len(df_train) + len(df_eval)), df_all)" + ] + }, + { + "cell_type": "markdown", + "id": "9fef8177", + "metadata": {}, + "source": [ + "# Cost Evaluation " + ] + }, + { + "cell_type": "code", + "execution_count": 259, + "id": "5fecde25", + "metadata": {}, + "outputs": [], + "source": [ + "from sktime.performance_metrics.forecasting import mean_squared_scaled_error\n", + "def get_loss_per_key(key: int, path, oracle_filename):\n", + "\n", + " oracle_residual = pd.read_csv(oracle_filename)[\n", + " \"pred_residual\"\n", + " ]\n", + "\n", + " df = pd.read_csv(path)\n", + " residual = df[\"pred_residual\"]\n", + " mask = ~np.isnan(residual)\n", + " loss = mean_squared_scaled_error(\n", + " y_true=oracle_residual[mask], y_pred=residual[mask], y_train=df[\"value\"]\n", + " )\n", + " loss = {\n", + " \"loss\": loss,\n", + " \"n_fits\": df[\"model_version\"].dropna().nunique(),\n", + " }\n", + " return loss" + ] + }, + { + "cell_type": "code", + "execution_count": 125, + "id": "21099224", + "metadata": {}, + "outputs": [], + "source": [ + "replica = 1\n", + "baseline_results = {}\n", + "for key in range(1, 101, 1):\n", + " losses = get_loss_per_key(key, f\"{artifact_dir}/plan_eval\")\n", + " baseline_results[key] = losses" + ] + }, + { + "cell_type": "code", + "execution_count": 139, + "id": "d82f9ca7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8400 78.42078584418643\n" + ] + } + ], + "source": [ + "slide_size = 12\n", + "baseline_total_cost = 0\n", + "baseline_total_loss = 0\n", + "for key in baseline_results.keys(): \n", + " for loss in baseline_results[key]:\n", + " if loss['slide_size'] == slide_size:\n", + " baseline_total_cost += loss['n_fits']\n", + " baseline_total_loss += loss['loss']\n", + "print(baseline_total_cost, baseline_total_loss)" + ] + }, + { + "cell_type": "code", + "execution_count": 135, + "id": "da85dcf1", + "metadata": {}, + "outputs": [], + "source": [ + "lp_results = {}\n", + "\n", + "for key in range(1, 101, 1):\n", + " oracle_filename = f\"{artifact_dir}/plan_eval/oracle_key_A4Benchmark-TS{key}.csv\"\n", + " filename = f\"{artifact_dir}/lp_plan_eval/{plan}/{key}.csv\"\n", + " lp_results[key] = get_loss_per_key(key, filename, oracle_filename)" + ] + }, + { + "cell_type": "code", + "execution_count": 136, + "id": "303fcfcf", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1100 95.26955983050661\n" + ] + } + ], + "source": [ + "lp_total_cost = 0\n", + "lp_total_loss = 0\n", + "for key in lp_results.keys(): \n", + " lp_total_cost += lp_results[key]['n_fits']\n", + " lp_total_loss += lp_results[key]['loss']\n", + "print(lp_total_cost, lp_total_loss)" + ] + }, + { + "cell_type": "code", + "execution_count": 260, + "id": "656758ed", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "max_fits_1100\n" + ] + }, + { + "ename": "TypeError", + "evalue": "string indices must be integers", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mkey\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mbaseline_results\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkeys\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mloss\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mbaseline_results\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 12\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0mloss\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'slide_size'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mslide_size\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 13\u001b[0m \u001b[0mbaseline_total_cost\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mloss\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'n_fits'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 14\u001b[0m \u001b[0mbaseline_total_loss\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mloss\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'loss'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mTypeError\u001b[0m: string indices must be integers" + ] + } + ], + "source": [ + "experiments = [(\"max_fits_1100\", 96), (\"max_fits_2100\", 48), (\"max_fits_4200\", 24), (\"max_fits_8400\", 12)]\n", + "\n", + "graph_results = {\"baseline\": [], \"optimized\": [], \"cost\": []}\n", + "\n", + "replica = 1\n", + "for plan, slide_size in experiments:\n", + " print(plan)\n", + " \n", + " baseline_total_cost = 0\n", + " baseline_total_loss = 0\n", + " for key in baseline_results.keys(): \n", + " for loss in baseline_results[key]:\n", + " if loss['slide_size'] == slide_size:\n", + " baseline_total_cost += loss['n_fits']\n", + " baseline_total_loss += loss['loss']\n", + " print(baseline_total_cost, baseline_total_loss)\n", + " \n", + " for key in range(1, 101, 1):\n", + " oracle_filename = f\"{artifact_dir}/plan_eval/oracle_key_A4Benchmark-TS{key}.csv\"\n", + " filename = f\"{artifact_dir}/lp_plan_eval/{plan}/{key}.csv\"\n", + " lp_results[key] = get_loss_per_key(key, filename, oracle_filename)\n", + " \n", + " lp_total_cost = 0\n", + " lp_total_loss = 0\n", + " for key in lp_results.keys(): \n", + " lp_total_cost += lp_results[key]['n_fits']\n", + " lp_total_loss += lp_results[key]['loss']\n", + " print(lp_total_cost, lp_total_loss)\n", + " \n", + " assert lp_total_cost <= baseline_total_cost\n", + " \n", + " graph_results[\"baseline\"].append(baseline_total_loss)\n", + " graph_results[\"optimized\"].append(lp_total_loss)\n", + " graph_results[\"cost\"].append(baseline_total_cost)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 163, + "id": "959d7dc6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Text(0.5, 0, 'Cost Budget'),\n", + " Text(0, 0.5, 'MASE Loss'),\n", + " Text(0.5, 1.0, 'Residual Estimate Loss for Time-Series Decomposition')]" + ] + }, + "execution_count": 163, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[34m\u001b[1mwandb\u001b[0m: Network error resolved after 0:00:38.544998, resuming normal operation.\n" + ] + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import seaborn\n", + "\n", + "x = 'Factor'\n", + "\n", + "df = pd.DataFrame({\n", + " x: graph_results[\"cost\"], \n", + " 'baseline': graph_results[\"baseline\"], \n", + " \"optimized\": graph_results[\"optimized\"],\n", + "})\n", + "fig, ax1 = plt.subplots(figsize=(10, 5))\n", + "tidy = df.melt(id_vars=x).rename(columns=str.title)\n", + "seaborn.barplot(x=x, y='Value', hue='Variable', data=tidy, ax=ax1)\n", + "seaborn.despine(fig)\n", + "\n", + "ax1.set(xlabel=\"Cost Budget\", ylabel=f'MASE Loss', title='Residual Estimate Loss for Time-Series Decomposition')\n", + "#ax1.legend_.remove()\n", + "#plt.legend(loc='lower center')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cb5185be", + "metadata": {}, + "outputs": [], + "source": [ + "baseline_results[2]" + ] + }, + { + "cell_type": "code", + "execution_count": 144, + "id": "526e9b31", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'baseline': [113.47347746568275,\n", + " 89.57722060605525,\n", + " 81.12720697469311,\n", + " 78.42078584418643],\n", + " 'optimized': [95.26955983050661,\n", + " 81.53832641325205,\n", + " 76.2934822322845,\n", + " 74.68576266515468],\n", + " 'cost': [1100, 2099, 4197, 8375]}" + ] + }, + "execution_count": 144, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "{**graph_results}" + ] + }, + { + "cell_type": "markdown", + "id": "a1e429ec", + "metadata": {}, + "source": [ + "# Plot different numbers of replicas" + ] + }, + { + "cell_type": "code", + "execution_count": 269, + "id": "38d0548e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "plan_baseline_1_lifo 172.98378216386888\n", + "plan_baseline_1_lifo 112.67935494700063\n", + "plan_baseline_6_lifo 180.18115087379635\n", + "plan_baseline_6_lifo 115.77955410145175\n", + "plan_baseline_12_lifo 184.2670899767375\n", + "plan_baseline_12_lifo 120.07497015444703\n", + "plan_baseline_18_lifo 190.24309735984917\n", + "plan_baseline_18_lifo 122.9708625384093\n", + "plan_baseline_24_lifo 196.18648185699215\n", + "plan_baseline_24_lifo 128.18398403462876\n", + "plan_baseline_48_lifo 225.58043199493562\n", + "plan_baseline_48_lifo 144.9251630795228\n", + "plan_baseline_96_lifo 320.8503011206009\n", + "plan_baseline_96_lifo 189.32209967308512\n", + "plan_baseline_168_lifo 431.41793348258363\n", + "plan_baseline_168_lifo 293.96569319942313\n", + "plan_baseline_192_lifo 544.0725854282231\n", + "plan_baseline_192_lifo 339.90741345037276\n", + "plan_baseline_336_lifo 949.2024557323098\n", + "plan_baseline_336_lifo 705.3804094682863\n", + "plan_baseline_672_lifo 1917.3666698011584\n", + "plan_baseline_672_lifo 1555.133039236265\n" + ] + }, + { + "data": { + "text/plain": [ + "{1: [172.98378216386888, 112.67935494700063],\n", + " 6: [180.18115087379635, 115.77955410145175],\n", + " 12: [184.2670899767375, 120.07497015444703],\n", + " 18: [190.24309735984917, 122.9708625384093],\n", + " 24: [196.18648185699215, 128.18398403462876],\n", + " 48: [225.58043199493562, 144.9251630795228],\n", + " 96: [320.8503011206009, 189.32209967308512],\n", + " 168: [431.41793348258363, 293.96569319942313],\n", + " 192: [544.0725854282231, 339.90741345037276],\n", + " 336: [949.2024557323098, 705.3804094682863],\n", + " 672: [1917.3666698011584, 1555.133039236265]}" + ] + }, + "execution_count": 269, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "experiments = [(\"max_fits_1100\", 96), (\"max_fits_2100\", 48), (\"max_fits_4200\", 24), (\"max_fits_8400\", 12)]\n", + "replicas = [1, 2]\n", + "slides = [1, 6, 12, 18, 24, 48, 96, 168, 192, 336, 672]\n", + "graph_results = {\"baseline\": [], \"optimized\": [], \"cost\": []}\n", + "prio = \"lifo\"\n", + "replica_results = {}\n", + "\n", + "for slide in slides: \n", + " replica_results[slide] = []\n", + " for replica in replicas: \n", + " baseline_plan = f\"plan_baseline_{slide}_{prio}\"\n", + " \n", + " total_loss = 0\n", + " for key in range(1, 101, 1):\n", + " oracle_filename = f\"{oracle_dir}/{key}.csv\"\n", + " \n", + " lp_filename = f\"{results_dir}/replica_{replica}/{baseline_plan}/{key}.csv\"\n", + " \n", + " baseline_filename = f\"{results_dir}/replica_{replica}/{baseline_plan}/{key}.csv\"\n", + " results = get_loss_per_key(key, baseline_filename, oracle_filename)\n", + " #print(results)\n", + " total_loss += results[\"loss\"]\n", + " \n", + " replica_results[slide].append(total_loss)\n", + " print(baseline_plan, total_loss)\n", + " \n", + "replica_results" + ] + }, + { + "cell_type": "code", + "execution_count": 206, + "id": "2b9c7c38", + "metadata": {}, + "outputs": [], + "source": [ + "del replica_results[1]" + ] + }, + { + "cell_type": "code", + "execution_count": 270, + "id": "8678b39b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Text(0.5, 0, 'Num Replicas'),\n", + " Text(0, 0.5, 'MASE Loss'),\n", + " Text(0.5, 1.0, 'Residual Estimate Loss for Time-Series Decomposition')]" + ] + }, + "execution_count": 270, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAnIAAAFSCAYAAAB2ajI+AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAABKUElEQVR4nO3de1wU9f4/8Neyy6KgiGAQCl7yKIfkqMgtL2SBZRqCaYURWpZd1NRUVFIUBdFWPYEXCDuHPKfi2NHkImhh5qUyw0t6jLA0QkRBkIuKoCy7O78//Dq/UC4L7rK78Ho+Hj4ezWdm3vOeWVjefT4zn5EIgiCAiIiIiEyOmaETICIiIqLWYSFHREREZKJYyBERERGZKBZyRERERCaKhRwRERGRiWIhR0RERGSiWMgRNWL37t147bXXGl0/depU7Ny584GPk52djccff/yB4zSnufPpiARBwHvvvQcvLy88//zzej1WUVER3N3doVar9XocfeDPju65u7ujsLCw0fXPPvsssrOz2zAjMlUSziNH7YGfnx/KysoglUphaWkJX19fLF++HFZWVno75tSpUxEYGIgXXnjhgeJkZ2dj0aJF+Pbbbxtc7+Ligs6dO0MikYhts2bNwhtvvNFozEuXLsHf3x+//PILZDLZA+WnjQe9Frq6li114sQJLFiwAF999RUsLS0fONbdz0QQBNy6datezD179qBnz54PdIyWSExMxI4dO1BZWYmuXbti2LBhiIuLa7PjNyclJQXLli1Dp06dAADdu3eHj48P3nzzTfTr18/A2bWt8PBwODg4YP78+YZOhUyQ/r/hidpIYmIiRowYgatXr+L111/HRx991G6+GNPT09GnTx9Dp9HuXL58Gb169WpVEadSqeoVyZ6enjh16hSA/19IHz9+vE0K6XulpqYiPT0d//rXv9C7d29cvXoVBw4caFWse89Tl4YOHYrt27dDrVbj8uXL+PjjjzFp0iT897//xcCBA/VyTKL2hkOr1O489NBDGDVqFM6ePSu2nT59GlOmTIGnpycCAwPrDVmkpKTA398f7u7u8PPzw+7du8X2l156SdzuyJEjeOaZZ+Dh4YGoqCj8uTN78+bNCAsLE5cvXboEFxcXqFQqAMCuXbswbtw4uLu7w9/fH59//rlOzvXMmTOYNGkShg0bhhEjRmDt2rUAgNDQUACAl5cX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//43VCoVDhw4ABcXF+zbtw99+vTBoUOHEBcXh4sXL6Jr1654/vnnMWfOnHrH37VrFzZv3gwAeO211/Daa681mOfp06fx/vvv4/fff0fPnj2xbNky+Pj46PHKEOmeRGaGkrhjOovn8K63zmIRERkb9shpoVOnThg3bhzS0tLEti+//BKPPPIILC0t8d577+HHH3/E559/jqNHj+I///lPvf3379+PHTt2YO/evffF7ty5MxQKBU6cOIGtW7di+/bt2L9/f71tsrOzsW/fPiQlJeGjjz7CDz/8cF+ckpISvPXWW5g5cyaOHTuGJUuWYO7cuaioqNDNRSAiIiKjw0JOSxMnTsRXX30lzruWlpaG5557Dm5ubhg6dChkMhmcnJwQHByM48eP19v3zTffhI2NjfhWiz/z8fGBi4sLzMzM8Ne//hXPPvssjh2r3xsxe/ZsWFpawsXFBZMmTRJfTfZn6enpePzxxzF69GiYmZlh5MiRcHNzw+HDh3V4FYiIiMiYcGhVS56enrC1tcU333yDwYMHIycnB1u2bEF+fj7ef/995OTk4NatW1Cr1Rg0aFC9fR0dHRuN+7///Q8bNmzA+fPnUVdXB6VSiWeeeabR/Xv16oVz587dF6eoqAhfffUVDh48KLapVCoOrRIREbVjLORaICgoCGlpacjPz8fIkSPRo0cPLFy4EI8++ij+/ve/o0uXLvjXv/6FrKysevs1NfHuwoULERoain/+85+wsLBATEwMKisr621TXFyM/v37A7hTsNnb298Xx9HREUFBQVi9erUOzpSIiIhMAYdWW2DixIk4evQoduzYgYkTJwIAqqurYWVlBSsrK+Tl5WH79u0tilldXY1u3brBwsICZ86caXDYNCEhAbdu3cL58+eRkpKC8ePH37dNYGAgDh48iO+++w5qtRq1tbXIzs7GlStXWnWuREREZPxYyLWAk5MT3N3dcevWLfj7+wMAlixZgszMTAwbNgzLly9vsMhqSmRkJDZt2gR3d3fEx8dj3Lhx923j7e2Np556Cq+++ipee+01jBo16r5tHB0dkZCQgK1bt2L48OEYPXo0kpKSoNFw6gUiIqL2SiLcOzlaB1BbW4ucnBy4ubnBwsJCbD979ixcXV0NmFnb64jnTMaP048QEWmHPXJEREREJoqFHBEREZGJYiFHREREZKJYyBERERGZKBZy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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import seaborn\n", + "\n", + "x = 'Factor'\n", + "\n", + "df = pd.DataFrame({\n", + " x: replicas, \n", + " **replica_results,\n", + "})\n", + "fig, ax1 = plt.subplots(figsize=(10, 5))\n", + "tidy = df.melt(id_vars=x).rename(columns=str.title)\n", + "seaborn.barplot(x=x, y='Value', hue='Variable', data=tidy, ax=ax1)\n", + "seaborn.despine(fig)\n", + "\n", + "ax1.set(xlabel=\"Num Replicas\", ylabel=f'MASE Loss', title='Residual Estimate Loss for Time-Series Decomposition')" + ] + }, + { + "cell_type": "code", + "execution_count": 272, + "id": "dd593565", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "max_fits_1100 1893.9663657607266\n", + "max_fits_1100 133.45026146609104\n", + "max_fits_1100 117.59550187337948\n", + "max_fits_2100 2875.0872626231935\n", + "max_fits_2100 1447.6250864288265\n", + "max_fits_2100 99.89538248542472\n", + "max_fits_4200 3430.718917641645\n", + "max_fits_4200 2591.967671743391\n", + "max_fits_4200 95.01342291496671\n", + "max_fits_8400 3586.4346343021443\n", + "max_fits_8400 3006.052341175111\n", + "max_fits_8400 93.57666588051953\n" + ] + }, + { + "data": { + "text/plain": [ + "{'max_fits_1100': [1893.9663657607266, 133.45026146609104, 117.59550187337948],\n", + " 'max_fits_2100': [2875.0872626231935, 1447.6250864288265, 99.89538248542472],\n", + " 'max_fits_4200': [3430.718917641645, 2591.967671743391, 95.01342291496671],\n", + " 'max_fits_8400': [3586.4346343021443, 3006.052341175111, 93.57666588051953]}" + ] + }, + "execution_count": 272, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "experiments = [(\"max_fits_1100\", 96), (\"max_fits_2100\", 48), (\"max_fits_4200\", 24), (\"max_fits_8400\", 12)]\n", + "replicas = [1, 2, 4]\n", + "slides = [1, 6, 12, 18, 24, 48, 96, 168, 192, 336, 672]\n", + "graph_results = {\"baseline\": [], \"optimized\": [], \"cost\": []}\n", + "\n", + "replica_results = {}\n", + "\n", + "\n", + " \n", + "for plan, slide in experiments: \n", + " replica_results[plan] = []\n", + " \n", + " for replica in replicas:\n", + " total_loss = 0\n", + " for key in range(1, 101, 1):\n", + " oracle_filename = f\"{oracle_dir}/{key}.csv\"\n", + " lp_filename = f\"{results_dir}/replica_{replica}/{plan}/{key}.csv\"\n", + " results = get_loss_per_key(key, lp_filename, oracle_filename)\n", + " total_loss += results[\"loss\"]\n", + " \n", + " replica_results[plan].append(total_loss)\n", + " print(plan, total_loss)\n", + " \n", + "replica_results" + ] + }, + { + "cell_type": "code", + "execution_count": 245, + "id": "fa644e00", + "metadata": {}, + "outputs": [], + "source": [ + "static_results = {1: [213.2200178532724, 150.7256273025718, 133.3349003094353],\n", + " 6: [218.75801939773078, 156.0948132080653, 135.81574629721845],\n", + " 12: [220.90611494937247, 159.05690147515068, 138.24448802117672],\n", + " 18: [229.63341620779627, 163.1813146667572, 140.3471142793597],\n", + " 24: [233.91725185369373, 164.71255155633278, 144.22561887879107],\n", + " 48: [268.3977607679711, 184.14616983478135, 158.3310894771346],\n", + " 96: [348.50466291276604, 229.46322062727472, 189.37872271737845],\n", + " 168: [474.50432909190295, 319.6199513026192, 281.5650612571233],\n", + " 192: [609.2301332698065, 399.7143084337964, 333.28670707646245],\n", + " 336: [908.5841349053487, 728.1723528503993, 650.7431132687982],\n", + " 672: [1848.5207568587812, 1612.2188363608043, 1489.8733845259228]}" + ] + }, + { + "cell_type": "code", + "execution_count": 246, + "id": "2a2bdeb1", + "metadata": {}, + "outputs": [], + "source": [ + "policy_results = {'max_fits_1100': [1893.9663657607266, 133.45026146609104, 117.59550187337948],\n", + " 'max_fits_2100': [2875.0872626231935, 1447.6250864288265, 99.89538248542472],\n", + " 'max_fits_4200': [3430.718917641645, 2591.967671743391, 95.01342291496671],\n", + " 'max_fits_8400': [3586.4346343021443, 3006.052341175111, 93.57666588051953]}" + ] + }, + { + "cell_type": "code", + "execution_count": 273, + "id": "239a5274", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'baseline': [213.2200178532724, 150.7256273025718],\n", + " 'policy': [1893.9663657607266, 133.45026146609104]}" + ] + }, + "execution_count": 273, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "replicas = [1, 2]\n", + "results = {\"baseline\": [], \"policy\": []}\n", + "for i in range(len(replicas)): \n", + " \n", + " best_baseline = None\n", + " for key in static_results.keys(): \n", + " if best_baseline is None or static_results[key][i] <= best_baseline: \n", + " best_baseline = static_results[key][i]\n", + " results[\"baseline\"].append(best_baseline)\n", + " \n", + " best_baseline = None\n", + " for key in policy_results.keys(): \n", + " if best_baseline is None or policy_results[key][i] <= best_baseline: \n", + " best_baseline = policy_results[key][i]\n", + " results[\"policy\"].append(best_baseline)\n", + " \n", + "results" + ] + }, + { + "cell_type": "code", + "execution_count": 274, + "id": "ee33ec46", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Text(0.5, 0, 'Num Replicas'),\n", + " Text(0, 0.5, 'MASE Loss'),\n", + " Text(0.5, 1.0, 'Residual Estimate Loss for Time-Series Decomposition')]" + ] + }, + "execution_count": 274, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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6KOP8sMPP7Bjxw5iY2P55ptv+O6777DZbJSUlLB+/Xp+//13jhw5wtdff01xcTEWi4XmzZufs4epW7du7Nq1i5UrV1JWVsbHH39cIawFBgayceNGDh06RFFREe+++669zWq1YrVa8fb2xsXFhTVr1rB27do6Oc7U1FTy8/Np0qSJ/cvM2dkZb29vmjRpUuVzqmrixIkTuLm54enpSWFhYYWL0eF078Yf93X77bezZ88eli5dSmlpKaWlpWzbto2srKxK91FWVkZJSYn9X2lpKTExMXz00Ufs37+fEydOMHXqVHr06IGLiwvr1q3jv//9LzabDQ8PD1xcXHB2dq72a3ou9913H4sXL2bHjh1YrVbefPNNOnbsaO/FcZSans/FixezevVqjh8/Tnl5OWvWrOG3336jY8eO+Pr60qVLF15//XV7+759+9iwYcMF12K1Wlm2bBlFRUW4urri7u5erXNvs9nYv38/EydOZMOGDQwdOhSgys+ur68vt912G6+88gpHjx6ltLTUPtxfH6/jjBkzsFqtbNq0idWrV3PPPffg7OzMPffcw9SpUzl+/DgHDx5k7ty59t7Jzz//3P5/AFu0aIGTkxNNmpz9tevj41Nh2PfP7r33Xt555x3y8/PJz89n5syZ3HfffbU+FmlcFOSkUfL29qZXr172HrlZs2bx7rvv0rlzZ7p168acOXMoLy+nvLycuXPnEhkZSXh4OBs3biQxMfGc23vrrbf4+9//TkREBHv37qVTp0729i5dutCzZ09iY2Pp3bt3heFNDw8Pxo4dy3PPPUdYWBjp6elERUXV6Hh69epFcHCw/V9ycjIA3333Hffee6993tSpU3Fzc6NZs2Y888wzPPzww4SGhrJ169bancj/59FHH6WkpIRbbrmFfv36ERkZWaH9kUceISMjg7CwMCZNmoSHhwdz5sxhxYoVREZG0rVrV6ZMmWK/0+5cJkyYQMeOHe3/XnzxRfr06UNsbCwDBgwgOjoai8XCuHHjgNO9niNGjCAkJISePXsSHh5ObGxstV/Tc+ncuTN/+9vfGD58OF27dmX//v1MnTq19ieujtT0fHp4eDB79mzuuOMOQkNDmTJlChMmTLD3dL3xxhuUlpbSs2dPwsLCGDFiBIcPH66TWlJTU4mKiqJTp058+umnvPHGG5Vu68wdwyEhITzyyCMcP36czz77jICAAIAqP7tnjsPFxYUePXpw66238tFHHwF1/zpeccUVeHp6EhkZSXx8PBMmTLAP1Y8bN45mzZpx5513EhcXR0xMDH369AFO3z384IMPEhwczJAhQ3j55Zdp3br1Wdvv27cvv/32G6GhoRXuvD3j2WefJSgoyD5c3qFDh3MuJ5cmPRBYRESkEud7YLeIo6lHTkRERMSkFORERERETEpDqyIiIiImpR45EREREZO6JIOcYRiUlJTUyXO8RERERBzlkgxyVquVzMzMKh+FICIiInKxuySDnIiIiEhjoCAnIiIiYlIKciIiIiImpSAnIiIiYlIuji5AREREzKe0tJQDBw5w6tQpR5fSaDRt2pRWrVrh6upa7XUU5ERERKTGDhw4wGWXXUbbtm1xcnJydDmmZxgGeXl5HDhwgGuuuaba62loVURERGrs1KlT+Pj4KMTVEScnJ3x8fGrcw6kgJyIiIrWiEFe3anM+FeRERERETEpBTkRERBqV4OBg9u/ff97lDhw4QEBAAGVlZedsnzFjBvHx8XVdXp1SkBMRERGHevzxx3nrrbfOmv/VV1/RpUuXSoNWZX766Sdat25dV+Vd1BTkRM6jvEy/yWtmev1ELn4PPPAAqampGIZRYf6yZcu47777cHGp3kM2ahr4GgM9fkTkPJq4WNg5ZZCjy5Baah//oaNLEJHzuPPOO0lMTGTTpk2EhYUBcPToUb755hvmzJlDv379yMrKomnTptx9990kJCRgsVgACAgIYPz48Xz00UeUlZWxatUqAgICWLlyJVdffTWrV69m2rRp7Nu3j8suu4y+ffsyfPjwCvtftGgRM2bMAOCxxx7jscceO2edW7du5fXXX+e3337jqquu4uWXXyYiIqIez8z5qUdOREREHKpp06b06NGDpUuX2ud9/vnnXHvttTRv3pwXX3yRdevW8emnn/Ljjz/yySefVFj/q6++YsGCBaxYseKsbTdr1oyUlBQ2bdrEu+++y/z58/nqq68qLLN+/XpWrlzJnDlzeO+99/jhhx/O2k5OTg5PP/00Q4YMYcOGDYwZM4YRI0aQn59fNyehlhTkRERExOHuv/9+vvjiC/tz1JYuXcoDDzxAUFAQN998My4uLrRq1Yp+/fqxcePGCus+9dRTeHl50bRp07O2GxERQUBAAE2aNOGGG27g3nvvZcOGDRWWGTp0KM2b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F8uXLwdOB7mXX365wvJ5eXkMHz4cm81GeXk57dq1IzEx0d4+YcIEEhISmDVrFp6envZuUREREXEca6mtWo8Kqc12La7O513OYrHQv39/CgoKSEpKwsfHh9tuu41ly5bRo0cP/Pz8CAoKsge2zz//nLS0NFxdXXFycuKll14C4KmnnuLtt9+mb9++ODk54eTkxLBhw+zDpjV1//33U1hYaB9aNQyDhx9+mBtuuKFW2/sjJ8MwjAveismUlJSQmZmpa+Sk2nZOGeToEqSW2sd/6OgSRBqlHTt22EfLpO7U9Lw6fGhVRERERGpHQU5ERETEpBTkRERERExKQU5ERETEpBTkRERERExKQU5ERETEpBTkREREpE6Ul1lNtd3169fTu3dv4PQvTQ0cOLBe9lOfHP4TXSIiItI4NHGx1MtzNxvieZB+fn7885//rPf91DX1yImIiIjpBQQEMGPGDPr370/37t3JyMiwt3377bfcf//93HfffTz66KPs3bv3rPUPHDhARESEffqnn37i4YcfJjY2ltjYWL7//ntWrFjB008/bV/GarXStWtXsrOz6/fgqqAeOREREWkUnJyc+PTTT/nf//7Hww8/TGhoKAAvvPAC//rXv7juuutYuHAh8fHxLFy4sNLtFBYWMmzYMGbMmEGnTp2w2WwcP34cd3d3Jk+ezP79+2ndujUrVqzgpptuwt/fv6EO8SzqkRMREZFG4cEHHwTg2muv5cYbb2Tr1q385z//4YYbbuC6664DoE+fPuzYsYPjx49Xup2tW7fSrl07OnXqBICzszMtWrTAxcWFfv368emnnwLwySef8Ne//rWej6pqCnIiIiLS6BiGgZOTk/1/a7puZR566CHS09PZvHkzx44do3Pnzhda6gVRkBMREZFGYdGiRQDs2bOHHTt2cNNNNxEcHMyOHTvIysoCYMmSJdx44414eHhUup3g4GCysrL46aefALDZbBw9ehQAb29vbr31VkaOHElcXFyNQ2Jd0zVyIiIiUifKy6z1codpeZmVJi6W8y5nsVjo378/BQUFJCUl4ePjA8Abb7xBfHw8ZWVleHt7M3ny5Cq34+XlxYwZM3j99dcpLi6mSZMmjBkzhltvvRWAvn378sUXX/DAAw9c+MFdICejqv7DRqqkpITMzEyCgoJwc3NzdDliAvVxO700jIZ4bIHIpWjHjh0E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Um07pwxydAlSS+3jP3R0CSIi9abKHjmbzca6devsPXFlZWUVpsvLy+u/QhERERE5pyqDnI+PDy+99JJ92svLq8K0rksTERERcZwqg9yqVasaqg4RERERqaEa/7LD//73P7788ksOHjxYH/WIiIiISDVVGeRef/11UlNT7dNLly4lJiaGcePG0aNHD9asWVPvBYqIiIjIuVUZ5L766ivCwsLs02+++SYvv/wy69at45VXXmHmzJn1XqCIiIiInFuVQS4/P5+rrroKgJ07d1JYWGj/ZYfY2Fj27NlT7wWKiIiIyLlVGeQuu+wyjhw5AsCmTZsICgrCYrEApx9FUtsHBIuIiIjIhavyrtUePXrw/PPPc9dddzF37lyefPJJe9t//vMfWrduXe8FioiIiMi5VdkjN2rUKCIiIvjhhx946KGHePjhh+1tO3bsoF+/fvVeoIiIiIicW5U9cq6urgwbNuycbY8++ii//fZbvRQlIiIiIudXZZA7l4KCApYvX86SJUv473//S2ZmZn3UJSIiIiLnUa0gV1ZWxurVq1myZAlr1qzBZrPxxBNP8M4779R3fSIiIiJSiSqD3M8//8zSpUtJT08HoHv37sydO5fnnnuOQYMG4ePj0yBFioiIiMjZqgxyDz74IF5eXowdO5YePXrg4nJ6cScnpwYpTkREREQqV+Vdq0OHDuWyyy5j3LhxjB49mlWrVlFWVtZQtYmIiIhIFaoMcsOHD+fLL7/k/fffp3nz5owePZouXbpw9OhRdu7c2VA1ioiIiMg5VBnkzggLCyM5OZm1a9fy8ssvEx4ezuOPP07fvn3ruz4RERERqUSNHj/StGlTYmNjiY2NJScnh9TU1PqqS0RERETOo8ogd+jQoSpXjomJqdNiRERERKT6qgxyUVFR9jtUDcM4q93JyYkdO3bUT2UiIiIiUqUqg1xAQAAlJSU88MADxMbG4uvr21B1iYiIiMh5VBnkUlNT2blzJ0uWLCEuLo5rr72WXr16cffdd9O0adOGqlFEREREzuG8d622b9+eMWPG8PXXXzNo0CBWr15N165d+eWXXxqiPhERERGpRLUePwKwZ88eNm7cyNatWwkMDMTT07M+6xIRERGR86hyaLWwsJDly5ezZMkSTpw4Qa9evfjXv/7FVVddVWcFHDhwgKFDh9qni4qKOH78OBs2bCAqKgqLxYKbmxsA8fHxREZGArB7924SEhIoLCzEy8uLlJQU2rZtW2d1iYiIiFzsqgxykZGRtGrVil69enHTTTcBsHfvXvbu3WtfpnPnzhdUQKtWrSo8jy45ORmbzWafnj59Ou3btz9rvcTEROLi4ujVqxepqamMHz+ejz/++IJqERERETGTKoPclVdeSUlJCQsWLGDBggVntTs5OfH111/XWTFWq5W0tDTmzJlT5XJ5eXls376duXPnAqefZzdx4kTy8/Px9vaus3pERERELmZVBrlVq1Y1VB32/fn5+dGhQwf7vPj4eAzDICQkhJEjR+Lp6Ul2djZ+fn44OzsD4OzsjK+vL9nZ2QpyIiIicsmo0U901bdFixbRp08f+/S8efPw9/fHarWSnJxMUlISU6ZMqbP9ZWZm1tm2pPEKCQlxdAlygTZv3uzoEkRELkhl30UXTZDLyclh48aNvPHGG/Z5/v7+AFgsFuLi4hgyZIh9fk5ODjabDWdnZ2w2G7m5ufblqysoKMh+I4WINF4K4yLSWFX78SP1bcmSJXTr1o3LL78cgOLiYoqKioDTPw+2YsUKAgMDAfDx8SEwMJD09HQA0tPTCQwM1LCqiIiIXFIumh65JUuW8PLLL9un8/LyGD58ODabjfLyctq1a0diYqK9fcKECSQkJDBr1iw8PT1JSUlxRNkiIiIiDuNkGIbh6CIaWklJCZmZmRpalWrbOWWQo0uQWmof/6GjSxARqTcXzdCqiIiIiNSMgpyIiIiISSnIiYiIiJiUgpyIiIiISSnIiYiIiJiUgpyIiIiISSnIiYiIiJiUgpyIiIiISSnIiYiIiJiUgpyIiIiISSnIiYiIiJiUgpyIiIiISSnIiYiIiJiUgpyIiIiISSnIiYiIiJiUgpyIiIiISSnIiYiIiJiUgpyIiIiISSnIiYiIiJiUgpyIiIiISSnIiYiIiJiUgpyIiIiISSnIiYiIiJiUgpyIiIiISSnIiYiIiJiUgpyIiIiISbk4ugCAqKgoLBYLbm5uAMTHxxMZGcnu3btJSEigsLAQLy8vUlJSaNu2LUCVbSIiIiKXgoumR2769OmkpqaSmppKZGQkAImJicTFxZGRkUFcXBzjx4+3L19Vm4iIiMil4KIJcn+Wl5fH9u3biYmJASAmJobt27eTn59fZZuIiIjIpeKiGFqF08OphmEQEhLCyJEjyc7Oxs/PD2dnZwCcnZ3x9fUlOzsbwzAqbfP29q72PjMzM+vlWKRxCQkJcXQJcoE2b97s6BJERC5IZd9FF0WQmzdvHv7+/litVpKTk0lKSmLQoEH1vt+goCD7dXki0ngpjItIY3VRDK36+/sDYLFYiIuLY8uWLfj7+5OTk4PNZgPAZrORm5uLv79/lW0iIiIilwqHB7ni4mKKiooAMAyDFStWEBgYiI+PD4GBgaSnpwOQnp5OYGAg3t7eVbaJiIiIXCqcDMMwHFnA/v37GT58ODabjfLyctq1a8fYsWPx9fUlKyuLhIQEjh07hqenJykpKVx77bUAVbadT0lJCZmZmRpalWrbOWWQo0uQWmof/6GjSxARqTcOD3KOoCAnNaUgZ14KciLSmDl8aFVEREREakdBTkRERMSkFORERERETEpBTkRERMSkFORERERETEpBTkRERMSkFORERERETEpBTkRERMSkFORERERETEpBTkRERMSkFORERERETEpBTkRERMSkFORERERETEpBTkRERMSkFORERERETEpBTkRERMSkFORERERETEpBTkRERMSkFORERERETEpBTkRERMSkFORERERETEpBTkRERMSkFORERERETEpBTkRERMSkFORERERETMrF0QUUFBTwwgsvsG/fPiwWC1dffTVJSUl4e3sTFRWFxWLBzc0NgPj4eCIjIwHYvXs3CQkJFBYW4uXlRUpKCm3btnXgkYiIiIg0LIf3yDk5OfHEE0+QkZFBWloarVu3ZsqUKfb26dOnk5qaSmpqqj3EASQmJhIXF0dGRgZxcXGMHz/eEeWLiIiIOIzDg5yXlxcRERH26ZtvvplDhw5VuU5eXh7bt28nJiYGgJiYGLZv305+fn691ioiIiJyMXH40OoflZeXM3/+fKKiouzz4uPjMQyDkJAQRo4ciaenJ9nZ2fj5+eHs7AyAs7Mzvr6+ZGdn4+3tXe39ZWZm1vkxSOMTEhLi6BLkAm3evNnRJYiIXJDKvosuqiA3ceJEmjdvzoABAwCYN28e/v7+WK1WkpOTSUpKqjDseqGCgoLs19+JSOOlMC4ijZXDh1bPSElJYe/evUybNo0mTU6X5e/vD4DFYiEuLo4tW7bY5+fk5GCz2QCw2Wzk5ubalxcRERG5FFwUQW7q1KlkZmYyc+ZMLBYLAMXFxRQVFQFgGAYrVqwgMDAQAB8fHwIDA0lPTwcgPT2dwMDAGg2rioiIiJidw4dWd+3axezZs2nbti39+/cHoFWrViQkJDB8+HBsNhvl5eW0a9eOxMRE+3oTJkwgISGBWbNm4enpSUpKiqMOQURERMQhnAzDMBxdREMrKSkhMzOzQa+Rs5basLg6N8i+pO7tnDLI0SVILbWP/9DRJYiI1BuH98hdKiyuzsSNX+3oMqQWPkm63dEliIiInNNFcY2ciIiIiNScgpyIiIiISSnIiYiIiJiUgpyIiIiISSnIiYiIiJiUgpyIiIiISSnIiYiIiJiUgpyIiIlZS22OLkFqSa+d1AU9EFhExMT0sHHz0sPGpS6oR05ERMQBysusji5BLsDF8vqpR05ERMQBmrhY9DvOJnax/I6zeuRERERETEpBTkRERMSkFORERERETEpBTkRERMSkFORERERETEpBTkRERMSkFORERERETEpBTkRERMSkFORERERETEpBTkRERMSkFORERERETEpBTkRERMSkFORERERETMrUQW737t3069eP7t27069fP/bs2ePokkREREQajKmDXGJiInFxcWRkZBAXF8f48eMdXZKIiIhIg3FxdAG1lZeXx/bt25k7dy4AMTExTJw4kfz8fLy9vatc1zAMAKxWa73X+UeezZwadH9SN0pKSihvepmjy5BaKikpcXQJ9U5/W8xJf1vMzRF/WywWC05OFT/vTsaZVGMymZmZjBkzhuXLl9vn9ezZk8mTJ9OhQ4cq1y0qKmLnzp31XaKIiIhInQkKCsLNza3CPNP2yF0Id3d32rdvj6ur61nJVkRERORiZLFYzppn2iDn7+9PTk4ONpsNZ2dnbDYbubm5+Pv7n3fdJk2acNll6s4WERERczPtzQ4+Pj4EBgaSnp4OQHp6OoGBgee9Pk5ERESksTDtNXIAWVlZJCQkcOzYMTw9PUlJSeHaa691dFkiIiIiDcLUQU5ERETkUmbaoVURERGRS52CnIiIiIhJKciJiIiImJSCnIiIiIhJKciJVCIlJYWoqCgCAgL0SyAiUmcKCgp48skn6d69O/fddx/Dhg0jPz/f0WWJSSnIiVQiOjqaefPm0bJlS0eXIiKNiJOTE0888QQZGRmkpaXRunVrpkyZ4uiyxKQU5EQqERoaWq1fChERqQkvLy8iIiLs0zfffDOHDh1yYEViZgpyIiIiDlJeXs78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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import seaborn\n", + "\n", + "x = 'Factor'\n", + "\n", + "df = pd.DataFrame({\n", + " x: replicas, \n", + " **results,\n", + "})\n", + "fig, ax1 = plt.subplots(figsize=(10, 5))\n", + "tidy = df.melt(id_vars=x).rename(columns=str.title)\n", + "seaborn.barplot(x=x, y='Value', hue='Variable', data=tidy, ax=ax1)\n", + "seaborn.despine(fig)\n", + "\n", + "ax1.set(xlabel=\"Num Replicas\", ylabel=f'MASE Loss', title='Residual Estimate Loss for Time-Series Decomposition')" + ] + }, + { + "cell_type": "code", + "execution_count": 277, + "id": "9a4dba29", + "metadata": {}, + "outputs": [ + { + "ename": "ValueError", + "evalue": "min() arg is an empty sequence", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0mfig\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0max1\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msubplots\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfigsize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0mtidy\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmelt\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mid_vars\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrename\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcolumns\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mstr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtitle\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 13\u001b[0;31m \u001b[0mseaborn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbarplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Value'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhue\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Variable'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtidy\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0max1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 14\u001b[0m \u001b[0mseaborn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdespine\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfig\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/data/wooders/anaconda3/lib/python3.8/site-packages/seaborn/_decorators.py\u001b[0m in \u001b[0;36minner_f\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 44\u001b[0m )\n\u001b[1;32m 45\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupdate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0marg\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mk\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0marg\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mzip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msig\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparameters\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 46\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 47\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0minner_f\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 48\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/data/wooders/anaconda3/lib/python3.8/site-packages/seaborn/categorical.py\u001b[0m in \u001b[0;36mbarplot\u001b[0;34m(x, y, hue, data, order, hue_order, estimator, ci, n_boot, units, seed, orient, color, palette, saturation, errcolor, errwidth, capsize, dodge, ax, **kwargs)\u001b[0m\n\u001b[1;32m 3177\u001b[0m ):\n\u001b[1;32m 3178\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3179\u001b[0;31m plotter = _BarPlotter(x, y, hue, data, order, hue_order,\n\u001b[0m\u001b[1;32m 3180\u001b[0m \u001b[0mestimator\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mci\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_boot\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0munits\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mseed\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3181\u001b[0m \u001b[0morient\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolor\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpalette\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msaturation\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/data/wooders/anaconda3/lib/python3.8/site-packages/seaborn/categorical.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, x, y, hue, data, order, hue_order, estimator, ci, n_boot, units, seed, orient, color, palette, saturation, errcolor, errwidth, capsize, dodge)\u001b[0m\n\u001b[1;32m 1584\u001b[0m self.establish_variables(x, y, hue, data, orient,\n\u001b[1;32m 1585\u001b[0m order, hue_order, units)\n\u001b[0;32m-> 1586\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mestablish_colors\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcolor\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpalette\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msaturation\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1587\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mestimate_statistic\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mestimator\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mci\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_boot\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mseed\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1588\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/data/wooders/anaconda3/lib/python3.8/site-packages/seaborn/categorical.py\u001b[0m in \u001b[0;36mestablish_colors\u001b[0;34m(self, color, palette, saturation)\u001b[0m\n\u001b[1;32m 317\u001b[0m \u001b[0;31m# Determine the gray color to use for the lines framing the plot\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 318\u001b[0m \u001b[0mlight_vals\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mcolorsys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrgb_to_hls\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mc\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrgb_colors\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 319\u001b[0;31m \u001b[0mlum\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlight_vals\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0;36m.6\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 320\u001b[0m \u001b[0mgray\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmpl\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolors\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrgb2hex\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlum\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlum\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlum\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 321\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mValueError\u001b[0m: min() arg is an empty sequence" + ] + }, + { + "data": { + "image/png": "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b2fXrl259dZbkyTvvPNOqtVq/vOf/+T++++veZg5c+Zk4sSJI/g1GGu9vb2ZO3fuWI/BCNhdfbO/+mV39evQoUOf6oLRsPE1ZcqUNDc3p6enJ4sXL05PT0+am5szefLkI2emT5+eLVu2HPl85cqVOXjwYO66664RDwYAcDKq6W87rlixIl1dXWlpaUlXV1c6OjqSJO3t7dm2bdsJHRAA4GRS0z1fs2bNSnd39zFfX7169Ueev/322z/dVAAAJynvcA8AUJD4AgAoSHwBABQkvgAAChJfAAAFiS8AgILEFwBAQeILAKAg8QUAUJD4AgAoSHwBABQkvgAAChJfAAAFiS8AgILEFwBAQeILAKAg8QUAUJD4AgAoSHwBABQkvgAAChJfAAAFiS8AgILEFwBAQeILAKAg8QUAUJD4AgAoSHwBABQkvgAAChJfAAAFiS8AgILEFwBAQeILAKAg8QUAUJD4AgAoSHwBABQkvgAAChJfAAAFiS8AgILEFwBAQeILAKAg8QUAUJD4AgAoSHwBABQkvgAAChJfAAAFiS8AgILG13Jo586dufvuu7N///6ceeaZ6ezszMyZM486s2rVqqxfvz6NjY0ZP3587rjjjsybN+9EzAwAULdqiq/ly5enra0tixcvzpNPPplly5blscceO+rMRRddlKVLl+a0007LSy+9lBtvvDGbN2/OqaeeekIGBwCoR8O+7DgwMJC+vr60trYmSVpbW9PX15d9+/YddW7evHk57bTTkiSzZ89OtVrN/v37R39iAIA6NuyVr/7+/kybNi2NjY1JksbGxkydOjX9/f2ZPHnyR37P2rVrc8455+Tss88+rmG2b99+XOf5bOnt7R3rERghu6tv9le/7O7zqaaXHY/HCy+8kAcffDC///3vj/t758yZk4kTJ472SBTQ29ubuXPnjvUYjIDd1Tf7q192V78OHTr0qS4YDfuyY1NTU3bv3p1KpZIkqVQq2bNnT5qamo45++KLL+bOO+/MqlWrcu655454KACAk9Ww8TVlypQ0Nzenp6cnSdLT05Pm5uZjXnLcunVr7rjjjjz00EO58MILT8y0AAB1rqb3+VqxYkW6urrS0tKSrq6udHR0JEna29uzbdu2JElHR0fee++9LFu2LIsXL87ixYuzY8eOEzc5AEAdqumer1mzZqW7u/uYr69evfrIx3/6059G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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import seaborn\n", + "\n", + "x = 'Factor'\n", + "\n", + "df = pd.DataFrame({\n", + " x: graph_results[\"cost\"], \n", + " 'baseline': graph_results[\"baseline\"], \n", + " \"optimized\": graph_results[\"optimized\"],\n", + "})\n", + "fig, ax1 = plt.subplots(figsize=(10, 5))\n", + "tidy = df.melt(id_vars=x).rename(columns=str.title)\n", + "seaborn.barplot(x=x, y='Value', hue='Variable', data=tidy, ax=ax1)\n", + "seaborn.despine(fig)\n", + "\n", + "ax1.set(xlabel=\"Cost Budget\", ylabel=f'MASE Loss', title='Residual Estimate Loss for Time-Series Decomposition')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a9bccc31", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.8" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/stl/offline/run_6_simulate_baseline.sh b/stl/offline/run_6_simulate_baseline.sh new file mode 100644 index 0000000..f70fabf --- /dev/null +++ b/stl/offline/run_6_simulate_baseline.sh @@ -0,0 +1,37 @@ +set -xe +PARAM_DIR="/data/wooders/stl/results" +PLAN_DIR="/data/wooders/stl/results" +TRAIN_PATH="./yahoo_train_data" +EVAL_PATH="./yahoo_eval_data" + +for key_policy in "lifo" "fifo" +do +for replicas in 1 2 4 8 +do + for slide in 672 1 6 12 18 24 48 96 168 192 336 + do + plan="plan_baseline_${slide}_${key_policy}" + param="plan_baseline_${slide}" + mkdir -p ${PLAN_DIR}/replica_${replicas} + python simulation.py \ + --model_runtime_s 1.5 \ + --total_runtime_s 2000 \ + --per_key_records_per_second 1 \ + --window_size 672 \ + --slide_size ${slide} \ + --per_key_slide_size_plan ${PARAM_DIR}/${param}.json \ + --output_path ${PLAN_DIR}/replica_${replicas}/${plan}.json \ + --source_data_path $TRAIN_PATH \ + --num_mapper_replicas ${replicas} \ + --key_prio_policy ${key_policy} + + mkdir -p ${PLAN_DIR}/replica_${replicas}/${plan} + python evaluation.py --offline-yahoo-csv-path $EVAL_PATH \ + --offline-plan-path ${PLAN_DIR}/replica_${replicas}/${plan}.json \ + --output-path ${PLAN_DIR}/replica_${replicas}/${plan} \ + --param-path ${PARAM_DIR}/${param}.json \ + --run-policy + + done +done +done diff --git a/wikipedia/config.yml b/wikipedia/config.yml index ad09cc0..2ae74c2 100644 --- a/wikipedia/config.yml +++ b/wikipedia/config.yml @@ -18,6 +18,8 @@ titles_file = %(data_dir)s/top_titles.csv revisions_file = %(data_dir)s/title_revisions_timestamps.json edits_file = %(data_dir)s/edits.csv questions_file = %(data_dir)s/questions.csv +train_questions_file = %(data_dir)s/train_questions.csv +test_questions_file = %(data_dir)s/test_questions.csv raw_pageview_file = %(data_dir)s/top_title_views.csv pageview_file = %(data_dir)s/pageviews.csv timestamp_weights_file = %(data_dir)s/timestamp_weights_file.json diff --git a/wikipedia/notebooks/Wikipedia Plots.ipynb b/wikipedia/notebooks/Wikipedia Plots.ipynb index 9213239..e417120 100644 --- a/wikipedia/notebooks/Wikipedia Plots.ipynb +++ b/wikipedia/notebooks/Wikipedia Plots.ipynb @@ -779,7 +779,7 @@ { "cell_type": "code", "execution_count": 183, - "id": "89abf373", + "id": "511f1c65", "metadata": {}, "outputs": [ { @@ -1347,7 +1347,7 @@ { "cell_type": "code", "execution_count": 191, - "id": "76fa4e4f", + "id": "d699a5a5", "metadata": {}, "outputs": [], "source": [ @@ -1357,7 +1357,7 @@ { "cell_type": "code", "execution_count": 192, - "id": "fe3f87bc", + "id": "c5b6cbeb", "metadata": {}, "outputs": [], "source": [ @@ -1368,7 +1368,7 @@ { "cell_type": "code", "execution_count": 193, - "id": "63a1c934", + "id": "d0c039a3", "metadata": {}, "outputs": [ { @@ -1584,7 +1584,7 @@ { "cell_type": "code", "execution_count": 195, - "id": "d3343738", + "id": "954b1ea8", "metadata": {}, "outputs": [ { @@ -1831,39 +1831,39 @@ }, { "cell_type": "code", - "execution_count": 197, + "execution_count": 215, "id": "d9dab1e5", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "What is the name of the company?? 4339\n", - "what is the name of the company?????? 4018\n", - "what is the u.s. open???????? 1201\n", - "What is the best tennis tournament in the world?? 1090\n", - "what is the std?????? 1035\n", - " ... \n", - "What are the main factors that affect the success of the high speed railway system?? 1\n", - "What did the government do?? 1\n", - "What is the purpose of the evacuation?? 1\n", - "what is a christian name?? 1\n", - "How many corridors are under construction?? 1\n", - "Name: question, Length: 3219, dtype: int64" + "1305297 8677\n", + "332667 4300\n", + "66304621 3720\n", + "17888363 3569\n", + "3259011 1581\n", + " ... \n", + "67959451 15\n", + "49474213 12\n", + "66135952 12\n", + "66074428 8\n", + "40713040 2\n", + "Name: doc_id, Length: 118, dtype: int64" ] }, - "execution_count": 197, + "execution_count": 215, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "train_df.question.value_counts()" + "test_df.doc_id.value_counts()" ] }, { "cell_type": "code", - "execution_count": 198, + "execution_count": 216, "id": "ea220f3d", "metadata": {}, "outputs": [ @@ -1884,7 +1884,7 @@ "Name: doc_id, Length: 118, dtype: int64" ] }, - "execution_count": 198, + "execution_count": 216, "metadata": {}, "output_type": "execute_result" } @@ -1895,7 +1895,26 @@ }, { "cell_type": "code", - "execution_count": 199, + "execution_count": 204, + "id": "bfdea858", + "metadata": {}, + "outputs": [], + "source": [ + "test_df.to_csv(\"/data/wooders/wikipedia/test_questions.csv\")\n", + "train_df.to_csv(\"/data/wooders/wikipedia/train_questions.csv\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b01259cc", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 205, "id": "86c3ebf2", "metadata": {}, "outputs": [], @@ -1905,15 +1924,169 @@ }, { "cell_type": "code", - "execution_count": 200, + "execution_count": 206, + "id": "f0941e02", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{1305297: 8677,\n", + " 332667: 4300,\n", + " 66304621: 3720,\n", + " 17888363: 3569,\n", + " 3259011: 1581,\n", + " 58112801: 1253,\n", + " 68507348: 1201,\n", + " 62808792: 1099,\n", + " 66052432: 987,\n", + " 62372638: 879,\n", + " 67089631: 860,\n", + " 67569553: 822,\n", + " 60476189: 822,\n", + " 68553225: 805,\n", + " 1425939: 774,\n", + " 66187257: 687,\n", + " 65521767: 585,\n", + " 67946554: 551,\n", + " 68498551: 453,\n", + " 442785: 446,\n", + " 734845: 401,\n", + " 487602: 381,\n", + " 66883576: 379,\n", + " 68294454: 369,\n", + " 61250187: 366,\n", + " 50170924: 360,\n", + " 61236755: 347,\n", + " 12936708: 309,\n", + " 1027173: 308,\n", + " 46754025: 276,\n", + " 58542318: 258,\n", + " 61258486: 242,\n", + " 66753136: 240,\n", + " 5575754: 240,\n", + " 65871303: 236,\n", + " 12202928: 228,\n", + " 60600284: 224,\n", + " 51150040: 222,\n", + " 34075129: 220,\n", + " 58385279: 217,\n", + " 61049392: 215,\n", + " 60203476: 212,\n", + " 66341639: 212,\n", + " 63129286: 210,\n", + " 26833: 210,\n", + " 24689651: 208,\n", + " 66629866: 207,\n", + " 33385984: 204,\n", + " 58113491: 200,\n", + " 63170193: 200,\n", + " 63395714: 193,\n", + " 55055575: 191,\n", + " 67918135: 190,\n", + " 68284887: 188,\n", + " 65984422: 187,\n", + " 66040815: 181,\n", + " 57798785: 168,\n", + " 67131229: 167,\n", + " 53943680: 166,\n", + " 20304678: 164,\n", + " 64783122: 160,\n", + " 51345275: 155,\n", + " 39734558: 150,\n", + " 65666080: 148,\n", + " 31243078: 147,\n", + " 36567599: 145,\n", + " 67742925: 144,\n", + " 67674654: 142,\n", + " 6063379: 140,\n", + " 66293350: 139,\n", + " 912080: 135,\n", + " 2514174: 134,\n", + " 67843993: 130,\n", + " 26000816: 127,\n", + " 67037597: 120,\n", + " 67903070: 117,\n", + " 65760352: 114,\n", + " 67711917: 112,\n", + " 404323: 111,\n", + " 68107833: 110,\n", + " 57817558: 108,\n", + " 49632909: 105,\n", + " 65770543: 103,\n", + " 67928132: 100,\n", + " 68207325: 100,\n", + " 25743896: 100,\n", + " 68475822: 100,\n", + " 21537193: 98,\n", + " 67334964: 97,\n", + " 68187748: 96,\n", + " 66461741: 93,\n", + " 56185392: 90,\n", + " 68315181: 80,\n", + " 61293820: 75,\n", + " 2656208: 71,\n", + " 60070859: 70,\n", + " 68076456: 70,\n", + " 65708437: 64,\n", + " 68420852: 60,\n", + " 61243245: 60,\n", + " 68463873: 40,\n", + " 60043578: 40,\n", + " 49588: 39,\n", + " 68229696: 36,\n", + " 737: 36,\n", + " 18097883: 34,\n", + " 66459202: 33,\n", + " 66128424: 30,\n", + " 58542328: 30,\n", + " 66916437: 30,\n", + " 67688633: 25,\n", + " 63417935: 24,\n", + " 20306953: 20,\n", + " 67959451: 15,\n", + " 49474213: 12,\n", + " 66135952: 12,\n", + " 66074428: 8,\n", + " 40713040: 2}" + ] + }, + "execution_count": 206, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "weights" + ] + }, + { + "cell_type": "code", + "execution_count": 210, + "id": "2c255c62", + "metadata": {}, + "outputs": [], + "source": [ + "buckets = [1, 2, 4, 8, 16, 32, 64]" + ] + }, + { + "cell_type": "code", + "execution_count": 213, "id": "af72ae1a", "metadata": {}, "outputs": [], "source": [ "for key in weights: \n", - " weights[key] = int(weights[key]/10)\n", - " if weights[key] == 0: \n", - " weights[key] = 1" + " w = int(weights[key]/10)\n", + " if w == 0: \n", + " w = 1\n", + " for b in buckets: \n", + " if w <= b:\n", + " w = b\n", + " break\n", + " weights[key] = b\n", + " #print(weights[key], b)" ] }, { @@ -2077,9 +2250,30 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 214, "id": "0901f729", "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1831" + ] + }, + "execution_count": 214, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "open(\"/home/eecs/wooders/experiments/wikipedia/bucket_weights.json\", \"w\").write(json.dumps(weights))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1a356582", + "metadata": {}, "outputs": [], "source": [] } diff --git a/wikipedia/preprocessing/log_data.py b/wikipedia/preprocessing/log_data.py index 23522a0..9cbaf06 100644 --- a/wikipedia/preprocessing/log_data.py +++ b/wikipedia/preprocessing/log_data.py @@ -8,6 +8,8 @@ def log_questions(run, config): artifact = wandb.Artifact("questions", type='dataset') artifact.add_file(config["files"]["raw_questions_file"]) artifact.add_file(config["files"]["questions_file"]) + artifact.add_file(config["files"]["test_questions_file"]) + artifact.add_file(config["files"]["train_questions_file"]) run.log_artifact(artifact) def log_files(run, config): diff --git a/wikipedia/run_1_generate_plan.sh b/wikipedia/run_1_generate_plan.sh index 36ac40b..5123d42 100644 --- a/wikipedia/run_1_generate_plan.sh +++ b/wikipedia/run_1_generate_plan.sh @@ -1,16 +1,19 @@ set -xe -for key_policy in "random" "weighted_random" "round_robin" "weighted_round_robin" +for replicas in 2 4 8 1 do - for event_policy in "lifo" "fifo" + for model_runtime in 0.25 do - for load_shedding_policy in "always_process" + for event_policy in "lifo" #"fifo" do - for model_runtime in 0.25 0.005 + for load_shedding_policy in "always_process" do - python simulate.py --model_runtime $model_runtime --send_rate 100 \ - --event_policy $event_policy --key_policy $key_policy --load_shedding_policy $load_shedding_policy + for key_policy in "round_robin" "weighted_round_robin" + do + python simulate.py --model_runtime $model_runtime --send_rate 100 \ + --event_policy $event_policy --key_policy $key_policy --load_shedding_policy $load_shedding_policy --num_replicas ${replicas} + done done done - done -done + done +done diff --git a/wikipedia/run_2_prepare_data.sh b/wikipedia/run_2_prepare_data.sh index e863f05..d170ebd 100644 --- a/wikipedia/run_2_prepare_data.sh +++ b/wikipedia/run_2_prepare_data.sh @@ -2,17 +2,19 @@ set -xe plan_dir=/data/wooders/wiki-plans -for model_runtime in 0.005 +for replicas in 2 +do +for model_runtime in 1.0 do for event_policy in "lifo" do for load_shedding_policy in "always_process" do - for key_policy in "round_robin" "weighted_round_robin" "random" "weighted_random" + for key_policy in "round_robin" "weighted_round_robin" do - python wiki_eval_tmp.py --offline-plan-path ${plan_dir}/plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100.json --workers 32 + python wiki_eval_tmp.py --offline-plan-path ${plan_dir}/plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100_replicas_${replicas}.json --workers 32 done done done done -p +done diff --git a/wikipedia/simulate.py b/wikipedia/simulate.py index fd2dc11..78ed8a1 100644 --- a/wikipedia/simulate.py +++ b/wikipedia/simulate.py @@ -1,6 +1,7 @@ -import json import itertools +import json from typing import DefaultDict, Dict, List, Optional, Tuple +from more_itertools.more import divide from collections import defaultdict from dataclasses import dataclass from functools import cmp_to_key @@ -56,234 +57,317 @@ def current_weights(ts, ts_to_weights): return ts_to_weights[key] -class RoundRobinLoadBalancerFix(CrossKeyLoadBalancer): +class KeyFIFO(CrossKeyLoadBalancer): """Simple policy that cycle through all the keys fairly""" - def __init__(self): - self.cur_key_set = set() - self.cur_key_iter = None + def __init__(self, num_replicas=1): + self.cur_key_set = {} + for replica_id in range(num_replicas): + self.cur_key_set[replica_id] = set() + print(num_replicas, self.cur_key_set) - def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: + def choose( + self, per_key_queues: Dict[str, PerKeyPriorityQueue], replica_id: int + ) -> str: key_set = set(per_key_queues.keys()) - if key_set != self.cur_key_set: - self.cur_key_set = key_set - self.cur_key_iter = itertools.cycle(key_set) + if key_set != self.cur_key_set[replica_id]: + #print("reset keys", replica_id, len(key_set), key_set, self.cur_key_set[replica_id]) + self.cur_key_set[replica_id] = key_set + self.cur_key_iter[replica_id] = itertools.cycle(key_set) - key = next(self.cur_key_iter) + seen = set([]) while per_key_queues[key].size() == 0: - key = next(self.cur_key_iter) + key = next(self.cur_key_iter[replica_id]) + #print(replica_id, key, per_key_queues[key].size(), per_key_queues[key].size() == 0) + if key in seen: + raise ValueError(f"Did full loop - livelock {replica_id}") + #return None + seen.add(key) # TODO(simon): maybe do a "peak" here to trigger eviction policies + #print("choose", replica_id, key) return key -class WeightedRoundRobin(CrossKeyLoadBalancer): +class RoundRobinLoadBalancer(CrossKeyLoadBalancer): """Simple policy that cycle through all the keys fairly""" - def __init__(self, pageview_file, all_keys): - self.cur_key_set = [] - self.cur_key_iter = None - pageview_df = pd.read_csv(pageview_file) - - self.weights = json.load(open("weights.json")) - - ##self.raw_weights = pageview_df.set_index("doc_id")["weights"].to_dict() - #self.raw_weights = pageview_df.set_index("doc_id")["2021090300"].to_dict() - #self.weights = {} - #for key in self.raw_weights.keys(): - # if str(key) not in all_keys: - # continue - - # self.weights[key] = int(self.raw_weights[key]*1000) - # #assert self.weights[key] > 0, f"Too small {key}, {self.raw_weights[key]}" - # if self.weights[key] == 0: - # self.weights[key] = 1 - - - for key in all_keys: - if key not in self.weights: - self.weights[key] = 1 - - - for key in self.weights.keys(): - for i in range(self.weights[key]): - self.cur_key_set.append(str(key)) - random.shuffle(self.cur_key_set) - self.cur_key_iter = itertools.cycle(self.cur_key_set) - + def __init__(self, num_replicas=1): + self.cur_key_iter = {} + self.cur_key_set = {} + for replica_id in range(num_replicas): + self.cur_key_set[replica_id] = set() + self.cur_key_iter[replica_id] = None + print(num_replicas, self.cur_key_set) + print(num_replicas, "replicas", self.cur_key_iter) + + def choose( + self, per_key_queues: Dict[str, PerKeyPriorityQueue], replica_id: int + ) -> str: + key_set = set(per_key_queues.keys()) + if key_set != self.cur_key_set[replica_id]: + #print("reset keys", replica_id, len(key_set), key_set, self.cur_key_set[replica_id]) + self.cur_key_set[replica_id] = key_set + self.cur_key_iter[replica_id] = itertools.cycle(key_set) - def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: + key = next(self.cur_key_iter[replica_id]) - key = next(self.cur_key_iter) + seen = set([]) while per_key_queues[key].size() == 0: - key = next(self.cur_key_iter) + key = next(self.cur_key_iter[replica_id]) + #print(replica_id, key, per_key_queues[key].size(), per_key_queues[key].size() == 0) + if key in seen: + raise ValueError(f"Did full loop - livelock {replica_id}") + #return None + seen.add(key) # TODO(simon): maybe do a "peak" here to trigger eviction policies + #print("choose", replica_id, key) return key -class AdaptiveWeightedRoundRobin(CrossKeyLoadBalancer): - """Simple policy that cycle through all the keys fairly""" - - def __init__(self, timestamp_weights_file): - self.cur_key_set = [] - self.cur_key_iter = None - - pageview_df = pd.read_csv(pageview_file) - self.raw_weights = pageview_df.set_index("doc_id")["weights"].to_dict() - self.weights = {} - for key in self.raw_weights.keys(): - if str(key) not in all_keys: - continue +class WeightedRoundRobinLoadBalancer(CrossKeyLoadBalancer): - self.weights[key] = int(self.raw_weights[key]*1000) - assert self.weights[key] > 0, f"Too small {key}, {self.raw_weights[key]}" + def __init__(self, all_keys, num_replicas=1): + + self.weights = json.load(open("bucket_weights.json")) + # set default weight + for key in all_keys: + if key not in self.weights: + self.weights[key] = 1 - for key in self.weights.keys(): - for i in range(self.weights[key]): - self.cur_key_set.append(str(key)) - random.shuffle(self.cur_key_set) - self.cur_key_iter = itertools.cycle(self.cur_key_set) + self.cur_key_iter = {} + self.cur_key_set = {} + for replica_id in range(num_replicas): + self.cur_key_set[replica_id] = set() + self.cur_key_iter[replica_id] = None + def choose( + self, per_key_queues: Dict[str, PerKeyPriorityQueue], replica_id: int + ) -> str: + key_set = set(per_key_queues.keys()) - def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: + # initialize keys + if key_set != self.cur_key_set[replica_id]: + self.cur_key_set[replica_id] = [] + for key in key_set: + for i in range(self.weights[key]): + self.cur_key_set[replica_id].append(key) + random.shuffle(self.cur_key_set[replica_id]) + self.cur_key_iter[replica_id] = itertools.cycle(self.cur_key_set[replica_id]) - key = next(self.cur_key_iter) + key = next(self.cur_key_iter[replica_id]) while per_key_queues[key].size() == 0: - key = next(self.cur_key_iter) - # TODO(simon): maybe do a "peak" here to trigger eviction policies + key = next(self.cur_key_iter[replica_id]) return key -class AdaptiveWeightedLoadBalancer(CrossKeyLoadBalancer): - - def __init__(self, timestamp_weights_file): - data = json.load(open(timestamp_weights_file)) - self.timestamp_weights = {} - for key in data.keys(): - self.timestamp_weights[int(key)] = data[key] - - def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], timestamp: int) -> str: - weights_map = current_weights(timestamp, self.timestamp_weights) - - chosen_key = None - max_len = 0 - total_len = 0 - keys = [] - weights = [] - for key in per_key_queues.keys(): - size = per_key_queues[key].size() - if size >= 1 and key in weights_map: - keys.append(key) - weights.append(weights_map[key]) - total_len += size - chosen_key = random.choices(keys, weights, k=1)[0] - return chosen_key - - -class WeightedLoadBalancer(CrossKeyLoadBalancer): - - def __init__(self, pageview_file): - pageview_df = pd.read_csv(pageview_file) - #self.weights = pageview_df.set_index("doc_id")["weights"].to_dict() - self.weights = json.load(open("weights.json")) - - def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: - chosen_key = None - max_len = 0 - total_len = 0 - keys = [] - weights = [] - for key in per_key_queues.keys(): - size = per_key_queues[key].size() - if size >= 1 and int(key) in self.weights: - keys.append(key) - weights.append(self.weights[int(key)]) - total_len += size - - chosen_key = random.choices(keys, weights, k=1)[0] - #print("choose", chosen_key, keys, weights) - return chosen_key - -class RandomLoadBalancer(CrossKeyLoadBalancer): - - def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: - chosen_key = None - max_len = 0 - total_len = 0 - keys = [] - for key in per_key_queues.keys(): - size = per_key_queues[key].size() - if size >= 1: - keys.append(key) - total_len += size - - chosen_key = random.choices(keys, k=1)[0] - return chosen_key - - -class WeightedLongestQueueLoadBalancer(CrossKeyLoadBalancer): - - def __init__(self, pageview_file): - pageview_df = pd.read_csv(pageview_file) - self.weights = pageview_df.set_index("doc_id")["weights"].to_dict() - #print(self.weights) - - def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: - chosen_key = None - max_len = 0 - total_len = 0 - for key in per_key_queues.keys(): - size = per_key_queues[key].size() - if int(key) not in self.weights: - continue - weighted_size = self.weights[int(key)]*self.weights[int(key)] - if weighted_size > max_len: - chosen_key = key - max_len = size - total_len += size - #print(chosen_key, max_len, self.weights[int(chosen_key)]) - per_key_queues[chosen_key].clear() - print("clear", chosen_key, total_len, per_key_queues[chosen_key].size()) - return chosen_key - -class WeightedLoadBalancer(CrossKeyLoadBalancer): - - def __init__(self, pageview_file): - pageview_df = pd.read_csv(pageview_file) - self.weights = pageview_df.set_index("doc_id")["weights"].to_dict() - #print(self.weights) - - def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: - chosen_key = None - max_len = 0 - total_len = 0 - keys = [] - weights = [] - for key in per_key_queues.keys(): - size = per_key_queues[key].size() - if size >= 1 and int(key) in self.weights: - keys.append(key) - weights.append(self.weights[int(key)]) - total_len += size - - chosen_key = random.choices(keys, weights, k=1)[0] - #print("choose", chosen_key, keys, weights) - return chosen_key - -class LongestQueueLoadBalancer(CrossKeyLoadBalancer): - - def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: - chosen_key = None - max_len = 0 - total_len = 0 - for key in per_key_queues.keys(): - size = per_key_queues[key].size() - if size > max_len: - chosen_key = key - max_len = size - total_len += size - per_key_queues[chosen_key].clear() - - return chosen_key +#class WeightedRoundRobin(CrossKeyLoadBalancer): +# """Simple policy that cycle through all the keys fairly""" +# +# def __init__(self, pageview_file, all_keys): +# self.cur_key_set = [] +# self.cur_key_iter = None +# pageview_df = pd.read_csv(pageview_file) +# +# self.weights = json.load(open("weights.json")) +# +# ##self.raw_weights = pageview_df.set_index("doc_id")["weights"].to_dict() +# #self.raw_weights = pageview_df.set_index("doc_id")["2021090300"].to_dict() +# #self.weights = {} +# #for key in self.raw_weights.keys(): +# # if str(key) not in all_keys: +# # continue +# +# # self.weights[key] = int(self.raw_weights[key]*1000) +# # #assert self.weights[key] > 0, f"Too small {key}, {self.raw_weights[key]}" +# # if self.weights[key] == 0: +# # self.weights[key] = 1 +# +# +# for key in all_keys: +# if key not in self.weights: +# self.weights[key] = 1 +# +# +# for key in self.weights.keys(): +# for i in range(self.weights[key]): +# self.cur_key_set.append(str(key)) +# random.shuffle(self.cur_key_set) +# self.cur_key_iter = itertools.cycle(self.cur_key_set) +# +# +# def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: +# +# key = next(self.cur_key_iter) +# while per_key_queues[key].size() == 0: +# key = next(self.cur_key_iter) +# # TODO(simon): maybe do a "peak" here to trigger eviction policies +# return key +# +#class AdaptiveWeightedRoundRobin(CrossKeyLoadBalancer): +# """Simple policy that cycle through all the keys fairly""" +# +# def __init__(self, timestamp_weights_file): +# self.cur_key_set = [] +# self.cur_key_iter = None +# +# pageview_df = pd.read_csv(pageview_file) +# self.raw_weights = pageview_df.set_index("doc_id")["weights"].to_dict() +# self.weights = {} +# for key in self.raw_weights.keys(): +# if str(key) not in all_keys: +# continue +# +# self.weights[key] = int(self.raw_weights[key]*1000) +# assert self.weights[key] > 0, f"Too small {key}, {self.raw_weights[key]}" +# +# +# for key in self.weights.keys(): +# for i in range(self.weights[key]): +# self.cur_key_set.append(str(key)) +# random.shuffle(self.cur_key_set) +# self.cur_key_iter = itertools.cycle(self.cur_key_set) +# +# +# def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: +# +# key = next(self.cur_key_iter) +# while per_key_queues[key].size() == 0: +# key = next(self.cur_key_iter) +# # TODO(simon): maybe do a "peak" here to trigger eviction policies +# return key +# +# +#class AdaptiveWeightedLoadBalancer(CrossKeyLoadBalancer): +# +# def __init__(self, timestamp_weights_file): +# data = json.load(open(timestamp_weights_file)) +# self.timestamp_weights = {} +# for key in data.keys(): +# self.timestamp_weights[int(key)] = data[key] +# +# def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], timestamp: int) -> str: +# weights_map = current_weights(timestamp, self.timestamp_weights) +# +# chosen_key = None +# max_len = 0 +# total_len = 0 +# keys = [] +# weights = [] +# for key in per_key_queues.keys(): +# size = per_key_queues[key].size() +# if size >= 1 and key in weights_map: +# keys.append(key) +# weights.append(weights_map[key]) +# total_len += size +# chosen_key = random.choices(keys, weights, k=1)[0] +# return chosen_key +# +# +#class WeightedLoadBalancer(CrossKeyLoadBalancer): +# +# def __init__(self, pageview_file): +# pageview_df = pd.read_csv(pageview_file) +# #self.weights = pageview_df.set_index("doc_id")["weights"].to_dict() +# self.weights = json.load(open("weights.json")) +# +# def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: +# chosen_key = None +# max_len = 0 +# total_len = 0 +# keys = [] +# weights = [] +# for key in per_key_queues.keys(): +# size = per_key_queues[key].size() +# if size >= 1 and int(key) in self.weights: +# keys.append(key) +# weights.append(self.weights[int(key)]) +# total_len += size +# +# chosen_key = random.choices(keys, weights, k=1)[0] +# #print("choose", chosen_key, keys, weights) +# return chosen_key +# +#class RandomLoadBalancer(CrossKeyLoadBalancer): +# +# def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: +# chosen_key = None +# max_len = 0 +# total_len = 0 +# keys = [] +# for key in per_key_queues.keys(): +# size = per_key_queues[key].size() +# if size >= 1: +# keys.append(key) +# total_len += size +# +# chosen_key = random.choices(keys, k=1)[0] +# return chosen_key +# +# +#class WeightedLongestQueueLoadBalancer(CrossKeyLoadBalancer): +# +# def __init__(self, pageview_file): +# pageview_df = pd.read_csv(pageview_file) +# self.weights = pageview_df.set_index("doc_id")["weights"].to_dict() +# #print(self.weights) +# +# def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: +# chosen_key = None +# max_len = 0 +# total_len = 0 +# for key in per_key_queues.keys(): +# size = per_key_queues[key].size() +# if int(key) not in self.weights: +# continue +# weighted_size = self.weights[int(key)]*self.weights[int(key)] +# if weighted_size > max_len: +# chosen_key = key +# max_len = size +# total_len += size +# #print(chosen_key, max_len, self.weights[int(chosen_key)]) +# per_key_queues[chosen_key].clear() +# print("clear", chosen_key, total_len, per_key_queues[chosen_key].size()) +# return chosen_key +# +#class WeightedLoadBalancer(CrossKeyLoadBalancer): +# +# def __init__(self, pageview_file): +# pageview_df = pd.read_csv(pageview_file) +# self.weights = pageview_df.set_index("doc_id")["weights"].to_dict() +# #print(self.weights) +# +# def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: +# chosen_key = None +# max_len = 0 +# total_len = 0 +# keys = [] +# weights = [] +# for key in per_key_queues.keys(): +# size = per_key_queues[key].size() +# if size >= 1 and int(key) in self.weights: +# keys.append(key) +# weights.append(self.weights[int(key)]) +# total_len += size +# +# chosen_key = random.choices(keys, weights, k=1)[0] +# #print("choose", chosen_key, keys, weights) +# return chosen_key +# +#class LongestQueueLoadBalancer(CrossKeyLoadBalancer): +# +# def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: +# chosen_key = None +# max_len = 0 +# total_len = 0 +# for key in per_key_queues.keys(): +# size = per_key_queues[key].size() +# if size > max_len: +# chosen_key = key +# max_len = size +# total_len += size +# per_key_queues[chosen_key].clear() +# +# return chosen_key class WikiMapper(RalfMapper): @@ -299,7 +383,7 @@ def __init__( super().__init__(env, source_queues, key_selection_policy_cls, model_run_time_s, num_replicas) self.keys = keys - self.source_queues = source_queues + #self.source_queues = source_queues # self.env = env # self.source_queues = source_queues @@ -308,21 +392,38 @@ def __init__( # self.env.process(self.run()) self.ready_time_to_batch: Dict[float, List[Tuple[int, float]]] = {} + + ## Shard source queues into each replica's id. + #source_keys = list(source_queues.keys()) + #random.shuffle(source_keys) + #self.sharded_keys = dict( + # enumerate(map(list, divide(num_replicas, source_keys))) + #) + #self.key_selection_policy = key_selection_policy_cls + #self.model_runtime_s = model_run_time_s + #for i in range(num_replicas): + # print("Run replica", i) + # self.env.process(self.run(replica_id=i)) - def run(self, replica_id: int): - self.source_queues = { + def run(self, replica_id: int): + this_shard_source_queues = { key: self.total_source_queues[key] for key in self.sharded_keys[replica_id] } + #print("keys", replica_id, self.sharded_keys[replica_id]) + + #self.source_queues = { + # key: self.total_source_queues[key] for key in self.sharded_keys[replica_id] + #} while True: - yield simpy.AnyOf(self.env, [q.wait() for q in self.source_queues.values()]) + x = yield simpy.AnyOf(self.env, [q.wait() for q in this_shard_source_queues.values()]) + #print("YIELD", replica_id, x) # choose key - print("env time", self.env.now) chosen_key = self.key_selection_policy.choose( - self.source_queues, - self.env.now*100 + this_shard_source_queues, + replica_id, ) assert chosen_key is not None @@ -330,10 +431,10 @@ def run(self, replica_id: int): # assert total_size_orig == 0 or total_size == total_size_orig, f"Bad queue size {total_size_orig} -> {total_size}" # get chosen key - windows = yield self.source_queues[chosen_key].get() - # print( - # f"at time {self.env.now:.2f}, RalfMapper should work on {windows} (last timestamp), queue size {total_size}, wait time {self.model_runtime_s}" - # ) + windows = yield this_shard_source_queues[chosen_key].get() + print( + f"at time {self.env.now:.2f}, RalfMapper replica {replica_id} should work on {windows} (last timestamp), wait time {self.model_runtime_s}" + ) edits = [(val, windows.key) for val in windows.window[0].value] if self.env.now in self.ready_time_to_batch: @@ -379,19 +480,6 @@ def run(self, replica_id: int): init_data = json.load(open(init_data_file)) keys = list(init_data.keys()) -policies = { - "fifo": fifo, - "lifo": lifo, - "always_process": always_process, - "sample_half": make_sampling_policy(0.5), - "weighted_random": WeightedLoadBalancer(pageview_file), - "adaptive_weighted_random": AdaptiveWeightedLoadBalancer(timestamp_weights_file), - "weighted_longest_queue": WeightedLongestQueueLoadBalancer(pageview_file), - "longest_queue": LongestQueueLoadBalancer(), - "random": RandomLoadBalancer(), - "round_robin": RoundRobinLoadBalancerFix(), - "weighted_round_robin": WeightedRoundRobin(pageview_file, keys) -} def run_once( out_path: str, @@ -405,6 +493,14 @@ def run_once( num_replicas: int, ): + policies = { + "fifo": fifo, + "lifo": lifo, + "always_process": always_process, + "round_robin": RoundRobinLoadBalancer(num_replicas=num_replicas), + "weighted_round_robin": WeightedRoundRobinLoadBalancer(keys, num_replicas=num_replicas) + } + env = simpy.Environment() source_to_window_queue = simpy.Store(env) From f28a429dee552c759caeb3a1c2a6c4b62cfc67cd Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Thu, 14 Oct 2021 23:09:05 -0700 Subject: [PATCH 17/26] stash --- stl/offline/run_1_simulate_windows.sh | 3 ++- stl/offline/run_2_eval_yahoo_keys.sh | 2 +- stl/offline/simulation.py | 3 +-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/stl/offline/run_1_simulate_windows.sh b/stl/offline/run_1_simulate_windows.sh index e195c39..a25823e 100644 --- a/stl/offline/run_1_simulate_windows.sh +++ b/stl/offline/run_1_simulate_windows.sh @@ -1,6 +1,7 @@ set -ex data_dir="./yahoo_train_data" +result_dir="/data/wooders/stl/results" tmp_script=`mktemp` for key_prio in "lifo" "fifo" @@ -10,7 +11,7 @@ do key=`basename $data` for slide in 6 12 18 24 48 96 168 192 336 672 do - echo \" python simulation.py --model_runtime_s 1.5 --total_runtime_s 2000 --per_key_records_per_second 1 --key_prio_policy ${key_prio} --window_size 672 --slide_size ${slide} --output_path offline_1_slide/plan/${key_prio}_slide_${slide}_plan.json --num_mapper_replicas 1\" >> $tmp_script + echo \" python simulation.py --num_keys 100 --model_runtime_s 1.5 --total_runtime_s 2000 --per_key_records_per_second 1 --key_prio_policy ${key_prio} --window_size 672 --slide_size ${slide} --output_path ${result_dir}/plan/${key_prio}_slide_${slide}_plan.json --num_mapper_replicas 1\" >> $tmp_script done done done diff --git a/stl/offline/run_2_eval_yahoo_keys.sh b/stl/offline/run_2_eval_yahoo_keys.sh index c5f106d..ed2eab8 100644 --- a/stl/offline/run_2_eval_yahoo_keys.sh +++ b/stl/offline/run_2_eval_yahoo_keys.sh @@ -17,7 +17,7 @@ do done done -cat $tmp_script | xargs -n 1 -P 36 bash -l -c +cat $tmp_script | xargs -n 1 -P 144 bash -l -c #set -ex diff --git a/stl/offline/simulation.py b/stl/offline/simulation.py index 476167d..6431293 100644 --- a/stl/offline/simulation.py +++ b/stl/offline/simulation.py @@ -81,8 +81,7 @@ def main(argv): else: keys = [i+1 for i in range(FLAGS.num_keys)] - print("keys", keys) - + print(FLAGS.key_prio_policy) source_to_window_queue = simpy.Store(env) windows_to_mapper_queue = { key: PerKeyPriorityQueue( From 3042b0c379229c8d8afe36b54acb0a6b71f92136 Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Thu, 14 Oct 2021 15:19:33 -0700 Subject: [PATCH 18/26] try lp 500 --- stl/offline/config_gen.py | 6 ++-- stl/offline/default_plans.py | 8 +++++ stl/offline/evaluate_loss.py | 48 ++++++++++++++++++++++++++ stl/offline/log_data.py | 45 ++++++++++++++++++++++++ stl/offline/run_4_generate_plan.sh | 6 ++-- stl/offline/run_6_simulate_baseline.sh | 2 +- 6 files changed, 108 insertions(+), 7 deletions(-) create mode 100644 stl/offline/default_plans.py create mode 100644 stl/offline/evaluate_loss.py create mode 100644 stl/offline/log_data.py diff --git a/stl/offline/config_gen.py b/stl/offline/config_gen.py index 58ebca5..91f9bf4 100644 --- a/stl/offline/config_gen.py +++ b/stl/offline/config_gen.py @@ -119,17 +119,17 @@ def run_lp(df: pd.DataFrame, objective="min_loss"): def get_loss_per_key(key: int, csv_dir): - key_one = glob(f"{csv_dir}/slide_*_key_A4Benchmark-TS{key}.csv") + key_one = glob(f"{csv_dir}/fifo_slide_*_key_{key}.csv") assert len(key_one) > 0 - oracle_residual = pd.read_csv(f"{csv_dir}/oracle_key_A4Benchmark-TS{key}.csv")[ + oracle_residual = pd.read_csv(f"./oracle/{key}.csv")[ "pred_residual" ] losses = [] for path in key_one: slide_size = int( - os.path.basename(path).split("_key_A4")[0].replace("slide_", "") + os.path.basename(path).split("_key_")[0].replace("fifo_slide_", "") ) df = pd.read_csv(path) residual = df["pred_residual"] diff --git a/stl/offline/default_plans.py b/stl/offline/default_plans.py new file mode 100644 index 0000000..8bcd66f --- /dev/null +++ b/stl/offline/default_plans.py @@ -0,0 +1,8 @@ +import json + +plan_dir = "/data/wooders/stl/results" +slides = [1, 6, 12, 18, 24, 48, 96, 168, 192, 336, 672] + +for slide in slides: + weights = {i: slide for i in range(1, 101, 1)} + open(f"{plan_dir}/plan_baseline_{slide}.json", "w").write(json.dumps(weights)) diff --git a/stl/offline/evaluate_loss.py b/stl/offline/evaluate_loss.py new file mode 100644 index 0000000..29d0242 --- /dev/null +++ b/stl/offline/evaluate_loss.py @@ -0,0 +1,48 @@ +from sktime.performance_metrics.forecasting import mean_squared_scaled_error +import numpy as np +import pandas as pd +from tqdm import tqdm +import argparse + +def get_loss_per_key(key: int, csv_dir, oracle_dir): + path = f"{csv_dir}/{key}.csv" + + oracle_residual = pd.read_csv(f"{oracle_dir}/oracle_key_A4Benchmark-TS{key}.csv")[ + "pred_residual" + ] + + df = pd.read_csv(path) + print(path) + residual = df["pred_residual"] + print("residual", len(residual.tolist())) + mask = ~np.isnan(residual) + print("residual", len(residual[mask].tolist())) + loss = mean_squared_scaled_error( + y_true=oracle_residual[mask], y_pred=residual[mask], y_train=df["value"] + ) + loss = { + "loss": loss, + "n_fits": df["model_version"].dropna().nunique(), + } + return loss + + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Specify experiment config") + parser.add_argument("--csv-path", type=str) + parser.add_argument("--oracle-path", type=str) + args = parser.parse_args() + + raw_data = [] + for key in tqdm(range(1, 101)): + entry = get_loss_per_key(key, csv_dir=args.csv_path, oracle_dir=args.oracle_path) + raw_data.append({"key": key, **entry}) + + df = pd.DataFrame(raw_data) + print("loss per n_fits") + print(df.groupby("n_fits")["loss"].describe()) + print(f"loss per key (sample of 10 out of {len(df)})") + print(df.groupby("key")["loss"].describe().sample(10)) + df.to_csv("final_results.csv") + diff --git a/stl/offline/log_data.py b/stl/offline/log_data.py new file mode 100644 index 0000000..b8eb566 --- /dev/null +++ b/stl/offline/log_data.py @@ -0,0 +1,45 @@ +import wandb +import configparser +import os + + +def log_experiment(run, config): + # log experiment output + artifact = wandb.Artifact("results", type='dataset') + artifact.add_dir("/data/wooders/stl/results") + run.log_artifact(artifact) + +def log_train(run, config): + # log experiment output + artifact = wandb.Artifact("yahoo_train_data", type='dataset') + artifact.add_dir("yahoo_train_data") + run.log_artifact(artifact) + +def log_eval(run, config): + # log experiment output + artifact = wandb.Artifact("yahoo_eval_data", type='dataset') + artifact.add_dir("yahoo_eval_data") + run.log_artifact(artifact) + +def log_oracle(run, config): + # log experiment output + artifact = wandb.Artifact("oracle", type='dataset') + artifact.add_dir("oracle") + run.log_artifact(artifact) + + + +if __name__ == "__main__": + + print("Running wandb logging on data") + run = wandb.init(job_type="dataset-creation", project="stl") + + # configuration file + config = configparser.ConfigParser() + config.read("config.yml") + + log_experiment(run, config) + log_train(run, config) + log_eval(run, config) + log_oracle(run, config) + diff --git a/stl/offline/run_4_generate_plan.sh b/stl/offline/run_4_generate_plan.sh index 0769b1f..ef514b5 100644 --- a/stl/offline/run_4_generate_plan.sh +++ b/stl/offline/run_4_generate_plan.sh @@ -7,9 +7,9 @@ set -ex # --csv_dir "./result/offline_1_slide/plan_eval" \ # --output_path "./result/offline_1_slide/min_loss_plan.json" -MAX_FITS=8400 +MAX_FITS=500 python config_gen.py \ - --csv_dir "./offline_1_slide/plan_eval" \ - --output_path "./offline_1_slide/max_fits_${MAX_FITS}.json" \ + --csv_dir "/data/wooders/stl/results/single_key" \ + --output_path "/data/wooders/stl/results/max_fits_${MAX_FITS}.json" \ --max_n_fits ${MAX_FITS} diff --git a/stl/offline/run_6_simulate_baseline.sh b/stl/offline/run_6_simulate_baseline.sh index f70fabf..c0cb4ed 100644 --- a/stl/offline/run_6_simulate_baseline.sh +++ b/stl/offline/run_6_simulate_baseline.sh @@ -4,7 +4,7 @@ PLAN_DIR="/data/wooders/stl/results" TRAIN_PATH="./yahoo_train_data" EVAL_PATH="./yahoo_eval_data" -for key_policy in "lifo" "fifo" +for key_policy in "fifo" do for replicas in 1 2 4 8 do From 6fed8980016cb838d4c27803764cd49db8e4c747 Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Thu, 14 Oct 2021 21:47:40 -0700 Subject: [PATCH 19/26] notebook --- stl/notebooks/STL Offline Plots.ipynb | 70 ++++---- wikipedia/notebooks/Wikipedia Plots.ipynb | 200 +++++++++++++--------- wikipedia/run_1_generate_plan.sh | 4 +- wikipedia/run_2_prepare_data.sh | 2 +- wikipedia/run_3_run_predictions.sh | 13 +- wikipedia/simulate.py | 5 +- 6 files changed, 169 insertions(+), 125 deletions(-) diff --git a/stl/notebooks/STL Offline Plots.ipynb b/stl/notebooks/STL Offline Plots.ipynb index 4b561e5..428ec9f 100644 --- a/stl/notebooks/STL Offline Plots.ipynb +++ b/stl/notebooks/STL Offline Plots.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 232, + "execution_count": 351, "id": "642f67ca", "metadata": {}, "outputs": [], @@ -22,14 +22,14 @@ }, { "cell_type": "code", - "execution_count": 252, + "execution_count": 352, "id": "0df714c8", "metadata": {}, "outputs": [ { "data": { "text/html": [ - "Finishing last run (ID:2od4u8d0) before initializing another..." + "Finishing last run (ID:29jne90e) before initializing another..." ], "text/plain": [ "" @@ -41,7 +41,7 @@ { "data": { "text/html": [ - "
Waiting for W&B process to finish, PID 80915... (success)." + "
Waiting for W&B process to finish, PID 56004... (success)." ], "text/plain": [ "" @@ -58,7 +58,7 @@ "version_minor": 0 }, "text/plain": [ - "VBox(children=(Label(value=' 0.26MB of 0.26MB uploaded (0.00MB deduped)\\r'), FloatProgress(value=1.0, max=1.0)…" + "VBox(children=(Label(value=' 0.51MB of 0.51MB uploaded (0.00MB deduped)\\r'), FloatProgress(value=1.0, max=1.0)…" ] }, "metadata": {}, @@ -76,8 +76,8 @@ "
\n", "
\n", "Synced 7 W&B file(s), 0 media file(s), 0 artifact file(s) and 1 other file(s)\n", - "
Synced restful-butterfly-20: https://wandb.ai/ucb-ralf/experiments-stl_notebooks/runs/2od4u8d0
\n", - "Find logs at: ./wandb/run-20211014_021333-2od4u8d0/logs
\n" + "
Synced drawn-morning-23: https://wandb.ai/ucb-ralf/experiments-stl_notebooks/runs/29jne90e
\n", + "Find logs at: ./wandb/run-20211014_214005-29jne90e/logs
\n" ], "text/plain": [ "" @@ -89,7 +89,7 @@ { "data": { "text/html": [ - "Successfully finished last run (ID:2od4u8d0). Initializing new run:
" + "Successfully finished last run (ID:29jne90e). Initializing new run:
" ], "text/plain": [ "" @@ -110,7 +110,7 @@ "data": { "text/html": [ "\n", - " Syncing run avid-flower-21 to Weights & Biases (docs).
\n", + " Syncing run vocal-terrain-24 to Weights & Biases (docs).
\n", "\n", " " ], @@ -147,7 +147,7 @@ }, { "cell_type": "code", - "execution_count": 253, + "execution_count": 353, "id": "0eedb687", "metadata": {}, "outputs": [], @@ -157,17 +157,17 @@ }, { "cell_type": "code", - "execution_count": 254, + "execution_count": 354, "id": "975d3b68", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[]" + "[]" ] }, - "execution_count": 254, + "execution_count": 354, "metadata": {}, "output_type": "execute_result" }, @@ -189,17 +189,17 @@ }, { "cell_type": "code", - "execution_count": 256, + "execution_count": 355, "id": "c37f7834", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[]" + "[]" ] }, - "execution_count": 256, + "execution_count": 355, "metadata": {}, "output_type": "execute_result" }, @@ -221,7 +221,7 @@ }, { "cell_type": "code", - "execution_count": 257, + "execution_count": 356, "id": "b3c30d2e", "metadata": {}, "outputs": [], @@ -231,17 +231,17 @@ }, { "cell_type": "code", - "execution_count": 258, + "execution_count": 357, "id": "93a15c67", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[]" + "[]" ] }, - "execution_count": 258, + "execution_count": 357, "metadata": {}, "output_type": "execute_result" }, @@ -270,7 +270,7 @@ }, { "cell_type": "code", - "execution_count": 259, + "execution_count": 358, "id": "5fecde25", "metadata": {}, "outputs": [], @@ -297,10 +297,22 @@ }, { "cell_type": "code", - "execution_count": 125, + "execution_count": 359, "id": "21099224", "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "TypeError", + "evalue": "get_loss_per_key() missing 1 required positional argument: 'oracle_filename'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mbaseline_results\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mkey\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m101\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mlosses\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_loss_per_key\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34mf\"{artifact_dir}/plan_eval\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0mbaseline_results\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlosses\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mTypeError\u001b[0m: get_loss_per_key() missing 1 required positional argument: 'oracle_filename'" + ] + } + ], "source": [ "replica = 1\n", "baseline_results = {}\n", @@ -311,18 +323,10 @@ }, { "cell_type": "code", - "execution_count": 139, + "execution_count": null, "id": "d82f9ca7", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "8400 78.42078584418643\n" - ] - } - ], + "outputs": [], "source": [ "slide_size = 12\n", "baseline_total_cost = 0\n", diff --git a/wikipedia/notebooks/Wikipedia Plots.ipynb b/wikipedia/notebooks/Wikipedia Plots.ipynb index e417120..ad9d8b5 100644 --- a/wikipedia/notebooks/Wikipedia Plots.ipynb +++ b/wikipedia/notebooks/Wikipedia Plots.ipynb @@ -608,17 +608,17 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 217, "id": "101571e2", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "'./artifacts/prediction_results:v3620'" + "'/home/eecs/wooders/DPR'" ] }, - "execution_count": 25, + "execution_count": 217, "metadata": {}, "output_type": "execute_result" } @@ -629,7 +629,7 @@ }, { "cell_type": "code", - "execution_count": 180, + "execution_count": 218, "id": "03e14929", "metadata": {}, "outputs": [], @@ -639,16 +639,16 @@ }, { "cell_type": "code", - "execution_count": 181, + "execution_count": 219, "id": "eaf30e01", "metadata": {}, "outputs": [], "source": [ - "#constants = [0.01, 0.05, 1.0, 10.0]\n", - "constants = [0.25]\n", - "policies = [\"lifo\"]\n", - "key_policies = [\"random\", \"weighted_random\", \"round_robin\", \"weighted_round_robin\"]\n", - "#key_policies = [\"random\", \"round_robin\"]\n", + "constants = [0.01, 0.05, 1.0, 10.0]\n", + "#constants = [0.25]\n", + "policies = [\"lifo\", \"fifo\"]\n", + "#key_policies = [\"random\", \"weighted_random\", \"round_robin\", \"weighted_round_robin\"]\n", + "key_policies = [\"round_robin\"]\n", "#key_policies = [\"weighted_random\", \"weighted_round_robin\"]\n", "d = artifact_dir\n", "metric = 'top10'" @@ -656,7 +656,7 @@ }, { "cell_type": "code", - "execution_count": 182, + "execution_count": 231, "id": "96209574", "metadata": {}, "outputs": [ @@ -664,28 +664,45 @@ "name": "stdout", "output_type": "stream", "text": [ - "/home/eecs/wooders/DPR/plan-random_lifo-always_process-0.25-100.json\n", - "/home/eecs/wooders/DPR/plan-weighted_random_lifo-always_process-0.25-100.json\n", - "/home/eecs/wooders/DPR/plan-round_robin_lifo-always_process-0.25-100.json\n", - "/home/eecs/wooders/DPR/plan-weighted_round_robin_lifo-always_process-0.25-100.json\n" + "/home/eecs/wooders/DPR/plan-round_robin_fifo-always_process-0.01-100.json\n", + "/home/eecs/wooders/DPR/plan-round_robin_fifo-always_process-0.05-100.json\n", + "/home/eecs/wooders/DPR/plan-round_robin_fifo-always_process-1.0-100.json\n", + "/home/eecs/wooders/DPR/plan-round_robin_fifo-always_process-10.0-100.json\n", + "/home/eecs/wooders/DPR/plan-round_robin_lifo-always_process-0.01-100.json\n", + "/home/eecs/wooders/DPR/plan-round_robin_lifo-always_process-0.05-100.json\n", + "/home/eecs/wooders/DPR/plan-round_robin_lifo-always_process-1.0-100.json\n", + "/home/eecs/wooders/DPR/plan-round_robin_lifo-always_process-10.0-100.json\n" ] }, { "data": { "text/plain": [ - "{'plan-random_lifo-always_process': [0.7078732804419647],\n", - " 'plan-weighted_random_lifo-always_process': [0.6361795795371613],\n", - " 'plan-round_robin_lifo-always_process': [0.6167886934890254],\n", - " 'plan-weighted_round_robin_lifo-always_process': [0.5987554048857813]}" + "{'plan-round_robin_fifo-always_process': [0.39603393208873827,\n", + " 0.6827773461716538,\n", + " 0.8776121979738054,\n", + " 0.8791895221727837],\n", + " 'plan-round_robin_lifo-always_process': [0.39388374885232,\n", + " 0.46513799624895036,\n", + " 0.8024342585399157,\n", + " 0.8759956368544546]}" ] }, - "execution_count": 182, + "execution_count": 231, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "all_results = {}\n", + "constants = [0.01, 0.05, 1.0, 10.0]\n", + "#constants = [0.25]\n", + "policies = [\"fifo\", \"lifo\"]\n", + "#key_policies = [\"random\", \"weighted_random\", \"round_robin\", \"weighted_round_robin\"]\n", + "key_policies = [\"round_robin\"]\n", + "#key_policies = [\"weighted_random\", \"weighted_round_robin\"]\n", + "d = artifact_dir\n", + "metric = 'top10'\n", + "\n", + "event_results = {}\n", "for policy in policies: \n", " for key_policy in key_policies: \n", " scores = []\n", @@ -695,96 +712,115 @@ " with open(f'{d}/{name}-{constant}-100.json') as results_file:\n", " results = json.load(results_file)\n", " scores.append(1-results[metric])\n", - " all_results[name] = scores\n", - "all_results" + " event_results[name] = scores\n", + "event_results" ] }, { "cell_type": "code", - "execution_count": 106, - "id": "b479a2bc", - "metadata": { - "scrolled": true - }, + "execution_count": 232, + "id": "332c0ff6", + "metadata": {}, "outputs": [ { "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAmgAAAFCCAYAAABFMCGEAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAA3oUlEQVR4nO3deVxU9f7H8dcwgIJLConiirskLrhboqZezYRwySXTUpNSKsrKXXHL3HPLJc2dzLQ0Fc0sy27d3MXU0NxTZDFBNBe2YX5/WNwfF0RcGI7wfj4ePh4z53znnM/MfIG337N8TVar1YqIiIiIGIZdbhcgIiIiIukpoImIiIgYjAKaiIiIiMEooImIiIgYjAKaiIiIiMHkmYBmtVpJTExEF6WKiIjIoy7PBLSkpCSOHj1KUlJSbpciIiIi8kDyTEATERERySsU0EREREQMRgFNRERExGAU0EREREQMRgFNRERExGAU0EREREQMRgFNRERExGAU0EREREQMRgFNRERExGAU0EREREQMRgFNRERExGAU0ICkZEtul5Cj8vr7ExERyWvsc7sAI3B0MNMzeGdul5FjQoKfBMy5XUaOSU1Jws7e0Wb7S0q24OiQNz/PvPzeREQeJQpo+YCdvSMnpvfJ7TJyTLX3ltt0f3k50K8e3zK3SxAREXSIU0RERMRwFNBEREREDEYBTURERMRgFNBEREREDEYBTURERMRgFNBEREREDEYBTURERMRgFNBEREREDEYBTURERMRgFNBEREREDEYBTURERMRgFNBEREREDEYBTURERMRgFNBEREREDEYBTURERMRgFNBEREREDEYBTURERMRg7G21o7NnzzJs2DDi4+MpVqwYU6ZMwcPDI12b2NhYhg8fTlRUFMnJyTRp0oRRo0Zhb2+zMkVERERync1G0MaMGUPPnj355ptv6NmzJ8HBwRnaLFy4kMqVK7N582Y2b97Mb7/9xvbt221VooiIiIgh2CSgxcbGEh4ejq+vLwC+vr6Eh4cTFxeXrp3JZOLGjRukpqaSlJREcnIyJUuWtEWJIiIiIoZhk4AWFRVFyZIlMZvNAJjNZtzc3IiKikrXLjAwkLNnz9KsWbO0f/Xr17dFiSICpKYk5XYJOSqvvz8RyTsMdXLXtm3bqF69OitWrODGjRsEBASwbds2nnnmmWxv4+jRo/e8X4XAR9+BAwdstq+83F/s7B05Mb1PbpeRY6q9t9ymfUVEJCtZ/T2xSUBzd3cnJiYGi8WC2WzGYrFw6dIl3N3d07ULCQnhgw8+wM7OjiJFitCqVSv27NlzTwHNy8uLAgUKPOy3IAaXl0OTPFzqKyLyKLDJIU5XV1c8PT0JDQ0FIDQ0FE9PT1xcXNK1K1u2LP/+978BSEpKYteuXVStWtUWJYqIiIgYhs2u4hw7diwhISG0a9eOkJAQxo0bB0BAQABHjhwBYMSIERw4cAA/Pz86duyIh4cH3bp1s1WJIiIiIoZgs3PQKleuzLp16zIsX7x4cdrj8uXLs2zZMluVJCIiImJImklARERExGAU0EREREQMRgFNRERExGAU0EREREQMRgFNRERExGAU0EREREQMRgFNRERExGAU0EREREQMRgFNRERExGAU0EREREQMRgFNRERExGAU0EREREQMRgFNRERExGAU0EREREQMRgFNRERExGAU0EREREQMRgFNRERExGAU0EREREQMRgFNRERExGAU0EREREQMRgFNRERExGAU0EREREQMRgFNRERExGAU0EREREQMRgFNRERExGAU0EREREQMRgFNRERExGAU0EREREQMRgFNRERExGAU0EREckhSsiW3S8hRef39ieQm+9wuQEQkr3J0MNMzeGdul5FjVo9vmdsliORZGkETERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRibBbSzZ8/SvXt32rVrR/fu3Tl37lym7bZu3Yqfnx++vr74+flx+fJlW5UoIiIiYgj2ttrRmDFj6NmzJ/7+/mzcuJHg4GBWrlyZrs2RI0f46KOPWLFiBSVKlOCvv/7C0dHRViWKiIiIGIJNRtBiY2MJDw/H19cXAF9fX8LDw4mLi0vXbvny5fTr148SJUoAUKRIEQoUKGCLEkVEREQMwyYBLSoqipIlS2I2mwEwm824ubkRFRWVrt3p06e5cOECL774Ip06dWL+/PlYrVZblCgiIiJiGDY7xJkdFouF33//nWXLlpGUlET//v0pXbo0HTt2zPY2jh49es/7rV+//j2/RozlwIEDNtuX+sujTX3l4bLl5ymS12T1O8ImAc3d3Z2YmBgsFgtmsxmLxcKlS5dwd3dP16506dI888wzODo64ujoSOvWrTl8+PA9BTQvLy8dFs2H8sMfQnk41FceLn2eIjnDJoc4XV1d8fT0JDQ0FIDQ0FA8PT1xcXFJ187X15eff/4Zq9VKcnIyu3fvpkaNGrYoUURERMQwbHabjbFjxxISEkK7du0ICQlh3LhxAAQEBHDkyBEAOnTogKurK88++ywdO3akSpUqPP/887YqUURERMQQbHYOWuXKlVm3bl2G5YsXL057bGdnx/Dhwxk+fLityhIRERExHM0kICIiImIwCmgiIiIiBpOtgJaamprTdYiIiIjI3+4a0CwWC3Xr1iUpKckW9YiIiIjke3cNaGazGQ8PD65cuWKLekRERETyvWxdxenn58eAAQN46aWXKFWqVLp1TZs2zZHCRERERPKrbAW0zz77DIC5c+emW24ymdixY8fDr0pEREQkH8tWQPv+++9zug4RERER+Vu2b1SbkpJCWFgYMTExlCpVirp162Jvb6i51kVERETyhGwlrNOnTzNw4EASEhJwd3cnKiqKAgUKsHDhQipXrpzTNYqIiIjkK9kKaOPGjaNbt2688sormEwmAJYsWcLYsWNZtWpVjhYoIiIikt9k60a1x48fp2/fvmnhDODll1/m+PHjOVaYiIiISH6VrYDm5ubG3r170y3bv38/bm5uOVKUiIiISH6WrUOcgwYNIjAwkJYtW1K6dGkiIyPZuXMn06ZNy+n6RERERPKdbI2gPf3002zYsIGqVaty48YNqlatyvr162nTpk1O1yciIiKS79x1BM1iseDt7c3+/fsJDAy0RU0iIiIi+Zrm4hQRERExGM3FKSIiImIwmotTRERExGDuGtBSU1OZOHEi9evXx9HR0RY1iYiIiORrdz0Hzc7OjsDAQIUzERERERvJ1m02GjZsyKFDh3K4FBERERGBbJ6DVrp0aQICAmjdujWlSpVKN+XTW2+9lWPFiYiIiORH2QpoiYmJaTeljYmJydGCRERERPK7bAW0SZMm5XQdIiIiIvK3LM9B+/rrr9M9P3PmTLrny5cvf+gFiYiIiOR3WQa0kSNHpnveo0ePdM/nzJnz8CsSERERyeeyDGhWq/WenouIiIjIg8syoP3/qzWz81xEREREHtxdLxKwWq1p/zJ7LiIiIiIPV5YB7ebNmzzxxBNpz61Wa9pzq9WqETQRERGRHJBlQNNE6CIiIiK2l2VAK1OmjK3qEBEREZG/ZWsuThERERGxHQU0ERG5L6kpSbldQo7K6+9PjC1bUz2JiIj8Lzt7R05M75PbZeSYau8tz+0SJB/TCJqIiIiIwdx1BO3zzz9nw4YNnDx5kps3b+Ls7EzVqlXp3Lkz3bp1s0WNIiIiIvlKlgFt2rRp7Ny5k759+1KjRg2KFCnC9evXOXbsGMuXL+fChQu8++67tqpVREREJF/IMqB9+eWXbNq0CTc3t3TLa9asiY+PD88995wCmoiIiMhDdk+TpYuIiIhIzstyBO3555/n5Zdfpl+/flSvXj3tEOfx48dZvnw5Xbt2tVWdIiIiIvlGlgFt8ODBlCtXji+//JJTp06lXSRQpUoVevfuTY8ePWxVp4iIiEi+cderOHv06KEgJiIiImJDD3QftMjIyIdVh4iIiIj87b4DWlJSEq1bt36YtYiIiIgIdznEuW/fvjuuS0rSHGUiIiIiOSHLgNa7d29KlCiBnZ1mhBIRERGxlSwDWunSpZk+fTr16tXLsC4xMZG6devmVF0iIiIi+VaWQ2NeXl4cPXo003Umkwl3d/ccKUpEREQkP8syoM2YMYMXXngh03WOjo58//332d7R2bNn6d69O+3ataN79+6cO3fujm3PnDlDnTp1mDJlSra3LyIiIpJXZBnQHBwccHBweCg7GjNmDD179uSbb76hZ8+eBAcHZ9rOYrEwZswY2rRp81D2KyIiIvKoydbZ/0lJScyePZu2bdtSt25d2rZty6xZs0hMTMzWTmJjYwkPD8fX1xcAX19fwsPDiYuLy9B20aJFtGzZEg8Pj+y/CxEREZE8JFsBbezYsezevZuRI0fyxRdfMHLkSPbt28fYsWOztZOoqChKliyJ2WwGwGw24+bmRlRUVLp2x48f5+eff6ZPnz739CZERERE8pK7TvUEsGPHDr799luKFi0KQJUqVahTpw5t27Z9aIUkJyczevRoJk2alBbk7sedLmrISv369e97f2IMBw4csNm+1F8ebeorci9s2V8k/8nqd0S2Atrjjz/OrVu30gIa3L7NRokSJbJVgLu7OzExMVgsFsxmMxaLhUuXLqW7CvTPP//k/PnzvPrqqwBcu3YNq9XK9evXmTBhQrb2A7evPC1QoEC220veoD+Ekl3qK3IvbNlfkpItODrc/wCFkaUmJ2Hn4JjbZeSY1JQk7Owf7vvLVkDz9/enf//+9O7dm5IlSxIdHc2nn36Kv78/u3btSmvXtGnTTF/v6uqKp6cnoaGh+Pv7ExoaiqenJy4uLmltSpcuzZ49e9Kez507l5s3bzJ06ND7fW8iIiKPDEcHMz2Dd+Z2GTli9fiWnJjeJ7fLyDHV3lv+0LeZrYC2Zs0aABYuXJhh+T/rTCYTO3bsuOM2xo4dy7Bhw5g/fz5FixZNu4VGQEAAQUFB1KpV677egIiIiEhek62Adi/3O7uTypUrs27dugzLFy9enGn7N99884H3KSIiIvIoylZAA0hJSSEsLIyYmBhKlSpF3bp1sbfP9stFREREJJuylbBOnz7NwIEDSUhIwN3dnaioKAoUKMDChQupXLlyTtcoIiIikq9kK6CNGzeObt268corr2AymQBYsmQJY8eOZdWqVTlaoIiIiEh+k60b1R4/fpy+ffumhTOAl19+mePHj+dYYSIiIiL5VbYCmpubG3v37k23bP/+/bi5ueVIUSIiIiL5WbYOcQ4aNIjAwEBatmxJ6dKliYyMZOfOnUybNi2n6xMRERHJd7I1gta6dWvWr19P1apVuXHjBlWrVmX9+vW0adMmp+sTERERyXeyNYK2ZMkSXnnlFQIDA9MtX7ZsGX379s2RwkRERETyq2yNoM2bNy/T5QsWLHioxYiIiIjIXUbQ/plnMzU1ld27d2O1WtPWRUREUKhQoZytTkRERCQfyjKgjRw5EoDExERGjBiRttxkMlGiRAlGjRqVs9WJiIiI5ENZBrR/5uAcMmQIU6dOtUlBIiIiIvldts5BUzgTERERsZ1sBTQRERERsR0FNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRh7W+3o7NmzDBs2jPj4eIoVK8aUKVPw8PBI12bevHls3boVs9mMvb09gwYNwsfHx1YlioiIiBiCzQLamDFj6NmzJ/7+/mzcuJHg4GBWrlyZrk3t2rXp168fTk5OHD9+nF69evHzzz9TsGBBW5UpIiIikutscogzNjaW8PBwfH19AfD19SU8PJy4uLh07Xx8fHBycgKgevXqWK1W4uPjbVGiiIiIiGHYZAQtKiqKkiVLYjabATCbzbi5uREVFYWLi0umr/nqq68oX748pUqVuqd9HT169J7rq1+//j2/RozlwIEDNtuX+sujTX1F7oX6i2TX/fSVrL5zmx3ivBd79+5l9uzZLF269J5f6+XlRYECBXKgKjEy/WKT7FJfkXuh/iLZ9bD7ik0Ocbq7uxMTE4PFYgHAYrFw6dIl3N3dM7QNCwtj8ODBzJs3j0qVKtmiPBERERFDsUlAc3V1xdPTk9DQUABCQ0Px9PTMcHjz8OHDDBo0iDlz5lCzZk1blCYiIiJiODa7D9rYsWMJCQmhXbt2hISEMG7cOAACAgI4cuQIAOPGjSMhIYHg4GD8/f3x9/fn999/t1WJIiIiIoZgs3PQKleuzLp16zIsX7x4cdrjL7/80lbliIiIiBiWZhIQERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDsdlk6bkpOTmZiIgIEhIS7thmYPvHbFiRbR07doxkn1dyu4wcc+zYMZvvM6/2l0eir1itmK7H4vDbduySb+V2NSIiOSJfBLSIiAiKFCmCh4cHJpMp0zZnLv5l46psp1KZIiREn83tMnJMwVIVbb7PvNpfHoW+YrVauXLdlVigwKGNuV2OiEiOyBeHOBMSEnB1db1jOBORR4fJZKJ4YSeshV1zuxQRkRyTLwIaoHAmkoeYTCbQz7SI5GH54hDn/0pKtuDoYE63rFKZIg+83VuJKURd1jkxIiIi8mDyZUBzdDDTM3jnQ9/u6vEtH/o2RUREJP/JN4c4HxXtWzXg1q2buV3GA7kYFU2L57o9tO0tWLaKGfMX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\n", "text/plain": [ - "dict_keys(['plan-random_lifo-always_process', 'plan-weighted_random_lifo-always_process', 'plan-round_robin_lifo-always_process', 'plan-weighted_round_robin_lifo-always_process', 'plan-random_fifo-always_process', 'plan-weighted_random_fifo-always_process', 'plan-round_robin_fifo-always_process', 'plan-weighted_round_robin_fifo-always_process'])" + "
" ] }, - "execution_count": 106, "metadata": {}, - "output_type": "execute_result" + "output_type": "display_data" } ], "source": [ - "all_results.keys()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "332c0ff6", - "metadata": {}, - "outputs": [], - "source": [ - "plan_weighted_random_lifo = []\n", - "for constant in constants:\n", - " with open(f'{d}/plan-weighted_random_lifo-always_process-{constant}-100.json') as results_file:\n", - " results = json.load(results_file)\n", - " plan_weighted_random_lifo.append(results[metric])\n", - "print(plan_weighted_random_lifo)\n", - " \n", - "plan_weighted_longest_queue_lifo = []\n", - "for constant in constants:\n", - " with open(f'{d}/plan-weighted_longest_queue_lifo-always_process-{constant}-100.json') as results_file:\n", - " results = json.load(results_file)\n", - " plan_weighted_longest_queue_lifo.append(results[metric])\n", - "print(plan_weighted_longest_queue_lifo)\n", - "\n", - "plan_longest_queue_lifo = []\n", - "for constant in constants:\n", - " with open(f'{d}/plan-longest_queue_lifo-always_process-{constant}-100.json') as results_file:\n", - " results = json.load(results_file)\n", - " plan_longest_queue_lifo.append(results[metric])\n", - "print(plan_longest_queue_lifo)\n", - "\n", - "plan_random_lifo = []\n", - "for constant in constants:\n", - " with open(f'{d}/plan-random_lifo-always_process-{constant}-100.json') as results_file:\n", - " results = json.load(results_file)\n", - " plan_random_lifo.append(results[metric])\n", - "print(plan_random_lifo)\n", - "\n", - "plan_round_robin_lifo = []\n", - "for constant in constants:\n", - " with open(f'{d}/plan-round_robin_lifo-always_process-{constant}-100.json') as results_file:\n", - " results = json.load(results_file)\n", - " plan_round_robin_lifo.append(results[metric])\n", - "print(plan_round_robin_lifo)\n" + "import matplotlib.pyplot as plt\n", + "import seaborn\n", + "resources = [int(10 / c) for c in constants] \n", + "df = pd.DataFrame({\n", + " 'Model Runtime Const': resources, \n", + " **event_results\n", + "})\n", + "fig, ax1 = plt.subplots(figsize=(10, 5))\n", + "tidy = df.melt(id_vars='Model Runtime Const').rename(columns=str.title)\n", + "seaborn.barplot(x='Model Runtime Const', y='Value', hue='Variable', data=tidy, ax=ax1)\n", + "ax1.set(xlabel='Resources', ylabel=f'{metric} Error')\n", + "ax1.legend_.remove()\n", + "plt.legend(loc='lower left')\n", + "seaborn.despine(fig)" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 229, "id": "6d536763", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/home/eecs/wooders/DPR/plan-round_robin_lifo-always_process-0.01-100.json\n", + "/home/eecs/wooders/DPR/plan-round_robin_lifo-always_process-0.05-100.json\n", + "/home/eecs/wooders/DPR/plan-round_robin_lifo-always_process-1.0-100.json\n", + "/home/eecs/wooders/DPR/plan-round_robin_lifo-always_process-10.0-100.json\n", + "/home/eecs/wooders/DPR/plan-weighted_round_robin_lifo-always_process-0.01-100.json\n", + "/home/eecs/wooders/DPR/plan-weighted_round_robin_lifo-always_process-0.05-100.json\n", + "/home/eecs/wooders/DPR/plan-weighted_round_robin_lifo-always_process-1.0-100.json\n", + "/home/eecs/wooders/DPR/plan-weighted_round_robin_lifo-always_process-10.0-100.json\n" + ] + }, + { + "data": { + "text/plain": [ + "{'plan-round_robin_lifo-always_process': [0.39388374885232,\n", + " 0.46513799624895036,\n", + " 0.8024342585399157,\n", + " 0.8759956368544546],\n", + " 'plan-weighted_round_robin_lifo-always_process': [0.39394652792491625,\n", + " 0.44209022922208885,\n", + " 0.6753066365327118,\n", + " 0.7929938554982696]}" + ] + }, + "execution_count": 229, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "from pylab import rcParams\n", - "rcParams['figure.figsize'] = 12, 6" + "constants = [0.01, 0.05, 1.0, 10.0]\n", + "#constants = [0.25]\n", + "policies = [\"lifo\"]\n", + "#key_policies = [\"random\", \"weighted_random\", \"round_robin\", \"weighted_round_robin\"]\n", + "key_policies = [\"round_robin\", \"weighted_round_robin\"]\n", + "#key_policies = [\"weighted_random\", \"weighted_round_robin\"]\n", + "d = artifact_dir\n", + "metric = 'top10'\n", + "\n", + "key_results = {}\n", + "for policy in policies: \n", + " for key_policy in key_policies: \n", + " scores = []\n", + " name = f\"plan-{key_policy}_{policy}-always_process\"\n", + " for constant in constants: \n", + " print(f'{d}/{name}-{constant}-100.json')\n", + " with open(f'{d}/{name}-{constant}-100.json') as results_file:\n", + " results = json.load(results_file)\n", + " scores.append(1-results[metric])\n", + " key_results[name] = scores\n", + "key_results" ] }, { "cell_type": "code", - "execution_count": 183, + "execution_count": 230, "id": "511f1c65", "metadata": {}, "outputs": [ { "data": { - "image/png": "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l19+mU2bNlGuXDlu375NuXLl+PLLL2nUqNHTrk9EREQkx3ngDJrRaKRq1aocPnyYPn36ZEVNIiIiIjma9uIUERERMTPai1NERETEzGgvThEREREz88CAlpyczIcffkj16tWxsbHJippEREREcrQHnoNmaWlJnz59FM5EREREskimbrPh6+tLSEjIUy5FRERERCCT56A5OzvTo0cPGjZsSLFixdJs+fTee+9laqBz584xbNgwrl+/TsGCBQkKCsLFxSXDtmfPnuXVV18lICCAoUOHZqp/ERERkedFpmbQ4uPjadSoERYWFkRFRXHlypXU/2XWmDFjCAgIYMeOHQQEBDB69OgM2xmNRsaMGaOb4IqIiEiOlakZtMmTJz/WINHR0YSFhbF8+XIA/P39mTBhAjExMdjb26dpu3jxYurXr09cXBxxcXGPNa6IiIjIs+i+Ae2bb76hWbNmqT+fPXsWV1fX1J9XrFhBly5dHjhIZGQkRYsWxWAwACk3v3V0dCQyMjJNQDt16hR79+5l5cqVLFiw4GHfCwChoaGP9LpnQfXq1bO7BBERkSx15MiR7C7hqbnf3/X7BrSRI0emCWgdOnTg4MGDqT/PmTMnUwEtMxITExk1ahSTJ09ODXKPwtPTk1y5cj2RmkRERCR75dTJifsGNJPJ9FA/34uTkxNRUVEYjUYMBgNGo5GrV6/i5OSU2ubPP//kwoULvPPOOwDcvHkTk8lEbGwsEyZMyNQ4IiIiIs+D+wa0/16tmZmf76Vw4cJ4eHgQHBxMq1atCA4OxsPDI83yprOzMwcOHEj9ee7cucTFxekqThEREclxHngVp8lkIjk5GaPRmOHPmTV27FhWrVqFn58fq1atYty4cQD06NGDEydOPELpIiIiIs+n+86gxcXFUbFixdSfTSZT6s8mkynTM2gAbm5urF+/Pt3zS5YsybD9u+++m+m+RURERJ4n9w1o2ghdREREJOvdN6AVL148q+oQERERkb9laicBEREREck6CmgiIiIiZkYBTURERMTMKKCJiIiImJkHbpa+du1aNm3axO+//05cXBy2traUK1eONm3a8Prrr2dFjSIiIiI5yn0D2rRp09i9ezddu3alQoUK5MuXj9jYWE6ePMmKFSu4ePEiAwcOzKpaRURERHKE+wa0jRs38tVXX+Ho6Jjm+UqVKlG3bl1atmypgCYiIiLyhN33HLTMboYuIiIiIk/OfWfQXnvtNTp37ky3bt1wd3dPXeI8deoUK1asoF27dllVp4iIiEiOcd+ANnjwYEqWLMnGjRv5448/Ui8SKFu2LJ06daJDhw5ZVaeIiIhIjvHAqzg7dOigICYiIiKShR7rPmgRERFPqg4RERER+dsjB7SEhAQaNmz4JGsRERERER6wxHno0KF7HktISHjixYiIiIjIAwJap06dcHBwwNJSO0KJiIiIZJX7BjRnZ2emT59OtWrV0h2Lj4/H29v7adUlIiIikmPdd2rM09OT0NDQDI9ZWFjg5OT0VIoSERERycnuO4M2Y8aMex6zsbHh+++/f+IFiYiIiOR09w1o1tbWWVWHiIiIiPztgTeqhZQrNhcuXMjWrVu5evUqjo6OvPLKK/Tu3ZtcuXI97RpFREREcpRMBbSxY8dy7tw5Ro4cSfHixbl8+TKLFy8mKiqKyZMnP+0aRURERHKUTAW0Xbt28d1335E/f34AypYti5eXF02aNHmqxYmIiIjkRJm6wVmRIkW4c+dOmufi4+NxcHB4KkWJiIiI5GSZmkFr1aoVb7/9Np06daJo0aJcuXKFzz//nFatWvHzzz+ntqtdu/ZTK1REREQkp8hUQFuzZg0AixYtSvf8P8csLCzYtWvXEy5PREREJOfJVEB7Evc7O3fuHMOGDeP69esULFiQoKAgXFxc0rTZuHEjK1aswNLSkuTkZNq1a8dbb7312GOLiIiIPEsyFdAAkpKSOHbsGFFRURQrVgxvb2+srDL9csaMGUNAQACtWrViy5YtjB49mpUrV6Zp4+fnR5s2bbCwsCA2NpYWLVpQo0YNKlSokPl3JCIiIvKMy1TCOnPmDL179+bu3bs4OTkRGRlJrly5WLRoEW5ubg98fXR0NGFhYSxfvhwAf39/JkyYQExMDPb29qnt8ubNm/r47t27JCYmYmFh8bDvSUREROSZlqmrOMeNG8frr7/Ojz/+yNq1a9mzZw8dOnRg7NixmRokMjKSokWLYjAYADAYDDg6OhIZGZmu7a5du2jevDkvv/wyb7/9Nu7u7pl/NyIiIiLPgUzNoJ06dYrly5enmc3q3LlzuosGnoSGDRvSsGFDIiIi6Nu3L/Xq1cPV1TXTr7/X5u7Pg+rVq2d3CSIiIlnqyJEj2V3CU3O/v+uZCmiOjo4cPHgwzW00Dh8+jKOjY6YKcHJyIioqCqPRiMFgwGg0cvXqVZycnO75GmdnZypXrszu3bsfKqB5enpq+ykREZHnRE6dnMhUQOvfvz99+vShfv36ODs7ExERwe7du5k2bVqmBilcuDAeHh4EBwfTqlUrgoOD8fDwSHP+GaSc6/bPOW0xMTEcOHBAuxWIiIhIjpOpgNawYUO+/PJLvvnmG65evUq5cuUIDAykTJkymR5o7NixDBs2jAULFpA/f36CgoIA6NGjB4GBgVSuXJm1a9eyb98+rKysMJlMvPnmm9SpU+fR3pmIiIjIMypTAW3p0qV0796dPn36pHl++fLldO3aNVMDubm5sX79+nTPL1myJPXxiBEjMtWXiIiIyPMsU1dxzp8/P8PnFy5c+ESLEREREZEHzKD9s89mcnIy+/fvx2QypR67dOkSdnZ2T7c6ERERkRzovgFt5MiRAMTHx6dZfrSwsMDBwYEPPvjg6VYnIiIikgPdN6D9swfnkCFDmDp1apYUJCIiIpLTZeocNIUzERERkayTqYAmIiIiIllHAU1ERETEzCigiYiIiJgZBTQRERERM6OAJiIiImJmFNBEREREzIwCmoiIiIiZUUATERERMTMKaCIiIiJmRgFNRERExMwooImIiIiYGQU0ERERETOjgCYiIiJiZhTQRERERMyMApqIiIiImVFAExERETEzCmgiIiIiZkYBTURERMTMKKCJiIiImBkFNBEREREzo4AmIiIiYmYU0ERERETMjAKaiIiIiJmxyqqBzp07x7Bhw7h+/ToFCxYkKCgIFxeXNG3mz5/Ptm3bMBgMWFlZ0b9/f+rWrZtVJYqIiIiYhSwLaGPGjCEgIIBWrVqxZcsWRo8ezcqVK9O0qVKlCt26dSNPnjycOnWKN998k71795I7d+6sKlNEREQk22VJQIuOjiYsLIzly5cD4O/vz4QJE4iJicHe3j613X9ny9zd3TGZTFy/fp1ixYo91viJiYlcunSJu3fvPlY/5qB3swLZXYI8gpMnT5JYt3t2lyGP6OTJk7Qu0DZLxjIB143X2H97H/Gm+CwZU0TMT5YEtMjISIoWLYrBYADAYDDg6OhIZGRkmoD2X5s3b6ZUqVIPHc5CQ0PTPWdpaYmjoyMODg5YWFg8/BswE3Z2dpy9fCu7y5BH4Fo8H3evnMvuMuQR5S5Whku3LmbJWCaTicI3CkMU/Bj7fZaMKWLOjhw5kt0lPDXVq1e/57EsW+J8GAcPHmT27NksW7bsoV/r6elJrly50jx38uRJnJ2dn+lwJiI5g4WFBXYFbCn4V6HsLkXELNwvxDzPsuQqTicnJ6KiojAajQAYjUauXr2Kk5NTurbHjh1j8ODBzJ8/H1dX1ydWg8KZiDwrLCws0P9jieRsWRLQChcujIeHB8HBwQAEBwfj4eGRbnnzl19+oX///syZM4dKlSplRWkiIiIiZifL7oM2duxYVq1ahZ+fH6tWrWLcuHEA9OjRgxMnTgAwbtw47t69y+jRo2nVqhWtWrXi9OnTT7yWhETjE+/zafYrIiIiOUuWnYPm5ubG+vXr0z2/ZMmS1McbN27MklpsrA0EjN79xPtdPb7+Y/fh7u7O0aNHsbOze/yCnrIh/d+h7eudqFn76d6r7r/jrFy+iNIurrz0chMSExMZP2ogf/11Fe+qvvTsO/CJjyciIpIdzPIiAXl6jMYkDIZn92t/q2uv1Mdn/jjN1agrfLx8XTZWZF6SkoxYWRmyuwwREXlMz+5f6meYu7s7/fr1Y9++fVy7do0BAwbg5+eXrl1QUBAHDx4kMTGRQoUKMWnSJCA/UVciCOzViWYt2nDowD7i797l/cGj8azsna6Pf9q2aP06x44epEGjZjiXKMXKZQtJSIgn2Wik/RvdqN8gZfwh/d+hvHslTob9Qkz0X9R9qRHd3nkXgPPhZ5k1dRxJSUmUcnElISEhdZyIyxeZM3MSN25cw2BpoMvbffGp8QIAzRr48Fa33vy870du3bxB4MCRhBw5yOFD/4cxKYkRY4IoVbpMpj67GUFjKVfeg2rVazL1ww+Iif6Tvj0CeD2gCzVq1WHhnGn8dvpXABo0foXXO3bJsJ9jRw/e8zP4x507cXTp2ILVG7/FYDDwTtd2eHn70Pe9oZw+GcrH82cyc94yfti1nS0bvyAxKRGAt3u9T9VqNdiz+zt2fbuVcZM+AiAhIYFm7Tvz+cdzuHL1TyZ/NB+TyURiUhLvdOpIs0YvZ1jr5cgrBPQMpGXTxhw5foL4+ARG9u9HNS/P1GMdXm3B/iPHaN64IbWqV2XCjDlcu34dg8FAYI+uvFjTB4DjoWHMXPQJcXF3AOjf+21e8K1O+IWLTJ37Mddv3CAxKYk3XnuV1q804c7du4yaNJ0z4RewsjLgUrIE08aNJPzCRUZNnsHd+HiMycm0atqYzh1ey9R3KCIiD6aAlk0sLCxYs2YNZ8+epWPHjvj4+FC4cOE0bXr06MHQoUMBWL9+PdOnT+fdQeMBuHnzBh4Vq9Cle1++3/kNyxfPYcbcjG9LcvPmDUqWLsObXXoCcOvWTabP/gSDwcC1mGje7dWJ6r61yZcvPwB/Xr3CtI+WcCcujm5vtsLvlVYUL1GK6ZNH07JNBxr7+XMy7ASDAv+98erUDz+gmf+r+L3SmvPhZxnyfg8+XrGBggVTbhWQN28+5ixcyU+7dzL+g4EMHz2Zrj36sX7Np6z5fBlDRkx4qM+vRCkX3h/0AZ8sms2cRZ8BsHTxHJJNySxcupa4uNsM6NeNMq7l8K35YrrXly1X4b6fAUCePLaUKOXCb6fDKFrUidy5cvPriRAAQo4dwruaLwDVfWpRv4EfFhYWXLoQzrBBfVi1bhsv1n2ZpYtmcyXyMq7FK7Djhz1UruhBMUcHJn80nzfbvUoLv0aYTCZuxd6+7/u9fuMm5V3LMLBPDw6H/MLQCVPYunpZ6rEypUvRu2snAN7o9R5tWzSjTfOmnAk/T7fAwWxauRiDpYH+oyYwc8IovD0rYjQauR0XR1KSkWETgpj8wVDKlC7J7bg4Or7zLl6VPDh7/gI3Y2PZtHJxyu/SrZT78K3dHEydWr707PxGmudFROTJUEDLJu3atQPA1dWVihUrEhISQsOGDdO02bNnD6tXryYuLo6kpKQ0x/LksU09R6qCR2U+WfjRPceysclFvfqNU3++cf0as6aOJ+LyBQwGK2Jv3eDSxfN4VKwMQJ2XGmJpaYld3ryULF2GyIhLFCxkT3j4GRo2fgUAj4qVcSlTFoC4uNucOfMbjZu2BKC0iyuuZd05FXaCWi/UA6Dey00AcCtXAQsLC2rUqgNA2fIe7Pvph4f/ADMQcuQgPfsNSrmPlF1e6jdoQsjRgxkGtAd9Bv/wqupLyJEDOBZ1ombtuhwPOcyff0Zx7MhBAjqlBNTIiEtMmTiS6L/+xMrKimsx0cTE/IW9fRGatWjD1q838oLPSNZuDqZf97cA8K3qxbLP1xEZdZVaPtWoUrHCfd+btbU1zZs0AMDHuwq5bWwIv3gJO1tbctnY4Pdyyud8Oy6O03+cpXWzvz9vl9K4l3Xll19PYWlpgWvpUnh7VgRSbhidP18+zoSf59z5iwwdPzl1vMTERM6ev4B7WVfOXbjEpFnz8PGuQt3aNQCo7lWZGQuWkJiUhG9VL2pU9Xro70tERO5NAc0MmEymdPdpu3z5MpMnT2bDhg2ULFmSo0ePMmjQoNTj1tbWqY8NBkuMxpQA98Wqpez9cRcA7/QZQDEnZ3Lnzp2m/3kfTaHWC/UYNX4aFhYWvP1WGxIT/t1Sxsbm3xv9Wlpapt6/7l53ZjKZTBk+/98xbWxsUmtNU7ulJcnGJ3P1a8rnmK4KAN7v05nExETy2NoyffYnD/wM/uFdzZfPP12MY1En/F5pjYWlJYf27+XMH6epULEKAFMmjqRH7/68UKc+ycnJtG5Wh8S/l3+b+beh3ztvcKRlU27FxlKzelUA3mz3Ki+9UJP9R44xZfYCXvCtRr+3u2T+vWJK/T7y5Pn3+73fd3GPQ5hMJgoWyM+6pQsyPL555WIOHAlh74FDzF2ygg3LF9HopTpUqeTBz4eOsOzzdWzetoPJHwzNdP0iInJ/OTKgJSQan8gVlxn1a2OduRO0N27cSJ8+fQgPD+fkyZN4eaWdgYiNjcXa2hoHBweSk5NZs2ZNpvrt+GZ3Or7579Jj1JWIdG1ux96iaDEnLCwsOHp4PxGXH7yFjZ1dXlzKuLF713YaNH6F0ydDCT/3R+oxN7fy7NwRTJNmLbl4IZyzZ37D3cMzUzU/KVV9arJj6xYqVvLizp04fvzhW97u9T4AHy34NE3bzH4GHhWrcPbM70T/9SfvDfwAg6UlUyaOpFz5Cqmh8/btWIo5OQOwY9sWEhP/PTevQIGCVK1WgwEDBvBWu9apQSr84iVcSpagZHFnbPPk4avtO+/73hITE9m28wf8mzTk6PFQ4hMScSlVgqt/Radpl9fODveyrny1fSetX2nCufMX+e2Pc1Su6I7B0sC4aR9xPDQMr/8scbqULEnu3Ln4esdOWvg1AuDc+Ys4FLHn9u048ufPR4O6L1DbtxqN277BjVu3uPtnPCWci9GqWRNKlSjO6CkzM/ktiYhIZuTIgJbZEPU0+7WxsaFDhw5cu3aN8ePHpzv/zN3dnaZNm9K8eXOcnZ3x9fXl8OHDT6TOrj36MX92EOu++JQyrmUp41ouU68bOGwcs6aO48v1n1OuvAcV/hPAhoycyJyZk9i0cTUGSwODh49PPf8sqwR0epsFc6bSu3t7IOUigX8uVPhfmf0MrK2tKe9eEYPBgJWVFeUrVCQ29iZeVX1T2/TsM4DxowZRuIgDlb2qkT9/2g3t/Zq3Yt9Pu2jZ9N9l5tUbt3Do2HGsrayxsbFmWGDv+763ggXyc+FSBG/0eo+7d+MJGjUszUzkf03+YCgTZsxh1fovMRgMfDhyMPYFCwIwc8Iops9fzJ27d7G0tGRA77ep5VONOZPHMW3uIj5dswFjcjKFCxVi2tgR/H42nNmLU851MyYn0+2N9jgWKcwnn61h687vsbayxsIChr7bK8NaRETk0ViY7rUm8oyJj48nNDT0nntxenh4ZFNl6T3Ovc60Wfqz54vPPiEp/iZDe771SK//50rNH7/S7USyS1Zulv6PC39cYPONrLk35PNuav2Z7H/vvewuQx5Brdmzs7uEbJMjZ9BEskrPrq9jMBj4bOVyMMZmdzkiIvKMUEDLBk9j+6pn3cH9e/k0g5PUO3fvk3rF57Pon5voOjjk4+6V+we0CTPmcCLsVJrnDAYDXyyeq9kzEZEcRgFNzEKNWnWe6SD2JIwaGJjdJYiIiJnIss3SRURERCRzFNBEREREzIwCmoiIiIiZyZEBLTkp4cGNzKhfERERyVly5EUCllY2/Da9yxPvt/ygFY/dx+PcI+1p+O10GJs2rGboyIn3bRd1JYLAXp1Yu3lXumOxsbf4JvhL2nXo/Eg1dO7YgnGTZqXu/ZmVmjXw4cute8iTx/apjuP1UlN+/mYTtrZ56DtkFMPe603J4s6cv3SZwWMmAdC5Q1uaN27wxMcTERHzkyNn0CTzyrtXfGA4e5DbsbfYsGblE6rowYxPaG/P7DJ/6gRKFk/ZOmrXnn14e3qwbun8JxbOnnXP+vcrIpIZOXIGLbu5u7vTr18/9u3bx7Vr1xgwYAB+fn7p2gUFBXHw4EESExMpVKgQkyZNAvKnzlY1a9GGQwf2EX/3Lu8PHo1nZe90fSxfMo98+fLzWoe32LP7O6ZMGMHqDTsoWMieUcMCad02gOq+tTi4fy9rP19GQkICVtbWvNNnAB4VK/NLyGE+WTSbOYs+A+CrTWvZ8uUa7PLmw7fmiwRvXpdm1mzF0vnpapo/O4jY2Fj69gggV67czJy3jJjov1gwdyp/Rl0hISGelxr40eGNbgCE/nKM+bOnYGOTiwoVK3PPXb7/9t32r/nxh28pUKAgF86f4/3Bowg5eogff/gWozEJG5tc9Ht/GG5l3YGUWbHO3fvwf3t3c+vmDbr3DKROvYYA7NvzPSuWzidfvgL41ky7TdThg//H8k/mkZycTIEChQgcMALn4iX5JeQwi+bNwL1CJU6dPIHBYMXg4eP5fOUSwsPP4OBQlKVLFmb6X0PN2r/FnMnj+e3MWVat30RycjIhoWHMGP8BJlPK/dKuXb+OwWAgsEdXXqzpk2E/n67dyI5du0kyJpPLxpqRA96lQjm3NG32HTzMFxu3MC9oAtHXrtOgdQemjR1Bk5frsXz1em7FxhL4TldmLFjCkZBfSExKomCBAowb2h/nYkX5cOY8SjgXo3OH1wA4+dsfDB0/mS2ffcLGr79h1fpN2NhYk5yczLSxIylTumSGtW755lu2ffcDdna2XLwcQYH8+flw5GCKOhRhyzffsv37HylUoABnz19g7JD+RMdcY/bi5SQnGylUsCCjBgZSqkRKqN20dQerN24GwNrKirlTxlPYvhA/7T/IJ5+tIT4hAWsrKwb360mVSh6EX7jIqMkzuBsfjzE5mVZNG9O5w2v8sPdn5n3yKQaDJckWBnoN7Im3j3cmv0URkcejgJZNLCwsWLNmDWfPnqVjx474+Pik24+zR48eDB06FID169czffp03h00HoCbN2/gUbEKXbr35fud37B88RxmzF2Wbhzvar5sXLeK1zq8RcjRg1TwqEzIsUPUqdeQ06d+pVJlbyIuX+KLVUuZGDQXO7u8nD93hlHDA1m5Zmuavs6d+Z11q1cwb8lqChYsxKJ5M9Icv1dNfd8bSmCvTsxfsjq17fQpo+n45ttU9qpGYmIiwwf1prx7RTyrVGPKhBEMGTmBKt4+7Nn9HV9tWvvAz/PXEyHMX/IFzsVLAFC4iCNtX38TgGNHDjB31mQ+mr8itb2trR1zFq7k19AQJo8bTp16Dbl+LYbZMz9k5pyllCjlwvo1/26wfv1aDNMmj2bqrMWUdnFlx7bNTP3wg9RN2C+cP8vAYWN5b9AHzJ8dxMih7zJr/nIcHIoyalggW7dupUXdjIPUvTRv3IALly4Td+cuA/v0AOCNXu/RtkUz2jRvypnw83QLHMymlYtT99r8rxZ+Dencvi0A+w8fZeLMuaxa+FGaNtWqeDJ8QhCJSUkcPHIMr0oeHDgaQpOX63Hg6DG6dmwHQLeA11Nr+DL4Gz76eBlTxwynY5uWBI4Yw1vt26b8Tm/6ivatW2BhYcGsRZ+wccXHFHN0ICEhAWNy8n3f77ETv7Ju6XxcSpVk0YpVTJ27iBnjP0g9tn7pAkoWdyb62nV6DRzB0jlTcXMpzZdbtzN8YhCfL5rNoWPHWfr5GlbMnUGRwvbExd3BYDBw8XIEiz9dzcLpH5LXzo4/zoXTd8godqz/jLWbg6lTy5eend8A4OatlO3UFixbycj+/ajm5Ym1Qyn+uPr7Q31/IiKPQwEtm7Rrl/KHz9XVlYoVKxISEkLDhg3TtNmzZw+rV68mLi6OpKSkNMfy5LGlZu26AFTwqMwn//OH9x8VPb2YNH44iYmJhIUe5+1e77N3zy6KFHHEpYwbuXPn5ujhn4mMuMSQ999JfZ3RaORaTHSavn45fgTfmi+mboLepFkLfti57aFrunvnDr+EHOHG9eupz8XF3ebihXAKFSpMrty5qeKdEmbq1W/MnBkfZtjPf1Wq7J0azgD++O0kaz9fzq1bN7CwtOTyxQtp2r/UwC+1zujoP0lIiOdU2AnKlnOnRCkXAJr5t2HZ4rkAnDoZiqtbeUq7uALQuGlL5s0OIi7uNgAlSpZOnaErW86dq1GRODgUBaBceQ/Onz8PDxnQ/tftuDhO/3GW1s2aAODmUhr3sq788usp6r9YK137k6f/4JNVa7hx6xaWFhacv3Q5XZs8uXPj5lKaE2Gn2H/kGD07v8HMhZ+k/L6c/h1vz0oA7D1wiLWbg4m7cyfNEqOrSymKOzmx78BhqlSqwI/7DjCob08AfKt6M3rKDOq/WJt6tWtQwtnpvu+vauVKuJRKmWF7tXlTXuvaK82xf5Z9T4SdonzZMri5lAagdbMmTJo1n9txcfy0/yD+TRpRpLA9QOo5dv938AgXIyLpFjg4tU+j0Uh0zDWqe1VmxoIlJCYl4VvVixpVvQCoUc2b6QsW06R+XRo0b42dk3mcFyoiOYMCmhkwmUxYWFikee7y5ctMnjyZDRs2ULJkSY4ePcqgQYNSj1tbW6c+NhgsMRpTAtwXq5ay98eUJcd3+gzAq6oPrm7l2P39DuwLF6GKtw9LFn5EkSKOeFX1TR3fx7c2g4aPT1fbxQvn0tTJ/9T5X/eq6X8lm5KxsLBg9sKVWFml/RU8e+a3e/Z/P7nz/Huye2JiIh+OHcq0j5ZQtnwFov/6kzdfb5amvY2Nzd91GoCUP9Ym7rOUajLd761jY5Mr9bGlpQHrv/tP+dnyiZw3ZbrHUq+FhQW/nznHyEnTAPCt6sX7PbsxcMxEls+Zhkf5clz9K5rGbd/I8PU1q3tz8GgIv4Sd4oMB71LYviDbdv5AeTdXcuWyIeJKFNPnL+bzj+dQwqkYIaFhDJ8wJfX1AW1bsXZzMGfOX6BBvRfIlzclyMyaOIrQU79x8GgIb78/lA8GvEudWr6ZfbNp/puwzfPfixlMWJDxl3Gv1XATJl6s4cOHIwenO9bopTpUqeTBz4eOsOzzdWzetoPJHwxlcL+e/H7mHAePHee9996jdcdWNH+1eebqFxF5TLpIIJts3LgRgPDwcE6ePImXl1ea47GxsVhbW+Pg4EBycjJr1qzJVL8d3+zO/CWrmb9kNV5VU2ZsvKv6smrFx3hXrYGNjQ1FHBz5bkcw3tVS/lhW86nF4UM/c/7cmdR+Tp/6NV3fVbyrc+jAPm7cuA7Azh3BmarJ1taO+Pi7qYHN1taOSpWrsu6LFalt/rx6hZiYvyhR0oX4+HhOHD8KwE8/7uT27YfbZDwhIR6j0UgRx5QZrOAt6zP1Oo+KVTjz+2kuX0qZbdu+dXPqsQqVqnDmj9+4eCEcSHnvbmXdsbXNulmVvHZ2uJd15avtOwE4d/4iv/1xjsoV3SnnVoZ1SxewbukCBvfrSXxCAkajkaKODgCs2/z1PfutUc2bLd98SzFHB6ytralZzZtFK1ZRs7o3ALdvx2FtZUUR+0IkJyezfkvape+6tXwJv3iJz9Z9SfvWLQBISjJyKSKSyh7udH+jPbV9qnHq9zP/O3QaIaFhqbN8W7Z/h29VrwzbVankwek/znLu/EUAvtq+kwrl3LCzteWlF2oS/O1OomOuARAXd4eEhARq+1Zn38HD/HEuPLWf0JMpe+JeuBRBEftCtGrWhF5d3iD0ZMo/EsIvXKScWxneeK01LVu25HSY9tAVkayTI2fQkpMSnsgtMTLq19LK5sENSZnB6dChA9euXWP8+PHpzj9zd3enadOmNG/eHGdnZ3x9fTl8+PAj1eVdrQYrly/C6+9A5l3Nl7DQ47hX8ASgeIlSDB4+gVnTJ5AQH09SUiIVPb1wr1ApTT+ubuVp1+EtBvTrSiH7wlStVgNbu7wPHD9f/gK83LAZvbt3IG/e/Myct4whIyeweP5MendvD0CePHb0HzIae/siDPvgw9SLBLyq+uLoWOyh3q+dXV46de3Je73fwtGxGD7/c7L/vRQsZE/ggJGMHdmffPkKULd+o3+PFSzE4OHjCZo4EmOykQIFCjFkxISHqutJmPzBUCbMmMOq9V9iMBj4cOTgDM8/y2tnR5+ub/FGz0CKOTpS5x4XEgBUrliBazdu0r6aNwA1qldlzpIVqUt95dzK0Lh+Xdp07olTUQeqe1Xh6C8nUl9vaWlJy6aN2HvgEO5lU5aAk5ONjJo8g1uxt7G0tKCoowPv9ex23/dW3asyC5d9xpnw86kXCWTEvmBBPhw5mGETpmA0plwkMGnkEAB8vKvQ7Y32vDNgOJaWFlhbWzN38jhKlyjOpA+GMHbqR8THx5OYmIR35Yp4erjz7Q972Lrze6ytrLGwgKHvpiytfvTxci5cvoyVwUAB+yK8O6LffesXEXmSLEz3Wjd5xsTHxxMaGoqnpye5cuVKc+zkyZN4eHhkU2XpPc69zs5evvUUKsq8uLjbqbNGq1Z8TETEpWwJKs8a1+L5uHvl3IMbPqN6DhhO2xbNaPJyvUd6/ZZvvmXPzwdTLwowN7mLleHSrYtZOuaFPy6w+cbGLB3zeTW1/kz2v/dedpchj6DW7NnZXUK2yZEzaPLoli+ZR1jocRKTEnFyKk7ggJHZXZJko19P/caQcZOpUM6NRi/Vye5yRESeGwpo2eD06Wf3XJa+7w3NtrEDe3VKd7J9hYqevNt/RDZV9HAWrfic73/al+75hdMnUbhQwawv6AmoVKE8W79Ynun2Hd95N913WLliBUYNDKTV31enioiIApo8Q/65We6zqleXN+jVJeMrKXOKL/6+bYmIiNxfll3Fee7cOdq3b4+fnx/t27cnPDw8XZu9e/fSpk0bPD09CQoKyqrSRERERMxKlgW0MWPGEBAQwI4dOwgICGD06NHp2pQsWZKJEyfSvXv3rCpLRERExOxkSUCLjo4mLCwMf39/APz9/QkLCyMmJiZNu9KlS1OxYsV0Ny8VERERyUmyJKBFRkZStGjR1Lu2GwwGHB0diYyMzIrh00k0Jj5T/YqIiEjO8txNVYWGhqZ7zsrKitu3b6f+bGdnx5DdA5742FPrz0wzzpP2KPdNExEReZYdOXIku0t4aqpXr37PY1kS0JycnIiKisJoNGIwGDAajVy9ehUnp/tvnvwo7nWj2qwKN487zuPcxNZcRF2JILBXJ9Zu3vVE+lu14mPu3LlDj97vpzu29asNJMTH82q7R7s6snPHFoybNAuXMmX5aPoEGjXxx7NKVW7euM7YkQOIj7/Lyw2b8lqHtx7zXaRo1v4t5kweTzlXlyfSn4jI8+5+IeZ5liUBrXDhwnh4eBAcHEyrVq0IDg7Gw8MDe3v7rBhe/sNoTMJgMK+J08epqXnL155YHe8PGpX6+NjRg+TNl4+Z85Y9sf6fdf/8A0tERJ6+LPtLPXbsWIYNG8aCBQvInz9/6m00evToQWBgIJUrV+bw4cMMGDCA2NhYTCYTW7du5cMPP6Ru3bpZVWaWcHd3p1+/fuzbt49r164xYMAA/Pz80rULCgri4MGDJCYmUqhQISZNmgTkT52hataiDYcO7CP+7l3eHzwaz8re6fr4p22L1q9z7OhBGjRqRtXqNZkzcxI3blzDYGmgy9t98anxQrqZr//+/KAxv968jk0bVmNfuAhVvB78r50ZQWPJk8eWiMsXuXH9GnM/XsW6L1bw/XfbACjvXonegYPJk8cWSNlMfdSwQK5GXaFkqdL0HzwGu7x508yufbf9a37YtZ18+fITfu4MefPmZeS4qdjbF8nU9zKk/zu0fb0TuXPnYenHs4m7fZu+PQLo/e5gipcoxdxZk4mMvAQmE23bd6JRE/8M+/lh13a2bPyCxKSUcxLf7vU+rsUbpmkTfuEi/UdNYNOni0lKMvJSy3b06NSRLh3bseP7Pfyw9/+YMnoYn67dyI5du0kyJpPLxpqRA96lQjk3lq9eT+TVq4x4vy8A0THXeK1bb7atWcH+w8eY98mnGAyWJBmNDH+vzz03Hj907DhT5y6iQrmy/HbmLAaDgQnDB+LmUppDx44zbd7HVK3sya+nf6NHp44ULlSQoDkLuXP3Lnly52ZoYG88PdwB+PH/DrBoxSqSkpKwsLBk4oiBlHdz5ZewU8z+eBm34+IA6NOtE/Vq1yT62nWGT5hCdMx1AGr5VGVwv56EhIYx+aP5mEwmEpOSeKdTR5o1ejlT36GIyPMiywKam5sb69evT/f8kiVLUh/7+PiwZ8+erCopW1lYWLBmzRrOnj1Lx44d8fHxSbdheo8ePRg6NOXO/evXr2f69Om8O2g8ADdv3sCjYhW6dO/L9zu/YfniOcyYm/Fsz82bNyhZugxvdukJwPt9OtPM/1X8XmnN+fCzDHm/Bx+v2PDAmu815rkzv7Pm82XM+/hzCtkXZt5HUzL1GZwKO8HUWYvJnScPhw7s4/vvtjFj7jJsbe2YMWUMqz/7hO7vBAIQeuIY8xevppB9YWZOHcfqzz7JcMnz99NhLPjkCxwcizF7+kS+2rSWLt37Zqqef3hV9aFTl14c2P8TH4ydCsDk8cNxKePG6AnTiYn+i34936BsuQq4lCmb7vXVfWpRv4EfFhYWXLoQzrBBfWjbIm1AcylVktu34/gzOpqIyCjcXEpz4GgIXTq248DRY9So7g1AC7+GdG7fFoD9h48yceZcVi38iLYtmtL6rXd4/51u2NrmYcPX23il0cvkyZ2bBctWMrJ/P6p5eWI0Grlz9+593+9vZ84xNLA3Pt5V+Gr7d3wwaXrqDWV/PxvOyP79GP5+HxITE/EP6Ma4of2p5VONA0eOMXD0RIJXL+PylSjGTfuI5XOnU7pEcRISEkhMSuLmrVgmzpjL/KnjcShcmD+jowno+R4bl1di23ff41TUkcUzU35fbt5K2Wd2+ep1vNnuVVr4NcJkMnEr9umd1ykiYq6y7D5okla7du0AcHV1pWLFioSEhKRrs2fPHl5//XX8/f1ZunQpJ0+eTD2WJ48tNWunzCxW8KhMZMTle45lY5OLevUbAymbnZ858xuNm7YEoLSLK65l3TkVduKBNd9rzF+OH6FGzToUsk8JmM38X31gXwB16jUkd548AIQcPchLLzfBzi4vFhYWNPVvQ8iRg6lta9aqm9q/3yutOH7sUIZ9VvT0wsGxWEqNFT2JjLiUqVoe5NjRgzRr0QYA+8JFqFGrDsePHc6wbWTEJUYO6UfPrq8zecIIrsVE8+eff6Zr51vViwNHQth/5BivtXyFK1f/JDExkQNHQqhRzRuAk6f/oOu7g2jTpSfT5y/m9B9nAMifLx/1X6hF8Le7SEoy8mXwdtq1ag5AjWreTF+wmBVfrOfs+YvkfcD5jKWKO+PjXQUA/yYN+f1sOLF/X+xSqoQzXp4VAQi/cAlraytq+VQDoGb1qlhbWxF+4RL7Dx+lTk1fSpcoDoCNjQ12trYc/zWMiCtX6DtkFK9370PfIaOwAC5ejqBKxQr8fOgoMxcu4cf/O0Cev38XfKt6sezzdSxeuZoTJ0+TP1/eTH1HIiLPE/M6GSmHMplMWFhYpHnu8uXLTJ48mQ0bNlCyZEmOHj3KoEGDUo9bW1unPjYYLDEakwD4YtVS9v6YskT5Tp8BFHNyJnfu3Kn9m0ymDGuwsLDA0mAg+T/HExIS0rS515j36vNB/glnqX38z2fwv5/Jv23vfczaxib1saWlId2+j4/DgvT13bxxneGD+gBQomRpho+ezJSJI+nRuz8v1KlPcnIyrZvVIT4+nnz/819bzereHDgSQsSVK0waOYQjx0/wza7dKX05FSMxMZGBYyayfM40PMqX4+pf0TRu++/FEB3btmL4hCnYFypImdIlcSlZAoDB/Xry+5lzHDx2nMFjPqTT621o26LZI71n2/9+R5jSfQZ/fxDc61fAZDJRzrUMy+dOz/D4uqUL+PnwUYK/3cWy1Wv5dN5M3mz3Ki+9UJP9R44xZfYCXvCtRr+3uzxS/SIiz6ocGdASjYlMrT/zqfRrbbB+cENg48aN9OnTh/DwcE6ePImXV9pzhGJjY7G2tsbBwYHk5GTWrFmTqX47vtmdjm/+uxND1JWINMft7PLi5laenTuCadKsJRcvhHP2zG+4e3iSL18+jElJRFy+iHPxkvywa3umxvTy9mHDmpVcvxZDwUL27Ni2JVOv+6+q1WuybPEcWrXpQJ48tuzYthnvajVSjx88sJfr169RsGAhdu74mirePg89xuOoWq0G32zdRKcuPYmJ+YtDB/bxatsA8hcoyPwlq9O0vX07lmJOzgDs2LaFxMSEjLqkZjVv5ixeTqGCBSjq6ECt6lWZs2Q5taqnzFDFJyRgNBop6ugAwLrNX6d5fTlXFwrkz8/UuYsY0f/fZdzwCxcp51aGcm5liLtzh19P/XbfgHbhcgRHj4dSzcuTbTt/oJyrS4azbmVKlSQhMZGDR49To5oXB48eJynJiEvJ4tjYWLPksy84f+lymiVOb8+KXLh0OfU1AKEnT1OpQnkuX4miqEMRmjWsT7UqnrQI6EZycjIXLkfgUrIEJYs7Y5snD19t3/mgr0dE5LmTIwNaZkPU0+zXxsaGDh06cO3aNcaPH5/u/DN3d3eaNm1K8+bNcXZ2xtfXl8OHM15Se1hDRk5kzsxJbNq4GoOlgcHDx1OwYCEAevYbyIjBfXEsWgyvTIagMm7laP9GVwYGdqeQfWFq1Kzz0DX51nyRc2d/Z0C/rgCUc69Ix07/Bk3vqr7MmjqeK5GXKVGyND169X/oMR5Hr36DmDtrEr3f7gAmE1179KN0GbcM2/bsM4DxowZRuIgDlb2qkT9/gQzbFXV0wNY2D1UrVwJSliYjo/5MDTJ57ezo0/Ut3ugZSDFHR+rUTP99tPFvytwlK6hb698w+9HHy7lw+TJWBgP58toxdsj9Pyv3sm58s2s3U+ctwtLSkokjBmXYztramhnjP0hzkcD0cSOxtramdInijB70HkPGTiI5OTmln+GDKOdWhtmTxjJr0SdMm7eIxMQkSjgXY87kcRw+9gsr123EymAgOTmZDwa+i6WlJas3buHQseNYW1ljY2PNsMDe961fROR5ZGF61PUpMxMfH09oaOg974Pm4eGRTZWl9zj3Ojt7+dZTqEieNtfi+bh75dwT73fs1Fm4lCxBl47tHun1h44dZ+bCT1IvCpCM5S5Whku3LmbpmBf+uMDmGxuzdMzn1dT6M9n/3nvZXYY8glqzZ2d3CdlGFwmIPIOu/hVNyze7c+FSBO1fbZHd5YiIyBOWI5c4s9vp06ezu4QsceaP08wMGpfu+RatX6dp89ZZVsf2rZv5evO6dM8PGDoGt7LuWVbHk+RYpDBfrVqa6faBw8dw5WraK0mLOTowZ/I4zZ6JiJghBTR5atzKuqc7gT47NG3eOksDoTmaMzl9UBYREfOlJU4RERERM6OAJiIiImJmFNBEREREzEyODGjJiYnPVL8iIiKSs+TIiwQsra2fyj1xnsT9Wh7nHmlPw2+nw9i0YTVDR068b7uoKxEE9urE2s270h2Ljb3FN8Ff0q5D50eqoXPHFoybNCvDjcmzy3fbv06zmfrj6v7eYN5q/xovvVAz3bGxU2fR0q8x1bw8H7rfy5FXCOgZyI9fpVzF+nr3PqxcMIvcuXIREhrG+OmzsTJYMajvO6k3yH0c/zueiIg8mhwZ0CTzyrtXfGA4e5DbsbfYsGblIwe0h2U0GjEYDFkyVmYlJSU98msftBPAw1i3dEHq4+Adu2jp1+iRb3L7vElOTsbCwuKe+7yKiGQlBbRs4O7uTr9+/di3bx/Xrl1jwIAB+Pn5pWsXFBTEwYMHSUxMpFChQkyaNAnInzpb1axFGw4d2Ef83bu8P3g0npW90/WxfMk88uXLz2sd3mLP7u+YMmEEqzfsoGAhe0YNC6R12wCq+9bi4P69rP18GQkJCVhZW/NOnwF4VKzMLyGH+WTRbOYs+gyArzatZcuXa7DLmw/fmi8SvHldmlmzFUvnp6tp/uwgYmNj6dsjgFy5cjNz3jJiov9iwdyp/Bl1hYSEeF5q4EeHN7oBEPrLMebPnoKNTS4qVKzMPXfi/tt327/mxx++pUCBglw4f473B4/iWkw0yz+ZR3JyMgUKFCJwwAici5dMN/P135+/2/41P+zaTr58+Qk/d4a8efMyctxU7O2LkJiYyMK5U/kl5AhFijhSopTLA7/nzh1b4PdKK44fO0Q5NxcGvf0mk2cv4NfTvwHg36Qh3QJeT21/4MgxVq7dQNSff9Gkfj0C30nZ9uq/s2ujJk/HxsaG8xcvE3X1T6pU8mDiiEGZDhVeLzXl5282sW5LMDt++JHcuXOzbecPrFwwiz/OhqfZxmloYG88PTK+T9yMBUs4EvILiUlJFCxQgHFD++NcrGiaNuu/2srvZ84xon8/Tpw8zZu93uPzRbPx9HDnw5nzcC/rymstX2H4hCDCL14iISGRksWdGT+sP/nz5aPvkFG0fqUJjevXBWDnnr2s37KNj2dMYtGKVXyzaze5bGwACz75KIj8+fJmWOvC5Z9xNvwCcXfuEhEVRZlSJRk3dAD58tqxcPlnXLgcwZ07d7l4OZLlc6fx474DrFizAQsLKOHszKhBgRQvltLX6uWr+X7791hYWpI7T25mf/IRlpaW7Aj+lq/Wf4XRaMQurx3vD3uPki4l+fX4r8yZOheTyURSUhJvdnuDBk0bEPxlMBtXf4m1jTXJycmMnjKKUi6lMvUdikjOoICWTSwsLFizZg1nz56lY8eO+Pj4pNuPs0ePHgwdOhSA9evXM336dN4dNB6Amzdv4FGxCl269+X7nd+wfPEcZsxdlm4c72q+bFy3itc6vEXI0YNU8KhMyLFD1KnXkNOnfqVSZW8iLl/ii1VLmRg0Fzu7vJw/d4ZRwwNZuWZrmr7OnfmddatXMG/JagoWLMSieTPSHL9XTX3fG0pgr05p7ok2fcpoOr75NpW9qpGYmMjwQb0p714RzyrVmDJhBENGTqCKtw97dn/HV5vWPvDz/PVECPOXfIFz8RJcvxbDiMF9mTprMaVdXNmxbTNTP/yAjxZ8+sB+fj8dxoJPvsDBsRizp0/kq01r6dK9L9u+3siVyAgWLVtHUlISQ97vgWMxpwf2FxP9F0EzP8a1eD4mj/0Ak8nExuWLuB0XR6c+/SnvWoY6tXwBOBN+gY9nTCEhIYFOffrj5VkxwyXPP86Fs3jGFCwtLXj97b7sP3yM2r7VHljLf3Xp2I4z4eep6F6ejm1akpiYyMDRExk3tD+1fKpx4MgxBo6eSPDqZVhbp99jtlvA6wzs0wOAL4O/4aOPlzF1zPA0bWpWq8qq9ZsAOHjkGF6VPDhwNARPD3cOHD3GW+3bADDk3V4UKpiyX+m8T1awbPV63u/ZjYC2rVi2el1qQFu7KZiAtq24eesWn67ZyA9b1pA7Vy5ux8WRyybt9m7/6+gvoaxbuoDC9oUYPWUmi1euTq3/6PFQ1iyZR6GCBfj9bDizFy/jiyVzcShcmHlLP2XK7AXMXbSEHcHf8n97fmb20tnY5bXjxvUbWFpa8suxE/z43W5mLZmJjY0NB/YdZNr46cxZNps1n67htYC2NG7eGJPJxO3Y2wAsnr2YT9Z+gmMxRxISEkhOTn6o709Enn8KaNmkXbuUZSVXV1cqVqxISEgIDRs2TNNmz549rF69mri4uHRLZHny2FKzdsofrgoelflk4UcZjlPR04tJ44eTmJhIWOhx3u71Pnv37KJIEUdcyriRO3dujh7+mciISwx5/53U1xmNRq7FRKfp65fjR/Ct+WLqxupNmrXgh53bHrqmu3fu8EvIEW5cv576XFzcbS5eCKdQocLkyp2bKn9v1F6vfmPmzPgww37+q1Jlb5yLlwDg1MlQXN3KU9rFFYDGTVsyb3YQcXG3H9hPRU8vHBxTpksqVPTk6JEDKe895AiN/PyxsrLCysqKlxs149fQkAf217BJ89THB44cY8i7vbCwsCCvnR3NGtZn/5FjqQGtZdNGWFkZsLLKQ9OGL3HwaEiGAa1BnRfIlcsGAI9yZbkYEUntB1Zyf+EXLmFtbUUtn5SgV7N6VaytrQi/cIlybmXStd974BBrNwcTd+cORqMxwz5LlXAmPj6BqKt/cuBoCIHvdGXJyi9o3rgBiYkps2UAX+/YybadP5CYmMSdu3cpXbI4AC/UqM60eR9zNvwCFhYWXIqIoF7tlE3hXUqVYMTEqbxYw4d6L9TAztb2vu+vXu2aFLZP+b19tbkfU2b/u9Rbp5ZvakA8dOw4dWr54vD3P5batXiFdt37ALD/p/20bNsCu7wp54cW+Ps1P+/5mTO/n6Vfl3cBMJlMxN5M2TPX28eb1Su+ICoyiuq1quPhmbInsLdvVaaNn8YL9V6gZp2aOJdwvm/9IpLzKKCZAZPJlG6J6vLly0yePJkNGzZQsmRJjh49yqBBg1KP/3dWw2CwxGhMCXBfrFrK3h9Tlhzf6TMAr6o+uLqVY/f3O7AvXIQq3j4sWfgRRYo44lXVN3V8H9/aDBo+Pl1tFy/8u8G3yWSC+yyl3aum/5VsSjnXZ/bClVhZpf0VPHvmt3v2fz+58+T59weT6Z5lGgwGTMn/LpkmJMSnOW5tY5P62NLSkBo+TA9YZr2XPP+pK6Pv+V5Lkxm1/YfNf2pM+ZwzDkgPw4QJCzIYz8KCfQcPM/vjlNnZVxq9TJOX6zF9/mI+/3gOJZyKERIaxvAJUzLs17eqF3v2HyQ65jo+3lWY9NF89vx8EN+q3kDK7NX6LVv5dMFM7AsWZNt3P7AxeNvfQ1vQ/tUWrN0cDMBrLV5JPbfwswUfERL6KwePHqdjj3dZMG0i5d1cM/de/+eztf3f74iMv6N7/w6YaNqyKV17dUl3pG1AW2rXq82RA0eZO3UePrWq061PN8ZNG8vpX09z7PAxBvYaxPvD36fmizUyVb+I5Aw5MqAlJyY+kSsuM+rXMoPloIxs3LiRPn36EB4ezsmTJ/HySnsFXWxsLNbW1jg4OJCcnMyaNWsy1W/HN7vT8c3uaZ7zrurLqhUf07xFW2xsbCji4Mh3O4IZMnICANV8avH5yiWcP3eG0mXcADh96lfcK1RK008V7+psWPsZN25cp0CBguzcEZypmmxt7YiPv4vRmITBYIWtrR2VKldl3RcrCOj0NgB/Xr2CwcqKEiVdiI+P58Txo1T2qsZPP+7k9u3YTI3zjwqVqjBr+gQuXginZCkXdu4Ixq2sO7a2djg5l+Dc2d9JSEjAwsKCvXu+xy5vxucu/Zd3NV++/24bL73cmKSkJHbv2o5D0WIPVVctn2p8Gbwdb8+KxN25w/bvf2Rg7x6px4O/3YXfyy+RkJjId7t/ot/bXR6q/8dRplRJEhITOXj0ODWqeXHw6HGSkoy4lCxOOVcXXqzhk9r29zPnsLayooh9IZKTk1m/Zes9+61Z3Zv5Sz/lhb9f7+1ZkeWr16a+t5uxseTNa0fB/PlJSEhg8zc70ry+ZdNGvPrWOyQkJvLlpx8DcDsujrg7d/DxroKPdxWO/3qSP86ev29A+2n/QWKuX8e+YEG+2v4dvlUzvmK1ZnVvln+xnr+iYyhS2J6NwdupWb0qALXr1earjV9T5+U62NrZcuP6DQoULEDturWZMiYI/1eb41DUAaPRyJnfzlDeozwXz1+iZOkSOJdwJo9tHr4N/hZjkpGoK1FU8KxABc8KRFyK4I/TfyigiUgaOTKgZTZEPc1+bWxs6NChA9euXWP8+PHpzj9zd3enadOmNG/eHGdnZ3x9fTl8+PAj1eVdrQYrly/Cq5rv3z/7EhZ6HPcKKbdtKF6iFIOHT2DW9AkkxMeTlJRIRU+vdAHN1a087Tq8xYB+XSlkX5iq1Wpga/fgcJMvfwFebtiM3t07kDdvfmbOW8aQkRNYPH8mvbu3ByBPHjv6DxmNvX0Rhn3wYepFAl5VfXF0fLggVLBgIQYPH0/QxJEYk40UKFCIISNSwqhHpSpUrV6D3t3bU7SYMyVLuRAT89cD+2zm34ZzZ/+gZ9fXKeJQlMpe1bly5fJD1dXzrQAmz55P2669gJSLBF6s+W/w8ShXlp4Dh3H1z2ga16+b4fLm02Jtbc2M8R+kuUhg+riRGZ5/Vs6tDI3r16VN5544FXWgulcVjv5yIsN+a1TzZuSH06hZzRtIOS9t49ffpN7So05NX7Z+9z2tOvWgqEMRKrmXI/TU6dTX29na8mINH+4mxGNfsCAAsbG3GTB6IvHx8SSbTHiUK0vDei/e9/3VqObNmCmzuBQZiUvJEgzs806G7cqWceG9Hl3pOXDE3xcJODFqYCAATZo35q+rf9Gv67sYDAZsbfMwa8ksqlSrQrc+3fhgwCiSk5NJSkyiXqN6lPcoz6Y1mwg5EoK1lRXWNtb0G9wPY7KRoLFTuX0rFgtLSxyKOvB2v7fvW7+I5DwWpkdduzEz8fHxhIaG4unpSa5caU8YPnnyJB4eHtlUWXqPc6+zs5dvPYWKMi8u7ja2til1r1rxMRERl1LDj9yba/F83L1y7sENJY2kJCPtuvVmwvCB97yi9EEWLv+MuDt3Uy8KeBS5i5Xh0q2Lj/z6R3HhjwtsvrExS8d8Xk2tP/Op3PtSnr6nsdr1rMiRM2jy6JYvmUdY6HESkxJxcipO4ICR2V2SPKd27/uZKbMX0qDuC48czkREnlUKaNng9OnTD25kpvq+NzTbxg7s1SndCfEVKnrybv8R2VQRbN+6ma83p79r/oChY3Arm3WhYsKMOZwIO5XmOYPBwBeL52ZZDU9a/RdrU//FzF2fGn3tOr0Hpf89aFD3RXp37fSkSxMReeoU0OSZ8c/Ncs1J0+atadq8dXaXkXqeVE5VuFDBNLskiIg863LMZunPyal2IpIDmEwm9P9YIjlbjghouXPnJjo6WiFNRMyeyWTi9o04rhuvZXcpIpKNcsQSZ4kSJbh06RJ//vlndpfy2P66fje7S5BHEH8zN4k3H3w7DzFP1tfucu1uTJaMZQKuG6+x//a+LBlPRMxTjgho1tbWlCmTfruaZ1HA6N3ZXYI8gtXjq/Lb9C7ZXYY8ovKDVjBk94DsLkNEcpAsW+I8d+4c7du3x8/Pj/bt2xMeHp6ujdFoZNy4cTRq1IjGjRuzfv36rCpPRERExGxkWUAbM2YMAQEB7Nixg4CAAEaPHp2uzddff82FCxf49ttvWbt2LXPnzuXSpUtZVaKIiIiIWciSJc7o6GjCwsJYvnw5AP7+/kyYMIGYmBjs7e1T223bto127dphaWmJvb09jRo1Yvv27bz99oO3QfnnAoCEhISn8ybMRP48996sXMxXfHw8ybnzZXcZ8oji4+OxtXj4nT/EPMTHx8Mj7Nwi2S8+Pj67S3jqbGxssLBI/7c9SwJaZGQkRYsWxWAwACk30HR0dCQyMjJNQIuMjMTZ2Tn1ZycnJ65cuZKpMRITEwH47bffnmDl5qdHkwfvfSnmJzQ0FGp3ye4y5BGFhobSIm/r7C5DHlFoaCjWbdtmdxnyCEJDQ7O7hKcuoy0q4Tm6SMDOzo7y5ctjbW2dYRIVERERMTc2NjYZPp8lAc3JyYmoqCiMRiMGgwGj0cjVq1dxcnJK1y4iIoIqVaoA6WfU7sfS0pJ8+bSEJCIiIs++LLlIoHDhwnh4eBAcHAxAcHAwHh4eaZY3AZo2bcr69etJTk4mJiaGnTt34ufnlxUlioiIiJgNC1MW3V7/zJkzDBs2jJs3b5I/f36CgoJwdXWlR48eBAYGUrlyZYxGI+PHj2ffvpQbNPbo0YP27dtnRXkiIiIiZiPLApqIiIiIZE6O2ItTRERE5FmigCYiIiJiZhTQRERERMyMApqIiIiImVFAExHJwLx583B3d0/dneTcuXO0b98ePz8/2rdvT3h4ePYWKCLPNQU0EZH/8euvvxISEpLmRtljxowhICCAHTt2EBAQwOjRo7OxQhF53imgiYj8R0JCAuPHj2fMmDGp28ZFR0cTFhaGv78/AP7+/oSFhRETE5OdpYrIc0wBTUTkP2bPnk3Lli0pWbJk6nORkZEULVoUg8EAgMFgwNHRkcjIyOwqU0SecwpoIiJ/O3bsGCdOnCAgICC7SxGRHE4BTUTkb4cOHeLs2bM0bNiQBg0acOXKFbp3786FCxeIiorCaDQCYDQauXr1Kk5OTtlcsYg8r7TVk4jIPTRo0IBFixZRvnx5OnXqxGuvvUarVq3YsmULGzZs4LPPPsvuEkXkOWWV3QWIiDwLxo4dy7Bhw1iwYAH58+cnKCgou0sSkeeYZtBEREREzIzOQRMRERExMwpoIiIiImZGAU1ERETEzCigiYiIiJgZBTQRERERM6OAJiIiImJmdB80EXmmNGjQgL/++guDwYCtrS1169Zl1KhR2NnZZXdpIiJPjGbQROSZs2jRIo4dO8bmzZsJCwtj8eLF2V0SAElJSdldgog8JxTQROSZ5eDgQJ06dTh58iQAISEhdOjQAR8fH1q2bMmBAwdS23755Zc0bNiQqlWr0qBBA7766isAkpOTWbBgAS+//DK1a9dmyJAh3Lp1C4ADBw5Qr169NGM2aNCA//u//wNg7ty5BAYGMmjQIKpVq8amTZu4fv06w4cPp06dOvj6+tKnT5/U1/7www+0atUKHx8fOnTowKlTp1KPLV68mLp161K1alX8/Pz4+eefn86HJiLPBC1xisgz68qVK/z000/UrFmTqKgoevbsydSpU6lbty4///wzgYGBfPPNN+TOnZuJEyeyYcMGXF1duXr1Kjdu3ABSgtumTZtYuXIl9vb2DB06lPHjxzNt2rRM1bBr1y5mz57N1KlTSUhIIDAwEFtbW7Zu3YqtrS3Hjh0D4Ndff2XEiBEsWrQIT09PvvrqK/r06cP27du5dOkSn3/+ORs2bKBo0aJcunSJ5OTkp/a5iYj50wyaiDxz+vbtS9WqVXnppZewt7cnMDCQLVu2UK9ePV566SUsLS158cUX8fT05McffwTA0tKS33//nbt37+Lo6Ei5cuUA+Prrr+nSpQslS5bEzs6OAQMGsG3btkwvV3p7e9OoUSMsLS25efMme/bsYdy4cRQoUABra2tq1KgBwLp162jfvj1eXl4YDAZeffVVrK2tCQkJwWAwkJCQwJkzZ0hMTKREiRKUKlXq6Xx4IvJMUEATkWfO/PnzOXbsGJ999hlnz57l2rVrREREsH37dnx8fFL/d+TIEf78809sbW2ZNWsWa9asoU6dOrzzzjucOXMGgKtXr1K8ePHUvosXL05SUhLR0dGZqqVYsWKpj69cuUKBAgUoUKBAunYREREsX748TX1Xrlzh6tWrlC5dmhEjRjB37lxeeOEF+vfvT1RU1GN+SiLyLNMSp4g8s2rUqEGbNm0ICgrCy8uLVq1aMXHixAzb1q1bl7p163L37l0++ugjRo0axerVq3F0dOTy5cup7SIiIrCysqJw4cJERUVx9+7d1GNGo5GYmJg0/VpYWKQ+LlasGDdu3ODmzZvkz58/TTsnJyd69epF7969M6yvRYsWtGjRgtjYWEaPHs306dMzvcwqIs8fzaCJyDOtc+fO/N///R/Vq1fnhx9+4KeffsJoNBIfH8+BAwe4cuUKf/31F7t27SIuLg4bGxtsbW0xGAwA+Pv78+mnn3Lx4kVu377NrFmzaNasGVZWVpQpU4b4+Hh2795NYmIiCxcuJCEh4Z61ODo6Uq9ePcaNG8eNGzdITEzk0KFDALRr1441a9Zw/PhxTCYTcXFx7N69m9jYWM6ePcvPP/9MQkICNjY25MqVK7U+EcmZFNBE5Jlmb29Pq1at+PTTT1mwYAEff/wxtWvX5qWXXmLp0qUkJyeTnJzM8uXLqVu3LjVq1ODQoUOMGTMGgLZt29KyZUvefPNNGjZsiI2NDaNGjQIgX758jBkzhg8++IB69eqRJ0+eNEuaGZk6dSpWVlY0a9aMF154gU8//RSAypUrM2HCBMaPH4+vry9NmjThyy+/BCAhIYEZM2ZQs2ZN6tSpQ0xMDP3793+Kn5qImDsLk8lkyu4iRERERORfmkETERERMTMKaCIiIiJmRgFNRERExMwooImIiIiYGQU0ERERETOjgCYiIiJiZhTQRERERMyMApqIiIiImVFAExERETEz/w9XY0rAI1nmmAAAAABJRU5ErkJggg==\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAmgAAAFCCAYAAABFMCGEAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAA7jElEQVR4nO3dd1xV9R/H8RdchoCaQixXzhTFvc2VmmZh2BKlLEeUUlmWuffIHDlz5ybnT01F00qz8cstDsJRjkxBVFwpwoXL/f1h0Y9AxMHlCO/n49Hjwb3ne875XPgGb7/fc87Xzmq1WhERERERw7DP6QJEREREJC0FNBERERGDUUATERERMRgFNBERERGDUUATERERMZhcE9CsViuJiYnoplQRERF52OWagGY2m4mMjMRsNud0KSIiIiL3JdcENBEREZHcQgFNRERExGAU0EREREQMRgFNRERExGAU0EREREQMRgFNRERExGAU0EREREQMRgFNRERExGAU0EREREQMRgFNRERExGAU0EREREQMRgENMCdZcrqEbJXbP5+IiEhu45DTBRiBk6OJ4MHbcrqMbLNkeNOcLkFERETugkbQRERERAxGAU1ERETEYBTQRERERAxGAU1ERETEYBTQRERERAxGAU1ERETEYBTQRERERAxGAU1ERETEYBTQRERERAxGAU1ERETEYBTQRERERAxGAU1ERETEYBTQRERERAxGAU1ERETEYBTQRERERAxGAU1ERETEYBTQRERERAxGAU1ERETEYBxsdaKTJ0/St29frly5QqFChRgzZgwlS5ZM0yYuLo5+/foRExNDUlIS9erVY+DAgTg42KxMERERkRxnsxG0IUOGEBwczObNmwkODmbw4MHp2sycOZMyZcqwfv161q9fzy+//MLXX39tqxJFREREDMEmAS0uLo6oqCgCAgIACAgIICoqikuXLqVpZ2dnx40bN0hJScFsNpOUlIS3t7ctShTJMnOSJadLyDa5+bOJiDxMbDJ3GBMTg7e3NyaTCQCTyYSXlxcxMTG4u7untgsNDeXdd9+lYcOG3Lx5k1deeYWaNWve1bkiIyPvur67PcfDaO/evTldQq5Rs2ZNggdvy+kyssWS4U3VV0REbCSz/GGoi7s2bdpE+fLlWbhwITdu3CAkJIRNmzbx9NNPZ/kY/v7+ODs7Z2OVD6e8EELlwVBf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iYiIiBiMApqIiIiIwSigiYiIiBiMApqIiIiIwSigiYiIiBiMApqIiIiIwSigiYiIiBiMApqIiIiIwSigiYiIiBiMApqIiIiIwTjY6kQnT56kb9++XLlyhUKFCjFmzBhKliyZps20adPYuHEjJpMJBwcHevbsSaNGjWxVooiIiIgh2CygDRkyhODgYAIDA1m7di2DBw9m0aJFadpUqVKFLl264OLiwpEjR3j11Vf56aefyJcvn63KFBEREclxNpnijIuLIyoqioCAAAACAgKIiori0qVLado1atQIFxcXAMqXL4/VauXKlSu2KFFERETEMGwyghYTE4O3tzcmkwkAk8mEl5cXMTExuLu7Z7jPl19+SYkSJfDx8bmrc0VGRt51fTVr1rzrfcRY9u7da7Nzqb883NRX5G6ov0hW3UtfyexnbrMpzruxa9cuJk+ezLx58+56X39/f5ydnbOhKjEy/WKTrFJfkbuh/iJZ9aD7ik2mOH19fYmNjcVisQBgsVg4f/48vr6+6dpGRETw0UcfMW3aNEqXLm2L8kREREQMxSYBzcPDAz8/P8LDwwEIDw/Hz88v3fTmwYMH6dmzJ1OmTKFSpUq2KE1ERETEcGz2HLShQ4cSFhZGq1atCAsLY9iwYQCEhIRw6NAhAIYNG0ZCQgKDBw8mMDCQwMBAjh49aqsSRURERAzBZteglSlThpUrV6Z7f86cOalfr1q1ylbliIiIiBiWVhIQERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDUUATERERMRgFNBERERGDsdli6TkpKSmJM2fOkJCQcNs23Vs/YsOKbOvw4cMkNeqa02Vkm8OHD9v8nLm1v6ivPHh321esVrhwzcLGPTe4abZmU1UiYnR5IqCdOXOGAgUKULJkSezs7DJsc+LsnzauynZKFy1AwrmTOV1GtsnnU8rm58yt/UV95cG7275itVrxuHEViGXVz9ezpygRMbw8McWZkJCAh4fHbcOZiIhR2NnZkc/tETwLmnK6FBHJQXkioAEKZyLy0LCzs0O/skTytjwxxflv5iQLTo5p/3VaumiB+z7uzcRkYi7evO/jiIiISN6WJwOak6OJ4MHbHvhxlwxv+sCPKSIiInlPnpnifFi0blaL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pOSIy5cvExISQqtWrWjTpg3vvPMOly5dAjLvH+o7ece9/P5Q37lLVsm1du/ebY2OjrY++eST1qNHj+Z0OWIwt+sfHTt2tH755ZdWq9Vq/fLLL60dO3bMqRIlh1y+fNm6Y8eO1NeffPKJtV+/flarNfP+ob6Td9zL7w/1nbujEbRcrFatWulWaxD5W0b9Iy4ujqioKAICAgAICAggKioqdfRE8oZChQpRt27d1NfVqlUjOjo60/6hvpO33O3vD/Wdu5dr1uIUkfsXExODt7c3JpMJAJPJhJeXFzExMelW/pC8ISUlhaVLl9KsWbNM+4fValXfyePutX+o72RMI2giInJbI0aMwNXVlVdffTWnSxHJUzSCJiKpfH19iY2NxWKxYDKZsFgsnD9/XlPledSYMWP4/fffmTlzJvb29pn2D6vVqr6Tx91r/1DfyZhG0EQklYeHB35+foSHhwMQHh6On59fnp5myKsmTpxIZGQk06ZNw8nJCci8f6jvyL32D/WdjGktzlxs5MiRfP3111y8eJHChQtTqFAhNmzYkNNliUHcrn8cP36cvn37cu3aNQoWLMiYMWMoXbp0TpcrNvTrr78SEBBAyZIlyZcvHwDFihVj2rRpmfYP9Z28415+f6jv3B0FNBERERGD0RSniIiIiMEooImIiIgYjAKaiIiIiMEooImIiIgYjAKaiIiIiMEooImIiIgYjFYSEJGHSrNmzbh48SImkwlXV1caNWrEoEGDcHNzy+nSREQeGI2gichDZ+bMmURERPDll18SFRXF7Nmzc7okAJKTk3O6BBHJJRTQROSh5enpScOGDTl8+DAA+/fvp3379tSqVYvnnnuOnTt3prZdvXo1zZs3p3r16jRr1ox169YBkJKSwvTp03nyySepX78+vXv35s8//wRg586dNG7cOM05mzVrxs8//wzA1KlT6dGjB7169aJGjRqsWbOGK1eu0K9fPxo2bEjt2rUJDQ1N3fe7774jMDCQWrVq0b59e44cOZK6bfbs2TRq1Ijq1avTqlUrtm/fnj3fNBF5KGiKU0QeWufOnePHH3+kbt26xMbG8tZbbzF27FgaNWrE9u3b6dGjB1999RX58uVj5MiR/Oc//6F06dKcP3+eq1evAreC25o1a1i0aBHu7u706dOH4cOHM27cuCzVsGXLFiZPnszYsWMxm8306NEDV1dXNmzYgKurKxEREQD88ssv9O/fn5kzZ+Lv78+6desIDQ1l06ZNnDlzhi+++IL//Oc/eHt7c+bMGVJSUrLt+yYixqcRNBF56Lz99ttUr16dJk2a4O7uTo8ePVi7di2NGzemSZMm2Nvb88QTT+Dv78/3338PgL29Pb/++isJCQl4eXlRrlw5ANavX0+nTp0oXrw4bm5ufPDBB2zcuDHL05XVqlWjRYsW2Nvbc+3aNX744QeGDRvGI488gqOjI3Xq1AFgxYoVBAUFUbVqVUwmE88//zyOjo7s378fk8mE2Wzm+PHjJCUlUaxYMUqUKJE93zwReSgooInIQ2fatGlERESwePFiTpw4weXLl4mOjmbTpk3UqlUr9b+9e/dy4cIFXF1dmThxIsuWLaNhw4a8+eabHD9+HIDz589TtGjR1GMXLVqU5ORk4uLislSLj49P6tfnzp3jkUce4ZFHHknXLjo6mvnz56ep79y5c5w/f57HHnuM/v37M3XqVBo0aEDPnj2JjY29z++SiDzMNMUpIg+tOnXq8MILLzBmzBiqVq1KYGAgI0eOzLBto0aNaNSoEQkJCUyaNIlBgwaxZMkSvLy8OHv2bGq76OhoHBwc8PDwIDY2loSEhNRtFouFS5cupTmunZ1d6tc+Pj5cvXqVa9euUbBgwTTtfH196datG927d8+wvjZt2tCmTRuuX7/O4MGDGT9+fJanWUUk99EImog81F5//XV+/vlnatasyXfffcePP/6IxWIhMTGRnTt3cu7cOS5evMiWLVuIj4/HyckJV1dXTCYTAAEBASxcuJA//viDGzduMHHiRFq3bo2DgwOlSpUiMTGRbdu2kZSUxIwZMzCbzbetxcvLi8aNGzNs2DCuXr1KUlISu3fvBuDll19m2bJlHDhwAKvVSnx8PNu2beP69eucOHGC7du3YzabcXJywtnZObU+EcmbFNBE5KHm7u5OYGAgCxcuZPr06cyaNYv69evTpEkT5s6dS0pKCikpKcyfP59GjRpRp04ddu/ezZAhQwB48cUXee6553j11Vdp3rw5Tk5ODBo0CIACBQowZMgQBg4cSOPGjXFxcUkzpZmRsWPH4uDgQOvWrWnQoAELFy4EoHLlyowYMYLhw4dTu3ZtWrZsyerVqwEwm818+umn1K1bl4YNG3Lp0iV69uyZjd81ETE6O6vVas3pIkRERETkHxpBExERETEYBTQRERERg1FAExERETEYBTQRERERg1FAExERETEYBTQRERERg1FAExERETEYBTQRERERg1FAExERETGY/wE1ySFMstKG5AAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] @@ -799,7 +835,7 @@ "resources = [int(10 / c) for c in constants] \n", "df = pd.DataFrame({\n", " 'Model Runtime Const': resources, \n", - " **all_results\n", + " **key_results\n", "})\n", "fig, ax1 = plt.subplots(figsize=(10, 5))\n", "tidy = df.melt(id_vars='Model Runtime Const').rename(columns=str.title)\n", diff --git a/wikipedia/run_1_generate_plan.sh b/wikipedia/run_1_generate_plan.sh index 5123d42..6027c32 100644 --- a/wikipedia/run_1_generate_plan.sh +++ b/wikipedia/run_1_generate_plan.sh @@ -1,8 +1,8 @@ set -xe -for replicas in 2 4 8 1 +for replicas in 1 2 4 do - for model_runtime in 0.25 + for model_runtime in 0.001 0.05 0.01 0.1 1.0 5.0 10.0 do for event_policy in "lifo" #"fifo" do diff --git a/wikipedia/run_2_prepare_data.sh b/wikipedia/run_2_prepare_data.sh index d170ebd..a7dcd74 100644 --- a/wikipedia/run_2_prepare_data.sh +++ b/wikipedia/run_2_prepare_data.sh @@ -4,7 +4,7 @@ plan_dir=/data/wooders/wiki-plans for replicas in 2 do -for model_runtime in 1.0 +for model_runtime in 0.25 do for event_policy in "lifo" do diff --git a/wikipedia/run_3_run_predictions.sh b/wikipedia/run_3_run_predictions.sh index e0e8f13..abbc646 100644 --- a/wikipedia/run_3_run_predictions.sh +++ b/wikipedia/run_3_run_predictions.sh @@ -5,18 +5,21 @@ dpr_dir=~/DPR cd $dpr_dir +for replicas in 1 2 4 +do for event_policy in "lifo" do - for model_runtime in 0.25 0.005 + for model_runtime in 0.25 #for model_runtime in 0.01 0.05 0.1 1.0 10.0 0.25 0.005 do for load_shedding_policy in "always_process" do - for key_policy in "weighted_round_robin" "round_robin" "random" "weighted_random" + for key_policy in "weighted_round_robin" "round_robin" do - plan_file=plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100 + #plan_file=plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100 + plan_file=plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100_replicas_${replicas} echo $plan_file - CUDA_VISIBLE_DEVICES=0,1,4 bash ${dpr_dir}/evaluate_retrieval_single_doc_stream.sh $plan_file & + CUDA_VISIBLE_DEVICES=0,2,3,4 bash ${dpr_dir}/evaluate_retrieval_single_doc_stream.sh $plan_file & #pid=$! done @@ -24,4 +27,4 @@ do done done done -p +done diff --git a/wikipedia/simulate.py b/wikipedia/simulate.py index 78ed8a1..27db63a 100644 --- a/wikipedia/simulate.py +++ b/wikipedia/simulate.py @@ -450,7 +450,8 @@ def run(self, replica_id: int): runtime = self.model_runtime_s * num_passages #print(runtime, num_passages) - yield self.env.timeout(self.model_runtime_s) + yield self.env.timeout(runtime) + #yield self.env.timeout(self.model_runtime_s) # configuration file @@ -612,4 +613,4 @@ def run_once( # print("DONE", out_path) #for f in output_files: # print(f) - #open("plans.txt", "w").write("\n".join(output_files)) + #slide_#open("plans.txt", "w").write("\n".join(output_files)) From 3a9669b51542c354ffe6e89e4bfab92705b91e4f Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Fri, 15 Oct 2021 00:33:46 -0700 Subject: [PATCH 20/26] stash --- stl/offline/run_2_eval_yahoo_keys.sh | 5 +- wikipedia/notebooks/Wikipedia Plots.ipynb | 101 ++++++++++++++++++++++ wikipedia/run_1_generate_plan.sh | 4 +- wikipedia/run_2_prepare_data.sh | 2 +- wikipedia/run_3_run_predictions.sh | 4 +- 5 files changed, 109 insertions(+), 7 deletions(-) diff --git a/stl/offline/run_2_eval_yahoo_keys.sh b/stl/offline/run_2_eval_yahoo_keys.sh index ed2eab8..a3cb4bc 100644 --- a/stl/offline/run_2_eval_yahoo_keys.sh +++ b/stl/offline/run_2_eval_yahoo_keys.sh @@ -1,6 +1,7 @@ set -ex data_dir="./yahoo_train_data" +results_dir="/data/wooders/stl/results" tmp_script=`mktemp` for key_prio in "lifo" "fifo" @@ -11,8 +12,8 @@ do for slide in 6 12 18 24 48 96 168 192 336 672 do echo \" python evaluation.py --offline-yahoo-csv-path $data \ - --offline-plan-path ./offline_1_slide/plan/${key_prio}_slide_${slide}_plan.json \ - --output-path ./offline_1_slide/single_key/${key_prio}_slide_${slide}_key_${key} \" >> $tmp_script + --offline-plan-path ${results_dir}/plan/${key_prio}_slide_${slide}_plan.json \ + --output-path ${results_dir}/single_key/${key_prio}_slide_${slide}_key_${key} \" >> $tmp_script done done done diff --git a/wikipedia/notebooks/Wikipedia Plots.ipynb b/wikipedia/notebooks/Wikipedia Plots.ipynb index ad9d8b5..6dc27f1 100644 --- a/wikipedia/notebooks/Wikipedia Plots.ipynb +++ b/wikipedia/notebooks/Wikipedia Plots.ipynb @@ -908,6 +908,107 @@ "plt.legend()" ] }, + { + "cell_type": "code", + "execution_count": 247, + "id": "aece6567", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_1.json\n", + "plan-round_robin_lifo-always_process {'top1': 0.06871169495648626, 'top5': 0.12280371338214406, 'top10': 0.13392345661573715, 'top100': 0.13392345661573715}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_2.json\n", + "plan-round_robin_lifo-always_process {'top1': 0.07980004865378126, 'top5': 0.1408997810579843, 'top10': 0.15672010735221414, 'top100': 0.15672010735221414}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_4.json\n", + "plan-round_robin_lifo-always_process {'top1': 0.08357464039362479, 'top5': 0.16605849440089146, 'top10': 0.1989547284412741, 'top100': 0.1989547284412741}\n", + "/data/wooders/wikipedia/predictions/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_1.json\n", + "plan-weighted_round_robin_lifo-always_process {'top1': 0.06215912925426309, 'top5': 0.1438268553177798, 'top10': 0.16673336943130007, 'top100': 0.16673336943130007}\n", + "/data/wooders/wikipedia/predictions/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_2.json\n", + "plan-weighted_round_robin_lifo-always_process {'top1': 0.07800299770071646, 'top5': 0.1567436495044377, 'top10': 0.18105484536729682, 'top100': 0.18105484536729682}\n", + "/data/wooders/wikipedia/predictions/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_4.json\n", + "plan-weighted_round_robin_lifo-always_process {'top1': 0.12434964804482426, 'top5': 0.2397768203969207, 'top10': 0.26929867928526025, 'top100': 0.26929867928526025}\n" + ] + }, + { + "data": { + "text/plain": [ + "{'round_robin': [0.8660765433842629, 0.8432798926477858, 0.801045271558726],\n", + " 'weighted_round_robin': [0.8332666305687,\n", + " 0.8189451546327031,\n", + " 0.7307013207147397]}" + ] + }, + "execution_count": 247, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "constants = [0.25]\n", + "policies = [\"lifo\"]\n", + "#key_policies = [\"random\", \"weighted_random\", \"round_robin\", \"weighted_round_robin\"]\n", + "key_policies = [\"round_robin\", \"weighted_round_robin\"]\n", + "replicas = [1, 2, 4]\n", + "#key_policies = [\"weighted_random\", \"weighted_round_robin\"]\n", + "d = artifact_dir\n", + "metric = 'top10'\n", + "d = \"/data/wooders/wikipedia/predictions\"\n", + "\n", + "replica_results = {}\n", + "\n", + "\n", + "for key_policy in key_policies:\n", + " scores = []\n", + " for replica in replicas:\n", + " for policy in policies: \n", + " \n", + " name = f\"plan-{key_policy}_{policy}-always_process\"\n", + " for constant in constants: \n", + " print(f'{d}/{name}-{constant}-100_replicas_{replica}.json')\n", + " with open(f'{d}/{name}-{constant}-100_replicas_{replica}.json') as results_file:\n", + " results = json.load(results_file)\n", + " print(name, results)\n", + " scores.append(1-results[metric])\n", + " replica_results[key_policy] = scores\n", + "replica_results" + ] + }, + { + "cell_type": "code", + "execution_count": 248, + "id": "e1822437", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import seaborn\n", + "df = pd.DataFrame({\n", + " 'Model Runtime Const': replicas, \n", + " **replica_results\n", + "})\n", + "fig, ax1 = plt.subplots(figsize=(10, 5))\n", + "tidy = df.melt(id_vars='Model Runtime Const').rename(columns=str.title)\n", + "seaborn.barplot(x='Model Runtime Const', y='Value', hue='Variable', data=tidy, ax=ax1)\n", + "ax1.set(xlabel='Resources', ylabel=f'{metric} Error')\n", + "ax1.legend_.remove()\n", + "plt.legend(loc='lower left')\n", + "seaborn.despine(fig)" + ] + }, { "cell_type": "markdown", "id": "cdf98fa5", diff --git a/wikipedia/run_1_generate_plan.sh b/wikipedia/run_1_generate_plan.sh index 6027c32..9d723a2 100644 --- a/wikipedia/run_1_generate_plan.sh +++ b/wikipedia/run_1_generate_plan.sh @@ -1,8 +1,8 @@ set -xe -for replicas in 1 2 4 +for replicas in 1 2 4 6 8 do - for model_runtime in 0.001 0.05 0.01 0.1 1.0 5.0 10.0 + for model_runtime in 0.25 #0.001 0.05 0.01 0.1 1.0 5.0 10.0 do for event_policy in "lifo" #"fifo" do diff --git a/wikipedia/run_2_prepare_data.sh b/wikipedia/run_2_prepare_data.sh index a7dcd74..a25969f 100644 --- a/wikipedia/run_2_prepare_data.sh +++ b/wikipedia/run_2_prepare_data.sh @@ -2,7 +2,7 @@ set -xe plan_dir=/data/wooders/wiki-plans -for replicas in 2 +for replicas in 6 8 do for model_runtime in 0.25 do diff --git a/wikipedia/run_3_run_predictions.sh b/wikipedia/run_3_run_predictions.sh index abbc646..78b92c7 100644 --- a/wikipedia/run_3_run_predictions.sh +++ b/wikipedia/run_3_run_predictions.sh @@ -5,7 +5,7 @@ dpr_dir=~/DPR cd $dpr_dir -for replicas in 1 2 4 +for replicas in 6 8 do for event_policy in "lifo" do @@ -19,7 +19,7 @@ do #plan_file=plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100 plan_file=plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100_replicas_${replicas} echo $plan_file - CUDA_VISIBLE_DEVICES=0,2,3,4 bash ${dpr_dir}/evaluate_retrieval_single_doc_stream.sh $plan_file & + CUDA_VISIBLE_DEVICES=0,1,2,3,4 bash ${dpr_dir}/evaluate_retrieval_single_doc_stream.sh $plan_file & #pid=$! done From a9a65ca27846e6f9a30e5b6b58cf060aa4595179 Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Fri, 15 Oct 2021 04:37:37 -0700 Subject: [PATCH 21/26] stash --- wikipedia/notebooks/Wikipedia Plots.ipynb | 42 +++++++++++++++++------ wikipedia/preprocessing/log_data.py | 16 +++++---- wikipedia/run_1_generate_plan.sh | 2 +- wikipedia/run_2_prepare_data.sh | 2 +- wikipedia/run_3_run_predictions.sh | 4 +-- 5 files changed, 44 insertions(+), 22 deletions(-) diff --git a/wikipedia/notebooks/Wikipedia Plots.ipynb b/wikipedia/notebooks/Wikipedia Plots.ipynb index 6dc27f1..1d8013b 100644 --- a/wikipedia/notebooks/Wikipedia Plots.ipynb +++ b/wikipedia/notebooks/Wikipedia Plots.ipynb @@ -910,7 +910,7 @@ }, { "cell_type": "code", - "execution_count": 247, + "execution_count": 257, "id": "aece6567", "metadata": {}, "outputs": [ @@ -924,24 +924,44 @@ "plan-round_robin_lifo-always_process {'top1': 0.07980004865378126, 'top5': 0.1408997810579843, 'top10': 0.15672010735221414, 'top100': 0.15672010735221414}\n", "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_4.json\n", "plan-round_robin_lifo-always_process {'top1': 0.08357464039362479, 'top5': 0.16605849440089146, 'top10': 0.1989547284412741, 'top100': 0.1989547284412741}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_8.json\n", + "plan-round_robin_lifo-always_process {'top1': 0.12422408989963196, 'top5': 0.25539311470521303, 'top10': 0.2912321177735402, 'top100': 0.2912321177735402}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_16.json\n", + "plan-round_robin_lifo-always_process {'top1': 0.19127213943232024, 'top5': 0.38433348243363075, 'top10': 0.4554621716850688, 'top100': 0.4554621716850688}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_32.json\n", + "plan-round_robin_lifo-always_process {'top1': 0.18883945036921942, 'top5': 0.40024797733675477, 'top10': 0.46685657336127, 'top100': 0.46685657336127}\n", "/data/wooders/wikipedia/predictions/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_1.json\n", "plan-weighted_round_robin_lifo-always_process {'top1': 0.06215912925426309, 'top5': 0.1438268553177798, 'top10': 0.16673336943130007, 'top100': 0.16673336943130007}\n", "/data/wooders/wikipedia/predictions/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_2.json\n", "plan-weighted_round_robin_lifo-always_process {'top1': 0.07800299770071646, 'top5': 0.1567436495044377, 'top10': 0.18105484536729682, 'top100': 0.18105484536729682}\n", "/data/wooders/wikipedia/predictions/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_4.json\n", - "plan-weighted_round_robin_lifo-always_process {'top1': 0.12434964804482426, 'top5': 0.2397768203969207, 'top10': 0.26929867928526025, 'top100': 0.26929867928526025}\n" + "plan-weighted_round_robin_lifo-always_process {'top1': 0.12434964804482426, 'top5': 0.2397768203969207, 'top10': 0.26929867928526025, 'top100': 0.26929867928526025}\n", + "/data/wooders/wikipedia/predictions/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_8.json\n", + "plan-weighted_round_robin_lifo-always_process {'top1': 0.14424276667372932, 'top5': 0.29131059161428535, 'top10': 0.34781175695082045, 'top100': 0.34781175695082045}\n", + "/data/wooders/wikipedia/predictions/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_16.json\n", + "plan-weighted_round_robin_lifo-always_process {'top1': 0.18262432218220057, 'top5': 0.3638204204628387, 'top10': 0.4380959107281588, 'top100': 0.4380959107281588}\n", + "/data/wooders/wikipedia/predictions/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_32.json\n", + "plan-weighted_round_robin_lifo-always_process {'top1': 0.20202305561441095, 'top5': 0.41511092277389333, 'top10': 0.489213770589574, 'top100': 0.489213770589574}\n" ] }, { "data": { "text/plain": [ - "{'round_robin': [0.8660765433842629, 0.8432798926477858, 0.801045271558726],\n", - " 'weighted_round_robin': [0.8332666305687,\n", - " 0.8189451546327031,\n", - " 0.7307013207147397]}" + "{'round_robin': [0.877196286617856,\n", + " 0.8591002189420157,\n", + " 0.8339415055991085,\n", + " 0.7446068852947869,\n", + " 0.6156665175663693,\n", + " 0.5997520226632452],\n", + " 'weighted_round_robin': [0.8561731446822202,\n", + " 0.8432563504955624,\n", + " 0.7602231796030793,\n", + " 0.7086894083857147,\n", + " 0.6361795795371613,\n", + " 0.5848890772261066]}" ] }, - "execution_count": 247, + "execution_count": 257, "metadata": {}, "output_type": "execute_result" } @@ -951,10 +971,10 @@ "policies = [\"lifo\"]\n", "#key_policies = [\"random\", \"weighted_random\", \"round_robin\", \"weighted_round_robin\"]\n", "key_policies = [\"round_robin\", \"weighted_round_robin\"]\n", - "replicas = [1, 2, 4]\n", + "replicas = [1, 2, 4, 8, 16, 32]\n", "#key_policies = [\"weighted_random\", \"weighted_round_robin\"]\n", "d = artifact_dir\n", - "metric = 'top10'\n", + "metric = 'top5'\n", "d = \"/data/wooders/wikipedia/predictions\"\n", "\n", "replica_results = {}\n", @@ -978,13 +998,13 @@ }, { "cell_type": "code", - "execution_count": 248, + "execution_count": 258, "id": "e1822437", "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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MBgCmhMlJCSob9++ateuHasgOMipU6c0cuRIDRgwQIMGDdJjjz2mkydPOrsslzFv3jz+vDvIRx99pCFDhigyMlKDBg3S+++/7+ySapzf+w0vLCxUXFycbrvtNg0aNEiTJ092YpU1y5gxYzR48GANGTJEUVFRSk9Pr7G/69zF6URffPGFmjRpogceeECLFi1S27ZtnV1SjZeXl6fvvvtO3bt3l3TxB/b06dN6/vnnnVxZzfftt99q1qxZOnjwoBYvXsyf92pktVoVFhamV199VW3bttX+/fv15z//Wbt375abG/9dXlV+7zf8ueeek5ubmyZOnCiTyaQTJ06oQYMGTq62Zjh79qztofQffvih5s+fr6SkpBr5u87fVCfq2rVrudUUUL18fHxsf4klqUuXLjp69KgTK3INRUVFmjp1quLi4liKzUHc3Nx09uxZSRf/UfP39yecVbFL/Ybn5+dr/fr1euKJJ2x/1glnVee3KwadO3dOJpOpxv6u15i1OIHKKi0t1b///W/17dvX2aXUeLNnz9bgwYN17bXXOrsUl2AymfTyyy9rzJgx8vb2Vn5+vhYvXuzsslzC4cOH5ePjo3nz5ik1NVV16tTRE088oa5duzq7tBrjmWee0WeffSar1aply5aV2VeTftf5zym4rGnTpsnb21sPPvigs0up0fbs2aO9e/cqKirK2aW4jJKSEi1evFgLFizQRx99pIULFyomJkb5+fnOLq3GKykp0eHDh9W+fXutXbtW48aN0+OPP65z5845u7QaY/r06dq2bZtiYmKUmJhYZl9N+l0noMElJSQk6KefftLLL7/MtE8127Vrlw4dOqR+/fqpb9++OnbsmEaMGKHt27c7u7QaKz09XTk5OQoNDZUkhYaGqnbt2jp48KCTK6v5GjduLHd3d0VEREiSgoODVb9+fWVkZDi5sppnyJAhSk1N1alTpyTVvN/1q/8bAJU0a9Ys7du3T/Pnz5enp6ezy6nxRo0ape3bt2vr1q3aunWrAgICtHz5cvXs2dPZpdVYAQEBOnbsmA4dOiTp4lrIJ06cULNmzZxcWc3n6+ur7t2729aUzsjIUG5urpo3b+7kyq5++fn5ysrKsr3funWr6tWrJx8fnxr5u85dnE703HPP6f3339eJEydUv359+fj46J133nF2WTXa999/r4iICLVo0UK1atWSJDVt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\n", "text/plain": [ "
" ] diff --git a/wikipedia/preprocessing/log_data.py b/wikipedia/preprocessing/log_data.py index 9cbaf06..c7fdb7a 100644 --- a/wikipedia/preprocessing/log_data.py +++ b/wikipedia/preprocessing/log_data.py @@ -44,19 +44,21 @@ def log_plans(run, config, plan_dir): def log_plan_data(run, config, plan_name, plan_path): artifact = wandb.Artifact(plan_name, type='dataset') - artifact.add_folder(plan_path) + artifact.add_dir(plan_path) run.log_artifact def log_experiment(run, config): # log experiment output artifact = wandb.Artifact("prediction_results", type='dataset') - files = os.listdir(config["directory"]["dpr_dir"]) - for filename in files: - if "plan-" in filename and '.json' in filename: - artifact.add_file(os.path.join(config["directory"]["dpr_dir"], filename)) - if "plan-" in filename and '.pkl' in filename: - artifact.add_file(os.path.join(config["directory"]["dpr_dir"], filename)) + #files = os.listdir(config["directory"]["dpr_dir"]) + #files = os.listdir("/data/wooders/wikipedia/predictions") + artifact.add_dir("/data/wooders/wikipedia/predictions") + #for filename in files: + # if "plan-" in filename and '.json' in filename: + # artifact.add_file(os.path.join(config["directory"]["dpr_dir"], filename)) + # if "plan-" in filename and '.pkl' in filename: + # artifact.add_file(os.path.join(config["directory"]["dpr_dir"], filename)) run.log_artifact(artifact) diff --git a/wikipedia/run_1_generate_plan.sh b/wikipedia/run_1_generate_plan.sh index 9d723a2..8bb1f25 100644 --- a/wikipedia/run_1_generate_plan.sh +++ b/wikipedia/run_1_generate_plan.sh @@ -1,6 +1,6 @@ set -xe -for replicas in 1 2 4 6 8 +for replicas in 16 32 do for model_runtime in 0.25 #0.001 0.05 0.01 0.1 1.0 5.0 10.0 do diff --git a/wikipedia/run_2_prepare_data.sh b/wikipedia/run_2_prepare_data.sh index a25969f..89faacc 100644 --- a/wikipedia/run_2_prepare_data.sh +++ b/wikipedia/run_2_prepare_data.sh @@ -2,7 +2,7 @@ set -xe plan_dir=/data/wooders/wiki-plans -for replicas in 6 8 +for replicas in 16 32 do for model_runtime in 0.25 do diff --git a/wikipedia/run_3_run_predictions.sh b/wikipedia/run_3_run_predictions.sh index 78b92c7..9b2d73b 100644 --- a/wikipedia/run_3_run_predictions.sh +++ b/wikipedia/run_3_run_predictions.sh @@ -5,7 +5,7 @@ dpr_dir=~/DPR cd $dpr_dir -for replicas in 6 8 +for replicas in 16 32 do for event_policy in "lifo" do @@ -19,7 +19,7 @@ do #plan_file=plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100 plan_file=plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100_replicas_${replicas} echo $plan_file - CUDA_VISIBLE_DEVICES=0,1,2,3,4 bash ${dpr_dir}/evaluate_retrieval_single_doc_stream.sh $plan_file & + CUDA_VISIBLE_DEVICES=4 bash ${dpr_dir}/evaluate_retrieval_single_doc_stream.sh $plan_file & #pid=$! done From 2b2193b9ec4367003d96a5bcec4d647b9d8b897d Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Fri, 15 Oct 2021 09:24:09 -0700 Subject: [PATCH 22/26] wiki graph --- stl/notebooks/STL Offline Plots.ipynb | 65 +++++++---------------- wikipedia/notebooks/Wikipedia Plots.ipynb | 19 +++---- 2 files changed, 29 insertions(+), 55 deletions(-) diff --git a/stl/notebooks/STL Offline Plots.ipynb b/stl/notebooks/STL Offline Plots.ipynb index 428ec9f..7ed30d7 100644 --- a/stl/notebooks/STL Offline Plots.ipynb +++ b/stl/notebooks/STL Offline Plots.ipynb @@ -22,14 +22,14 @@ }, { "cell_type": "code", - "execution_count": 352, + "execution_count": 412, "id": "0df714c8", "metadata": {}, "outputs": [ { "data": { "text/html": [ - "Finishing last run (ID:29jne90e) before initializing another..." + "Finishing last run (ID:1r9i8p8d) before initializing another..." ], "text/plain": [ "" @@ -41,7 +41,7 @@ { "data": { "text/html": [ - "
Waiting for W&B process to finish, PID 56004... (success)." + "
Waiting for W&B process to finish, PID 30648... (success)." ], "text/plain": [ "" @@ -58,7 +58,7 @@ "version_minor": 0 }, "text/plain": [ - "VBox(children=(Label(value=' 0.51MB of 0.51MB uploaded (0.00MB deduped)\\r'), FloatProgress(value=1.0, max=1.0)…" + "VBox(children=(Label(value=' 0.66MB of 0.66MB uploaded (0.00MB deduped)\\r'), FloatProgress(value=1.0, max=1.0)…" ] }, "metadata": {}, @@ -75,9 +75,9 @@ "
\n", "
\n", "
\n", - "Synced 7 W&B file(s), 0 media file(s), 0 artifact file(s) and 1 other file(s)\n", - "
Synced drawn-morning-23: https://wandb.ai/ucb-ralf/experiments-stl_notebooks/runs/29jne90e
\n", - "Find logs at: ./wandb/run-20211014_214005-29jne90e/logs
\n" + "Synced 6 W&B file(s), 0 media file(s), 0 artifact file(s) and 1 other file(s)\n", + "
Synced daily-waterfall-26: https://wandb.ai/ucb-ralf/experiments-stl_notebooks/runs/1r9i8p8d
\n", + "Find logs at: ./wandb/run-20211015_043830-1r9i8p8d/logs
\n" ], "text/plain": [ "" @@ -89,7 +89,7 @@ { "data": { "text/html": [ - "Successfully finished last run (ID:29jne90e). Initializing new run:
" + "Successfully finished last run (ID:1r9i8p8d). Initializing new run:
" ], "text/plain": [ "" @@ -110,7 +110,7 @@ "data": { "text/html": [ "\n", - " Syncing run vocal-terrain-24 to Weights & Biases (docs).
\n", + " Syncing run rural-voice-27 to Weights & Biases (docs).
\n", "\n", " " ], @@ -125,13 +125,13 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[34m\u001b[1mwandb\u001b[0m: Downloading large artifact results:v11, 1446.02MB. 6579 files... Done. 0:0:0\n" + "\u001b[34m\u001b[1mwandb\u001b[0m: Downloading large artifact results:v12, 2349.20MB. 11474 files... Done. 0:0:0\n" ] } ], "source": [ "run = wandb.init()\n", - "results_dir = run.use_artifact('ucb-ralf/stl/results:v11', type='dataset').download()\n", + "results_dir = run.use_artifact('ucb-ralf/stl/results:v12', type='dataset').download()\n", "yahoo_train_dir = run.use_artifact('ucb-ralf/stl/yahoo_train_data:v0', type='dataset').download()\n", "yahoo_eval_dir = run.use_artifact('ucb-ralf/stl/yahoo_eval_data:v0', type='dataset').download()\n", "oracle_dir = run.use_artifact('ucb-ralf/stl/oracle:v0', type='dataset').download()" @@ -270,7 +270,7 @@ }, { "cell_type": "code", - "execution_count": 358, + "execution_count": 413, "id": "5fecde25", "metadata": {}, "outputs": [], @@ -297,7 +297,7 @@ }, { "cell_type": "code", - "execution_count": 359, + "execution_count": 414, "id": "21099224", "metadata": {}, "outputs": [ @@ -308,7 +308,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mbaseline_results\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mkey\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m101\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mlosses\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_loss_per_key\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34mf\"{artifact_dir}/plan_eval\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0mbaseline_results\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlosses\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mbaseline_results\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mkey\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m101\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mlosses\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_loss_per_key\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34mf\"{artifact_dir}/plan_eval\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0mbaseline_results\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlosses\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mTypeError\u001b[0m: get_loss_per_key() missing 1 required positional argument: 'oracle_filename'" ] } @@ -341,7 +341,7 @@ }, { "cell_type": "code", - "execution_count": 135, + "execution_count": null, "id": "da85dcf1", "metadata": {}, "outputs": [], @@ -356,18 +356,10 @@ }, { "cell_type": "code", - "execution_count": 136, + "execution_count": null, "id": "303fcfcf", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1100 95.26955983050661\n" - ] - } - ], + "outputs": [], "source": [ "lp_total_cost = 0\n", "lp_total_loss = 0\n", @@ -379,29 +371,10 @@ }, { "cell_type": "code", - "execution_count": 260, + "execution_count": null, "id": "656758ed", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "max_fits_1100\n" - ] - }, - { - "ename": "TypeError", - "evalue": "string indices must be integers", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mkey\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mbaseline_results\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkeys\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mloss\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mbaseline_results\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 12\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0mloss\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'slide_size'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mslide_size\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 13\u001b[0m \u001b[0mbaseline_total_cost\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mloss\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'n_fits'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 14\u001b[0m \u001b[0mbaseline_total_loss\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mloss\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'loss'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mTypeError\u001b[0m: string indices must be integers" - ] - } - ], + "outputs": [], "source": [ "experiments = [(\"max_fits_1100\", 96), (\"max_fits_2100\", 48), (\"max_fits_4200\", 24), (\"max_fits_8400\", 12)]\n", "\n", diff --git a/wikipedia/notebooks/Wikipedia Plots.ipynb b/wikipedia/notebooks/Wikipedia Plots.ipynb index 1d8013b..d2f8647 100644 --- a/wikipedia/notebooks/Wikipedia Plots.ipynb +++ b/wikipedia/notebooks/Wikipedia Plots.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 184, + "execution_count": 266, "id": "e0030940", "metadata": {}, "outputs": [], @@ -24,7 +24,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 267, "id": "016e13bb", "metadata": {}, "outputs": [ @@ -32,7 +32,6 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[34m\u001b[1mwandb\u001b[0m: Currently logged in as: \u001b[33mucb-ralf\u001b[0m (use `wandb login --relogin` to force relogin)\n", "\u001b[34m\u001b[1mwandb\u001b[0m: wandb version 0.12.4 is available! To upgrade, please run:\n", "\u001b[34m\u001b[1mwandb\u001b[0m: $ pip install wandb --upgrade\n" ] @@ -41,7 +40,7 @@ "data": { "text/html": [ "\n", - " Syncing run royal-planet-167 to Weights & Biases (docs).
\n", + " Syncing run toasty-plasma-547 to Weights & Biases (docs).
\n", "\n", " " ], @@ -56,14 +55,16 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[34m\u001b[1mwandb\u001b[0m: Downloading large artifact questions:latest, 60.97MB. 2 files... Done. 0:0:0\n" + "\u001b[34m\u001b[1mwandb\u001b[0m: Downloading large artifact questions:latest, 84.36MB. 4 files... Done. 0:0:0\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: Downloading large artifact prediction_results:latest, 6400.51MB. 413 files... Done. 0:0:0\n" ] } ], "source": [ "run = wandb.init(job_type=\"evaluation\", project=\"wiki-workload\")\n", "pageview_dir = run.use_artifact('pageviews:latest').download()\n", - "questions_dir = run.use_artifact('questions:latest').download()" + "questions_dir = run.use_artifact('questions:latest').download()\n", + "predictions_dir = run.use_artifact('prediction_results:latest').download()" ] }, { @@ -910,7 +911,7 @@ }, { "cell_type": "code", - "execution_count": 257, + "execution_count": 268, "id": "aece6567", "metadata": {}, "outputs": [ @@ -961,7 +962,7 @@ " 0.5848890772261066]}" ] }, - "execution_count": 257, + "execution_count": 268, "metadata": {}, "output_type": "execute_result" } @@ -998,7 +999,7 @@ }, { "cell_type": "code", - "execution_count": 258, + "execution_count": 269, "id": "e1822437", "metadata": {}, "outputs": [ From 7f38ccbe0cfa871cab06691d92211fa4eba9298c Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Fri, 15 Oct 2021 09:25:37 -0700 Subject: [PATCH 23/26] add rght filepath --- wikipedia/notebooks/Wikipedia Plots.ipynb | 32 +++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/wikipedia/notebooks/Wikipedia Plots.ipynb b/wikipedia/notebooks/Wikipedia Plots.ipynb index d2f8647..369a44e 100644 --- a/wikipedia/notebooks/Wikipedia Plots.ipynb +++ b/wikipedia/notebooks/Wikipedia Plots.ipynb @@ -911,7 +911,7 @@ }, { "cell_type": "code", - "execution_count": 268, + "execution_count": 270, "id": "aece6567", "metadata": {}, "outputs": [ @@ -919,29 +919,29 @@ "name": "stdout", "output_type": "stream", "text": [ - "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_1.json\n", + "./artifacts/prediction_results:v3622/plan-round_robin_lifo-always_process-0.25-100_replicas_1.json\n", "plan-round_robin_lifo-always_process {'top1': 0.06871169495648626, 'top5': 0.12280371338214406, 'top10': 0.13392345661573715, 'top100': 0.13392345661573715}\n", - "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_2.json\n", + "./artifacts/prediction_results:v3622/plan-round_robin_lifo-always_process-0.25-100_replicas_2.json\n", "plan-round_robin_lifo-always_process {'top1': 0.07980004865378126, 'top5': 0.1408997810579843, 'top10': 0.15672010735221414, 'top100': 0.15672010735221414}\n", - "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_4.json\n", + "./artifacts/prediction_results:v3622/plan-round_robin_lifo-always_process-0.25-100_replicas_4.json\n", "plan-round_robin_lifo-always_process {'top1': 0.08357464039362479, 'top5': 0.16605849440089146, 'top10': 0.1989547284412741, 'top100': 0.1989547284412741}\n", - "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_8.json\n", + "./artifacts/prediction_results:v3622/plan-round_robin_lifo-always_process-0.25-100_replicas_8.json\n", "plan-round_robin_lifo-always_process {'top1': 0.12422408989963196, 'top5': 0.25539311470521303, 'top10': 0.2912321177735402, 'top100': 0.2912321177735402}\n", - "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_16.json\n", + "./artifacts/prediction_results:v3622/plan-round_robin_lifo-always_process-0.25-100_replicas_16.json\n", "plan-round_robin_lifo-always_process {'top1': 0.19127213943232024, 'top5': 0.38433348243363075, 'top10': 0.4554621716850688, 'top100': 0.4554621716850688}\n", - "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_32.json\n", + "./artifacts/prediction_results:v3622/plan-round_robin_lifo-always_process-0.25-100_replicas_32.json\n", "plan-round_robin_lifo-always_process {'top1': 0.18883945036921942, 'top5': 0.40024797733675477, 'top10': 0.46685657336127, 'top100': 0.46685657336127}\n", - "/data/wooders/wikipedia/predictions/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_1.json\n", + "./artifacts/prediction_results:v3622/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_1.json\n", "plan-weighted_round_robin_lifo-always_process {'top1': 0.06215912925426309, 'top5': 0.1438268553177798, 'top10': 0.16673336943130007, 'top100': 0.16673336943130007}\n", - "/data/wooders/wikipedia/predictions/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_2.json\n", + "./artifacts/prediction_results:v3622/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_2.json\n", "plan-weighted_round_robin_lifo-always_process {'top1': 0.07800299770071646, 'top5': 0.1567436495044377, 'top10': 0.18105484536729682, 'top100': 0.18105484536729682}\n", - "/data/wooders/wikipedia/predictions/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_4.json\n", + "./artifacts/prediction_results:v3622/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_4.json\n", "plan-weighted_round_robin_lifo-always_process {'top1': 0.12434964804482426, 'top5': 0.2397768203969207, 'top10': 0.26929867928526025, 'top100': 0.26929867928526025}\n", - "/data/wooders/wikipedia/predictions/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_8.json\n", + "./artifacts/prediction_results:v3622/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_8.json\n", "plan-weighted_round_robin_lifo-always_process {'top1': 0.14424276667372932, 'top5': 0.29131059161428535, 'top10': 0.34781175695082045, 'top100': 0.34781175695082045}\n", - "/data/wooders/wikipedia/predictions/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_16.json\n", + "./artifacts/prediction_results:v3622/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_16.json\n", "plan-weighted_round_robin_lifo-always_process {'top1': 0.18262432218220057, 'top5': 0.3638204204628387, 'top10': 0.4380959107281588, 'top100': 0.4380959107281588}\n", - "/data/wooders/wikipedia/predictions/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_32.json\n", + "./artifacts/prediction_results:v3622/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_32.json\n", "plan-weighted_round_robin_lifo-always_process {'top1': 0.20202305561441095, 'top5': 0.41511092277389333, 'top10': 0.489213770589574, 'top100': 0.489213770589574}\n" ] }, @@ -962,7 +962,7 @@ " 0.5848890772261066]}" ] }, - "execution_count": 268, + "execution_count": 270, "metadata": {}, "output_type": "execute_result" } @@ -976,7 +976,7 @@ "#key_policies = [\"weighted_random\", \"weighted_round_robin\"]\n", "d = artifact_dir\n", "metric = 'top5'\n", - "d = \"/data/wooders/wikipedia/predictions\"\n", + "d = predictions_dir #\"/data/wooders/wikipedia/predictions\"\n", "\n", "replica_results = {}\n", "\n", @@ -999,7 +999,7 @@ }, { "cell_type": "code", - "execution_count": 269, + "execution_count": 271, "id": "e1822437", "metadata": {}, "outputs": [ From 5e0263e83145a1ff0b651a41a21144dca44f2ef3 Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Tue, 19 Oct 2021 12:43:47 -0700 Subject: [PATCH 24/26] reorganize wiki dir --- wikipedia/benchmark_bert.py | 7 - wikipedia/config.yml | 35 - wikipedia/config_aws.yml | 29 - wikipedia/notebooks/Wikipedia Plots.ipynb | 148 +++-- wikipedia/preprocessing/embedding.py | 152 ----- wikipedia/preprocessing/generate_diffs.py | 442 ------------- wikipedia/preprocessing/log_data.py | 79 --- wikipedia/preprocessing/wiki_api_data.py | 731 --------------------- wikipedia/run_0_generate_data.sh | 1 - wikipedia/run_1_generate_plan.sh | 19 - wikipedia/run_2_prepare_data.sh | 20 - wikipedia/run_3_run_predictions.sh | 30 - wikipedia/run_4_run_optimal_predictions.sh | 8 - wikipedia/run_5_pipeline_predict.sh | 30 - wikipedia/run_wiki.sh | 10 - wikipedia/simulate.py | 616 ----------------- wikipedia/wiki_eval.py | 325 --------- 17 files changed, 95 insertions(+), 2587 deletions(-) delete mode 100644 wikipedia/benchmark_bert.py delete mode 100644 wikipedia/config.yml delete mode 100644 wikipedia/config_aws.yml delete mode 100644 wikipedia/preprocessing/embedding.py delete mode 100644 wikipedia/preprocessing/generate_diffs.py delete mode 100644 wikipedia/preprocessing/log_data.py delete mode 100644 wikipedia/preprocessing/wiki_api_data.py delete mode 100644 wikipedia/run_0_generate_data.sh delete mode 100644 wikipedia/run_1_generate_plan.sh delete mode 100644 wikipedia/run_2_prepare_data.sh delete mode 100644 wikipedia/run_3_run_predictions.sh delete mode 100644 wikipedia/run_4_run_optimal_predictions.sh delete mode 100644 wikipedia/run_5_pipeline_predict.sh delete mode 100644 wikipedia/run_wiki.sh delete mode 100644 wikipedia/simulate.py delete mode 100644 wikipedia/wiki_eval.py diff --git a/wikipedia/benchmark_bert.py b/wikipedia/benchmark_bert.py deleted file mode 100644 index 4a636c0..0000000 --- a/wikipedia/benchmark_bert.py +++ /dev/null @@ -1,7 +0,0 @@ -from transformers import PyTorchBenchmark, PyTorchBenchmarkArguments -from pprint import pprint - -args = PyTorchBenchmarkArguments(models=["bert-base-uncased"], batch_sizes=[1], sequence_lengths=[100], no_multi_process=True) -benchmark = PyTorchBenchmark(args) -results = benchmark.run() -pprint(results) diff --git a/wikipedia/config.yml b/wikipedia/config.yml deleted file mode 100644 index 2ae74c2..0000000 --- a/wikipedia/config.yml +++ /dev/null @@ -1,35 +0,0 @@ -[directory] -data_dir = /data/wooders/wikipedia -revisions_dir = %(data_dir)s/recentchanges -raw_doc_dir = %(data_dir)s/doc_xml/ -parsed_doc_dir = %(data_dir)s/doc_pkl/ -parsed_tmp_dir = %(data_dir)s/parsed_tmp/ -diff_dir = %(data_dir)s/diffs/ -embedding_dir = %(data_dir)s/embeddings/ -exp_dir = %(data_dir)s/simulation_output/ -dpr_dir = /home/eecs/wooders/DPR - -[files] -data_dir = /data/wooders/wikipedia -raw_questions_file = %(data_dir)s/10042021_questions_revid_filtered.csv -model_file = %(data_dir)s/bert-base-encoder.cp -changes_file = %(data_dir)s/changes.csv -titles_file = %(data_dir)s/top_titles.csv -revisions_file = %(data_dir)s/title_revisions_timestamps.json -edits_file = %(data_dir)s/edits.csv -questions_file = %(data_dir)s/questions.csv -train_questions_file = %(data_dir)s/train_questions.csv -test_questions_file = %(data_dir)s/test_questions.csv -raw_pageview_file = %(data_dir)s/top_title_views.csv -pageview_file = %(data_dir)s/pageviews.csv -timestamp_weights_file = %(data_dir)s/timestamp_weights_file.json - -[simulation] -data_dir = /data/wooders/wikipedia -plan_dir = /data/wooders/wiki-plans -init_data_file = %(data_dir)s/init_data.json -optimal_plan_file = %(data_dir)s/optimal_plan.json -stream_edits_file = %(data_dir)s/edit_stream.json -stream_questions_file = %(data_dir)s/question_stream.json - - diff --git a/wikipedia/config_aws.yml b/wikipedia/config_aws.yml deleted file mode 100644 index b13c221..0000000 --- a/wikipedia/config_aws.yml +++ /dev/null @@ -1,29 +0,0 @@ -[directory] -data_dir = /home/ubuntu/experiments/wikipedia/result/wikipedia -revisions_dir = %(data_dir)s/recentchanges -raw_doc_dir = %(data_dir)s/doc_xml/ -parsed_doc_dir = %(data_dir)s/doc_pkl/ -parsed_tmp_dir = %(data_dir)s/parsed_tmp/ -diff_dir = %(data_dir)s/diffs/ -embedding_dir = %(data_dir)s/embeddings/ -exp_dir = %(data_dir)s/simulation_output/ - -[files] -data_dir = /home/ubuntu/experiments/wikipedia/result/wikipedia -raw_questions_file = %(data_dir)s/10052021_questions_revid.csv -model_file = %(data_dir)s/bert-base-encoder.cp -changes_file = %(data_dir)s/changes.csv -titles_file = %(data_dir)s/top_titles.csv -revisions_file = %(data_dir)s/title_revisions_timestamps.json -edits_file = %(data_dir)s/edits.csv -questions_file = %(data_dir)s/questions.csv -pageview_file = %(data_dir)s/top_title_views.csv - -[simulation] -data_dir = /home/ubuntu/experiments/wikipedia/result/wikipedia -plan_dir = /home/ubuntu/experiments/wikipedia/result/wiki-plans -init_data_file = %(data_dir)s/init_data.json -stream_edits_file = %(data_dir)s/edit_stream.json -stream_questions_file = %(data_dir)s/question_stream.json - - diff --git a/wikipedia/notebooks/Wikipedia Plots.ipynb b/wikipedia/notebooks/Wikipedia Plots.ipynb index 369a44e..6b56acc 100644 --- a/wikipedia/notebooks/Wikipedia Plots.ipynb +++ b/wikipedia/notebooks/Wikipedia Plots.ipynb @@ -911,7 +911,7 @@ }, { "cell_type": "code", - "execution_count": 270, + "execution_count": 280, "id": "aece6567", "metadata": {}, "outputs": [ @@ -919,99 +919,141 @@ "name": "stdout", "output_type": "stream", "text": [ - "./artifacts/prediction_results:v3622/plan-round_robin_lifo-always_process-0.25-100_replicas_1.json\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_1.json\n", "plan-round_robin_lifo-always_process {'top1': 0.06871169495648626, 'top5': 0.12280371338214406, 'top10': 0.13392345661573715, 'top100': 0.13392345661573715}\n", - "./artifacts/prediction_results:v3622/plan-round_robin_lifo-always_process-0.25-100_replicas_2.json\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_fifo-always_process-0.25-100_replicas_1.json\n", + "plan-round_robin_fifo-always_process {'top1': 0.0640895857365947, 'top5': 0.11222543964969277, 'top10': 0.12234071772174746, 'top100': 0.12234071772174746}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_2.json\n", "plan-round_robin_lifo-always_process {'top1': 0.07980004865378126, 'top5': 0.1408997810579843, 'top10': 0.15672010735221414, 'top100': 0.15672010735221414}\n", - "./artifacts/prediction_results:v3622/plan-round_robin_lifo-always_process-0.25-100_replicas_4.json\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_fifo-always_process-0.25-100_replicas_2.json\n", + "plan-round_robin_fifo-always_process {'top1': 0.06708728645306088, 'top5': 0.11490139761910367, 'top10': 0.1252442498293194, 'top100': 0.1252442498293194}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_4.json\n", "plan-round_robin_lifo-always_process {'top1': 0.08357464039362479, 'top5': 0.16605849440089146, 'top10': 0.1989547284412741, 'top100': 0.1989547284412741}\n", - "./artifacts/prediction_results:v3622/plan-round_robin_lifo-always_process-0.25-100_replicas_8.json\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_fifo-always_process-0.25-100_replicas_4.json\n", + "plan-round_robin_fifo-always_process {'top1': 0.0692296223054045, 'top5': 0.1186367524385746, 'top10': 0.1285087616043192, 'top100': 0.1285087616043192}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_8.json\n", "plan-round_robin_lifo-always_process {'top1': 0.12422408989963196, 'top5': 0.25539311470521303, 'top10': 0.2912321177735402, 'top100': 0.2912321177735402}\n", - "./artifacts/prediction_results:v3622/plan-round_robin_lifo-always_process-0.25-100_replicas_16.json\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_fifo-always_process-0.25-100_replicas_8.json\n", + "plan-round_robin_fifo-always_process {'top1': 0.06077798965714779, 'top5': 0.12347074102847816, 'top10': 0.1354536965102683, 'top100': 0.1354536965102683}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_16.json\n", "plan-round_robin_lifo-always_process {'top1': 0.19127213943232024, 'top5': 0.38433348243363075, 'top10': 0.4554621716850688, 'top100': 0.4554621716850688}\n", - "./artifacts/prediction_results:v3622/plan-round_robin_lifo-always_process-0.25-100_replicas_32.json\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_fifo-always_process-0.25-100_replicas_16.json\n", + "plan-round_robin_fifo-always_process {'top1': 0.07892114163743516, 'top5': 0.16019649849722595, 'top10': 0.17815916064379939, 'top100': 0.17815916064379939}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_32.json\n", "plan-round_robin_lifo-always_process {'top1': 0.18883945036921942, 'top5': 0.40024797733675477, 'top10': 0.46685657336127, 'top100': 0.46685657336127}\n", - "./artifacts/prediction_results:v3622/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_1.json\n", - "plan-weighted_round_robin_lifo-always_process {'top1': 0.06215912925426309, 'top5': 0.1438268553177798, 'top10': 0.16673336943130007, 'top100': 0.16673336943130007}\n", - "./artifacts/prediction_results:v3622/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_2.json\n", - "plan-weighted_round_robin_lifo-always_process {'top1': 0.07800299770071646, 'top5': 0.1567436495044377, 'top10': 0.18105484536729682, 'top100': 0.18105484536729682}\n", - "./artifacts/prediction_results:v3622/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_4.json\n", - "plan-weighted_round_robin_lifo-always_process {'top1': 0.12434964804482426, 'top5': 0.2397768203969207, 'top10': 0.26929867928526025, 'top100': 0.26929867928526025}\n", - "./artifacts/prediction_results:v3622/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_8.json\n", - "plan-weighted_round_robin_lifo-always_process {'top1': 0.14424276667372932, 'top5': 0.29131059161428535, 'top10': 0.34781175695082045, 'top100': 0.34781175695082045}\n", - "./artifacts/prediction_results:v3622/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_16.json\n", - "plan-weighted_round_robin_lifo-always_process {'top1': 0.18262432218220057, 'top5': 0.3638204204628387, 'top10': 0.4380959107281588, 'top100': 0.4380959107281588}\n", - "./artifacts/prediction_results:v3622/plan-weighted_round_robin_lifo-always_process-0.25-100_replicas_32.json\n", - "plan-weighted_round_robin_lifo-always_process {'top1': 0.20202305561441095, 'top5': 0.41511092277389333, 'top10': 0.489213770589574, 'top100': 0.489213770589574}\n" + "/data/wooders/wikipedia/predictions/plan-round_robin_fifo-always_process-0.25-100_replicas_32.json\n", + "plan-round_robin_fifo-always_process {'top1': 0.12397297360924736, 'top5': 0.21128296882234307, 'top10': 0.22860214547480598, 'top100': 0.22860214547480598}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_1.json\n", + "plan-round_robin_lifo-always_process {'top1': 0.06871169495648626, 'top5': 0.12280371338214406, 'top10': 0.13392345661573715, 'top100': 0.13392345661573715}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_fifo-always_process-0.25-100_replicas_1.json\n", + "plan-round_robin_fifo-always_process {'top1': 0.0640895857365947, 'top5': 0.11222543964969277, 'top10': 0.12234071772174746, 'top100': 0.12234071772174746}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_2.json\n", + "plan-round_robin_lifo-always_process {'top1': 0.07980004865378126, 'top5': 0.1408997810579843, 'top10': 0.15672010735221414, 'top100': 0.15672010735221414}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_fifo-always_process-0.25-100_replicas_2.json\n", + "plan-round_robin_fifo-always_process {'top1': 0.06708728645306088, 'top5': 0.11490139761910367, 'top10': 0.1252442498293194, 'top100': 0.1252442498293194}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_4.json\n", + "plan-round_robin_lifo-always_process {'top1': 0.08357464039362479, 'top5': 0.16605849440089146, 'top10': 0.1989547284412741, 'top100': 0.1989547284412741}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_fifo-always_process-0.25-100_replicas_4.json\n", + "plan-round_robin_fifo-always_process {'top1': 0.0692296223054045, 'top5': 0.1186367524385746, 'top10': 0.1285087616043192, 'top100': 0.1285087616043192}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_8.json\n", + "plan-round_robin_lifo-always_process {'top1': 0.12422408989963196, 'top5': 0.25539311470521303, 'top10': 0.2912321177735402, 'top100': 0.2912321177735402}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_fifo-always_process-0.25-100_replicas_8.json\n", + "plan-round_robin_fifo-always_process {'top1': 0.06077798965714779, 'top5': 0.12347074102847816, 'top10': 0.1354536965102683, 'top100': 0.1354536965102683}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_16.json\n", + "plan-round_robin_lifo-always_process {'top1': 0.19127213943232024, 'top5': 0.38433348243363075, 'top10': 0.4554621716850688, 'top100': 0.4554621716850688}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_fifo-always_process-0.25-100_replicas_16.json\n", + "plan-round_robin_fifo-always_process {'top1': 0.07892114163743516, 'top5': 0.16019649849722595, 'top10': 0.17815916064379939, 'top100': 0.17815916064379939}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_lifo-always_process-0.25-100_replicas_32.json\n", + "plan-round_robin_lifo-always_process {'top1': 0.18883945036921942, 'top5': 0.40024797733675477, 'top10': 0.46685657336127, 'top100': 0.46685657336127}\n", + "/data/wooders/wikipedia/predictions/plan-round_robin_fifo-always_process-0.25-100_replicas_32.json\n", + "plan-round_robin_fifo-always_process {'top1': 0.12397297360924736, 'top5': 0.21128296882234307, 'top10': 0.22860214547480598, 'top100': 0.22860214547480598}\n" ] }, { "data": { "text/plain": [ - "{'round_robin': [0.877196286617856,\n", + "{'lifo_round_robin': [0.877196286617856,\n", + " 0.8877745603503072,\n", " 0.8591002189420157,\n", + " 0.8850986023808963,\n", " 0.8339415055991085,\n", + " 0.8813632475614254,\n", " 0.7446068852947869,\n", + " 0.8765292589715219,\n", " 0.6156665175663693,\n", - " 0.5997520226632452],\n", - " 'weighted_round_robin': [0.8561731446822202,\n", - " 0.8432563504955624,\n", - " 0.7602231796030793,\n", - " 0.7086894083857147,\n", - " 0.6361795795371613,\n", - " 0.5848890772261066]}" + " 0.839803501502774,\n", + " 0.5997520226632452,\n", + " 0.7887170311776569],\n", + " 'fifo_round_robin': [0.877196286617856,\n", + " 0.8877745603503072,\n", + " 0.8591002189420157,\n", + " 0.8850986023808963,\n", + " 0.8339415055991085,\n", + " 0.8813632475614254,\n", + " 0.7446068852947869,\n", + " 0.8765292589715219,\n", + " 0.6156665175663693,\n", + " 0.839803501502774,\n", + " 0.5997520226632452,\n", + " 0.7887170311776569]}" ] }, - "execution_count": 270, + "execution_count": 280, "metadata": {}, "output_type": "execute_result" } ], "source": [ "constants = [0.25]\n", - "policies = [\"lifo\"]\n", + "policies = [\"lifo\", \"fifo\"]\n", "#key_policies = [\"random\", \"weighted_random\", \"round_robin\", \"weighted_round_robin\"]\n", - "key_policies = [\"round_robin\", \"weighted_round_robin\"]\n", + "key_policies = [\"round_robin\"]\n", "replicas = [1, 2, 4, 8, 16, 32]\n", "#key_policies = [\"weighted_random\", \"weighted_round_robin\"]\n", "d = artifact_dir\n", "metric = 'top5'\n", - "d = predictions_dir #\"/data/wooders/wikipedia/predictions\"\n", + "d = \"/data/wooders/wikipedia/predictions\"\n", "\n", "replica_results = {}\n", "\n", + "for pol in policies: \n", + " \n", + " for key_policy in key_policies:\n", + " scores = []\n", + " for replica in replicas:\n", + " for policy in policies: \n", "\n", - "for key_policy in key_policies:\n", - " scores = []\n", - " for replica in replicas:\n", - " for policy in policies: \n", - " \n", - " name = f\"plan-{key_policy}_{policy}-always_process\"\n", - " for constant in constants: \n", - " print(f'{d}/{name}-{constant}-100_replicas_{replica}.json')\n", - " with open(f'{d}/{name}-{constant}-100_replicas_{replica}.json') as results_file:\n", - " results = json.load(results_file)\n", - " print(name, results)\n", - " scores.append(1-results[metric])\n", - " replica_results[key_policy] = scores\n", + " name = f\"plan-{key_policy}_{policy}-always_process\"\n", + " for constant in constants: \n", + " print(f'{d}/{name}-{constant}-100_replicas_{replica}.json')\n", + " with open(f'{d}/{name}-{constant}-100_replicas_{replica}.json') as results_file:\n", + " results = json.load(results_file)\n", + " print(name, results)\n", + " scores.append(1-results[metric])\n", + " replica_results[pol + \"_\" + key_policy] = scores\n", "replica_results" ] }, { "cell_type": "code", - "execution_count": 271, + "execution_count": 281, "id": "e1822437", "metadata": {}, "outputs": [ { - "data": { - "image/png": "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MBgCmhMlJCSob9++ateuHasgOMipU6c0cuRIDRgwQIMGDdJjjz2mkydPOrsslzFv3jz+vDvIRx99pCFDhigyMlKDBg3S+++/7+ySapzf+w0vLCxUXFycbrvtNg0aNEiTJ092YpU1y5gxYzR48GANGTJEUVFRSk9Pr7G/69zF6URffPGFmjRpogceeECLFi1S27ZtnV1SjZeXl6fvvvtO3bt3l3TxB/b06dN6/vnnnVxZzfftt99q1qxZOnjwoBYvXsyf92pktVoVFhamV199VW3bttX+/fv15z//Wbt375abG/9dXlV+7zf8ueeek5ubmyZOnCiTyaQTJ06oQYMGTq62Zjh79qztofQffvih5s+fr6SkpBr5u87fVCfq2rVrudUUUL18fHxsf4klqUuXLjp69KgTK3INRUVFmjp1quLi4liKzUHc3Nx09uxZSRf/UfP39yecVbFL/Ybn5+dr/fr1euKJJ2x/1glnVee3KwadO3dOJpOpxv6u15i1OIHKKi0t1b///W/17dvX2aXUeLNnz9bgwYN17bXXOrsUl2AymfTyyy9rzJgx8vb2Vn5+vhYvXuzsslzC4cOH5ePjo3nz5ik1NVV16tTRE088oa5duzq7tBrjmWee0WeffSar1aply5aV2VeTftf5zym4rGnTpsnb21sPPvigs0up0fbs2aO9e/cqKirK2aW4jJKSEi1evFgLFizQRx99pIULFyomJkb5+fnOLq3GKykp0eHDh9W+fXutXbtW48aN0+OPP65z5845u7QaY/r06dq2bZtiYmKUmJhYZl9N+l0noMElJSQk6KefftLLL7/MtE8127Vrlw4dOqR+/fqpb9++OnbsmEaMGKHt27c7u7QaKz09XTk5OQoNDZUkhYaGqnbt2jp48KCTK6v5GjduLHd3d0VEREiSgoODVb9+fWVkZDi5sppnyJAhSk1N1alTpyTVvN/1q/8bAJU0a9Ys7du3T/Pnz5enp6ezy6nxRo0ape3bt2vr1q3aunWrAgICtHz5cvXs2dPZpdVYAQEBOnbsmA4dOiTp4lrIJ06cULNmzZxcWc3n6+ur7t2729aUzsjIUG5urpo3b+7kyq5++fn5ysrKsr3funWr6tWrJx8fnxr5u85dnE703HPP6f3339eJEydUv359+fj46J133nF2WTXa999/r4iICLVo0UK1atWSJDVt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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" + "ename": "ValueError", + "evalue": "arrays must all be same length", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mmatplotlib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpyplot\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mseaborn\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m df = pd.DataFrame({\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;34m'Model Runtime Const'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mreplicas\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mreplica_results\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/data/wooders/anaconda3/lib/python3.8/site-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, data, index, columns, dtype, copy)\u001b[0m\n\u001b[1;32m 527\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 528\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdict\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 529\u001b[0;31m \u001b[0mmgr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0minit_dict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolumns\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 530\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mMaskedArray\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 531\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mnumpy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmrecords\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mmrecords\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/data/wooders/anaconda3/lib/python3.8/site-packages/pandas/core/internals/construction.py\u001b[0m in \u001b[0;36minit_dict\u001b[0;34m(data, index, columns, dtype)\u001b[0m\n\u001b[1;32m 285\u001b[0m \u001b[0marr\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mis_datetime64tz_dtype\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marr\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0marr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcopy\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0marr\u001b[0m \u001b[0;32min\u001b[0m \u001b[0marrays\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 286\u001b[0m ]\n\u001b[0;32m--> 287\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0marrays_to_mgr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marrays\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata_names\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolumns\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 288\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 289\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/data/wooders/anaconda3/lib/python3.8/site-packages/pandas/core/internals/construction.py\u001b[0m in \u001b[0;36marrays_to_mgr\u001b[0;34m(arrays, arr_names, index, columns, dtype, verify_integrity)\u001b[0m\n\u001b[1;32m 78\u001b[0m \u001b[0;31m# figure out the index, if necessary\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 79\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mindex\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 80\u001b[0;31m \u001b[0mindex\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mextract_index\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marrays\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 81\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 82\u001b[0m \u001b[0mindex\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mensure_index\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/data/wooders/anaconda3/lib/python3.8/site-packages/pandas/core/internals/construction.py\u001b[0m in \u001b[0;36mextract_index\u001b[0;34m(data)\u001b[0m\n\u001b[1;32m 399\u001b[0m \u001b[0mlengths\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mraw_lengths\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 400\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlengths\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 401\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"arrays must all be same length\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 402\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 403\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mhave_dicts\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mValueError\u001b[0m: arrays must all be same length" + ] } ], "source": [ diff --git a/wikipedia/preprocessing/embedding.py b/wikipedia/preprocessing/embedding.py deleted file mode 100644 index 58b66e9..0000000 --- a/wikipedia/preprocessing/embedding.py +++ /dev/null @@ -1,152 +0,0 @@ -from typing import List -import pickle -from tqdm import tqdm -import time -import numpy as np -import json -import pandas as pd -import argparse -import json -import os -from collections import defaultdict -from multiprocessing import Pool -import torch -from dpr.models import init_biencoder_components -from dpr.options import ( - add_encoder_params, - setup_args_gpu, - print_args, - set_encoder_params_from_state, - add_tokenizer_params, - add_cuda_params, -) -from dpr.utils.model_utils import ( - setup_for_distributed_mode, - load_states_from_checkpoint, - get_model_obj, - move_to_device, -) -from dpr.utils.data_utils import Tensorizer - - -class Retriever: - def __init__(self, model_file): - - parser = argparse.ArgumentParser(description="") - add_encoder_params(parser) - add_tokenizer_params(parser) - add_cuda_params(parser) - args = parser.parse_args() - - setup_args_gpu(args) - - print(args) - - saved_state = load_states_from_checkpoint(model_file) - set_encoder_params_from_state(saved_state.encoder_params, args) - - self.tensorizer, self.encoder, _ = init_biencoder_components( - args.encoder_model_type, args, inference_only=True - ) - - self.encoder = self.encoder.ctx_model - - self.encoder, _ = setup_for_distributed_mode( - self.encoder, - None, - args.device, - args.n_gpu, - args.local_rank, - args.fp16, - args.fp16_opt_level, - ) - self.encoder.eval() - - model_to_load = get_model_obj(self.encoder) - - prefix_len = len("ctx_model.") - ctx_state = { - key[prefix_len:]: value - for (key, value) in saved_state.model_dict.items() - if key.startswith("ctx_model.") - } - model_to_load.load_state_dict(ctx_state) - self.device = args.device - - def predict(self, text): - - st = time.time() - batch_token_tensors = [self.tensorizer.text_to_tensor(text)] - - ctx_ids_batch = move_to_device( - torch.stack(batch_token_tensors, dim=0), self.device - ) - ctx_seg_batch = move_to_device(torch.zeros_like(ctx_ids_batch), self.device) - ctx_attn_mask = move_to_device( - self.tensorizer.get_attn_mask(ctx_ids_batch), self.device - ) - with torch.no_grad(): - _, embedding, _ = self.encoder(ctx_ids_batch, ctx_seg_batch, ctx_attn_mask) - embedding = embedding.cpu().numpy() - return embedding - - -def embed_passages(sents, retriever_model, num_sent_in_pass=10): - passages = [] - embeddings = [] - for i in range(0, len(sents), num_sent_in_pass): - passages.append(" ".join(sents[i : i + num_sent_in_pass])) - embeddings.append(retriever_model.predict(passages[-1])) - return passages, embeddings - - -def get_passages(sents, num_sent_in_pass=10): - passages = [] - for i in range(0, len(sents), num_sent_in_pass): - passages.append(" ".join(sents[i : i + num_sent_in_pass])) - return passages - - -def generate_embeddings(model_file, diff_dir, embedding_dir): - - # create retriever - retriever_model = Retriever(model_file) - - # loop through files - index = 0 - # gpu = 2 - for filename in tqdm(os.listdir(diff_dir)): - - # index += 1 - # if index % 5 != gpu: - # continue - - new_id = filename.replace(".json", "").split("_")[0] - old_id = filename.replace(".json", "").split("_")[1] - - for revid in [new_id, old_id]: - - data = json.load(open(os.path.join(diff_dir, filename))) - - if len(data["diffs"]) == 0: - continue - - if revid == data["orig_id"]: - sents = [d["sent_a"] for d in data["diffs"][0]] - filepath = os.path.join(embedding_dir, revid + "_orig.pkl") - elif revid == data["new_id"]: - sents = [d["sent_b"] for d in data["diffs"][0]] - filepath = os.path.join(embedding_dir, revid + "_new.pkl") - - if not os.path.exists(filepath): - passages, embeddings = embed_passages(sents, retriever_model) - - pickle.dump( - { - "timestamp": data["timestamp"], - "passages": passages, - "file": filepath, - "embeddings": embeddings, - }, - open(filepath, "wb"), - ) diff --git a/wikipedia/preprocessing/generate_diffs.py b/wikipedia/preprocessing/generate_diffs.py deleted file mode 100644 index 400ed3a..0000000 --- a/wikipedia/preprocessing/generate_diffs.py +++ /dev/null @@ -1,442 +0,0 @@ -from tqdm import tqdm -import re -from collections import defaultdict -import os -from bs4 import BeautifulSoup -import pickle -import difflib -import scipy - -# import spacy -# from benepar.spacy_plugin import BeneparComponent -from nltk.translate.bleu_score import sentence_bleu - - -def read_incr_dump(d): - edit_titles = {} - for folder in tqdm(os.listdir(d)): - for file in os.listdir(os.path.join(d, folder)): - f = os.path.join(d, folder, file) - data = open(f, "r").read() - - # parse - soup = BeautifulSoup(data, "html.parser") - - for doc in soup.find_all("doc"): - id = doc.get("id") - title = doc.get("title") - url = doc.get("url") - text = doc.get_text() - assert title not in edit_titles - edit_titles[title] = { - "id": id, - "title": title, - "url": url, - "text": text, - } - return edit_titles - - -def read_dump(d, edits): - documents = [] - for file in tqdm(os.listdir(d)): - data = pickle.loads(open(os.path.join(d, file), "rb").read()) - for doc in data: - title = doc["title"] - if title in edits and edits[title]["id"] == doc["id"]: - documents.append(doc) - return documents - - -def get_spans(sent_diffs): - spans = [] - start = None - for i in range(len(sent_diffs)): - r = sent_diffs[i] - if r[:2] == "+ " or r[:2] == "- ": - if start is None: - start = i - - if start is not None: - if (r[:2] != "+ " and r[:2] != "- ") or i == len(sent_diffs) - 1: - spans.append((start, i)) - start = None - return spans - - -def get_diffs(sent_a, sent_b): - d = difflib.Differ() - result = list(d.compare(sent_a, sent_b)) - sent_a_diffs = [r for r in result if "+ " not in r] - sent_b_diffs = [r for r in result if "- " not in r] - return sent_a_diffs, sent_b_diffs - - -def split_sentences(text): - rtext = text.replace(".\n", ".\n") - rtext = rtext.replace(". ", ". ") - sentences = rtext.split("") - assert len(text) == sum( - [len(s) for s in sentences] - ), f"Invalid length {len(text)}, {sum([len(s) for s in sentences])}" - - index_to_sent = [-1] * len(text) - sent_to_index = [-1] * len(sentences) - index = 0 - for i in range(len(sentences)): - sent_to_index[i] = index - for j in range(len(sentences[i])): - # map character index to sentence index - index_to_sent[index] = i - index += 1 - - assert index == len(text), f"changed text len {index}, {len(text)}" - for i in index_to_sent: - assert i >= 0 - - return sentences, index_to_sent, sent_to_index - - -def get_diff_spans(doc, doc_diffs_raw, nlp): - - # get spans - doc_spans = get_spans(doc_diffs_raw) - - # get sentences from - sentences, index_to_sent, sent_to_index = split_sentences(doc) - - sent_diffs = [] - - for span in doc_spans: - - # print('DIFF:', doc[span[0]:span[1]]) - - # get sentence indices - start_i = index_to_sent[span[0]] - end_i = index_to_sent[span[1]] - sent_ind = range(start_i, end_i + 1, 1) if end_i > start_i else [start_i] - - # offset char indices - offset = sent_to_index[start_i] - diff_span = (span[0] - offset, span[1] - offset) - - # parse sentence - sent_comb = " ".join([sentences[i] for i in sent_ind]) - if len(sent_comb) > 10000: - print("sentence too long", len(sent_comb)) - continue - - try: - - parsed = nlp(sent_comb) - csent_all = list(parsed.sents) - - # generate word spans - word_spans = [] - words = [] - for csent in csent_all: - for constituent in csent._.constituents: - - word_spans.append((constituent.start, constituent.end)) - if DEBUG: - print("C:", const_offset, constituent) - if constituent.start + 1 == constituent.end: - words.append((constituent.start, str(constituent))) - except Exception as e: - print(e) - continue - - # map word indices to character indices - index = 0 - word_to_char_index = {len(words): len(sent_comb)} - # TODO: make sure to sort words - for word_index, word in words: - csize = len(word) - while str(sent_comb[index : index + csize]) != str(word): - index += 1 - word_to_char_index[word_index] = index - - # convert word spans to char spans - char_spans = [ - (word_to_char_index[s[0]], word_to_char_index[s[1]]) for s in word_spans - ] - - # find minimal length span - min_i = None - min_length = len(sent_comb) - for i in range(len(char_spans)): - span_len = char_spans[i][1] - char_spans[i][0] - if ( - char_spans[i][0] <= diff_span[0] - and char_spans[i][1] >= diff_span[1] - and span_len <= min_length - ): - min_i = i - min_length = span_len - - if min_i is None: - span_text = sent_comb - # print("COULD NOT DETERMINE SPAN") - # print(doc[span[0]:span[1]]) - else: - span_text = sent_comb[char_spans[min_i][0] : char_spans[min_i][1]] - - # generate span text - diff_text = doc[span[0] : span[1]] - sent_diffs.append((diff_text, span_text)) - - if DEBUG: - print("WORD SPANS", word_spans) - print("CHAR SPANS", char_spans) - print("DIFF SPAN", diff_span) - print("DIFF", diff_text) - print(char_spans[min_i], span_text) - print() - - return sent_diffs - - -def get_diffs(sent_a, sent_b): - d = difflib.Differ() - result = list(d.compare(sent_a, sent_b)) - sent_a_diffs = [r for r in result if "+ " not in r] - sent_b_diffs = [r for r in result if "- " not in r] - return sent_a_diffs, sent_b_diffs - - -def get_diffs(sent_a, sent_b): - d = difflib.Differ() - result = list(d.compare(sent_a, sent_b)) - sent_a_diffs = [r for r in result if "+ " not in r] - sent_b_diffs = [r for r in result if "- " not in r] - return sent_a_diffs, sent_b_diffs - - -def get_diffs(sent_a, sent_b): - d = difflib.Differ() - result = list(d.compare(sent_a, sent_b)) - sent_a_diffs = [r for r in result if "+ " not in r] - sent_b_diffs = [r for r in result if "- " not in r] - return sent_a_diffs, sent_b_diffs - - -def get_diffs(sent_a, sent_b): - d = difflib.Differ() - result = list(d.compare(sent_a, sent_b)) - sent_a_diffs = [r for r in result if "+ " not in r] - sent_b_diffs = [r for r in result if "- " not in r] - return sent_a_diffs, sent_b_diffs - - -def get_sentence_diff(sent_a, sent_b, nlp=None): - - # get spans from differ - sent_a_diffs_raw, sent_b_diffs_raw = get_diffs(sent_a, sent_b) - - if nlp is None: - diffs_a = sent_a_diffs_raw - diffs_b = sent_b_diffs_raw - else: - diffs_a = list(set(get_diff_spans(sent_a, sent_a_diffs_raw, nlp))) - diffs_b = list(set(get_diff_spans(sent_b, sent_b_diffs_raw, nlp))) - - span_diffs_a = [d[1] for d in diffs_a] - span_diffs_b = [d[1] for d in diffs_b] - raw_diffs_a = [d[0] for d in diffs_a] - raw_diffs_b = [d[0] for d in diffs_b] - - return { - "sent_a": sent_a, - "sent_b": sent_b, - "sent_a_diffs": span_diffs_a, - "sent_b_diffs": span_diffs_b, - "sent_a_raw_diffs": raw_diffs_a, - "sent_b_raw_diffs": raw_diffs_b, - } - - -def generate_diffs(documents, edits): - all_diffs = [] - i = 0 - for article in tqdm(documents): - title = article["title"] - edit = edits[title] - - sent_a = article["text"] - sent_b = edit["text"] - - doc_id = article["id"] - assert ( - article["id"] == edit["id"] - ), f"Mismatch article - title: {title}, {edit['title']}, id: {article['id']}, {edit['id']}" - - DEBUG = False - # run: python -m spacy download en - # nlp = spacy.load("en") - ## nlp = spacy.load("en_core_web_sm") - # nlp.add_pipe(BeneparComponent("benepar_en3")) - - diff = get_sentence_diff(sent_a, sent_b, nlp) - diff["title"] = (title,) - diff["doc_id"] = doc_id - all_diffs.append(diff) - - if len(all_diffs) > 1000: - print("Writing", i) - pickle.dump(all_diffs, open(f"output/diffs_{i}.pkl", "wb")) - all_diffs = [] - - i += 1 - - -def check_alphanumeric(s): - return re.match("(?s).*[a-zA-Z0-9]+(?s).*$", s) is not None - - -def generate_sentence_level_diffs(documents, edits): - all_diffs = [] - count = 0 - - # for article in tqdm(documents): - for article in documents: - title = article["title"] - edit = edits[title] - sent_a = article["text"] - sent_b = edit["text"] - - splits_a, index_to_sent_a, sent_to_index_a = split_sentences(sent_a) - splits_b, index_to_sent_b, sent_to_index_b = split_sentences(sent_b) - - d = difflib.Differ( - linejunk=lambda x: x in " \n", charjunk=lambda x: x in " \n \t" - ) - diff = list(d.compare(splits_a, splits_b)) - - index = 0 - last_match = 0 - options = defaultdict(list) - for i in range(len(diff)): - - code = diff[i][:2] - if code == "? ": - continue - elif code == "+ ": - options[last_match].append(diff[i]) - elif code == "- ": - options[last_match].append(diff[i]) - else: - options[index] = diff[i][2:] - last_match = index + 1 - index += 1 - - diff_data = [] - - has_diff = False - for key, value in options.items(): - # print(key, value) - if not isinstance(value, list): - diff_data.append( - { - "sent_a": value, - "sent_b": value, - "sent_a_diffs": [], - "sent_b_diffs": [], - "diff_type": None, - } - ) - continue - - diff_a = [d[2:] for d in value if "- " in d] - diff_b = [d[2:] for d in value if "+ " in d] - - has_diff = True - - # nlp = spacy.load("en") - # nlp.add_pipe(BeneparComponent("benepar_en3")) - - for da in diff_a: - match = False - for i in range(len(diff_b) - 1, -1, -1): - db = diff_b[i] - score = sentence_bleu([da.split()], db.split()) - # print(score) - if score > 0.1: - # local_a, local_b = get_diffs(da, db) - diff = get_sentence_diff(da, db, nlp=None) - diff["diff_type"] = "EDIT" - diff["score"] = score - - # filter alphanumeric - # orig_a = list( diff["sent_a_diffs"]) - # orig_b = list( diff["sent_b_diffs"]) - diff["sent_a_diffs"] = [ - d for d in diff["sent_a_diffs"] if check_alphanumeric(d) - ] - diff["sent_b_diffs"] = [ - d for d in diff["sent_b_diffs"] if check_alphanumeric(d) - ] - if ( - len(diff["sent_a_diffs"]) == 0 - and len(diff["sent_b_diffs"]) == 0 - and da == db - ): - diff["diff_type"] = None - # print("CONVERT EDIT TO NONE") - # print(diff["sent_a_raw_diffs"]) - # print(diff["sent_b_raw_diffs"]) - # print(orig_a) - # print(orig_b) - - # pprint(diff) - diff_data.append(diff) - del diff_b[i] # avoid double counting - match = True - break - - if not match: - diff_data.append( - { - "sent_a": da, - "sent_b": "", - "sent_a_diffs": [da], - "sent_b_diffs": [], - "diff_type": "DELETE", - } - ) - - for db in diff_b: - diff_data.append( - { - "sent_a": "", - "sent_b": db, - "sent_a_diffs": [], - "sent_b_diffs": [db], - "diff_type": "INSERT", - } - ) - - # pprint([d for d in diff_data if d['diff_type'] is not None]) - all_diffs.append(diff_data) - count += 1 - - # if len(all_diffs) > 1000: - # print("Writing", count) - # pickle.dump(all_diffs, open(f"output/sent_diffs_{count}.pkl", "wb")) - # all_diffs = [] - - return all_diffs, has_diff - - -def main(): - edits = read_incr_dump("/home/ubuntu/incr-enwiki-20190206/text/") - print("finished reading edits", len(edits.keys())) - documents = read_dump("/home/ubuntu/enwiki-20190201/tmp/parsed", edits) - print("finished reading docs", len(documents)) - - print("generating diffs...") - # generate_diffs(documents, edits) - generate_sentence_level_diffs(documents, edits) - - -if __name__ == "__main__": - main() diff --git a/wikipedia/preprocessing/log_data.py b/wikipedia/preprocessing/log_data.py deleted file mode 100644 index c7fdb7a..0000000 --- a/wikipedia/preprocessing/log_data.py +++ /dev/null @@ -1,79 +0,0 @@ -import wandb -import configparser -import os - - -def log_questions(run, config): - # log questions file - artifact = wandb.Artifact("questions", type='dataset') - artifact.add_file(config["files"]["raw_questions_file"]) - artifact.add_file(config["files"]["questions_file"]) - artifact.add_file(config["files"]["test_questions_file"]) - artifact.add_file(config["files"]["train_questions_file"]) - run.log_artifact(artifact) - -def log_files(run, config): - # log files - artifact = wandb.Artifact("files", type='dataset') - artifact.add_file(config["files"]["changes_file"]) - artifact.add_file(config["files"]["titles_file"]) - artifact.add_file(config["files"]["edits_file"]) - run.log_artifact(artifact) - -def log_pageview(run, config): - # log pageview - artifact = wandb.Artifact("pageviews", type='dataset') - artifact.add_file(config["files"]["raw_pageview_file"]) - artifact.add_file(config["files"]["pageview_file"]) - artifact.add_file(config["files"]["timestamp_weights_file"]) - run.log_artifact(artifact) - -def log_simulation(run, config): - # log simulation data - artifact = wandb.Artifact("simulation", type='dataset') - artifact.add_file(config["simulation"]["stream_edits_file"]) - artifact.add_file(config["simulation"]["stream_questions_file"]) - artifact.add_file(config["simulation"]["init_data_file"]) - run.log_artifact(artifact) - -def log_plans(run, config, plan_dir): - artifact = wandb.Artifact("plans", type='dataset') - artifact.add_file(config["simulation"]["optimal_plan_file"]) - artifact.add_dir(plan_dir) - run.log_artifact(artifact) - -def log_plan_data(run, config, plan_name, plan_path): - artifact = wandb.Artifact(plan_name, type='dataset') - artifact.add_dir(plan_path) - run.log_artifact - - -def log_experiment(run, config): - # log experiment output - artifact = wandb.Artifact("prediction_results", type='dataset') - #files = os.listdir(config["directory"]["dpr_dir"]) - #files = os.listdir("/data/wooders/wikipedia/predictions") - artifact.add_dir("/data/wooders/wikipedia/predictions") - #for filename in files: - # if "plan-" in filename and '.json' in filename: - # artifact.add_file(os.path.join(config["directory"]["dpr_dir"], filename)) - # if "plan-" in filename and '.pkl' in filename: - # artifact.add_file(os.path.join(config["directory"]["dpr_dir"], filename)) - - run.log_artifact(artifact) - -if __name__ == "__main__": - - print("Running wandb logging on data") - run = wandb.init(job_type="dataset-creation", project="wiki-workload") - - # configuration file - config = configparser.ConfigParser() - config.read("config.yml") - - log_questions(run, config) - log_files(run, config) - log_pageview(run, config) - log_simulation(run, config) - log_experiment(run, config) - diff --git a/wikipedia/preprocessing/wiki_api_data.py b/wikipedia/preprocessing/wiki_api_data.py deleted file mode 100644 index 06b9b7b..0000000 --- a/wikipedia/preprocessing/wiki_api_data.py +++ /dev/null @@ -1,731 +0,0 @@ -import os -import time -import pickle -import json -from tqdm import tqdm -from collections import defaultdict -from datetime import datetime -import subprocess - -import configparser -import argparse - -import pandas as pd -import numpy as np - -from multiprocessing import Pool - -import wandb - -# from concurrent.futures import ProcessPoolExecutor - -# from generate diffs file (originally from DPR repo... sorry kevin) -from generate_diffs import generate_sentence_level_diffs -from embedding import generate_embeddings - -from log_data import log_files, log_pageview, log_simulation, log_questions - - -def query_recentchanges(start_time, end_time, revision_file): - from bs4 import BeautifulSoup - pass - - -def query_doc_versions(titles_file, start_time, end_time, raw_doc_dir): - # TODO: query doc versions - titles_df = pd.read_csv(titles_file) - titles = list(set(top_titles.index.tolist())) - pass - - -def get_recent_changes(revisions_dir, changes_file): - changes = [] - revids = set([]) - files = os.listdir(revisions_dir) - for i in range(len(files)): - f = files[i] - f_changes = json.loads(open(os.path.join(revisions_dir, f), "r").read()) - - for change in f_changes: - if change["revid"] in revids: - continue - - changes.append(change) - revids.add(change["revid"]) - - # if i % 100 == 0: - # print(f"Read {i}/{len(files)}, changes so far: {len(changes)}") - - # create dataframe - changes_df = pd.DataFrame(changes) - - # create time index - changes_df["datetime"] = pd.to_datetime(changes_df["timestamp"]) - changes_df = changes_df.set_index("datetime").sort_index() - - # save to CSV file - changes_df.to_csv(changes_file) - - return changes_df - - -def get_titles(changes_file, titles_file, n=200): - changes_df = pd.read_csv(changes_file) - title_ids = set(changes_df[["title", "pageid"]].apply(tuple, axis=1).tolist()) - - counts = changes_df.title.value_counts().to_frame() - top_titles = counts[counts["title"] > n] - top_titles.columns = ["count"] - top_titles["title"] = top_titles.index - top_titles.to_csv(titles_file) - return top_titles - - -def get_edits(edits_file, changes_file, titles_file): - changes_df = pd.read_csv(changes_file) - titles_df = get_titles(changes_file, titles_file) - titles = list(set(titles_df.index.tolist())) - edits_df = changes_df[changes_df.title.apply(lambda x: x in titles)] - - # assign timestamps - edits_df["ts_min"] = ( - pd.to_datetime(edits_df["datetime"]) - .astype(np.int64) - .apply(assign_timestamps_min) - ) - - # write CSV - edits_df.to_csv(edits_file) - return edits_df - - -def get_questions(raw_questions_file, questions_file): - questions_df = pd.read_csv(raw_questions_file, sep="\t") - questions_df.columns = [ - "question", - "answer", - "doc_id", - "datetime", - "revid", - "oldrevid", - ] - - # assign timestamps - questions_df["ts_min"] = ( - pd.to_datetime(questions_df["datetime"]) - .astype(np.int64) - .apply(assign_timestamps_min) - ) - - # write CSV - questions_df.to_csv(questions_file) - return questions_df - -def get_pageviews(raw_pageview_file, pageview_file, edits_file, timestamp_weights_file): - - edits_df = pd.read_csv(edits_file) - pageview_df = pd.read_csv(raw_pageview_file) - - # map title -> id - title_to_id = edits_df.set_index("title")["pageid"].to_dict() - open("title_to_id.json", "w").write(json.dumps(title_to_id)) - - # calculate page weights - total_views = pageview_df.iloc[:, 2:].sum(axis=1).sum() - weights = pageview_df.iloc[:, 2:].sum(axis=1) / total_views - pageview_df['weights'] = weights - pageview_df['doc_id'] = pageview_df['title'].apply(lambda x: title_to_id[x]) - pageview_df.to_csv(pageview_file) - - # page weights per timestamp - ts_to_weights = {} - dates = pageview_df.columns[2:-2] - for date in dates: - print(date) - dt = datetime.strptime(date[:-2], '%Y%m%d') - ts = dt.timestamp() * 1000000000 - ts_min = assign_timestamps_min(ts) - view_counts = pageview_df[date].tolist() - id_to_count = pageview_df.set_index("doc_id")[date].to_dict() - ts_to_weights[ts_min] = id_to_count - open(timestamp_weights_file, "w").write(json.dumps(ts_to_weights)) - print("Generated ts weights file", timestamp_weights_file) - return pageview_df - - -# create diff JSON file from valid list of revision pairs, doc pkl -def create_diff_json(doc_pkl, rev_pairs, diff_dir): - - # load data for file - data = pickle.loads(open(doc_pkl, "rb").read()) - title = os.path.basename(doc_pkl).replace(".pkl", "") - - for i in range(len(data)): - orig_doc = data[i] - - for j in range(0, len(data), 1): - new_doc = data[j] - - rev_pair = orig_doc["id"] + "_" + new_doc["id"] - - if rev_pair not in rev_pairs: - continue - - diff_file = os.path.join(diff_dir, rev_pair + ".json") - if os.path.exists(diff_file): - # skip - continue - - edits = {orig_doc["title"]: new_doc} - try: - all_diffs = generate_sentence_level_diffs([orig_doc], edits) - except Exception as e: - print(e) - raise ValueError(f"Failed to parse diffs {rev_pair}") - diff = { - "title": orig_doc["title"], - "timestamp": rev_pairs[rev_pair], - "orig_id": orig_doc["id"], - "new_id": new_doc["id"], - "diffs": all_diffs, - } - open(diff_file, "w").write(json.dumps(diff, indent=2)) - - -def generate_diffs_helper(filename, diff_dir, rev_pair, timestamp): - - data = pickle.loads(open(filename, "rb").read()) - - for i in range(len(data)): - for j in range(len(data)): - orig_doc = data[i] - new_doc = data[j] - - if new_doc["id"] + "_" + orig_doc["id"] != rev_pair: - continue - - # parse diffs - diff_file = os.path.join(diff_dir, rev_pair + ".json") - - if os.path.exists(diff_file): - continue - - edits = {orig_doc["title"]: new_doc} - st = time.time() - all_diffs, has_diff = generate_sentence_level_diffs([orig_doc], edits) - # print("runtime", time.time() - st) - diff = { - "title": orig_doc["title"], - "timestamp": timestamp, - "orig_id": orig_doc["id"], - "new_id": new_doc["id"], - "diffs": all_diffs, - } - if has_diff: - diff = { - "title": orig_doc["title"], - "timestamp": timestamp, - "orig_id": orig_doc["id"], - "new_id": new_doc["id"], - "diffs": all_diffs, - } - else: - diff = { - "title": orig_doc["title"], - "timestamp": timestamp, - "orig_id": orig_doc["id"], - "new_id": new_doc["id"], - "diffs": [], - } - # TODO: write to tmp file first (make sure we dont have messed up files) - open(diff_file, "w").write(json.dumps(diff, indent=2)) - return - - -def generate_diffs( - edits_file, titles_file, parsed_doc_dir, diff_dir, revision_file, workers=32 -): - - # make sure title is in titles df - titles_df = pd.read_csv(titles_file) - titles = list(set(titles_df.title.tolist())) - - # print(titles) - - # filter out revision pairs not in edits_file - edits_df = pd.read_csv(edits_file) - title_to_rev_pairs = defaultdict(dict) - for index, row in edits_df.iterrows(): - if row["title"] not in titles: - continue # skip if not top title - - # map title -> (revid, old_revid) -> timestamp of revision - rev_pair = str(row["revid"]) + "_" + str(row["old_revid"]) - title_to_rev_pairs[row["title"]][rev_pair] = row["timestamp"] - - open(revision_file, "w").write(json.dumps(title_to_rev_pairs)) - - num_keys = len(title_to_rev_pairs.keys()) - # print( - # f"Proceessing revisions for {num_keys} titles, writing to {diff_dir}" - # ) - - inputs = [] - for title in tqdm(titles): - filename = os.path.join(parsed_doc_dir, f"{title}.pkl") - if not os.path.exists(filename): - print("missing", filename) - continue - - for rev_pair in title_to_rev_pairs[title].keys(): - if os.path.exists(os.path.join(diff_dir, rev_pair + ".json")): - continue - inputs.append( - (filename, diff_dir, rev_pair, title_to_rev_pairs[title][rev_pair]) - ) - - print("processing revids", len(inputs), diff_dir) - chunk_size = 100000 - for i in range(0, len(inputs), chunk_size): - p = Pool(128) - print("created pool", i, i + chunk_size, len(inputs)) - p.starmap(generate_diffs_helper, inputs[i : i + chunk_size]) - p.close() - - return - - # diff remaining - inputs = [ - ( - os.path.join(parsed_doc_dir, f"{title}.pkl"), - title_to_rev_pairs[title], - diff_dir, - ) - for title in titles - ] - p = Pool(workers) - p.starmap(create_diff_json, inputs) - p.close() - - -# convert wikipedia dump into single pkl file per title -def dump_to_pickle_title(top_folder, target_dir, title): - total = 0 - docs = [] - for folder in os.listdir(top_folder): - for file in os.listdir(os.path.join(top_folder, folder)): - - filename = os.path.join(top_folder, folder, file) - data = open(filename, "r").read() - soup = BeautifulSoup(data, "html.parser") - - for doc in soup.find_all("doc"): - id = doc.get("id") - title = doc.get("title") - url = doc.get("url") - text = doc.get_text() - docs.append({"id": id, "url": url, "title": title, "text": text}) - total += len(docs) - pickle.dump(docs, open(os.path.join(target_dir, title + ".pkl"), "wb")) - return os.path.join(target_dir, title + ".pkl") - - -# call wikiextractor library on XML -def extract(title, raw_doc_dir, parsed_tmp_dir, parsed_doc_dir): - f = f"{raw_doc_dir}/{title}" - bashCommand = f"wikiextractor {f} -o {parsed_tmp_dir}/tmp_parsed{title}" - - process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE) - output, error = process.communicate() - - pkl_file = dump_to_pickle_title( - f"{parsed_tmp_dir}/tmp_parsed{title}", parsed_doc_dir, title - ) - - -def parse_docs(raw_doc_dir, parsed_tmp_dir, parsed_doc_dir, workers=32): - # parse documents from raw XML - - # extract individual doc - files = os.listdir(raw_doc_dir) - # TODO: add assert to make sure titles correspond to filenames - files = [ - (f, raw_doc_dir, parsed_tmp_dir, parsed_doc_dir) - for f in files - if not os.path.isdir(f) - ] - - # create pool and run - p = Pool(workers) - p.starmap(extract, files) - p.close() - - -# assign timesteps -def assign_timestamps_min(ts): - # take in unix timestamp - covert to integer - start_ts = 1628131044000000000 # don't change - delta = ts - start_ts - if delta < 0: - return None - - return int(delta / (60 * 1000000000)) - - -def generate_simulation_data( - questions_file, - edits_file, - diff_dir, - init_data_file, - stream_edits_file, - stream_questions_file, -): - edits_df = pd.read_csv(edits_file) - questions_df = pd.read_csv(questions_file) - - # lists for questions/edits at each timestep - questions = [] - edits = [] - - # initialization data for embeddings/passages - init_data = {} - - # timestamp to stop - max_ts = int(questions_df.ts_min.max()) - - # loop through timestamps - for ts in range(max_ts + 1): - - ts_edits = defaultdict(list) - ts_queries = defaultdict(list) - for index, row in edits_df[edits_df["ts_min"] == ts].iterrows(): - filename = str(row["revid"]) + "_" + str(row["old_revid"]) + ".json" - key = row["pageid"] - - # make sure file is OK - file_path = os.path.join(diff_dir, filename) - if os.path.exists(file_path): - try: - data = json.load(open(file_path)) - if len(data["diffs"]) == 0: - continue - diffs = data["diffs"][0] - except Exception as e: - print(file_path) - print(e) - continue - diff_types = [ - d["diff_type"] for d in diffs if d["diff_type"] is not None - ] - if len(diff_types) == 0: - print(f"Invalid file {filename}") - continue - assert str(data["orig_id"]) == str( - row["old_revid"] - ), f"Invalid id {filename}, id {data['orig_id']} row {row['revid']}" - - # get length of passage - - if key not in init_data: - diffs = data["diffs"][0] - init_data[key] = { - "revid": data["orig_id"], - "sents": [d["sent_a"] for d in diffs], - "file": filename, - "ts_min": row["ts_min"], - } - ts_edits[key].append(filename) - - else: - # print("missing", file_path) - continue - - for index, row in questions_df[questions_df["ts_min"] == ts].iterrows(): - key = row["doc_id"] - ts_queries[key].append( - { - "question": row["question"], - "doc_id": key, - "answer": row["answer"], - "datetime": row["datetime"], - "ts_min": row["ts_min"], - "revid": row["revid"], - "old_revid": row["oldrevid"], - } - ) - - edits.append(ts_edits) - questions.append(ts_queries) - - if ts % 1000 == 0: - unique_files = set([]) - for e in edits: - for files in e.values(): - for f in files: - unique_files.add(f) - print(f"Num edits ts {ts}/{max_ts+1}: {len(unique_files)}") - - open(stream_edits_file, "w").write(json.dumps(edits)) - open(stream_questions_file, "w").write(json.dumps(questions)) - open(init_data_file, "w").write(json.dumps(init_data)) - - -def search_answer(rev_file, embedding_dir, question): - # read file and see if answer is contained - revid = rev_file.replace(".json", "").split("_")[0] - # assert str(revid) == str(question["revid"]), f"Invalid id {revid}, {question}" - embedding_filename = os.path.join(embedding_dir, f"{revid}_new.pkl") - try: - passages = pickle.load(open(embedding_filename, "rb"))["passages"] - except Exception as e: - print(e) - print("File error", embedding_filename) - return False - - found_answer = False - for passage in passages: - if question["answer"] in passage: - found_answer = True - return found_answer - - -def generate_key_weights(pageview_file, titles_file): - pass - - -def check_dataset( - titles_file, - edits_file, - init_data_file, - stream_edits_file, - stream_questions_file, - diff_dir, -): - # TODO: add checks (init data keys match stream keys, questions match keys, etc.) - - # load data - edits_df = pd.read_csv(edits_file) - titles_df = get_titles(changes_file, titles_file) - titles = list(set(titles_df.index.tolist())) - init_data = json.load(open(init_data_file)) - edits = json.load(open(stream_edits_file)) - questions = json.load(open(stream_questions_file)) - - # same length - assert len(questions) == len(edits) - - for ts in range(len(questions)): - for doc_id in questions[ts].keys(): - if not doc_id in init_data: - print("missing doc", doc_id) - continue - for question in questions[ts][doc_id]: - # print(question) - answer = question["answer"] - # import pdb; pdb.set_trace() - - # question = questions[ts][doc_id] - rev_file = ( - str(question["revid"]) + "_" + str(question["old_revid"]) + ".json" - ) - - if not os.path.exists(os.path.join(diff_dir, rev_file)): - print("Still missing diff", rev_file) - continue - - # question generated from document edit - assert it was created before - found = False - revision_file = None - found_index = 0 - for i in range(ts): - if doc_id in edits[ts - i]: - if rev_file in edits[ts - i][doc_id]: - found = True - revision_file = rev_file - found_index = ts - i - break - if not found: - # only option is that it was derived from original doc - assert str(init_data[doc_id]["revid"]) == str( - question["old_revid"] - ), f"Missing revision {ts}, {rev_file}, {doc_id}, init version {init_data[doc_id]['revid']}" - revision_file = init_data[doc_id]["file"] - - # search for answer in revision file - found_answer = search_answer(revision_file, embedding_dir, question) - if not found_answer: - print("NOT FOUND", found_answer, revision_file) - else: - print("FOUND", found_answer, revision_file) - - if ( - question["question"] - == "how far is hurricane ida from cuba?????????????????" - ): - print("DEBUG", question) - print(rev_file) - print("question ts", ts, "edit ts", found_index) - for i in range(found_index, ts + 1, 1): - if doc_id in edits[i]: - print( - i, - edits[i][doc_id], - search_answer( - edits[i][doc_id][-1], embedding_dir, question - ), - ) - print(found_answer) - - # docid_to_title = {} - # for index, row in edits_df.iterrows(): - # docid_to_title[row["pageid"]] = row["title"] - - # open("docid_to_title.json", "w").write(json.dumps(docid_to_title)) - - ## check matching keys - # last_doc = init_data - # for i in len(edits): - # # TODO: assert that question actually contained in this edit? - # continue - - # check each edit is contained - - # check raw edit timestamp is same as query timestamp - - -if __name__ == "__main__": - - run = wandb.init(job_type="dataset-creation", project="wiki-workload") - - # configuration file - config = configparser.ConfigParser() - config.read("config.yml") - - # argument flags - parser = argparse.ArgumentParser() - parser.add_argument( - "--run_query_recentchanges", action="store_true", default=False - ) # query wiki api for recentchanges - parser.add_argument( - "--run_query_doc_versions", action="store_true", default=False - ) # query wiki api for doc versions - parser.add_argument( - "--run_recent_changes", action="store_true", default=False - ) # re-processing api changes data - parser.add_argument( - "--run_parse_docs", action="store_true", default=False - ) # re-parse document versions - parser.add_argument("--run_get_questions", action="store_true", default=False) - parser.add_argument("--run_get_pageviews", action="store_true", default=False) - parser.add_argument( - "--run_generate_diffs", action="store_true", default=False - ) # re-process generating diffs - parser.add_argument( - "--run_generate_simulation_data", action="store_true", default=False - ) - parser.add_argument("--run_check_dataset", action="store_true", default=False) - parser.add_argument("--run_generate_embeddings", action="store_true", default=False) - args = parser.parse_args() - - # directories - data_dir = config["directory"]["data_dir"] - revisions_dir = config["directory"]["revisions_dir"] - raw_doc_dir = config["directory"]["raw_doc_dir"] - parsed_doc_dir = config["directory"]["parsed_doc_dir"] - parsed_tmp_dir = config["directory"]["parsed_tmp_dir"] - diff_dir = config["directory"]["diff_dir"] - embedding_dir = config["directory"]["embedding_dir"] - - # intermediate files - model_file = config["files"]["model_file"] - changes_file = config["files"]["changes_file"] - titles_file = config["files"]["titles_file"] - revisions_file = config["files"]["revisions_file"] - edits_file = config["files"]["edits_file"] - raw_questions_file = config["files"]["raw_questions_file"] - questions_file = config["files"]["questions_file"] - raw_pageview_file = config["files"]["raw_pageview_file"] - pageview_file = config["files"]["pageview_file"] - timestamp_weights_file = config["files"]["timestamp_weights_file"] - - # simulation data - init_data_file = config["simulation"]["init_data_file"] - stream_edits_file = config["simulation"]["stream_edits_file"] - stream_questions_file = config["simulation"]["stream_questions_file"] - - if args.run_query_recentchanges: - query_edit_stream(start_time, end_time, revisions_dir) - - if args.run_query_doc_versions: - query_doc_versions(titles_file, start_time, end_time, raw_doc_dir) - - if args.run_recent_changes: - print("Generating from revisions", revisions_dir) - changes_df = get_recent_changes(revisions_dir, changes_file) - - print("Generated changes file", changes_file) - titles_df = get_titles(changes_file, titles_file) - print("Generated titles file", titles_file) - edits_df = get_edits(edits_file, changes_file, titles_file) - print("Generated edits file", edits_file) - log_files(run, config) - - # query document versions for list of titles - if args.run_query_doc_versions: - if not os.path.exists(raw_doc_dir): - os.mkdir(raw_doc_dir) - query_doc_versions(titles_file, start_time, end_time, raw_doc_dir) - - # parse documents - if args.run_parse_docs: - if not os.path.exists(parsed_doc_dir): - os.mkdir(parsed_doc_dir) - if not os.path.exists(parsed_tmp_dir): - os.mkdir(parsed_tmp_dir) - parse_docs(raw_doc_dir, parsed_tmp_dir, parsed_doc_dir, workers=32) - - # get questions - if args.run_get_questions: - questions_df = get_questions(raw_questions_file, questions_file) - print("Generated questions file", raw_questions_file, questions_file) - log_questions(run, config) - - # generate pageviews / compute page weights - if args.run_get_pageviews: - get_pageviews(raw_pageview_file, pageview_file, edits_file, timestamp_weights_file) - log_pageview(run, config) - - # generate diffs between document versions - if args.run_generate_diffs: - # if not os.path.isdir(diff_dir): - # os.mkdir(diff_dir) - generate_diffs( - edits_file, titles_file, parsed_doc_dir, diff_dir, revisions_file - ) - - # generate simulation data - if args.run_generate_simulation_data: - generate_simulation_data( - questions_file, - edits_file, - diff_dir, - init_data_file, - stream_edits_file, - stream_questions_file, - ) - log_simulation(run, config) - - # run tests to validate simulation data - if args.run_check_dataset: - check_dataset( - titles_file, - edits_file, - init_data_file, - stream_edits_file, - stream_questions_file, - diff_dir, - ) - - # generate embeddings for revids from diffs (make passages) - if args.run_generate_embeddings: - generate_embeddings(model_file, diff_dir, embedding_dir) diff --git a/wikipedia/run_0_generate_data.sh b/wikipedia/run_0_generate_data.sh deleted file mode 100644 index 5d92ff6..0000000 --- a/wikipedia/run_0_generate_data.sh +++ /dev/null @@ -1 +0,0 @@ -python preprocessing/wiki_api_data.py --run_generate_simulation_data --run_get_questions diff --git a/wikipedia/run_1_generate_plan.sh b/wikipedia/run_1_generate_plan.sh deleted file mode 100644 index 8bb1f25..0000000 --- a/wikipedia/run_1_generate_plan.sh +++ /dev/null @@ -1,19 +0,0 @@ -set -xe - -for replicas in 16 32 -do - for model_runtime in 0.25 #0.001 0.05 0.01 0.1 1.0 5.0 10.0 - do - for event_policy in "lifo" #"fifo" - do - for load_shedding_policy in "always_process" - do - for key_policy in "round_robin" "weighted_round_robin" - do - python simulate.py --model_runtime $model_runtime --send_rate 100 \ - --event_policy $event_policy --key_policy $key_policy --load_shedding_policy $load_shedding_policy --num_replicas ${replicas} - done - done - done - done -done diff --git a/wikipedia/run_2_prepare_data.sh b/wikipedia/run_2_prepare_data.sh deleted file mode 100644 index 89faacc..0000000 --- a/wikipedia/run_2_prepare_data.sh +++ /dev/null @@ -1,20 +0,0 @@ -set -xe - -plan_dir=/data/wooders/wiki-plans - -for replicas in 16 32 -do -for model_runtime in 0.25 -do - for event_policy in "lifo" - do - for load_shedding_policy in "always_process" - do - for key_policy in "round_robin" "weighted_round_robin" - do - python wiki_eval_tmp.py --offline-plan-path ${plan_dir}/plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100_replicas_${replicas}.json --workers 32 - done - done - done -done -done diff --git a/wikipedia/run_3_run_predictions.sh b/wikipedia/run_3_run_predictions.sh deleted file mode 100644 index 9b2d73b..0000000 --- a/wikipedia/run_3_run_predictions.sh +++ /dev/null @@ -1,30 +0,0 @@ -set -xe - -plan_dir=/data/wooders/wiki-plans -dpr_dir=~/DPR - -cd $dpr_dir - -for replicas in 16 32 -do -for event_policy in "lifo" -do - for model_runtime in 0.25 - #for model_runtime in 0.01 0.05 0.1 1.0 10.0 0.25 0.005 - do - for load_shedding_policy in "always_process" - do - for key_policy in "weighted_round_robin" "round_robin" - do - #plan_file=plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100 - plan_file=plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100_replicas_${replicas} - echo $plan_file - CUDA_VISIBLE_DEVICES=4 bash ${dpr_dir}/evaluate_retrieval_single_doc_stream.sh $plan_file & - - #pid=$! - done - #wait $pid - done - done -done -done diff --git a/wikipedia/run_4_run_optimal_predictions.sh b/wikipedia/run_4_run_optimal_predictions.sh deleted file mode 100644 index 14abe91..0000000 --- a/wikipedia/run_4_run_optimal_predictions.sh +++ /dev/null @@ -1,8 +0,0 @@ -set -xe - -plan_dir=/data/wooders/wiki-plans -dpr_dir=~/DPR -python wiki_eval.py --offline-plan-path optimal_plan.json -cd $dpr_dir -echo $plan_file -CUDA_VISIBLE_DEVICES=5 bash ${dpr_dir}/evaluate_retrieval_single_doc_stream.sh optimal_plan diff --git a/wikipedia/run_5_pipeline_predict.sh b/wikipedia/run_5_pipeline_predict.sh deleted file mode 100644 index ea36102..0000000 --- a/wikipedia/run_5_pipeline_predict.sh +++ /dev/null @@ -1,30 +0,0 @@ -set -xe - -plan_dir=/data/wooders/wiki-plans -dpr_dir=/home/eecs/wooders/DPR -wiki_dir=/home/eecs/wooders/experiments/wikipedia - - -#for key_policy in "weighted_random" "weighted_round_robin" -#for key_policy in "random" "weighted_random" -for model_runtime in 0.01 0.05 0.1 1 10 0.25 0.005 -do - for event_policy in "lifo" "fifo" - do - for load_shedding_policy in "always_process" - do - for key_policy in "round_robin" "weighted_round_robin" "random" "weighted_random" - do - cd $wiki_dir - plan_file=plan-${key_policy}_${event_policy}-${load_shedding_policy}-${model_runtime}-100 - echo $plan_file - python wiki_eval.py --offline-plan-path ${plan_dir}/${plan_file}.json - cd $dpr_dir - CUDA_VISIBLE_DEVICES=3 bash ${dpr_dir}/evaluate_retrieval_single_doc_stream.sh $plan_file - pid=$! - done - wait $pid - done - done -done -p diff --git a/wikipedia/run_wiki.sh b/wikipedia/run_wiki.sh deleted file mode 100644 index 55a3035..0000000 --- a/wikipedia/run_wiki.sh +++ /dev/null @@ -1,10 +0,0 @@ -FILE="passages_sent_diffs_10010.pkl" -MODEL_FILE="/home/ubuntu/DPR/checkpoint/retriever/single/nq/bert-base-encoder.cp" -SEND_RATE=100 -DATA_DIR="/home/ubuntu/flink-feature-flow/RayServer/data/" -EXP_DIR="/home/ubuntu/flink-feature-flow/RayServer/experiments/" -TIMESTAMP=$(date +%s) -EXP="experiment_$TIMESTAMP" -echo $EXP; -python wiki_server.py --data-dir $DATA_DIR --send-rate $SEND_RATE --exp-dir $EXP_DIR --exp $EXP --file $FILE --model_file $MODEL_FILE -#python wiki_client.py --exp $EXP_DIR diff --git a/wikipedia/simulate.py b/wikipedia/simulate.py deleted file mode 100644 index 27db63a..0000000 --- a/wikipedia/simulate.py +++ /dev/null @@ -1,616 +0,0 @@ -import itertools -import json -from typing import DefaultDict, Dict, List, Optional, Tuple -from more_itertools.more import divide -from collections import defaultdict -from dataclasses import dataclass -from functools import cmp_to_key -import random - -import configparser -import argparse - -import pandas as pd - -import wandb - -import simpy -from ralf.state import Record -from ralf.policies.load_shedding_policy import ( - always_process, - make_mean_policy, - make_sampling_policy, -) -from ralf.policies.processing_policy import fifo, lifo # , make_sorter_with_key_weights -from ralf.simulation.priority_queue import PerKeyPriorityQueue -from ralf.simulation.source import JSONSource -from ralf.simulation.window import WindowOperator -from ralf.simulation.mapper import ( - RalfMapper, - RoundRobinLoadBalancer, - CrossKeyLoadBalancer, -) - - -from ralf.policies.load_shedding_policy import ( - always_process, - newer_processing_time, - later_complete_time, - make_sampling_policy, - make_mean_policy, - make_cosine_policy, -) - -from typing import Dict, List, Tuple, Type - -from preprocessing.log_data import log_plans - -def current_weights(ts, ts_to_weights): - ts = int(ts) - min_dist = max(list(ts_to_weights.keys())) - - index = 0 - for key in ts_to_weights.keys(): - if key >= ts: - break - index = key - - return ts_to_weights[key] - -class KeyFIFO(CrossKeyLoadBalancer): - """Simple policy that cycle through all the keys fairly""" - - def __init__(self, num_replicas=1): - self.cur_key_set = {} - for replica_id in range(num_replicas): - self.cur_key_set[replica_id] = set() - print(num_replicas, self.cur_key_set) - - def choose( - self, per_key_queues: Dict[str, PerKeyPriorityQueue], replica_id: int - ) -> str: - key_set = set(per_key_queues.keys()) - if key_set != self.cur_key_set[replica_id]: - #print("reset keys", replica_id, len(key_set), key_set, self.cur_key_set[replica_id]) - self.cur_key_set[replica_id] = key_set - self.cur_key_iter[replica_id] = itertools.cycle(key_set) - - seen = set([]) - while per_key_queues[key].size() == 0: - key = next(self.cur_key_iter[replica_id]) - #print(replica_id, key, per_key_queues[key].size(), per_key_queues[key].size() == 0) - if key in seen: - raise ValueError(f"Did full loop - livelock {replica_id}") - #return None - seen.add(key) - # TODO(simon): maybe do a "peak" here to trigger eviction policies - #print("choose", replica_id, key) - return key - - -class RoundRobinLoadBalancer(CrossKeyLoadBalancer): - """Simple policy that cycle through all the keys fairly""" - - def __init__(self, num_replicas=1): - self.cur_key_iter = {} - self.cur_key_set = {} - for replica_id in range(num_replicas): - self.cur_key_set[replica_id] = set() - self.cur_key_iter[replica_id] = None - print(num_replicas, self.cur_key_set) - print(num_replicas, "replicas", self.cur_key_iter) - - def choose( - self, per_key_queues: Dict[str, PerKeyPriorityQueue], replica_id: int - ) -> str: - key_set = set(per_key_queues.keys()) - if key_set != self.cur_key_set[replica_id]: - #print("reset keys", replica_id, len(key_set), key_set, self.cur_key_set[replica_id]) - self.cur_key_set[replica_id] = key_set - self.cur_key_iter[replica_id] = itertools.cycle(key_set) - - key = next(self.cur_key_iter[replica_id]) - - seen = set([]) - while per_key_queues[key].size() == 0: - key = next(self.cur_key_iter[replica_id]) - #print(replica_id, key, per_key_queues[key].size(), per_key_queues[key].size() == 0) - if key in seen: - raise ValueError(f"Did full loop - livelock {replica_id}") - #return None - seen.add(key) - # TODO(simon): maybe do a "peak" here to trigger eviction policies - #print("choose", replica_id, key) - return key - -class WeightedRoundRobinLoadBalancer(CrossKeyLoadBalancer): - - def __init__(self, all_keys, num_replicas=1): - - self.weights = json.load(open("bucket_weights.json")) - - # set default weight - for key in all_keys: - if key not in self.weights: - self.weights[key] = 1 - - self.cur_key_iter = {} - self.cur_key_set = {} - for replica_id in range(num_replicas): - self.cur_key_set[replica_id] = set() - self.cur_key_iter[replica_id] = None - - def choose( - self, per_key_queues: Dict[str, PerKeyPriorityQueue], replica_id: int - ) -> str: - key_set = set(per_key_queues.keys()) - - # initialize keys - if key_set != self.cur_key_set[replica_id]: - self.cur_key_set[replica_id] = [] - for key in key_set: - for i in range(self.weights[key]): - self.cur_key_set[replica_id].append(key) - random.shuffle(self.cur_key_set[replica_id]) - self.cur_key_iter[replica_id] = itertools.cycle(self.cur_key_set[replica_id]) - - key = next(self.cur_key_iter[replica_id]) - while per_key_queues[key].size() == 0: - key = next(self.cur_key_iter[replica_id]) - return key - - -#class WeightedRoundRobin(CrossKeyLoadBalancer): -# """Simple policy that cycle through all the keys fairly""" -# -# def __init__(self, pageview_file, all_keys): -# self.cur_key_set = [] -# self.cur_key_iter = None -# pageview_df = pd.read_csv(pageview_file) -# -# self.weights = json.load(open("weights.json")) -# -# ##self.raw_weights = pageview_df.set_index("doc_id")["weights"].to_dict() -# #self.raw_weights = pageview_df.set_index("doc_id")["2021090300"].to_dict() -# #self.weights = {} -# #for key in self.raw_weights.keys(): -# # if str(key) not in all_keys: -# # continue -# -# # self.weights[key] = int(self.raw_weights[key]*1000) -# # #assert self.weights[key] > 0, f"Too small {key}, {self.raw_weights[key]}" -# # if self.weights[key] == 0: -# # self.weights[key] = 1 -# -# -# for key in all_keys: -# if key not in self.weights: -# self.weights[key] = 1 -# -# -# for key in self.weights.keys(): -# for i in range(self.weights[key]): -# self.cur_key_set.append(str(key)) -# random.shuffle(self.cur_key_set) -# self.cur_key_iter = itertools.cycle(self.cur_key_set) -# -# -# def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: -# -# key = next(self.cur_key_iter) -# while per_key_queues[key].size() == 0: -# key = next(self.cur_key_iter) -# # TODO(simon): maybe do a "peak" here to trigger eviction policies -# return key -# -#class AdaptiveWeightedRoundRobin(CrossKeyLoadBalancer): -# """Simple policy that cycle through all the keys fairly""" -# -# def __init__(self, timestamp_weights_file): -# self.cur_key_set = [] -# self.cur_key_iter = None -# -# pageview_df = pd.read_csv(pageview_file) -# self.raw_weights = pageview_df.set_index("doc_id")["weights"].to_dict() -# self.weights = {} -# for key in self.raw_weights.keys(): -# if str(key) not in all_keys: -# continue -# -# self.weights[key] = int(self.raw_weights[key]*1000) -# assert self.weights[key] > 0, f"Too small {key}, {self.raw_weights[key]}" -# -# -# for key in self.weights.keys(): -# for i in range(self.weights[key]): -# self.cur_key_set.append(str(key)) -# random.shuffle(self.cur_key_set) -# self.cur_key_iter = itertools.cycle(self.cur_key_set) -# -# -# def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: -# -# key = next(self.cur_key_iter) -# while per_key_queues[key].size() == 0: -# key = next(self.cur_key_iter) -# # TODO(simon): maybe do a "peak" here to trigger eviction policies -# return key -# -# -#class AdaptiveWeightedLoadBalancer(CrossKeyLoadBalancer): -# -# def __init__(self, timestamp_weights_file): -# data = json.load(open(timestamp_weights_file)) -# self.timestamp_weights = {} -# for key in data.keys(): -# self.timestamp_weights[int(key)] = data[key] -# -# def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], timestamp: int) -> str: -# weights_map = current_weights(timestamp, self.timestamp_weights) -# -# chosen_key = None -# max_len = 0 -# total_len = 0 -# keys = [] -# weights = [] -# for key in per_key_queues.keys(): -# size = per_key_queues[key].size() -# if size >= 1 and key in weights_map: -# keys.append(key) -# weights.append(weights_map[key]) -# total_len += size -# chosen_key = random.choices(keys, weights, k=1)[0] -# return chosen_key -# -# -#class WeightedLoadBalancer(CrossKeyLoadBalancer): -# -# def __init__(self, pageview_file): -# pageview_df = pd.read_csv(pageview_file) -# #self.weights = pageview_df.set_index("doc_id")["weights"].to_dict() -# self.weights = json.load(open("weights.json")) -# -# def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: -# chosen_key = None -# max_len = 0 -# total_len = 0 -# keys = [] -# weights = [] -# for key in per_key_queues.keys(): -# size = per_key_queues[key].size() -# if size >= 1 and int(key) in self.weights: -# keys.append(key) -# weights.append(self.weights[int(key)]) -# total_len += size -# -# chosen_key = random.choices(keys, weights, k=1)[0] -# #print("choose", chosen_key, keys, weights) -# return chosen_key -# -#class RandomLoadBalancer(CrossKeyLoadBalancer): -# -# def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: -# chosen_key = None -# max_len = 0 -# total_len = 0 -# keys = [] -# for key in per_key_queues.keys(): -# size = per_key_queues[key].size() -# if size >= 1: -# keys.append(key) -# total_len += size -# -# chosen_key = random.choices(keys, k=1)[0] -# return chosen_key -# -# -#class WeightedLongestQueueLoadBalancer(CrossKeyLoadBalancer): -# -# def __init__(self, pageview_file): -# pageview_df = pd.read_csv(pageview_file) -# self.weights = pageview_df.set_index("doc_id")["weights"].to_dict() -# #print(self.weights) -# -# def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: -# chosen_key = None -# max_len = 0 -# total_len = 0 -# for key in per_key_queues.keys(): -# size = per_key_queues[key].size() -# if int(key) not in self.weights: -# continue -# weighted_size = self.weights[int(key)]*self.weights[int(key)] -# if weighted_size > max_len: -# chosen_key = key -# max_len = size -# total_len += size -# #print(chosen_key, max_len, self.weights[int(chosen_key)]) -# per_key_queues[chosen_key].clear() -# print("clear", chosen_key, total_len, per_key_queues[chosen_key].size()) -# return chosen_key -# -#class WeightedLoadBalancer(CrossKeyLoadBalancer): -# -# def __init__(self, pageview_file): -# pageview_df = pd.read_csv(pageview_file) -# self.weights = pageview_df.set_index("doc_id")["weights"].to_dict() -# #print(self.weights) -# -# def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: -# chosen_key = None -# max_len = 0 -# total_len = 0 -# keys = [] -# weights = [] -# for key in per_key_queues.keys(): -# size = per_key_queues[key].size() -# if size >= 1 and int(key) in self.weights: -# keys.append(key) -# weights.append(self.weights[int(key)]) -# total_len += size -# -# chosen_key = random.choices(keys, weights, k=1)[0] -# #print("choose", chosen_key, keys, weights) -# return chosen_key -# -#class LongestQueueLoadBalancer(CrossKeyLoadBalancer): -# -# def choose(self, per_key_queues: Dict[str, PerKeyPriorityQueue], ts) -> str: -# chosen_key = None -# max_len = 0 -# total_len = 0 -# for key in per_key_queues.keys(): -# size = per_key_queues[key].size() -# if size > max_len: -# chosen_key = key -# max_len = size -# total_len += size -# per_key_queues[chosen_key].clear() -# -# return chosen_key - - -class WikiMapper(RalfMapper): - def __init__( - self, - env: simpy.Environment, - source_queues: Dict[str, PerKeyPriorityQueue], - key_selection_policy_cls: Type[CrossKeyLoadBalancer], - model_run_time_s: float, - keys: List[str], - num_replicas: int = 1, - ) -> None: - - super().__init__(env, source_queues, key_selection_policy_cls, model_run_time_s, num_replicas) - self.keys = keys - #self.source_queues = source_queues - - # self.env = env - # self.source_queues = source_queues - # self.key_selection_policy = key_selection_policy_cls() - # self.model_runtime_s = model_run_time_s - # self.env.process(self.run()) - - self.ready_time_to_batch: Dict[float, List[Tuple[int, float]]] = {} - - ## Shard source queues into each replica's id. - #source_keys = list(source_queues.keys()) - #random.shuffle(source_keys) - #self.sharded_keys = dict( - # enumerate(map(list, divide(num_replicas, source_keys))) - #) - #self.key_selection_policy = key_selection_policy_cls - #self.model_runtime_s = model_run_time_s - #for i in range(num_replicas): - # print("Run replica", i) - # self.env.process(self.run(replica_id=i)) - - - def run(self, replica_id: int): - this_shard_source_queues = { - key: self.total_source_queues[key] for key in self.sharded_keys[replica_id] - } - #print("keys", replica_id, self.sharded_keys[replica_id]) - - #self.source_queues = { - # key: self.total_source_queues[key] for key in self.sharded_keys[replica_id] - #} - - while True: - x = yield simpy.AnyOf(self.env, [q.wait() for q in this_shard_source_queues.values()]) - #print("YIELD", replica_id, x) - - # choose key - chosen_key = self.key_selection_policy.choose( - this_shard_source_queues, - replica_id, - ) - assert chosen_key is not None - - # make sure queue size OK - jk doesn't work with dropping - # assert total_size_orig == 0 or total_size == total_size_orig, f"Bad queue size {total_size_orig} -> {total_size}" - - # get chosen key - windows = yield this_shard_source_queues[chosen_key].get() - print( - f"at time {self.env.now:.2f}, RalfMapper replica {replica_id} should work on {windows} (last timestamp), wait time {self.model_runtime_s}" - ) - edits = [(val, windows.key) for val in windows.window[0].value] - - if self.env.now in self.ready_time_to_batch: - self.ready_time_to_batch[self.env.now] += edits - else: - self.ready_time_to_batch[self.env.now] = edits - - # TODO: Add variable runtime - - filename = f"{diff_dir}/{edits[0][0]}" - data = json.load(open(filename)) - num_passages = int(len(data["diffs"][0]) / 10) - runtime = self.model_runtime_s * num_passages - #print(runtime, num_passages) - - yield self.env.timeout(runtime) - #yield self.env.timeout(self.model_runtime_s) - - -# configuration file -config = configparser.ConfigParser() -config.read("config.yml") -plan_dir = config["simulation"]["plan_dir"] -diff_dir = config["directory"]["diff_dir"] -#init_data_file = config["simulation"]["init_data_file"] -#stream_edits_file = config["simulation"]["stream_edits_file"] -#stream_questions_file = config["simulation"]["stream_questions_file"] -#pageview_file = config["files"]["pageview_file"] -#timestamp_weights_file = config["files"]["timestamp_weights_file"] - -run = wandb.init(job_type="dataset-creation", project="wiki-workload") -question_dir = run.use_artifact('ucb-ralf/wiki-workload /questions:v2', type='dataset').download() -simulation_dir = run.use_artifact('ucb-ralf/wiki-workload /simulation:v2', type='dataset').download() -pageview_dir = run.use_artifact('ucb-ralf/wiki-workload /pageviews:v0', type='dataset').download() - -init_data_file = f"{simulation_dir}/init_data.json" -stream_edits_file = f"{simulation_dir}/edit_stream.json" -stream_questions_file = f"{simulation_dir}/question_stream.json" -pageview_file = f"{pageview_dir}/pageviews.csv" -timestamp_weights_file = f"{pageview_dir}/timestamp_weights_file.json" - -# load simulation data -edits = json.load(open(stream_edits_file)) -init_data = json.load(open(init_data_file)) -keys = list(init_data.keys()) - - -def run_once( - out_path: str, - prioritization_policy: str, - load_shedding_policy: str, - keys: List[str], - per_key_records_per_second: int, - total_runtime_s: float, - model_runtime_constant: float, - key_selection_policy: str, - num_replicas: int, -): - - policies = { - "fifo": fifo, - "lifo": lifo, - "always_process": always_process, - "round_robin": RoundRobinLoadBalancer(num_replicas=num_replicas), - "weighted_round_robin": WeightedRoundRobinLoadBalancer(keys, num_replicas=num_replicas) - } - - env = simpy.Environment() - - source_to_window_queue = simpy.Store(env) - windows_to_mapper_queue = { - key: PerKeyPriorityQueue( - env, - processing_policy=policies[prioritization_policy], - load_shedding_policy=policies[load_shedding_policy], - ) - for key in keys - } - - JSONSource( - env, - records_per_sec_per_key=per_key_records_per_second, - num_keys=len(keys), - next_queue=source_to_window_queue, - total_run_time=total_runtime_s, - data_file=stream_edits_file, - ) - - WindowOperator( - env, - window_size=1, - slide_size=1, - source_queue=source_to_window_queue, - next_queues=windows_to_mapper_queue, - ) - - m = WikiMapper( - env, - source_queues=windows_to_mapper_queue, - model_run_time_s=model_runtime_constant, - key_selection_policy_cls=policies[key_selection_policy], - keys=keys, - num_replicas=num_replicas, - ) - env.run(until=total_runtime_s) - - plan = m.ready_time_to_batch - with open(out_path, "w") as f: - json.dump(plan, f) - - -if __name__ == "__main__": - - # argument flags - parser = argparse.ArgumentParser() - parser.add_argument("--send_rate", type=int) - parser.add_argument("--model_runtime", type=float) - parser.add_argument("--total_runtime", type=float, default=len(edits)) - parser.add_argument("--event_policy", type=str) - parser.add_argument("--key_policy", type=str) - parser.add_argument("--load_shedding_policy", type=str) - parser.add_argument("--num_replicas", type=int) - args = parser.parse_args() - - plan_name = f"{plan_dir}/plan-{args.key_policy}_{args.event_policy}-{args.load_shedding_policy}-{args.model_runtime}-{args.send_rate}_replicas_{args.num_replicas}" - out_path = f"{plan_name}.json" - print(out_path) - run_once( - out_path=out_path, - prioritization_policy=args.event_policy, - load_shedding_policy=args.load_shedding_policy, - keys=keys, - per_key_records_per_second=args.send_rate, - total_runtime_s=args.total_runtime, - model_runtime_constant=args.model_runtime, - key_selection_policy=args.key_policy, - num_replicas=args.num_replicas, - ) - log_plans(run, config, plan_dir) - - - # load sheding: random, drop short edits - # prioritization: prioritize most recent version - # cross-key prioritzation: historical page views, - # policies - #prioritization_policies = ["lifo"] # ["fifo", "lifo"] - ##key_selection_policies = ["adaptive_weighted_random", "weighted_round_robin", "weighted_random", "weighted_longest_queue", "longest_queue", "random", "round_robin"] - #key_selection_policies = ["round_robin"] - #load_shedding_policies = ["always_process"] - ##model_runtimes = [0.01, 0.05, 0.1, 1, 5, 10] # [0.000001, 0.00001, 0.0000001, 0.000000001, 0] - #model_runtimes = [0.02, 0.05, 0.07] # [0.000001, 0.00001, 0.0000001, 0.000000001, 0] - #records_per_second = [100] - - #output_files = [] - - #for key_selection in key_selection_policies: - # for prio_policy in prioritization_policies: - # for load_shed_policy in load_shedding_policies: - # for runtime in model_runtimes: - # for rate in records_per_second: - - # out_path = f"{plan_dir}/plan-{key_selection}_{prio_policy}-{load_shed_policy}-{runtime}-{rate}.json" - # print("running", out_path, runtime) - # run_once( - # out_path, - # prio_policy, - # load_shed_policy, - # keys, - # per_key_records_per_second=rate, - # total_runtime_s=len(edits), - # model_runtime_constant=runtime, - # key_selection_policy=key_selection, - # ) - - # output_files.append(out_path) - # print("DONE", out_path) - #for f in output_files: - # print(f) - #slide_#open("plans.txt", "w").write("\n".join(output_files)) diff --git a/wikipedia/wiki_eval.py b/wikipedia/wiki_eval.py deleted file mode 100644 index ddc6604..0000000 --- a/wikipedia/wiki_eval.py +++ /dev/null @@ -1,325 +0,0 @@ -import configparser -from typing import List -import pickle -import shutil -from tqdm import tqdm -import time -import numpy as np -import json -import pandas as pd -import argparse -from statsmodels.tsa.seasonal import STL, DecomposeResult -import json -import os -from collections import defaultdict -from multiprocessing import Pool -import torch -from dpr.models import init_biencoder_components -from dpr.options import ( - add_encoder_params, - setup_args_gpu, - print_args, - set_encoder_params_from_state, - add_tokenizer_params, - add_cuda_params, -) -from dpr.utils.model_utils import ( - setup_for_distributed_mode, - load_states_from_checkpoint, - get_model_obj, - move_to_device, -) -from dpr.utils.data_utils import Tensorizer - -from preprocessing.log_data import log_plan_data - -""" - -Script for evaluating plans for the wikipedia edit stream dataset. Writes output files which need to be processed by DPR script. - -Download require data: - * rev_dir = s3://feature-store-datasets/wikipedia/edit_diffs/ - * init_data_file = s3://feature-store-datasets/wikipedia/simulation/init_data.json - * questions_file = ?? - * model_file = s3://feature-store-datasets/wikipedia/models/bert-base-encoder.cp - -Upload results: - * exp_dir = s3://feature-store-datasets/wikipedia/simulation_output/ -""" -# simulation data - -import wandb -run = wandb.init(project='wiki-workload', job_type="dataset-creation") -simulation_dir = run.use_artifact('ucb-ralf/wiki-workload /simulation:v2', type='dataset').download() -question_dir = run.use_artifact('ucb-ralf/wiki-workload /questions:v2', type='dataset').download() - -init_data_file = f"{simulation_dir}/init_data.json" -stream_edits_file = f"{simulation_dir}/edit_stream.json" -stream_questions_file = f"{simulation_dir}/question_stream.json" - -config = configparser.ConfigParser() -config.read("config.yml") -#plan_dir = config["simulation"]["plan_dir"] -#init_data_file = config["simulation"]["init_data_file"] -#stream_edits_file = config["simulation"]["stream_edits_file"] -#stream_questions_file = config["simulation"]["stream_questions_file"] -rev_dir = config['directory']['diff_dir'] -embedding_dir = config['directory']['embedding_dir'] -exp_dir = config['directory']['exp_dir'] -model_file = config['files']['model_file'] - -# Create parser -parser = argparse.ArgumentParser(description="Specify experiment config") -parser.add_argument("--offline-plan-path", type=str) -parser.add_argument("--embed", default=False, action="store_true") -parser.add_argument("--wandb", default=False, action="store_true") -args = parser.parse_args() - -exp_id = os.path.basename(args.offline_plan_path).replace(".json", "") -run.config.update(vars(args)) -run.config.update({"plan": exp_id}) - -def sents_to_passages(sents, num_sent_in_pass=10): - passages = [] - - for i in range(0, len(sents), num_sent_in_pass): - passages.append(" ".join(sents[i : i + num_sent_in_pass])) - return passages - - -def embedding_path(revid, version="_new"): - return os.path.join(embedding_dir, f"{revid}{version}.pkl") - - -def offline_eval(plan_json_path, exp_id, compute_embeddings=True): - - # only process subset of keys - keys = ["51150040"] - filter_keys = False - - - # compute initial passage embeddings for each document - init_data = json.load(open(init_data_file)) - init_state = {} - for key in tqdm(init_data.keys()): - - if filter_keys and key not in keys: - continue - sents = init_data[key]["sents"] - revid = init_data[key]["revid"] - - print(init_data_file) - print(init_data[key]["file"]) - embedding_data = pickle.load(open(embedding_path(revid, version="_orig"), "rb")) - embeddings = embedding_data["embeddings"] - passages = sents_to_passages(sents) - if not len(passages) == len(embeddings): - print(f"passage {len(passages)} embeddings {len(embeddings)}") - print(len(embedding_data["passages"])) - print(revid) - print("diff file", init_data[key]["file"]) - print("embedding file", embedding_data["file"]) - print(embedding_data["timestamp"]) - print(len(sents)) - return - - init_state[key] = { - "passages": passages, - "embeddings": embeddings, - "rev": "init", - } - - print(f"Created init state for {len(init_state.keys())} keys") - - # compute passage embeddings for each timestep (using plan) - embed_versions = {"0": init_state} - plan = json.load(open(plan_json_path)) - embed_version_keys: List[str] = list(plan.keys()) - count = 0 - missing = set([]) - print("looping keys", len(embed_version_keys)) - for version in tqdm(embed_version_keys): - state = {} - for task in plan[version]: - #print("task", task, version) - rev_file = task[0] - doc_id = task[1] - # doc_id = task[2] - # rev_file = task[3] - # if filter_keys and doc_id not in keys: - # continue - data = json.load(open(os.path.join(rev_dir, rev_file))) - timestamp = data["timestamp"] - title = data["title"] - sents = [d["sent_b"] for d in data["diffs"][0]] - revid = rev_file.replace(".json", "").split("_")[0] - embedding_filename = embedding_path(revid, version="_new") - assert os.path.exists( - embedding_filename - ), f"Missing revid {embedding_filename}" - if os.path.exists(embedding_filename): - embedding_data = pickle.load( - open(embedding_path(revid, version="_new"), "rb") - ) - # assert embedding_data["timestamp"] == timestamp - embeddings = embedding_data["embeddings"] - passages = embedding_data["passages"] - assert len(passages) == len( - sents_to_passages(sents) - ), f"Inconsistent passage len {len(passages)}, {len(sents_to_passages(sents))}" - # passages = sents_to_passages(sents) - assert len(passages) == len(embeddings) - else: - missing.add(doc_id) - continue - # print("fitting", timestamp, version, doc_id, rev_file) - count += 1 - state[doc_id] = { - "passages": passages, - "embeddings": embeddings, - "rev": rev_file, - } - - # save version - embed_versions[version] = state - print("EMBED", embed_versions.keys()) - print("Num refits", count, len(missing)) - - embed_filename = "embed_versions.pkl" - pickle.dump(embed_versions, open(embed_filename, "wb")) - return embed_filename - -# returns latest version of document embeddings for timestep/key -def get_latest_embedding(timestep, doc_id, embed_versions): - - latest = 0 - for version in embed_versions.keys(): - version = float(version) - if ( - float(timestep) >= version - and version > latest - and doc_id in embed_versions[str(version)] - ): - latest = version - #print(doc_id, "latest", timestep, latest, timestep - latest) - assert ( - doc_id in embed_versions[str(latest)] - ), f"Missing doc id {doc_id} {latest} {doc_id in init_data}" - doc_version = embed_versions[str(latest)][doc_id] - assert latest <= timestep - return ( - doc_version["passages"], - doc_version["embeddings"], - doc_version["rev"], - latest, - ) - -def generate_question_data_all(exp_id, embed_filename): - # create experiment directory - directory = os.path.join(exp_dir, exp_id) - if os.path.isdir(directory): - print("Removing", directory) - shutil.rmtree(directory) - print("Creating", directory) - os.mkdir(directory) - - # get simulation data questions - questions = json.load(open(stream_questions_file)) - - for ts in range(len(questions)): - questions[ts]["ts"] = ts - - print("processing questions", len(questions)) - print("directory", directory) - - chunk_size = 1000 - chunks = [(questions[i:i+chunk_size], embed_filename, directory) for i in range(0, len(questions), chunk_size)] - p = Pool(64) - staleness_all = p.starmap(generate_question_data, chunks) - p.close() - staleness_all = [item for sublist in staleness_all for item in sublist] - staleness = np.array(staleness_all).mean() - print("all staleness", staleness) - wandb.log({"staleness": staleness}) - return directory - - -def generate_question_data(questions, embed_filename, directory): - embed_versions = pickle.load(open(embed_filename, "rb")) - init_data = json.load(open(init_data_file)) - - staleness = [] - for ts_questions in questions: - ts = ts_questions["ts"] - timestep = ts / 100 # TODO: Watch out!! can change and mess up experiment - for doc_id in ts_questions.keys(): - if doc_id == "ts": continue - # not considered in edits - if doc_id not in init_data: - print("missing", doc_id) - # print(init_data.keys()) - continue - - # get current embedding and write - passage_texts, passage_embeddings, version, latest = get_latest_embedding( - timestep, doc_id, embed_versions - ) - - # loop through questions - doc_questions = ts_questions[doc_id] - queries = [] - for q in doc_questions: - question = q["question"] - answer = q["answer"] - assert ( - str(q["doc_id"]) == doc_id - ), f"doc id mismatch {q['doc_id']}, {doc_id}" - assert ( - q["ts_min"] == ts - ), f"time mismatch {q['ts_min']}, {timestep}, {ts}" - queries.append([question, [answer], doc_id]) - - # append per query - staleness.append(timestep - latest) - - # dump CTX/question script - contex_file = f"{directory}/dpr_ctx_after_{int(ts)}_{doc_id}" - text_file = f"{directory}/passages_{int(ts)}_{doc_id}.tsv" - doc_questions_file = ( - f"{directory}/qa_{int(ts)}_{doc_id}.tsv" # question, answer(s), doc id - ) - doc_questions_df = pd.DataFrame(queries) - doc_questions_df.to_csv( - doc_questions_file, sep="\t", index=False, header=False - ) - # write passage file - id, text, title, doc_id - text_df = pd.DataFrame( - [[i, passage_texts[i], "", doc_id] for i in range(len(passage_texts))] - ) - text_df.to_csv(text_file, sep="\t", index=False, header=False) - # write ctx file - passage_ctx = [] - for i in range(len(passage_embeddings)): - passage_ctx.append([i, passage_embeddings[i]]) - pickle.dump(np.array(passage_ctx, dtype=object), open(contex_file, "wb")) - - assert len(passage_ctx) == len(passage_texts) - assert len(passage_embeddings) == len(passage_texts) - print("staleness", np.array(staleness).mean()) - return staleness - -def main(): - - - embed_filename = offline_eval(args.offline_plan_path, exp_id, compute_embeddings=args.embed) - - #embed_filename = "embed_versions.pkl" - generate_question_data_all(exp_id, embed_filename) - #if args.wandb: - # import wandb - # run = wandb.init(job_type="dataset-creation", project="wiki-workload") - # log_plan_data(run, config, exp_id, output_dir) - - -if __name__ == "__main__": - main() From 1fdb9073ea5cd2fe79ada11a16f24ff47ef86892 Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Tue, 19 Oct 2021 12:45:39 -0700 Subject: [PATCH 25/26] rename file --- wikipedia/offline/prepare_dpr_data.py | 326 ++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 wikipedia/offline/prepare_dpr_data.py diff --git a/wikipedia/offline/prepare_dpr_data.py b/wikipedia/offline/prepare_dpr_data.py new file mode 100644 index 0000000..5f454a1 --- /dev/null +++ b/wikipedia/offline/prepare_dpr_data.py @@ -0,0 +1,326 @@ +import configparser +from typing import List +import pickle +import shutil +from tqdm import tqdm +import time +import numpy as np +import json +import pandas as pd +import argparse +from statsmodels.tsa.seasonal import STL, DecomposeResult +import json +import os +from collections import defaultdict +from multiprocessing import Pool +import torch +from dpr.models import init_biencoder_components +from dpr.options import ( + add_encoder_params, + setup_args_gpu, + print_args, + set_encoder_params_from_state, + add_tokenizer_params, + add_cuda_params, +) +from dpr.utils.model_utils import ( + setup_for_distributed_mode, + load_states_from_checkpoint, + get_model_obj, + move_to_device, +) +from dpr.utils.data_utils import Tensorizer + +from preprocessing.log_data import log_plan_data + +""" + +Script for evaluating plans for the wikipedia edit stream dataset. Writes output files which need to be processed by DPR script. + +Download require data: + * rev_dir = s3://feature-store-datasets/wikipedia/edit_diffs/ + * init_data_file = s3://feature-store-datasets/wikipedia/simulation/init_data.json + * questions_file = ?? + * model_file = s3://feature-store-datasets/wikipedia/models/bert-base-encoder.cp + +Upload results: + * exp_dir = s3://feature-store-datasets/wikipedia/simulation_output/ +""" +# simulation data + +import wandb +run = wandb.init(project='wiki-workload', job_type="dataset-creation") +simulation_dir = run.use_artifact('ucb-ralf/wiki-workload /simulation:v2', type='dataset').download() +question_dir = run.use_artifact('ucb-ralf/wiki-workload /questions:v2', type='dataset').download() + +init_data_file = f"{simulation_dir}/init_data.json" +stream_edits_file = f"{simulation_dir}/edit_stream.json" +stream_questions_file = f"{simulation_dir}/question_stream.json" + +config = configparser.ConfigParser() +config.read("config.yml") +#plan_dir = config["simulation"]["plan_dir"] +#init_data_file = config["simulation"]["init_data_file"] +#stream_edits_file = config["simulation"]["stream_edits_file"] +#stream_questions_file = config["simulation"]["stream_questions_file"] +rev_dir = config['directory']['diff_dir'] +embedding_dir = config['directory']['embedding_dir'] +exp_dir = config['directory']['exp_dir'] +model_file = config['files']['model_file'] + +# Create parser +parser = argparse.ArgumentParser(description="Specify experiment config") +parser.add_argument("--offline-plan-path", type=str) +parser.add_argument("--embed", default=False, action="store_true") +parser.add_argument("--wandb", default=False, action="store_true") +parser.add_argument("--workers", type=int) +args = parser.parse_args() + +exp_id = os.path.basename(args.offline_plan_path).replace(".json", "") +run.config.update(vars(args)) +run.config.update({"plan": exp_id}) + +def sents_to_passages(sents, num_sent_in_pass=10): + passages = [] + + for i in range(0, len(sents), num_sent_in_pass): + passages.append(" ".join(sents[i : i + num_sent_in_pass])) + return passages + + +def embedding_path(revid, version="_new"): + return os.path.join(embedding_dir, f"{revid}{version}.pkl") + + +def offline_eval(plan_json_path, exp_id, compute_embeddings=True): + + # only process subset of keys + keys = ["51150040"] + filter_keys = False + + + # compute initial passage embeddings for each document + init_data = json.load(open(init_data_file)) + init_state = {} + for key in tqdm(init_data.keys()): + + if filter_keys and key not in keys: + continue + sents = init_data[key]["sents"] + revid = init_data[key]["revid"] + + print(init_data_file) + print(init_data[key]["file"]) + embedding_data = pickle.load(open(embedding_path(revid, version="_orig"), "rb")) + embeddings = embedding_data["embeddings"] + passages = sents_to_passages(sents) + if not len(passages) == len(embeddings): + print(f"passage {len(passages)} embeddings {len(embeddings)}") + print(len(embedding_data["passages"])) + print(revid) + print("diff file", init_data[key]["file"]) + print("embedding file", embedding_data["file"]) + print(embedding_data["timestamp"]) + print(len(sents)) + return + + init_state[key] = { + "passages": passages, + "embeddings": embeddings, + "rev": "init", + } + + print(f"Created init state for {len(init_state.keys())} keys") + + # compute passage embeddings for each timestep (using plan) + embed_versions = {"0": init_state} + plan = json.load(open(plan_json_path)) + embed_version_keys: List[str] = list(plan.keys()) + count = 0 + missing = set([]) + print("looping keys", len(embed_version_keys)) + for version in tqdm(embed_version_keys): + state = {} + for task in plan[version]: + #print("task", task, version) + rev_file = task[0] + doc_id = task[1] + # doc_id = task[2] + # rev_file = task[3] + # if filter_keys and doc_id not in keys: + # continue + data = json.load(open(os.path.join(rev_dir, rev_file))) + timestamp = data["timestamp"] + title = data["title"] + sents = [d["sent_b"] for d in data["diffs"][0]] + revid = rev_file.replace(".json", "").split("_")[0] + embedding_filename = embedding_path(revid, version="_new") + assert os.path.exists( + embedding_filename + ), f"Missing revid {embedding_filename}" + if os.path.exists(embedding_filename): + embedding_data = pickle.load( + open(embedding_path(revid, version="_new"), "rb") + ) + # assert embedding_data["timestamp"] == timestamp + embeddings = embedding_data["embeddings"] + passages = embedding_data["passages"] + assert len(passages) == len( + sents_to_passages(sents) + ), f"Inconsistent passage len {len(passages)}, {len(sents_to_passages(sents))}" + # passages = sents_to_passages(sents) + assert len(passages) == len(embeddings) + else: + missing.add(doc_id) + continue + # print("fitting", timestamp, version, doc_id, rev_file) + count += 1 + state[doc_id] = { + "passages": passages, + "embeddings": embeddings, + "rev": rev_file, + } + + # save version + embed_versions[version] = state + print("EMBED", embed_versions.keys()) + print("Num refits", count, len(missing)) + + embed_filename = "embed_versions.pkl" + pickle.dump(embed_versions, open(embed_filename, "wb")) + return embed_filename + +# returns latest version of document embeddings for timestep/key +def get_latest_embedding(timestep, doc_id, embed_versions): + + latest = 0 + for version in embed_versions.keys(): + version = float(version) + if ( + float(timestep) >= version + and version > latest + and doc_id in embed_versions[str(version)] + ): + latest = version + #print(doc_id, "latest", timestep, latest, timestep - latest) + assert ( + doc_id in embed_versions[str(latest)] + ), f"Missing doc id {doc_id} {latest} {doc_id in init_data}" + doc_version = embed_versions[str(latest)][doc_id] + assert latest <= timestep + return ( + doc_version["passages"], + doc_version["embeddings"], + doc_version["rev"], + latest, + ) + +def generate_question_data_all(exp_id, embed_filename): + # create experiment directory + directory = os.path.join(exp_dir, exp_id) + if os.path.isdir(directory): + print("Removing", directory) + shutil.rmtree(directory) + print("Creating", directory) + os.mkdir(directory) + + # get simulation data questions + questions = json.load(open(stream_questions_file)) + + for ts in range(len(questions)): + questions[ts]["ts"] = ts + + print("processing questions", len(questions)) + print("directory", directory) + + chunk_size = 1000 + chunks = [(questions[i:i+chunk_size], embed_filename, directory) for i in range(0, len(questions), chunk_size)] + p = Pool(args.workers) + staleness_all = p.starmap(generate_question_data, chunks) + p.close() + staleness_all = [item for sublist in staleness_all for item in sublist] + staleness = np.array(staleness_all).mean() + print("all staleness", staleness) + wandb.log({"staleness": staleness}) + return directory + + +def generate_question_data(questions, embed_filename, directory): + embed_versions = pickle.load(open(embed_filename, "rb")) + init_data = json.load(open(init_data_file)) + + staleness = [] + for ts_questions in questions: + ts = ts_questions["ts"] + timestep = ts / 100 # TODO: Watch out!! can change and mess up experiment + for doc_id in ts_questions.keys(): + if doc_id == "ts": continue + # not considered in edits + if doc_id not in init_data: + print("missing", doc_id) + # print(init_data.keys()) + continue + + # get current embedding and write + passage_texts, passage_embeddings, version, latest = get_latest_embedding( + timestep, doc_id, embed_versions + ) + + # loop through questions + doc_questions = ts_questions[doc_id] + queries = [] + for q in doc_questions: + question = q["question"] + answer = q["answer"] + assert ( + str(q["doc_id"]) == doc_id + ), f"doc id mismatch {q['doc_id']}, {doc_id}" + assert ( + q["ts_min"] == ts + ), f"time mismatch {q['ts_min']}, {timestep}, {ts}" + queries.append([question, [answer], doc_id]) + + # append per query + staleness.append(timestep - latest) + + # dump CTX/question script + contex_file = f"{directory}/dpr_ctx_after_{int(ts)}_{doc_id}" + text_file = f"{directory}/passages_{int(ts)}_{doc_id}.tsv" + doc_questions_file = ( + f"{directory}/qa_{int(ts)}_{doc_id}.tsv" # question, answer(s), doc id + ) + doc_questions_df = pd.DataFrame(queries) + doc_questions_df.to_csv( + doc_questions_file, sep="\t", index=False, header=False + ) + # write passage file - id, text, title, doc_id + text_df = pd.DataFrame( + [[i, passage_texts[i], "", doc_id] for i in range(len(passage_texts))] + ) + text_df.to_csv(text_file, sep="\t", index=False, header=False) + # write ctx file + passage_ctx = [] + for i in range(len(passage_embeddings)): + passage_ctx.append([i, passage_embeddings[i]]) + pickle.dump(np.array(passage_ctx, dtype=object), open(contex_file, "wb")) + + assert len(passage_ctx) == len(passage_texts) + assert len(passage_embeddings) == len(passage_texts) + print("staleness", np.array(staleness).mean()) + return staleness + +def main(): + + + embed_filename = offline_eval(args.offline_plan_path, exp_id, compute_embeddings=args.embed) + + #embed_filename = "embed_versions.pkl" + generate_question_data_all(exp_id, embed_filename) + #if args.wandb: + # import wandb + # run = wandb.init(job_type="dataset-creation", project="wiki-workload") + # log_plan_data(run, config, exp_id, output_dir) + + +if __name__ == "__main__": + main() From 6d97aa686fa71d99176e32bbeb09ebee13340192 Mon Sep 17 00:00:00 2001 From: Sarah Wooders Date: Tue, 19 Oct 2021 15:00:43 -0700 Subject: [PATCH 26/26] update README --- wikipedia/README.md | 60 ++++++++++++++++++++++++++++++ wikipedia/offline/download_data.sh | 21 +++++++++++ 2 files changed, 81 insertions(+) create mode 100644 wikipedia/README.md create mode 100644 wikipedia/offline/download_data.sh diff --git a/wikipedia/README.md b/wikipedia/README.md new file mode 100644 index 0000000..983b625 --- /dev/null +++ b/wikipedia/README.md @@ -0,0 +1,60 @@ +# Wikipedia Experiment Pipeline + +### Configuration +Update `config.yml` + +### Generating simulation data +Run parts of the pipeline using flags: +``` +python generate_data.py \ + --run_query_recentchanges # query wikipedia recentchanges api + --run_query_doc_versions # query wikipedia docs api + --run_recent_changes # process raw changes data into changes.csv file + --run_parse_docs # process raw doc data with wikiparser + --run_get_questions # process raw questions into questions.csv + --run_get_pageviews # process raw pageview data into pageviews.csv + --run_generate_diffs # compute diffs between different version + --run_generate_simulation_data # generate simulation data + --run_check_dataset # check dataset + --run_generate_embeddings # embed documents +``` +To update simulation data, make sure you have the embeddings and diffs already download, and run: +``` +python generate_data.py --run_generate_simulation_data --run_get_questions --run_check_dataset +``` + + +## Offline Simulation Pipeline +Download the data with `./download_data.sh` (warning: 100s of GBs) and update `config.yml`. + +Run the simulation in stages to go from raw Wikipedia API data to simulation results: + +``` +./run_0_generate_data.sh # generate simulation data from questions.csv file +./run_1_generate_plan.sh # run simulations to generate plan +./run_2_prepare_data.sh # use plan to determine questions / embedding versions at each timestep +./run_3_run_predictions.sh # run DPR model on embeddings +./run_4_run_optimal_predictons.sh # generate optimal predictions +``` + +### Logging Data +To save the current data, run +``` +python log_data.py +``` + +### Logging Experiments +TODO + +## Online Pipeline (ralf) +(NOTE: incomplete) +Run the server +``` +python wiki_server.py +``` +Run the client +``` +python wiki_client.py +``` + + diff --git a/wikipedia/offline/download_data.sh b/wikipedia/offline/download_data.sh new file mode 100644 index 0000000..208e477 --- /dev/null +++ b/wikipedia/offline/download_data.sh @@ -0,0 +1,21 @@ +data_dir=/data/wooders/wikipedia + +# download diffs +mkdir -p ${data_dir}/diffs; +aws s3 sync s3://feature-store-datasets/wikipedia/diffs diffs; + +# download model +aws s3 cp s3://feature-store-datasets/wikipedia/models/bert-base-encoder.cp ${data_dir}; + +# download questions +aws s3 cp s3://feature-store-datasets/wikipedia/10062021_filtered_questions.csv ${data_dir}; + +# download embeddings +mkdir -p ${data_dir}/embeddings; +aws s3 sync s3://feature-store-datasets/wikipedia/embeddings embeddings; + +## download raw api data +#mkdir -p ${data_dir}/recentchanges; +#mkdir -p ${data_dir}/doc_xml; +#aws s3 sync s3://feature-store-datasets/wikipedia/recentchanges recentchanges; +#aws s3 sync s3://feature-store-datasets/wikipedia/doc_xml doc_xml;