openfree commited on
Commit
56fd5f8
ยท
verified ยท
1 Parent(s): 085f012

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +147 -60
app.py CHANGED
@@ -12,9 +12,17 @@ import gradio as gr
12
  import spaces
13
  import torch
14
  from loguru import logger
15
- from transformers import AutoTokenizer, AutoModelForCausalLM, TextIteratorStreamer, BitsAndBytesConfig
16
  from peft import PeftModel
17
 
 
 
 
 
 
 
 
 
18
  # CSV/TXT ๋ถ„์„
19
  import pandas as pd
20
  # PDF ํ…์ŠคํŠธ ์ถ”์ถœ
@@ -56,9 +64,19 @@ def extract_keywords(text: str, top_k: int = 5) -> str:
56
  2) ๊ณต๋ฐฑ ๊ธฐ์ค€ ํ† ํฐ ๋ถ„๋ฆฌ
57
  3) ์ตœ๋Œ€ top_k๊ฐœ๋งŒ
58
  """
59
- text = re.sub(r"[^a-zA-Z0-9๊ฐ€-ํžฃ\s]", "", text)
 
60
  tokens = text.split()
61
- key_tokens = tokens[:top_k]
 
 
 
 
 
 
 
 
 
62
  return " ".join(key_tokens)
63
 
64
  ##############################################################################
@@ -128,12 +146,15 @@ def do_web_search(query: str) -> str:
128
  )
129
 
130
  instructions = """
131
- # ์›น ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ
 
132
  ์•„๋ž˜๋Š” ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค. ์งˆ๋ฌธ์— ๋‹ต๋ณ€ํ•  ๋•Œ ์ด ์ •๋ณด๋ฅผ ํ™œ์šฉํ•˜์„ธ์š”:
