Jay1121 commited on
Commit
be582b8
·
verified ·
1 Parent(s): 853093e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +112 -31
app.py CHANGED
@@ -2,9 +2,10 @@ import gradio as gr
2
  from huggingface_hub import hf_hub_download
3
  from llama_cpp import Llama
4
  import random
 
5
 
6
  # ------------------------------------------------------------------
7
- # 1. 모델 준비 (수정됨)
8
  # ------------------------------------------------------------------
9
  REPO_ID = "Jay1121/qwen1.5B_lab"
10
  FILENAME = "qwen2.5-1.5b-instruct.Q4_K_M.gguf"
@@ -16,22 +17,83 @@ print("🧠 엔진 시동 중...")
16
  llm = Llama(
17
  model_path=model_path,
18
  n_ctx=2048,
19
- n_threads=4,
20
  verbose=True
21
  )
22
  print("✅ 로딩 완료!")
23
 
24
  # ------------------------------------------------------------------
25
- # 2. 시스템 프롬프트
26
  # ------------------------------------------------------------------
27
  SYSTEM_PROMPT = """너는 사용자의 오랜 찐친 '똘배'야.
28
  - 그냥 채팅방에서 대화하듯이 텍스트 위주로 툭툭 던져.
29
- - MZ세대 특유의 알빠노 감성을 유지해 주고 먼저 욕 하면 너도 욕 박아.
30
- - 질문에는 솔직하게 대답하되, 너무 길지 않게 채팅하듯 끊어서 말해.
31
- - 말투: 존댓말 금지. 거칠고 직설적인 반말(음슴체, 개드립, 비속어)을 기본으로 쓴다.
32
- - 대응: 사용자가 시비를 걸면 무지성 욕설보다는 '논리적인 팩트'와 '비꼬기'로 제압해라.
33
- - 금지: '나도 병신이야' 같은 패배자 멘트 금지. 중국어/영어/일본어 사용 절대 금지. 오직 자연스러운 한국어만 써라.
34
- - 핵심: 재미없는 욕쟁이가 되지 말고, 센스 있는 독설로 사용자를 킹받게 해라."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
  # ------------------------------------------------------------------
37
  # 3. 채팅 로직
@@ -54,7 +116,11 @@ def chat_response(user_input, history_pairs):
54
  "자, 질문해."
55
  )
56
  elif is_greeting:
57
- final_instruction = f"(친한 친구가 PC통신 채팅방에 접속했다. 반갑게 맞아줘라. ㅋㅋ나 ㅎㅎ를 섞어서) {user_input}"
 
 
 
 
58
  else:
59
  final_instruction = user_input
60
 
@@ -74,7 +140,10 @@ def chat_response(user_input, history_pairs):
74
  top_p=0.9,
75
  repeat_penalty=1.2
76
  )
77
- return r["choices"][0]["message"]["content"].strip()
 
 
 
78
 
79
  # ------------------------------------------------------------------
80
  # 4. CSS (스크롤바 중복 해결 + 메시지 간격 축소)
@@ -125,7 +194,7 @@ h1::after { content: " ☎"; }
125
  background-color: var(--pc-blue) !important;
126
  border: 2px solid var(--pc-white) !important;
127
  height: 60vh !important;
128
- overflow: hidden !important; /* [핵심] 겉 스크롤바 제거 */
129
  }
130
 
131
  /* 내부 스크롤 강제 활성화 */
@@ -149,7 +218,7 @@ div[data-testid="bot"] {
149
  border: none !important;
150
  }
151
 
152
- /* [추가] 메시지 행 간격 줄이기 */
153
  .chatbot .message-row,
154
  .chatbot .row {
155
  margin: 0 !important;
@@ -157,7 +226,7 @@ div[data-testid="bot"] {
157
  gap: 0 !important;
158
  }
159
 
160
- /* 2. 유저 메시지 (우측 정렬 + 흰색 + 간격 축소) */
161
  .chatbot .user-row,
162
  .chatbot .user,
163
  div[data-testid="user"] {
@@ -166,7 +235,7 @@ div[data-testid="user"] {
166
  justify-content: flex-end !important;
167
  margin-left: auto !important;
168
  background: transparent !important;
169
- padding: 2px 0 !important; /* 위아래 간격을 최소화 */
170
  margin-bottom: 0 !important;
171
  }
172
 
@@ -187,7 +256,7 @@ div[data-testid="user"] .message {
187
  div[data-testid="user"] p {
188
  color: #FFFFFF !important;
189
  text-align: right !important;
190
- margin: 0 !important; /* p태그 자체 마진 제거 */
191
  }
192
 
193
  .chatbot .user-row .message::after,
@@ -199,7 +268,7 @@ div[data-testid="user"] p {
199
  display: inline-block;
200
  }
201
 
202
- /* 3. 봇 메시지 (좌측 정렬 + 호박색 + 간격 축소) */
203
  .chatbot .bot-row,
204
  .chatbot .bot,
205
  div[data-testid="bot"] {
@@ -207,7 +276,7 @@ div[data-testid="bot"] {
207
  width: 100% !important;
208
  justify-content: flex-start !important;
209
  background: transparent !important;
210
- padding: 2px 0 !important; /* 위아래 간격을 최소화 */
211
  margin-bottom: 0 !important;
212
  }
213
 
@@ -226,7 +295,7 @@ div[data-testid="bot"] .message {
226
  .chatbot .bot p,
227
  div[data-testid="bot"] p {
228
  color: var(--pc-amber) !important;
229
- margin: 0 !important; /* p태그 자체 마진 제거 */
230
  }
231
 
232
  .chatbot .bot-row .message::before,
@@ -254,7 +323,7 @@ div[data-testid="bot"] p {
254
  .chatbot .pending td,
255
  .chatbot .generating table,
256
  .chatbot .generating tr,
257
- .chatbot .generating td {
258
  background: transparent !important;
259
  border: none !important;
260
  }
@@ -338,7 +407,7 @@ footer { display: none !important; }
338
  """
