ogx786 commited on
Commit
37abe8d
·
verified ·
1 Parent(s): 8591efd

Create chatbot_local.py

Browse files
Files changed (1) hide show
  1. chatbot_local.py +123 -0
chatbot_local.py ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from threading import Thread
3
+ from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
4
+
5
+
6
+ # ==================================================
7
+ # CONFIG
8
+ # ==================================================
9
+
10
+ # Either the HF hub id (auto-downloads + caches on first run):
11
+ MODEL_PATH = "Qwen/Qwen2.5-0.5B-Instruct"
12
+ # ...or a local folder if you already downloaded it yourself
13
+ # (e.g. via snapshot_download or git lfs clone), e.g.:
14
+ # MODEL_PATH = "./Qwen2.5-0.5B-Instruct"
15
+
16
+ SYSTEM_PROMPT = "You are a helpful assistant."
17
+
18
+ MAX_NEW_TOKENS = 512
19
+ HISTORY_TURNS = 6 # number of past user/assistant exchanges kept as context
20
+
21
+ device = "cuda" if torch.cuda.is_available() else "cpu"
22
+ dtype = torch.bfloat16 if torch.cuda.is_available() else torch.float32
23
+
24
+
25
+ # ==================================================
26
+ # LOAD MODEL
27
+ # ==================================================
28
+
29
+ print("Loading tokenizer...")
30
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH)
31
+
32
+ print("Loading model...")
33
+ model = AutoModelForCausalLM.from_pretrained(MODEL_PATH, torch_dtype=dtype)
34
+ model.to(device)
35
+ model.eval()
36
+
37
+ print("Device:", device)
38
+
39
+
40
+ # ==================================================
41
+ # PROMPT BUILDING
42
+ # ==================================================
43
+
44
+ def build_prompt(history, user_input):
45
+ messages = [{"role": "system", "content": SYSTEM_PROMPT}]
46
+
47
+ for role, text in history:
48
+ messages.append({"role": role, "content": text})
49
+
50
+ messages.append({"role": "user", "content": user_input})
51
+
52
+ return tokenizer.apply_chat_template(
53
+ messages,
54
+ tokenize=False,
55
+ add_generation_prompt=True,
56
+ )
57
+
58
+
59
+ # ==================================================
60
+ # GENERATION (streamed)
61
+ # ==================================================
62
+
63
+ def generate_reply(history, user_input):
64
+ prompt = build_prompt(history, user_input)
65
+ inputs = tokenizer(prompt, return_tensors="pt").to(device)
66
+
67
+ streamer = TextIteratorStreamer(
68
+ tokenizer,
69
+ skip_prompt=True,
70
+ skip_special_tokens=True,
71
+ )
72
+
73
+ generation_kwargs = dict(
74
+ **inputs,
75
+ streamer=streamer,
76
+ max_new_tokens=MAX_NEW_TOKENS,
77
+ do_sample=True,
78
+ temperature=0.7,
79
+ top_p=0.9,
80
+ repetition_penalty=1.1,
81
+ pad_token_id=tokenizer.eos_token_id,
82
+ )
83
+
84
+ thread = Thread(target=model.generate, kwargs=generation_kwargs)
85
+ thread.start()
86
+
87
+ full_text = ""
88
+ for token in streamer:
89
+ print(token, end="", flush=True)
90
+ full_text += token
91
+
92
+ thread.join()
93
+ print()
94
+
95
+ return full_text
96
+
97
+
98
+ # ==================================================
99
+ # CHAT
100
+ # ==================================================
101
+
102
+ print("\n" + "=" * 60)
103
+ print("Qwen2.5-0.5B-Instruct Chatbot")
104
+ print("Type exit to quit")
105
+ print("=" * 60)
106
+
107
+ history = [] # list of (role, text) tuples, most recent last
108
+
109
+ while True:
110
+ user_input = input("\nUser: ")
111
+
112
+ if user_input.lower() == "exit":
113
+ break
114
+
115
+ if not user_input.strip():
116
+ continue
117
+
118
+ print("\nAssistant:")
119
+ reply = generate_reply(history, user_input)
120
+
121
+ history.append(("user", user_input))
122
+ history.append(("assistant", reply))
123
+ history = history[-HISTORY_TURNS * 2:]