133
- 1. ๊ฐ ๊ฒฐ๊ณผ์˜ ์ œ๋ชฉ, ๋‚ด์šฉ, ์ถœ์ฒ˜ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”
134
- 2. ๋‹ต๋ณ€์— ๊ด€๋ จ ์ •๋ณด์˜ ์ถœ์ฒ˜๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ธ์šฉํ•˜์„ธ์š” (์˜ˆ: "X ์ถœ์ฒ˜์— ๋”ฐ๋ฅด๋ฉด...")
135
- 3. ์‘๋‹ต์— ์‹ค์ œ ์ถœ์ฒ˜ ๋งํฌ๋ฅผ ํฌํ•จํ•˜์„ธ์š”
136
- 4. ์—ฌ๋Ÿฌ ์ถœ์ฒ˜์˜ ์ •๋ณด๋ฅผ ์ข…ํ•ฉํ•˜์—ฌ ๋‹ต๋ณ€ํ•˜์„ธ์š”
 
 
137
  """
138
 
139
  search_results = instructions + "\n".join(summary_lines)
@@ -158,24 +179,52 @@ def load_model(model_name="VIDraft/Gemma-3-R1984-1B", adapter_name="openfree/Gem
158
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
159
  logger.info(f"Using device: {device}")
160
 
161
- bnb_config = BitsAndBytesConfig(
162
- load_in_4bit=True,
163
- bnb_4bit_use_double_quant=True,
164
- bnb_4bit_quant_type="nf4",
165
- bnb_4bit_compute_dtype=torch.bfloat16,
166
- )
167
-
168
- # ๋ฒ ์ด์Šค ๋ชจ๋ธ ๋กœ๋“œ
169
- model = AutoModelForCausalLM.from_pretrained(
170
- model_name,
171
- quantization_config=bnb_config,
172
- device_map="auto",
173
- trust_remote_code=False,
174
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
 
176
  # ํ† ํฌ๋‚˜์ด์ € ๋กœ๋“œ (๋ฒ ์ด์Šค ๋ชจ๋ธ๊ณผ ๋™์ผํ•œ ํ† ํฌ๏ฟฝ๏ฟฝ์ด์ € ์‚ฌ์šฉ)
177
  tokenizer = AutoTokenizer.from_pretrained(model_name)
178
  tokenizer.pad_token = tokenizer.eos_token
 
 
 
179
 
180
  # PEFT ์–ด๋Œ‘ํ„ฐ ๋กœ๋“œ ๋ฐ ๋ฒ ์ด์Šค ๋ชจ๋ธ์— ๋ณ‘ํ•ฉ
181
  try:
@@ -186,6 +235,10 @@ def load_model(model_name="VIDraft/Gemma-3-R1984-1B", adapter_name="openfree/Gem
186
  logger.warning("์–ด๋Œ‘ํ„ฐ ๋กœ๋”ฉ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฒ ์ด์Šค ๋ชจ๋ธ๋กœ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.")
187
 
188
  model.eval() # ์ถ”๋ก  ๋ชจ๋“œ๋กœ ์„ค์ •
 
 
 
 
189
 
190
  logger.info("๋ชจ๋ธ ๋ฐ ํ† ํฌ๋‚˜์ด์ € ๋กœ๋”ฉ ์™„๋ฃŒ")
191
  return model, tokenizer
@@ -351,7 +404,12 @@ def run(
351
  logger.info(f"[Auto WebSearch Keyword] {ws_query!r}")
352
  ws_result = do_web_search(ws_query)
353
  full_prompt += f"[Web Search Results]\n{ws_result}\n\n"
354
- full_prompt += "[์ค‘์š”: ์œ„ ๊ฒ€์ƒ‰๊ฒฐ๊ณผ์˜ ์ถœ์ฒ˜๋ฅผ ์ธ์šฉํ•˜์—ฌ ๋‹ต๋ณ€ํ•ด ์ฃผ์„ธ์š”.]\n\n"
 
 
 
 
 
355
 
356
  # ๋Œ€ํ™” ํžˆ์Šคํ† ๋ฆฌ
357
  if history:
@@ -360,7 +418,20 @@ def run(
360
 
361
  # ํ˜„์žฌ ์‚ฌ์šฉ์ž ๋ฉ”์‹œ์ง€
362
  user_content = process_new_user_message(message)
363
- full_prompt += f"\nUser: {user_content}\nAssistant:"
 
 
 
 
 
 
 
 
 
 
 
 
 
364
 
365
  # ํ† ํฐํ™”
366
  inputs = tokenizer(
@@ -382,8 +453,10 @@ def run(
382
  inputs,
383
  streamer=streamer,
384
  max_new_tokens=max_new_tokens,
385
- temperature=0.7,
386
- top_p=0.9,
 
 
387
  do_sample=True,
388
  )
389
 
@@ -393,8 +466,15 @@ def run(
393
 
394
  # ์ŠคํŠธ๋ฆฌ๋ฐ ์ถœ๋ ฅ
395
  output = ""
 
396
  for new_text in streamer:
397
  output += new_text
 
 
 
 
 
 
398
  yield output
399
 
400
  except Exception as e:
@@ -415,17 +495,17 @@ def run(
415
  examples = [
416
  [
417
  {
418
- "text": "Compare the contents of the two PDF files.",
419
- "files": [
420
- "assets/additional-examples/before.pdf",
421
- "assets/additional-examples/after.pdf",
422
- ],
423
  }
424
  ],
425
  [
426
  {
427
- "text": "Summarize and analyze the contents of the CSV file.",
428
- "files": ["assets/additional-examples/sample-csv.csv"],
 
 
 
429
  }
430
  ],
431
  [
@@ -436,13 +516,13 @@ examples = [
436
  ],
437
  [
438
  {
439
- "text": "Analyze the data trends in this CSV file.",
440
  "files": ["assets/additional-examples/data.csv"],
441
  }
442
  ],
443
  [
444
  {
445
- "text": "Summarize the main points from this text document.",
446
  "files": ["assets/additional-examples/document.txt"],
447
  }
448
  ],
@@ -486,37 +566,44 @@ button:hover, .btn:hover {
486
  """
487
 
488
  title_html = """
489
- <h1 align="center" style="margin-bottom: 0.2em; font-size: 1.6em;"> ๐Ÿค— Gemma3-R1984-1B (Text Only) </h1>
490
  <p align="center" style="font-size:1.1em; color:#555;">
491
- โœ…Agentic AI Platform โœ…Reasoning โœ…Text Analysis โœ…Deep-Research & RAG <br>
492
- โœ…Document Processing (PDF, CSV, TXT) โœ…Web Search Integration<br>
493
- Operates on an โœ…'NVIDIA L40s / A100(ZeroGPU) GPU' as an independent local server<br>
494
- @Model Repository: VIDraft/Gemma-3-R1984-1B, @Based by 'Google Gemma-3-1b'
495
  </p>
496
  """