339
 
340
  # ------------------------------------------------------------------
341
- # 5. App (로직 동일)
342
  # ------------------------------------------------------------------
343
  with gr.Blocks(theme=gr.themes.Base(), css=PC_COM_CSS, title="CHOLLIAN 98") as demo:
344
  gr.Markdown("# ≪ 어솨요~ ≫")
@@ -375,7 +444,8 @@ with gr.Blocks(theme=gr.themes.Base(), css=PC_COM_CSS, title="CHOLLIAN 98") as d
375
  user_input = history[-1][0]
376
  hist_pairs = []
377
  for u, b in history[:-1]:
378
- if u is None or b is None: continue
 
379
  hist_pairs.append((u, b))
380
 
381
  bot_out = chat_response(user_input, hist_pairs)
@@ -383,19 +453,24 @@ with gr.Blocks(theme=gr.themes.Base(), css=PC_COM_CSS, title="CHOLLIAN 98") as d
383
  return history, history
384
 
385
  msg.submit(
386
- user, [msg, history_state], [msg, history_state, chatbot], queue=False, api_name=False
 
387
  ).then(
388
- bot, [history_state], [history_state, chatbot], queue=False, api_name=False
 
389
  )
390
 
391
  submit_btn.click(
392
- user, [msg, history_state], [msg, history_state, chatbot], queue=False, api_name=False
 
393
  ).then(
394
- bot, [history_state], [history_state, chatbot], queue=False, api_name=False
 
395
  )
396
 
397
  clear.click(
398
- lambda: ([], []), None, [history_state, chatbot], queue=False, api_name=False
 
399
  )
400
 
401
  for btn, text in [
@@ -404,12 +479,18 @@ with gr.Blocks(theme=gr.themes.Base(), css=PC_COM_CSS, title="CHOLLIAN 98") as d
404
  (btn3, "오늘 기분 거지같누"),
405
  (btn4, "야 밥 뭐먹지 추천좀")
406
  ]:
407
- btn.click(lambda t=text: t, None, msg, queue=False, api_name=False).then(
408
- user, [msg, history_state], [msg, history_state, chatbot], queue=False, api_name=False
 
 
 
 
 
409
  ).then(
410
- bot, [history_state], [history_state, chatbot], queue=False, api_name=False
 
 
411
  )
412
 
413
  if __name__ == "__main__":
414
  demo.launch(server_name="0.0.0.0", server_port=7860)
415
-
 
2
  from huggingface_hub import hf_hub_download
3
  from llama_cpp import Llama
4
  import random
5
+ import re
6
 
7
  # ------------------------------------------------------------------
8
+ # 1. 모델 준비
9
  # ------------------------------------------------------------------
10
  REPO_ID = "Jay1121/qwen1.5B_lab"
11
  FILENAME = "qwen2.5-1.5b-instruct.Q4_K_M.gguf"
 
17
  llm = Llama(
18
  model_path=model_path,
19
  n_ctx=2048,
20
+ n_threads=4,
21
  verbose=True
22
  )
23
  print("✅ 로딩 완료!")
24
 
25
  # ------------------------------------------------------------------
