cahya commited on
Commit
e5f4bf9
1 Parent(s): 630a323

Add first commit

Browse files
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2021 indonesian-nlp
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.
README.md CHANGED
@@ -1,37 +1,2 @@
1
- ---
2
- title: Gpt2 App
3
- emoji: 🏢
4
- colorFrom: gray
5
- colorTo: gray
6
- sdk: streamlit
7
- app_file: app.py
8
- pinned: false
9
- ---
10
-
11
- # Configuration
12
-
13
- `title`: _string_
14
- Display title for the Space
15
-
16
- `emoji`: _string_
17
- Space emoji (emoji-only character allowed)
18
-
19
- `colorFrom`: _string_
20
- Color for Thumbnail gradient (red, yellow, green, blue, indigo, purple, pink, gray)
21
-
22
- `colorTo`: _string_
23
- Color for Thumbnail gradient (red, yellow, green, blue, indigo, purple, pink, gray)
24
-
25
- `sdk`: _string_
26
- Can be either `gradio` or `streamlit`
27
-
28
- `sdk_version` : _string_
29
- Only applicable for `streamlit` SDK.
30
- See [doc](https://hf.co/docs/hub/spaces) for more info on supported versions.
31
-
32
- `app_file`: _string_
33
- Path to your main application file (which contains either `gradio` or `streamlit` Python code).
34
- Path is relative to the root of the repository.
35
-
36
- `pinned`: _boolean_
37
- Whether the Space stays on top of your list.
 
1
+ # gpt2-app
2
+ Streamlit app showing some Indonesian GPT-2 models
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/SessionState.py ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Hack to add per-session state to Streamlit.
2
+ Usage
3
+ -----
4
+ >>> import SessionState
5
+ >>>
6
+ >>> session_state = SessionState.get(user_name='', favorite_color='black')
7
+ >>> session_state.user_name
8
+ ''
9
+ >>> session_state.user_name = 'Mary'
10
+ >>> session_state.favorite_color
11
+ 'black'
12
+ Since you set user_name above, next time your script runs this will be the
13
+ result:
14
+ >>> session_state = get(user_name='', favorite_color='black')
15
+ >>> session_state.user_name
16
+ 'Mary'
17
+ """
18
+ try:
19
+ import streamlit.ReportThread as ReportThread
20
+ from streamlit.server.Server import Server
21
+ except Exception:
22
+ # Streamlit >= 0.65.0
23
+ import streamlit.report_thread as ReportThread
24
+ from streamlit.server.server import Server
25
+
26
+
27
+ class SessionState(object):
28
+ def __init__(self, **kwargs):
29
+ """A new SessionState object.
30
+ Parameters
31
+ ----------
32
+ **kwargs : any
33
+ Default values for the session state.
34
+ Example
35
+ -------
36
+ >>> session_state = SessionState(user_name='', favorite_color='black')
37
+ >>> session_state.user_name = 'Mary'
38
+ ''
39
+ >>> session_state.favorite_color
40
+ 'black'
41
+ """
42
+ for key, val in kwargs.items():
43
+ setattr(self, key, val)
44
+
45
+
46
+ def get(**kwargs):
47
+ """Gets a SessionState object for the current session.
48
+ Creates a new object if necessary.
49
+ Parameters
50
+ ----------
51
+ **kwargs : any
52
+ Default values you want to add to the session state, if we're creating a
53
+ new one.
54
+ Example
55
+ -------
56
+ >>> session_state = get(user_name='', favorite_color='black')
57
+ >>> session_state.user_name
58
+ ''
59
+ >>> session_state.user_name = 'Mary'
60
+ >>> session_state.favorite_color
61
+ 'black'
62
+ Since you set user_name above, next time your script runs this will be the
63
+ result:
64
+ >>> session_state = get(user_name='', favorite_color='black')
65
+ >>> session_state.user_name
66
+ 'Mary'
67
+ """
68
+ # Hack to get the session object from Streamlit.
69
+
70
+ ctx = ReportThread.get_report_ctx()
71
+
72
+ this_session = None
73
+
74
+ current_server = Server.get_current()
75
+ if hasattr(current_server, '_session_infos'):
76
+ # Streamlit < 0.56
77
+ session_infos = Server.get_current()._session_infos.values()
78
+ else:
79
+ session_infos = Server.get_current()._session_info_by_id.values()
80
+
81
+ for session_info in session_infos:
82
+ s = session_info.session
83
+ if (
84
+ # Streamlit < 0.54.0
85
+ (hasattr(s, '_main_dg') and s._main_dg == ctx.main_dg)
86
+ or
87
+ # Streamlit >= 0.54.0
88
+ (not hasattr(s, '_main_dg') and s.enqueue == ctx.enqueue)
89
+ or
90
+ # Streamlit >= 0.65.2
91
+ (not hasattr(s, '_main_dg') and s._uploaded_file_mgr == ctx.uploaded_file_mgr)
92
+ ):
93
+ this_session = s
94
+
95
+ if this_session is None:
96
+ raise RuntimeError(
97
+ "Oh noes. Couldn't get your Streamlit Session object. "
98
+ 'Are you doing something fancy with threads?')
99
+
100
+ # Got the session object! Now let's attach some state into it.
101
+
102
+ if not hasattr(this_session, '_custom_session_state'):
103
+ this_session._custom_session_state = SessionState(**kwargs)
104
+
105
+ return this_session._custom_session_state
106
+
107
+ __all__ = ['get']
app/__pycache__/SessionState.cpython-37.pyc ADDED
Binary file (2.93 kB). View file
 
app/__pycache__/prompts.cpython-37.pyc ADDED
Binary file (1.36 kB). View file
 
app/app.py ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import SessionState
3
+ from mtranslate import translate
4
+ from prompts import PROMPT_LIST
5
+ import random
6
+ import time
7
+ from transformers import pipeline, set_seed
8
+ import psutil
9
+ import codecs
10
+ import streamlit.components.v1 as stc
11
+ import shutil
12
+ import pathlib
13
+
14
+ # st.set_page_config(page_title="Indonesian Story Generator")
15
+
16
+ MODELS = {
17
+ "Indonesian Literature - GPT-2 Small": {
18
+ "name": "cahya/gpt2-small-indonesian-story",
19
+ "text_generator": None
20
+ },
21
+ "Indonesian Literature - GPT-2 Medium": {
22
+ "name": "cahya/gpt2-medium-indonesian-story",
23
+ "text_generator": None
24
+ },
25
+ "Indonesian Persona Chatbot": {
26
+ "name": "",
27
+ "text_generator": None
28
+ },
29
+ }
30
+
31
+
32
+ def stc_chatbot(html_file, width=700, height=900):
33
+ html = codecs.open(html_file, "r")
34
+ page = html.read()
35
+ stc.html(page, width=width, height=height, scrolling=True)
36
+
37
+
38
+ model = st.sidebar.selectbox('Model', (MODELS.keys()))
39
+
40
+
41
+ @st.cache(suppress_st_warning=True, allow_output_mutation=True)
42
+ def get_generator(model_name: str):
43
+ st.write(f"Loading the GPT2 model {model_name}, please wait...")
44
+ text_generator = pipeline('text-generation', model=model_name)
45
+ return text_generator
46
+
47
+
48
+ # Disable the st.cache for this function due to issue on newer version of streamlit
49
+ # @st.cache(suppress_st_warning=True, hash_funcs={tokenizers.Tokenizer: id})
50
+ def process(text_generator, text: str, max_length: int = 100, do_sample: bool = True, top_k: int = 50, top_p: float = 0.95,
51
+ temperature: float = 1.0, max_time: float = 60.0, seed=42):
52
+ # st.write("Cache miss: process")
53
+ set_seed(seed)
54
+ result = text_generator(text, max_length=max_length, do_sample=do_sample,
55
+ top_k=top_k, top_p=top_p, temperature=temperature,
56
+ max_time=max_time)
57
+ return result
58
+
59
+
60
+ st.title("Indonesian GPT-2 Applications")
61
+ prompt_group_name = ""
62
+ if model.find("Indonesian Literature") != -1:
63
+ st.subheader("Indonesian Literature")
64
+ prompt_group_name = "Indonesian Literature"
65
+ st.markdown(
66
+ """
67
+ This application is a demo for Indonesian Literature Generator using GPT2.
68
+ """
69
+ )
70
+ session_state = SessionState.get(prompt=None, prompt_box=None, text=None)
71
+ ALL_PROMPTS = list(PROMPT_LIST[prompt_group_name].keys())+["Custom"]
72
+
73
+ prompt = st.selectbox('Prompt', ALL_PROMPTS, index=len(ALL_PROMPTS)-1)
74
+
75
+ # Update prompt
76
+ if session_state.prompt is None:
77
+ session_state.prompt = prompt
78
+ elif session_state.prompt is not None and (prompt != session_state.prompt):
79
+ session_state.prompt = prompt
80
+ session_state.prompt_box = None
81
+ session_state.text = None
82
+ else:
83
+ session_state.prompt = prompt
84
+
85
+ # Update prompt box
86
+ if session_state.prompt == "Custom":
87
+ session_state.prompt_box = "Enter your text here"
88
+ else:
89
+ print(f"# prompt: {session_state.prompt}")
90
+ print(f"# prompt_box: {session_state.prompt_box}")
91
+ if session_state.prompt is not None and session_state.prompt_box is None:
92
+ session_state.prompt_box = random.choice(PROMPT_LIST[prompt_group_name][session_state.prompt])
93
+
94
+ session_state.text = st.text_area("Enter text", session_state.prompt_box)
95
+
96
+ max_length = st.sidebar.number_input(
97
+ "Maximum length",
98
+ value=100,
99
+ max_value=512,
100
+ help="The maximum length of the sequence to be generated."
101
+ )
102
+
103
+ temperature = st.sidebar.slider(
104
+ "Temperature",
105
+ value=1.0,
106
+ min_value=0.0,
107
+ max_value=10.0
108
+ )
109
+
110
+ do_sample = st.sidebar.checkbox(
111
+ "Use sampling",
112
+ value=True
113
+ )
114
+
115
+ top_k = 40
116
+ top_p = 0.95
117
+
118
+ if do_sample:
119
+ top_k = st.sidebar.number_input(
120
+ "Top k",
121
+ value=top_k
122
+ )
123
+ top_p = st.sidebar.number_input(
124
+ "Top p",
125
+ value=top_p
126
+ )
127
+
128
+ seed = st.sidebar.number_input(
129
+ "Random Seed",
130
+ value=25,
131
+ help="The number used to initialize a pseudorandom number generator"
132
+ )
133
+
134
+ for group_name in MODELS:
135
+ if group_name.find("Indonesian Literature") != -1:
136
+ MODELS[group_name]["text_generator"] = get_generator(MODELS[group_name]["name"])
137
+ # text_generator = get_generator()
138
+ if st.button("Run"):
139
+ with st.spinner(text="Getting results..."):
140
+ memory = psutil.virtual_memory()
141
+ st.subheader("Result")
142
+ time_start = time.time()
143
+ # text_generator = MODELS[model]["text_generator"]
144
+ result = process(MODELS[model]["text_generator"], text=session_state.text, max_length=int(max_length),
145
+ temperature=temperature, do_sample=do_sample,
146
+ top_k=int(top_k), top_p=float(top_p), seed=seed)
147
+ time_end = time.time()
148
+ time_diff = time_end-time_start
149
+ result = result[0]["generated_text"]
150
+ st.write(result.replace("\n", " \n"))
151
+ st.text("Translation")
152
+ translation = translate(result, "en", "id")
153
+ st.write(translation.replace("\n", " \n"))
154
+ # st.write(f"*do_sample: {do_sample}, top_k: {top_k}, top_p: {top_p}, seed: {seed}*")
155
+ info = f"""
156
+ *Memory: {memory.total/(1024*1024*1024):.2f}GB, used: {memory.percent}%, available: {memory.available/(1024*1024*1024):.2f}GB*
157
+ *Text generated in {time_diff:.5} seconds*
158
+ """
159
+ st.write(info)
160
+
161
+ # Reset state
162
+ session_state.prompt = None
163
+ session_state.prompt_box = None
164
+ session_state.text = None
165
+ elif model == "Indonesian Persona Chatbot":
166
+ st.subheader("Indonesian GPT-2 Persona Chatbot")
167
+ STREAMLIT_STATIC_PATH = pathlib.Path(st.__path__[0]) / 'static'
168
+ # We create a videos directory within the streamlit static asset directory
169
+ # and we write output files to it
170
+ ASSETS_PATH = STREAMLIT_STATIC_PATH/"gpt2-app"
171
+ if not ASSETS_PATH.is_dir():
172
+ ASSETS_PATH.mkdir()
173
+ shutil.copytree("app/css", ASSETS_PATH/"css")
174
+ shutil.copytree("app/js", ASSETS_PATH/"js")
175
+
176
+ stc_chatbot("app/chatbot.html")
app/chatbot.html ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <!-- Required meta tags -->
5
+ <meta charset="utf-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1">
7
+
8
+ <!-- Bootstrap CSS -->
9
+ <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
10
+
11
+ <title>Indonesian GPT2 Chatbot</title>
12
+ <link rel="stylesheet" href="gpt2-app/css/main.css">
13
+ <script src="gpt2-app/js/main.js"></script>
14
+ </head>
15
+ <body onload="pageSetup();">
16
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>
17
+
18
+ <div class="buttons" style="display: none">
19
+ <div class="minus button">-</div>
20
+ <div class="value">?</div>
21
+ <div class="plus button">+</div>
22
+ </div>
23
+ <div class="state" style="display: none">
24
+ <span class="users"></span>
25
+ </div>
26
+
27
+ <div class="container">
28
+ <div class="chat-container">
29
+ <div class="chat-messages">
30
+ <div class="messages">
31
+ </div>
32
+ </div>
33
+ </div>
34
+ <div class="chat-input input-group mb-3">
35
+ <input type="text" class="form-control user-input" placeholder="Type a message..." aria-label="User message" aria-describedby="basic-addon2">
36
+ <span class="input-group-text btn btn-primary user-input-button" id="basic-addon2">Send</span>
37
+ </div>
38
+ <!--
39
+ <div class="chat-suggestion">
40
+ Suggestion: <span class="js-loading">Loading…</span> <a class="js-suggestion hide">Kenapa kamu sedih?</a>
41
+ </div>
42
+ -->
43
+ <div class="server-message">
44
+ <span class="server-message-value"></span>
45
+ </div>
46
+ <div class="accordion" id="accordionExample">
47
+ <div class="accordion-item">
48
+ <h2 class="accordion-header" id="headingOne">
49
+ <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
50
+ Bots Personalities
51
+ </button>
52
+ </h2>
53
+ <div id="collapseOne" class="accordion-collapse collapse show" aria-labelledby="headingOne" data-bs-parent="#accordionExample">
54
+ <form class="bot-personality">
55
+ <div class="mb-3">
56
+ <div class="row g-2 align-items-center">
57
+ <div class="col-auto">
58
+ <label for="inputPersonality1" class="col-form-label">Personality 1:</label>
59
+ </div>
60
+ <div class="col-auto">
61
+ <input type="text" class="form-control" id="inputPersonality1">
62
+ </div>
63
+ </div>
64
+ <div class="row g-2 align-items-center">
65
+ <div class="col-auto">
66
+ <label for="inputPersonality2" class="col-form-label">Personality 2:</label>
67
+ </div>
68
+ <div class="col-auto">
69
+ <input type="text" class="form-control" id="inputPersonality2">
70
+ </div>
71
+ </div>
72
+ <div class="row g-2 align-items-center">
73
+ <div class="col-auto">
74
+ <label for="inputPersonality3" class="col-form-label">Personality 3:</label>
75
+ </div>
76
+ <div class="col-auto">
77
+ <input type="text" class="form-control" id="inputPersonality3">
78
+ </div>
79
+ </div>
80
+ <div class="row g-2 align-items-center">
81
+ <div class="col-auto">
82
+ <label for="inputPersonality4" class="col-form-label">Personality 4:</label>
83
+ </div>
84
+ <div class="col-auto">
85
+ <input type="text" class="form-control" id="inputPersonality4">
86
+ </div>
87
+ </div>
88
+ <div class="row g-2 align-items-center">
89
+ <div class="col-auto">
90
+ <label for="inputPersonality5" class="col-form-label">Personality 5:</label>
91
+ </div>
92
+ <div class="col-auto">
93
+ <input type="text" class="form-control" id="inputPersonality5">
94
+ </div>
95
+ </div>
96
+ </div>
97
+ <button id="updatePersonality" class="btn btn-primary" type="button" data-bs-toggle="collapse" data-bs-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample">
98
+ Update Personality
99
+ </button>
100
+ </form>
101
+ </div>
102
+ </div>
103
+ <div class="accordion-item">
104
+ <h2 class="accordion-header" id="headingThree">
105
+ <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
106
+ Parameters
107
+ </button>
108
+ </h2>
109
+ <div id="collapseThree" class="accordion-collapse collapse" aria-labelledby="headingThree" data-bs-parent="#accordionExample">
110
+
111
+ <div class="chat-parameter card card-body">
112
+ <div class="form-check">
113
+ <input class="form-check-input" type="checkbox" value="" id="doSample" checked>
114
+ <label class="form-check-label" for="doSample">
115
+ Do Sample
116
+ </label>
117
+ </div>
118
+ <label for="minLength" class="form-label">Minimal Length: <span id="minLengthValue">1</span></label>
119
+ <input type="range" class="form-range" min="1" max="10" value="1" id="minLength" onmousemove="updateValue('minLengthValue', this.value);">
120
+ <label for="maxLength" class="form-label">Maximal Length: <span id="maxLengthValue">20</span></label>
121
+ <input type="range" class="form-range" min="20" max="50" value="20" id="maxLength" onmousemove="updateValue('maxLengthValue', this.value);">
122
+ <label for="temperature" class="form-label">Temperature: <span id="temperatureValue">0.7</span></label>
123
+ <input type="range" class="form-range" min="0.5" max="10" value="0.7" step="0.1" id="temperature" onmousemove="updateValue('temperatureValue', this.value);">
124
+ <label for="topK" class="form-label">Top k: <span id="topKValue">0</span></label>
125
+ <input type="range" class="form-range" min="0" max="50" value="0" id="topK" onmousemove="updateValue('topKValue', this.value);">
126
+ <label for="topP" class="form-label">Top p: <span id="topPValue">0.9</span></label>
127
+ <input type="range" class="form-range" min="0.1" max="1.0" value="0.9" step="0.01" id="topP" onmousemove="updateValue('topPValue', this.value);">
128
+ </div>
129
+ </div>
130
+ </div>
131
+ </div>
132
+ </div>
133
+ </body>
134
+ </html>
app/css/main.css ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ font-family: "Arial, Courier New", sans-serif;
3
+ text-align: center;
4
+ }
5
+
6
+ h1 {
7
+ margin: 10px 10px;
8
+ }
9
+
10
+ .buttons {
11
+ font-size: 2em;
12
+ display: flex;
13
+ justify-content: center;
14
+ }
15
+
16
+ .button, .value {
17
+ line-height: 1;
18
+ padding: 1rem;
19
+ margin: 1rem;
20
+ border: medium solid;
21
+ min-height: 1em;
22
+ min-width: 1em;
23
+ }
24
+
25
+ .button {
26
+ cursor: pointer;
27
+ user-select: none;
28
+ }
29
+
30
+ .minus {
31
+ color: red;
32
+ }
33
+
34
+ .plus {
35
+ color: green;
36
+ }
37
+
38
+ .value {
39
+ min-width: 2em;
40
+ }
41
+
42
+ .state {
43
+ font-size: 2em;
44
+ }
45
+
46
+ .container {
47
+ min-width: 30em;
48
+ max-width: 40em;
49
+ }
50
+
51
+ .accordion-collapse {
52
+ padding: 5px 5px 0 5px;
53
+ }
54
+
55
+ .chat-container {
56
+ margin: 10px 0;
57
+ min-height: 300px;
58
+ max-height: 600px;
59
+ overflow: auto;
60
+ }
61
+
62
+ .bot-personality {
63
+ text-align: left;
64
+ margin: 0 0 5px 0;
65
+ }
66
+
67
+ .chat-parameter {
68
+ text-align: left;
69
+ margin: 5px 0 5px 0;
70
+ }
71
+
72
+ .bot-personality input {
73
+ margin: 5px 0 0 0;
74
+ min-width: 20em;
75
+ }
76
+
77
+ .message {
78
+ margin: 5px 0;
79
+ }
80
+
81
+ .message-inner {
82
+ font-size: 16px;
83
+ }
84
+
85
+ .outgoing {
86
+ text-align: right;
87
+ }
88
+
89
+ .outgoing .badge {
90
+ text-align: right;
91
+ }
92
+
93
+ .botPersonality, .incoming, .incoming .badge, .chat-suggestion, .server-message, .parameters {
94
+ text-align: left;
95
+ }
96
+
97
+ .chat-suggestion, .server-message
98
+ {
99
+ padding-left: 5px;
100
+ }
101
+
102
+ .server-message-value {
103
+ font-style: italic;
104
+ }
105
+
106
+ #collapseParameter {
107
+ width: 300px;
108
+ margin: 8px 0px;
109
+ }
app/js/main.js ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ updateValue = function(id, value) {
2
+ document.getElementById(id).innerText = value;
3
+ }
4
+
5
+ htmlToElement = function(html) {
6
+ let template = document.createElement('template');
7
+ html = html.trim(); // Never return a text node of whitespace as the result
8
+ template.innerHTML = html;
9
+ return template.content.firstChild;
10
+ }
11
+
12
+ pageSetup = function() {
13
+ const minus = document.querySelector('.minus');
14
+ const plus = document.querySelector('.plus');
15
+ const value = document.querySelector('.value');
16
+ // const users = document.querySelector('.users');
17
+ const userInput = document.querySelector('.user-input');
18
+ const userInputButton = document.querySelector('.user-input-button');
19
+ const serverMessageValue = document.querySelector('.server-message-value');
20
+ const messages = document.querySelector('.messages');
21
+ const updatePersonality = document.getElementById("updatePersonality")
22
+ const websocket = new WebSocket("wss://gpt2-chat.ai-research.id/");
23
+ //const websocket = new WebSocket("ws://localhost:8502/");
24
+
25
+ minus.onclick = function () {
26
+ websocket.send(JSON.stringify({action: 'minus'}));
27
+ }
28
+
29
+ plus.onclick = function () {
30
+ websocket.send(JSON.stringify({action: 'plus'}));
31
+ }
32
+
33
+ updatePersonality.onclick = function () {
34
+ const elements = document.querySelectorAll(".bot-personality input")
35
+ let data = {
36
+ "action": "personality",
37
+ "message": []
38
+ }
39
+ for (let i = 0; i < Math.min(elements.length, 5); i++) {
40
+ if(elements[i].value.length >0)
41
+ data.message.push(elements[i].value);
42
+ }
43
+ websocket.send(JSON.stringify(data));
44
+ }
45
+
46
+ let getParameters = function() {
47
+ return {
48
+ "do_sample": document.getElementById("doSample").checked,
49
+ "min_length": parseInt(document.getElementById("minLength").value),
50
+ "max_length": parseInt(document.getElementById("maxLength").value),
51
+ "temperature": parseFloat(document.getElementById("temperature").value),
52
+ "top_k": parseInt(document.getElementById("topK").value),
53
+ "top_p": parseFloat(document.getElementById("topP").value),
54
+ };
55
+ }
56
+
57
+ let processUserInput = function (userInput) {
58
+ let parameters = getParameters();
59
+ parameters["action"] = "talk";
60
+ parameters["utterance"] = userInput.value;
61
+ websocket.send(JSON.stringify(parameters));
62
+ const element = htmlToElement("<div class=\"message outgoing\"><div class=\"message-inner badge bg-primary text-wrap\">"
63
+ + userInput.value + "</div></div>");
64
+ userInput.value = "";
65
+ messages.appendChild(element);
66
+ messages.scrollIntoView(false)
67
+ }
68
+
69
+ userInputButton.onclick = function () {
70
+ processUserInput(userInput);
71
+ }
72
+
73
+ userInput.addEventListener("keyup", function(event) {
74
+ if (event.keyCode === 13) {
75
+ // Cancel the default action, if needed
76
+ event.preventDefault();
77
+ processUserInput(userInput);
78
+ }
79
+ });
80
+
81
+ websocket.onmessage = function (event) {
82
+ let data = JSON.parse(event.data);
83
+ switch (data.type) {
84
+ case 'connection':
85
+ console.log(data.value)
86
+ websocket.send(JSON.stringify({action: 'dialog', personality: []}));
87
+ break;
88
+ case 'state':
89
+ value.textContent = data.value;
90
+ break;
91
+ case 'users':
92
+ serverMessageValue.textContent = (
93
+ data.count.toString() + " user" +
94
+ (data.count === 1 ? "" : "s") + " online");
95
+ break;
96
+ case 'dialog':
97
+ console.log(data.message)
98
+ break;
99
+ case 'talk':
100
+ const element = htmlToElement("<div class=\"message incoming\"><div class=\"message-inner badge bg-success text-wrap\">"
101
+ + data.message+ "</div></div>");
102
+ messages.appendChild(element);
103
+ messages.scrollIntoView(false)
104
+ break;
105
+ case 'personality':
106
+ const elements = document.querySelectorAll(".bot-personality input")
107
+ for (let i = 0; i < Math.min(elements.length, data.message.length); i++) {
108
+ elements[i].value = data.message[i];
109
+ }
110
+ break;
111
+ case 'personality_reply':
112
+ serverMessageValue.textContent = data.message
113
+ setTimeout(function() {
114
+ websocket.send(JSON.stringify({action: 'get_users'}));
115
+ }, 3000);
116
+ break;
117
+ default:
118
+ console.error(
119
+ "unsupported event", data);
120
+ }
121
+ };
122
+ }
app/prompts.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ PROMPT_LIST = {
2
+ "Indonesian Literature": {
3
+ "Adult Romance": [
4
+ "Ini adalah kisah tentang seorang laki-laki yang berusaha memperjuangkan cintanya",
5
+ "Alunan musik terdengar memenuhi ruangan kantor, cowok itu duduk di balik meja kerjanya sambil memejamkan mata. Berusaha meresapi nada per nada",
6
+ "Aku mencari dan terus mencari\nDimana bahagia akan kutemui\nKumencari terus mencari\nHingga ku tak mengerti arti hari-hari",
7
+ "Gadis itu mengharuskan dirinya tegar, dan kuat dalam menghadapi masalah. Menahan air matanya jatuh setiap kali ingin menangis"
8
+ ],
9
+ "Horror": [
10
+ "Ditengah-tengah perbincangan mereka berdua, datanglah sesosok mahluk tinggi hitam dan besar",
11
+ "Sesosok hantu perempuan seperti kuntilanak yang melayang keluar dan bergerak perlahan dari pintu kamar kecil tadi yang tertutup.",
12
+ "Sejak pertemuannya dengan leak, yang ternyata tinggal satu atap dengannya, hidupnya terus dihantui oleh berbagai sosok seram."
13
+ ],
14
+ "Poetry": [
15
+ "Aku ingin menulis sajak\nyang melesat dalam kejap\nmenembus hati yang pejam\nmemaksa mimpimu terjaga\ndari semu",
16
+ "Malam ini langitku lengang\ntiada hujan yang membasuh rindu\npun awan yang biasanya temani seruput kopimu",
17
+ "Di sisimu waktu menjelma\nsetangkai kembang api\ngelora membakar tanpa jeda\nmemercik pijar binar kita."
18
+ ]
19
+ }
20
+ }
requirements.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ numpy
2
+ torch
3
+ tokenizers
4
+ transformers
5
+ datasets
6
+ mtranslate
7
+ # streamlit version 0.67.1 is needed due to issue with caching
8
+ # streamlit==0.67.1
9
+ streamlit
10
+ psutil