497
 
498
  with gr.Blocks(css=css, title="Gemma3-R1984-1B") as demo:
499
  gr.Markdown(title_html)
500
 
501
- web_search_checkbox = gr.Checkbox(
502
- label="Deep Research",
503
- value=False
504
- )
505
-
506
- system_prompt_box = gr.Textbox(
507
- lines=3,
508
- value="You are a deep thinking AI that may use extremely long chains of thought to thoroughly analyze the problem and deliberate using systematic reasoning processes to arrive at a correct solution before answering.",
509
- visible=False
510
- )
511
-
512
- max_tokens_slider = gr.Slider(
513
- label="Max New Tokens",
514
- minimum=100,
515
- maximum=8000,
516
- step=50,
517
- value=1000,
518
- visible=False
519
- )
 
 
 
 
 
 
 
520
 
521
  web_search_text = gr.Textbox(
522
  lines=1,
@@ -552,7 +639,7 @@ with gr.Blocks(css=css, title="Gemma3-R1984-1B") as demo:
552
 
553
  with gr.Row(elem_id="examples_row"):
554
  with gr.Column(scale=12, elem_id="examples_container"):
555
- gr.Markdown("### Example Inputs (click to load)")
556
 
557
  if __name__ == "__main__":
558
  demo.launch()
 
12
  import spaces
13
  import torch
14
  from loguru import logger
15
+ from transformers import AutoTokenizer, AutoModelForCausalLM, TextIteratorStreamer
16
  from peft import PeftModel
17
 
18
+ # BitsAndBytesConfig๋Š” ์กฐ๊ฑด๋ถ€๋กœ import
19
+ try:
20
+ from transformers import BitsAndBytesConfig
21
+ BITSANDBYTES_AVAILABLE = True
22
+ except ImportError:
23
+ logger.warning("BitsAndBytesConfig๋ฅผ importํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์–‘์žํ™” ๊ธฐ๋Šฅ์ด ๋น„ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.")
24
+ BITSANDBYTES_AVAILABLE = False
25
+
26
  # CSV/TXT ๋ถ„์„
27
  import pandas as pd
28
  # PDF ํ…์ŠคํŠธ ์ถ”์ถœ
 
64
  2) ๊ณต๋ฐฑ ๊ธฐ์ค€ ํ† ํฐ ๋ถ„๋ฆฌ
65
  3) ์ตœ๋Œ€ top_k๊ฐœ๋งŒ
66
  """
67
+ # ํŠน์ˆ˜๋ฌธ์ž ์ œ๊ฑฐํ•˜๋˜ ๊ธฐ๋ณธ์ ์ธ ๋ฌธ์žฅ ๋ถ€ํ˜ธ๋Š” ์œ ์ง€
68
+ text = re.sub(r"[^a-zA-Z0-9๊ฐ€-ํžฃ\s\.\,\?\!]", "", text)
69
  tokens = text.split()
70
+
71
+ # ์ค‘๋ณต ์ œ๊ฑฐํ•˜๋ฉด์„œ ์ˆœ์„œ ์œ ์ง€
72
+ seen = set()
73
+ unique_tokens = []
74
+ for token in tokens:
75
+ if token not in seen and len(token) > 1: # 1๊ธ€์ž ๋‹จ์–ด ์ œ์™ธ
76
+ seen.add(token)
77
+ unique_tokens.append(token)
78
+
79
+ key_tokens = unique_tokens[:top_k]
80
  return " ".join(key_tokens)
81
 
82
  ##############################################################################
 
146
  )
147
 
148
  instructions = """
149
+ # ์›น ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ / Web Search Results
150
+
151
  ์•„๋ž˜๋Š” ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค. ์งˆ๋ฌธ์— ๋‹ต๋ณ€ํ•  ๋•Œ ์ด ์ •๋ณด๋ฅผ ํ™œ์šฉํ•˜์„ธ์š”:
