huang342 commited on
Commit
7729193
·
verified ·
1 Parent(s): 9630e2d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -189
app.py CHANGED
@@ -1,201 +1,59 @@
1
- # -*- coding: utf-8 -*-
2
- """app
3
-
4
- Automatically generated by Colab.
5
-
6
- Original file is located at
7
- https://colab.research.google.com/drive/1OBF9xRogFp1BlMVFwZX6R-0jD8yU_tEk
8
- """
9
-
10
- import torch
11
- import torch.nn as nn
12
- from torch.nn import functional as F
13
- import requests
14
-
15
- # hyperparameters
16
- batch_size = 16
17
- block_size = 32
18
- n_embd = 64
19
- n_head = 4
20
- n_layer = 4
21
- dropout = 0.0
22
- device = 'cuda' if torch.cuda.is_available() else 'cpu'
23
- learning_rate = 1e-3
24
- max_iters = 5000 # Number of training iterations
25
-
26
- # File path for saving the Book of Mormon text
27
- file_path = "Book of Mormon.txt"
28
-
29
- # Download and save the file
30
- url = "https://raw.githubusercontent.com/huang-0505/LLM/refs/heads/main/Book%20of%20Mormon.txt"
31
- response = requests.get(url)
32
- with open("Book of Mormon.txt", "w", encoding="utf-8") as f:
33
- f.write(response.text)
34
-
35
- # Read the content of the file into the `text` variable
36
- with open("Book of Mormon.txt", "r", encoding="utf-8") as f:
37
- text = f.read()
38
-
39
- # Tokenizer setup
40
- chars = sorted(list(set(text)))
41
- stoi = {ch: i for i, ch in enumerate(chars)}
42
- itos = {i: ch for i, ch in enumerate(chars)}
43
- encode = lambda s: [stoi[c] for c in s]
44
- decode = lambda l: ''.join([itos[i] for i in l])
45
-
46
- # Encode the dataset
47
- data = torch.tensor(encode(text), dtype=torch.long)
48
-
49
- # Split into training and validation sets
50
- n = int(0.9 * len(data)) # 90% training, 10% validation
51
- train_data = data[:n]
52
- val_data = data[n:]
53
-
54
- # Function to get batches of data
55
- def get_batch(split):
56
- data = train_data if split == "train" else val_data
57
- ix = torch.randint(len(data) - block_size, (batch_size,))
58
- x = torch.stack([data[i:i + block_size] for i in ix])
59
- y = torch.stack([data[i + 1:i + block_size + 1] for i in ix])
60
- return x.to(device), y.to(device)
61
-
62
- # Model definition
63
- class BigramLanguageModel(nn.Module):
64
- def __init__(self):
65
- super().__init__()
66
- self.token_embedding_table = nn.Embedding(len(chars), n_embd)
67
- self.position_embedding_table = nn.Embedding(block_size, n_embd)
68
- self.blocks = nn.Sequential(*[Block(n_embd, n_head=n_head) for _ in range(n_layer)])
69
- self.ln_f = nn.LayerNorm(n_embd)
70
- self.lm_head = nn.Linear(n_embd, len(chars))
71
-
72
- def forward(self, idx, targets=None):
73
- tok_emb = self.token_embedding_table(idx)
74
- pos_emb = self.position_embedding_table(torch.arange(idx.shape[1], device=device))
75
- x = tok_emb + pos_emb
76
- x = self.blocks(x)
77
- x = self.ln_f(x)
78
- logits = self.lm_head(x)
79
- loss = F.cross_entropy(logits.view(-1, logits.size(-1)), targets.view(-1)) if targets is not None else None
80
- return logits, loss
81
-
82
- def generate(self, idx, max_new_tokens):
83
- for _ in range(max_new_tokens):
84
- idx_cond = idx[:, -block_size:]
85
- logits, _ = self(idx_cond)
86
- logits = logits[:, -1, :]
87
- probs = F.softmax(logits, dim=-1)
88
- idx_next = torch.multinomial(probs, num_samples=1)
89
- idx = torch.cat((idx, idx_next), dim=1)
90
- return idx
91
-
92
- class Block(nn.Module):
93
- def __init__(self, n_embd, n_head):
94
- super().__init__()
95
- head_size = n_embd // n_head
96
- self.sa = MultiHeadAttention(n_head, head_size)
97
- self.ffwd = FeedForward(n_embd)
98
- self.ln1 = nn.LayerNorm(n_embd)
99
- self.ln2 = nn.LayerNorm(n_embd)
100
-
101
- def forward(self, x):
102
- x = x + self.sa(self.ln1(x))
103
- x = x + self.ffwd(self.ln2(x))
104
- return x
105
-
106
- class MultiHeadAttention(nn.Module):
107
- def __init__(self, num_heads, head_size):
108
- super().__init__()
109
- self.heads = nn.ModuleList([Head(head_size) for _ in range(num_heads)])
110
- self.proj = nn.Linear(n_embd, n_embd)
111
- self.dropout = nn.Dropout(dropout)
112
-
113
- def forward(self, x):
114
- out = torch.cat([h(x) for h in self.heads], dim=-1)
115
- out = self.dropout(self.proj(out))
116
- return out
117
-
118
- class Head(nn.Module):
119
- def __init__(self, head_size):
120
- super().__init__()
121
- self.key = nn.Linear(n_embd, head_size, bias=False)
122
- self.query = nn.Linear(n_embd, head_size, bias=False)
123
- self.value = nn.Linear(n_embd, head_size, bias=False)
124
- self.register_buffer('tril', torch.tril(torch.ones(block_size, block_size)))
125
-
126
- def forward(self, x):
127
- k, q, v = self.key(x), self.query(x), self.value(x)
128
- wei = q @ k.transpose(-2, -1) * (k.size(-1) ** -0.5)
129
- wei = wei.masked_fill(self.tril[:x.size(1), :x.size(1)] == 0, float('-inf'))
130
- wei = F.softmax(wei, dim=-1)
131
- return wei @ v
132
-
133
- class FeedForward(nn.Module):
134
- def __init__(self, n_embd):
135
- super().__init__()
136
- self.net = nn.Sequential(
137
- nn.Linear(n_embd, 4 * n_embd),
138
- nn.ReLU(),
139
- nn.Linear(4 * n_embd, n_embd),
140
- nn.Dropout(dropout)
141
- )
142
-
143
- def forward(self, x):
144
- return self.net(x)
145
-
146
- # Initialize model and optimizer
147
- model = BigramLanguageModel().to(device)
148
- optimizer = torch.optim.AdamW(model.parameters(), lr=learning_rate)
149
-
150
- # Training loop
151
- for iter in range(max_iters):
152
- xb, yb = get_batch("train")
153
- logits, loss = model(xb, yb)
154
- optimizer.zero_grad()
155
- loss.backward()
156
- optimizer.step()
157
-
158
- if iter % 100 == 0:
159
- print(f"Step {iter}: Loss = {loss.item()}")
160
-
161
- # Save the model
162
- torch.save(model.state_dict(), "model.pth")
163
- print("Model trained and saved as 'model.pth'")
164
-
165
  import gradio as gr
 
 
 
 