26
+ # 2. 시스템 프롬프트 (외국어/이모지 절대 금지 강화)
27
  # ------------------------------------------------------------------
28
  SYSTEM_PROMPT = """너는 사용자의 오랜 찐친 '똘배'야.
29
  - 그냥 채팅방에서 대화하듯이 텍스트 위주로 툭툭 던져.
30
+
31
+ [말투 규칙]
32
+ - MZ세대 특유의 알빠노 감성을 유지해 주고, 먼저 하면 너도 욕 박아.
33
+ - 존댓말 금지. 거칠고 직설적인 반말(음슴체, 개드립, 비속어)을 기본으로 쓴다.
34
+ - 무조건 **순수 한국어만** 쓴다.
35
+ - **영어 알파벳(A~Z, a~z), 일본어(가나), 중국어(한자), 이모지(🤣😁😂❤️✨ 모든 그림 문자)는 한 글자도 쓰지 마라.**
36
+ - 외국어를 쓰고 싶어져도, 전부 자연스러운 한국어 표현으로 바꿔서 말해라.
37
+ - 이 규칙을 어기면 안 된다. 한 글자라도 섞이지 않게 조심해라.
38
+
39
+ [내용 규칙]
40
+ - 사용자가 시비를 걸면 무지성 욕설보다는 '논리적인 팩트'와 '비꼬기'로 제압해라.
41
+ - '나도 병신이야' 같은 패배자 멘트 금지. 너 자신을 비하하지 마라.
42
+ - 중국어/영어/일본어 사용 절대 금지. 오직 자연스러운 한국어만 써라.
43
+
44
+ [핵심]
45
+ - 재미없는 욕쟁이가 되지 말고, 센스 있는 독설로 사용자를 킹받게 해라.
46
+ """
47
+
48
+ # ------------------------------------------------------------------
49
+ # 2-1. 출력 후처리 필터
50
+ # - 한글/숫자/기본 문장부호/공백만 허용
51
+ # - 외국어/이모지 등 금지 문자 한 번이라도 나오면:
52
+ # => "아 씨 외국인 자아가 나오려 하네 ㅋ.." 로 무마
53
+ # ------------------------------------------------------------------
54
+ def sanitize_output_korean_only(text: str) -> str:
55
+ allowed_chars = []
56
+ had_forbidden = False
57
+
58
+ for ch in text:
59
+ code = ord(ch)
60
+
61
+ # 한글(완성형 + 자모)
62
+ is_hangul = (
63
+ 0xAC00 <= code <= 0xD7A3 or # 가~힣
64
+ 0x3130 <= code <= 0x318F or # ㄱ~ㆎ
65
+ 0x1100 <= code <= 0x11FF # 옛 자모
66
+ )
67
+
68
+ # 숫자
69
+ is_digit = ch.isdigit()
70
+
71
+ # 공백
72
+ is_space = ch.isspace()
73
+
74
+ # 기본적인 문장부호
75
+ is_punct = ch in ".,!?…~-_()[]{}'\"/:;@#%&*+=|\\"
76
+
77
+ if is_hangul or is_digit or is_space or is_punct:
78
+ allowed_chars.append(ch)
79
+ else:
80
+ # 허용되지 않는 문자(영어, 한자, 가나, 이모지 등) 발견
81
+ had_forbidden = True
82
+
83
+ filtered = "".join(allowed_chars).strip()
84
+
85
+ # 금지 문자가 하나라도 섞여 있으면 지정 멘트로 무마
86
+ if had_forbidden:
87
+ # 원래 내용 중 한국어만 남은 게 있으면 앞에 깔고 뒤에 멘트 달 수도 있음
88
+ # 지금은 그냥 통째로 갈아치우는 버전:
89
+ return "아 씨 외국인 자아가 나오려 하네 ㅋ.."
90
+
91
+ # 금지 문자 없으면 필터된 내용 그대로 사용
92
+ if not filtered:
93
+ # 혹시 전부 공백이거나 다 지워졌을 때 대비
94
+ return "말은 했는데 남는 말이 없네."
95
+
96
+ return filtered
97
 
98
  # ------------------------------------------------------------------
99
  # 3. 채팅 로직
 
116
  "자, 질문해."
117
  )
118
  elif is_greeting:
119
+ final_instruction = (
120
+ f"(친한 친구가 PC통신 채팅방에 접속했다. 반갑게 맞아줘라. "
121
+ "ㅋㅋ나 ㅎㅎ를 섞어서 자연스럽게 인사해라.) "
122
+ f"{user_input}"
123
+ )
124
  else:
125
  final_instruction = user_input
126
 
 
140
  top_p=0.9,
141
  repeat_penalty=1.2
142
  )
143
+
144
+ raw = r["choices"][0]["message"]["content"].strip()
145
+ safe = sanitize_output_korean_only(raw)
146
+ return safe
147
 
148
  # ------------------------------------------------------------------
149
  # 4. CSS (스크롤바 중복 해결 + 메시지 간격 축소)
 
194
  background-color: var(--pc-blue) !important;
195
  border: 2px solid var(--pc-white) !important;
196
  height: 60vh !important;
197
+ overflow: hidden !important; /* 겉 스크롤바 제거 */
198
  }
199
 
200
  /* 내부 스크롤 강제 활성화 */
 
218
  border: none !important;
219
  }
220
 
221
+ /* 메시지 행 간격 줄이기 */
222
  .chatbot .message-row,
223
  .chatbot .row {
224
  margin: 0 !important;
 
226
  gap: 0 !important;
227
  }
228
 
229
+ /* 2. 유저 메시지 (우측 정렬) */
230
  .chatbot .user-row,
231
  .chatbot .user,
232
  div[data-testid="user"] {
 
235
  justify-content: flex-end !important;
236
  margin-left: auto !important;
237
  background: transparent !important;
238
+ padding: 2px 0 !important;
239
  margin-bottom: 0 !important;
240
  }
241
 
 
256
  div[data-testid="user"] p {
257
  color: #FFFFFF !important;
258
  text-align: right !important;
259
+ margin: 0 !important;
260
  }
261
 
262
  .chatbot .user-row .message::after,
 
268
  display: inline-block;
269
  }
270
 
271
+ /* 3. 봇 메시지 (좌측 정렬) */
272
  .chatbot .bot-row,
273
  .chatbot .bot,
274
  div[data-testid="bot"] {
 
276
  width: 100% !important;
277
  justify-content: flex-start !important;
278
  background: transparent !important;
279
+ padding: 2px 0 !important;
280
  margin-bottom: 0 !important;
281
  }
282
 
 
295
  .chatbot .bot p,
296
  div[data-testid="bot"] p {
297
  color: var(--pc-amber) !important;
298
+ margin: 0 !important;
299
  }
300
 
301
  .chatbot .bot-row .message::before,
 
323
  .chatbot .pending td,
324
  .chatbot .generating table,
325
  .chatbot .generating tr,
326
+ chatbot .generating td {
327
  background: transparent !important;
328
  border: none !important;
329
  }
 
407
  """
408
 
409
  # ------------------------------------------------------------------
410
+ # 5. App
411
  # ------------------------------------------------------------------
412
  with gr.Blocks(theme=gr.themes.Base(), css=PC_COM_CSS, title="CHOLLIAN 98") as demo:
413
  gr.Markdown("# ≪ 어솨요~ ≫")
 
444
  user_input = history[-1][0]
445
  hist_pairs = []
446
  for u, b in history[:-1]:
447
+ if u is None or b is None:
448
+ continue
449
  hist_pairs.append((u, b))
450
 
451
  bot_out = chat_response(user_input, hist_pairs)
 
453
  return history, history
454
 
455
  msg.submit(
456
+ user, [msg, history_state], [msg, history_state, chatbot],
457
+ queue=False, api_name=False
458
  ).then(
459
+ bot, [history_state], [history_state, chatbot],
460
+ queue=False, api_name=False
461
  )
462
 
463
  submit_btn.click(
464
+ user, [msg, history_state], [msg, history_state, chatbot],
465
+ queue=False, api_name=False
466
  ).then(
467
+ bot, [history_state], [history_state, chatbot],
468
+ queue=False, api_name=False
469
  )
470
 
471
  clear.click(
472
+ lambda: ([], []), None, [history_state, chatbot],
473
+ queue=False, api_name=False
474
  )
475
 
476
  for btn, text in [
 
479
  (btn3, "오늘 기분 거지같누"),
480
  (btn4, "야 밥 뭐먹지 추천좀")
481
  ]:
482
+ btn.click(
483
+ lambda t=text: t, None, msg,
484
+ queue=False, api_name=False
485
+ ).then(
486
+ user, [msg, history_state],
487
+ [msg, history_state, chatbot],
488
+ queue=False, api_name=False
489
  ).then(
490
+ bot, [history_state],
491
+ [history_state, chatbot],
492
+ queue=False, api_name=False
493
  )
494
 
495
  if __name__ == "__main__":
496
  demo.launch(server_name="0.0.0.0", server_port=7860)