Spaces:
Runtime error
Runtime error
zxsipola123456
commited on
Upload 33 files
Browse files- .gitignore +160 -0
- LICENSE +21 -0
- app.py +391 -0
- common/__init__.py +19 -0
- global_config.py +20 -0
- human_simulator.py +137 -0
- imgs/webui-snapshot.png +0 -0
- init_prompt.json +1 -0
- misc/ali_pay.png +0 -0
- misc/placeholder +1 -0
- misc/wechat_pay.png +0 -0
- models/__init__.py +4 -0
- models/aquila_fa.py +38 -0
- models/aquila_hf.py +20 -0
- models/baichuan_hf.py +50 -0
- models/chatglm_hf.py +76 -0
- models/falcon_hf.py +70 -0
- models/vicuna_bin.py +32 -0
- prompts/__init__.py +4 -0
- prompts/chatgpt_query.py +134 -0
- prompts/human_simulator.py +120 -0
- prompts/llm_query.py +135 -0
- prompts/service_init.py +79 -0
- recurrent_llm.py +121 -0
- recurrentgpt.py +104 -0
- requirements.txt +19 -0
- utils/__init__.py +181 -0
- utils/aquila_util.py +84 -0
- utils/baichuan_util.py +53 -0
- utils/chatglm_util.py +42 -0
- utils/falcon_util.py +46 -0
- utils/openai_util.py +38 -0
- utils/vicuna_util.py +59 -0
.gitignore
ADDED
@@ -0,0 +1,160 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Byte-compiled / optimized / DLL files
|
2 |
+
__pycache__/
|
3 |
+
*.py[cod]
|
4 |
+
*$py.class
|
5 |
+
|
6 |
+
# C extensions
|
7 |
+
*.so
|
8 |
+
|
9 |
+
# Distribution / packaging
|
10 |
+
.Python
|
11 |
+
build/
|
12 |
+
develop-eggs/
|
13 |
+
dist/
|
14 |
+
downloads/
|
15 |
+
eggs/
|
16 |
+
.eggs/
|
17 |
+
lib/
|
18 |
+
lib64/
|
19 |
+
parts/
|
20 |
+
sdist/
|
21 |
+
var/
|
22 |
+
wheels/
|
23 |
+
share/python-wheels/
|
24 |
+
*.egg-info/
|
25 |
+
.installed.cfg
|
26 |
+
*.egg
|
27 |
+
MANIFEST
|
28 |
+
|
29 |
+
# PyInstaller
|
30 |
+
# Usually these files are written by a python script from a template
|
31 |
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
32 |
+
*.manifest
|
33 |
+
*.spec
|
34 |
+
|
35 |
+
# Installer logs
|
36 |
+
pip-log.txt
|
37 |
+
pip-delete-this-directory.txt
|
38 |
+
|
39 |
+
# Unit test / coverage reports
|
40 |
+
htmlcov/
|
41 |
+
.tox/
|
42 |
+
.nox/
|
43 |
+
.coverage
|
44 |
+
.coverage.*
|
45 |
+
.cache
|
46 |
+
nosetests.xml
|
47 |
+
coverage.xml
|
48 |
+
*.cover
|
49 |
+
*.py,cover
|
50 |
+
.hypothesis/
|
51 |
+
.pytest_cache/
|
52 |
+
cover/
|
53 |
+
|
54 |
+
# Translations
|
55 |
+
*.mo
|
56 |
+
*.pot
|
57 |
+
|
58 |
+
# Django stuff:
|
59 |
+
*.log
|
60 |
+
local_settings.py
|
61 |
+
db.sqlite3
|
62 |
+
db.sqlite3-journal
|
63 |
+
|
64 |
+
# Flask stuff:
|
65 |
+
instance/
|
66 |
+
.webassets-cache
|
67 |
+
|
68 |
+
# Scrapy stuff:
|
69 |
+
.scrapy
|
70 |
+
|
71 |
+
# Sphinx documentation
|
72 |
+
docs/_build/
|
73 |
+
|
74 |
+
# PyBuilder
|
75 |
+
.pybuilder/
|
76 |
+
target/
|
77 |
+
|
78 |
+
# Jupyter Notebook
|
79 |
+
.ipynb_checkpoints
|
80 |
+
|
81 |
+
# IPython
|
82 |
+
profile_default/
|
83 |
+
ipython_config.py
|
84 |
+
|
85 |
+
# pyenv
|
86 |
+
# For a library or package, you might want to ignore these files since the code is
|
87 |
+
# intended to run in multiple environments; otherwise, check them in:
|
88 |
+
# .python-version
|
89 |
+
|
90 |
+
# pipenv
|
91 |
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
92 |
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
93 |
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
94 |
+
# install all needed dependencies.
|
95 |
+
#Pipfile.lock
|
96 |
+
|
97 |
+
# poetry
|
98 |
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
99 |
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
100 |
+
# commonly ignored for libraries.
|
101 |
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
102 |
+
#poetry.lock
|
103 |
+
|
104 |
+
# pdm
|
105 |
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
106 |
+
#pdm.lock
|
107 |
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
108 |
+
# in version control.
|
109 |
+
# https://pdm.fming.dev/#use-with-ide
|
110 |
+
.pdm.toml
|
111 |
+
|
112 |
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
113 |
+
__pypackages__/
|
114 |
+
|
115 |
+
# Celery stuff
|
116 |
+
celerybeat-schedule
|
117 |
+
celerybeat.pid
|
118 |
+
|
119 |
+
# SageMath parsed files
|
120 |
+
*.sage.py
|
121 |
+
|
122 |
+
# Environments
|
123 |
+
.env
|
124 |
+
.venv
|
125 |
+
env/
|
126 |
+
venv/
|
127 |
+
ENV/
|
128 |
+
env.bak/
|
129 |
+
venv.bak/
|
130 |
+
|
131 |
+
# Spyder project settings
|
132 |
+
.spyderproject
|
133 |
+
.spyproject
|
134 |
+
|
135 |
+
# Rope project settings
|
136 |
+
.ropeproject
|
137 |
+
|
138 |
+
# mkdocs documentation
|
139 |
+
/site
|
140 |
+
|
141 |
+
# mypy
|
142 |
+
.mypy_cache/
|
143 |
+
.dmypy.json
|
144 |
+
dmypy.json
|
145 |
+
|
146 |
+
# Pyre type checker
|
147 |
+
.pyre/
|
148 |
+
|
149 |
+
# pytype static type analyzer
|
150 |
+
.pytype/
|
151 |
+
|
152 |
+
# Cython debug symbols
|
153 |
+
cython_debug/
|
154 |
+
|
155 |
+
# PyCharm
|
156 |
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
157 |
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
158 |
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
159 |
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
160 |
+
#.idea/
|
LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
MIT License
|
2 |
+
|
3 |
+
Copyright (c) 2023 MK
|
4 |
+
|
5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6 |
+
of this software and associated documentation files (the "Software"), to deal
|
7 |
+
in the Software without restriction, including without limitation the rights
|
8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9 |
+
copies of the Software, and to permit persons to whom the Software is
|
10 |
+
furnished to do so, subject to the following conditions:
|
11 |
+
|
12 |
+
The above copyright notice and this permission notice shall be included in all
|
13 |
+
copies or substantial portions of the Software.
|
14 |
+
|
15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21 |
+
SOFTWARE.
|
app.py
ADDED
@@ -0,0 +1,391 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
import gradio as gr
|
6 |
+
import random
|
7 |
+
from sentence_transformers import SentenceTransformer
|
8 |
+
from human_simulator import Human
|
9 |
+
from prompts.service_init import get_init_prompt
|
10 |
+
from utils import get_init, parse_instructions
|
11 |
+
from global_config import lang_opt, llm_model_opt
|
12 |
+
|
13 |
+
if "openai" == llm_model_opt:
|
14 |
+
from recurrentgpt import RecurrentGPT as AIWriter
|
15 |
+
llm_model = None
|
16 |
+
llm_tokenizer = None
|
17 |
+
|
18 |
+
elif "vicuna" == llm_model_opt:
|
19 |
+
from recurrent_llm import RecurrentLLM as AIWriter
|
20 |
+
from models.vicuna_bin import load_model
|
21 |
+
llm_tokenizer, llm_model = load_model()
|
22 |
+
|
23 |
+
elif "chatglm" == llm_model_opt:
|
24 |
+
from recurrent_llm import RecurrentLLM as AIWriter
|
25 |
+
from models.chatglm_hf import load_model
|
26 |
+
llm_tokenizer, llm_model = load_model()
|
27 |
+
|
28 |
+
elif "baichuan" == llm_model_opt:
|
29 |
+
from recurrent_llm import RecurrentLLM as AIWriter
|
30 |
+
from models.baichuan_hf import load_model
|
31 |
+
llm_tokenizer, llm_model = load_model()
|
32 |
+
|
33 |
+
elif "aquila" == llm_model_opt:
|
34 |
+
from recurrent_llm import RecurrentLLM as AIWriter
|
35 |
+
from models.aquila_fa import load_model
|
36 |
+
# from models.aquila_hf import load_model
|
37 |
+
llm_tokenizer, llm_model = load_model()
|
38 |
+
|
39 |
+
elif "falcon" == llm_model_opt:
|
40 |
+
from recurrent_llm import RecurrentLLM
|
41 |
+
from models.falcon_hf import load_model
|
42 |
+
llm_tokenizer, llm_model = load_model()
|
43 |
+
|
44 |
+
else:
|
45 |
+
raise Exception("not supported llm model name: {}".format(llm_model_opt))
|
46 |
+
|
47 |
+
# from urllib.parse import quote_plus
|
48 |
+
# from pymongo import MongoClient
|
49 |
+
|
50 |
+
# uri = "mongodb://%s:%s@%s" % (quote_plus("xxx"),
|
51 |
+
# quote_plus("xxx"), "localhost")
|
52 |
+
# client = MongoClient(uri, maxPoolSize=None)
|
53 |
+
# db = client.recurrentGPT_db
|
54 |
+
# log = db.log
|
55 |
+
|
56 |
+
_CACHE = {}
|
57 |
+
|
58 |
+
|
59 |
+
# Build the semantic search model
|
60 |
+
embedder = SentenceTransformer('multi-qa-mpnet-base-cos-v1')
|
61 |
+
|
62 |
+
|
63 |
+
def init_prompt(novel_type, description):
|
64 |
+
if description == "":
|
65 |
+
description = ""
|
66 |
+
else:
|
67 |
+
description = " about " + description
|
68 |
+
|
69 |
+
return get_init_prompt(lang_opt, novel_type, description)
|
70 |
+
|
71 |
+
|
72 |
+
def init(novel_type, description, request: gr.Request):
|
73 |
+
if novel_type == "":
|
74 |
+
novel_type = "Science Fiction" if "en" == lang_opt else "科幻故事"
|
75 |
+
global _CACHE
|
76 |
+
cookie = request.headers['cookie']
|
77 |
+
cookie = cookie.split('; _gat_gtag')[0]
|
78 |
+
# prepare first init
|
79 |
+
init_paragraphs = get_init(text=init_prompt(
|
80 |
+
novel_type, description), model=llm_model, tokenizer=llm_tokenizer)
|
81 |
+
# print(init_paragraphs)
|
82 |
+
start_input_to_human = {
|
83 |
+
'output_paragraph': init_paragraphs['Paragraph 3'],
|
84 |
+
'input_paragraph': '\n\n'.join([init_paragraphs['Paragraph 1'], init_paragraphs['Paragraph 2'], init_paragraphs['Paragraph 3']]),
|
85 |
+
'output_memory': init_paragraphs['Summary'],
|
86 |
+
"output_instruction": [init_paragraphs['Instruction 1'], init_paragraphs['Instruction 2'], init_paragraphs['Instruction 3']]
|
87 |
+
}
|
88 |
+
|
89 |
+
_CACHE[cookie] = {"start_input_to_human": start_input_to_human,
|
90 |
+
"init_paragraphs": init_paragraphs}
|
91 |
+
written_paras = f"""Title: {init_paragraphs['name']}
|
92 |
+
|
93 |
+
Outline: {init_paragraphs['Outline']}
|
94 |
+
|
95 |
+
Paragraphs:
|
96 |
+
|
97 |
+
{start_input_to_human['input_paragraph']}""" if "en" == lang_opt else f"""标题: {init_paragraphs['name']}
|
98 |
+
|
99 |
+
梗概: {init_paragraphs['Outline']}
|
100 |
+
|
101 |
+
段落:
|
102 |
+
|
103 |
+
{start_input_to_human['input_paragraph']}"""
|
104 |
+
long_memory = parse_instructions(
|
105 |
+
[init_paragraphs['Paragraph 1'], init_paragraphs['Paragraph 2'], init_paragraphs['Paragraph 3']])
|
106 |
+
# short memory, long memory, current written paragraphs, 3 next instructions
|
107 |
+
return start_input_to_human['output_memory'], long_memory, written_paras, init_paragraphs['Instruction 1'], init_paragraphs['Instruction 2'], init_paragraphs['Instruction 3']
|
108 |
+
|
109 |
+
|
110 |
+
def step(short_memory, long_memory, instruction1, instruction2, instruction3, current_paras, request: gr.Request, ):
|
111 |
+
if current_paras == "":
|
112 |
+
return "", "", "", "", "", ""
|
113 |
+
global _CACHE
|
114 |
+
# print(list(_CACHE.keys()))
|
115 |
+
# print(request.headers.get('cookie'))
|
116 |
+
cookie = request.headers['cookie']
|
117 |
+
cookie = cookie.split('; _gat_gtag')[0]
|
118 |
+
cache = _CACHE[cookie]
|
119 |
+
|
120 |
+
if "writer" not in cache:
|
121 |
+
start_input_to_human = cache["start_input_to_human"]
|
122 |
+
start_input_to_human['output_instruction'] = [
|
123 |
+
instruction1, instruction2, instruction3]
|
124 |
+
init_paragraphs = cache["init_paragraphs"]
|
125 |
+
human = Human(input=start_input_to_human,
|
126 |
+
memory=None, embedder=embedder, model=llm_model, tokenizer=llm_tokenizer)
|
127 |
+
human.step()
|
128 |
+
start_short_memory = init_paragraphs['Summary']
|
129 |
+
writer_start_input = human.output
|
130 |
+
|
131 |
+
# Init writerGPT
|
132 |
+
writer = AIWriter(input=writer_start_input, short_memory=start_short_memory, long_memory=[
|
133 |
+
init_paragraphs['Paragraph 1'], init_paragraphs['Paragraph 2'], init_paragraphs['Paragraph 3']], memory_index=None, embedder=embedder,
|
134 |
+
model=llm_model, tokenizer=llm_tokenizer)
|
135 |
+
cache["writer"] = writer
|
136 |
+
cache["human"] = human
|
137 |
+
writer.step()
|
138 |
+
else:
|
139 |
+
human = cache["human"]
|
140 |
+
writer = cache["writer"]
|
141 |
+
output = writer.output
|
142 |
+
output['output_memory'] = short_memory
|
143 |
+
# randomly select one instruction out of three
|
144 |
+
instruction_index = random.randint(0, 2)
|
145 |
+
output['output_instruction'] = [instruction1,
|
146 |
+
instruction2, instruction3][instruction_index]
|
147 |
+
human.input = output
|
148 |
+
human.step()
|
149 |
+
writer.input = human.output
|
150 |
+
writer.step()
|
151 |
+
|
152 |
+
long_memory = [[v] for v in writer.long_memory]
|
153 |
+
# short memory, long memory, current written paragraphs, 3 next instructions
|
154 |
+
return writer.output['output_memory'], long_memory, current_paras + '\n\n' + writer.output['input_paragraph'], human.output['output_instruction'], *writer.output['output_instruction']
|
155 |
+
|
156 |
+
|
157 |
+
def controled_step(short_memory, long_memory, selected_instruction, current_paras, request: gr.Request, ):
|
158 |
+
if current_paras == "":
|
159 |
+
return "", "", "", "", "", ""
|
160 |
+
global _CACHE
|
161 |
+
# print(list(_CACHE.keys()))
|
162 |
+
# print(request.headers.get('cookie'))
|
163 |
+
cookie = request.headers['cookie']
|
164 |
+
cookie = cookie.split('; _gat_gtag')[0]
|
165 |
+
cache = _CACHE[cookie]
|
166 |
+
if "writer" not in cache:
|
167 |
+
start_input_to_human = cache["start_input_to_human"]
|
168 |
+
start_input_to_human['output_instruction'] = selected_instruction
|
169 |
+
init_paragraphs = cache["init_paragraphs"]
|
170 |
+
human = Human(input=start_input_to_human,
|
171 |
+
memory=None, embedder=embedder, model=llm_model, tokenizer=llm_tokenizer)
|
172 |
+
human.step()
|
173 |
+
start_short_memory = init_paragraphs['Summary']
|
174 |
+
writer_start_input = human.output
|
175 |
+
|
176 |
+
# Init writerGPT
|
177 |
+
writer = AIWriter(input=writer_start_input, short_memory=start_short_memory, long_memory=[
|
178 |
+
init_paragraphs['Paragraph 1'], init_paragraphs['Paragraph 2'], init_paragraphs['Paragraph 3']], memory_index=None, embedder=embedder,
|
179 |
+
model=llm_model, tokenizer=llm_tokenizer)
|
180 |
+
cache["writer"] = writer
|
181 |
+
cache["human"] = human
|
182 |
+
writer.step()
|
183 |
+
else:
|
184 |
+
human = cache["human"]
|
185 |
+
writer = cache["writer"]
|
186 |
+
output = writer.output
|
187 |
+
output['output_memory'] = short_memory
|
188 |
+
output['output_instruction'] = selected_instruction
|
189 |
+
human.input = output
|
190 |
+
human.step()
|
191 |
+
writer.input = human.output
|
192 |
+
writer.step()
|
193 |
+
|
194 |
+
# short memory, long memory, current written paragraphs, 3 next instructions
|
195 |
+
return writer.output['output_memory'], parse_instructions(writer.long_memory), current_paras + '\n\n' + writer.output['input_paragraph'], *writer.output['output_instruction']
|
196 |
+
|
197 |
+
|
198 |
+
# SelectData is a subclass of EventData
|
199 |
+
def on_select(instruction1, instruction2, instruction3, evt: gr.SelectData):
|
200 |
+
selected_plan = int(evt.value.replace("Instruction ", "")
|
201 |
+
) if "en" == lang_opt else int(evt.value.replace("指令 ", ""))
|
202 |
+
selected_plan = [instruction1, instruction2, instruction3][selected_plan-1]
|
203 |
+
return selected_plan
|
204 |
+
|
205 |
+
|
206 |
+
def reload_model(choice):
|
207 |
+
pass
|
208 |
+
|
209 |
+
|
210 |
+
with gr.Blocks(title="RecurrentGPT", css="footer {visibility: hidden}", theme="default") as demo:
|
211 |
+
if "en" == lang_opt:
|
212 |
+
gr.Markdown(
|
213 |
+
"""
|
214 |
+
# Recurrent-LLM
|
215 |
+
Interactive Generation of (Arbitrarily) Long Texts with Human-in-the-Loop
|
216 |
+
""")
|
217 |
+
elif lang_opt in ["zh1", "zh2"]:
|
218 |
+
gr.Markdown(
|
219 |
+
"""
|
220 |
+
# Recurrent-LLM
|
221 |
+
可以根据题目和简介自动续写文章
|
222 |
+
也可以手动选择剧情走向进行续写
|
223 |
+
""")
|
224 |
+
|
225 |
+
with gr.Tab("Auto-Generation"):
|
226 |
+
with gr.Row():
|
227 |
+
with gr.Column():
|
228 |
+
with gr.Box():
|
229 |
+
with gr.Row():
|
230 |
+
with gr.Column(scale=1, min_width=200):
|
231 |
+
novel_type = gr.Textbox(
|
232 |
+
label="Novel Type", placeholder="e.g. science fiction") if "en" == lang_opt else gr.Textbox(
|
233 |
+
label="请输入文本", placeholder="可以自己填写或者从EXamples中选择一个填入")
|
234 |
+
with gr.Column(scale=2, min_width=400):
|
235 |
+
description = gr.Textbox(
|
236 |
+
label="Description") if "en" == lang_opt else gr.Textbox(label="剧情简介(非必选项)")
|
237 |
+
btn_init = gr.Button(
|
238 |
+
"Init Novel Generation", variant="primary") if "en" == lang_opt else gr.Button(
|
239 |
+
"点击开始运行", variant="primary")
|
240 |
+
if "en" == lang_opt:
|
241 |
+
gr.Examples(["Science Fiction", "Romance", "Mystery", "Fantasy",
|
242 |
+
"Historical", "Horror", "Thriller", "Western", "Young Adult", ], inputs=[novel_type])
|
243 |
+
elif lang_opt in ["zh1", "zh2"]:
|
244 |
+
gr.Examples(["科幻故事", "青春伤痛文学", "爱到死去活来", "搞笑",
|
245 |
+
"幽默", "鬼故事", "喜剧", "童话", "魔法世界", ], inputs=[novel_type])
|
246 |
+
else:
|
247 |
+
raise Exception(f"not supported language: {lang_opt}")
|
248 |
+
|
249 |
+
written_paras = gr.Textbox(
|
250 |
+
label="Written Paragraphs (editable)", max_lines=21, lines=21) if "en" == lang_opt else gr.Textbox(
|
251 |
+
label="文章内容", max_lines=21, lines=21)
|
252 |
+
with gr.Column():
|
253 |
+
with gr.Box():
|
254 |
+
if "en" == lang_opt:
|
255 |
+
gr.Markdown("### Memory Module\n")
|
256 |
+
elif lang_opt in ["zh1", "zh2"]:
|
257 |
+
gr.Markdown("### 剧情模型\n")
|
258 |
+
|
259 |
+
short_memory = gr.Textbox(
|
260 |
+
label="Short-Term Memory (editable)", max_lines=3, lines=3) if "en" == lang_opt else gr.Textbox(
|
261 |
+
label="短期记忆 (可编辑)", max_lines=3, lines=3)
|
262 |
+
long_memory = gr.Textbox(
|
263 |
+
label="Long-Term Memory (editable)", max_lines=6, lines=6) if "en" == lang_opt else gr.Textbox(
|
264 |
+
label="长期记忆 (可编辑)", max_lines=6, lines=6)
|
265 |
+
# long_memory = gr.Dataframe(
|
266 |
+
# # label="Long-Term Memory (editable)",
|
267 |
+
# headers=["Long-Term Memory (editable)"],
|
268 |
+
# datatype=["str"],
|
269 |
+
# row_count=3,
|
270 |
+
# max_rows=3,
|
271 |
+
# col_count=(1, "fixed"),
|
272 |
+
# type="array",
|
273 |
+
# )
|
274 |
+
with gr.Box():
|
275 |
+
if "en" == lang_opt:
|
276 |
+
gr.Markdown("### Instruction Module\n")
|
277 |
+
elif lang_opt in ["zh1", "zh2"]:
|
278 |
+
gr.Markdown("### 选项模型\n")
|
279 |
+
|
280 |
+
with gr.Row():
|
281 |
+
instruction1 = gr.Textbox(
|
282 |
+
label="Instruction 1 (editable)", max_lines=4, lines=4) if "en" == lang_opt else gr.Textbox(
|
283 |
+
label="指令1(可编辑)", max_lines=4, lines=4)
|
284 |
+
instruction2 = gr.Textbox(
|
285 |
+
label="Instruction 2 (editable)", max_lines=4, lines=4) if "en" == lang_opt else gr.Textbox(
|
286 |
+
label="指令2(可编辑)", max_lines=4, lines=4)
|
287 |
+
instruction3 = gr.Textbox(
|
288 |
+
label="Instruction 3 (editable)", max_lines=4, lines=4) if "en" == lang_opt else gr.Textbox(
|
289 |
+
label="指令3(可编辑)", max_lines=4, lines=4)
|
290 |
+
selected_plan = gr.Textbox(
|
291 |
+
label="Revised Instruction (from last step)", max_lines=2, lines=2) if "en" == lang_opt else gr.Textbox(
|
292 |
+
label="选项说明 (来自上一步)", max_lines=2, lines=2)
|
293 |
+
|
294 |
+
btn_step = gr.Button("Next Step", variant="primary") if "en" == lang_opt else gr.Button(
|
295 |
+
"下一步", variant="primary")
|
296 |
+
|
297 |
+
btn_init.click(init, inputs=[novel_type, description], outputs=[
|
298 |
+
short_memory, long_memory, written_paras, instruction1, instruction2, instruction3])
|
299 |
+
btn_step.click(step, inputs=[short_memory, long_memory, instruction1, instruction2, instruction3, written_paras], outputs=[
|
300 |
+
short_memory, long_memory, written_paras, selected_plan, instruction1, instruction2, instruction3])
|
301 |
+
|
302 |
+
with gr.Tab("Human-in-the-Loop"):
|
303 |
+
with gr.Row():
|
304 |
+
with gr.Column():
|
305 |
+
with gr.Box():
|
306 |
+
with gr.Row():
|
307 |
+
with gr.Column(scale=1, min_width=200):
|
308 |
+
novel_type = gr.Textbox(
|
309 |
+
label="Novel Type", placeholder="e.g. science fiction") if "en" == lang_opt else gr.Textbox(
|
310 |
+
label="请输入文本", placeholder="可以自己填写或者从EXamples中选择一个填入")
|
311 |
+
with gr.Column(scale=2, min_width=400):
|
312 |
+
description = gr.Textbox(
|
313 |
+
label="Description") if "en" == lang_opt else gr.Textbox(label="剧情简介(非必选项)")
|
314 |
+
btn_init = gr.Button(
|
315 |
+
"Init Novel Generation", variant="primary") if "en" == lang_opt else gr.Button(
|
316 |
+
"点击开始运行", variant="primary")
|
317 |
+
|
318 |
+
if "en" == lang_opt:
|
319 |
+
gr.Examples(["Science Fiction", "Romance", "Mystery", "Fantasy",
|
320 |
+
"Historical", "Horror", "Thriller", "Western", "Young Adult", ], inputs=[novel_type])
|
321 |
+
elif lang_opt in ["zh1", "zh2"]:
|
322 |
+
gr.Examples(["科幻小说", "爱情小说", "推理小说", "奇幻小说",
|
323 |
+
"玄幻小说", "恐怖", "悬疑", "惊悚", "武侠小说", ], inputs=[novel_type])
|
324 |
+
|
325 |
+
written_paras = gr.Textbox(
|
326 |
+
label="Written Paragraphs (editable)", max_lines=23, lines=23) if "en" == lang_opt else gr.Textbox(
|
327 |
+
label="文章内容 (可编辑)", max_lines=23, lines=23)
|
328 |
+
with gr.Column():
|
329 |
+
with gr.Box():
|
330 |
+
if "en" == lang_opt:
|
331 |
+
gr.Markdown("### Memory Module\n")
|
332 |
+
elif lang_opt in ["zh1", "zh2"]:
|
333 |
+
gr.Markdown("### 剧情模型\n")
|
334 |
+
|
335 |
+
short_memory = gr.Textbox(
|
336 |
+
label="Short-Term Memory (editable)", max_lines=3, lines=3) if "en" == lang_opt else gr.Textbox(
|
337 |
+
label="短期记忆 (可编辑)", max_lines=3, lines=3)
|
338 |
+
long_memory = gr.Textbox(
|
339 |
+
label="Long-Term Memory (editable)", max_lines=6, lines=6) if "en" == lang_opt else gr.Textbox(
|
340 |
+
label="长期记忆 (可编辑)", max_lines=6, lines=6)
|
341 |
+
with gr.Box():
|
342 |
+
if "en" == lang_opt:
|
343 |
+
gr.Markdown("### Instruction Module\n")
|
344 |
+
elif lang_opt in ["zh1", "zh2"]:
|
345 |
+
gr.Markdown("### 选项模型\n")
|
346 |
+
|
347 |
+
with gr.Row():
|
348 |
+
instruction1 = gr.Textbox(
|
349 |
+
label="Instruction 1", max_lines=3, lines=3, interactive=False) if "en" == lang_opt else gr.Textbox(
|
350 |
+
label="指令1", max_lines=3, lines=3, interactive=False)
|
351 |
+
instruction2 = gr.Textbox(
|
352 |
+
label="Instruction 2", max_lines=3, lines=3, interactive=False) if "en" == lang_opt else gr.Textbox(
|
353 |
+
label="指令2", max_lines=3, lines=3, interactive=False)
|
354 |
+
instruction3 = gr.Textbox(
|
355 |
+
label="Instruction 3", max_lines=3, lines=3, interactive=False) if "en" == lang_opt else gr.Textbox(
|
356 |
+
label="指令3", max_lines=3, lines=3, interactive=False)
|
357 |
+
with gr.Row():
|
358 |
+
with gr.Column(scale=1, min_width=100):
|
359 |
+
selected_plan = gr.Radio(
|
360 |
+
["Instruction 1", "Instruction 2", "Instruction 3"], label="Instruction Selection",) if "en" == lang_opt else gr.Radio(["指令 1", "指令 2", "指令 3"], label="指令 选择",)
|
361 |
+
# info="Select the instruction you want to revise and use for the next step generation.")
|
362 |
+
with gr.Column(scale=3, min_width=300):
|
363 |
+
selected_instruction = gr.Textbox(
|
364 |
+
label="Selected Instruction (editable)", max_lines=5, lines=5) if "en" == lang_opt else gr.Textbox(
|
365 |
+
label="在上一步骤中被选择的 (可编辑)", max_lines=5, lines=5)
|
366 |
+
|
367 |
+
btn_step = gr.Button("Next Step", variant="primary") if "en" == lang_opt else gr.Button(
|
368 |
+
"下一步", variant="primary")
|
369 |
+
|
370 |
+
btn_init.click(init, inputs=[novel_type, description], outputs=[
|
371 |
+
short_memory, long_memory, written_paras, instruction1, instruction2, instruction3])
|
372 |
+
btn_step.click(controled_step, inputs=[short_memory, long_memory, selected_instruction, written_paras], outputs=[
|
373 |
+
short_memory, long_memory, written_paras, instruction1, instruction2, instruction3])
|
374 |
+
selected_plan.select(on_select, inputs=[
|
375 |
+
instruction1, instruction2, instruction3], outputs=[selected_instruction])
|
376 |
+
|
377 |
+
with gr.Tab("Model-Config"):
|
378 |
+
model_opt_radio = gr.Radio(["OpenAI", "ChatGLM-6B", "Vicuna-7B"], value="OpenAI", label="model",
|
379 |
+
info="select language you preferred. Default is English.",
|
380 |
+
interactive=True
|
381 |
+
)
|
382 |
+
|
383 |
+
reload_button = gr.Button("Reload/重新加载")
|
384 |
+
reload_button.click(reload_model, show_progress=True,
|
385 |
+
inputs=[model_opt_radio],
|
386 |
+
outputs=[novel_type])
|
387 |
+
|
388 |
+
demo.queue(concurrency_count=1)
|
389 |
+
|
390 |
+
if __name__ == "__main__":
|
391 |
+
demo.launch(show_error=True,show_api=False)
|
common/__init__.py
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
|
6 |
+
import torch
|
7 |
+
|
8 |
+
def torch_gc():
|
9 |
+
if torch.cuda.is_available():
|
10 |
+
# with torch.cuda.device(DEVICE):
|
11 |
+
torch.cuda.empty_cache()
|
12 |
+
torch.cuda.ipc_collect()
|
13 |
+
elif torch.backends.mps.is_available():
|
14 |
+
try:
|
15 |
+
from torch.mps import empty_cache
|
16 |
+
empty_cache()
|
17 |
+
except Exception as e:
|
18 |
+
print(e)
|
19 |
+
print("如果您使用的是 macOS 建议将 pytorch 版本升级至 2.0.0 或更高版本,以支持及时清理 torch 产生的内存占用。")
|
global_config.py
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
####################################################
|
6 |
+
|
7 |
+
# lang_opt = "zh1"
|
8 |
+
lang_opt = "zh2"
|
9 |
+
# lang_opt = "en"
|
10 |
+
|
11 |
+
####################################################
|
12 |
+
|
13 |
+
# llm_model_opt = "openai"
|
14 |
+
# llm_model_opt = "vicuna"
|
15 |
+
llm_model_opt = "chatglm"
|
16 |
+
# llm_model_opt = "baichuan"
|
17 |
+
# llm_model_opt = "aquila"
|
18 |
+
# llm_model_opt = "falcon"
|
19 |
+
|
20 |
+
####################################################
|
human_simulator.py
ADDED
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
|
6 |
+
from utils import get_content_between_a_b, parse_instructions
|
7 |
+
from prompts.human_simulator import get_input_text
|
8 |
+
from global_config import lang_opt, llm_model_opt
|
9 |
+
|
10 |
+
if "openai" == llm_model_opt:
|
11 |
+
from utils.openai_util import get_api_response
|
12 |
+
elif "vicuna" == llm_model_opt:
|
13 |
+
from utils.vicuna_util import get_api_response
|
14 |
+
elif "chatglm" == llm_model_opt:
|
15 |
+
from utils.chatglm_util import get_api_response
|
16 |
+
elif "baichuan" == llm_model_opt:
|
17 |
+
from utils.baichuan_util import get_api_response
|
18 |
+
elif "aquila" == llm_model_opt:
|
19 |
+
from utils.aquila_util import get_api_response
|
20 |
+
elif "falcon" == llm_model_opt:
|
21 |
+
from utils.falcon_util import get_api_response
|
22 |
+
else:
|
23 |
+
raise Exception("not supported llm model name: {}".format(llm_model_opt))
|
24 |
+
|
25 |
+
|
26 |
+
class Human:
|
27 |
+
|
28 |
+
def __init__(self, input, memory, embedder, model, tokenizer):
|
29 |
+
self.input = input
|
30 |
+
if memory:
|
31 |
+
self.memory = memory
|
32 |
+
else:
|
33 |
+
self.memory = self.input['output_memory']
|
34 |
+
self.embedder = embedder
|
35 |
+
self.model = model
|
36 |
+
self.tokenizer = tokenizer
|
37 |
+
self.output = {}
|
38 |
+
|
39 |
+
def prepare_input(self):
|
40 |
+
previous_paragraph = self.input["input_paragraph"]
|
41 |
+
writer_new_paragraph = self.input["output_paragraph"]
|
42 |
+
memory = self.input["output_memory"]
|
43 |
+
user_edited_plan = self.input["output_instruction"]
|
44 |
+
|
45 |
+
input_text = get_input_text(
|
46 |
+
lang_opt, previous_paragraph, memory, writer_new_paragraph, user_edited_plan)
|
47 |
+
|
48 |
+
return input_text
|
49 |
+
|
50 |
+
def parse_plan(self, response):
|
51 |
+
plan = get_content_between_a_b('Selected Plan:', 'Reason', response)
|
52 |
+
return plan
|
53 |
+
|
54 |
+
def select_plan(self, response_file): # TODO ???
|
55 |
+
|
56 |
+
previous_paragraph = self.input["input_paragraph"]
|
57 |
+
writer_new_paragraph = self.input["output_paragraph"]
|
58 |
+
memory = self.input["output_memory"]
|
59 |
+
previous_plans = self.input["output_instruction"]
|
60 |
+
prompt = f"""
|
61 |
+
Now imagine you are a helpful assistant that help a novelist with decision making. You will be given a previously written paragraph and a paragraph written by a ChatGPT writing assistant, a summary of the main storyline maintained by the ChatGPT assistant, and 3 different possible plans of what to write next.
|
62 |
+
I need you to:
|
63 |
+
Select the most interesting and suitable plan proposed by the ChatGPT assistant.
|
64 |
+
|
65 |
+
Previously written paragraph:
|
66 |
+
{previous_paragraph}
|
67 |
+
|
68 |
+
The summary of the main storyline maintained by your ChatGPT assistant:
|
69 |
+
{memory}
|
70 |
+
|
71 |
+
The new paragraph written by your ChatGPT assistant:
|
72 |
+
{writer_new_paragraph}
|
73 |
+
|
74 |
+
Three plans of what to write next proposed by your ChatGPT assistant:
|
75 |
+
{parse_instructions(previous_plans)}
|
76 |
+
|
77 |
+
Now start choosing, organize your output by strictly following the output format as below:
|
78 |
+
|
79 |
+
Selected Plan:
|
80 |
+
<copy the selected plan here>
|
81 |
+
|
82 |
+
Reason:
|
83 |
+
<Explain why you choose the plan>
|
84 |
+
"""
|
85 |
+
print(prompt+'\n'+'\n')
|
86 |
+
|
87 |
+
response = get_api_response(self.model, self.tokenizer, prompt)
|
88 |
+
|
89 |
+
plan = self.parse_plan(response)
|
90 |
+
while plan == None:
|
91 |
+
response = get_api_response(self.model, self.tokenizer, prompt)
|
92 |
+
plan = self.parse_plan(response)
|
93 |
+
|
94 |
+
if response_file:
|
95 |
+
with open(response_file, 'a', encoding='utf-8') as f:
|
96 |
+
f.write(f"Selected plan here:\n{response}\n\n")
|
97 |
+
|
98 |
+
return plan
|
99 |
+
|
100 |
+
def parse_output(self, text):
|
101 |
+
try:
|
102 |
+
if text.splitlines()[0].startswith('Extended Paragraph'):
|
103 |
+
new_paragraph = get_content_between_a_b(
|
104 |
+
'Extended Paragraph:', 'Selected Plan', text)
|
105 |
+
else:
|
106 |
+
new_paragraph = text.splitlines()[0]
|
107 |
+
|
108 |
+
lines = text.splitlines()
|
109 |
+
if lines[-1] != '\n' and lines[-1].startswith('Revised Plan:'):
|
110 |
+
revised_plan = lines[-1][len("Revised Plan:"):]
|
111 |
+
elif lines[-1] != '\n':
|
112 |
+
revised_plan = lines[-1]
|
113 |
+
|
114 |
+
output = {
|
115 |
+
"output_paragraph": new_paragraph,
|
116 |
+
# "selected_plan": selected_plan,
|
117 |
+
"output_instruction": revised_plan,
|
118 |
+
# "memory":self.input["output_memory"]
|
119 |
+
}
|
120 |
+
|
121 |
+
return output
|
122 |
+
except:
|
123 |
+
return None
|
124 |
+
|
125 |
+
def step(self, response_file=None):
|
126 |
+
|
127 |
+
prompt = self.prepare_input()
|
128 |
+
print(prompt+'\n'+'\n')
|
129 |
+
|
130 |
+
response = get_api_response(self.model, self.tokenizer, prompt)
|
131 |
+
self.output = self.parse_output(response)
|
132 |
+
while self.output == None:
|
133 |
+
response = get_api_response(self.model, self.tokenizer, prompt)
|
134 |
+
self.output = self.parse_output(response)
|
135 |
+
if response_file:
|
136 |
+
with open(response_file, 'a', encoding='utf-8') as f:
|
137 |
+
f.write(f"Human's output here:\n{response}\n\n")
|
imgs/webui-snapshot.png
ADDED
init_prompt.json
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{"init_prompt": "\nPlease write a {type} novel about {topic} with about 50 chapters. Follow the format below precisely:\n\n Begin with the name of the novel.\n Next, write an outline for the first chapter. The outline should describe the background and the beginning of the novel.\n Write the first three paragraphs with their indication of the novel based on your outline. Write in a novelistic style and take your time to set the scene.\n Write a summary that captures the key information of the three paragraphs.\n Finally, write three different instructions for what to write next, each containing around five sentences. Each instruction should present a possible, interesting continuation of the story.\n The output format should follow these guidelines:\n Name: <name of the novel>\n Outline: <outline for the first chapter>\n Paragraph 1: <content for paragraph 1>\n Paragraph 2: <content for paragraph 2>\n Paragraph 3: <content for paragraph 3>\n Summary: <content of summary>\n Instruction 1: <content for instruction 1>\n Instruction 2: <content for instruction 2>\n Instruction 3: <content for instruction 3>\n \n Make sure to be precise and follow the output format strictly.\n \n "}
|
misc/ali_pay.png
ADDED
misc/placeholder
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
|
misc/wechat_pay.png
ADDED
models/__init__.py
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
models/aquila_fa.py
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
import os
|
6 |
+
import torch
|
7 |
+
from flagai.auto_model.auto_loader import AutoLoader
|
8 |
+
from flagai.model.predictor.predictor import Predictor
|
9 |
+
from flagai.model.predictor.aquila import aquila_generate
|
10 |
+
from flagai.data.tokenizer import Tokenizer
|
11 |
+
import bminf
|
12 |
+
|
13 |
+
|
14 |
+
|
15 |
+
max_token: int = 128 # 10000 # 64
|
16 |
+
temperature: float = 0.75
|
17 |
+
top_p = 0.9
|
18 |
+
|
19 |
+
state_dict = "./checkpoints_in"
|
20 |
+
model_name = 'aquilachat-7b'
|
21 |
+
|
22 |
+
def load_model():
|
23 |
+
loader = AutoLoader(
|
24 |
+
"lm",
|
25 |
+
model_dir=state_dict,
|
26 |
+
model_name=model_name,
|
27 |
+
use_cache=True,
|
28 |
+
fp16=True)
|
29 |
+
model = loader.get_model()
|
30 |
+
tokenizer = loader.get_tokenizer()
|
31 |
+
cache_dir = os.path.join(state_dict, model_name)
|
32 |
+
|
33 |
+
model.eval()
|
34 |
+
|
35 |
+
with torch.cuda.device(0):
|
36 |
+
model = bminf.wrapper(model, quantization=False, memory_limit=2 << 30)
|
37 |
+
|
38 |
+
return tokenizer, model
|
models/aquila_hf.py
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
|
6 |
+
import torch
|
7 |
+
from transformers import AutoTokenizer, AutoModelForCausalLM
|
8 |
+
|
9 |
+
# trust_remote_code: remote code depends old version transformers
|
10 |
+
"""
|
11 |
+
File "/root/.cache/huggingface/modules/transformers_modules/qhduan/aquilachat-7b/9d8fcc4f12b6bb6ea0c8a494ba85110f78804739/modeling_aquila.py", line 33, in <module>
|
12 |
+
from transformers.models.llama.configuration_llama import LlamaConfig
|
13 |
+
ModuleNotFoundError: No module named 'transformers.models.llama'
|
14 |
+
"""
|
15 |
+
def load_model():
|
16 |
+
tokenizer = AutoTokenizer.from_pretrained('qhduan/aquilachat-7b')
|
17 |
+
model = AutoModelForCausalLM.from_pretrained('qhduan/aquilachat-7b', trust_remote_code=True)
|
18 |
+
model = model.eval().half().cuda()
|
19 |
+
|
20 |
+
return tokenizer, model
|
models/baichuan_hf.py
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
6 |
+
from peft import PeftModel
|
7 |
+
|
8 |
+
max_token: int = 10000 # 10000 # 64
|
9 |
+
temperature: float = 0.75
|
10 |
+
top_p = 0.9
|
11 |
+
use_lora = False
|
12 |
+
|
13 |
+
|
14 |
+
# def load_model():
|
15 |
+
# model_name_or_path = "baichuan-inc/baichuan-7B"
|
16 |
+
# # model_name_or_path = "~/.cache/huggingface/hub/models--baichuan-inc--baichuan-7B/snapshots/39916f64eb892ccdc1982b0eef845b3b8fd43f6b/"
|
17 |
+
# tokenizer = AutoTokenizer.from_pretrained(
|
18 |
+
# model_name_or_path,
|
19 |
+
# trust_remote_code=True)
|
20 |
+
# model = AutoModelForCausalLM.from_pretrained(
|
21 |
+
# model_name_or_path,
|
22 |
+
# device_map="auto",
|
23 |
+
# trust_remote_code=True)
|
24 |
+
|
25 |
+
# # inputs = tokenizer('登鹳雀楼->王之涣\n夜雨寄北->', return_tensors='pt')
|
26 |
+
# # inputs = inputs.to('cuda:0')
|
27 |
+
# # pred = model.generate(**inputs, max_new_tokens=64,repetition_penalty=1.1)
|
28 |
+
# # print(tokenizer.decode(pred.cpu()[0], skip_special_tokens=True))
|
29 |
+
|
30 |
+
# return tokenizer, model
|
31 |
+
|
32 |
+
|
33 |
+
def load_model(use_lora=True, LOAD_IN_8BIT=False):
|
34 |
+
"""
|
35 |
+
params:
|
36 |
+
use_lora=True, LOAD_IN_8BIT=False
|
37 |
+
use_lora=False. LOAD_IN_8BIT=True
|
38 |
+
"""
|
39 |
+
tokenizer = AutoTokenizer.from_pretrained("baichuan-inc/baichuan-7B",
|
40 |
+
trust_remote_code=True)
|
41 |
+
model = AutoModelForCausalLM.from_pretrained("baichuan-inc/baichuan-7B",
|
42 |
+
device_map="auto",
|
43 |
+
trust_remote_code=True,
|
44 |
+
load_in_8bit=LOAD_IN_8BIT, # if not have enough GPU memory, then use 8bit
|
45 |
+
)
|
46 |
+
|
47 |
+
if use_lora:
|
48 |
+
model = PeftModel.from_pretrained(model, "hiyouga/baichuan-7b-sft")
|
49 |
+
|
50 |
+
return tokenizer, model
|
models/chatglm_hf.py
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
import torch
|
6 |
+
from transformers import AutoTokenizer, AutoConfig, AutoModel
|
7 |
+
|
8 |
+
model_name_or_path = "THUDM/chatglm-6b-int8"
|
9 |
+
max_token: int = 10000
|
10 |
+
temperature: float = 0.75
|
11 |
+
top_p = 0.9
|
12 |
+
use_lora = False
|
13 |
+
|
14 |
+
def auto_configure_device_map(num_gpus: int, use_lora: bool):
|
15 |
+
# transformer.word_embeddings 占用1层
|
16 |
+
# transformer.final_layernorm 和 lm_head 占用1层
|
17 |
+
# transformer.layers 占用 28 层
|
18 |
+
# 总共30层分配到num_gpus张卡上
|
19 |
+
num_trans_layers = 28
|
20 |
+
per_gpu_layers = 30 / num_gpus
|
21 |
+
|
22 |
+
# bugfix: PEFT加载lora模型出现的层命名不同
|
23 |
+
# if LLM_LORA_PATH and use_lora:
|
24 |
+
# layer_prefix = 'base_model.model.transformer'
|
25 |
+
# else:
|
26 |
+
layer_prefix = 'transformer'
|
27 |
+
|
28 |
+
# bugfix: 在linux中调用torch.embedding传入的weight,input不在同一device上,导致RuntimeError
|
29 |
+
# windows下 model.device 会被设置成 transformer.word_embeddings.device
|
30 |
+
# linux下 model.device 会被设置成 lm_head.device
|
31 |
+
# 在调用chat或者stream_chat时,input_ids会被放到model.device上
|
32 |
+
# 如果transformer.word_embeddings.device和model.device不同,则会导致RuntimeError
|
33 |
+
# 因此这里将transformer.word_embeddings,transformer.final_layernorm,lm_head都放到第一张卡上
|
34 |
+
device_map = {f'{layer_prefix}.word_embeddings': 0,
|
35 |
+
f'{layer_prefix}.final_layernorm': 0, 'lm_head': 0,
|
36 |
+
f'base_model.model.lm_head': 0, }
|
37 |
+
|
38 |
+
used = 2
|
39 |
+
gpu_target = 0
|
40 |
+
for i in range(num_trans_layers):
|
41 |
+
if used >= per_gpu_layers:
|
42 |
+
gpu_target += 1
|
43 |
+
used = 0
|
44 |
+
assert gpu_target < num_gpus
|
45 |
+
device_map[f'{layer_prefix}.layers.{i}'] = gpu_target
|
46 |
+
used += 1
|
47 |
+
|
48 |
+
return device_map
|
49 |
+
|
50 |
+
def load_model(llm_device="cuda", device_map=None):
|
51 |
+
tokenizer = AutoTokenizer.from_pretrained(model_name_or_path,trust_remote_code=True)
|
52 |
+
model_config = AutoConfig.from_pretrained(model_name_or_path, trust_remote_code=True)
|
53 |
+
model = AutoModel.from_pretrained(model_name_or_path, config=model_config, trust_remote_code=True)
|
54 |
+
|
55 |
+
if torch.cuda.is_available() and llm_device.lower().startswith("cuda"):
|
56 |
+
# 根据当前设备GPU数量决定是否进行多卡部署
|
57 |
+
num_gpus = torch.cuda.device_count()
|
58 |
+
if num_gpus < 2 and device_map is None:
|
59 |
+
model = model.half().cuda()
|
60 |
+
else:
|
61 |
+
from accelerate import dispatch_model
|
62 |
+
|
63 |
+
# model = AutoModel.from_pretrained(model_name_or_path, trust_remote_code=True,
|
64 |
+
# config=model_config, **kwargs)
|
65 |
+
# 可传入device_map自定义每张卡的部署情况
|
66 |
+
if device_map is None:
|
67 |
+
device_map = auto_configure_device_map(num_gpus, use_lora)
|
68 |
+
|
69 |
+
model = dispatch_model(
|
70 |
+
model.half(), device_map=device_map)
|
71 |
+
else:
|
72 |
+
model = model.float().to(llm_device)
|
73 |
+
|
74 |
+
model = model.eval()
|
75 |
+
|
76 |
+
return tokenizer, model
|
models/falcon_hf.py
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
|
6 |
+
import torch
|
7 |
+
from transformers import AutoTokenizer, AutoModelForCausalLM
|
8 |
+
from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig
|
9 |
+
|
10 |
+
max_token: int = 10000 # 10000 # 64
|
11 |
+
temperature: float = 0.75
|
12 |
+
top_p = 0.9
|
13 |
+
use_lora = False
|
14 |
+
|
15 |
+
# model_name_or_path = "Hannes-Epoch/falcon-7b-instruct-8bit" # not work, miss file
|
16 |
+
|
17 |
+
|
18 |
+
def load_model(opt="gptq"):
|
19 |
+
if "pt" == opt:
|
20 |
+
return load_pt_model()
|
21 |
+
elif "gptq" == opt:
|
22 |
+
return load_gptq_model()
|
23 |
+
else:
|
24 |
+
raise Exception("not supported opt: {}".format(opt))
|
25 |
+
|
26 |
+
########################################################################################################
|
27 |
+
|
28 |
+
def load_gptq_model():
|
29 |
+
model_name_or_path = "TheBloke/falcon-7b-instruct-GPTQ"
|
30 |
+
# You could also download the model locally, and access it there
|
31 |
+
# model_name_or_path = "/path/to/TheBloke_falcon-7b-instruct-GPTQ"
|
32 |
+
|
33 |
+
model_basename = "gptq_model-4bit-64g"
|
34 |
+
|
35 |
+
use_triton = False
|
36 |
+
|
37 |
+
tokenizer = AutoTokenizer.from_pretrained(
|
38 |
+
model_name_or_path, use_fast=True)
|
39 |
+
|
40 |
+
model = AutoGPTQForCausalLM.from_quantized(model_name_or_path,
|
41 |
+
model_basename=model_basename,
|
42 |
+
use_safetensors=True,
|
43 |
+
trust_remote_code=True,
|
44 |
+
device="cuda:0",
|
45 |
+
use_triton=use_triton,
|
46 |
+
quantize_config=None)
|
47 |
+
|
48 |
+
return tokenizer, model
|
49 |
+
|
50 |
+
|
51 |
+
########################################################################################################
|
52 |
+
|
53 |
+
def load_pt_model():
|
54 |
+
model_name_or_path = "tiiuae/falcon-7b"
|
55 |
+
# model_name_or_path = "tiiuae/falcon-7b-instruct"
|
56 |
+
|
57 |
+
tokenizer = AutoTokenizer.from_pretrained(
|
58 |
+
model_name_or_path,
|
59 |
+
trust_remote_code=True,
|
60 |
+
)
|
61 |
+
model = AutoModelForCausalLM.from_pretrained(
|
62 |
+
model_name_or_path,
|
63 |
+
trust_remote_code=True,
|
64 |
+
device_map='auto',
|
65 |
+
# load_in_8bit=True, # not working "RWForCausalLM.__init__() got an unexpected keyword argument 'load_in_8bit'"
|
66 |
+
)
|
67 |
+
|
68 |
+
return tokenizer, model
|
69 |
+
|
70 |
+
########################################################################################################
|
models/vicuna_bin.py
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
|
6 |
+
|
7 |
+
from llama_cpp import Llama, LlamaCache
|
8 |
+
from common import torch_gc
|
9 |
+
|
10 |
+
|
11 |
+
max_token: int = 10000
|
12 |
+
temperature: float = 0.75
|
13 |
+
top_p = 0.9
|
14 |
+
|
15 |
+
def load_model():
|
16 |
+
model_name_or_path = "/root/下载/ggml-vic13b-q5_1.bin"
|
17 |
+
|
18 |
+
params = {
|
19 |
+
'model_path': str(model_name_or_path),
|
20 |
+
'n_ctx': 2048,
|
21 |
+
'seed': 0,
|
22 |
+
'n_threads': 8,
|
23 |
+
'n_gpu_layers': 40,
|
24 |
+
'n_batch': 512,
|
25 |
+
'verbose': True,
|
26 |
+
}
|
27 |
+
model = Llama(**params)
|
28 |
+
model.set_cache(LlamaCache)
|
29 |
+
|
30 |
+
tokenizer = model.tokenizer()
|
31 |
+
|
32 |
+
return tokenizer, model
|
prompts/__init__.py
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
prompts/chatgpt_query.py
ADDED
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
def get_input_text(lang_opt, short_memory, input_paragraph, input_instruction, input_long_term_memory, new_character_prompt):
|
6 |
+
if "en" == lang_opt:
|
7 |
+
input_text = f"""I need you to help me write a novel. Now I give you a memory (a brief summary) of 400 words, you should use it to store the key content of what has been written so that you can keep track of very long context. For each time, I will give you your current memory (a brief summary of previous stories. You should use it to store the key content of what has been written so that you can keep track of very long context), the previously written paragraph, and instructions on what to write in the next paragraph.
|
8 |
+
I need you to write:
|
9 |
+
1. Output Paragraph: the next paragraph of the novel. The output paragraph should contain around 20 sentences and should follow the input instructions.
|
10 |
+
2. Output Memory: The updated memory. You should first explain which sentences in the input memory are no longer necessary and why, and then explain what needs to be added into the memory and why. After that you should write the updated memory. The updated memory should be similar to the input memory except the parts you previously thought that should be deleted or added. The updated memory should only store key information. The updated memory should never exceed 20 sentences!
|
11 |
+
3. Output Instruction: instructions of what to write next (after what you have written). You should output 3 different instructions, each is a possible interesting continuation of the story. Each output instruction should contain around 5 sentences
|
12 |
+
Here are the inputs:
|
13 |
+
|
14 |
+
Input Memory:
|
15 |
+
{short_memory}
|
16 |
+
|
17 |
+
Input Paragraph:
|
18 |
+
{input_paragraph}
|
19 |
+
|
20 |
+
Input Instruction:
|
21 |
+
{input_instruction}
|
22 |
+
|
23 |
+
Input Related Paragraphs:
|
24 |
+
{input_long_term_memory}
|
25 |
+
|
26 |
+
Now start writing, organize your output by strictly following the output format as below:
|
27 |
+
Output Paragraph:
|
28 |
+
<string of output paragraph>, around 20 sentences.
|
29 |
+
|
30 |
+
Output Memory:
|
31 |
+
Rational: <string that explain how to update the memory>;
|
32 |
+
Updated Memory: <string of updated memory>, around 10 to 20 sentences
|
33 |
+
|
34 |
+
Output Instruction:
|
35 |
+
Instruction 1: <content for instruction 1>, around 5 sentences
|
36 |
+
Instruction 2: <content for instruction 2>, around 5 sentences
|
37 |
+
Instruction 3: <content for instruction 3>, around 5 sentences
|
38 |
+
|
39 |
+
Very important!! The updated memory should only store key information. The updated memory should never contain over 500 words!
|
40 |
+
Finally, remember that you are writing a novel. Write like a novelist and do not move too fast when writing the output instructions for the next paragraph. Remember that the chapter will contain over 10 paragraphs and the novel will contain over 100 chapters. And this is just the beginning. Just write some interesting staffs that will happen next. Also, think about what plot can be attractive for common readers when writing output instructions.
|
41 |
+
|
42 |
+
Very Important:
|
43 |
+
You should first explain which sentences in the input memory are no longer necessary and why, and then explain what needs to be added into the memory and why. After that, you start rewrite the input memory to get the updated memory.
|
44 |
+
{new_character_prompt}
|
45 |
+
"""
|
46 |
+
|
47 |
+
elif "zh1" == lang_opt:
|
48 |
+
input_text = f"""I need you to help me write a novel. Now I give you a memory (a brief summary) of 400 words, you should use it to store the key content of what has been written so that you can keep track of very long context. For each time, I will give you your current memory (a brief summary of previous stories. You should use it to store the key content of what has been written so that you can keep track of very long context), the previously written paragraph, and instructions on what to write in the next paragraph.
|
49 |
+
I need you to write:
|
50 |
+
1. Output Paragraph: the next paragraph of the novel. The output paragraph should contain around 20 sentences and should follow the input instructions.
|
51 |
+
2. Output Memory: The updated memory. You should first explain which sentences in the input memory are no longer necessary and why, and then explain what needs to be added into the memory and why. After that you should write the updated memory. The updated memory should be similar to the input memory except the parts you previously thought that should be deleted or added. The updated memory should only store key information. The updated memory should never exceed 20 sentences!
|
52 |
+
3. Output Instruction: instructions of what to write next (after what you have written). You should output 3 different instructions, each is a possible interesting continuation of the story. Each output instruction should contain around 5 sentences
|
53 |
+
4. 非常重要!请将输出信息内容全部转化为中文,注意要符合中文母语的语法和���词习惯。
|
54 |
+
Here are the inputs:
|
55 |
+
|
56 |
+
Input Memory:
|
57 |
+
{short_memory}
|
58 |
+
|
59 |
+
Input Paragraph:
|
60 |
+
{input_paragraph}
|
61 |
+
|
62 |
+
Input Instruction:
|
63 |
+
{input_instruction}
|
64 |
+
|
65 |
+
Input Related Paragraphs:
|
66 |
+
{input_long_term_memory}
|
67 |
+
|
68 |
+
Now start writing, organize your output by strictly following the output format as below:
|
69 |
+
Output Paragraph:
|
70 |
+
<string of output paragraph>, around 20 sentences.
|
71 |
+
|
72 |
+
Output Memory:
|
73 |
+
Rational: <string that explain how to update the memory>;
|
74 |
+
Updated Memory: <string of updated memory>, around 10 to 20 sentences
|
75 |
+
|
76 |
+
Output Instruction:
|
77 |
+
Instruction 1: <content for instruction 1>, around 5 sentences
|
78 |
+
Instruction 2: <content for instruction 2>, around 5 sentences
|
79 |
+
Instruction 3: <content for instruction 3>, around 5 sentences
|
80 |
+
|
81 |
+
Very important!! The updated memory should only store key information. The updated memory should never contain over 500 words!
|
82 |
+
Finally, remember that you are writing a novel. Write like a novelist and do not move too fast when writing the output instructions for the next paragraph. Remember that the chapter will contain over 10 paragraphs and the novel will contain over 100 chapters. And this is just the beginning. Just write some interesting staffs that will happen next. Also, think about what plot can be attractive for common readers when writing output instructions.
|
83 |
+
|
84 |
+
Very Important:
|
85 |
+
You should first explain which sentences in the input memory are no longer necessary and why, and then explain what needs to be added into the memory and why. After that, you start rewrite the input memory to get the updated memory.
|
86 |
+
非常重要!请将输出信息内容全部转化为中文,注意要符合中文母语的语法和用词习惯。
|
87 |
+
{new_character_prompt}
|
88 |
+
"""
|
89 |
+
|
90 |
+
elif "zh2" == lang_opt:
|
91 |
+
input_text = f"""我需要你帮我写一部小说。现在我给你一个400字的记忆(一个简短的总结),你应该用它来存储已经写好的关键内容,这样你就可以记录很长的上下文。每一次,我都会给你当前的记忆(以前的故事的简要总结。你应该用它来存储所写内容的关键内容,这样你就能记下很长的上下文),之前写的段落,以及下一段要写的内容的指示。
|
92 |
+
我需要你来写:
|
93 |
+
1. 输出段落:小说的下一个段落。输出段应包含约20句话,并应遵循输入指示。
|
94 |
+
2. 输出记忆: 更新后的记忆。你应该首先解释输入记忆中的哪些句子不再需要,为什么,然后解释需要添加到记忆中的内容,为什么。之后,你应该写出更新的记忆。除了你之前认为应该删除或添加的部分,更新后的记忆应该与输入的记忆相似。更新后的记忆应该只存储关键信息。更新后的记忆不应该超过20个句子!
|
95 |
+
3. 输出指令:接下来要写什么的指令(在你写完之后)。你应该输出3个不同的指令,每个指令都是故事的一个可能的有趣的延续。每个输出指令应该包含大约5个句子
|
96 |
+
下面是输入的内容:
|
97 |
+
|
98 |
+
输入内存:
|
99 |
+
{short_memory}
|
100 |
+
|
101 |
+
输入段落:
|
102 |
+
{input_paragraph}
|
103 |
+
|
104 |
+
输入指令:
|
105 |
+
{input_instruction}。
|
106 |
+
|
107 |
+
输入相关段落:
|
108 |
+
{input_long_term_memory}
|
109 |
+
|
110 |
+
现在开始写,严格按照下面的输出格式来组织你的输出:
|
111 |
+
输出段落:
|
112 |
+
<输出段落的字符串>,大约20句话。
|
113 |
+
|
114 |
+
输出记忆:
|
115 |
+
理性: <解释如何更新内存的字符串>;
|
116 |
+
更新的记忆: <更新内存的字符串>,大约10到20句话
|
117 |
+
|
118 |
+
输出指令:
|
119 |
+
指令1:<指令1的内容>,大约5句话
|
120 |
+
指令2:<指令2的内容>,大约5句话
|
121 |
+
指令3:<指令3的内容>,大约5句话
|
122 |
+
|
123 |
+
非常重要!! 更新的内存应该只存储关键信息。更新后的记忆不应该包含超过500个字!!!!
|
124 |
+
最后,记住你在写一本小说。像小说家一样写作,在写下一段的输出指令时不要走得太快。记住,这一章将包含10多段,而小说将包含100多章。而这仅仅是个开始。就要写一些接下来会发生的有趣的职员。另外,在写输出说明时,要考虑什么情节能吸引普通读者。
|
125 |
+
|
126 |
+
非常重要:
|
127 |
+
你应该首先解释输入存储器中的哪些句子不再需要,为什么,然后解释需要添加到存储器中的内容,为什么。之后,你开始重写输入内存,得到更新的内存。
|
128 |
+
{new_character_prompt}
|
129 |
+
"""
|
130 |
+
|
131 |
+
else:
|
132 |
+
raise Exception("not supported lang_opt: {}".format(lang_opt))
|
133 |
+
|
134 |
+
return input_text
|
prompts/human_simulator.py
ADDED
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
|
6 |
+
def get_input_text(lang_opt, previous_paragraph, memory, writer_new_paragraph, user_edited_plan):
|
7 |
+
if "en" == lang_opt:
|
8 |
+
input_text = f"""
|
9 |
+
Now imagine you are a novelist writing a Chinese novel with the help of ChatGPT. You will be given a previously written paragraph (wrote by you), and a paragraph written by your ChatGPT assistant, a summary of the main storyline maintained by your ChatGPT assistant, and a plan of what to write next proposed by your ChatGPT assistant.
|
10 |
+
I need you to write:
|
11 |
+
1. Extended Paragraph: Extend the new paragraph written by the ChatGPT assistant to twice the length of the paragraph written by your ChatGPT assistant.
|
12 |
+
2. Selected Plan: Copy the plan proposed by your ChatGPT assistant.
|
13 |
+
3. Revised Plan: Revise the selected plan into an outline of the next paragraph.
|
14 |
+
|
15 |
+
Previously written paragraph:
|
16 |
+
{previous_paragraph}
|
17 |
+
|
18 |
+
The summary of the main storyline maintained by your ChatGPT assistant:
|
19 |
+
{memory}
|
20 |
+
|
21 |
+
The new paragraph written by your ChatGPT assistant:
|
22 |
+
{writer_new_paragraph}
|
23 |
+
|
24 |
+
The plan of what to write next proposed by your ChatGPT assistant:
|
25 |
+
{user_edited_plan}
|
26 |
+
|
27 |
+
Now start writing, organize your output by strictly following the output format as below,所有输出仍然保持是中文:
|
28 |
+
|
29 |
+
Extended Paragraph:
|
30 |
+
<string of output paragraph>, around 40-50 sentences.
|
31 |
+
|
32 |
+
Selected Plan:
|
33 |
+
<copy the plan here>
|
34 |
+
|
35 |
+
Revised Plan:
|
36 |
+
<string of revised plan>, keep it short, around 5-7 sentences.
|
37 |
+
|
38 |
+
Very Important:
|
39 |
+
Remember that you are writing a novel. Write like a novelist and do not move too fast when writing the plan for the next paragraph. Think about how the plan can be attractive for common readers when selecting and extending the plan. Remember to follow the length constraints! Remember that the chapter will contain over 10 paragraphs and the novel will contain over 100 chapters. And the next paragraph will be the second paragraph of the second chapter. You need to leave space for future stories.
|
40 |
+
|
41 |
+
"""
|
42 |
+
|
43 |
+
elif "zh1" == lang_opt:
|
44 |
+
input_text = f"""
|
45 |
+
Now imagine you are a novelist writing a Chinese novel with the help of ChatGPT. You will be given a previously written paragraph (wrote by you), and a paragraph written by your ChatGPT assistant, a summary of the main storyline maintained by your ChatGPT assistant, and a plan of what to write next proposed by your ChatGPT assistant.
|
46 |
+
I need you to write:
|
47 |
+
1. Extended Paragraph: Extend the new paragraph written by the ChatGPT assistant to twice the length of the paragraph written by your ChatGPT assistant.
|
48 |
+
2. Selected Plan: Copy the plan proposed by your ChatGPT assistant.
|
49 |
+
3. Revised Plan: Revise the selected plan into an outline of the next paragraph.
|
50 |
+
4. 非常重要!请将输出信息内容全部转化为中文,注意要符合中文母语的语法和用词习惯。
|
51 |
+
|
52 |
+
Previously written paragraph:
|
53 |
+
{previous_paragraph}
|
54 |
+
|
55 |
+
The summary of the main storyline maintained by your ChatGPT assistant:
|
56 |
+
{memory}
|
57 |
+
|
58 |
+
The new paragraph written by your ChatGPT assistant:
|
59 |
+
{writer_new_paragraph}
|
60 |
+
|
61 |
+
The plan of what to write next proposed by your ChatGPT assistant:
|
62 |
+
{user_edited_plan}
|
63 |
+
|
64 |
+
Now start writing, organize your output by strictly following the output format as below,所有输出仍然保持是中文:
|
65 |
+
|
66 |
+
Extended Paragraph:
|
67 |
+
<string of output paragraph>, around 40-50 sentences.
|
68 |
+
|
69 |
+
Selected Plan:
|
70 |
+
<copy the plan here>
|
71 |
+
|
72 |
+
Revised Plan:
|
73 |
+
<string of revised plan>, keep it short, around 5-7 sentences.
|
74 |
+
|
75 |
+
Very Important:
|
76 |
+
Remember that you are writing a novel. Write like a novelist and do not move too fast when writing the plan for the next paragraph. Think about how the plan can be attractive for common readers when selecting and extending the plan. Remember to follow the length constraints! Remember that the chapter will contain over 10 paragraphs and the novel will contain over 100 chapters. And the next paragraph will be the second paragraph of the second chapter. You need to leave space for future stories.
|
77 |
+
非常重要!请将输出信息内容全部转化为中文,注意要符合中文母语的语法和用词习惯。
|
78 |
+
|
79 |
+
"""
|
80 |
+
|
81 |
+
elif "zh2" == lang_opt:
|
82 |
+
input_text = f"""
|
83 |
+
现在想象一下,你是一个小说家,在ChatGPT的帮助下写一本中文小说。你会得到一个先前写好的段落(由你写),和一个由你的ChatGPT助手写的段落,一个由你的ChatGPT助手保持的主要故事情节的总结,以及一个由你的ChatGPT助手提出的下一步写作计划。
|
84 |
+
我需要你写:
|
85 |
+
1. 扩展段落: 将ChatGPT助手写的新段落延长到你的ChatGPT助手���写段落的两倍。
|
86 |
+
2. 选定计划: 复制您的ChatGPT助手提出的计划。
|
87 |
+
3. 修订的计划: 将选定的计划修改为下一段的纲要。
|
88 |
+
|
89 |
+
以前写的段落:
|
90 |
+
{previous_paragraph}
|
91 |
+
|
92 |
+
由你的ChatGPT助手维护的主要故事情节的摘要:
|
93 |
+
{memory}
|
94 |
+
|
95 |
+
您的ChatGPT助理写的新段落:
|
96 |
+
{writer_new_paragraph}
|
97 |
+
|
98 |
+
您的ChatGPT助理提出的下一步写作计划:
|
99 |
+
{user_edited_plan}
|
100 |
+
|
101 |
+
现在开始写,严格按照下面的输出格式来组织你的输出,所有输出仍然保持是中文:
|
102 |
+
|
103 |
+
扩展段落:
|
104 |
+
<输出段落的字符串>,大约40-50个句子。
|
105 |
+
|
106 |
+
选定的计划:
|
107 |
+
<在此复制计划>
|
108 |
+
|
109 |
+
修改后的计划:
|
110 |
+
<修改后的计划字符串>,保持简短,大约5-7句话。
|
111 |
+
|
112 |
+
非常重要:
|
113 |
+
记住你在写一本小说。像小说家一样写作,在写下一段的计划时不要走得太快。在选择和扩展计划时,要考虑计划如何对普通读者具有吸引力。记住要遵循长度限制! 记住,这一章将包含10多段,而小说将包含100多章。而下一段将是第二章的第二段。你需要为未来的故事留出空间。
|
114 |
+
|
115 |
+
"""
|
116 |
+
|
117 |
+
else:
|
118 |
+
raise Exception("not supported lang_opt: {}".format(lang_opt))
|
119 |
+
|
120 |
+
return input_text
|
prompts/llm_query.py
ADDED
@@ -0,0 +1,135 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
|
6 |
+
def get_input_text(lang_opt, short_memory, input_paragraph, input_instruction, input_long_term_memory, new_character_prompt):
|
7 |
+
if "en" == lang_opt:
|
8 |
+
input_text = f"""I need you to help me write a novel. Now I give you a memory (a brief summary) of 400 words, you should use it to store the key content of what has been written so that you can keep track of very long context. For each time, I will give you your current memory (a brief summary of previous stories. You should use it to store the key content of what has been written so that you can keep track of very long context), the previously written paragraph, and instructions on what to write in the next paragraph.
|
9 |
+
I need you to write:
|
10 |
+
1. Output Paragraph: the next paragraph of the novel. The output paragraph should contain around 20 sentences and should follow the input instructions.
|
11 |
+
2. Output Memory: The updated memory. You should first explain which sentences in the input memory are no longer necessary and why, and then explain what needs to be added into the memory and why. After that you should write the updated memory. The updated memory should be similar to the input memory except the parts you previously thought that should be deleted or added. The updated memory should only store key information. The updated memory should never exceed 20 sentences!
|
12 |
+
3. Output Instruction: instructions of what to write next (after what you have written). You should output 3 different instructions, each is a possible interesting continuation of the story. Each output instruction should contain around 5 sentences
|
13 |
+
Here are the inputs:
|
14 |
+
|
15 |
+
Input Memory:
|
16 |
+
{short_memory}
|
17 |
+
|
18 |
+
Input Paragraph:
|
19 |
+
{input_paragraph}
|
20 |
+
|
21 |
+
Input Instruction:
|
22 |
+
{input_instruction}
|
23 |
+
|
24 |
+
Input Related Paragraphs:
|
25 |
+
{input_long_term_memory}
|
26 |
+
|
27 |
+
Now start writing, organize your output by strictly following the output format as below:
|
28 |
+
Output Paragraph:
|
29 |
+
<string of output paragraph>, around 20 sentences.
|
30 |
+
|
31 |
+
Output Memory:
|
32 |
+
Rational: <string that explain how to update the memory>;
|
33 |
+
Updated Memory: <string of updated memory>, around 10 to 20 sentences
|
34 |
+
|
35 |
+
Output Instruction:
|
36 |
+
Instruction 1: <content for instruction 1>, around 5 sentences
|
37 |
+
Instruction 2: <content for instruction 2>, around 5 sentences
|
38 |
+
Instruction 3: <content for instruction 3>, around 5 sentences
|
39 |
+
|
40 |
+
Very important!! The updated memory should only store key information. The updated memory should never contain over 500 words!
|
41 |
+
Finally, remember that you are writing a novel. Write like a novelist and do not move too fast when writing the output instructions for the next paragraph. Remember that the chapter will contain over 10 paragraphs and the novel will contain over 100 chapters. And this is just the beginning. Just write some interesting staffs that will happen next. Also, think about what plot can be attractive for common readers when writing output instructions.
|
42 |
+
|
43 |
+
Very Important:
|
44 |
+
You should first explain which sentences in the input memory are no longer necessary and why, and then explain what needs to be added into the memory and why. After that, you start rewrite the input memory to get the updated memory.
|
45 |
+
{new_character_prompt}
|
46 |
+
"""
|
47 |
+
|
48 |
+
elif "zh1" == lang_opt:
|
49 |
+
input_text = f"""I need you to help me write a novel. Now I give you a memory (a brief summary) of 400 words, you should use it to store the key content of what has been written so that you can keep track of very long context. For each time, I will give you your current memory (a brief summary of previous stories. You should use it to store the key content of what has been written so that you can keep track of very long context), the previously written paragraph, and instructions on what to write in the next paragraph.
|
50 |
+
I need you to write:
|
51 |
+
1. Output Paragraph: the next paragraph of the novel. The output paragraph should contain around 20 sentences and should follow the input instructions.
|
52 |
+
2. Output Memory: The updated memory. You should first explain which sentences in the input memory are no longer necessary and why, and then explain what needs to be added into the memory and why. After that you should write the updated memory. The updated memory should be similar to the input memory except the parts you previously thought that should be deleted or added. The updated memory should only store key information. The updated memory should never exceed 20 sentences!
|
53 |
+
3. Output Instruction: instructions of what to write next (after what you have written). You should output 3 different instructions, each is a possible interesting continuation of the story. Each output instruction should contain around 5 sentences
|
54 |
+
4. 非常重要!请将输出信息内容全部转化为中文,注意要符合中文母语的语法��用词习惯。
|
55 |
+
Here are the inputs:
|
56 |
+
|
57 |
+
Input Memory:
|
58 |
+
{short_memory}
|
59 |
+
|
60 |
+
Input Paragraph:
|
61 |
+
{input_paragraph}
|
62 |
+
|
63 |
+
Input Instruction:
|
64 |
+
{input_instruction}
|
65 |
+
|
66 |
+
Input Related Paragraphs:
|
67 |
+
{input_long_term_memory}
|
68 |
+
|
69 |
+
Now start writing, organize your output by strictly following the output format as below:
|
70 |
+
Output Paragraph:
|
71 |
+
<string of output paragraph>, around 20 sentences.
|
72 |
+
|
73 |
+
Output Memory:
|
74 |
+
Rational: <string that explain how to update the memory>;
|
75 |
+
Updated Memory: <string of updated memory>, around 10 to 20 sentences
|
76 |
+
|
77 |
+
Output Instruction:
|
78 |
+
Instruction 1: <content for instruction 1>, around 5 sentences
|
79 |
+
Instruction 2: <content for instruction 2>, around 5 sentences
|
80 |
+
Instruction 3: <content for instruction 3>, around 5 sentences
|
81 |
+
|
82 |
+
Very important!! The updated memory should only store key information. The updated memory should never contain over 500 words!
|
83 |
+
Finally, remember that you are writing a novel. Write like a novelist and do not move too fast when writing the output instructions for the next paragraph. Remember that the chapter will contain over 10 paragraphs and the novel will contain over 100 chapters. And this is just the beginning. Just write some interesting staffs that will happen next. Also, think about what plot can be attractive for common readers when writing output instructions.
|
84 |
+
|
85 |
+
Very Important:
|
86 |
+
You should first explain which sentences in the input memory are no longer necessary and why, and then explain what needs to be added into the memory and why. After that, you start rewrite the input memory to get the updated memory.
|
87 |
+
非常重要!请将输出信息内容全部转化为中文,注意要符合中文母语的语法和用词习惯。
|
88 |
+
{new_character_prompt}
|
89 |
+
"""
|
90 |
+
|
91 |
+
elif "zh2" == lang_opt:
|
92 |
+
input_text = f"""我需要你帮我写一部小说。现在我给你一个400字的记忆(一个简短的总结),你应该用它来存储已经写好的关键内容,这样你就可以记录很长的上下文。每一次,我都会给你当前的记忆(以前的故事的简要总结。你应该用它来存储所写内容的关键内容,这样你就能记下很长的上下文),之前写的段落,以及下一段要写的内容的指示。
|
93 |
+
我需要你来写:
|
94 |
+
1. 输出段落:小说的下一个段落。输出段应包含约20句话,并应遵循输入指示。
|
95 |
+
2. 输出记忆: 更新后的记忆。你应该首先解释输入记忆中的哪些句子不再需要,为什么,然后解释需要添加到记忆中的内容,为什么。之后,你应该写出更新的记忆。除了你之前认为应该删除或添加的部分,更新后的记忆应该与输入的记忆相似。更新后的记忆应该只存储关键信息。更新后的记忆不应该超过20个句子!
|
96 |
+
3. 输出指令:接下来要写什么的指令(在你写完之后)。你应该输出3个不同的指令,每个指令都是故事的一个可能的有趣的延续。每个输出指令应该包含大约5个句子
|
97 |
+
下面是输入的内容:
|
98 |
+
|
99 |
+
输入内存:
|
100 |
+
{short_memory}
|
101 |
+
|
102 |
+
输入段落:
|
103 |
+
{input_paragraph}
|
104 |
+
|
105 |
+
输入指令:
|
106 |
+
{input_instruction}。
|
107 |
+
|
108 |
+
输入相关段落:
|
109 |
+
{input_long_term_memory}
|
110 |
+
|
111 |
+
现在开始写,严格按照下面的输出格式来组织你的输出:
|
112 |
+
输出段落:
|
113 |
+
<输出段落的字符串>,大约20句话。
|
114 |
+
|
115 |
+
输出记忆:
|
116 |
+
理性: <解释如何更新内存的字符串>;
|
117 |
+
更新的记忆: <更新内存的字符串>,大约10到20句话
|
118 |
+
|
119 |
+
输出指令:
|
120 |
+
指令1:<指令1的内容>,大约5句话
|
121 |
+
指令2:<指令2的内容>,大约5句话
|
122 |
+
指令3:<指令3的内容>,大约5句话
|
123 |
+
|
124 |
+
非常重要!! 更新的内存应该只存储关键信息。更新后的记忆不应该包含超过500个字!!!!
|
125 |
+
最后,记住你在写一本小说。像小说家一样写作,在写下一段的输出指令时不要走得太快。记住,这一章将包含10多段,而小说将包含100多章。而这仅仅是个开始。就要写一些接下来会发生的有趣的职员。另外,在写输出说明时,要考虑什么情节能吸引普通读者。
|
126 |
+
|
127 |
+
非常重要:
|
128 |
+
你应该首先解释输入存储器中的哪些句子不再需要,为什么,然后解释需要添加到存储器中的内容,为什么。之后,你开始重写输入内存,得到更新的内存。
|
129 |
+
{new_character_prompt}
|
130 |
+
"""
|
131 |
+
|
132 |
+
else:
|
133 |
+
raise Exception("not supported lang_opt: {}".format(lang_opt))
|
134 |
+
|
135 |
+
return input_text
|
prompts/service_init.py
ADDED
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
|
6 |
+
def get_init_prompt(lang_opt, novel_type, description):
|
7 |
+
if "en" == lang_opt:
|
8 |
+
return f"""
|
9 |
+
Please write a {novel_type} novel{description} with 50 chapters. Follow the format below precisely:
|
10 |
+
|
11 |
+
Begin with the name of the novel.
|
12 |
+
Next, write an outline for the first chapter. The outline should describe the background and the beginning of the novel.
|
13 |
+
Write the first three paragraphs with their indication of the novel based on your outline. Write in a novelistic style and take your time to set the scene.
|
14 |
+
Write a summary that captures the key information of the three paragraphs.
|
15 |
+
Finally, write three different instructions for what to write next, each containing around five sentences. Each instruction should present a possible, interesting continuation of the story.
|
16 |
+
The output format should follow these guidelines:
|
17 |
+
Name: <name of the novel>
|
18 |
+
Outline: <outline for the first chapter>
|
19 |
+
Paragraph 1: <content for paragraph 1>
|
20 |
+
Paragraph 2: <content for paragraph 2>
|
21 |
+
Paragraph 3: <content for paragraph 3>
|
22 |
+
Summary: <content of summary>
|
23 |
+
Instruction 1: <content for instruction 1>
|
24 |
+
Instruction 2: <content for instruction 2>
|
25 |
+
Instruction 3: <content for instruction 3>
|
26 |
+
|
27 |
+
Make sure to be precise and follow the output format strictly.
|
28 |
+
|
29 |
+
"""
|
30 |
+
elif "zh1" == lang_opt:
|
31 |
+
return f"""
|
32 |
+
Please write a {novel_type} novel{description} with 50 chapters. Follow the format below precisely:
|
33 |
+
|
34 |
+
Begin with the name of the novel.
|
35 |
+
Next, write an outline for the first chapter. The outline should describe the background and the beginning of the novel.
|
36 |
+
Write the first three paragraphs with their indication of the novel based on your outline. Write in a novelistic style and take your time to set the scene.
|
37 |
+
Write a summary that captures the key information of the three paragraphs.
|
38 |
+
Finally, write three different instructions for what to write next, each containing around five sentences. Each instruction should present a possible, interesting continuation of the story.
|
39 |
+
The output format should follow these guidelines:
|
40 |
+
名称: <name of the novel>
|
41 |
+
概述: <outline for the first chapter>
|
42 |
+
段落1: <content for paragraph 1>
|
43 |
+
段落2: <content for paragraph 2>
|
44 |
+
段落3: <content for paragraph 3>
|
45 |
+
总结: <content of summary>
|
46 |
+
指令1: <content for instruction 1>
|
47 |
+
指令2: <content for instruction 2>
|
48 |
+
指令3:<content for instruction 3>
|
49 |
+
|
50 |
+
Make sure to be precise and follow the output format strictly.
|
51 |
+
非常重要!请将输出信息内容全部转化为中文,注意要符合中文母语的语法和用词习惯。
|
52 |
+
|
53 |
+
"""
|
54 |
+
|
55 |
+
elif "zh2" == lang_opt:
|
56 |
+
return f"""
|
57 |
+
请写一篇{novel_type}的小说{description},有50个章节。准确遵循以下格式:
|
58 |
+
|
59 |
+
以小说的名称开始。
|
60 |
+
接下来,写出第一章的大纲。大纲应描述小说的背景和开头。
|
61 |
+
根据你的提纲写出前三段,并说明小说的内容。用小说的风格来写,慢慢地设置场景。
|
62 |
+
写一个摘要,抓住这三段的关键信息。
|
63 |
+
最后,写出三个不同的指示,说明接下来要写什么,每个指示包含大约五句话。每个指示都应该提出一个可能的、有趣的故事的延续。
|
64 |
+
输出格式应遵循这些准则:
|
65 |
+
名称: <小说的名称>
|
66 |
+
概述: <第一章的大纲>
|
67 |
+
段落1: <第1段的内容>
|
68 |
+
段落2: <第2段的内容>
|
69 |
+
段落3: <第3段的内容>
|
70 |
+
总结: <摘要的内容>。
|
71 |
+
指令1: <指令1的内容>
|
72 |
+
指令2: <指令2的内容>
|
73 |
+
指令3:<指令3的内容>
|
74 |
+
|
75 |
+
请务必准确无误,并严格遵守输出格式。
|
76 |
+
"""
|
77 |
+
|
78 |
+
else:
|
79 |
+
raise Exception(f"not supported language: {lang_opt}")
|
recurrent_llm.py
ADDED
@@ -0,0 +1,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
import torch
|
6 |
+
import random
|
7 |
+
from sentence_transformers import util
|
8 |
+
|
9 |
+
from utils import get_content_between_a_b
|
10 |
+
from prompts.llm_query import get_input_text
|
11 |
+
from global_config import lang_opt, llm_model_opt
|
12 |
+
|
13 |
+
if "openai" == llm_model_opt:
|
14 |
+
from utils.openai_util import get_api_response
|
15 |
+
elif "vicuna" == llm_model_opt:
|
16 |
+
from utils.vicuna_util import get_api_response
|
17 |
+
elif "chatglm" == llm_model_opt:
|
18 |
+
from utils.chatglm_util import get_api_response
|
19 |
+
elif "baichuan" == llm_model_opt:
|
20 |
+
from utils.baichuan_util import get_api_response
|
21 |
+
elif "aquila" == llm_model_opt:
|
22 |
+
from utils.aquila_util import get_api_response
|
23 |
+
elif "falcon" == llm_model_opt:
|
24 |
+
from utils.falcon_util import get_api_response
|
25 |
+
else:
|
26 |
+
raise Exception("not supported llm model name: {}".format(llm_model_opt))
|
27 |
+
|
28 |
+
|
29 |
+
class RecurrentLLM:
|
30 |
+
|
31 |
+
def __init__(self, input, short_memory, long_memory, memory_index, embedder, model, tokenizer):
|
32 |
+
print("AIWriter loaded by RecurrentLLM")
|
33 |
+
self.input = input
|
34 |
+
self.short_memory = short_memory
|
35 |
+
self.long_memory = long_memory
|
36 |
+
self.embedder = embedder
|
37 |
+
self.model = model
|
38 |
+
self.tokenizer = tokenizer
|
39 |
+
if self.long_memory and not memory_index:
|
40 |
+
self.memory_index = self.embedder.encode(
|
41 |
+
self.long_memory, convert_to_tensor=True)
|
42 |
+
self.output = {}
|
43 |
+
|
44 |
+
def prepare_input(self, new_character_prob=0.1, top_k=2):
|
45 |
+
|
46 |
+
input_paragraph = self.input["output_paragraph"]
|
47 |
+
input_instruction = self.input["output_instruction"]
|
48 |
+
|
49 |
+
instruction_embedding = self.embedder.encode(
|
50 |
+
input_instruction, convert_to_tensor=True)
|
51 |
+
|
52 |
+
# get the top 3 most similar paragraphs from memory
|
53 |
+
|
54 |
+
memory_scores = util.cos_sim(
|
55 |
+
instruction_embedding, self.memory_index)[0]
|
56 |
+
top_k_idx = torch.topk(memory_scores, k=top_k)[1]
|
57 |
+
top_k_memory = [self.long_memory[idx] for idx in top_k_idx]
|
58 |
+
# combine the top 3 paragraphs
|
59 |
+
input_long_term_memory = '\n'.join(
|
60 |
+
[f"Related Paragraphs {i+1} :" + selected_memory for i, selected_memory in enumerate(top_k_memory)])
|
61 |
+
# randomly decide if a new character should be introduced
|
62 |
+
if random.random() < new_character_prob:
|
63 |
+
new_character_prompt = f"If it is reasonable, you can introduce a new character in the output paragrah and add it into the memory."
|
64 |
+
else:
|
65 |
+
new_character_prompt = ""
|
66 |
+
|
67 |
+
input_text = get_input_text(lang_opt, self.short_memory, input_paragraph, input_instruction, input_long_term_memory, new_character_prompt)
|
68 |
+
|
69 |
+
return input_text
|
70 |
+
|
71 |
+
def parse_output(self, output):
|
72 |
+
try:
|
73 |
+
output_paragraph = get_content_between_a_b(
|
74 |
+
'Output Paragraph:', 'Output Memory', output)
|
75 |
+
output_memory_updated = get_content_between_a_b(
|
76 |
+
'Updated Memory:', 'Output Instruction:', output)
|
77 |
+
self.short_memory = output_memory_updated
|
78 |
+
ins_1 = get_content_between_a_b(
|
79 |
+
'Instruction 1:', 'Instruction 2', output)
|
80 |
+
ins_2 = get_content_between_a_b(
|
81 |
+
'Instruction 2:', 'Instruction 3', output)
|
82 |
+
lines = output.splitlines()
|
83 |
+
# content of Instruction 3 may be in the same line with I3 or in the next line
|
84 |
+
if lines[-1] != '\n' and lines[-1].startswith('Instruction 3'):
|
85 |
+
ins_3 = lines[-1][len("Instruction 3:"):]
|
86 |
+
elif lines[-1] != '\n':
|
87 |
+
ins_3 = lines[-1]
|
88 |
+
|
89 |
+
output_instructions = [ins_1, ins_2, ins_3]
|
90 |
+
assert len(output_instructions) == 3
|
91 |
+
|
92 |
+
output = {
|
93 |
+
"input_paragraph": self.input["output_paragraph"],
|
94 |
+
"output_memory": output_memory_updated, # feed to human
|
95 |
+
"output_paragraph": output_paragraph,
|
96 |
+
"output_instruction": [instruction.strip() for instruction in output_instructions]
|
97 |
+
}
|
98 |
+
|
99 |
+
return output
|
100 |
+
except:
|
101 |
+
return None
|
102 |
+
|
103 |
+
def step(self, response_file=None):
|
104 |
+
|
105 |
+
prompt = self.prepare_input()
|
106 |
+
|
107 |
+
print(prompt+'\n'+'\n')
|
108 |
+
|
109 |
+
response = get_api_response(self.model, self.tokenizer, prompt)
|
110 |
+
|
111 |
+
self.output = self.parse_output(response)
|
112 |
+
while self.output == None:
|
113 |
+
response = get_api_response(self.model, self.tokenizer, prompt)
|
114 |
+
self.output = self.parse_output(response)
|
115 |
+
if response_file:
|
116 |
+
with open(response_file, 'a', encoding='utf-8') as f:
|
117 |
+
f.write(f"Writer's output here:\n{response}\n\n")
|
118 |
+
|
119 |
+
self.long_memory.append(self.input["output_paragraph"])
|
120 |
+
self.memory_index = self.embedder.encode(
|
121 |
+
self.long_memory, convert_to_tensor=True)
|
recurrentgpt.py
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
import torch
|
6 |
+
import random
|
7 |
+
from sentence_transformers import util
|
8 |
+
|
9 |
+
from utils import get_content_between_a_b, get_api_response
|
10 |
+
from prompts.chatgpt_query import get_input_text
|
11 |
+
from global_config import lang_opt
|
12 |
+
|
13 |
+
|
14 |
+
class RecurrentGPT:
|
15 |
+
|
16 |
+
def __init__(self, input, short_memory, long_memory, memory_index, embedder):
|
17 |
+
print("AIWriter loaded by RecurrentGPT")
|
18 |
+
self.input = input
|
19 |
+
self.short_memory = short_memory
|
20 |
+
self.long_memory = long_memory
|
21 |
+
self.embedder = embedder
|
22 |
+
if self.long_memory and not memory_index:
|
23 |
+
self.memory_index = self.embedder.encode(
|
24 |
+
self.long_memory, convert_to_tensor=True)
|
25 |
+
self.output = {}
|
26 |
+
|
27 |
+
def prepare_input(self, new_character_prob=0.1, top_k=2):
|
28 |
+
|
29 |
+
input_paragraph = self.input["output_paragraph"]
|
30 |
+
input_instruction = self.input["output_instruction"]
|
31 |
+
|
32 |
+
instruction_embedding = self.embedder.encode(
|
33 |
+
input_instruction, convert_to_tensor=True)
|
34 |
+
|
35 |
+
# get the top 3 most similar paragraphs from memory
|
36 |
+
|
37 |
+
memory_scores = util.cos_sim(
|
38 |
+
instruction_embedding, self.memory_index)[0]
|
39 |
+
top_k_idx = torch.topk(memory_scores, k=top_k)[1]
|
40 |
+
top_k_memory = [self.long_memory[idx] for idx in top_k_idx]
|
41 |
+
# combine the top 3 paragraphs
|
42 |
+
input_long_term_memory = '\n'.join(
|
43 |
+
[f"Related Paragraphs {i+1} :" + selected_memory for i, selected_memory in enumerate(top_k_memory)])
|
44 |
+
# randomly decide if a new character should be introduced
|
45 |
+
if random.random() < new_character_prob:
|
46 |
+
new_character_prompt = f"If it is reasonable, you can introduce a new character in the output paragrah and add it into the memory."
|
47 |
+
else:
|
48 |
+
new_character_prompt = ""
|
49 |
+
|
50 |
+
input_text = get_input_text(lang_opt, self.short_memory, input_paragraph, input_instruction, input_long_term_memory, new_character_prompt)
|
51 |
+
|
52 |
+
return input_text
|
53 |
+
|
54 |
+
def parse_output(self, output):
|
55 |
+
try:
|
56 |
+
output_paragraph = get_content_between_a_b(
|
57 |
+
'Output Paragraph:', 'Output Memory', output)
|
58 |
+
output_memory_updated = get_content_between_a_b(
|
59 |
+
'Updated Memory:', 'Output Instruction:', output)
|
60 |
+
self.short_memory = output_memory_updated
|
61 |
+
ins_1 = get_content_between_a_b(
|
62 |
+
'Instruction 1:', 'Instruction 2', output)
|
63 |
+
ins_2 = get_content_between_a_b(
|
64 |
+
'Instruction 2:', 'Instruction 3', output)
|
65 |
+
lines = output.splitlines()
|
66 |
+
# content of Instruction 3 may be in the same line with I3 or in the next line
|
67 |
+
if lines[-1] != '\n' and lines[-1].startswith('Instruction 3'):
|
68 |
+
ins_3 = lines[-1][len("Instruction 3:"):]
|
69 |
+
elif lines[-1] != '\n':
|
70 |
+
ins_3 = lines[-1]
|
71 |
+
|
72 |
+
output_instructions = [ins_1, ins_2, ins_3]
|
73 |
+
assert len(output_instructions) == 3
|
74 |
+
|
75 |
+
output = {
|
76 |
+
"input_paragraph": self.input["output_paragraph"],
|
77 |
+
"output_memory": output_memory_updated, # feed to human
|
78 |
+
"output_paragraph": output_paragraph,
|
79 |
+
"output_instruction": [instruction.strip() for instruction in output_instructions]
|
80 |
+
}
|
81 |
+
|
82 |
+
return output
|
83 |
+
except:
|
84 |
+
return None
|
85 |
+
|
86 |
+
def step(self, response_file=None):
|
87 |
+
|
88 |
+
prompt = self.prepare_input()
|
89 |
+
|
90 |
+
print(prompt+'\n'+'\n')
|
91 |
+
|
92 |
+
response = get_api_response(prompt)
|
93 |
+
|
94 |
+
self.output = self.parse_output(response)
|
95 |
+
while self.output == None:
|
96 |
+
response = get_api_response(prompt)
|
97 |
+
self.output = self.parse_output(response)
|
98 |
+
if response_file:
|
99 |
+
with open(response_file, 'a', encoding='utf-8') as f:
|
100 |
+
f.write(f"Writer's output here:\n{response}\n\n")
|
101 |
+
|
102 |
+
self.long_memory.append(self.input["output_paragraph"])
|
103 |
+
self.memory_index = self.embedder.encode(
|
104 |
+
self.long_memory, convert_to_tensor=True)
|
requirements.txt
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
pip install -U sentence-transformers
|
2 |
+
pip install --upgrade openai
|
3 |
+
|
4 |
+
|
5 |
+
pip install bitsandbytes==0.39.0
|
6 |
+
pip install transformers@git+https://github.com/huggingface/transformers.git
|
7 |
+
pip install peft@git+https://github.com/huggingface/peft.git
|
8 |
+
pip install accelerate@git+https://github.com/huggingface/accelerate.git
|
9 |
+
|
10 |
+
|
11 |
+
llama-cpp-python@git+https://github.com/abetlen/llama-cpp-python.git
|
12 |
+
|
13 |
+
|
14 |
+
pip install -U flagai
|
15 |
+
pip install bminf
|
16 |
+
|
17 |
+
|
18 |
+
pip install auto-gptq
|
19 |
+
pip install einops
|
utils/__init__.py
ADDED
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
import re
|
6 |
+
from global_config import lang_opt, llm_model_opt
|
7 |
+
|
8 |
+
if "openai" == llm_model_opt:
|
9 |
+
from utils.openai_util import get_api_response
|
10 |
+
elif "vicuna" == llm_model_opt:
|
11 |
+
from utils.vicuna_util import get_api_response
|
12 |
+
elif "chatglm" == llm_model_opt:
|
13 |
+
from utils.chatglm_util import get_api_response
|
14 |
+
elif "baichuan" == llm_model_opt:
|
15 |
+
from utils.baichuan_util import get_api_response
|
16 |
+
elif "aquila" == llm_model_opt:
|
17 |
+
from utils.aquila_util import get_api_response
|
18 |
+
elif "falcon" == llm_model_opt:
|
19 |
+
from utils.falcon_util import get_api_response
|
20 |
+
else:
|
21 |
+
raise Exception("not supported llm model name: {}".format(llm_model_opt))
|
22 |
+
|
23 |
+
|
24 |
+
def get_content_between_a_b(a, b, text):
|
25 |
+
if "en" == lang_opt:
|
26 |
+
if "vicuna" == llm_model_opt:
|
27 |
+
return re.search(f"{a}(.*?)\n(.*?){b}", text, re.DOTALL).group(1).strip()
|
28 |
+
elif "openai" == llm_model_opt:
|
29 |
+
return re.search(f"{a}(.*?)\n{b}", text, re.DOTALL).group(1).strip()
|
30 |
+
elif llm_model_opt in ["chatglm", "baichuan", "aquila", "falcon"]:
|
31 |
+
return re.search(f"{a}(.*?)\n(.*?){b}", text, re.DOTALL).group(1).strip()
|
32 |
+
else:
|
33 |
+
raise Exception(
|
34 |
+
"not supported llm model name: {}".format(llm_model_opt))
|
35 |
+
|
36 |
+
elif lang_opt in ["zh1", "zh2"]:
|
37 |
+
if "vicuna" == llm_model_opt:
|
38 |
+
match = re.search(f"{a}(.*?)\n(.*?){b}", text, re.DOTALL)
|
39 |
+
elif "openai" == llm_model_opt:
|
40 |
+
match = re.search(f"{a}(.*?)\n{b}", text, re.DOTALL)
|
41 |
+
elif llm_model_opt in ["chatglm", "baichuan", "aquila", "falcon"]:
|
42 |
+
match = re.search(f"{a}(.*?)\n(.*?){b}", text, re.DOTALL)
|
43 |
+
else:
|
44 |
+
raise Exception(
|
45 |
+
"not supported llm model name: {}".format(llm_model_opt))
|
46 |
+
|
47 |
+
if match:
|
48 |
+
return match.group(1).strip()
|
49 |
+
else:
|
50 |
+
if "1" in a or "2" in a or "3" in a:
|
51 |
+
a = ''.join(a.split(" "))
|
52 |
+
if "1" in b or "2" in b or "3" in b:
|
53 |
+
b = "".join(b.split(" "))
|
54 |
+
|
55 |
+
if "vicuna" == llm_model_opt:
|
56 |
+
match = re.search(f"{a}(.*?)\n(.*?){b}", text, re.DOTALL)
|
57 |
+
elif "openai" == llm_model_opt:
|
58 |
+
match = re.search(f"{a}(.*?)\n{b}", text, re.DOTALL)
|
59 |
+
elif llm_model_opt in ["chatglm", "baichuan", "aquila", "falcon"]:
|
60 |
+
match = re.search(f"{a}(.*?)\n(.*?){b}", text, re.DOTALL)
|
61 |
+
else:
|
62 |
+
raise Exception(
|
63 |
+
"not supported llm model name: {}".format(llm_model_opt))
|
64 |
+
|
65 |
+
if match:
|
66 |
+
return match.group(1).strip()
|
67 |
+
else:
|
68 |
+
# 处理找不到匹配内容的情况
|
69 |
+
return "翻译时出现错误请重试" # 或者返回其他默认值或采取其他的处理方式
|
70 |
+
else:
|
71 |
+
raise Exception(f"not supported language: {lang_opt}")
|
72 |
+
|
73 |
+
|
74 |
+
def get_init(init_text=None, text=None, response_file=None, model=None, tokenizer=None):
|
75 |
+
"""
|
76 |
+
init_text: if the title, outline, and the first 3 paragraphs are given in a .txt file, directly read
|
77 |
+
text: if no .txt file is given, use init prompt to generate
|
78 |
+
"""
|
79 |
+
if not init_text:
|
80 |
+
response = get_api_response(model, tokenizer, text)
|
81 |
+
print("response: {}".format(response))
|
82 |
+
|
83 |
+
if response_file:
|
84 |
+
with open(response_file, 'a', encoding='utf-8') as f:
|
85 |
+
f.write(f"Init output here:\n{response}\n\n")
|
86 |
+
else:
|
87 |
+
with open(init_text, 'r', encoding='utf-8') as f:
|
88 |
+
response = f.read()
|
89 |
+
f.close()
|
90 |
+
paragraphs = {
|
91 |
+
"name": "",
|
92 |
+
"Outline": "",
|
93 |
+
"Paragraph 1": "",
|
94 |
+
"Paragraph 2": "",
|
95 |
+
"Paragraph 3": "",
|
96 |
+
"Summary": "",
|
97 |
+
"Instruction 1": "",
|
98 |
+
"Instruction 2": "",
|
99 |
+
"Instruction 3": ""
|
100 |
+
}
|
101 |
+
|
102 |
+
if "en" == lang_opt:
|
103 |
+
paragraphs['name'] = get_content_between_a_b(
|
104 |
+
'Name:', 'Outline', response)
|
105 |
+
|
106 |
+
paragraphs['Paragraph 1'] = get_content_between_a_b(
|
107 |
+
'Paragraph 1:', 'Paragraph 2:', response)
|
108 |
+
paragraphs['Paragraph 2'] = get_content_between_a_b(
|
109 |
+
'Paragraph 2:', 'Paragraph 3:', response)
|
110 |
+
paragraphs['Paragraph 3'] = get_content_between_a_b(
|
111 |
+
'Paragraph 3:', 'Summary', response)
|
112 |
+
paragraphs['Summary'] = get_content_between_a_b(
|
113 |
+
'Summary:', 'Instruction 1', response)
|
114 |
+
paragraphs['Instruction 1'] = get_content_between_a_b(
|
115 |
+
'Instruction 1:', 'Instruction 2', response)
|
116 |
+
paragraphs['Instruction 2'] = get_content_between_a_b(
|
117 |
+
'Instruction 2:', 'Instruction 3', response)
|
118 |
+
lines = response.splitlines()
|
119 |
+
# content of Instruction 3 may be in the same line with I3 or in the next line
|
120 |
+
if lines[-1] != '\n' and lines[-1].startswith('Instruction 3'):
|
121 |
+
paragraphs['Instruction 3'] = lines[-1][len("Instruction 3:"):]
|
122 |
+
elif lines[-1] != '\n':
|
123 |
+
paragraphs['Instruction 3'] = lines[-1]
|
124 |
+
# Sometimes it gives Chapter outline, sometimes it doesn't
|
125 |
+
for line in lines:
|
126 |
+
if line.startswith('Chapter'):
|
127 |
+
paragraphs['Outline'] = get_content_between_a_b(
|
128 |
+
'Outline:', 'Chapter', response)
|
129 |
+
break
|
130 |
+
if paragraphs['Outline'] == '':
|
131 |
+
paragraphs['Outline'] = get_content_between_a_b(
|
132 |
+
'Outline:', 'Paragraph', response)
|
133 |
+
|
134 |
+
elif lang_opt in ["zh1", "zh2"]:
|
135 |
+
paragraphs['name'] = get_content_between_a_b('名称:', '概述:', response)
|
136 |
+
|
137 |
+
paragraphs['Paragraph 1'] = get_content_between_a_b(
|
138 |
+
'段落 1:', '段落 2:', response)
|
139 |
+
paragraphs['Paragraph 2'] = get_content_between_a_b(
|
140 |
+
'段落 2:', '段落 3:', response)
|
141 |
+
paragraphs['Paragraph 3'] = get_content_between_a_b(
|
142 |
+
'段落 3:', '总结:', response)
|
143 |
+
paragraphs['Summary'] = get_content_between_a_b(
|
144 |
+
'总结:', '指令 1', response)
|
145 |
+
paragraphs['Instruction 1'] = get_content_between_a_b(
|
146 |
+
'指令 1:', '指令 2:', response)
|
147 |
+
paragraphs['Instruction 2'] = get_content_between_a_b(
|
148 |
+
'指令 2:', '指令 3:', response)
|
149 |
+
lines = response.splitlines()
|
150 |
+
# content of Instruction 3 may be in the same line with I3 or in the next line
|
151 |
+
if lines[-1] != '\n' and lines[-1].startswith('Instruction 3'):
|
152 |
+
paragraphs['Instruction 3'] = lines[-1][len("Instruction 3:"):]
|
153 |
+
elif lines[-1] != '\n':
|
154 |
+
paragraphs['Instruction 3'] = lines[-1]
|
155 |
+
# Sometimes it gives Chapter outline, sometimes it doesn't
|
156 |
+
for line in lines:
|
157 |
+
if line.startswith('Chapter'):
|
158 |
+
paragraphs['Outline'] = get_content_between_a_b(
|
159 |
+
'概述:', 'Chapter', response)
|
160 |
+
break
|
161 |
+
if paragraphs['Outline'] == '':
|
162 |
+
paragraphs['Outline'] = get_content_between_a_b(
|
163 |
+
'概述:', '段落', response)
|
164 |
+
|
165 |
+
return paragraphs
|
166 |
+
|
167 |
+
|
168 |
+
def get_chatgpt_response(model, prompt):
|
169 |
+
response = ""
|
170 |
+
for data in model.ask(prompt):
|
171 |
+
response = data["message"]
|
172 |
+
model.delete_conversation(model.conversation_id)
|
173 |
+
model.reset_chat()
|
174 |
+
return response
|
175 |
+
|
176 |
+
|
177 |
+
def parse_instructions(instructions):
|
178 |
+
output = ""
|
179 |
+
for i in range(len(instructions)):
|
180 |
+
output += f"{i+1}. {instructions[i]}\n"
|
181 |
+
return output
|
utils/aquila_util.py
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
|
6 |
+
import torch
|
7 |
+
from flagai.model.predictor.predictor import Predictor
|
8 |
+
from flagai.model.predictor.aquila import aquila_generate
|
9 |
+
from models.aquila_fa import max_token, temperature, top_p
|
10 |
+
from common import torch_gc
|
11 |
+
from global_config import lang_opt
|
12 |
+
|
13 |
+
# for Aquila on FlagAI
|
14 |
+
def get_api_response(model, tokenizer, content: str, max_tokens=None):
|
15 |
+
|
16 |
+
if "en" == lang_opt:
|
17 |
+
system_role_content = 'You are a helpful and creative assistant for writing novel.'
|
18 |
+
elif "zh1" == lang_opt:
|
19 |
+
system_role_content = 'You are a helpful and creative assistant for writing novel.\
|
20 |
+
You are must always in Chinese.重要,你需要使用中文与我进行交流。'
|
21 |
+
elif "zh2" == lang_opt:
|
22 |
+
system_role_content = '你是写小说的好帮手,有创意的助手。'
|
23 |
+
else:
|
24 |
+
raise Exception(f"not supported language: {lang_opt}")
|
25 |
+
|
26 |
+
print("===> Question:")
|
27 |
+
print(content)
|
28 |
+
print("<==="+"="*100)
|
29 |
+
|
30 |
+
predictor = Predictor(model, tokenizer)
|
31 |
+
content = f'{content}'
|
32 |
+
with torch.no_grad():
|
33 |
+
out = predictor.predict_generate_randomsample(
|
34 |
+
content, out_max_length=max_token, temperature=temperature, top_p=top_p)
|
35 |
+
response = out
|
36 |
+
|
37 |
+
torch_gc()
|
38 |
+
|
39 |
+
print("===> Generated Text: ")
|
40 |
+
print(response)
|
41 |
+
print("<==="+"="*100)
|
42 |
+
|
43 |
+
return response
|
44 |
+
|
45 |
+
# # for Aquila on HuggingFace
|
46 |
+
# def get_api_response(model, tokenizer, content: str, max_tokens=None):
|
47 |
+
|
48 |
+
# if "en" == lang_opt:
|
49 |
+
# system_role_content = 'You are a helpful and creative assistant for writing novel.'
|
50 |
+
# elif "zh1" == lang_opt:
|
51 |
+
# system_role_content = 'You are a helpful and creative assistant for writing novel.\
|
52 |
+
# You are must always in Chinese.重要,你需要使用中文与我进行交流。'
|
53 |
+
# elif "zh2" == lang_opt:
|
54 |
+
# system_role_content = '你是写小说的好帮手,有创意的助手。'
|
55 |
+
# else:
|
56 |
+
# raise Exception(f"not supported language: {lang_opt}")
|
57 |
+
|
58 |
+
# print("===> Question:")
|
59 |
+
# print(content)
|
60 |
+
# print("<==="+"="*100)
|
61 |
+
|
62 |
+
# with torch.no_grad():
|
63 |
+
# ret = model.generate(
|
64 |
+
# **tokenizer(content, return_tensors='pt').to('cuda'),
|
65 |
+
# do_sample=False,
|
66 |
+
# max_new_tokens=max_token,
|
67 |
+
# temperature=temperature,
|
68 |
+
# top_p=top_p,
|
69 |
+
# use_cache=True
|
70 |
+
# )
|
71 |
+
# output_ids = ret[0].detach().cpu().numpy().tolist()
|
72 |
+
# if 100007 in output_ids:
|
73 |
+
# output_ids = output_ids[:output_ids.index(100007)]
|
74 |
+
# elif 0 in output_ids:
|
75 |
+
# output_ids = output_ids[:output_ids.index(0)]
|
76 |
+
# response = tokenizer.decode(output_ids)
|
77 |
+
|
78 |
+
# torch_gc()
|
79 |
+
|
80 |
+
# print("===> Generated Text: ")
|
81 |
+
# print(response)
|
82 |
+
# print("<==="+"="*100)
|
83 |
+
|
84 |
+
# return response
|
utils/baichuan_util.py
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
from transformers import TextStreamer
|
6 |
+
|
7 |
+
from models.baichuan_hf import max_token, temperature, top_p
|
8 |
+
from common import torch_gc
|
9 |
+
from global_config import lang_opt
|
10 |
+
|
11 |
+
|
12 |
+
def get_api_response(model, tokenizer, content: str, max_tokens=None):
|
13 |
+
|
14 |
+
if "en" == lang_opt:
|
15 |
+
system_role_content = 'You are a helpful and creative assistant for writing novel.'
|
16 |
+
elif "zh1" == lang_opt:
|
17 |
+
system_role_content = 'You are a helpful and creative assistant for writing novel.\
|
18 |
+
You are must always in Chinese.重要,你需要使用中文与我进行交流。'
|
19 |
+
elif "zh2" == lang_opt:
|
20 |
+
system_role_content = '你是写小说的好帮手,有创意的助手。'
|
21 |
+
else:
|
22 |
+
raise Exception(f"not supported language: {lang_opt}")
|
23 |
+
|
24 |
+
print("===> Question:")
|
25 |
+
print(content)
|
26 |
+
print("<==="+"="*100)
|
27 |
+
|
28 |
+
streamer = TextStreamer(tokenizer,
|
29 |
+
skip_prompt=True,
|
30 |
+
skip_special_tokens=True
|
31 |
+
)
|
32 |
+
|
33 |
+
# inputs = tokenizer(content, return_tensors='pt')
|
34 |
+
inputs = tokenizer("<human>:{}\n<bot>:".format(content), return_tensors='pt')
|
35 |
+
# inputs = inputs.to('cuda') # UserWarning: You are calling .generate() with the `input_ids` being on a device type different than your model's device. `input_ids` is on cuda, whereas the model is on cpu. You may experience unexpected behaviors or slower generation. Please make sure that you have put `input_ids` to the correct device by calling for example input_ids = input_ids.to('cpu') before running `.generate()`.
|
36 |
+
inputs = inputs.to('cpu')
|
37 |
+
generate_ids = model.generate(**inputs,
|
38 |
+
max_new_tokens=max_token,
|
39 |
+
top_p=top_p,
|
40 |
+
temperature=temperature,
|
41 |
+
repetition_penalty=1.1,
|
42 |
+
streamer=streamer,
|
43 |
+
)
|
44 |
+
response = tokenizer.decode(
|
45 |
+
generate_ids.cpu()[0], skip_special_tokens=True)
|
46 |
+
|
47 |
+
torch_gc()
|
48 |
+
|
49 |
+
print("===> Generated Text: ")
|
50 |
+
print(response)
|
51 |
+
print("<==="+"="*100)
|
52 |
+
|
53 |
+
return response
|
utils/chatglm_util.py
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
|
6 |
+
from models.chatglm_hf import max_token, temperature, top_p
|
7 |
+
from common import torch_gc
|
8 |
+
from global_config import lang_opt
|
9 |
+
|
10 |
+
|
11 |
+
def get_api_response(model, tokenizer, content: str, max_tokens=None):
|
12 |
+
|
13 |
+
if "en" == lang_opt:
|
14 |
+
system_role_content = 'You are a helpful and creative assistant for writing novel.'
|
15 |
+
elif "zh1" == lang_opt:
|
16 |
+
system_role_content = 'You are a helpful and creative assistant for writing novel.\
|
17 |
+
You are must always in Chinese.重要,你需要使用中文与我进行交流。'
|
18 |
+
elif "zh2" == lang_opt:
|
19 |
+
system_role_content = '你是写小说的好帮手,有创意的助手。'
|
20 |
+
else:
|
21 |
+
raise Exception(f"not supported language: {lang_opt}")
|
22 |
+
|
23 |
+
print("===> Question:")
|
24 |
+
print(content)
|
25 |
+
print("<==="+"="*100)
|
26 |
+
|
27 |
+
response, history = model.chat(
|
28 |
+
tokenizer,
|
29 |
+
content,
|
30 |
+
history=[],
|
31 |
+
max_length=max_token,
|
32 |
+
temperature=temperature,
|
33 |
+
top_p=top_p,
|
34 |
+
)
|
35 |
+
|
36 |
+
torch_gc()
|
37 |
+
|
38 |
+
print("===> Generated Text: ")
|
39 |
+
print(response)
|
40 |
+
print("<==="+"="*100)
|
41 |
+
|
42 |
+
return response
|
utils/falcon_util.py
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
from models.falcon_hf import max_token, temperature, top_p
|
6 |
+
from common import torch_gc
|
7 |
+
from global_config import lang_opt
|
8 |
+
|
9 |
+
|
10 |
+
def get_api_response(model, tokenizer, content: str, max_tokens=None):
|
11 |
+
|
12 |
+
if "en" == lang_opt:
|
13 |
+
system_role_content = 'You are a helpful and creative assistant for writing novel.'
|
14 |
+
elif "zh1" == lang_opt:
|
15 |
+
system_role_content = 'You are a helpful and creative assistant for writing novel.\
|
16 |
+
You are must always in Chinese.重要,你需要使用中文与我进行交流。'
|
17 |
+
elif "zh2" == lang_opt:
|
18 |
+
system_role_content = '你是写小说的好帮手,有创意的助手。'
|
19 |
+
else:
|
20 |
+
raise Exception(f"not supported language: {lang_opt}")
|
21 |
+
|
22 |
+
print("===> Question:")
|
23 |
+
print(content)
|
24 |
+
print("<==="+"="*100)
|
25 |
+
|
26 |
+
inputs = tokenizer(content,
|
27 |
+
return_tensors='pt',
|
28 |
+
return_token_type_ids=False, # ValueError: The following model_kwargs are not used by the model: ['token_type_ids'] (note: typos in the generate arguments will also show up in this list)
|
29 |
+
)
|
30 |
+
inputs = inputs.to('cuda:0')
|
31 |
+
output = model.generate(**inputs,
|
32 |
+
max_new_tokens=max_token,
|
33 |
+
top_p=top_p,
|
34 |
+
temperature=temperature,
|
35 |
+
repetition_penalty=1.1,
|
36 |
+
# eos_token_id=tokenizer.eos_token_id,
|
37 |
+
)
|
38 |
+
response = tokenizer.decode(output.cpu()[0], skip_special_tokens=True)
|
39 |
+
|
40 |
+
torch_gc()
|
41 |
+
|
42 |
+
print("===> Generated Text: ")
|
43 |
+
print(response)
|
44 |
+
print("<==="+"="*100)
|
45 |
+
|
46 |
+
return response
|
utils/openai_util.py
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
|
6 |
+
import openai
|
7 |
+
|
8 |
+
from global_config import lang_opt
|
9 |
+
|
10 |
+
|
11 |
+
def get_api_response(model, tokenizer, content: str, max_tokens=None):
|
12 |
+
|
13 |
+
if "en" == lang_opt:
|
14 |
+
system_role_content = 'You are a helpful and creative assistant for writing novel.'
|
15 |
+
elif "zh1" == lang_opt:
|
16 |
+
system_role_content = 'You are a helpful and creative assistant for writing novel.\
|
17 |
+
You are must always in Chinese.重要,你需要使用中文与我进行交流。'
|
18 |
+
elif "zh2" == lang_opt:
|
19 |
+
system_role_content = '你是写小说的好帮手,有创意的助手。'
|
20 |
+
else:
|
21 |
+
raise Exception(f"not supported language: {lang_opt}")
|
22 |
+
|
23 |
+
response = openai.ChatCompletion.create(
|
24 |
+
model='gpt-3.5-turbo',
|
25 |
+
messages=[{
|
26 |
+
'role': 'system',
|
27 |
+
'content': system_role_content
|
28 |
+
}, {
|
29 |
+
'role': 'user',
|
30 |
+
'content': content,
|
31 |
+
}],
|
32 |
+
temperature=0.5,
|
33 |
+
max_tokens=max_tokens
|
34 |
+
)
|
35 |
+
|
36 |
+
return response['choices'][0]['message']['content']
|
37 |
+
|
38 |
+
|
utils/vicuna_util.py
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
# @author: Kun
|
4 |
+
|
5 |
+
|
6 |
+
from models.vicuna_bin import max_token, temperature, top_p
|
7 |
+
from common import torch_gc
|
8 |
+
from global_config import lang_opt
|
9 |
+
|
10 |
+
|
11 |
+
def get_api_response(model, tokenizer, content: str, max_tokens=None):
|
12 |
+
|
13 |
+
if "en" == lang_opt:
|
14 |
+
system_role_content = 'You are a helpful and creative assistant for writing novel.'
|
15 |
+
elif "zh1" == lang_opt:
|
16 |
+
system_role_content = 'You are a helpful and creative assistant for writing novel.\
|
17 |
+
You are must always in Chinese.重要,你需要使用中文与我进行交流。'
|
18 |
+
elif "zh2" == lang_opt:
|
19 |
+
system_role_content = '你是写小说的好帮手,有创意的助手。'
|
20 |
+
else:
|
21 |
+
raise Exception(f"not supported language: {lang_opt}")
|
22 |
+
|
23 |
+
print("===> Question:")
|
24 |
+
print(content)
|
25 |
+
print("<==="+"="*100)
|
26 |
+
|
27 |
+
content = content.encode()
|
28 |
+
tokens = model.tokenize(content)
|
29 |
+
|
30 |
+
output = b""
|
31 |
+
count = 0
|
32 |
+
token_count = 10000
|
33 |
+
top_k = 40
|
34 |
+
repetition_penalty = 1.1
|
35 |
+
for token in model.generate(tokens,
|
36 |
+
top_k=top_k,
|
37 |
+
top_p=top_p,
|
38 |
+
temp=temperature,
|
39 |
+
repeat_penalty=repetition_penalty):
|
40 |
+
text = model.detokenize([token])
|
41 |
+
# print(text)
|
42 |
+
output += text
|
43 |
+
|
44 |
+
count += 1
|
45 |
+
if count >= token_count or (token == model.token_eos()):
|
46 |
+
break
|
47 |
+
|
48 |
+
response = output.decode()
|
49 |
+
# print("===> [vicuna][generate] response: {}".format(response))
|
50 |
+
|
51 |
+
torch_gc()
|
52 |
+
|
53 |
+
print("===> Generated Text: ")
|
54 |
+
print(response)
|
55 |
+
print("<==="+"="*100)
|
56 |
+
|
57 |
+
return response
|
58 |
+
|
59 |
+
|