mirror of
https://github.com/wassname/Clover-Edition.git
synced 2026-09-10 11:40:48 +08:00
refactoring significantly
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -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
@@ -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.
@@ -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)
|
||||
@@ -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 |
@@ -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 }}
|
||||
|
||||
Reference in New Issue
Block a user