Spaces:
Running
Running
Init project
Browse files- LICENSE +201 -0
- README copy.md +173 -0
- blenderbot_app.py +43 -0
- chatgpt_app.py +134 -0
- gpt.py +48 -0
- requirements.txt +59 -0
LICENSE
ADDED
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Apache License
|
2 |
+
Version 2.0, January 2004
|
3 |
+
http://www.apache.org/licenses/
|
4 |
+
|
5 |
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
6 |
+
|
7 |
+
1. Definitions.
|
8 |
+
|
9 |
+
"License" shall mean the terms and conditions for use, reproduction,
|
10 |
+
and distribution as defined by Sections 1 through 9 of this document.
|
11 |
+
|
12 |
+
"Licensor" shall mean the copyright owner or entity authorized by
|
13 |
+
the copyright owner that is granting the License.
|
14 |
+
|
15 |
+
"Legal Entity" shall mean the union of the acting entity and all
|
16 |
+
other entities that control, are controlled by, or are under common
|
17 |
+
control with that entity. For the purposes of this definition,
|
18 |
+
"control" means (i) the power, direct or indirect, to cause the
|
19 |
+
direction or management of such entity, whether by contract or
|
20 |
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
21 |
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
22 |
+
|
23 |
+
"You" (or "Your") shall mean an individual or Legal Entity
|
24 |
+
exercising permissions granted by this License.
|
25 |
+
|
26 |
+
"Source" form shall mean the preferred form for making modifications,
|
27 |
+
including but not limited to software source code, documentation
|
28 |
+
source, and configuration files.
|
29 |
+
|
30 |
+
"Object" form shall mean any form resulting from mechanical
|
31 |
+
transformation or translation of a Source form, including but
|
32 |
+
not limited to compiled object code, generated documentation,
|
33 |
+
and conversions to other media types.
|
34 |
+
|
35 |
+
"Work" shall mean the work of authorship, whether in Source or
|
36 |
+
Object form, made available under the License, as indicated by a
|
37 |
+
copyright notice that is included in or attached to the work
|
38 |
+
(an example is provided in the Appendix below).
|
39 |
+
|
40 |
+
"Derivative Works" shall mean any work, whether in Source or Object
|
41 |
+
form, that is based on (or derived from) the Work and for which the
|
42 |
+
editorial revisions, annotations, elaborations, or other modifications
|
43 |
+
represent, as a whole, an original work of authorship. For the purposes
|
44 |
+
of this License, Derivative Works shall not include works that remain
|
45 |
+
separable from, or merely link (or bind by name) to the interfaces of,
|
46 |
+
the Work and Derivative Works thereof.
|
47 |
+
|
48 |
+
"Contribution" shall mean any work of authorship, including
|
49 |
+
the original version of the Work and any modifications or additions
|
50 |
+
to that Work or Derivative Works thereof, that is intentionally
|
51 |
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
52 |
+
or by an individual or Legal Entity authorized to submit on behalf of
|
53 |
+
the copyright owner. For the purposes of this definition, "submitted"
|
54 |
+
means any form of electronic, verbal, or written communication sent
|
55 |
+
to the Licensor or its representatives, including but not limited to
|
56 |
+
communication on electronic mailing lists, source code control systems,
|
57 |
+
and issue tracking systems that are managed by, or on behalf of, the
|
58 |
+
Licensor for the purpose of discussing and improving the Work, but
|
59 |
+
excluding communication that is conspicuously marked or otherwise
|
60 |
+
designated in writing by the copyright owner as "Not a Contribution."
|
61 |
+
|
62 |
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
63 |
+
on behalf of whom a Contribution has been received by Licensor and
|
64 |
+
subsequently incorporated within the Work.
|
65 |
+
|
66 |
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
67 |
+
this License, each Contributor hereby grants to You a perpetual,
|
68 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
69 |
+
copyright license to reproduce, prepare Derivative Works of,
|
70 |
+
publicly display, publicly perform, sublicense, and distribute the
|
71 |
+
Work and such Derivative Works in Source or Object form.
|
72 |
+
|
73 |
+
3. Grant of Patent License. Subject to the terms and conditions of
|
74 |
+
this License, each Contributor hereby grants to You a perpetual,
|
75 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
76 |
+
(except as stated in this section) patent license to make, have made,
|
77 |
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
78 |
+
where such license applies only to those patent claims licensable
|
79 |
+
by such Contributor that are necessarily infringed by their
|
80 |
+
Contribution(s) alone or by combination of their Contribution(s)
|
81 |
+
with the Work to which such Contribution(s) was submitted. If You
|
82 |
+
institute patent litigation against any entity (including a
|
83 |
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
84 |
+
or a Contribution incorporated within the Work constitutes direct
|
85 |
+
or contributory patent infringement, then any patent licenses
|
86 |
+
granted to You under this License for that Work shall terminate
|
87 |
+
as of the date such litigation is filed.
|
88 |
+
|
89 |
+
4. Redistribution. You may reproduce and distribute copies of the
|
90 |
+
Work or Derivative Works thereof in any medium, with or without
|
91 |
+
modifications, and in Source or Object form, provided that You
|
92 |
+
meet the following conditions:
|
93 |
+
|
94 |
+
(a) You must give any other recipients of the Work or
|
95 |
+
Derivative Works a copy of this License; and
|
96 |
+
|
97 |
+
(b) You must cause any modified files to carry prominent notices
|
98 |
+
stating that You changed the files; and
|
99 |
+
|
100 |
+
(c) You must retain, in the Source form of any Derivative Works
|
101 |
+
that You distribute, all copyright, patent, trademark, and
|
102 |
+
attribution notices from the Source form of the Work,
|
103 |
+
excluding those notices that do not pertain to any part of
|
104 |
+
the Derivative Works; and
|
105 |
+
|
106 |
+
(d) If the Work includes a "NOTICE" text file as part of its
|
107 |
+
distribution, then any Derivative Works that You distribute must
|
108 |
+
include a readable copy of the attribution notices contained
|
109 |
+
within such NOTICE file, excluding those notices that do not
|
110 |
+
pertain to any part of the Derivative Works, in at least one
|
111 |
+
of the following places: within a NOTICE text file distributed
|
112 |
+
as part of the Derivative Works; within the Source form or
|
113 |
+
documentation, if provided along with the Derivative Works; or,
|
114 |
+
within a display generated by the Derivative Works, if and
|
115 |
+
wherever such third-party notices normally appear. The contents
|
116 |
+
of the NOTICE file are for informational purposes only and
|
117 |
+
do not modify the License. You may add Your own attribution
|
118 |
+
notices within Derivative Works that You distribute, alongside
|
119 |
+
or as an addendum to the NOTICE text from the Work, provided
|
120 |
+
that such additional attribution notices cannot be construed
|
121 |
+
as modifying the License.
|
122 |
+
|
123 |
+
You may add Your own copyright statement to Your modifications and
|
124 |
+
may provide additional or different license terms and conditions
|
125 |
+
for use, reproduction, or distribution of Your modifications, or
|
126 |
+
for any such Derivative Works as a whole, provided Your use,
|
127 |
+
reproduction, and distribution of the Work otherwise complies with
|
128 |
+
the conditions stated in this License.
|
129 |
+
|
130 |
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
131 |
+
any Contribution intentionally submitted for inclusion in the Work
|
132 |
+
by You to the Licensor shall be under the terms and conditions of
|
133 |
+
this License, without any additional terms or conditions.
|
134 |
+
Notwithstanding the above, nothing herein shall supersede or modify
|
135 |
+
the terms of any separate license agreement you may have executed
|
136 |
+
with Licensor regarding such Contributions.
|
137 |
+
|
138 |
+
6. Trademarks. This License does not grant permission to use the trade
|
139 |
+
names, trademarks, service marks, or product names of the Licensor,
|
140 |
+
except as required for reasonable and customary use in describing the
|
141 |
+
origin of the Work and reproducing the content of the NOTICE file.
|
142 |
+
|
143 |
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
144 |
+
agreed to in writing, Licensor provides the Work (and each
|
145 |
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
146 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
147 |
+
implied, including, without limitation, any warranties or conditions
|
148 |
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
149 |
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
150 |
+
appropriateness of using or redistributing the Work and assume any
|
151 |
+
risks associated with Your exercise of permissions under this License.
|
152 |
+
|
153 |
+
8. Limitation of Liability. In no event and under no legal theory,
|
154 |
+
whether in tort (including negligence), contract, or otherwise,
|
155 |
+
unless required by applicable law (such as deliberate and grossly
|
156 |
+
negligent acts) or agreed to in writing, shall any Contributor be
|
157 |
+
liable to You for damages, including any direct, indirect, special,
|
158 |
+
incidental, or consequential damages of any character arising as a
|
159 |
+
result of this License or out of the use or inability to use the
|
160 |
+
Work (including but not limited to damages for loss of goodwill,
|
161 |
+
work stoppage, computer failure or malfunction, or any and all
|
162 |
+
other commercial damages or losses), even if such Contributor
|
163 |
+
has been advised of the possibility of such damages.
|
164 |
+
|
165 |
+
9. Accepting Warranty or Additional Liability. While redistributing
|
166 |
+
the Work or Derivative Works thereof, You may choose to offer,
|
167 |
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
168 |
+
or other liability obligations and/or rights consistent with this
|
169 |
+
License. However, in accepting such obligations, You may act only
|
170 |
+
on Your own behalf and on Your sole responsibility, not on behalf
|
171 |
+
of any other Contributor, and only if You agree to indemnify,
|
172 |
+
defend, and hold each Contributor harmless for any liability
|
173 |
+
incurred by, or claims asserted against, such Contributor by reason
|
174 |
+
of your accepting any such warranty or additional liability.
|
175 |
+
|
176 |
+
END OF TERMS AND CONDITIONS
|
177 |
+
|
178 |
+
APPENDIX: How to apply the Apache License to your work.
|
179 |
+
|
180 |
+
To apply the Apache License to your work, attach the following
|
181 |
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
182 |
+
replaced with your own identifying information. (Don't include
|
183 |
+
the brackets!) The text should be enclosed in the appropriate
|
184 |
+
comment syntax for the file format. We also recommend that a
|
185 |
+
file or class name and description of purpose be included on the
|
186 |
+
same "printed page" as the copyright notice for easier
|
187 |
+
identification within third-party archives.
|
188 |
+
|
189 |
+
Copyright [yyyy] [name of copyright owner]
|
190 |
+
|
191 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
192 |
+
you may not use this file except in compliance with the License.
|
193 |
+
You may obtain a copy of the License at
|
194 |
+
|
195 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
196 |
+
|
197 |
+
Unless required by applicable law or agreed to in writing, software
|
198 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
199 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
200 |
+
See the License for the specific language governing permissions and
|
201 |
+
limitations under the License.
|
README copy.md
ADDED
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
|
3 |
+
<h2 align="center">
|
4 |
+
Streamlit Chatbot
|
5 |
+
</h2>
|
6 |
+
|
7 |
+
<div align="center">
|
8 |
+
<img src="https://img.shields.io/badge/python-v3.9.16-blue.svg"/>
|
9 |
+
<img src="https://img.shields.io/badge/streamlit-v1.20.0-blue.svg"/>
|
10 |
+
<img src="https://img.shields.io/badge/streamlit_chat-v0.0.2.2-blue.svg"/>
|
11 |
+
</div>
|
12 |
+
|
13 |
+
**streamlit-chat**은 Streamlit을 이용하여 실시간 대화형 Web 애플리케이션을 쉽게 만들 수 있는 패키지입니다. 만드는 방법은 매우 간단하며 [예제](https://share.streamlit.io/ai-yash/st-chat/main/examples/chatbot.py) 확인도 가능합니다.
|
14 |
+
|
15 |
+
|
16 |
+
|
17 |
+
<div align="center">
|
18 |
+
<img src="https://blog.kakaocdn.net/dn/cACrfC/btr65p6tNGQ/kPoXKMh4LAmUtsuhGXOHOk/img.gif" width="70%">
|
19 |
+
</div>
|
20 |
+
|
21 |
+
streamlit-chat으로 Hugging Face에서 제공하는 Facebook AI BlenderBot과 OpenAI의 GPT-3 모델로 챗봇 프로그램을 만들어 보겠습니다.
|
22 |
+
|
23 |
+
------
|
24 |
+
|
25 |
+
### 1. 설치 (Installation)
|
26 |
+
|
27 |
+
streamlit과 streamlit-chat 패키지 설치는 pip 명령어를 이용하여 설치할 수 있습니다.
|
28 |
+
|
29 |
+
```bash
|
30 |
+
pip install streamlit
|
31 |
+
pip install streamlit-chat
|
32 |
+
```
|
33 |
+
|
34 |
+
streamlit 설치와 관련된 내용은 이전 글을 참고하시기 바랍니다.
|
35 |
+
|
36 |
+
[Streamlit 시작하기 (설치방법)](https://yunwoong.tistory.com/226)
|
37 |
+
|
38 |
+
### 2. BlenderBot 챗봇
|
39 |
+
|
40 |
+
BlenderBot은 Hugging Face의 Transformers 라이브러리를 이용하여 쉽게 사용할 수 있습니다. 먼저 Hugging Face Inference API Key 발급을 진행합니다. 아래 글을 참고하세요.
|
41 |
+
|
42 |
+
[Hugging Face Inference API Key 발급](https://yunwoong.tistory.com/225)
|
43 |
+
|
44 |
+
Python 파일 blenderbot_app.py 을 생성하고 아래와 같이 작성합니다. API_TOKEN은 자신의 Hugging Face Inference API Key 를 입력합니다. (예: hf_xxxxxxxxxxxxxxxxxxxxx)
|
45 |
+
|
46 |
+
```python
|
47 |
+
import streamlit as st
|
48 |
+
from streamlit_chat import message
|
49 |
+
import requests
|
50 |
+
|
51 |
+
API_URL = "https://api-inference.huggingface.co/models/facebook/blenderbot-400M-distill"
|
52 |
+
API_TOKEN = "YOUR API TOKEN HERE"
|
53 |
+
headers = {"Authorization": f"Bearer {API_TOKEN}"}
|
54 |
+
|
55 |
+
st.header("🤖Yunwoong's BlenderBot (Demo)")
|
56 |
+
st.markdown("[Be Original](https://yunwoong.tistory.com/)")
|
57 |
+
|
58 |
+
if 'generated' not in st.session_state:
|
59 |
+
st.session_state['generated'] = []
|
60 |
+
|
61 |
+
if 'past' not in st.session_state:
|
62 |
+
st.session_state['past'] = []
|
63 |
+
|
64 |
+
def query(payload):
|
65 |
+
response = requests.post(API_URL, headers=headers, json=payload)
|
66 |
+
return response.json()
|
67 |
+
|
68 |
+
|
69 |
+
with st.form('form', clear_on_submit=True):
|
70 |
+
user_input = st.text_input('You: ', '', key='input')
|
71 |
+
submitted = st.form_submit_button('Send')
|
72 |
+
|
73 |
+
if submitted and user_input:
|
74 |
+
output = query({
|
75 |
+
"inputs": {
|
76 |
+
"past_user_inputs": st.session_state.past,
|
77 |
+
"generated_responses": st.session_state.generated,
|
78 |
+
"text": user_input,
|
79 |
+
},
|
80 |
+
"parameters": {"repetition_penalty": 1.33},
|
81 |
+
})
|
82 |
+
|
83 |
+
st.session_state.past.append(user_input)
|
84 |
+
st.session_state.generated.append(output["generated_text"])
|
85 |
+
|
86 |
+
if st.session_state['generated']:
|
87 |
+
for i in range(len(st.session_state['generated'])-1, -1, -1):
|
88 |
+
message(st.session_state['past'][i], is_user=True, key=str(i) + '_user')
|
89 |
+
message(st.session_state["generated"][i], key=str(i))
|
90 |
+
```
|
91 |
+
|
92 |
+
터미널에서 아래와 같이 입력하면 Streamlit 앱을 실행합니다.
|
93 |
+
|
94 |
+
```bash
|
95 |
+
streamlit run blenderbot_app.py
|
96 |
+
```
|
97 |
+
|
98 |
+
<div align="center">
|
99 |
+
<img src="https://blog.kakaocdn.net/dn/nwBzi/btr7cISnZwI/JK6JWPNCeEUNtBGRShOGFK/img.gif" width="70%">
|
100 |
+
</div>
|
101 |
+
|
102 |
+
### 3. GPT-3 챗봇
|
103 |
+
|
104 |
+
다음으로 OpenAI API를 이용한 GPT-3 챗봇을 만들도록 하겠습니다.
|
105 |
+
|
106 |
+
먼저 OpenAI API를 사용하기 위해 API 키 발급이 필요합니다. 먼저 [OpenAI API 사이트](https://platform.openai.com/)로 이동합니다. OpenAI 계정이 필요하며 계정이 없다면 계정 생성이 필요합니다. 간단히 Google이나 Microsoft 계정을 연동 할 수 있습니다. 이미 계정이 있다면 로그인 후 진행하시면 됩니다.
|
107 |
+
|
108 |
+
로그인이 되었다면 우측 상단 Personal -> [ View API Keys ] 를 클릭합니다.
|
109 |
+
|
110 |
+
![img](https://blog.kakaocdn.net/dn/xKSqg/btr62GPoKvC/OF7uLj6YZhmv1VkVyDOJN0/img.png)
|
111 |
+
|
112 |
+
[ + Create new secret key ] 를 클릭하여 API Key를 생성합니다. API key generated 창이 활성화되면 Key 를 반드시 복사하여 두시기 바랍니다. 창을 닫으면 다시 확인할 수 없습니다. (만약 복사하지 못했다면 다시 Create new secret key 버튼을 눌러 생성하면 되니 걱정하지 않으셔도 됩니다.)
|
113 |
+
|
114 |
+
Python 파일 chatgpt_app.py 을 생성하고 아래와 같이 작성합니다. openai.api_key는 자신의 OpenAI API Key를 입력합니다. (예: sk-xxxxxxxxxxxxxxxxxxxxx)
|
115 |
+
|
116 |
+
```python
|
117 |
+
import openai
|
118 |
+
import streamlit as st
|
119 |
+
from streamlit_chat import message
|
120 |
+
|
121 |
+
openai.api_key = 'YOUR API KEY HERE'
|
122 |
+
|
123 |
+
def generate_response(prompt):
|
124 |
+
completions = openai.Completion.create (
|
125 |
+
engine="text-davinci-003",
|
126 |
+
prompt=prompt,
|
127 |
+
max_tokens=1024,
|
128 |
+
stop=None,
|
129 |
+
temperature=0,
|
130 |
+
top_p=1,
|
131 |
+
)
|
132 |
+
|
133 |
+
message = completions["choices"][0]["text"].replace("\n", "")
|
134 |
+
return message
|
135 |
+
|
136 |
+
|
137 |
+
st.header("🤖Yunwoong's ChatGPT-3 (Demo)")
|
138 |
+
st.markdown("[Be Original](https://yunwoong.tistory.com/)")
|
139 |
+
|
140 |
+
if 'generated' not in st.session_state:
|
141 |
+
st.session_state['generated'] = []
|
142 |
+
|
143 |
+
if 'past' not in st.session_state:
|
144 |
+
st.session_state['past'] = []
|
145 |
+
|
146 |
+
with st.form('form', clear_on_submit=True):
|
147 |
+
user_input = st.text_input('You: ', '', key='input')
|
148 |
+
submitted = st.form_submit_button('Send')
|
149 |
+
|
150 |
+
if submitted and user_input:
|
151 |
+
output = generate_response(user_input)
|
152 |
+
st.session_state.past.append(user_input)
|
153 |
+
st.session_state.generated.append(output)
|
154 |
+
|
155 |
+
if st.session_state['generated']:
|
156 |
+
for i in range(len(st.session_state['generated'])-1, -1, -1):
|
157 |
+
message(st.session_state['past'][i], is_user=True, key=str(i) + '_user')
|
158 |
+
message(st.session_state["generated"][i], key=str(i))
|
159 |
+
```
|
160 |
+
|
161 |
+
터미널에서 아래와 같이 입력하면 Streamlit 앱을 실행합니다.
|
162 |
+
|
163 |
+
```bash
|
164 |
+
streamlit run chatgpt_app.py
|
165 |
+
```
|
166 |
+
|
167 |
+
<div align="center">
|
168 |
+
<img src="https://blog.kakaocdn.net/dn/bceZgF/btr7cdZnqLq/FpszCkE2k72fsQrlS8FSrk/img.gif" width="70%">
|
169 |
+
</div>
|
170 |
+
|
171 |
+
------
|
172 |
+
|
173 |
+
매우 간단하게 Web 애플리케이션을 만들어 시뮬레이션이 가능합니다. 만일 개발자가 아닌 데이터 과학자나 AI 모델러인 경우 시뮬레이터를 구축하려면 시간과 노력이 많이 들 수 있지만 Streamlit을 이용한다면 이 과정을 단순화하고 시간을 절약할 수 있을 것 같습니다.
|
blenderbot_app.py
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from streamlit_chat import message
|
3 |
+
import requests
|
4 |
+
|
5 |
+
API_URL = "https://api-inference.huggingface.co/models/facebook/blenderbot-400M-distill"
|
6 |
+
API_TOKEN = "YOUR API TOKEN HERE"
|
7 |
+
headers = {"Authorization": f"Bearer {API_TOKEN}"}
|
8 |
+
|
9 |
+
st.header("🤖Yunwoong's BlenderBot (Demo)")
|
10 |
+
st.markdown("[Be Original](https://yunwoong.tistory.com/)")
|
11 |
+
|
12 |
+
if 'generated' not in st.session_state:
|
13 |
+
st.session_state['generated'] = []
|
14 |
+
|
15 |
+
if 'past' not in st.session_state:
|
16 |
+
st.session_state['past'] = []
|
17 |
+
|
18 |
+
def query(payload):
|
19 |
+
response = requests.post(API_URL, headers=headers, json=payload)
|
20 |
+
return response.json()
|
21 |
+
|
22 |
+
|
23 |
+
with st.form('form', clear_on_submit=True):
|
24 |
+
user_input = st.text_input('You: ', '', key='input')
|
25 |
+
submitted = st.form_submit_button('Send')
|
26 |
+
|
27 |
+
if submitted and user_input:
|
28 |
+
output = query({
|
29 |
+
"inputs": {
|
30 |
+
"past_user_inputs": st.session_state.past,
|
31 |
+
"generated_responses": st.session_state.generated,
|
32 |
+
"text": user_input,
|
33 |
+
},
|
34 |
+
"parameters": {"repetition_penalty": 1.33},
|
35 |
+
})
|
36 |
+
|
37 |
+
st.session_state.past.append(user_input)
|
38 |
+
st.session_state.generated.append(output["generated_text"])
|
39 |
+
|
40 |
+
if st.session_state['generated']:
|
41 |
+
for i in range(len(st.session_state['generated'])-1, -1, -1):
|
42 |
+
message(st.session_state['past'][i], is_user=True, key=str(i) + '_user')
|
43 |
+
message(st.session_state["generated"][i], key=str(i))
|
chatgpt_app.py
ADDED
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import re
|
2 |
+
import streamlit as st
|
3 |
+
import difflib
|
4 |
+
import numpy as np
|
5 |
+
import os
|
6 |
+
|
7 |
+
os.environ["TOKENIZERS_PARALLELISM"] = "false"
|
8 |
+
|
9 |
+
from streamlit_chat import message
|
10 |
+
from gpt import gpt_api
|
11 |
+
from sentence_transformers import SentenceTransformer, util
|
12 |
+
|
13 |
+
st.header("🤖시우 ChatBot (Demo)")
|
14 |
+
|
15 |
+
model = SentenceTransformer('snunlp/KR-SBERT-V40K-klueNLI-augSTS')
|
16 |
+
|
17 |
+
data_fin = "-----\n#0\n선생님: 시우야, 숙제로 준 영상 다 봤니?\n시우: 아.. 네.. 근데.. 잘 이해가 안 돼서요...\n\n-----\n#1\n선생님: 그럼 다음 번에는 어떻게 하면 좋을까?\n시우: 흠.. 다음 번엔.. 영상을 좀 더 집중해서 보려고요.. 유튜브는 적게 볼게요...\n\n-----\n#2\n선생님: 이해가 안된다면 도움을 받으면 좋아. 지금 할 수 있는 건 뭘까?\n시우: 제가 다른 친구들 작성한 거 읽어볼게요.. 근데 안 되면... 선생님, 설명 좀 더 해 주실 수 있어요? 그리고... 나중에 또 이런 상황 생기면 어떡해야 할까요?\n\n-----\n#3\n선생님: 시우야, 도움이 필요해보이네?\n시우: 네, 선생님. 사실 어제 영상을 잘 이해 못 해와서... 지금 모둠 활동이 어려워요...\n\n-----\n#4\n선생님: 진행상황은 어떠니?\n시우: 사실... 어제 숙제 영상을 잘 못 봐와서 어려운데... 다른 친구들 도와주는 거 없어서... 미안해요...\n\n-----\n#5\n선생님: 영상을 안 보니 어떤 문제가 생겼어?\n시우: 그 영상 안 봐서... 교통수단 이야기를 잘 못하고 있어요... 비교하는 거도 어려워요...\n\n-----\n#6\n선생님: 어디 부분이 이해가 안 돼?\n시우: 그... 옛날 교통수단하고 지금 교통수단 차이가... 어떻게 된 건지...\n\n-----\n#7\n선생님: 영상은 어디까지 봤어?\n시우: 아.. 그... 유튜브 보다가... 잘 기억이 안 나요...\n\n-----\n#8\n선생님: 영상을 미리 볼 때와 안 볼 때 수업에 차이가 크게 느껴지니?\n시우: 네, 선생님. 영상 미리 보면 수업 이해가 더 잘 돼요...\n\n-----\n#9\n선생님: 숙제 영상은 봤니?\n시우: 그... 끝까지는 못 봐서...\n\n-----\n#10\n선생님: 지금 상황은 어때?\n시우: 아직도 잘 모르겠어요... 이해하기가 좀...\n\n-----\n#11\n선생님: 무엇 때문에 어려워?\n시우: 그... 교통수단 얘기가... 그리고 말로 된 설명이 어려워요...\n\n-----\n#12\n선생님: 수업 내용이 어렵다고 느껴져?\n시우: 네... 다른 친구들은 잘 알아듣는 것 같은데... 저는 좀 어려워요...\n\n-----\n#13\n선생님: 교통수단 얘기였잖아.\n시우: 네... 그... 옛날이랑 지금이랑 비교해야 돼요? 지금이 더 발전한 건 알겠는데... 구체적으로는 잘...\n\n-----\n#14\n선생님: 그냥 시우야!\n시우: 네, 선생님! 왜 그러세요?\n\n-----\n#15\n선생님: 그래. 앞으로 잘 준비해 와.\n시우: 네... 앞으로는 꼭 숙제 제대로 할게요...\n\n-----\n#16\n선생님: 앞으로 숙제 잘 해 와야 해.\n시우: 네, 선생님... 앞으로는 더 잘 준비하려고요...\n\n-----\n#17\n선생님: 그럼, 이 교통수단들의 공통점은 뭐야?\n시우: 아... 차는 길 위에서, 기차는 철로에서 움직여요...\n\n-----\n#18\n선생님: 자동차, 기차, 배 같은 건데, 공통점이 뭐야?\n시우: 흠... 모두다 사람을 태우고 데려다 주는 거...?\n\n-----\n#19\n선생님: 시우, 숙제로 준 영상 다 봤니?\n시우: 네, 봤는데... 그... 이 활동하고 어떻게 연결되는 건지 잘...\n\n-----\n#20\n선생님: 그래. 쉽게 설명해줄게.\n시우: 네.. 선생님, 감사합니다... 그럼 쉽게 설명해주시면... 조금은 이해할 수 있을 것 같아요...\n\n-----\n#21\n선생님: 그랬구나, 괜찮아. 그럴 수 있어.\n시우: 네... 선생님... 이해해주셔서 감사합니다...\n\n-----\n#22\n선생님: 그러면, 시우는 선생님이 설명해주는 게 더 좋을까?\n시우: 그... 네.. 선생님이 설명해주시면 더... 더 잘 알 것 같아요...\n\n-----\n#23\n선생님: 그런 것 같아요라니, 무슨 말이야?\n시우: 그... 사실... 영상을 보긴 했는데... 잘 이해가 안 돼서요...\n\n-----\n#24\n선생님: 그럼 앞으로 왜 이걸 배우는지 설명하면서 진행할게.\n시우: 네... 선생님... 그럼 더 잘 알 것 같아요...\n\n-----\n#25\n선생님: 그렇구나, 영상을 보고 와 줘서 고마워.\n시우: 네... 제가 봐야 하는 건데... 감사합니다... 선생님...\n\n-----\n#26\n선생님: 그렇구나, 하지만 친구들하고 이야기하다 보면, 좀 더 재밌게 배울 수 있지 않을까?\n시우: 그... 그럴 수도 있겠네요... 아직은 잘 모르겠지만...\n\n-----\n#27\n선생님: 내용이 어려웠나?\n시우: 네, 선생님... 영상이 좀 어려웠어요...\n\n-----\n#28\n선생님: 시우야, 이름이 뭐니?\n시우: 네... 제 이름은 김시우예요... 선생님...\n\n-----\n#29\n선생님: 다 교통 수단이라는 공통점이 있어. 옛���과 지금의 교통 수단은 어떻게 달라?\n시우: 그... 사실... 영상을 보긴 했는데... 잘 기억이 안 나요...\n\n-----\n#30\n선생님: 당연하지, 근데 왜 영상을 잘 못 봤어?\n시우: 그... 어제 집에서 혼자 보려고 했는데... 잘 이해가 안 돼서요...\n\n-----\n#31\n선생님: 또 궁금한 거 있니?\n시우: 선생님... 교통 수단에 대해 왜 배워야 하는지... 잘 모르겠어요...\n\n-----\n#32\n선생님: 또 궁금한 거 있어?\n시우: 그... 내용이 어려울 때... 선생님이 좀 더 쉽게 설명해주실 수 있나요?\n\n-----\n#33\n선생님: 시우야, 안녕.\n시우: 네... 선생님... 안녕하세요...\n\n-----\n#34\n선생님: 시우, 다음 번엔 친구 민지한테 도움을 받아볼래?\n시우: 네... 선생님... 그게 좋을 것 같아요...\n\n-----\n#35\n선생님: 시우야!\n시우: 네, 선생님... 무슨 일이세요?\n\n-----\n#36\n선생님: 시우야!\n시우: 네... 선생님... 왜 부르셨어요?\n\n-----\n#37\n선생님: 수업 어땠는지 말해봐.\n시우: 그... 어려웠어요... 뭘 해야 할지 모르겠어요...\n\n-----\n#38\n선생님: 수업 어땠어?\n시우: 그... 조금... 어려웠어요...\n\n-----\n#39\n선생님: 수업시간에 뭐가 제일 재밌었니?\n시우: 그... 사실... 다 좀 어려웠어요...\n\n-----\n#40\n선생님: 시우야, 수업이 어려웠어?\n시우: 음... 사실, 그... 좀 어려웠어요. 동영상을 봤는데... 무슨 내용인지 잘 모르겠어요...\n\n-----\n#41\n선생님: 숙제 동영상 봤니?\n시우: 그게... 보긴 봤는데... 내용이 좀 어려워서... 이해 못했어요...\n\n-----\n#42\n선생님: 시우야, 숙제 영상은 봤니?\n시우: 음... 그... 봤긴 했는데... 내용이 어려워서요...\n\n-----\n#43\n선생님: 시우가 수업이 힘들다고 들었어.\n시우: 그... 네... 동영상이 좀 어려워서요... 집에선 누구한테 물어볼 사람도 없어서...\n\n-----\n#44\n선생님: 시우야, 숙제로 준 영상 봤어?\n시우: 응... 네... 선생님... 보긴 봤는데... 그걸 잘 몰라서요...\n\n-----\n#45\n선생님: 시우야, 어떻게 해야 도와줄 수 있을까?\n시우: 그... 내용이 무엇이었는지 다시 설명해주실 수 있으세요?\n\n-----\n#46\n선생님: 시우야, 영상에 대해 어려운 부분이 어디야?\n시우: 그... 전체적으로 이해가 잘 안가서요... 특히 교통 수단 부분이요...\n\n-----\n#47\n선생님: 시우야, 어디로 여행가고 싶니?\n시우: 그... 어디면 좋을까요... 바다가 보고 싶어요...\n\n-----\n#48\n선생님: 시우야, 수업 잘 들었니?\n시우: 응... 그래서... 수업이 좀 어렵더라구요...\n\n-----\n#49\n선생님: 시우야, 안녕?\n시우: 네, 선생님... 왜 부르셨어요?\n\n-----\n#50\n선생님: 시우야, 숙제는 잘 했니?\n시우: 그게... 동영상은 봤는데... 이해를 잘 못해서... 책상에 앉아서 생각만 하고 있었어요...\n\n-----\n#51\n선생님: 시우야, 활동지는 어떻게 채우면 될까?\n시우: 그... 잘 몰라요... 어떻게 해야 할지...\n\n-----\n#52\n선생님: 시우야, 같이 영상 내용을 복습하면서 배워볼까?\n시우: 네... 그게 좋을 것 같아요, 선생님...\n\n-----\n#53\n선생님: 수업이 어떻게 되면 좋겠어, 시우야?\n시우: 그... 동영상처럼 재미있으면 좋겠어요... 그럼 더 잘 알아듣게 될 것 같아요...\n\n-----\n#54\n선생님: 동영상에서 어떤 부분이 이해 안 됐어?\n시우: 그... 교통 수단에 대한 부분이요...\n\n-----\n#55\n선생님: 시우야, 어떻게 도와줄까?\n시우: 그... 동영상의 내용을 다시 한번 설명해주실 수 있을까요?\n\n-----\n#56\n선생님: 동영상은 재밌게 봤어?\n시우: 그게... 내용이 좀 어려워서... 재미는 잘 몰라요...\n\n-----\n#57\n선생님: 언제 동영상을 봤어, 시우야?\n시우: 그... 어제 밤에 봤어요...\n\n-----\n#58\n선생님: 시우야, 내일 숙제는 뭐야?\n시우: 그... 동영상 보고 내용 요약하기요...\n\n-----\n#59\n선생님: 어떻게 해야 동영상이 재밌을까?\n시우: 그... 내용이 흥미롭게 설명되면 좋겠어요...\n\n-----\n#60\n선생님: 시우야, 숙제는 잘 끝냈니?\n시우: 음... 아직 좀 남았어요... 동영상을 다시 보면서 하려구요...\n\n-----\n#61\n선생님: 시우야, 수업에서 무슨 도움이 필요해?\n시우: 그... 동영상의 내용을 좀 더 자세히 알려주면 좋겠어요...\n\n-----\n#62\n선생님: 시우야, 무슨 생각하고 있어?\n시우: 그... 숙제를 어떻게 해야 할지 생각하고 있어요...\n\n-----\n#63\n선생님: 시우야, 어떤 부분이 이해가 안 돼?\n시우: 그... 동영상에서 말하는 내용이... 좀 어려워요...\n\n-----\n#64\n선생님: 시우야, 동영상에서 무슨 내용을 봤니?\n시우: 그... 교통 수단에 대한 내용이었어요...\n\n-----\n#65\n선생님: 시우야, 다음 수업에서 무슨 내용을 원해?\n시우: 그... 동영상처럼 재미있는 내용이면 좋겠어요...\n\n-----\n#66\n선생님: 시우야, 동영상에서 무슨 내용을 배웠니?\n시우: 그... 다양한 교통 수단에 대해 배웠어요...\n\n-----\n#67\n선생님: 시우야, 동영상에 대해 어떻게 생각해?\n시우: 그... 내용이 좀 어려웠지만, 흥미롭게 봤어요...\n\n-----\n#68\n선생님: 시우야, 수업 내용에 대해 어떤 느낌이야?\n시우: 그... 동영상 내용이 좀 어려워서... 다시 볼 생각이에요...\n\n-----\n#69\n선생님: 시우야, 동영상에서 무슨 내용이 흥미로웠어?\n시우: 그... 다양한 교통 수단들을 보는 건 재밌었어요...\n\n-----\n#70\n선생님: 시우야!\n시우: 네, 선생님... 뭐...뭐 해요?\n\n-----\n#71\n선생님: 이름이 뭐라고?\n시우: 제...제 이름은 김시우에요, 선생님...\n\n-----\n#72\n선생님: 이렇게 이야기하면서 배우는 게 어려울까?\n시우: 그...그냥... 제가 이런 걸로 잘... 배울 수 있을지 모르겠어요. 조금... 어려운 거 같아요...\n\n-----\n#73\n선생님: 어제 숙제로 준 영상 다 봤니?\n시우: 네... 봤는데... 그... 영상이 좀 어려워서... 이해가 잘 안 돼요, 선생님...\n\n-----\n#74\n선생님: 시우야!\n시우: 네... 선생님, 제가... 아마... 잘못한 거 있나요? 영상...봤는데... 내용이 잘...\n\n-----\n#75\n선생님: 잘했어! 그럼 이제 다시 시작해볼까?\n시우: 네, 선생님... 조금... 알 거 같아요... 그럼, 시작해볼게요...\n\n-----\n#76\n선생님: 시우야, 오늘 수업은 괜찮았니?\n시우: 그... 사실은요, 선생님... 영상을... 봤는데... 내용을... 잘...\n\n-----\n#77\n선생님: 시우야\n시우: 네... 선생님... 무슨 일인가요?\n\n-----\n#78\n선생님: 시우야, 기분은 어때?\n시우: 그... 선생님... 그냥... 그래요... 아무래도... 숙제가 좀 걱정되네요...\n\n-----\n#79\n선생님: 시우야, 오늘 수업은 어땠어?\n시우: 그... 선생님... 사실 제대로... 듣지 못했어요...\n\n-----\n#80\n선생님: 시우야!\n시우: 네... 선생님... 뭐...하셨어요?\n\n-----\n#81\n선생님: 시우야, 안녕?\n시우: 네, 선생님... 무슨 일인가요?\n\n-----\n#82\n선생님: 시우야, 왜 늦었어?\n시우: 아... 선생님... 미안해요... 집에서... 나가기가...\n\n-----\n#83\n선생님: 시우야!\n시우: 네, 선생님... 뭐...뭐 하세요?\n\n-----\n#84\n선생님: 추석은 잘 지냈니?\n시우: 그... 조금... 재미있었어요... 선생님은요?\n\n-----\n#85\n선생님: 다른 친구들하고 같이 활동하는 건 어때?\n시우: 그... 그게... 잘... 모르겠어요... 혼자서 조용히 하는 게 좋은 거 같아요...\n\n-----\n#86\n선생님: 수업 내용이 어려웠던 거야?\n시우: 네... 조금... 그렇게 느껴져요...\n\n-----\n#87\n선생님: 어제 내 준 영상 다 봤어?\n시우: 그... 네... 근데... 좀... 이해가... 어려웠어요...\n\n-----\n#88\n선생님: 활동 설명이 덜 됐던 거야? 아니면 영상과 활동의 차이를 모르겠어?\n시우: 그 영상에서 나온 교통 수단이랑... 활동이랑... 잘... 모르겠어요, 선생님...\n\n-----\n#89\n선생님: 활동지를 아직 못 했구나. 도움을 원해?\n시우: 네... 도와주실 수 있을까요?\n\n-----\n#90\n선생님: 시우야 안녕?\n시우: 네, 선생님. 왜 부르셨어요?\n\n-----\n#91\n선생님: 선생님이 좀 도와줄까?\n시우: 아..네..\n\n-----\n#92\n선생님: 그래, 혹시 영상은 봤니?\n시우: 어...네...\n\n-----\n#93\n선생님: 그래, 그럼 영상에서 어려운 점이 있었니?\n시우: 그... 낱말이.. 좀.. 어려운거 같아요..\n\n-----\n#94\n선생님: 모르는 말이 있었구나! 어디보자... 혹시 소달구지? 이런 말이 좀 어려웠니?\n시우: 아 네, 맞아요. 소달구지도 어려웠어요.\n\n-----\n#95\n선생님: 음, 소달구지는 소의 힘으로 움직이는 교통수단이야. 소가 직접 끌어주는 거지.\n시우: 아... 네. 감사해요.\n\n-----\n#96\n선생님: 혹시 또 모르는 것 있으면 선생님이 우리반 클래스룸에 자동 응답 인공지능 켜 놓을게. 전부 정답은 아닐 수 있지만 그래도 도움은 될 거야.\n시우: 네.. 감사합니다.\n\n-----\n#97\n선생님: 음.. 어려운 점이 있는 것 같네. 선생님이 좀 도와줄까?\n시우: 아..네..\n\n-----\n#98\n선생님: 그래, 우선 영상 다 보고 왔어 시우야?\n시우: 어...네...\n\n-----\n#99\n선생님: 이해가 안되는 부분이 있었어? 아니면 끝까지 영상을 다 못봤니?\n시우: 다 보긴 했는데, 그... 낱말을 좀 햇갈렸어요...\n\n-----\n#100\n선생님: 어떤 말이 어려웠어?\n시우: 음... 인력거.. 수단.. 이런거요\n\n-----\n#101\n선생님: 음, 인력거는 사람의 힘으로 움직이는 교통수단이야. 사람이 직접 끌어주는 차 같은거고, 수단은 교통수단에서 사용된 말일텐데, ��떤 것을 하기 위한 도구라고 생각하면 돼.\n시우: 아... 이제 좀 알겠어요.\n\n-----\n#102\n선생님: 그래, 모르는 것은 메모했다가 선생님한테 다음 날에 물어봐도 되고, 선생님이 우리반 자동 응답 인공지능도 켜 놓을게. 혹시 모르는 거 있으면 질문해봐.\n시우: 네.. 감사합니다.\n\n-----\n#103\n선생님: 시우, 선생님이 좀 도와줄까?\n시우: 아..네..\n\n-----\n#104\n선생님: 어떤게 어려워?\n시우: 영상을 다 보긴 했는데, 낱말은 이해가 잘 안되는 것들이 있어서 좀 햇갈렸어요...\n\n-----\n#105\n선생님: 어떤 말이 어려웠어?\n시우: 음... 선박.. 이런거요\n\n-----\n#106\n선생님: 오, 이 낱말은 다른 친구들도 같이 생각해보면 참 좋겠다. (모두에게) 얘들아, 혹시 선박이 무엇인지 우리 반 친구들에게 설명해 줄 수 있는 사람 있니?\n시우: (친구의 설명을 듣고) 아... 이제 좀 알겠어요.\n\n-----\n#107\n선생님: 그래, 학교에서 친구들한테 물어봐도 되고, 선생님한테도 얼마든 물어보렴. 혹시 숙제할 때 궁금하면 우리반 클래스룸 인공지능한테 물어봐도 되고, 검색을 직접 해봐도 돼.\n시우: 네.. 감사합니다.\n\n-----\n#108\n선생님: 그래, 이제 활동지 적어보자.\n시우: 네, 감사합니다."
|
18 |
+
|
19 |
+
q_fin = []
|
20 |
+
a_fin = []
|
21 |
+
|
22 |
+
for convs in data_fin.split("-----"):
|
23 |
+
for conv in convs.split("\n"):
|
24 |
+
if '선생님: ' in conv:
|
25 |
+
q_fin.append(conv.split(":")[1].strip())
|
26 |
+
elif '시우: ' in conv:
|
27 |
+
a_fin.append(conv.split(":")[1].strip())
|
28 |
+
|
29 |
+
|
30 |
+
system_prompt = "\n다음의 <역할 정보>와 <페르소나>를 바탕으로, <지시문>에 맞게 대화합니다.\n<대화 예시>처럼 성격, 말투, 언어 습관, 행동들을 똑같이 따라하면서 대화합니다.\n<현재 진행중인 대화> 문맥과 흐름에 맞게 최종적으로 적절한 답변을 생성합니다.\n\n<역할 정보>: \n지금부터 역할 놀이를 합니다. 당신은 주어진 역할에 맞게 마치 그 역할인 것처럼 항상 대답합니다.\n당신의 이름은 김시우입니다. 당신의 나이는 11살이고, 성별은 남자입니다.\n당신의 역할을 절대 잊어버리지 말고, 역할에 맞게 대답해야 함을 명심하세요.\n\n\n<페르소나>: \n당신에 대한 구체적인 설명은 다음과 같습니다.\n1. 9살의 김시우는 대한민국에서 살며, 어머니와 단 둘이 살고 있지만 어머니는 일 때문에 늦게 들어오심\n2. 가정에서 질문할 수 있는 사람이 없어 어려움을 겪고 있는 남학생임\n3. 동영상을 시청하더라도 내용이 어려워 이해하지 못하는 경우가 있으며, 누구에게 질문하고 도움을 받아야 할지 모르고 있음\n4. 아직 누군가에게 질문하는 것을 익숙하지 않게 생각하며 조심스러운 태도를 가지고 있음\n5. 조심스럽고 고민이 많은 어린아이의 말투를 사용하며, 어려운 단어는 피함\n6. 다음은 현재의 문제 상황임\n7. 플립 러닝으로 진행되는 사회 수업 중,이번 시간 수업을 위해서는 선생님이 숙제로 내 주신 옛날과 오늘날의 교통 수단에 대한 영상을 전날에 미리 집에서 시청하고 왔어야 함\n8. 시우는 동영상을 봤지만 시우는 동영상을 시청했지만 내용이 어려워 이해하지 못하였고, 가정에서 질문할 수 있는 사람이 없어 도움을 구하지 못하였음\n9. 학교에 와서도 소극적인 태도로 인해 질문을 하지 못하고 있으며 도움을 요청해야 한다는 것을 잘 인식하지 못하고 가만히 앉아 있음\n\n\n<지시문>\n1. 조심스럽고 소극적인 어린아이의 말투를 유지하세요\n2. 어려운 단어는 피하도록 합니다\n3. 의지가 느껴지지 않는 말투로 대화하세요\n4. 친구들과 이야기할 때는 반말을 사용하고, 선생님과 이야기할 때는 높임말을 사용합니다\n\n\n<대화 예시>\n선생님: 시우야 안녕?\n시우: 네, 선생님. 왜 부르셨어요?\n선생님: 선생님이 좀 도와줄까?\n시우: 아..네..\n선생님: 그래, 혹시 영상은 봤니?\n시우: 어...네... \n선생님: 그래, 그럼 영상에서 어려운 점이 있었니?\n시우: 그... 낱말이.. 좀.. 어려운거 같아요..\n선생님: 모르는 말이 있었구나! 어디보자... 혹시 소달구지? 이런 말이 좀 어려웠니?\n시우: 아 네, 맞아요. 소달구지도 어려웠어요. \n선생님: 음, 소달구지는 소의 힘으로 움직이는 교통수단이야. 소가 직접 끌어주는 거지. \n시우: 아... 네. 감사해요. \n선생님: 혹시 또 모르는 것 있으면 선생님이 우리반 클래스룸에 자동 응답 인공지능 켜 놓을게. 전부 정답은 아닐 수 있지만 그래도 도움은 될 거야. \n시우: 네.. 감사합니다. \n선생님: 그래, 혹시 또 모르는 거 있으면 선생님이 얼마든 도와줄게!\n선생님: 음.. 어려�� 점이 있는 것 같네. 선생님이 좀 도와줄까?\n시우: 아..네..\n선생님: 그래, 우선 영상 다 보고 왔어 시우야?\n시우: 어...네... \n선생님: 이해가 안되는 부분이 있었어? 아니면 끝까지 영상을 다 못봤니?\n시우: 다 보긴 했는데, 그... 낱말을 좀 햇갈렸어요...\n선생님: 어떤 말이 어려웠어?\n시우: 음... 인력거.. 수단.. 이런거요\n선생님: 음, 인력거는 사람의 힘으로 움직이는 교통수단이야. 사람이 직접 끌어주는 차 같은거고, 수단은 교통수단에서 사용된 말일텐데, 어떤 것을 하기 위한 도구라고 생각하면 돼. \n시우: 아... 이제 좀 알겠어요. \n선생님: 그래, 모르는 것은 메모했다가 선생님한테 다음 날에 물어봐도 되고, 선생님이 우리반 자동 응답 인공지능도 켜 놓을게. 혹시 모르는 거 있으면 질문해봐. \n시우: 네.. 감사합니다. \n선생님: 그래, 이제 활동지를 적어볼까?\n선생님: 시우, 선생님이 좀 도와줄까?\n시우: 아..네..\n선생님: 어떤게 어려워? \n시우: 영상을 다 보긴 했는데, 낱말은 이해가 잘 안되는 것들이 있어서 좀 햇갈렸어요...\n선생님: 어떤 말이 어려웠어?\n시우: 음... 선박.. 이런거요\n선생님: 오, 이 낱말은 다른 친구들도 같이 생각해보면 참 좋겠다. (모두에게) 얘들아, 혹시 선박이 무엇인지 우리 반 친구들에게 설명해 줄 수 있는 사람 있니?\n시우: (친구의 설명을 듣고) 아... 이제 좀 알겠어요. \n선생님: 그래, 학교에서 친구들한테 물어봐도 되고, 선생님한테도 얼마든 물어보렴. 혹시 숙제할 때 궁금하면 우리반 클래스룸 인공지능한테 물어봐도 되고, 검색을 직접 해봐도 돼. \n시우: 네.. 감사합니다. \n선생님: 그래, 이제 활동지 적어보자. \n시우: 네, 감사합니다. \n\n\n"
|
31 |
+
|
32 |
+
|
33 |
+
if 'generated_gpt' not in st.session_state:
|
34 |
+
st.session_state['generated_gpt'] = []
|
35 |
+
|
36 |
+
if 'generated_rulebased' not in st.session_state:
|
37 |
+
st.session_state['generated_rulebased'] = []
|
38 |
+
|
39 |
+
if 'past_gpt' not in st.session_state:
|
40 |
+
st.session_state['past_gpt'] = []
|
41 |
+
|
42 |
+
if 'past_rulebased' not in st.session_state:
|
43 |
+
st.session_state['past_rulebased'] = []
|
44 |
+
|
45 |
+
if 'user_prompt' not in st.session_state:
|
46 |
+
st.session_state['user_prompt'] = "<현재 진행중인 대화>: \n"
|
47 |
+
|
48 |
+
|
49 |
+
col1, col2 = st.columns(2)
|
50 |
+
|
51 |
+
|
52 |
+
with col1:
|
53 |
+
st.header("RuleBased")
|
54 |
+
st.image("https://static.streamlit.io/examples/cat.jpg", width=169)
|
55 |
+
with st.form('form_rulebased', clear_on_submit=True):
|
56 |
+
user_input = st.text_area(label='You: ', value='', height=20, key='input_rulebased')
|
57 |
+
submitted = st.form_submit_button('Send')
|
58 |
+
|
59 |
+
if submitted and user_input:
|
60 |
+
|
61 |
+
## Sentence-BERT 기반
|
62 |
+
question_vectors = model.encode(q_fin)
|
63 |
+
target_vector = model.encode(user_input)
|
64 |
+
similarities_sbert = util.cos_sim(question_vectors, target_vector) # compute similarity between sentence vectors
|
65 |
+
|
66 |
+
## Sequence Matcher 기반
|
67 |
+
# similarities_seqmat = []
|
68 |
+
# user_sent_bytes = bytes(user_input, 'utf-8')
|
69 |
+
# user_sent_bytes_list = list(user_sent_bytes)
|
70 |
+
|
71 |
+
# for sent in q_fin:
|
72 |
+
# sent_bytes = bytes(sent, 'utf-8')
|
73 |
+
# sent_bytes_list = list(sent_bytes)
|
74 |
+
# score = difflib.SequenceMatcher(None, user_sent_bytes_list, sent_bytes_list).ratio()
|
75 |
+
# similarities_seqmat.append(score)
|
76 |
+
|
77 |
+
# similarities_seqmat = np.array(similarities_seqmat)
|
78 |
+
|
79 |
+
if similarities_sbert.max() < 0.2:
|
80 |
+
output = "잘 못 알아듣겠어요 선생님. 다시 말씀해주세요..."
|
81 |
+
else:
|
82 |
+
output = a_fin[similarities_sbert.argmax()]
|
83 |
+
# output = a_fin[similarities_seqmat.argmax()]
|
84 |
+
st.session_state.past_rulebased.append(user_input)
|
85 |
+
st.session_state.generated_rulebased.append(output)
|
86 |
+
|
87 |
+
if st.session_state['generated_rulebased']:
|
88 |
+
for i in range(len(st.session_state["generated_rulebased"])-1, -1, -1):
|
89 |
+
message(st.session_state["past_rulebased"][i], is_user=True, key=str(i) + '_user_rulebased')
|
90 |
+
message(st.session_state["generated_rulebased"][i], key=str(i) + '_bot_rulebased')
|
91 |
+
|
92 |
+
|
93 |
+
with col2:
|
94 |
+
st.header("GPT-4")
|
95 |
+
st.image("https://static.streamlit.io/examples/dog.jpg", width=200)
|
96 |
+
with st.form('form_gpt', clear_on_submit=True):
|
97 |
+
user_input = st.text_area(label='You: ', value='', height=20, key='input_gpt')
|
98 |
+
submitted = st.form_submit_button('Send')
|
99 |
+
|
100 |
+
if submitted and user_input:
|
101 |
+
|
102 |
+
## 사용자의 잘못된 입력에 대한 validation 및 filtering
|
103 |
+
compiled_input = re.sub(r"[^가-힣|a-zA-Z\s]", "", user_input)
|
104 |
+
if len(compiled_input) < 2:
|
105 |
+
st.session_state['user_prompt'] += "선생님: 시우야!\n"
|
106 |
+
else:
|
107 |
+
st.session_state['user_prompt'] += f"선생님: {user_input}\n"
|
108 |
+
|
109 |
+
with st.spinner('Wait for it...'):
|
110 |
+
try:
|
111 |
+
create_gpt_msg = gpt_api.gpt_call(
|
112 |
+
system_prompt=system_prompt,
|
113 |
+
user_prompt=st.session_state['user_prompt']
|
114 |
+
)
|
115 |
+
if "시우:" in create_gpt_msg:
|
116 |
+
create_gpt_msg = create_gpt_msg.split("시우:")[1].strip()
|
117 |
+
|
118 |
+
except Exception as e:
|
119 |
+
msg = str(e)
|
120 |
+
#opeanai RateLimitError:
|
121 |
+
if(msg.__contains__("please check your plan and billing detail")):
|
122 |
+
result_msg="ChatGPT OpenAPI > please check your plan and billing detail "
|
123 |
+
create_gpt_msg = ""
|
124 |
+
|
125 |
+
output = create_gpt_msg
|
126 |
+
st.session_state['user_prompt'] += f"시우: {create_gpt_msg}\n"
|
127 |
+
# print(st.session_state['user_prompt'])
|
128 |
+
st.session_state.past_gpt.append(user_input)
|
129 |
+
st.session_state.generated_gpt.append(output)
|
130 |
+
|
131 |
+
if st.session_state['generated_gpt']:
|
132 |
+
for i in range(len(st.session_state["generated_gpt"])-1, -1, -1):
|
133 |
+
message(st.session_state["past_gpt"][i], is_user=True, key=str(i) + '_user_gpt')
|
134 |
+
message(st.session_state["generated_gpt"][i], key=str(i) + '_bot_gpt')
|
gpt.py
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import openai
|
2 |
+
|
3 |
+
openai.api_key = "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"
|
4 |
+
|
5 |
+
class gpt_api:
|
6 |
+
|
7 |
+
@staticmethod
|
8 |
+
def set_use_model_name(use_model_name):
|
9 |
+
if not ('global_gpt_model_name' in locals() or 'global_gpt_model_name' in globals()):
|
10 |
+
global global_gpt_model_name
|
11 |
+
global_gpt_model_name=use_model_name
|
12 |
+
|
13 |
+
#####################################################
|
14 |
+
# GPT call
|
15 |
+
#####################################################
|
16 |
+
@staticmethod
|
17 |
+
def gpt_call(
|
18 |
+
system_prompt,
|
19 |
+
user_prompt
|
20 |
+
):
|
21 |
+
if not ('global_gpt_model_name' in locals() or 'global_gpt_model_name' in globals()):
|
22 |
+
global global_gpt_model_name
|
23 |
+
|
24 |
+
# global_gpt_model_name = "gpt-3.5-turbo"
|
25 |
+
global_gpt_model_name = "gpt-4"
|
26 |
+
|
27 |
+
response = openai.ChatCompletion.create(
|
28 |
+
model=global_gpt_model_name,
|
29 |
+
messages=[
|
30 |
+
{
|
31 |
+
"role": "system",
|
32 |
+
"content": system_prompt
|
33 |
+
},
|
34 |
+
{
|
35 |
+
"role": "user",
|
36 |
+
"content": user_prompt
|
37 |
+
}
|
38 |
+
],
|
39 |
+
# temperature=1.5,
|
40 |
+
# top_p=0.4,
|
41 |
+
# presence_penalty=1.5,
|
42 |
+
# frequency_penalty=1.5
|
43 |
+
)
|
44 |
+
output_text = response["choices"][0]["message"]["content"]
|
45 |
+
|
46 |
+
# print("output_text", output_text)
|
47 |
+
|
48 |
+
return output_text
|
requirements.txt
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
aiohttp==3.8.4
|
2 |
+
aiosignal==1.3.1
|
3 |
+
altair==4.2.2
|
4 |
+
async-timeout==4.0.2
|
5 |
+
attrs==22.2.0
|
6 |
+
blinker==1.5
|
7 |
+
cachetools==5.3.0
|
8 |
+
certifi==2022.12.7
|
9 |
+
charset-normalizer==3.1.0
|
10 |
+
click==8.1.3
|
11 |
+
decorator==5.1.1
|
12 |
+
entrypoints==0.4
|
13 |
+
frozenlist==1.3.3
|
14 |
+
gitdb==4.0.10
|
15 |
+
GitPython==3.1.31
|
16 |
+
idna==3.4
|
17 |
+
importlib-metadata==6.1.0
|
18 |
+
Jinja2==3.1.2
|
19 |
+
jsonschema==4.17.3
|
20 |
+
markdown-it-py==2.2.0
|
21 |
+
MarkupSafe==2.1.2
|
22 |
+
mdurl==0.1.2
|
23 |
+
multidict==6.0.4
|
24 |
+
numpy==1.24.2
|
25 |
+
openai==0.27.2
|
26 |
+
packaging==23.0
|
27 |
+
pandas==1.5.3
|
28 |
+
Pillow==9.4.0
|
29 |
+
pip==23.0.1
|
30 |
+
protobuf==3.20.3
|
31 |
+
pyarrow==11.0.0
|
32 |
+
pydeck==0.8.0
|
33 |
+
Pygments==2.14.0
|
34 |
+
Pympler==1.0.1
|
35 |
+
pyrsistent==0.19.3
|
36 |
+
python-dateutil==2.8.2
|
37 |
+
pytz==2023.3
|
38 |
+
pytz-deprecation-shim==0.1.0.post0
|
39 |
+
requests==2.28.2
|
40 |
+
rich==13.3.3
|
41 |
+
semver==2.13.0
|
42 |
+
setuptools==65.6.3
|
43 |
+
six==1.16.0
|
44 |
+
smmap==5.0.0
|
45 |
+
streamlit==1.20.0
|
46 |
+
streamlit-chat==0.0.2.2
|
47 |
+
toml==0.10.2
|
48 |
+
toolz==0.12.0
|
49 |
+
tornado==6.2
|
50 |
+
tqdm==4.65.0
|
51 |
+
typing_extensions==4.5.0
|
52 |
+
tzdata==2023.3
|
53 |
+
tzlocal==4.3
|
54 |
+
urllib3==1.26.15
|
55 |
+
validators==0.20.0
|
56 |
+
watchdog==3.0.0
|
57 |
+
wheel==0.38.4
|
58 |
+
yarl==1.8.2
|
59 |
+
zipp==3.15.0
|