152
+ Below are the search results. Use this information when answering the question:
153
+
154
+ 1. ๊ฐ ๊ฒฐ๊ณผ์˜ ์ œ๋ชฉ, ๋‚ด์šฉ, ์ถœ์ฒ˜ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š” / Reference the title, content, and source links
155
+ 2. ๋‹ต๋ณ€์— ๊ด€๋ จ ์ •๋ณด์˜ ์ถœ์ฒ˜๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ธ์šฉํ•˜์„ธ์š” / Explicitly cite relevant sources
156
+ 3. ์‘๋‹ต์— ์‹ค์ œ ์ถœ์ฒ˜ ๋งํฌ๋ฅผ ํฌํ•จํ•˜์„ธ์š” / Include actual source links in response
157
+ 4. ์—ฌ๋Ÿฌ ์ถœ์ฒ˜์˜ ์ •๋ณด๋ฅผ ์ข…ํ•ฉํ•˜์—ฌ ๋‹ต๋ณ€ํ•˜์„ธ์š” / Synthesize information from multiple sources
158
  """
159
 
160
  search_results = instructions + "\n".join(summary_lines)
 
179
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
180
  logger.info(f"Using device: {device}")
181
 
182
+ # ์–‘์žํ™” ์„ค์ •์„ ์‹œ๋„ํ•˜๋˜, ์‹คํŒจํ•˜๋ฉด ์ผ๋ฐ˜ ๋กœ๋“œ
183
+ if BITSANDBYTES_AVAILABLE:
184
+ try:
185
+ # bitsandbytes๊ฐ€ ์„ค์น˜๋˜์–ด ์žˆ๋Š”์ง€ ์ถ”๊ฐ€ ํ™•์ธ
186
+ import bitsandbytes
187
+ bnb_config = BitsAndBytesConfig(
188
+ load_in_4bit=True,
189
+ bnb_4bit_use_double_quant=True,
190
+ bnb_4bit_quant_type="nf4",
191
+ bnb_4bit_compute_dtype=torch.bfloat16,
192
+ )
193
+
194
+ # ๋ฒ ์ด์Šค ๋ชจ๋ธ ๋กœ๋“œ (์–‘์žํ™” ์ ์šฉ)
195
+ model = AutoModelForCausalLM.from_pretrained(
196
+ model_name,
197
+ quantization_config=bnb_config,
198
+ device_map="auto",
199
+ trust_remote_code=False,
200
+ )
201
+ logger.info("4-bit ์–‘์žํ™”๋กœ ๋ชจ๋ธ ๋กœ๋“œ ์™„๋ฃŒ")
202
+
203
+ except ImportError:
204
+ logger.warning("bitsandbytes๊ฐ€ ์„ค์น˜๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์–‘์žํ™” ์—†์ด ๋ชจ๋ธ์„ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.")
205
+ # ๋ฒ ์ด์Šค ๋ชจ๋ธ ๋กœ๋“œ (์–‘์žํ™” ์—†์ด)
206
+ model = AutoModelForCausalLM.from_pretrained(
207
+ model_name,
208
+ torch_dtype=torch.float16, # GPU ๋ฉ”๋ชจ๋ฆฌ ์ ˆ์•ฝ์„ ์œ„ํ•ด float16 ์‚ฌ์šฉ
209
+ device_map="auto",
210
+ trust_remote_code=False,
211
+ )
212
+ else:
213
+ logger.info("BitsAndBytesConfig๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜ ๋ชจ๋“œ๋กœ ๋ชจ๋ธ์„ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.")
214
+ # ๋ฒ ์ด์Šค ๋ชจ๋ธ ๋กœ๋“œ (์–‘์žํ™” ์—†์ด)
215
+ model = AutoModelForCausalLM.from_pretrained(
216
+ model_name,
217
+ torch_dtype=torch.float16, # GPU ๋ฉ”๋ชจ๋ฆฌ ์ ˆ์•ฝ์„ ์œ„ํ•ด float16 ์‚ฌ์šฉ
218
+ device_map="auto",
219
+ trust_remote_code=False,
220
+ )
221
 
222
  # ํ† ํฌ๋‚˜์ด์ € ๋กœ๋“œ (๋ฒ ์ด์Šค ๋ชจ๋ธ๊ณผ ๋™์ผํ•œ ํ† ํฌ๏ฟฝ๏ฟฝ์ด์ € ์‚ฌ์šฉ)
223
  tokenizer = AutoTokenizer.from_pretrained(model_name)
224
  tokenizer.pad_token = tokenizer.eos_token
225
+
226
+ # ํ•œ๊ธ€ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ์ถ”๊ฐ€ ์„ค์ •
227
+ tokenizer.model_max_length = MAX_INPUT_LENGTH
228
 
229
  # PEFT ์–ด๋Œ‘ํ„ฐ ๋กœ๋“œ ๋ฐ ๋ฒ ์ด์Šค ๋ชจ๋ธ์— ๋ณ‘ํ•ฉ
230
  try:
 
235
  logger.warning("์–ด๋Œ‘ํ„ฐ ๋กœ๋”ฉ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฒ ์ด์Šค ๋ชจ๋ธ๋กœ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.")
236
 
237
  model.eval() # ์ถ”๋ก  ๋ชจ๋“œ๋กœ ์„ค์ •
238
+
239
+ # ๋ชจ๋ธ ์„ค์ • ๋กœ๊น…
240
+ logger.info(f"๋ชจ๋ธ ์„ค์ • - device: {device}, dtype: {model.dtype}")
241
+ logger.info(f"ํ† ํฌ๋‚˜์ด์ € ์„ค์ • - vocab_size: {tokenizer.vocab_size}, max_length: {tokenizer.model_max_length}")
242
 
243
  logger.info("๋ชจ๋ธ ๋ฐ ํ† ํฌ๋‚˜์ด์ € ๋กœ๋”ฉ ์™„๋ฃŒ")
244
  return model, tokenizer
 
404
  logger.info(f"[Auto WebSearch Keyword] {ws_query!r}")
405
  ws_result = do_web_search(ws_query)
406
  full_prompt += f"[Web Search Results]\n{ws_result}\n\n"
407
+
408
+ # ์–ธ์–ด์— ๋”ฐ๋ฅธ ์ง€์‹œ์‚ฌํ•ญ
409
+ if any(ord('๊ฐ€') <= ord(char) <= ord('ํžฃ') for char in user_text):
410
+ full_prompt += "[์ค‘์š”: ์œ„ ๊ฒ€์ƒ‰๊ฒฐ๊ณผ์˜ ์ถœ์ฒ˜๋ฅผ ํ•œ๊ธ€๋กœ ์ธ์šฉํ•˜์—ฌ ๋‹ต๋ณ€ํ•ด ์ฃผ์„ธ์š”.]\n\n"
411
+ else:
412
+ full_prompt += "[Important: Please cite the sources from the search results above.]\n\n"
413
 
414
  # ๋Œ€ํ™” ํžˆ์Šคํ† ๋ฆฌ
415
  if history:
 
418
 
419
  # ํ˜„์žฌ ์‚ฌ์šฉ์ž ๋ฉ”์‹œ์ง€
420
  user_content = process_new_user_message(message)
421
+
422
+ # ์–ธ์–ด ๊ฐ์ง€ ๋ฐ ์ถ”๊ฐ€ ์ง€์‹œ์‚ฌํ•ญ
423
+ has_korean = any(ord('๊ฐ€') <= ord(char) <= ord('ํžฃ') for char in user_content)
424
+ if has_korean:
425
+ lang_instruction = "\n[์ค‘์š”: ๋ฐ˜๋“œ์‹œ ํ•œ๊ธ€๋กœ ๋‹ต๋ณ€ํ•˜์„ธ์š”. ์˜์–ด๋กœ ๋‹ต๋ณ€ํ•˜์ง€ ๋งˆ์„ธ์š”.]\n"
426
+ logger.info("ํ•œ๊ธ€ ์งˆ๋ฌธ ๊ฐ์ง€ - ํ•œ๊ธ€ ๋‹ต๋ณ€ ๋ชจ๋“œ")
427
+ else:
428
+ lang_instruction = ""
429
+ logger.info("์˜์–ด ์งˆ๋ฌธ ๊ฐ์ง€ - ์˜์–ด ๋‹ต๋ณ€ ๋ชจ๋“œ")
430
+
431
+ full_prompt += f"\nUser: {user_content}{lang_instruction}\nAssistant:"
432
+
433
+ # ํ”„๋กฌํ”„ํŠธ ๊ธธ์ด ๋กœ๊น…
434
+ logger.info(f"ํ”„๋กฌํ”„ํŠธ ๊ธธ์ด: {len(full_prompt)} ๋ฌธ์ž")
435
 
436
  # ํ† ํฐํ™”
437
  inputs = tokenizer(
 
453
  inputs,
454
  streamer=streamer,
455
  max_new_tokens=max_new_tokens,
456
+ temperature=0.8, # 0.7์—์„œ 0.8๋กœ ์ฆ๊ฐ€
457
+ top_p=0.95, # 0.9์—์„œ 0.95๋กœ ์ฆ๊ฐ€
458
+ top_k=50, # top_k ์ถ”๊ฐ€
459
+ repetition_penalty=1.1, # ๋ฐ˜๋ณต ๋ฐฉ์ง€ ์ถ”๊ฐ€
460
  do_sample=True,
461
  )
462
 
 
466
 
467
  # ์ŠคํŠธ๋ฆฌ๋ฐ ์ถœ๋ ฅ
468
  output = ""
469
+ chunk_count = 0
470
  for new_text in streamer:
471
  output += new_text
472
+ chunk_count += 1
473
+
474
+ # ์ฃผ๊ธฐ์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ์ •๋ฆฌ
475
+ if chunk_count % 100 == 0:
476
+ gc.collect()
477
+
478
  yield output
479
 
480
  except Exception as e:
 
495
  examples = [
496
  [
497
  {
498
+ "text": "์ด CSV ํŒŒ์ผ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„์„ํ•˜๊ณ  ์ฃผ์š” ์ธ์‚ฌ์ดํŠธ๋ฅผ ํ•œ๊ธ€๋กœ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”.",
499
+ "files": ["assets/additional-examples/sample-csv.csv"],
 
 
 
500
  }
501
  ],
502
  [
503
  {
504
+ "text": "๋‘ PDF ํŒŒ์ผ์˜ ๋‚ด์šฉ์„ ๋น„๊ต ๋ถ„์„ํ•ด์ฃผ์„ธ์š”.",
505
+ "files": [
506
+ "assets/additional-examples/before.pdf",
507
+ "assets/additional-examples/after.pdf",
508
+ ],
509
  }
510
  ],
511
  [
 
516
  ],
517
  [
518
  {
519
+ "text": "์ด ๋ฐ์ดํ„ฐ์˜ ์ถ”์„ธ๋ฅผ ๋ถ„์„ํ•˜๊ณ  ํ–ฅํ›„ ์˜ˆ์ธก์„ ์ œ์‹œํ•ด์ฃผ์„ธ์š”.",
520
  "files": ["assets/additional-examples/data.csv"],
521
  }
522
  ],
523
  [
524
  {
525
+ "text": "ํ…์ŠคํŠธ ๋ฌธ์„œ์˜ ํ•ต์‹ฌ ๋‚ด์šฉ์„ ์š”์•ฝํ•˜๊ณ  ์ค‘์š”ํ•œ ํฌ์ธํŠธ๋ฅผ ์ •๋ฆฌํ•ด์ฃผ์„ธ์š”.",
526
  "files": ["assets/additional-examples/document.txt"],
527
  }
528
  ],
 
566
  """
