ginipick commited on
Commit
eadc038
·
verified ·
1 Parent(s): 6523f76

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +201 -134
app.py CHANGED
@@ -1,65 +1,82 @@
1
- import sys
2
- import subprocess
3
- import os
4
-
5
- # First, try to install all dependencies
6
- packages_to_install = [
7
- "gradio",
8
- "torch",
9
- "transformers",
10
- "accelerate",
11
- "einops",
12
- "timm",
13
- "av",
14
- "opencv-python-headless" # Using headless version for better compatibility
15
- ]
16
-
17
- for package in packages_to_install:
18
- print(f"Installing {package}...")
19
- try:
20
- subprocess.check_call([sys.executable, "-m", "pip", "install", package])
21
- print(f"Successfully installed {package}")
22
- except Exception as e:
23
- print(f"Error installing {package}: {e}")
24
-
25
- # Now proceed with the actual application
26
  import gradio as gr
27
  import torch
28
  from transformers import AutoModelForCausalLM, AutoTokenizer
29
  import gc
 
30
  import datetime
31
  import time
32
- import spaces
33
 
34
- # --- 설정 ---
35
- MODEL_ID = "naver-hyperclovax/HyperCLOVAX-SEED-Vision-Instruct-3B"
36
  MAX_NEW_TOKENS = 512
 
37
 
38
  # Hugging Face 토큰 설정 - 환경 변수에서 가져오기
39
  HF_TOKEN = os.getenv("HF_TOKEN")
40
  if not HF_TOKEN:
41
  print("경고: HF_TOKEN 환경 변수가 설정되지 않았습니다. 비공개 모델에 접근할 수 없을 수 있습니다.")
42
 
43
- # --- 환경 설정 ---
44
- print("--- 환경 설정 ---")
45
- print(f"PyTorch 버전: {torch.__version__}")
46
- print(f"실행 장치: {torch.device('cuda' if torch.cuda.is_available() else 'cpu')}")
 
 
47
  print(f"HF_TOKEN 설정 여부: {'있음' if HF_TOKEN else '없음'}")
48
 
49
- # --- 모델 토크나이저 로딩 ---
50
- print(f"--- 모델 로딩 중: {MODEL_ID} ---")
51
- print("첫 실행 시 몇 분 정도 소요될 수 있습니다...")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
  model = None
54
  tokenizer = None
55
  load_successful = False
56
- stop_token_ids_list = [] # stop_token_ids_list 초기화
57
 
58
  try:
59
  start_load_time = time.time()
60
- # 자원에 따라 device_map 설정
61
- device_map = "auto" if torch.cuda.is_available() else "cpu"
62
- dtype = torch.float16 if torch.cuda.is_available() else torch.float32
63
 
64
  # 토크나이저 로딩
