got cached version working

This commit is contained in:
Nick
2019-09-16 19:47:34 -06:00
parent 7084696850
commit ef3a8ca864
20 changed files with 395 additions and 160 deletions
+27 -5
View File
@@ -7,6 +7,9 @@ from generator.web.web_generator import *
import tensorflow as tf
import textwrap
CRED_FILE = "./AI-Adventure-2bb65e3a4e2f.json"
prompt = "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"
# Set the key
def console_print(str):
@@ -15,8 +18,7 @@ def console_print(str):
def play_unconstrained():
generator = WebGenerator("./AI-Adventure-2bb65e3a4e2f.json")
prompt = "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"
generator = WebGenerator(CRED_FILE)
story_manager = UnconstrainedStoryManager(generator, prompt)
console_print(str(story_manager.story))
@@ -26,9 +28,9 @@ def play_unconstrained():
result = story_manager.act(action)
console_print(action + result)
def play_constrained():
generator = WebGenerator("./AI-Adventure-2bb65e3a4e2f.json")
prompt = "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"
generator = WebGenerator(CRED_FILE)
story_manager = ConstrainedStoryManager(generator, prompt)
console_print(str(story_manager.story))
@@ -47,8 +49,28 @@ def play_constrained():
console_print(result)
def play_cached():
generator = WebGenerator(CRED_FILE)
story_manager = CachedStoryManager(generator, 0, 0, CRED_FILE)
console_print(str(story_manager.story))
possible_actions = story_manager.get_possible_actions()
while (True):
console_print("\nOptions:")
for i, action in enumerate(possible_actions):
console_print(str(i) + ") " + action)
result = None
while(result == None):
action_choice = input("Which action do you choose? ")
print("\n")
result, possible_actions = story_manager.act(action_choice)
console_print(result)
if __name__ == '__main__':
play_constrained()
play_cached()
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+13 -88
View File
@@ -6,19 +6,25 @@ import json
from flask import Flask, render_template, request, abort
from story.story_manager import *
from generator.web.web_generator import *
from other.caching import *
from other.cacher import *
app = Flask(__name__)
app.secret_key = '#d\xe0\xd1\xfb\xee\xa4\xbb\xd0\xf0/e)\xb5g\xdd<`\xc7\xa5\xb0-\xb8d0S'
GOOGLE_CRED_LOCATION = "./AI-Adventure-2bb65e3a4e2f.json"
# Initializes everything for a session
def story_init(session, seed):
pass
# Routes to index
@app.route('/')
def root():
seed = -1
data = {'seed': seed}
return render_template('index.html', data=data)
# Starts an adventure with a specific seed
@app.route('/<seed>')
def rootseed(seed):
if seed == "":
@@ -29,104 +35,23 @@ def rootseed(seed):
session["seed"] = seed
return render_template('index.html', data=data)
# Starts an adventure
@app.route('/index.html')
def index():
data = {'seed': -1}
return render_template('index.html', data=data)
# Shows about. (Should also link to paper when published)
@app.route('/about.html')
def about():
return render_template('about.html')
# generator = WebGenerator("./AI-Adventure-2bb65e3a4e2f.json")
# prompt = "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"
# story_manager = ConstrainedStoryManager(generator, prompt)
#
# console_print(str(story_manager.story))
# possible_actions = story_manager.get_possible_actions()
# while (True):
# console_print("\nOptions:")
# for i, action in enumerate(possible_actions):
# console_print(str(i) + ") " + action)
#
# result = None
# while(result == None):
# action_choice = input("Which action do you choose? ")
# print("\n")
# result, possible_actions = story_manager.act(action_choice)
#
# console_print(result)
def story_init(session, seed):
session["seed"] = seed
prompt_num = 0
session["prompt_num"] = prompt_num
session["generator"] = WebGenerator(GOOGLE_CRED_LOCATION)
first_story = retrieve_from_cache(seed, prompt_num, [], "story")
if prompt is None:
prompt = prompts[prompt_num]
response = generate_story_block(prompt, local=RUN_LOCAL)
cache_file(seed, prompt_num, [], response, "story")
session["story_manager"] = ConstrainedStoryManager(session["generator"], prompt)
session["initialized"] = True
@app.route('/generate', methods=['POST'])
# Bread and butter of app, updates story and returns based on choice
@app.route('/choose', methods=['POST'])
def story_request():
print("****Generating Story****")
seed = request.form["seed"]
prompt_num = int(request.form["prompt_num"])
gen_actions = request.form["actions"]
pass
if "initialized" not in session:
story_init(session, seed, prompt_num)
print("Session Seed is ", session["seed"])
if int(seed) < 0 or int(seed) > 100:
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)
action_results = retrieve_from_cache(seed, prompt_num, choices, "choices")
if action_results is not None:
response = action_results
else:
last_action_result = request.form["last_action_result"]
prompt = continuing_prompts[prompt_num] + last_action_result
#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:
result = retrieve_from_cache(seed, prompt_num, [], "story")
if result is not None:
response = result
else:
prompt = prompts[prompt_num]
response = generate_story_block(prompt, local=RUN_LOCAL)
cache_file(seed, prompt_num, [], response, "story")
return response
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
+264
View File
@@ -0,0 +1,264 @@
# 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
import os
import googleapiclient.discovery
from utils import *
from google.cloud import storage
from google import cloud
import json
from flask import Flask, render_template, request, abort
from flask import Response
import requests
import pdb
import sys
import gpt2.src.encoder as encoder
# App Info
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__)
# Encoder Info
encoder_path = 'gpt2/models/117M'
enc = encoder.get_encoder(encoder_path)
# Model/Cache Info
project = "ai-adventure"
model = "generator_v1"
version = "version2"
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = "./AI-Adventure-2bb65e3a4e2f.json"
storage_client = storage.Client()
bucket = storage_client.get_bucket("dungeon-cache")
def predict(context_tokens):
service = googleapiclient.discovery.build('ml', 'v1')
name = 'projects/{}/models/{}'.format(project, model)
instance = context_tokens
if version is not None:
name += '/versions/{}'.format(version)
response = service.projects().predict(
name=name,
body={'instances': [{'context': instance}]}
).execute()
if 'error' in response:
raise RuntimeError(response['error'])
return response['predictions']
def generate(prompt):
while (True):
context_tokens = enc.encode(prompt)
try:
pred = predict(context_tokens)
pred = pred[0]["output"][len(context_tokens):]
output = enc.decode(pred)
return output
except:
print("generate request failed, trying again")
continue
def generate_story_block(prompt):
block = generate(prompt)
block = cut_trailing_sentence(block)
block = story_replace(block)
return block
def generate_action_result(prompt, phrase):
action = phrase + generate(prompt + phrase)
action_result = cut_trailing_sentence(action)
action_result = story_replace(action_result)
action = first_sentence(action)
return action, action_result
@app.route('/')
def root():
seed = -1
data = {'seed': seed}
return render_template('index.html', data=data)
@app.route('/<seed>')
def rootseed(seed):
if seed == "":
seed = -1
else:
seed = int(seed)
data = {'seed': seed}
return render_template('index.html', data=data)
@app.route('/index.html')
def index():
data = {'seed': -1}
return render_template('index.html', data=data)
@app.route('/about.html')
def about():
return render_template('about.html')
def cache_file(seed, prompt_num, choices, response, tag):
blob_file_name = "prompt" + str(prompt_num) + "/seed" + str(seed) + "/" + tag
for action in choices:
blob_file_name = blob_file_name + str(action)
blob = bucket.blob(blob_file_name)
blob.upload_from_string(response)
print("File ", blob_file_name, " cached")
def retrieve_from_cache(seed, prompt_num, choices, tag):
blob_file_name = "prompt" + str(prompt_num) + "/seed" + str(seed) + "/" + tag
for action in choices:
blob_file_name = blob_file_name + str(action)
blob = bucket.blob(blob_file_name)
if blob.exists(storage_client):
result = blob.download_as_string().decode("utf-8")
print(blob_file_name, " found in cache")
else:
result = None
print(blob_file_name, " not found in cache")
return result
@app.route('/generate', methods=['POST'])
def story_request():
print("****Generating Story****")
seed = request.form["seed"]
prompt_num = int(request.form["prompt_num"])
gen_actions = request.form["actions"]
if int(seed) < 0 or int(seed) > 100:
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)
action_results = retrieve_from_cache(seed, prompt_num, choices, "choices")
if action_results is not None:
response = action_results
else:
last_action_result = request.form["last_action_result"]
prompt = continuing_prompts[prompt_num] + last_action_result
print("\n\nAction prompt is \n ", prompt)
action_results = [generate_action_result(prompt, phrase) 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)
result = retrieve_from_cache(seed, prompt_num, [], "story")
if result is not None:
response = result
else:
prompt = prompts[prompt_num]
response = generate_story_block(prompt)
cache_file(seed, prompt_num, [], response, "story")
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__':
if (len(sys.argv) > 1):
generate_cache()
else:
app.run(host='0.0.0.0', port=8080)
# [START gae_python37_render_template]
+34 -25
View File
@@ -1,35 +1,44 @@
from google.cloud import storage
# Model/Cache Info
storage_client = storage.Client()
bucket = storage_client.get_bucket("dungeon-cache")
import os
def cache_file(seed, prompt_num, choices, response, tag):
class cacher():
blob_file_name = "prompt" + str(prompt_num) + "/seed" + str(seed) + "/" + tag
for action in choices:
blob_file_name = blob_file_name + str(action)
blob = bucket.blob(blob_file_name)
def __init__(self, credentials_file):
# Model/Cache Info
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = credentials_file
self.storage_client = storage.Client()
self.bucket = self.storage_client.get_bucket("dungeon-cache")
pass
blob.upload_from_string(response)
def cache_file(self, seed, prompt_num, choices, response, tag, print_result=False):
print("File ", blob_file_name, " cached")
blob_file_name = "prompt" + str(prompt_num) + "/seed" + str(seed) + "/" + tag
for action in choices:
blob_file_name = blob_file_name + str(action)
blob = self.bucket.blob(blob_file_name)
blob.upload_from_string(response)
if print_result: print("File ", blob_file_name, " cached")
def retrieve_from_cache(self, seed, prompt_num, choices, tag, print_result=False):
blob_file_name = "prompt" + str(prompt_num) + "/seed" + str(seed) + "/" + tag
for action in choices:
blob_file_name = blob_file_name + str(action)
blob = self.bucket.blob(blob_file_name)
if blob.exists(self.storage_client):
result = blob.download_as_string().decode("utf-8")
if print_result: print(blob_file_name, " found in cache")
else:
result = None
if print_result: print(blob_file_name, " not found in cache")
return result
def retrieve_from_cache(seed, prompt_num, choices, tag):
blob_file_name = "prompt" + str(prompt_num) + "/seed" + str(seed) + "/" + tag
for action in choices:
blob_file_name = blob_file_name + str(action)
blob = bucket.blob(blob_file_name)
if blob.exists(storage_client):
result = blob.download_as_string().decode("utf-8")
print(blob_file_name, " found in cache")
else:
result = None
print(blob_file_name, " not found in cache")
return result
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+57 -42
View File
@@ -1,5 +1,9 @@
from story.utils import *
from other.cacher import *
import json
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"]
class Story():
@@ -32,27 +36,36 @@ class Story():
return "".join(story_list)
class UnconstrainedStoryManager():
class StoryManager():
def __init__(self, generator, story_prompt):
self.generator = generator
self.story_prompt = story_prompt
self.action_phrases = ["You attack", "You tell", "You use", "You go"]
block = self.generator.generate(story_prompt)
def init_story(self):
block = self.generator.generate(self.story_prompt)
block = cut_trailing_sentence(block)
block = story_replace(block)
story_start = story_prompt + block
story_start = self.story_prompt + block
self.story = Story(story_start)
def act(self, action_choice):
result = self.generate_result(action_choice)
self.story.add_to_story(action_choice, result)
return result
return story_start
def story_context(self):
return self.story.latest_result()
class UnconstrainedStoryManager(StoryManager):
def __init__(self, generator, story_prompt):
super().__init__(generator, story_prompt)
self.init_story()
def act(self, action_choice):
result = self.generate_result(action_choice)
self.story.add_to_story(action_choice, result)
return result
def generate_result(self, action):
block = self.generator.generate(self.story_context() + action)
block = cut_trailing_sentence(block)
@@ -60,16 +73,12 @@ class UnconstrainedStoryManager():
return block
class ConstrainedStoryManager():
class ConstrainedStoryManager(StoryManager):
def __init__(self, generator, story_prompt):
self.generator = generator
self.action_phrases = ["You attack", "You tell", "You use", "You go"]
block = self.generator.generate(story_prompt)
block = cut_trailing_sentence(block)
block = story_replace(block)
story_start = story_prompt + block
self.story = Story(story_start)
super().__init__(generator, story_prompt)
self.init_story()
self.possible_action_results = None
def get_possible_actions(self):
@@ -95,9 +104,6 @@ class ConstrainedStoryManager():
self.possible_action_results = self.get_action_results()
return result, self.get_possible_actions()
def story_context(self):
return self.story.latest_result()
def get_action_results(self):
return [self.generate_action_result(self.story_context(), phrase) for phrase in self.action_phrases]
@@ -112,17 +118,26 @@ class ConstrainedStoryManager():
return action, result
class CachedStoryManager():
class CachedStoryManager(ConstrainedStoryManager):
def __init__(self, generator, prompt_num, seed):
# self.generator = generator
# self.action_phrases = ["You attack", "You tell", "You use", "You go"]
# block = self.generator.generate(story_prompt)
# block = cut_trailing_sentence(block)
# block = story_replace(block)
# story_start = story_prompt + block
# self.story = Story(story_start)
# self.possible_action_results = None
def __init__(self, generator, prompt_num, seed, credentials_file):
self.cacher = cacher(credentials_file)
prompt = prompts[prompt_num]
super().__init__(generator, prompt)
self.seed = seed
self.prompt_num = prompt_num
self.choices = []
result = self.cacher.retrieve_from_cache(seed, prompt_num, [], "story")
if result is not None:
story_start = result
self.story = Story(story_start)
else:
story_start = self.init_story()
self.cacher.cache_file(seed, prompt_num, [], story_start, "story")
self.possible_action_results = None
def get_possible_actions(self):
if self.possible_action_results is None:
@@ -142,23 +157,23 @@ class CachedStoryManager():
print("Error invalid choice.")
return None, None
self.choices.append(action_choice)
action, result = self.possible_action_results[action_choice]
self.story.add_to_story(action, result)
self.possible_action_results = self.get_action_results()
return result, self.get_possible_actions()
def story_context(self):
return self.story.latest_result()
def get_action_results(self):
return [self.generate_action_result(self.story_context(), phrase) for phrase in self.action_phrases]
def generate_action_result(self, prompt, phrase):
action = phrase + self.generator.generate(prompt + phrase)
action_result = cut_trailing_sentence(action)
response = self.cacher.retrieve_from_cache(self.seed, self.prompt_num, self.choices, "choices")
if response is not None:
action_results = json.loads(response)
else:
action_results = super().get_action_results()
response = json.dumps(action_results)
self.cacher.cache_file(self.seed, self.prompt_num, self.choices, response, "choices")
return action_results
action, result = split_first_sentence(action_result)
result = story_replace(action_result)
action = action_replace(action)
return action, result