567
 
568
  title_html = """
569
+ <h1 align="center" style="margin-bottom: 0.2em; font-size: 1.6em;"> ๐Ÿค— Gemma3-R1984-1B (ํ…์ŠคํŠธ ์ „์šฉ) </h1>
570
  <p align="center" style="font-size:1.1em; color:#555;">
571
+ โœ…์—์ด์ „ํ‹ฑ AI ํ”Œ๋žซํผ โœ…์ถ”๋ก  ๋ฐ ๋ถ„์„ โœ…ํ…์ŠคํŠธ ๋ถ„์„ โœ…์‹ฌ์ธต ์—ฐ๊ตฌ & RAG <br>
572
+ โœ…๋ฌธ์„œ ์ฒ˜๋ฆฌ (PDF, CSV, TXT) โœ…์›น ๊ฒ€์ƒ‰ ํ†ตํ•ฉ โœ…ํ•œ๊ธ€/์˜์–ด ์ง€์›<br>
573
+ โœ…'NVIDIA L40s / A100(ZeroGPU) GPU'์—์„œ ๋…๋ฆฝ ๋กœ์ปฌ ์„œ๋ฒ„๋กœ ์ž‘๋™<br>
574
+ @๋ชจ๋ธ ์ €์žฅ์†Œ: VIDraft/Gemma-3-R1984-1B, @๊ธฐ๋ฐ˜: 'Google Gemma-3-1b'
575
  </p>
576
  """