65
  tokenizer_kwargs = {
@@ -69,7 +86,7 @@ try:
69
  # HF_TOKEN이 설정되어 있으면 추가
70
  if HF_TOKEN:
71
  tokenizer_kwargs["token"] = HF_TOKEN
72
-
73
  tokenizer = AutoTokenizer.from_pretrained(
74
  MODEL_ID,
75
  **tokenizer_kwargs
@@ -77,15 +94,15 @@ try:
77
 
78
  # 모델 로딩
79
  model_kwargs = {
80
- "torch_dtype": dtype,
81
- "device_map": device_map,
82
- "trust_remote_code": True
83
  }
84
 
85
  # HF_TOKEN이 설정되어 있으면 추가
86
  if HF_TOKEN:
87
  model_kwargs["token"] = HF_TOKEN
88
-
89
  model = AutoModelForCausalLM.from_pretrained(
90
  MODEL_ID,
91
  **model_kwargs
@@ -93,74 +110,80 @@ try:
93
 
94
  model.eval()
95
  load_time = time.time() - start_load_time
96
- print(f"--- 모델 토크나이저 로딩 완료: {load_time:.2f} 소요 ---")
97
  load_successful = True
98
 
99
- # --- 중지 토큰 설정 ---
100
- stop_token_strings = ["</s>", "<|endoftext|>"]
101
  temp_stop_ids = [tokenizer.convert_tokens_to_ids(token) for token in stop_token_strings]
102
 
103
  if tokenizer.eos_token_id is not None and tokenizer.eos_token_id not in temp_stop_ids:
104
  temp_stop_ids.append(tokenizer.eos_token_id)
105
  elif tokenizer.eos_token_id is None:
106
- print("경고: tokenizer.eos_token_id None입니다. 중지 토큰에 추가할 없습니다.")
107
 
108
  stop_token_ids_list = [tid for tid in temp_stop_ids if tid is not None]
109
 
110
  if not stop_token_ids_list:
111
- print("경고: 중지 토큰 ID를 찾을 없습니다. 가능하면 기본 EOS 사용하고, 그렇지 않으면 생성이 올바르게 중지되지 않을 수 있습니다.")
112
  if tokenizer.eos_token_id is not None:
113
  stop_token_ids_list = [tokenizer.eos_token_id]
114
  else:
115
- print("오류: 기본 EOS를 포함하여 중지 토큰을 찾을 없습니다. 생성이 무한정 실행될 수 있습니다.")
116
 
117
- print(f"사용할 중지 토큰 ID: {stop_token_ids_list}")
118
 
119
  except Exception as e:
120
- print(f"!!! 모델 로딩 오류: {e}")
121
  if 'model' in locals() and model is not None: del model
122
  if 'tokenizer' in locals() and tokenizer is not None: del tokenizer
123
  gc.collect()
124
- raise gr.Error(f"모델 {MODEL_ID} 로딩에 실패했습니다. 애플리케이션을 시작할 없습니다. 오류: {e}")
 
125
 
126
- # --- 시스템 프롬프트 정의 ---
127
  def get_system_prompt():
128
  current_date = datetime.datetime.now().strftime("%Y-%m-%d (%A)")
129
  return (
130
- f"- 오늘은 {current_date}입니다.\n"
131
- f"- 사용자의 질문에 대해 친절하고 자세하게 한국어로 답변해야 합니다."
 
132
  )
133
 
134
- # --- 웜업 함수 ---
135
  def warmup_model():
136
  if not load_successful or model is None or tokenizer is None:
137
- print("웜업 건너뛰기: 모델이 성공적으로 로드되지 않았습니다.")
138
  return
139
 
140
- print("--- 모델 웜업 시작 ---")
141
  try:
142
  start_warmup_time = time.time()
143
  warmup_message = "안녕하세요"
144
-
145
- # 모델에 맞는 형식으로 입력 구성
146
  system_prompt = get_system_prompt()
147
-
148
- # MiMo 모델의 프롬프트 형식에 맞게 조정
149
- prompt = f"Human: {warmup_message}\nAssistant:"
150
-
151
- inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
152
-
153
- # 중지 토큰이 비어 있는지 확인하고 적절히 처리
 
 
 
 
 
 
 
154
  gen_kwargs = {
155
  "max_new_tokens": 10,
156
  "pad_token_id": tokenizer.eos_token_id if tokenizer.eos_token_id is not None else tokenizer.pad_token_id,
157
  "do_sample": False
158
  }
159
-
160
  if stop_token_ids_list:
161
  gen_kwargs["eos_token_id"] = stop_token_ids_list
162
  else:
163
- print("웜업 경고: 생성에 정의된 중지 토큰이 없습니다.")
164
 
165
  with torch.no_grad():
166
  output_ids = model.generate(**inputs, **gen_kwargs)
@@ -169,132 +192,176 @@ def warmup_model():
169
  del output_ids
170
  gc.collect()
171
  warmup_time = time.time() - start_warmup_time
172
- print(f"--- 모델 웜업 완료: {warmup_time:.2f} 소요 ---")
173
 
174
  except Exception as e:
175
- print(f"!!! 모델 웜업 오류 발생: {e}")
176
  finally:
177
  gc.collect()
178
 
179
- # --- 추론 함수 ---
180
- @spaces.GPU()
181
  def predict(message, history):
182
  """
183
- HyperCLOVAX-SEED-Vision-Instruct-3B 모델을 사용하여 응답을 생성합니다.
184
- 'history' Gradio 'messages' 형식을 가정합니다: List[Dict].
185
  """
186
  if model is None or tokenizer is None:
187
  return "오류: 모델이 로드되지 않았습니다."
188
 
189
- # 대화 기록 처리
190
- history_text = ""
191
- if isinstance(history, list):
192
- for turn in history:
193
- if isinstance(turn, tuple) and len(turn) == 2:
194
- history_text += f"Human: {turn[0]}\nAssistant: {turn[1]}\n"
195
 
196
- # MiMo 모델 입력 형식에 맞게 프롬프트 구성
197
- prompt = f"{history_text}Human: {message}\nAssistant:"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
 
199
  inputs = None
200
  output_ids = None
201
 
202
  try:
203
- # 입력 준비
204
- inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
205
- input_length = inputs.input_ids.shape[1]
206
- print(f"\n입력 토큰 수: {input_length}")
 
 
 
 
207
 
208
  except Exception as e:
209
- print(f"!!! 입력 처리 오류 발생: {e}")
210
  return f"오류: 입력 형식을 처리하는 중 문제가 발생했습니다. ({e})"
211
 
212
  try:
213
- print("응답 생성 중...")
214
  generation_start_time = time.time()
215
 
216
- # 생성 인수 준비, 비어 있는 stop_token_ids_list 처리
217
  gen_kwargs = {
218
  "max_new_tokens": MAX_NEW_TOKENS,
219
  "pad_token_id": tokenizer.eos_token_id if tokenizer.eos_token_id is not None else tokenizer.pad_token_id,
220
  "do_sample": True,
221
  "temperature": 0.7,
222
  "top_p": 0.9,
223
- "repetition_penalty": 1.1
224
  }
225
-
226
  if stop_token_ids_list:
227
  gen_kwargs["eos_token_id"] = stop_token_ids_list
228
  else:
229
- print("생성 경고: 정의된 중지 토큰이 없습니다.")
230
 
231
  with torch.no_grad():
232
  output_ids = model.generate(**inputs, **gen_kwargs)
233
 
234
  generation_time = time.time() - generation_start_time
235
- print(f"생성 완료: {generation_time:.2f} 소요.")
236
 
237
  except Exception as e:
238
- print(f"!!! 모델 생성 오류 발생: {e}")
239
  if inputs is not None: del inputs
240
  if output_ids is not None: del output_ids
241
  gc.collect()
242
  return f"오류: 응답을 생성하는 중 문제가 발생했습니다. ({e})"
243
 
244
- # 응답 디코딩
245
  response = "오류: 응답 생성에 실패했습니다."
246
  if output_ids is not None:
247
  try:
248
  new_tokens = output_ids[0, input_length:]
249
  response = tokenizer.decode(new_tokens, skip_special_tokens=True)
250
- print(f"출력 토큰 수: {len(new_tokens)}")
251
  del new_tokens
252
  except Exception as e:
253
- print(f"!!! 응답 디코딩 오류 발생: {e}")
254
  response = "오류: 응답을 디코딩하는 중 문제가 발생했습니다."
255
 
256
- # 메모리 정리
257
  if inputs is not None: del inputs
258
  if output_ids is not None: del output_ids
259
  gc.collect()
260
- print("메모리 정리 완료.")
261
-
262
- return response.strip()
263
-
264
- # --- Gradio 인터페이스 설정 ---
265
- print("--- Gradio 인터페이스 설정 중 ---")
266
-
267
- examples = [
268
- ["안녕하세요! 자기소개 좀 해주세요."],
269
- ["인공지능과 머신러닝의 차이점은 무엇인가요?"],
270
- ["딥러닝 모델 학습 과정을 단계별로 알려주세요."],
271
- ["제주도 여행 계획을 세우고 있는데, 3박 4일 추천 코스 좀 알려주세요."],
272
- ]
273
-
274
- # 모델 이름에 맞게 타이틀 조정
275
- title = "🤖 HyperCLOVAX-SEED-Vision-Instruct-3B"
276
-
277
- # ChatInterface를 사용하여 자체 Chatbot 컴포넌트 관리
278
- demo = gr.ChatInterface(
279
- fn=predict,
280
- title=title,
281
- description=(
282
- f"**모델:** {MODEL_ID}\n"
283
- ),
284
- examples=examples,
285
- cache_examples=False,
286
- theme=gr.themes.Soft(),
287
- )
288
-
289
- # --- 애플리케이션 실행 ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
290
  if __name__ == "__main__":
291
  if load_successful:
292
  warmup_model()
293
  else:
294
- print("모델 로딩에 실패하여 웜업을 건너뜁니다.")
295
 
296
- print("--- Gradio 실행 중 ---")
297
  demo.queue().launch(
298
- # share=True # 공개 링크를 원하면 주석 해제
299
- # server_name="0.0.0.0" # 로컬 네트워크 접근을 원하면 주석 해제
300
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
  import torch
3
  from transformers import AutoModelForCausalLM, AutoTokenizer
4
  import gc
5
+ import os
6
  import datetime
7
  import time
 
8
 
9
+ # --- Configuration ---
10
+ MODEL_ID = "naver-hyperclovax/HyperCLOVAX-SEED-Text-Instruct-0.5B"
11
  MAX_NEW_TOKENS = 512
12
+ USE_GPU = True # Enable GPU usage
13
 
14
  # Hugging Face 토큰 설정 - 환경 변수에서 가져오기
15
  HF_TOKEN = os.getenv("HF_TOKEN")
16
  if not HF_TOKEN:
17
  print("경고: HF_TOKEN 환경 변수가 설정되지 않았습니다. 비공개 모델에 접근할 수 없을 수 있습니다.")
18
 
19
+ # --- Environment setup ---
20
+ print("--- Environment Setup ---")
21
+ device = torch.device("cuda" if torch.cuda.is_available() and USE_GPU else "cpu")
22
+ print(f"PyTorch version: {torch.__version__}")
23
+ print(f"Running on device: {device}")
24
+ print(f"Torch Threads: {torch.get_num_threads()}")
25
  print(f"HF_TOKEN 설정 여부: {'있음' if HF_TOKEN else '없음'}")
26
 
27
+ # Custom CSS for improved UI
28
+ custom_css = """
29
+ .gradio-container {
30
+ max-width: 850px !important;
31
+ margin: auto;
32
+ }
33
+ .gr-chat {
34
+ border-radius: 10px;
35
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
36
+ }
37
+ .user-message {
38
+ background-color: #f0f7ff !important;
39
+ border-radius: 8px;
40
+ }
41
+ .assistant-message {
42
+ background-color: #f9f9f9 !important;
43
+ border-radius: 8px;
44
+ }
45
+ .gr-button.primary-button {
46
+ background-color: #1f4e79 !important;
47
+ }
48
+ .gr-form {
49
+ padding: 20px;
50
+ border-radius: 10px;
51
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
52
+ }
53
+ #intro-message {
54
+ text-align: center;
55
+ margin-bottom: 20px;
56
+ padding: 15px;
57
+ background: linear-gradient(135deg, #e8f4ff 0%, #f0f7ff 100%);
58
+ border-radius: 10px;
59
+ border-left: 4px solid #1f4e79;
60
+ }
61
+ .footer {
62
+ text-align: center;
63
+ margin-top: 20px;
64
+ font-size: 0.8em;
65
+ color: #666;
66
+ }
67
+ """
68
+
69
+ # --- Model and Tokenizer Loading ---
70
+ print(f"--- Loading Model: {MODEL_ID} ---")
71
+ print("This might take a few minutes, especially on the first launch...")
72
 
73
  model = None
74
  tokenizer = None
75
  load_successful = False
76
+ stop_token_ids_list = [] # Initialize stop_token_ids_list
77
 
78
  try:
79
  start_load_time = time.time()
 
 
 
80
 
81
  # 토크나이저 로딩
82
  tokenizer_kwargs = {
 
86
  # HF_TOKEN이 설정되어 있으면 추가
87
  if HF_TOKEN:
88
  tokenizer_kwargs["token"] = HF_TOKEN
89
+
90
  tokenizer = AutoTokenizer.from_pretrained(
91
  MODEL_ID,
92
  **tokenizer_kwargs
 
94
 
95
  # 모델 로딩
96
  model_kwargs = {
97
+ "trust_remote_code": True,
98
+ "device_map": "auto" if device.type == "cuda" else "cpu",
99
+ "torch_dtype": torch.float16 if device.type == "cuda" else torch.float32,
100
  }
101
 
102
  # HF_TOKEN이 설정되어 있으면 추가
103
  if HF_TOKEN:
104
  model_kwargs["token"] = HF_TOKEN
105
+
106
  model = AutoModelForCausalLM.from_pretrained(
107
  MODEL_ID,
108
  **model_kwargs
 
110
 
111
  model.eval()
112
  load_time = time.time() - start_load_time
113
+ print(f"--- Model and Tokenizer Loaded Successfully in {load_time:.2f} seconds ---")
114
  load_successful = True
115
 
116
+ # --- Stop Token Configuration ---
117
+ stop_token_strings = ["<|endofturn|>", "<|stop|>"]
118
  temp_stop_ids = [tokenizer.convert_tokens_to_ids(token) for token in stop_token_strings]
119
 
120
  if tokenizer.eos_token_id is not None and tokenizer.eos_token_id not in temp_stop_ids:
121
  temp_stop_ids.append(tokenizer.eos_token_id)
122
  elif tokenizer.eos_token_id is None:
123
+ print("Warning: tokenizer.eos_token_id is None. Cannot add to stop tokens.")
124
 
125
  stop_token_ids_list = [tid for tid in temp_stop_ids if tid is not None]
126
 
127
  if not stop_token_ids_list:
128
+ print("Warning: Could not find any stop token IDs. Using default EOS if available, otherwise generation might not stop correctly.")
129
  if tokenizer.eos_token_id is not None:
130
  stop_token_ids_list = [tokenizer.eos_token_id]
131
  else:
132
+ print("Error: No stop tokens found, including default EOS. Generation may run indefinitely.")
133
 
134
+ print(f"Using Stop Token IDs: {stop_token_ids_list}")
135
 
136
  except Exception as e:
137
+ print(f"!!! Error loading model: {e}")
138
  if 'model' in locals() and model is not None: del model
139
  if 'tokenizer' in locals() and tokenizer is not None: del tokenizer
140
  gc.collect()
141
+ # Raise Gradio error to display in the Space UI if loading fails
142
+ raise gr.Error(f"Failed to load the model {MODEL_ID}. Cannot start the application. Error: {e}")
143
 
144
+ # --- System Prompt Definition ---
145
  def get_system_prompt():
146
  current_date = datetime.datetime.now().strftime("%Y-%m-%d (%A)")
147
  return (
148
+ f"- AI 언어모델의 이름은 \"CLOVA X\" 이며 네이버에서 만들었다.\n"
149
+ f"- 오늘은 {current_date}이다.\n"
150
+ f"- 사용자의 질문에 대해 친절하고 자세하게 한국어로 답변해야 한다."
151
  )
152
 
153
+ # --- Warm-up Function ---
154
  def warmup_model():
155
  if not load_successful or model is None or tokenizer is None:
156
+ print("Skipping warmup: Model not loaded successfully.")
157
  return
158
 
159
+ print("--- Starting Model Warm-up ---")
160
  try:
161
  start_warmup_time = time.time()
162
  warmup_message = "안녕하세요"
 
 
163
  system_prompt = get_system_prompt()
164
+ warmup_chat = [
165
+ {"role": "tool_list", "content": ""},
166
+ {"role": "system", "content": system_prompt},
167
+ {"role": "user", "content": warmup_message}
168
+ ]
169
+
170
+ inputs = tokenizer.apply_chat_template(
171
+ warmup_chat,
172
+ add_generation_prompt=True,
173
+ return_dict=True,
174
+ return_tensors="pt"
175
+ ).to(device)
176
+
177
+ # Check if stop_token_ids_list is empty and handle appropriately
178
  gen_kwargs = {
179
  "max_new_tokens": 10,
180
  "pad_token_id": tokenizer.eos_token_id if tokenizer.eos_token_id is not None else tokenizer.pad_token_id,
181
  "do_sample": False
182
  }
 
183
  if stop_token_ids_list:
184
  gen_kwargs["eos_token_id"] = stop_token_ids_list
185
  else:
186
+ print("Warmup Warning: No stop tokens defined for generation.")
187
 
188
  with torch.no_grad():
189
  output_ids = model.generate(**inputs, **gen_kwargs)
 
192
  del output_ids
193
  gc.collect()
194
  warmup_time = time.time() - start_warmup_time
195
+ print(f"--- Model Warm-up Completed in {warmup_time:.2f} seconds ---")
196
 
197
  except Exception as e:
198
+ print(f"!!! Error during model warm-up: {e}")
199
  finally:
200
  gc.collect()
201
 
202
+ # --- Inference Function ---
 
203
  def predict(message, history):
204
  """
205
+ Generates response using HyperCLOVAX.
206
+ Assumes 'history' is in the Gradio 'messages' format: List[Dict].
207
  """
208
  if model is None or tokenizer is None:
209
  return "오류: 모델이 로드되지 않았습니다."
210
 
211
+ system_prompt = get_system_prompt()
 
 
 
 
 
212
 
213
+ # Start with system prompt
214
+ chat_history_formatted = [
215
+ {"role": "tool_list", "content": ""}, # As required by model card
216
+ {"role": "system", "content": system_prompt}
217
+ ]
218
+
219
+ # Append history (List of {'role': 'user'/'assistant', 'content': '...'})
220
+ if isinstance(history, list): # Check if history is a list
221
+ for turn in history:
222
+ # Validate turn format
223
+ if isinstance(turn, dict) and "role" in turn and "content" in turn:
224
+ chat_history_formatted.append(turn)
225
+ # Handle potential older tuple format
226
+ elif isinstance(turn, (list, tuple)) and len(turn) == 2:
227
+ print(f"Warning: Received history item in tuple format: {turn}. Converting to messages format.")
228
+ chat_history_formatted.append({"role": "user", "content": turn[0]})
229
+ if turn[1]: # Ensure assistant message exists
230
+ chat_history_formatted.append({"role": "assistant", "content": turn[1]})
231
+ else:
232
+ print(f"Warning: Skipping unexpected history format item: {turn}")
233
+
234
+ # Append the latest user message
235
+ chat_history_formatted.append({"role": "user", "content": message})
236
 
237
  inputs = None
238
  output_ids = None
239
 
240
  try:
241
+ inputs = tokenizer.apply_chat_template(
242
+ chat_history_formatted,
243
+ add_generation_prompt=True,
244
+ return_dict=True,
245
+ return_tensors="pt"
246
+ ).to(device)
247
+ input_length = inputs['input_ids'].shape[1]
248
+ print(f"\nInput tokens: {input_length}")
249
 
250
  except Exception as e:
251
+ print(f"!!! Error applying chat template: {e}")
252
  return f"오류: 입력 형식을 처리하는 중 문제가 발생했습니다. ({e})"
253
 
254
  try:
255
+ print("Generating response...")
256
  generation_start_time = time.time()
257
 
258
+ # Prepare generation arguments, handling empty stop_token_ids_list
259
  gen_kwargs = {
260
  "max_new_tokens": MAX_NEW_TOKENS,
261
  "pad_token_id": tokenizer.eos_token_id if tokenizer.eos_token_id is not None else tokenizer.pad_token_id,
262
  "do_sample": True,
263
  "temperature": 0.7,
264
  "top_p": 0.9,
 
265
  }
 
266
  if stop_token_ids_list:
267
  gen_kwargs["eos_token_id"] = stop_token_ids_list
268
  else:
269
+ print("Generation Warning: No stop tokens defined.")
270
 
271
  with torch.no_grad():
272
  output_ids = model.generate(**inputs, **gen_kwargs)
273
 
274
  generation_time = time.time() - generation_start_time
275
+ print(f"Generation complete in {generation_time:.2f} seconds.")
276
 
277
  except Exception as e:
278
+ print(f"!!! Error during model generation: {e}")
279
  if inputs is not None: del inputs
280
  if output_ids is not None: del output_ids
281
  gc.collect()
282
  return f"오류: 응답을 생성하는 중 문제가 발생했습니다. ({e})"
283
 
284
+ # Decode the response
285
  response = "오류: 응답 생성에 실패했습니다."
286
  if output_ids is not None:
287
  try:
288
  new_tokens = output_ids[0, input_length:]
289
  response = tokenizer.decode(new_tokens, skip_special_tokens=True)
290
+ print(f"Output tokens: {len(new_tokens)}")
291
  del new_tokens
292
  except Exception as e:
293
+ print(f"!!! Error decoding response: {e}")
294
  response = "오류: 응답을 디코딩하는 중 문제가 발생했습니다."
295
 
296
+ # Clean up memory
297
  if inputs is not None: del inputs
298
  if output_ids is not None: del output_ids
299
  gc.collect()
300
+ print("Memory cleaned.")
301
+
302
+ return response
303
+
304
+ # --- Additional UI components ---
305
+ def create_welcome_markdown():
306
+ return """
307
+ # 🇰🇷 네이버 HyperCLOVA X SEED
308
+
309
+ 한국의 기술력으로 개발된 네이버의 초거대 AI 언어모델 'HyperCLOVA X'를 경험해보세요.
310
+ 데모는 0.5B 파라미터 경량 모델을 사용하여 한국어 자연어 처리 능력을 보여줍니다.
311
+
312
+ **사용 방법**:
313
+ - 아래 채팅창에 질문이나 요청을 입력하세요
314
+ - 한국어로 다양한 주제에 대한 대화를 나눠보세요
315
+ - 예시 질문을 클릭하여 빠르게 시작할 수도 있습니다
316
+ """
317
+
318
+ # --- Gradio Interface Setup ---
319
+ print("--- Setting up Gradio Interface ---")
320
+
321
+ with gr.Blocks(css=custom_css) as demo:
322
+ gr.Markdown(create_welcome_markdown(), elem_id="intro-message")
323
+
324
+ chatbot = gr.ChatInterface(
325
+ fn=predict,
326
+ title="",
327
+ description="",
328
+ examples=[
329
+ ["네이버 클로바X는 무엇인가요?"],
330
+ ["슈뢰딩거 방정식과 양자역학의 관계를 설명해주세요."],
331
+ ["딥러닝 모델 학습 과정을 단계별로 알려줘."],
332
+ ["제주도 여행 계획을 세우고 있는데, 3박 4일 추천 코스 좀 짜줄래?"],
333
+ ["한국 역사에서 가장 중요한 사건 5가지는 무엇인가요?"],
334
+ ["인공지능 윤리에 대해 설명해주세요."],
335
+ ],
336
+ cache_examples=False,
337
+ submit_btn="보내기",
338
+ retry_btn="다시 시도",
339
+ undo_btn="취소",
340
+ clear_btn="새로운 대화",
341
+ )
342
+
343
+ with gr.Accordion("모델 정보", open=False):
344
+ gr.Markdown(f"""
345
+ - **모델**: {MODEL_ID}
346
+ - **환경**: ZeroGPU 공유 환경에서 실행 중
347
+ - **토큰 제한**: 최대 생성 토큰 수는 {MAX_NEW_TOKENS}개로 제한됩니다.
348
+ - **하드웨어**: {"GPU" if device.type == "cuda" else "CPU"} 환경에서 실행 중
349
+ """)
350
+
351
+ gr.Markdown(
352
+ "© 2025 네이버 HyperCLOVA X 데모 | Powered by Hugging Face & ZeroGPU",
353
+ elem_classes="footer"
354
+ )
355
+
356
+ # --- Application Launch ---
357
  if __name__ == "__main__":
358
  if load_successful:
359
  warmup_model()
360
  else:
361
+ print("Skipping warm-up because model loading failed.")
362
 
363
+ print("--- Launching Gradio App ---")
364
  demo.queue().launch(
365
+ # share=True # Uncomment for public link
366
+ # server_name="0.0.0.0" # Uncomment for local network access
367
  )