166
 
167
-
168
- def ask_question(question, max_new_tokens=100):
169
- # Format the input context
170
- context_text = f"Q: {question}\nA:"
171
- context_tokens = torch.tensor([encode(context_text)], dtype=torch.long, device=device)
172
-
173
- # Generate the response
174
- generated_tokens = model.generate(context_tokens, max_new_tokens=max_new_tokens)
175
-
176
- # Decode the generated tokens into text
177
- generated_text = decode(generated_tokens[0].tolist())
178
-
179
- # Extract the answer (after "A:")
180
- answer = generated_text.split("A:")[1].strip()
181
- return answer
182
-
183
- # Function to process the question
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  def chatbot_response(question):
185
- try:
186
- answer = ask_question(question)
187
- return f"Q: {question}\nA: {answer}"
188
- except Exception as e:
189
- return f"Error: {e}"
190
 
191
- # Create a Gradio interface
192
  demo = gr.Interface(
193
  fn=chatbot_response,
194
  inputs="text",
195
  outputs="text",
196
  title="Religious Chatbot",
197
- description="Ask questions about the book of Mormon, and the chatbot will generate answers based on its knowledge."
198
  )
199
 
200
  # Launch the app
201
- demo.launch(share=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
+ from transformers import AutoTokenizer, AutoModelForCausalLM
3
+ from sentence_transformers import SentenceTransformer, util
4
+ import pandas as pd
5
+ import torch
6
 
7
+ # Load the knowledge base
8
+ knowledge_base_df = pd.read_csv('knowledge_base.csv')
9
+ knowledge_base = knowledge_base_df['content'].tolist()
10
+
11
+ # Initialize models
12
+ embedder = SentenceTransformer('all-MiniLM-L6-v2')
13
+ knowledge_embeddings = embedder.encode(knowledge_base, convert_to_tensor=True)
14
+
15
+ tokenizer = AutoTokenizer.from_pretrained('gpt2')
16
+ model = AutoModelForCausalLM.from_pretrained('gpt2')
17
+
18
+ # Retrieval function
19
+ def retrieve_documents(query, top_k=3):
20
+ query_embedding = embedder.encode(query, convert_to_tensor=True)
21
+ scores = util.cos_sim(query_embedding, knowledge_embeddings)[0]
22
+ top_results = torch.topk(scores, k=top_k)
23
+ return [knowledge_base[i] for i in top_results.indices]
24
+
25
+ # Generate a response
26
+ def ask_question(question, top_k=3, max_new_tokens=50, device='cpu'):
27
+ retrieved_docs = retrieve_documents(question, top_k=top_k)
28
+ context = "<retrieval> " + " ".join(retrieved_docs) + " <query> " + question
29
+ context_text = f"<bos> Q: {context}\nA: "
30
+ input_ids = tokenizer.encode(context_text, return_tensors="pt")
31
+ generated_outputs = model.generate(
32
+ input_ids=input_ids,
33
+ max_length=input_ids.shape[1] + max_new_tokens,
34
+ do_sample=True,
35
+ temperature=0.7,
36
+ eos_token_id=tokenizer.eos_token_id
37
+ )
38
+ generated_text = tokenizer.decode(generated_outputs[0], skip_special_tokens=True)
39
+ return generated_text.split("A:")[1].strip() if "A:" in generated_text else generated_text.strip()
40
+
41
+ # Gradio function
42
  def chatbot_response(question):
43
+ try:
44
+ answer = ask_question(question)
45
+ return f"Q: {question}\nA: {answer}"
46
+ except Exception as e:
47
+ return f"Error: {e}"
48
 
49
+ # Gradio app
50
  demo = gr.Interface(
51
  fn=chatbot_response,
52
  inputs="text",
53
  outputs="text",
54
  title="Religious Chatbot",
55
+ description="Ask questions about religious texts, and the chatbot will generate answers based on its knowledge."
56
  )
57
 
58
  # Launch the app
59
+ demo.launch()