577
 
578
  with gr.Blocks(css=css, title="Gemma3-R1984-1B") as demo:
579
  gr.Markdown(title_html)
580
 
581
+ with gr.Accordion("๊ณ ๊ธ‰ ์„ค์ •", open=False):
582
+ web_search_checkbox = gr.Checkbox(
583
+ label="Deep Research (์›น ๊ฒ€์ƒ‰ ํ™œ์„ฑํ™”)",
584
+ value=False
585
+ )
586
+
587
+ max_tokens_slider = gr.Slider(
588
+ label="์ตœ๋Œ€ ํ† ํฐ ์ˆ˜ (๋‹ต๋ณ€ ๊ธธ์ด)",
589
+ minimum=100,
590
+ maximum=8000,
591
+ step=50,
592
+ value=2048,
593
+ info="๋” ๊ธด ๋‹ต๋ณ€์„ ์›ํ•˜์‹œ๋ฉด ์ด ๊ฐ’์„ ๋Š˜๋ ค์ฃผ์„ธ์š”"
594
+ )
595
+
596
+ system_prompt_box = gr.Textbox(
597
+ lines=5,
598
+ label="์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ",
599
+ value="""๋‹น์‹ ์€ ์‹ฌ์ธต์ ์ธ ์‚ฌ๊ณ ๋ฅผ ํ•˜๋Š” AI ์–ด์‹œ์Šคํ„ดํŠธ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ์ง€์นจ์„ ๋”ฐ๋ผ์ฃผ์„ธ์š”:
600
+
601
+ 1. **์–ธ์–ด**: ์‚ฌ์šฉ์ž๊ฐ€ ํ•œ๊ธ€๋กœ ์งˆ๋ฌธํ•˜๋ฉด ๋ฐ˜๋“œ์‹œ ํ•œ๊ธ€๋กœ ๋‹ต๋ณ€ํ•˜์„ธ์š”. ์˜์–ด๋กœ ์งˆ๋ฌธํ•˜๋ฉด ์˜์–ด๋กœ ๋‹ต๋ณ€ํ•˜์„ธ์š”.
602
+ 2. **๋‹ต๋ณ€ ๊ธธ์ด**: ์ถฉ๋ถ„ํžˆ ์ƒ์„ธํ•˜๊ณ  ํ’๋ถ€ํ•œ ๋‹ต๋ณ€์„ ์ œ๊ณตํ•˜์„ธ์š”. ์ตœ์†Œ 3-5๊ฐœ ๋ฌธ๋‹จ์œผ๋กœ ๊ตฌ์„ฑ๋œ ๋‹ต๋ณ€์„ ์ž‘์„ฑํ•˜์„ธ์š”.
603
+ 3. **๋ถ„์„ ๋ฐฉ์‹**: ๋ฌธ์ œ๋ฅผ ์ฒ ์ €ํžˆ ๋ถ„์„ํ•˜๊ณ , ์ฒด๊ณ„์ ์ธ ์ถ”๋ก  ๊ณผ์ •์„ ๊ฑฐ์ณ ์ •ํ™•ํ•œ ํ•ด๋‹ต์„ ์ œ์‹œํ•˜์„ธ์š”.
604
+ 4. **๊ตฌ์กฐ**: ๋‹ต๋ณ€์„ ๋ช…ํ™•ํ•œ ๊ตฌ์กฐ๋กœ ๊ตฌ์„ฑํ•˜๊ณ , ํ•„์š”์‹œ ๋ฒˆํ˜ธ๋‚˜ ๋ถˆ๋ฆฟ ํฌ์ธํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.
605
+ 5. **์˜ˆ์‹œ์™€ ์„ค๋ช…**: ๊ฐ€๋Šฅํ•œ ํ•œ ๊ตฌ์ฒด์ ์ธ ์˜ˆ์‹œ์™€ ์ƒ์„ธํ•œ ์„ค๋ช…์„ ํฌํ•จํ•˜์„ธ์š”."""
606
+ )
607
 
608
  web_search_text = gr.Textbox(
609
  lines=1,
 
639
 
640
  with gr.Row(elem_id="examples_row"):
641
  with gr.Column(scale=12, elem_id="examples_container"):
642
+ gr.Markdown("### ์˜ˆ์‹œ ์ž…๋ ฅ (ํด๋ฆญํ•˜์—ฌ ๋กœ๋“œ)")
643
 
644
  if __name__ == "__main__":
645
  demo.launch()