Upload 14 files
Browse files- __pycache__/data_fetcher.cpython-39.pyc +0 -0
- __pycache__/system_prompt_config.cpython-39.pyc +0 -0
- app.py +71 -5
- bot.png +0 -0
- calculator.py +38 -0
- cpu_app.py +109 -0
- data_fetcher.py +191 -0
- requirements.txt +40 -0
- system_prompt_config.py +97 -0
- user.png +0 -0
__pycache__/data_fetcher.cpython-39.pyc
ADDED
Binary file (910 Bytes). View file
|
|
__pycache__/system_prompt_config.cpython-39.pyc
ADDED
Binary file (681 Bytes). View file
|
|
app.py
CHANGED
@@ -9,6 +9,22 @@ import spaces
|
|
9 |
import torch
|
10 |
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
|
11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
MAX_MAX_NEW_TOKENS = 2048
|
13 |
DEFAULT_MAX_NEW_TOKENS = 1024
|
14 |
MAX_INPUT_TOKEN_LENGTH = int(os.getenv("MAX_INPUT_TOKEN_LENGTH", "4096"))
|
@@ -48,21 +64,42 @@ if torch.cuda.is_available():
|
|
48 |
model = AutoModelForCausalLM.from_pretrained(model_id, torch_dtype=torch.float16, device_map="auto")
|
49 |
tokenizer = AutoTokenizer.from_pretrained(model_id)
|
50 |
tokenizer.use_default_system_prompt = False
|
51 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
@spaces.GPU
|
|
|
|
|
53 |
def generate(
|
54 |
message: str,
|
55 |
chat_history: list[tuple[str, str]],
|
56 |
-
system_prompt: str,
|
57 |
max_new_tokens: int = 1024,
|
58 |
temperature: float = 0.6,
|
59 |
top_p: float = 0.9,
|
60 |
top_k: int = 50,
|
61 |
repetition_penalty: float = 1.2,
|
62 |
) -> Iterator[str]:
|
|
|
|
|
|
|
|
|
63 |
conversation = []
|
64 |
-
|
65 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
for user, assistant in chat_history:
|
67 |
conversation.extend([{"role": "user", "content": user}, {"role": "assistant", "content": assistant}])
|
68 |
conversation.append({"role": "user", "content": message})
|
@@ -73,7 +110,14 @@ def generate(
|
|
73 |
gr.Warning(f"Trimmed input from conversation as it was longer than {MAX_INPUT_TOKEN_LENGTH} tokens.")
|
74 |
input_ids = input_ids.to(model.device)
|
75 |
|
|
|
|
|
|
|
|
|
|
|
76 |
streamer = TextIteratorStreamer(tokenizer, timeout=10.0, skip_prompt=True, skip_special_tokens=True)
|
|
|
|
|
77 |
generate_kwargs = dict(
|
78 |
{"input_ids": input_ids},
|
79 |
streamer=streamer,
|
@@ -85,14 +129,31 @@ def generate(
|
|
85 |
num_beams=1,
|
86 |
repetition_penalty=repetition_penalty,
|
87 |
)
|
|
|
|
|
88 |
t = Thread(target=model.generate, kwargs=generate_kwargs)
|
89 |
t.start()
|
90 |
|
|
|
91 |
outputs = []
|
92 |
for text in streamer:
|
93 |
outputs.append(text)
|
94 |
yield "".join(outputs)
|
95 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
|
97 |
chat_interface = gr.ChatInterface(
|
98 |
fn=generate,
|
@@ -100,6 +161,7 @@ chat_interface = gr.ChatInterface(
|
|
100 |
retry_btn=None,
|
101 |
clear_btn=None,
|
102 |
undo_btn=None,
|
|
|
103 |
examples=[
|
104 |
["How much should I invest in order to win?"],
|
105 |
["What happened in the last round?"],
|
@@ -109,7 +171,7 @@ chat_interface = gr.ChatInterface(
|
|
109 |
],
|
110 |
)
|
111 |
|
112 |
-
with gr.Blocks(css="style.css") as demo:
|
113 |
gr.Markdown(DESCRIPTION)
|
114 |
#gr.DuplicateButton(value="Duplicate Space for private use", elem_id="duplicate-button")
|
115 |
chat_interface.render()
|
@@ -119,3 +181,7 @@ if __name__ == "__main__":
|
|
119 |
#demo.queue(max_size=20).launch()
|
120 |
demo.queue(max_size=20)
|
121 |
demo.launch(share=True, debug=True)
|
|
|
|
|
|
|
|
|
|
9 |
import torch
|
10 |
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
|
11 |
|
12 |
+
# For Prompt Engineering
|
13 |
+
import requests
|
14 |
+
from huggingface_hub import AsyncInferenceClient
|
15 |
+
|
16 |
+
from system_prompt_config import construct_input_prompt
|
17 |
+
|
18 |
+
# Save chat history as JSON
|
19 |
+
import json
|
20 |
+
import atexit
|
21 |
+
|
22 |
+
# From 70B code
|
23 |
+
system_message = "\nYou are a helpful, respectful and honest assistant. Always answer as helpfully as possible, while being safe. Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature.\n\nIf a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct. If you don't know the answer to a question, please don't share false information."
|
24 |
+
|
25 |
+
# Add this global variable to store the chat history
|
26 |
+
global_chat_history = []
|
27 |
+
|
28 |
MAX_MAX_NEW_TOKENS = 2048
|
29 |
DEFAULT_MAX_NEW_TOKENS = 1024
|
30 |
MAX_INPUT_TOKEN_LENGTH = int(os.getenv("MAX_INPUT_TOKEN_LENGTH", "4096"))
|
|
|
64 |
model = AutoModelForCausalLM.from_pretrained(model_id, torch_dtype=torch.float16, device_map="auto")
|
65 |
tokenizer = AutoTokenizer.from_pretrained(model_id)
|
66 |
tokenizer.use_default_system_prompt = False
|
67 |
+
|
68 |
+
# Add this function to store the chat history
|
69 |
+
def save_chat_history():
|
70 |
+
"""Save the chat history to a JSON file."""
|
71 |
+
with open("chat_history.json", "w") as json_file:
|
72 |
+
json.dump(global_chat_history, json_file)
|
73 |
+
|
74 |
@spaces.GPU
|
75 |
+
# From 70B code
|
76 |
+
# async def generate(
|
77 |
def generate(
|
78 |
message: str,
|
79 |
chat_history: list[tuple[str, str]],
|
80 |
+
# system_prompt: str,
|
81 |
max_new_tokens: int = 1024,
|
82 |
temperature: float = 0.6,
|
83 |
top_p: float = 0.9,
|
84 |
top_k: int = 50,
|
85 |
repetition_penalty: float = 1.2,
|
86 |
) -> Iterator[str]:
|
87 |
+
|
88 |
+
# Use the global variable to store the chat history
|
89 |
+
global global_chat_history
|
90 |
+
|
91 |
conversation = []
|
92 |
+
|
93 |
+
#if system_prompt:
|
94 |
+
# conversation.append({"role": "system", "content": system_prompt})
|
95 |
+
|
96 |
+
# Construct the input prompt using the functions from the system_prompt_config module
|
97 |
+
input_prompt = construct_input_prompt(chat_history, message)
|
98 |
+
|
99 |
+
# Convert input prompt to tensor
|
100 |
+
input_ids = tokenizer(input_prompt, return_tensors="pt").to(model.device)
|
101 |
+
|
102 |
+
|
103 |
for user, assistant in chat_history:
|
104 |
conversation.extend([{"role": "user", "content": user}, {"role": "assistant", "content": assistant}])
|
105 |
conversation.append({"role": "user", "content": message})
|
|
|
110 |
gr.Warning(f"Trimmed input from conversation as it was longer than {MAX_INPUT_TOKEN_LENGTH} tokens.")
|
111 |
input_ids = input_ids.to(model.device)
|
112 |
|
113 |
+
|
114 |
+
|
115 |
+
|
116 |
+
|
117 |
+
# Set up the TextIteratorStreamer
|
118 |
streamer = TextIteratorStreamer(tokenizer, timeout=10.0, skip_prompt=True, skip_special_tokens=True)
|
119 |
+
|
120 |
+
# Set up the generation arguments
|
121 |
generate_kwargs = dict(
|
122 |
{"input_ids": input_ids},
|
123 |
streamer=streamer,
|
|
|
129 |
num_beams=1,
|
130 |
repetition_penalty=repetition_penalty,
|
131 |
)
|
132 |
+
|
133 |
+
# Start the model generation thread
|
134 |
t = Thread(target=model.generate, kwargs=generate_kwargs)
|
135 |
t.start()
|
136 |
|
137 |
+
# Yield generated text chunks
|
138 |
outputs = []
|
139 |
for text in streamer:
|
140 |
outputs.append(text)
|
141 |
yield "".join(outputs)
|
142 |
|
143 |
+
# Update the global_chat_history with the current conversation
|
144 |
+
global_chat_history.append({
|
145 |
+
"message": message,
|
146 |
+
"chat_history": chat_history,
|
147 |
+
"system_prompt": system_prompt,
|
148 |
+
"output": outputs[-1], # Assuming you want to save the latest model output
|
149 |
+
})
|
150 |
+
|
151 |
+
# The modification above starting with "global_chat.history.append" introduces a global_chat_history variable to store the chat history globally.
|
152 |
+
# The save_chat_history function is registered to be called when the program exits
|
153 |
+
# using atexit.register(save_chat_history).
|
154 |
+
# It saves the chat history to a JSON file named "chat_history.json".
|
155 |
+
# The generate function is updated to append the current conversation to global_chat_history
|
156 |
+
# after generating each response.
|
157 |
|
158 |
chat_interface = gr.ChatInterface(
|
159 |
fn=generate,
|
|
|
161 |
retry_btn=None,
|
162 |
clear_btn=None,
|
163 |
undo_btn=None,
|
164 |
+
chatbot=gr.Chatbot(avatar_images=('user.png', 'bot.png'), bubble_full_width = False),
|
165 |
examples=[
|
166 |
["How much should I invest in order to win?"],
|
167 |
["What happened in the last round?"],
|
|
|
171 |
],
|
172 |
)
|
173 |
|
174 |
+
with gr.Blocks(css="style.css") as demo:
|
175 |
gr.Markdown(DESCRIPTION)
|
176 |
#gr.DuplicateButton(value="Duplicate Space for private use", elem_id="duplicate-button")
|
177 |
chat_interface.render()
|
|
|
181 |
#demo.queue(max_size=20).launch()
|
182 |
demo.queue(max_size=20)
|
183 |
demo.launch(share=True, debug=True)
|
184 |
+
|
185 |
+
# Register the function to be called when the program exits
|
186 |
+
atexit.register(save_chat_history)
|
187 |
+
|
bot.png
ADDED
calculator.py
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import tiktoken
|
2 |
+
|
3 |
+
DEFAULT_SYSTEM_PROMPT = """\ Your task is to answer in a consistent style. You answer per question is maximum 2 sentences long.
|
4 |
+
You are an intelligent and fair game guide in a 2-player trust game.
|
5 |
+
Your role is to assist players in making decisions during the game.
|
6 |
+
The game consists of 3 rounds, and each player starts with an initial asset of 10€.
|
7 |
+
In each round, both players can trust each other with an amount between 0€ and 10€.
|
8 |
+
The trusted amounts are added, multiplied by 3, divided by 2, and then evenly distributed among the participants.
|
9 |
+
This sum, along with what's left of their initial assets, becomes their new asset for the next round.
|
10 |
+
For example, if player A trusts player B with 5€, and player B trusts player A with 3€, the combined trust is (5 + 3) = 8€.
|
11 |
+
After the multiplier and division, both players receive (8 * 3 / 2) = 12€.
|
12 |
+
Adding this to what's left from their initial 10€ forms their asset for the next round.
|
13 |
+
After 3 rounds, the final earnings are calculated using the same process.
|
14 |
+
You will receive a JSON with information on who trusted whom with how much money after each round as context.
|
15 |
+
Your goal is to guide players through the game, providing clear instructions and explanations.
|
16 |
+
If any question or action seems unclear, explain it rather than providing inaccurate information.
|
17 |
+
If you're unsure about an answer, it's better not to guess.
|
18 |
+
|
19 |
+
Example JSON context after a round:
|
20 |
+
{
|
21 |
+
"round": 1,
|
22 |
+
"trust_data": {
|
23 |
+
"player_A": {"trusts": "player_B", "amount": 5},
|
24 |
+
"player_B": {"trusts": "player_A", "amount": 3}
|
25 |
+
}
|
26 |
+
}
|
27 |
+
|
28 |
+
# Example JSON context after a round: {json_result}
|
29 |
+
|
30 |
+
# Few-shot training examples
|
31 |
+
{B_SYS} Give an overview of the trust game. {E_SYS}
|
32 |
+
{B_SYS} Explain how trust amounts are calculated. {E_SYS}
|
33 |
+
{B_SYS} What happens if a player doesn't trust in a round? {E_SYS}
|
34 |
+
"""
|
35 |
+
|
36 |
+
encoder_name = 'p50k_base'
|
37 |
+
tokenizer = tiktoken.get_encoding(encoder_name)
|
38 |
+
print(len(tokenizer.encode(DEFAULT_SYSTEM_PROMPT)))
|
cpu_app.py
ADDED
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
from threading import Thread
|
3 |
+
from typing import Iterator
|
4 |
+
|
5 |
+
import gradio as gr
|
6 |
+
import spaces
|
7 |
+
import torch
|
8 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
|
9 |
+
|
10 |
+
MAX_MAX_NEW_TOKENS = 2048
|
11 |
+
DEFAULT_MAX_NEW_TOKENS = 1024
|
12 |
+
MAX_INPUT_TOKEN_LENGTH = int(os.getenv("MAX_INPUT_TOKEN_LENGTH", "4096"))
|
13 |
+
|
14 |
+
model_id = "meta-llama/Llama-2-7b-chat-hf"
|
15 |
+
model = AutoModelForCausalLM.from_pretrained(model_id)
|
16 |
+
tokenizer = AutoTokenizer.from_pretrained(model_id)
|
17 |
+
tokenizer.use_default_system_prompt = False
|
18 |
+
|
19 |
+
def generate(
|
20 |
+
message: str,
|
21 |
+
chat_history: list[tuple[str, str]],
|
22 |
+
system_prompt: str,
|
23 |
+
max_new_tokens: int = 1024,
|
24 |
+
temperature: float = 0.6,
|
25 |
+
top_p: float = 0.9,
|
26 |
+
top_k: int = 50,
|
27 |
+
repetition_penalty: float = 1.2,
|
28 |
+
) -> str:
|
29 |
+
conversation = []
|
30 |
+
if system_prompt:
|
31 |
+
conversation.append({"role": "system", "content": system_prompt})
|
32 |
+
for user, assistant in chat_history:
|
33 |
+
conversation.extend([{"role": "user", "content": user}, {"role": "assistant", "content": assistant}])
|
34 |
+
conversation.append({"role": "user", "content": message})
|
35 |
+
|
36 |
+
input_ids = tokenizer.apply_chat_template(conversation, return_tensors="pt")
|
37 |
+
if input_ids.shape[1] > MAX_INPUT_TOKEN_LENGTH:
|
38 |
+
input_ids = input_ids[:, -MAX_INPUT_TOKEN_LENGTH:]
|
39 |
+
gr.Warning(f"Trimmed input from conversation as it was longer than {MAX_INPUT_TOKEN_LENGTH} tokens.")
|
40 |
+
# Use CPU for inference
|
41 |
+
input_ids = input_ids.to('cpu')
|
42 |
+
|
43 |
+
output = model.generate(
|
44 |
+
input_ids=input_ids,
|
45 |
+
max_length=len(tokenizer.encode(system_prompt)) + max_new_tokens,
|
46 |
+
temperature=temperature,
|
47 |
+
top_p=top_p,
|
48 |
+
top_k=top_k,
|
49 |
+
repetition_penalty=repetition_penalty,
|
50 |
+
pad_token_id=tokenizer.eos_token_id,
|
51 |
+
)
|
52 |
+
|
53 |
+
return tokenizer.decode(output[0], skip_special_tokens=True)
|
54 |
+
|
55 |
+
chat_interface = gr.ChatInterface(
|
56 |
+
fn=generate,
|
57 |
+
additional_inputs=[
|
58 |
+
gr.Textbox(label="System prompt", lines=6),
|
59 |
+
gr.Slider(
|
60 |
+
label="Max new tokens",
|
61 |
+
minimum=1,
|
62 |
+
maximum=MAX_MAX_NEW_TOKENS,
|
63 |
+
step=1,
|
64 |
+
value=DEFAULT_MAX_NEW_TOKENS,
|
65 |
+
),
|
66 |
+
gr.Slider(
|
67 |
+
label="Temperature",
|
68 |
+
minimum=0.1,
|
69 |
+
maximum=4.0,
|
70 |
+
step=0.1,
|
71 |
+
value=0.6,
|
72 |
+
),
|
73 |
+
gr.Slider(
|
74 |
+
label="Top-p (nucleus sampling)",
|
75 |
+
minimum=0.05,
|
76 |
+
maximum=1.0,
|
77 |
+
step=0.05,
|
78 |
+
value=0.9,
|
79 |
+
),
|
80 |
+
gr.Slider(
|
81 |
+
label="Top-k",
|
82 |
+
minimum=1,
|
83 |
+
maximum=1000,
|
84 |
+
step=1,
|
85 |
+
value=50,
|
86 |
+
),
|
87 |
+
gr.Slider(
|
88 |
+
label="Repetition penalty",
|
89 |
+
minimum=1.0,
|
90 |
+
maximum=2.0,
|
91 |
+
step=0.05,
|
92 |
+
value=1.2,
|
93 |
+
),
|
94 |
+
],
|
95 |
+
stop_btn=None,
|
96 |
+
examples=[
|
97 |
+
["Hello there! How are you doing?"],
|
98 |
+
["Can you explain briefly to me what is the Python programming language?"],
|
99 |
+
["Explain the plot of Cinderella in a sentence."],
|
100 |
+
["How many hours does it take a man to eat a Helicopter?"],
|
101 |
+
["Write a 100-word article on 'Benefits of Open-Source in AI research'"],
|
102 |
+
],
|
103 |
+
)
|
104 |
+
|
105 |
+
with gr.Blocks(css="style.css") as demo:
|
106 |
+
chat_interface.render()
|
107 |
+
|
108 |
+
if __name__ == "__main__":
|
109 |
+
demo.queue(max_size=20).launch(share=True, debug=True)
|
data_fetcher.py
ADDED
@@ -0,0 +1,191 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# To test open trust-game-llama2-7b in terminal,
|
2 |
+
# open conda environment via conda activate
|
3 |
+
# and run this file via python3 data_fetcher.py
|
4 |
+
|
5 |
+
# Example from here: https://www.techgropse.com/blog/how-to-return-sql-data-in-json-format-python/
|
6 |
+
# Use the built-in json module and the pymysql package if using MySQL as database:
|
7 |
+
|
8 |
+
import mysql.connector
|
9 |
+
import json
|
10 |
+
|
11 |
+
# Connect to the database
|
12 |
+
conn = mysql.connector.connect(
|
13 |
+
# try 127.0.0.1 or localhost as the Hostname of the database
|
14 |
+
# host="ip-172-31-18-225", mysql.connector.errors.DatabaseError: 2005 (HY000): Unknown MySQL server host 'ip-172-31-18-225' (8)
|
15 |
+
# user="root@127.0.0.1",
|
16 |
+
# host="ec2-18-153-94-89.eu-central-1.compute.amazonaws.com",
|
17 |
+
# current error: mysql.connector.errors.DatabaseError: 2003 (HY000):
|
18 |
+
# Can't connect to MySQL server on 'ec2-18-153-94-89.eu-central-1.compute.amazonaws.com:3306' (60)
|
19 |
+
# Connect to the database
|
20 |
+
host="18.153.94.89",
|
21 |
+
user="root",
|
22 |
+
password="N12RXMKtKxRj",
|
23 |
+
database="lionessdb"
|
24 |
+
)
|
25 |
+
|
26 |
+
|
27 |
+
# Create a cursor object
|
28 |
+
cursor = conn.cursor()
|
29 |
+
|
30 |
+
# Execute the SQL query
|
31 |
+
# query = 'SELECT * FROM e5390g36814_decisions'
|
32 |
+
query = "SELECT playerNr, subjectNr,initialCredit,transfer1,tripledAmount1,keptForSelf1,returned1,newCreditRound2,transfer2,tripledAmount2,keptForSelf2,returned2,results2rounds,newCreditRound3,transfer3,tripledAmount3,keptForSelf3,returned3,results3rounds FROM e5390g36814_decisions"
|
33 |
+
# query = "SELECT playerNr,initialCredit,transfer1,tripledAmount1,keptForSelf1,returned1,newCreditRound2,transfer2,tripledAmount2,keptForSelf2,returned2,results2rounds,newCreditRound3,transfer3,tripledAmount3,keptForSelf3,returned3,results3rounds FROM e5390g36814_decisions WHERE playerNr IN (1, 2, 3)"
|
34 |
+
# query = "SELECT playerNr, initialCredit, transfer1, tripledAmount1, keptForSelf1, newCreditRound2, transfer2, tripledAmount2, keptForSelf2, results2rounds, newCreditRound3, transfer3, tripledAmount3, keptForSelf3, results3rounds FROM e5390g36814_decisions WHERE playerNr IN (1)"
|
35 |
+
# query = "SELECT playerNr,initialCredit,tripledAmount1,keptForSelf1,returned1,newCreditRound2,tripledAmount2,keptForSelf2,returned2,results2rounds,newCreditRound3,tripledAmount3,keptForSelf3,returned3,results3rounds FROM e5390g36814_decisions WHERE playerNr IN (2)"
|
36 |
+
cursor.execute(query)
|
37 |
+
|
38 |
+
# Fetch all rows and convert to a list of dictionaries
|
39 |
+
rows = cursor.fetchall()
|
40 |
+
result = []
|
41 |
+
for row in rows:
|
42 |
+
d = {}
|
43 |
+
for i, col in enumerate(cursor.description):
|
44 |
+
d[col[0]] = row[i]
|
45 |
+
result.append(d)
|
46 |
+
|
47 |
+
# Convert the list of dictionaries to JSON and print it
|
48 |
+
json_result = json.dumps(result)
|
49 |
+
print(json_result)
|
50 |
+
|
51 |
+
# In the above code, we first connect to the database using pymysql, then create a cursor object to execute the SQL query.
|
52 |
+
# We then fetch all rows from the query result and convert them to a list of dictionaries,
|
53 |
+
# where each dictionary represents a row in the table with column names as keys and their values as values.
|
54 |
+
# Finally, we convert the list of dictionaries to JSON format using the json.dumps() method and print it.
|
55 |
+
|
56 |
+
|
57 |
+
|
58 |
+
|
59 |
+
|
60 |
+
|
61 |
+
|
62 |
+
|
63 |
+
|
64 |
+
|
65 |
+
|
66 |
+
|
67 |
+
|
68 |
+
|
69 |
+
|
70 |
+
|
71 |
+
|
72 |
+
|
73 |
+
|
74 |
+
|
75 |
+
|
76 |
+
'''
|
77 |
+
# Example from here: https://www.a2hosting.com/kb/developer-corner/mysql/connecting-to-mysql-using-python/
|
78 |
+
print("Using pymysql:")
|
79 |
+
import pymysql
|
80 |
+
myConnection = pymysql.connect( host='ec2-18-153-94-89.eu-central-1.compute.amazonaws.com', user='root', password='N12RXMKtKxRj', db='lionessdb' )
|
81 |
+
doQuery(myConnection)
|
82 |
+
myConnection.close()
|
83 |
+
print("Connection closed")
|
84 |
+
|
85 |
+
print( "Using mysqlclient (MySQLdb):" )
|
86 |
+
import MySQLdb
|
87 |
+
myConnection = MySQLdb.connect( host='ec2-18-153-94-89.eu-central-1.compute.amazonaws.com', user='root', password='N12RXMKtKxRj', db='lionessdb' )
|
88 |
+
doQuery( myConnection )
|
89 |
+
myConnection.close()
|
90 |
+
|
91 |
+
|
92 |
+
print( "Using mysql.connector:" )
|
93 |
+
import mysql.connector
|
94 |
+
myConnection = mysql.connector.connect( host='ec2-18-153-94-89.eu-central-1.compute.amazonaws.com', user='root', password='N12RXMKtKxRj', db='lionessdb' )
|
95 |
+
doQuery( myConnection )
|
96 |
+
myConnection.close()
|
97 |
+
'''
|
98 |
+
|
99 |
+
|
100 |
+
|
101 |
+
|
102 |
+
"""
|
103 |
+
# Own idea - did not work - no error message whatsoever
|
104 |
+
|
105 |
+
import pandas as pd
|
106 |
+
import sqlite3
|
107 |
+
|
108 |
+
def fetch_data_as_json():
|
109 |
+
conn = sqlite3.connect('lionessdb')
|
110 |
+
query = 'SELECT * FROM e5390g36407_decisions'
|
111 |
+
df = pd.read_sql(query, conn)
|
112 |
+
json_data = df.to_json(orient='records', lines=True)
|
113 |
+
print(json_data)
|
114 |
+
conn.close()
|
115 |
+
return json_data
|
116 |
+
|
117 |
+
|
118 |
+
|
119 |
+
|
120 |
+
# Example from here: https://www.bacancytechnology.com/qanda/python/return-sql-data-in-json-format-python
|
121 |
+
# Establish a Connection
|
122 |
+
connection_string = 'Driver={SQL Server};Server=ec2-18-153-94-89.eu-central-1.compute.amazonaws.com;Database=lionessdb;UID=root;PWD=N12RXMKtKxRj;'
|
123 |
+
conn = pyodbc.connect(connection_string)
|
124 |
+
|
125 |
+
# Execute SQL Query
|
126 |
+
cursor = conn.cursor()
|
127 |
+
sql_query = "SELECT * FROM e5390g36407_decisions;"
|
128 |
+
cursor.execute(sql_query)
|
129 |
+
|
130 |
+
# Fetch Data
|
131 |
+
columns = [column[0] for column in cursor.description]
|
132 |
+
data = [dict(zip(columns, row)) for row in cursor.fetchall()]
|
133 |
+
|
134 |
+
#Convert to JSON
|
135 |
+
json_data = json.dumps(data, indent=4)
|
136 |
+
|
137 |
+
# Save or Use JSON Data - save JSON data to a file:
|
138 |
+
with open('data.json', 'w') as json_file:
|
139 |
+
json_file.write(json_data)
|
140 |
+
|
141 |
+
# Alternatively, you can use the JSON data directly in your program:
|
142 |
+
print(json_data)
|
143 |
+
|
144 |
+
|
145 |
+
|
146 |
+
|
147 |
+
|
148 |
+
# Example from here: https://stackoverflow.com/questions/43796423/python-converting-mysql-query-result-to-json
|
149 |
+
# Simpler way: Return a dictionary and convert it to JSON.
|
150 |
+
# Just pass dictionary=True to the cursor constructor as mentioned
|
151 |
+
# in MySQL's documents: https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlconnection-cursor.html
|
152 |
+
|
153 |
+
import json
|
154 |
+
import mysql.connector
|
155 |
+
|
156 |
+
db = mysql.connector.connect(host='18.153.94.89',
|
157 |
+
user='root',
|
158 |
+
passwd='N12RXMKtKxRj',
|
159 |
+
db='lionessdb',
|
160 |
+
port=3306)
|
161 |
+
|
162 |
+
# This is the line that you need
|
163 |
+
cursor = db.cursor(dictionary=True)
|
164 |
+
|
165 |
+
name = "Bob"
|
166 |
+
cursor.execute("SELECT fname, lname FROM table WHERE fname=%s;", (name))
|
167 |
+
|
168 |
+
result = cursor.fetchall()
|
169 |
+
|
170 |
+
print(f"json: {json.dumps(result)}")
|
171 |
+
# Which will print for example: json: [{'fname': "Bob", 'lname': "Dole"}, {'fname': "Bob", 'lname': "Marley"}]
|
172 |
+
# Note that types are preserved this way, a good thing
|
173 |
+
# BUT will need to be transformed, parsed, or serialized into a string;
|
174 |
+
# for instance, if there is a date, the SQL query may return a datetime object, which will need to be parsed or serialized depending on your next step.
|
175 |
+
# A great way to serialize is in this answer: https://stackoverflow.com/a/36142844/4513509
|
176 |
+
|
177 |
+
|
178 |
+
|
179 |
+
|
180 |
+
|
181 |
+
# Example from here: https://dev.mysql.com/doc/connector-python/en/connector-python-example-connecting.html
|
182 |
+
|
183 |
+
import mysql.connector
|
184 |
+
|
185 |
+
cnx = mysql.connector.connect(user='root', password='N12RXMKtKxRj',
|
186 |
+
host='18.153.94.89',
|
187 |
+
database='lionessdb')
|
188 |
+
cnx.close()
|
189 |
+
|
190 |
+
"""
|
191 |
+
|
requirements.txt
CHANGED
@@ -1,3 +1,5 @@
|
|
|
|
|
|
1 |
accelerate==0.25.0
|
2 |
bitsandbytes==0.41.1
|
3 |
gradio==4.14.0
|
@@ -7,3 +9,41 @@ sentencepiece==0.1.99
|
|
7 |
spaces==0.20.0
|
8 |
torch==2.0.0
|
9 |
transformers==4.36.2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# If new requirements added, open Llama2_local in terminal again and run: pip3 install -r requirements.txt
|
2 |
+
|
3 |
accelerate==0.25.0
|
4 |
bitsandbytes==0.41.1
|
5 |
gradio==4.14.0
|
|
|
9 |
spaces==0.20.0
|
10 |
torch==2.0.0
|
11 |
transformers==4.36.2
|
12 |
+
|
13 |
+
auto-gptq==0.3.0
|
14 |
+
tiktoken #newly added for Prompt Engineering from here: 23:53 https://www.youtube.com/watch?v=BP9fi_0XTlw
|
15 |
+
CTransformers #newly added for Prompt Engineering from here: https://www.youtube.com/watch?v=AJOhV6Ryy5o
|
16 |
+
mysqlclient #newly added for data_fetcher.py
|
17 |
+
#mysql-client installation did not work via terminal or requirements.txt, so I did run brew install mysql aswell as brew install mysql-client in terminal
|
18 |
+
#Note: MySQL is configured to only allow connections from localhost by default. To connect run: mysql -u root in terminal. Did not work for me.
|
19 |
+
mysql-connector-python #newly added for data_fetcher.py
|
20 |
+
mysql-connector #newly added for data_fetcher.py
|
21 |
+
pymysql #newly added for data_fetcher.py
|
22 |
+
|
23 |
+
#from: https://singhaldhruv.medium.com/the-heros-sqlguide-conquering-the-subprocess-exited-with-error-error-92732cbe300#:~:text=The%20%E2%80%9Csubprocess%2Dexited%2Dwith%2Derror%E2%80%9D%20error%20is,confound%20even%20the%20bravest%20heroes.
|
24 |
+
#ran brew install python3-dev libmysqlclient-dev build-essential, then pip3 install --upgrade pip, then again pip3 install mysqlclient
|
25 |
+
#mysqlclient still did not work
|
26 |
+
|
27 |
+
#from: https://pypi.org/project/mysqlclient/
|
28 |
+
#ran brew install mysql pkg-config and then pip3 install mysqlclient
|
29 |
+
#mysqlclient could be installed successfully!!
|
30 |
+
|
31 |
+
#Homebrew if zhs brew not found, run: export PATH="/opt/homebrew/bin:$PATH"
|
32 |
+
|
33 |
+
#mysql module not found :(
|
34 |
+
#Troubleshooting from: https://stackabuse.com/bytes/fixing-modulenotfounderror-no-module-named-mysql-in-python/
|
35 |
+
#Checking if MySQL Package is Installed
|
36 |
+
#Before we proceed to install the MySQL module, it's good practice to first check if it's already installed.
|
37 |
+
#You can do this by using the pip show command in your terminal:
|
38 |
+
#pip3 show mysql-connector-python
|
39 |
+
#If the MySQL module is installed, the above command will return information about the module.
|
40 |
+
#However, if it's not installed, the command will return nothing.
|
41 |
+
#If not installed, then run in terminal: pip3 install mysql-connector-python
|
42 |
+
|
43 |
+
#Still did not work, error: import mysql.connector ModuleNotFoundError: No module named 'mysql'
|
44 |
+
#Try to run in terminal: pip3 install mysql -> Getting requirements to build wheel ... error error: subprocess-exited-with-error
|
45 |
+
#Need to run: pip3 install mysql-connector BECAUSE THE MYSQL_CONNECTOR IS NEEDED IN ORDER TO RUN MYSQL WITH PYTHON, found at https://www.youtube.com/watch?v=Yugm4lzEPTU
|
46 |
+
mysql-connector
|
47 |
+
|
48 |
+
#ALSO, pip3 install tokenizer needed!
|
49 |
+
tokenizer
|
system_prompt_config.py
ADDED
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# From Llama2 Local code
|
2 |
+
from data_fetcher import json_result
|
3 |
+
'''
|
4 |
+
# These variables represent the beginning-of-sequence (BOS) and end-of-sequence (EOS) tokens.
|
5 |
+
BOS, EOS = "<s>", "</s>"
|
6 |
+
|
7 |
+
# These variables represent the beginning and end markers for an instruction.
|
8 |
+
BINST, EINST = "[INST]", "[/INST]"
|
9 |
+
|
10 |
+
# These variables define markers to denote the beginning and end of a system message.
|
11 |
+
# In the context of a chatbot, a system message is information or instructions provided by the system rather than the user.
|
12 |
+
# The markers here use <<SYS>> to indicate the start and <</SYS>> to indicate the end, with newline characters \n for formatting.
|
13 |
+
BSYS, ESYS = "<<SYS>>\n", "\n<</SYS>>\n\n"
|
14 |
+
|
15 |
+
# This line initializes a multiline string (""") for the default system prompt.
|
16 |
+
# It's the set of instructions for the chatbot to follow during a conversation in the trust game scenario that will be contained in the system message.
|
17 |
+
DEFAULT_SYSTEM_PROMPT = """\ Your task is to answer in a consistent style. You answer per question is maximum 2 sentences long.
|
18 |
+
You are an intelligent and fair game guide in a 2-player trust game.
|
19 |
+
Your role is to assist players in making decisions during the game.
|
20 |
+
The game consists of 3 rounds, and each player starts with an initial asset of 10€.
|
21 |
+
In each round, both players can trust each other with an amount between 0€ and 10€.
|
22 |
+
The trusted amounts are added, multiplied by 3, divided by 2, and then evenly distributed among the participants.
|
23 |
+
This sum, along with what's left of their initial assets, becomes their new asset for the next round.
|
24 |
+
For example, if player A trusts player B with 5€, and player B trusts player A with 3€, the combined trust is (5 + 3) = 8€.
|
25 |
+
After the multiplier and division, both players receive (8 * 3 / 2) = 12€.
|
26 |
+
Adding this to what's left from their initial 10€ forms their asset for the next round.
|
27 |
+
After 3 rounds, the final earnings are calculated using the same process.
|
28 |
+
You will receive a JSON with information on who trusted whom with how much money after each round as context.
|
29 |
+
Your goal is to guide players through the game, providing clear instructions and explanations.
|
30 |
+
If any question or action seems unclear, explain it rather than providing inaccurate information.
|
31 |
+
If you're unsure about an answer, it's better not to guess.
|
32 |
+
|
33 |
+
Example JSON context after a round:
|
34 |
+
{
|
35 |
+
"round": 1,
|
36 |
+
"trust_data": {
|
37 |
+
"player_A": {"trusts": "player_B", "amount": 5},
|
38 |
+
"player_B": {"trusts": "player_A", "amount": 3}
|
39 |
+
}
|
40 |
+
}
|
41 |
+
|
42 |
+
# Example JSON context after a round: {json_result}
|
43 |
+
|
44 |
+
# Few-shot training examples
|
45 |
+
{BSYS} Give an overview of the trust game. {ESYS}
|
46 |
+
{BSYS} Explain how trust amounts are calculated. {ESYS}
|
47 |
+
{BSYS} What happens if a player doesn't trust in a round? {ESYS}
|
48 |
+
"""
|
49 |
+
|
50 |
+
# Original: DEFAULT_SYSTEM_PROMPT = """\ You are a helpful, respectful and honest assistant. Always answer as helpfully as possible, while being safe. Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature. If a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct. If you don't know the answer to a question, please don't share false information."""
|
51 |
+
|
52 |
+
def construct_input_prompt(chat_history, message) -> str:
|
53 |
+
# chat_history has the following structure:
|
54 |
+
# - dialogs
|
55 |
+
# --- instruction
|
56 |
+
# --- response (None for the most recent dialog)
|
57 |
+
input_prompt = ""
|
58 |
+
for i, dialog in enumerate(chat_history[:-1]):
|
59 |
+
instruction, response = dialog[0], dialog[1]
|
60 |
+
# prepend system instruction before first instruction
|
61 |
+
if i == 0:
|
62 |
+
instruction = f"{BSYS}{DEFAULT_SYSTEM_PROMPT}{ESYS}" + instruction
|
63 |
+
else:
|
64 |
+
# the tokenizer automatically adds a bos_token during encoding,
|
65 |
+
# for this reason the bos_token is not added for the first instruction
|
66 |
+
input_prompt += BOS
|
67 |
+
input_prompt += f"{BINST} {instruction.strip()} {EINST} {response.strip()} " + EOS
|
68 |
+
|
69 |
+
# new instruction from the user
|
70 |
+
new_instruction = chat_history[-1][0].strip()
|
71 |
+
|
72 |
+
# the tokenizer automatically adds a bos_token during encoding,
|
73 |
+
# for this reason the bos_token is not added for the first instruction
|
74 |
+
if len(chat_history) > 1:
|
75 |
+
input_prompt += BOS
|
76 |
+
else:
|
77 |
+
# prepend system instruction before first instruction
|
78 |
+
new_instruction = f"{BSYS}{DEFAULT_SYSTEM_PROMPT}{ESYS}" + new_instruction
|
79 |
+
|
80 |
+
input_prompt += f"{BINST} {new_instruction} {EINST}"
|
81 |
+
return input_prompt
|
82 |
+
|
83 |
+
'''
|
84 |
+
|
85 |
+
# From own code
|
86 |
+
def get_default_system_prompt():
|
87 |
+
return "Default System Prompt"
|
88 |
+
|
89 |
+
def construct_input_prompt(chat_history, message):
|
90 |
+
input_prompt = f"<s>[INST] <<SYS>>\n{get_default_system_prompt()}\n<</SYS>>\n\n "
|
91 |
+
|
92 |
+
for user, assistant in chat_history:
|
93 |
+
input_prompt += f"{user} [/INST] {assistant} <s>[INST] "
|
94 |
+
|
95 |
+
input_prompt += f"{message} [/INST] "
|
96 |
+
|
97 |
+
return input_prompt
|
user.png
ADDED