sdfsdh commited on
Commit
e0a73dc
Β·
verified Β·
1 Parent(s): b36b1be

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +233 -0
src/streamlit_app.py CHANGED
@@ -0,0 +1,233 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import torch
3
+ from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
4
+ import zipfile
5
+ import os
6
+ import tempfile
7
+ import json
8
+ from huggingface_hub import hf_hub_download
9
+
10
+ # ν™˜κ²½ λ³€μˆ˜ 및 μΊμ‹œ 디렉토리 μ„€μ • (μƒλž΅, κΈ°μ‘΄ μ½”λ“œμ™€ 동일)
11
+
12
+ # ... (ν™˜κ²½ λ³€μˆ˜ 및 μΊμ‹œ 디렉토리 생성 뢀뢄은 κΈ°μ‘΄ μ½”λ“œμ™€ 동일)
13
+
14
+ HF_REPO_ID = "sdfsdh/koalpaca-cpu-model"
15
+ HF_FILENAME = "koalpaca_cpu_deployment.zip"
16
+
17
+ def download_model_from_hf_hub():
18
+ try:
19
+ st.info("πŸ“₯ Hugging Face Model Repositoryμ—μ„œ λ‹€μš΄λ‘œλ“œ 쀑...")
20
+ zip_path = hf_hub_download(
21
+ repo_id=HF_REPO_ID,
22
+ filename=HF_FILENAME,
23
+ cache_dir="/tmp/hf_hub_cache",
24
+ repo_type="model"
25
+ )
26
+ st.success(f"βœ… λ‹€μš΄λ‘œλ“œ μ™„λ£Œ: {os.path.getsize(zip_path) / 1024**3:.2f}GB")
27
+ st.info(f"πŸ“ λ‹€μš΄λ‘œλ“œ 경둜: {zip_path}")
28
+ return zip_path
29
+ except Exception as e:
30
+ st.error(f"❌ Hugging Face Hub λ‹€μš΄λ‘œλ“œ μ‹€νŒ¨: {e}")
31
+ return None
32
+
33
+ def verify_zip_file(zip_path):
34
+ try:
35
+ with zipfile.ZipFile(zip_path, 'r') as zip_ref:
36
+ zip_ref.testzip()
37
+ file_list = zip_ref.namelist()
38
+ st.info(f"πŸ“¦ ZIP 파일 검증 성곡: {len(file_list)}개 파일")
39
+ return True
40
+ except zipfile.BadZipFile:
41
+ st.error("❌ μœ νš¨ν•˜μ§€ μ•Šμ€ ZIP 파일")
42
+ return False
43
+ except Exception as e:
44
+ st.error(f"❌ ZIP 파일 검증 μ‹€νŒ¨: {e}")
45
+ return False
46
+
47
+ def extract_zip_streaming(zip_path, extract_path):
48
+ """RAM μ‚¬μš©λŸ‰ μ΅œμ†Œν™”λ₯Ό μœ„ν•œ 슀트리밍 방식 μ••μΆ• ν•΄μ œ"""
49
+ st.info("πŸ“¦ 슀트리밍 λ°©μ‹μœΌλ‘œ μ••μΆ• ν•΄μ œ 쀑...")
50
+ with zipfile.ZipFile(zip_path, 'r') as zip_ref:
51
+ for member in zip_ref.infolist():
52
+ # 디렉토리면 μƒμ„±λ§Œ
53
+ extracted_path = os.path.join(extract_path, member.filename)
54
+ if member.is_dir():
55
+ os.makedirs(extracted_path, exist_ok=True)
56
+ continue
57
+ # μƒμœ„ 디렉토리 생성
58
+ os.makedirs(os.path.dirname(extracted_path), exist_ok=True)
59
+ # 파일 슀트리밍 볡사
60
+ with zip_ref.open(member) as src, open(extracted_path, "wb") as dst:
61
+ while True:
62
+ chunk = src.read(1024 * 1024) # 1MB 버퍼
63
+ if not chunk:
64
+ break
65
+ dst.write(chunk)
66
+ st.success("βœ… μ••μΆ• ν•΄μ œ μ™„λ£Œ!")
67
+
68
+ @st.cache_resource
69
+ def download_and_load_model():
70
+ try:
71
+ temp_dir = "/tmp/koalpaca_model"
72
+ os.makedirs(temp_dir, exist_ok=True)
73
+ extract_path = os.path.join(temp_dir, "koalpaca_cpu_deployment")
74
+
75
+ zip_path = download_model_from_hf_hub()
76
+ if zip_path is None:
77
+ raise Exception("Hugging Face Hub λ‹€μš΄λ‘œλ“œ μ‹€νŒ¨")
78
+
79
+ if not verify_zip_file(zip_path):
80
+ raise Exception("ZIP 파일 검증 μ‹€νŒ¨")
81
+
82
+ # κΈ°μ‘΄ extractall() β†’ 슀트리밍 λ°©μ‹μœΌλ‘œ λ³€κ²½
83
+ extract_zip_streaming(zip_path, extract_path)
84
+
85
+ # λͺ¨λΈ 경둜 탐색 (κΈ°μ‘΄ μ½”λ“œμ™€ 동일)
86
+ model_path = None
87
+ for root, dirs, files in os.walk(extract_path):
88
+ if "cpu_quantized_model.pt" in files or "tokenizer.json" in files:
89
+ model_path = root
90
+ break
91
+ if model_path is None:
92
+ subdirs = [d for d in os.listdir(extract_path) if os.path.isdir(os.path.join(extract_path, d))]
93
+ if subdirs:
94
+ model_path = os.path.join(extract_path, subdirs[0])
95
+ else:
96
+ model_path = extract_path
97
+
98
+ st.info(f"πŸ“ λͺ¨λΈ 경둜: {model_path}")
99
+ st.info(f"πŸ“‹ 파일 λͺ©λ‘: {os.listdir(model_path)}")
100
+
101
+ st.info("πŸ“ ν† ν¬λ‚˜μ΄μ € λ‘œλ”© 쀑...")
102
+ tokenizer = AutoTokenizer.from_pretrained(
103
+ model_path,
104
+ trust_remote_code=True,
105
+ use_fast=False,
106
+ cache_dir="/tmp/transformers_cache"
107
+ )
108
+
109
+ quantized_model_path = os.path.join(model_path, "cpu_quantized_model.pt")
110
+ if os.path.exists(quantized_model_path):
111
+ st.info("⚑ μ–‘μžν™”λœ CPU λͺ¨λΈ λ‘œλ“œ 쀑...")
112
+ model = AutoModelForCausalLM.from_pretrained(
113
+ "beomi/KoAlpaca-Polyglot-5.8B",
114
+ torch_dtype=torch.float32,
115
+ device_map="cpu",
116
+ trust_remote_code=True,
117
+ low_cpu_mem_usage=True,
118
+ cache_dir="/tmp/transformers_cache"
119
+ )
120
+ checkpoint = torch.load(quantized_model_path, map_location="cpu")
121
+ if 'model_state_dict' in checkpoint:
122
+ model.load_state_dict(checkpoint['model_state_dict'])
123
+ st.success("βœ… μ–‘μžν™”λœ λͺ¨λΈ λ‘œλ“œ μ™„λ£Œ!")
124
+ else:
125
+ raise KeyError("model_state_dict not found")
126
+ else:
127
+ st.info("🧠 ν‘œμ€€ λͺ¨λΈ λ‘œλ“œ 쀑...")
128
+ model = AutoModelForCausalLM.from_pretrained(
129
+ "beomi/KoAlpaca-Polyglot-5.8B",
130
+ torch_dtype=torch.float16,
131
+ device_map="auto",
132
+ trust_remote_code=True,
133
+ low_cpu_mem_usage=True,
134
+ cache_dir="/tmp/transformers_cache"
135
+ )
136
+
137
+ model.eval()
138
+ st.info("πŸ”§ Pipeline 생성 쀑...")
139
+ pipe = pipeline(
140
+ 'text-generation',
141
+ model=model,
142
+ tokenizer=tokenizer,
143
+ device_map="auto"
144
+ )
145
+ return pipe, tokenizer
146
+ except Exception as e:
147
+ st.error(f"❌ λͺ¨λΈ λ‘œλ“œ μ‹€νŒ¨: {str(e)}")
148
+ import traceback
149
+ st.error(f"상세 였λ₯˜: {traceback.format_exc()}")
150
+ return None, None
151
+
152
+ def generate_response(pipe, prompt, max_new_tokens=200):
153
+ try:
154
+ formatted_prompt = f"### 질문: {prompt}\n\n### λ‹΅λ³€:"
155
+ result = pipe(
156
+ formatted_prompt,
157
+ do_sample=True,
158
+ max_new_tokens=max_new_tokens,
159
+ temperature=0.7,
160
+ top_p=0.9,
161
+ return_full_text=False,
162
+ eos_token_id=2,
163
+ )
164
+ return result[0]['generated_text'].strip()
165
+ except Exception as e:
166
+ return f"응닡 생성 쀑 였λ₯˜: {str(e)}"
167
+
168
+ def main():
169
+ st.title("πŸ€– KoAlpaca CPU μ„œλ²„")
170
+ st.markdown("Hugging Face Model Repositoryμ—μ„œ λ‘œλ“œλœ KoAlpaca λͺ¨λΈ μ„œλΉ™")
171
+ st.info("πŸ”§ μΊμ‹œ 디렉토리 κΆŒν•œ 문제 해결됨")
172
+ st.info(f"πŸ“ TRANSFORMERS_CACHE: {os.environ.get('TRANSFORMERS_CACHE')}")
173
+ st.info(f"πŸ“ HF_HOME: {os.environ.get('HF_HOME')}")
174
+ st.info(f"πŸ“ Model Repository: {HF_REPO_ID}")
175
+ st.info(f"πŸ“„ 파일λͺ…: {HF_FILENAME}")
176
+
177
+ with st.spinner("λͺ¨λΈ μ΄ˆκΈ°ν™” 쀑... (μΊμ‹œ κΆŒν•œ 문제 해결됨, 5-10λΆ„ μ†Œμš”)"):
178
+ pipe, tokenizer = download_and_load_model()
179
+ if pipe is None:
180
+ st.error("❌ λͺ¨λΈ λ‘œλ“œμ— μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.")
181
+ st.info("πŸ’‘ ν•΄κ²° 방법:")
182
+ st.markdown(f"""
183
+ 1. μΊμ‹œ 디렉토리 κΆŒν•œ λ¬Έμ œλŠ” ν•΄κ²°λ˜μ—ˆμŠ΅λ‹ˆλ‹€
184
+ 2. Model Repository μ ‘κ·Ό 확인: https://huggingface.co/{HF_REPO_ID}
185
+ 3. λ„€νŠΈμ›Œν¬ μ—°κ²° μƒνƒœ 확인
186
+ """)
187
+ return
188
+
189
+ st.success("βœ… KoAlpaca λͺ¨λΈ μ„œλΉ™ μ€€λΉ„ μ™„λ£Œ!")
190
+ st.header("πŸ”Œ API μΈν„°νŽ˜μ΄μŠ€")
191
+ prompt = st.text_area(
192
+ "질문 μž…λ ₯:",
193
+ height=100,
194
+ placeholder="예: μ‚Όμ„±μ „μžμ˜ μž¬λ¬΄μƒνƒœλŠ” μ–΄λ–»μŠ΅λ‹ˆκΉŒ?"
195
+ )
196
+ col1, col2 = st.columns(2)
197
+ with col1:
198
+ max_tokens = st.slider("μ΅œλŒ€ 토큰 수", 50, 500, 200)
199
+ with col2:
200
+ temperature = st.slider("Temperature", 0.1, 1.0, 0.7)
201
+ if st.button("πŸš€ 응닡 생성", type="primary"):
202
+ if prompt.strip():
203
+ with st.spinner("응닡 생성 쀑..."):
204
+ response = generate_response(pipe, prompt, max_tokens)
205
+ st.markdown("### πŸ“ 응닡:")
206
+ st.write(response)
207
+ with st.expander("πŸ“Š JSON 응닡"):
208
+ api_response = {
209
+ "prompt": prompt,
210
+ "response": response,
211
+ "model": "KoAlpaca-Polyglot-5.8B",
212
+ "max_tokens": max_tokens,
213
+ "temperature": temperature,
214
+ "source": f"HF Model Repository: {HF_REPO_ID}"
215
+ }
216
+ st.json(api_response)
217
+ else:
218
+ st.warning("μ§ˆλ¬Έμ„ μž…λ ₯ν•΄μ£Όμ„Έμš”.")
219
+ with st.expander("πŸ”§ μ‹œμŠ€ν…œ 정보"):
220
+ system_info = {
221
+ "ν”Œλž«νΌ": "Hugging Face Spaces",
222
+ "λͺ¨λΈ": "KoAlpaca-Polyglot-5.8B",
223
+ "μ΅œμ ν™”": "CPU μ–‘μžν™”",
224
+ "λ©”λͺ¨λ¦¬": "16GB RAM",
225
+ "μ†ŒμŠ€": f"HF Model Repository: {HF_REPO_ID}",
226
+ "μΊμ‹œ 디렉토리": "/tmp (κΆŒν•œ 문제 해결됨)",
227
+ "TRANSFORMERS_CACHE": os.environ.get('TRANSFORMERS_CACHE'),
228
+ "HF_HOME": os.environ.get('HF_HOME')
229
+ }
230
+ st.json(system_info)
231
+
232
+ if __name__ == "__main__":
233
+ main()