refactoring significantly

This commit is contained in:
Nick
2019-09-10 12:35:11 -06:00
parent 840178ccc9
commit 61d0cd77cc
18 changed files with 201 additions and 108 deletions
+1 -1
View File
@@ -1 +1 @@
# Keys
#AIDungeon Code
Binary file not shown.
Binary file not shown.
View File
View File
+129
View File
@@ -0,0 +1,129 @@
# This file includes code which was modified from https://github.com/openai/gpt-2
import tensorflow as tf
import os
import json
import regex as re
from functools import lru_cache
import requests
import boto3
@lru_cache()
def bytes_to_unicode():
bs = (
list(range(ord("!"), ord("~") + 1))
+ list(range(ord("¡"), ord("¬") + 1))
+ list(range(ord("®"), ord("ÿ") + 1))
)
cs = bs[:]
n = 0
for b in range(2 ** 8):
if b not in bs:
bs.append(b)
cs.append(2 ** 8 + n)
n += 1
cs = [chr(n) for n in cs]
return dict(zip(bs, cs))
def get_pairs(word):
pairs = set()
prev_char = word[0]
for char in word[1:]:
pairs.add((prev_char, char))
prev_char = char
return pairs
class Encoder:
def __init__(self, encoder, bpe_merges, errors="replace"):
self.encoder = encoder
self.decoder = {v: k for k, v in self.encoder.items()}
self.errors = errors
self.byte_encoder = bytes_to_unicode()
self.byte_decoder = {v: k for k, v in self.byte_encoder.items()}
self.bpe_ranks = dict(zip(bpe_merges, range(len(bpe_merges))))
self.cache = {}
self.pat = re.compile(
r"""'s|'t|'re|'ve|'m|'ll|'d| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+"""
)
def bpe(self, token):
if token in self.cache:
return self.cache[token]
word = tuple(token)
pairs = get_pairs(word)
if not pairs:
return token
while True:
bigram = min(pairs, key=lambda pair: self.bpe_ranks.get(pair, float("inf")))
if bigram not in self.bpe_ranks:
break
first, second = bigram
new_word = []
i = 0
while i < len(word):
try:
j = word.index(first, i)
new_word.extend(word[i:j])
i = j
except:
new_word.extend(word[i:])
break
if word[i] == first and i < len(word) - 1 and word[i + 1] == second:
new_word.append(first + second)
i += 2
else:
new_word.append(word[i])
i += 1
new_word = tuple(new_word)
word = new_word
if len(word) == 1:
break
else:
pairs = get_pairs(word)
word = " ".join(word)
self.cache[token] = word
return word
def encode(self, text):
bpe_tokens = []
for token in re.findall(self.pat, text):
token = "".join(self.byte_encoder[b] for b in token.encode("utf-8"))
bpe_tokens.extend(self.encoder[bpe_token] for bpe_token in self.bpe(token).split(" "))
return bpe_tokens
def decode(self, tokens):
text = "".join([self.decoder[token] for token in tokens])
text = bytearray([self.byte_decoder[c] for c in text]).decode("utf-8", errors=self.errors)
return text
def get_encoder():
s3 = boto3.client("s3")
encoder = json.load(
s3.get_object(Bucket="cortex-examples", Key="gpt-2/774M/encoder.json")["Body"]
)
bpe_data = (
s3.get_object(Bucket="cortex-examples", Key="gpt-2/774M/vocab.bpe")["Body"]
.read()
.decode("utf-8")
)
bpe_merges = [tuple(merge_str.split()) for merge_str in bpe_data.split("\n")[1:-1]]
return Encoder(encoder=encoder, bpe_merges=bpe_merges)
encoder = get_encoder()
def pre_inference(sample, metadata):
context = encoder.encode(sample["text"])
return {"context": [context]}
def post_inference(prediction, metadata):
return {encoder.decode(prediction["response"]["sample"])}
+5 -23
View File
@@ -8,6 +8,7 @@ from tensorflow.contrib import predictor
import gpt2.src.sample as sample
import gpt2.src.encoder as encoder
from utils import *
import pdb
pos_action_starts = ["You attack", "You tell", "You use", "You go"]
@@ -24,7 +25,9 @@ class StoryGenerator():
self.enc = encoder.get_encoder(model_path)
hparams = model.default_hparams()
with open(os.path.join(model_path, 'hparams.json')) as f:
hparams.override_from_dict(json.load(f))
hparams.override_from_dict(json.load(f))
pdb.set_trace()
self.context = tf.placeholder(tf.int32, [batch_size, None])
np.random.seed(seed)
@@ -38,8 +41,7 @@ class StoryGenerator():
saver = tf.train.Saver()
ckpt = tf.train.latest_checkpoint(model_path)
saver.restore(self.sess, ckpt)
def generate(self, prompt):
context_tokens = self.enc.encode(prompt)
out = self.sess.run(self.output, feed_dict={
@@ -72,7 +74,6 @@ class StoryGenerator():
action_result = story_replace(action_result)
action = first_sentence(action)
return action, action_result
@@ -107,31 +108,12 @@ def save_model():
tf.saved_model.simple_save(sess, "./saved2", inputs={"context": context}, outputs={"output": output})
def generate_gpu_config(memory_fraction):
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
config.gpu_options.per_process_gpu_memory_fraction = memory_fraction
return config
def run_interactive():
pass
def load_model():
# Set your memory fraction equal to a value less than 1, 0.6 is a good starting point.
# If no fraction is defined, the tensorflow algorithm may run into gpu out of memory problems.
fraction = 0.6
config = config=generate_gpu_config(fraction)
path_to_graph = "./saved"
#tf.saved_model.loader.load(
# session,
# [tf.saved_model.tag_constants.SERVING],
# path_to_graph)
#output = session.graph.get_tensor_by_name('output:0')
#context = session.graph.get_tensor_by_name('context:0')
model_path = 'gpt2/models/117M'
enc = encoder.get_encoder(model_path)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+13 -83
View File
@@ -1,20 +1,6 @@
# Copyright 2018 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START gae_python37_render_template]
import datetime
from flask import g
from flask import session
import os
import googleapiclient.discovery
from utils import *
@@ -35,6 +21,7 @@ phrases = [" You attack", " You use", " You tell", " You go"]
prompts = ["You enter a dungeon with your trusty sword and shield. You are searching for the evil necromancer who killed your family. You've heard that he resides at the bottom of the dungeon, guarded by legions of the undead. You enter the first door and see"]
continuing_prompts = ["You are in a dungeon with your sword and shield. You are on a quest to defeat the necromancer. This dungeon is full of zombie and skeletons."]
app = Flask(__name__)
app.secret_key = '#d\xe0\xd1\xfb\xee\xa4\xbb\xd0\xf0/e)\xb5g\xdd<`\xc7\xa5\xb0-\xb8d0S'
# Encoder Info
encoder_path='gpt2/models/117M'
@@ -49,8 +36,7 @@ storage_client = storage.Client()
bucket = storage_client.get_bucket("dungeon-cache")
# Local generator functionality
RUN_LOCAL = True
session = None
RUN_LOCAL = False
local_generator = None
def get_local_generator():
if "gen" not in g:
@@ -134,7 +120,6 @@ def root():
data = {'seed': seed}
return render_template('index.html', data=data)
@app.route('/<seed>')
def rootseed(seed):
if seed == "":
@@ -142,6 +127,7 @@ def rootseed(seed):
else:
seed = int(seed)
data = {'seed': seed}
session["seed"] = seed
return render_template('index.html', data=data)
@app.route('/index.html')
@@ -192,15 +178,17 @@ def story_request():
prompt_num = int(request.form["prompt_num"])
gen_actions = request.form["actions"]
print("Session Seed is ", session["seed"])
if int(seed) < 0 or int(seed) > 100:
print("Invalid seed: " + seed)
#print("Invalid seed: " + seed)
abort(404)
if gen_actions == "true":
#prompt = request.form["prompt"]
choices = json.loads(request.form["choices"])
print("Getting response for seed ", seed, " prompt_num ", prompt_num, " and choices ", choices)
#print("Getting response for seed ", seed, " prompt_num ", prompt_num, " and choices ", choices)
action_results = retrieve_from_cache(seed, prompt_num, choices, "choices")
@@ -209,13 +197,13 @@ def story_request():
else:
last_action_result = request.form["last_action_result"]
prompt = continuing_prompts[prompt_num] + last_action_result
print("\n\nAction prompt is \n ", prompt)
#print("\n\nAction prompt is \n ", prompt)
action_results = [generate_action_result(prompt, phrase, local=RUN_LOCAL) for phrase in phrases]
response = json.dumps(action_results)
cache_file(seed, prompt_num, choices, response, "choices")
else:
print("Getting response for seed ", seed, " prompt_num ", prompt_num)
#print("Getting response for seed ", seed, " prompt_num ", prompt_num)
result = retrieve_from_cache(seed, prompt_num, [], "story")
if result is not None:
@@ -225,68 +213,10 @@ def story_request():
response = generate_story_block(prompt, local=RUN_LOCAL)
cache_file(seed, prompt_num, [], response, "story")
print("\nGenerated response is: \n", response)
print("")
#print("\nGenerated response is: \n", response)
#print("")
return response
def generate_cache():
start_seed = int(sys.argv[1])
end_seed = int(sys.argv[2])
# Generate story sections
prompt_num = 0
action_queue = []
prompt = prompts[prompt_num]
for seed in range(start_seed,end_seed):
result = retrieve_from_cache(seed, prompt_num, [], "story")
if result is not None:
response = result
else:
prompt = prompts[prompt_num]
#print("\n Story prompt is ", prompt)
response = generate_story_block(prompt)
#print("\n Story response is ", response)
cache_file(seed, prompt_num, [], response, "story")
action_queue.append([seed,0,[],response])
while(True):
next_gen = action_queue.pop(0)
seed = next_gen[0]
prompt_num = next_gen[1]
choices = next_gen[2]
last_action_result = next_gen[3]
action_results = retrieve_from_cache(seed, prompt_num, choices, "choices")
if action_results is not None:
response = action_results
else:
if len(choices) is 0:
prompt = prompts[prompt_num] + last_action_result
else:
prompt = continuing_prompts[prompt_num] + last_action_result
#print("\n\n Action prompt is \n ", prompt)
action_results = [generate_action_result(prompt, phrase) for phrase in phrases]
response = json.dumps(action_results)
#print("\n\n Action
cache_file(seed, prompt_num, choices, response, "choices")
un_jsoned = json.loads(response)
for j in range(4):
new_choices = choices[:]
new_choices.append(j)
action_queue.append([seed, 0, new_choices, un_jsoned[j][1]])
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
# [START gae_python37_render_template]
app.run(host='0.0.0.0', port=8080)
View File
+51
View File
@@ -0,0 +1,51 @@
def generate_cache():
start_seed = int(sys.argv[1])
end_seed = int(sys.argv[2])
# Generate story sections
prompt_num = 0
action_queue = []
prompt = prompts[prompt_num]
for seed in range(start_seed, end_seed):
result = retrieve_from_cache(seed, prompt_num, [], "story")
if result is not None:
response = result
else:
prompt = prompts[prompt_num]
# print("\n Story prompt is ", prompt)
response = generate_story_block(prompt)
# print("\n Story response is ", response)
cache_file(seed, prompt_num, [], response, "story")
action_queue.append([seed, 0, [], response])
while (True):
next_gen = action_queue.pop(0)
seed = next_gen[0]
prompt_num = next_gen[1]
choices = next_gen[2]
last_action_result = next_gen[3]
action_results = retrieve_from_cache(seed, prompt_num, choices, "choices")
if action_results is not None:
response = action_results
else:
if len(choices) is 0:
prompt = prompts[prompt_num] + last_action_result
else:
prompt = continuing_prompts[prompt_num] + last_action_result
# print("\n\n Action prompt is \n ", prompt)
action_results = [generate_action_result(prompt, phrase) for phrase in phrases]
response = json.dumps(action_results)
# print("\n\n Action
cache_file(seed, prompt_num, choices, response, "choices")
un_jsoned = json.loads(response)
for j in range(4):
new_choices = choices[:]
new_choices.append(j)
action_queue.append([seed, 0, new_choices, un_jsoned[j][1]])
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

+2 -1
View File
@@ -13,7 +13,8 @@
ga('send', 'pageview');
</script>
<!-- End Google Analytics -->
<title>Dungeon</title>
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
<title>AI Dungeon</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
var seed = {{ data.seed }}