Spaces:
Sleeping
feat: Add flexible hardware support (ZeroGPU + CPU Upgrade)
Browse files✨ Features:
- Automatic hardware detection (ZeroGPU vs CPU Upgrade)
- Conditional @spaces.GPU decorator application
- Dynamic UI based on hardware type
- No code changes needed when switching hardware
🔧 Technical Implementation:
- Try/except for 'spaces' import detection
- Shared generation logic (generate_response_impl)
- Conditional decorator wrapper
- Device-aware model loading (float16 for GPU, float32 for CPU)
📚 Documentation:
- Comprehensive README with hardware comparison
- Setup guides for both hardware options
- Performance benchmarks and cost analysis
- Usage scenarios and optimization tips
🎯 Benefits:
- ZeroGPU: Fast (3-5s), cheap ($9/mo), 25min/day limit
- CPU Upgrade: Slower (30s-1m), pricey ($22/mo), unlimited
- Easy switching via Space Settings (no code changes)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
@@ -10,155 +10,226 @@ pinned: false
|
|
| 10 |
license: mit
|
| 11 |
---
|
| 12 |
|
| 13 |
-
# 🤖 Llama-2-Ko 7B Chatbot (
|
| 14 |
|
| 15 |
-
한국어에 최적화된 Llama-2-Ko 7B 모델을 사용한 대화형 챗봇입니다. ZeroGPU
|
| 16 |
|
| 17 |
## ✨ 주요 특징
|
| 18 |
|
| 19 |
- **🇰🇷 한글 대화 최적화**: Llama-2-Ko 7B 모델 사용
|
| 20 |
-
- **⚡
|
| 21 |
-
-
|
| 22 |
-
-
|
| 23 |
|
| 24 |
## 🎯 모델 정보
|
| 25 |
|
| 26 |
- **모델**: `beomi/llama-2-ko-7b`
|
| 27 |
- **크기**: ~14GB
|
| 28 |
- **특징**: 한글 대화에 특화된 Llama 2 기반 모델
|
| 29 |
-
- **하드웨어**: NVIDIA H200 (70GB VRAM)
|
| 30 |
|
| 31 |
-
## 🚀
|
| 32 |
|
| 33 |
-
###
|
| 34 |
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
|
| 40 |
-
|
|
|
|
|
|
|
| 41 |
|
| 42 |
-
|
| 43 |
-
안녕하세요
|
| 44 |
-
인공지능에 대해 설명해주세요
|
| 45 |
-
오늘 날씨가 어때요?
|
| 46 |
-
```
|
| 47 |
|
| 48 |
-
|
| 49 |
|
| 50 |
-
|
| 51 |
-
-
|
| 52 |
-
-
|
| 53 |
-
-
|
| 54 |
|
| 55 |
-
|
|
|
|
|
|
|
| 56 |
|
| 57 |
-
|
| 58 |
|
| 59 |
-
|
| 60 |
-
- ZeroGPU 하드웨어 선택 (Space Settings에서)
|
| 61 |
|
| 62 |
-
###
|
| 63 |
|
| 64 |
-
|
| 65 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
```
|
| 73 |
|
| 74 |
-
###
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
|
| 76 |
```
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
spaces # ZeroGPU 필수
|
| 81 |
```
|
| 82 |
|
| 83 |
-
|
| 84 |
|
| 85 |
-
|
| 86 |
-
2. **ZeroGPU** 선택 (PRO 구독자만 가능)
|
| 87 |
-
3. Deploy
|
| 88 |
|
| 89 |
-
|
|
|
|
|
|
|
| 90 |
|
| 91 |
-
|
| 92 |
-
# 저장소 클론
|
| 93 |
-
git clone <repository-url>
|
| 94 |
-
cd simple-chatbot-gradio
|
| 95 |
|
| 96 |
-
|
| 97 |
-
|
|
|
|
| 98 |
|
| 99 |
-
|
| 100 |
-
export HF_TOKEN=your_hugging_face_token
|
| 101 |
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
|
| 106 |
-
|
|
|
|
|
|
|
| 107 |
|
| 108 |
## ⚠️ 제한사항
|
| 109 |
|
| 110 |
-
###
|
| 111 |
|
| 112 |
-
-
|
| 113 |
-
-
|
| 114 |
-
-
|
| 115 |
|
| 116 |
-
###
|
| 117 |
|
| 118 |
-
-
|
| 119 |
-
-
|
| 120 |
-
-
|
| 121 |
|
| 122 |
-
|
| 123 |
|
| 124 |
-
|
|
|
|
|
|
|
| 125 |
|
| 126 |
-
|
| 127 |
-
```python
|
| 128 |
-
@spaces.GPU(duration=60) # 짧은 응답용
|
| 129 |
-
```
|
| 130 |
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
|
|
|
| 134 |
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
if model is None:
|
| 138 |
-
model = AutoModelForCausalLM.from_pretrained(...)
|
| 139 |
-
```
|
| 140 |
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
model = AutoModelForCausalLM.from_pretrained(
|
| 144 |
-
...,
|
| 145 |
-
torch_dtype=torch.float16,
|
| 146 |
-
)
|
| 147 |
-
```
|
| 148 |
|
| 149 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 150 |
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 156 |
|
| 157 |
## 🔗 관련 리소스
|
| 158 |
|
| 159 |
- [Llama-2-Ko Model Card](https://huggingface.co/beomi/llama-2-ko-7b)
|
| 160 |
- [ZeroGPU Documentation](https://huggingface.co/docs/hub/spaces-zerogpu)
|
| 161 |
- [Gradio Documentation](https://www.gradio.app/docs)
|
|
|
|
| 162 |
|
| 163 |
## 📄 라이선스
|
| 164 |
|
|
@@ -167,3 +238,7 @@ MIT License
|
|
| 167 |
## 🙋♂️ 문의
|
| 168 |
|
| 169 |
이슈나 질문이 있으시면 GitHub Issues를 통해 문의해주세요.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
license: mit
|
| 11 |
---
|
| 12 |
|
| 13 |
+
# 🤖 Llama-2-Ko 7B Chatbot (Flexible Hardware)
|
| 14 |
|
| 15 |
+
한국어에 최적화된 Llama-2-Ko 7B 모델을 사용한 대화형 챗봇입니다. **ZeroGPU**와 **CPU Upgrade** 하드웨어를 모두 지원합니다.
|
| 16 |
|
| 17 |
## ✨ 주요 특징
|
| 18 |
|
| 19 |
- **🇰🇷 한글 대화 최적화**: Llama-2-Ko 7B 모델 사용
|
| 20 |
+
- **⚡ 유연한 하드웨어 지원**: ZeroGPU/CPU Upgrade 자동 감지
|
| 21 |
+
- **🔄 자동 전환**: 하드웨어 변경 시 코드 수정 불필요
|
| 22 |
+
- **💰 비용 효율적**: 상황에 맞는 하드웨어 선택 가능
|
| 23 |
|
| 24 |
## 🎯 모델 정보
|
| 25 |
|
| 26 |
- **모델**: `beomi/llama-2-ko-7b`
|
| 27 |
- **크기**: ~14GB
|
| 28 |
- **특징**: 한글 대화에 특화된 Llama 2 기반 모델
|
|
|
|
| 29 |
|
| 30 |
+
## 🚀 하드웨어 옵션
|
| 31 |
|
| 32 |
+
### Option 1: ZeroGPU (추천)
|
| 33 |
|
| 34 |
+
**장점**:
|
| 35 |
+
- ⚡ 빠른 응답 (3-5초)
|
| 36 |
+
- 💰 저렴한 비용 ($9/month)
|
| 37 |
+
- 🔋 자동 GPU 할당/해제
|
| 38 |
|
| 39 |
+
**제약**:
|
| 40 |
+
- 하루 25분 무료 사용 (PRO 구독 필요)
|
| 41 |
+
- 대기열 가능 (사용자 많을 경우)
|
| 42 |
|
| 43 |
+
**비용**: $9/month (PRO 구독)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
|
| 45 |
+
### Option 2: CPU Upgrade
|
| 46 |
|
| 47 |
+
**장점**:
|
| 48 |
+
- ⏰ 무제한 사용
|
| 49 |
+
- 📊 예측 가능한 성능
|
| 50 |
+
- 🔧 간단한 설정
|
| 51 |
|
| 52 |
+
**제약**:
|
| 53 |
+
- 🐢 느린 응답 (30초~1분)
|
| 54 |
+
- 💵 상대적으로 비싼 비용
|
| 55 |
|
| 56 |
+
**비용**: $0.03/hour (월 약 $22)
|
| 57 |
|
| 58 |
+
## ⚙️ 하드웨어 설정 방법
|
|
|
|
| 59 |
|
| 60 |
+
### ZeroGPU로 변경
|
| 61 |
|
| 62 |
+
1. Space Settings → Hardware
|
| 63 |
+
2. **ZeroGPU** 선택
|
| 64 |
+
3. Confirm
|
| 65 |
+
4. 빌드 완료 대기 (1-2분)
|
| 66 |
+
|
| 67 |
+
→ UI에 "ZeroGPU" 표시 확인
|
| 68 |
|
| 69 |
+
### CPU Upgrade로 변경
|
| 70 |
+
|
| 71 |
+
1. Space Settings → Hardware
|
| 72 |
+
2. **CPU Upgrade (8 vCPU / 32 GB)** 선택
|
| 73 |
+
3. Confirm
|
| 74 |
+
4. 빌드 완료 대기 (1-2분)
|
| 75 |
+
|
| 76 |
+
→ UI에 "CPU Upgrade" 표시 확인
|
| 77 |
+
|
| 78 |
+
## 📊 성능 비교
|
| 79 |
+
|
| 80 |
+
| 항목 | ZeroGPU | CPU Upgrade |
|
| 81 |
+
|------|---------|-------------|
|
| 82 |
+
| **첫 응답** | 10-15초 | 1-2분 |
|
| 83 |
+
| **이후 응답** | 3-5초 | 30초~1분 |
|
| 84 |
+
| **일일 한도** | 25분 | 무제한 |
|
| 85 |
+
| **월 비용** | $9 | $22 |
|
| 86 |
+
| **GPU** | H200 (70GB) | 없음 |
|
| 87 |
+
| **RAM** | - | 32GB |
|
| 88 |
+
|
| 89 |
+
## 🔧 기술 구조
|
| 90 |
+
|
| 91 |
+
### 자동 하드웨어 감지
|
| 92 |
+
|
| 93 |
+
```python
|
| 94 |
+
# ZeroGPU 사용 가능 여부 자동 감지
|
| 95 |
+
try:
|
| 96 |
+
import spaces
|
| 97 |
+
ZEROGPU_AVAILABLE = True
|
| 98 |
+
except ImportError:
|
| 99 |
+
ZEROGPU_AVAILABLE = False
|
| 100 |
+
|
| 101 |
+
# 조건부 decorator 적용
|
| 102 |
+
if ZEROGPU_AVAILABLE:
|
| 103 |
+
@spaces.GPU(duration=120)
|
| 104 |
+
def generate_response(message, history):
|
| 105 |
+
return generate_response_impl(message, history)
|
| 106 |
+
else:
|
| 107 |
+
def generate_response(message, history):
|
| 108 |
+
return generate_response_impl(message, history)
|
| 109 |
```
|
| 110 |
|
| 111 |
+
### 동적 UI 생성
|
| 112 |
+
|
| 113 |
+
- ZeroGPU 모드: GPU 가속 안내
|
| 114 |
+
- CPU Upgrade 모드: CPU 제약 안내
|
| 115 |
+
- 하드웨어 정보 자동 표시
|
| 116 |
+
|
| 117 |
+
## 📝 사용 방법
|
| 118 |
+
|
| 119 |
+
### 1. Space 접속
|
| 120 |
+
|
| 121 |
+
https://huggingface.co/spaces/alex4cip/simple-chat
|
| 122 |
+
|
| 123 |
+
### 2. 하드웨어 확인
|
| 124 |
+
|
| 125 |
+
- UI 상단에 현재 하드웨어 표시
|
| 126 |
+
- "ZeroGPU" 또는 "CPU Upgrade"
|
| 127 |
+
|
| 128 |
+
### 3. 대화 시작
|
| 129 |
|
| 130 |
```
|
| 131 |
+
안녕하세요
|
| 132 |
+
인공지능에 대해 설명해주세요
|
| 133 |
+
한국의 수도는 어디인가요?
|
|
|
|
| 134 |
```
|
| 135 |
|
| 136 |
+
## 💡 최적화 팁
|
| 137 |
|
| 138 |
+
### ZeroGPU 모드
|
|
|
|
|
|
|
| 139 |
|
| 140 |
+
1. **짧은 대화**: 긴 대화는 GPU 시간 소모
|
| 141 |
+
2. **효율적 프롬프트**: 명확하고 간결한 질문
|
| 142 |
+
3. **일일 한도 관리**: 25분 내 사용
|
| 143 |
|
| 144 |
+
### CPU Upgrade 모드
|
|
|
|
|
|
|
|
|
|
| 145 |
|
| 146 |
+
1. **인내심**: 응답 대기 시간 ���어짐
|
| 147 |
+
2. **배치 질문**: 여러 질문 동시에
|
| 148 |
+
3. **장시간 사용**: 24시간 무제한
|
| 149 |
|
| 150 |
+
## 🔗 하드웨어 전환 시나리오
|
|
|
|
| 151 |
|
| 152 |
+
### 시나리오 1: 빠른 데모 (ZeroGPU)
|
| 153 |
+
|
| 154 |
+
- 짧은 시간 내 많은 사람에게 시연
|
| 155 |
+
- 빠른 응답으로 좋은 인상
|
| 156 |
+
- 일일 한도 내 충분히 사용
|
| 157 |
+
|
| 158 |
+
### 시나리오 2: 장시간 개발 (CPU Upgrade)
|
| 159 |
+
|
| 160 |
+
- 지속적인 테스트 필요
|
| 161 |
+
- 일일 한도 걱정 없음
|
| 162 |
+
- 느린 속도 감수
|
| 163 |
+
|
| 164 |
+
### 시나리오 3: 혼합 사용
|
| 165 |
|
| 166 |
+
- 평상시: CPU Upgrade
|
| 167 |
+
- 데모 시: ZeroGPU로 전환
|
| 168 |
+
- 코드 수정 불필요 (자동 감지)
|
| 169 |
|
| 170 |
## ⚠️ 제한사항
|
| 171 |
|
| 172 |
+
### 공통
|
| 173 |
|
| 174 |
+
- **모델 크기**: 14GB (로딩 시간 필요)
|
| 175 |
+
- **컨텍스트**: 최근 3턴만 유지
|
| 176 |
+
- **한글 특화**: 영어 입력 시 품질 낮음
|
| 177 |
|
| 178 |
+
### ZeroGPU 전용
|
| 179 |
|
| 180 |
+
- **일일 한도**: 25분 (PRO 구독)
|
| 181 |
+
- **대기열**: 사용자 많을 경우 대기
|
| 182 |
+
- **PRO 필요**: $9/month 구독 필요
|
| 183 |
|
| 184 |
+
### CPU Upgrade 전용
|
| 185 |
|
| 186 |
+
- **느린 속도**: 30초~1분 응답
|
| 187 |
+
- **비용**: 시간당 $0.03 ($22/month)
|
| 188 |
+
- **성능**: GPU 대비 10배 이상 느림
|
| 189 |
|
| 190 |
+
## 📦 로컬 실행
|
|
|
|
|
|
|
|
|
|
| 191 |
|
| 192 |
+
```bash
|
| 193 |
+
# 저장소 클론
|
| 194 |
+
git clone <repository-url>
|
| 195 |
+
cd simple-chatbot-gradio
|
| 196 |
|
| 197 |
+
# 의존성 설치
|
| 198 |
+
pip install -r requirements.txt
|
|
|
|
|
|
|
|
|
|
| 199 |
|
| 200 |
+
# HF 토큰 설정
|
| 201 |
+
export HF_TOKEN=your_hugging_face_token
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 202 |
|
| 203 |
+
# 실행 (GPU 권장)
|
| 204 |
+
python app.py
|
| 205 |
+
```
|
| 206 |
+
|
| 207 |
+
**참고**: 로컬은 CPU 모드로 실행됨 (매우 느림)
|
| 208 |
+
|
| 209 |
+
## 🛠️ 기술 스택
|
| 210 |
+
|
| 211 |
+
- **프레임워크**: Gradio 5.x
|
| 212 |
+
- **ML 라이브러리**: Transformers, PyTorch
|
| 213 |
+
- **GPU 인프라**: Hugging Face ZeroGPU (선택적)
|
| 214 |
+
- **언어**: Python 3.10+
|
| 215 |
|
| 216 |
+
## 📚 Dependencies
|
| 217 |
+
|
| 218 |
+
```txt
|
| 219 |
+
gradio==5.9.1
|
| 220 |
+
transformers==4.46.0
|
| 221 |
+
torch==2.1.0
|
| 222 |
+
safetensors==0.4.5
|
| 223 |
+
accelerate==0.26.1
|
| 224 |
+
spaces # ZeroGPU support (optional)
|
| 225 |
+
```
|
| 226 |
|
| 227 |
## 🔗 관련 리소스
|
| 228 |
|
| 229 |
- [Llama-2-Ko Model Card](https://huggingface.co/beomi/llama-2-ko-7b)
|
| 230 |
- [ZeroGPU Documentation](https://huggingface.co/docs/hub/spaces-zerogpu)
|
| 231 |
- [Gradio Documentation](https://www.gradio.app/docs)
|
| 232 |
+
- [HF Spaces Pricing](https://huggingface.co/pricing)
|
| 233 |
|
| 234 |
## 📄 라이선스
|
| 235 |
|
|
|
|
| 238 |
## 🙋♂️ 문의
|
| 239 |
|
| 240 |
이슈나 질문이 있으시면 GitHub Issues를 통해 문의해주세요.
|
| 241 |
+
|
| 242 |
+
---
|
| 243 |
+
|
| 244 |
+
**💡 TIP**: 빠른 데모가 필요하면 ZeroGPU, 장시간 사용이 필요하면 CPU Upgrade를 선택하세요!
|
|
@@ -1,9 +1,17 @@
|
|
| 1 |
"""
|
| 2 |
-
|
| 3 |
-
|
| 4 |
"""
|
| 5 |
|
| 6 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
import os
|
| 8 |
import gradio as gr
|
| 9 |
from transformers import AutoModelForCausalLM, AutoTokenizer
|
|
@@ -41,23 +49,40 @@ def load_model_once():
|
|
| 41 |
if tokenizer.pad_token is None:
|
| 42 |
tokenizer.pad_token = tokenizer.eos_token
|
| 43 |
|
| 44 |
-
#
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
|
|
|
|
| 53 |
print(f"✅ Model {MODEL_NAME} loaded successfully")
|
| 54 |
|
| 55 |
return model, tokenizer
|
| 56 |
|
| 57 |
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
"""Generate chatbot response with GPU acceleration"""
|
| 61 |
if not message or not message.strip():
|
| 62 |
return history
|
| 63 |
|
|
@@ -68,12 +93,12 @@ def generate_response(message, history):
|
|
| 68 |
if current_model is None or current_tokenizer is None:
|
| 69 |
return history + [[message, "❌ 모델을 로드할 수 없습니다."]]
|
| 70 |
|
| 71 |
-
#
|
| 72 |
-
current_model.
|
| 73 |
|
| 74 |
-
# Build conversation context
|
| 75 |
conversation = ""
|
| 76 |
-
for user_msg, bot_msg in history[-3:]:
|
| 77 |
if user_msg:
|
| 78 |
conversation += f"사용자: {user_msg}\n"
|
| 79 |
if bot_msg:
|
|
@@ -87,7 +112,7 @@ def generate_response(message, history):
|
|
| 87 |
return_tensors="pt",
|
| 88 |
truncation=True,
|
| 89 |
max_length=512,
|
| 90 |
-
).to(
|
| 91 |
|
| 92 |
# Generate response
|
| 93 |
with torch.no_grad():
|
|
@@ -125,26 +150,58 @@ def generate_response(message, history):
|
|
| 125 |
return history + [[message, f"❌ 오류: {error_msg[:200]}"]]
|
| 126 |
|
| 127 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
def chat_wrapper(message, history):
|
| 129 |
"""Wrapper for Gradio ChatInterface"""
|
| 130 |
return generate_response(message, history)
|
| 131 |
|
| 132 |
|
| 133 |
-
|
|
|
|
|
|
|
| 134 |
|
| 135 |
# Create Gradio interface
|
| 136 |
with gr.Blocks(title="🤖 Llama-2-Ko Chatbot") as demo:
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 148 |
|
| 149 |
chatbot = gr.Chatbot(height=400, type="tuples", show_label=False)
|
| 150 |
|
|
@@ -165,19 +222,37 @@ with gr.Blocks(title="🤖 Llama-2-Ko Chatbot") as demo:
|
|
| 165 |
msg.submit(submit, [msg, chatbot], [chatbot, msg])
|
| 166 |
clear.click(lambda: [], outputs=chatbot)
|
| 167 |
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 181 |
|
| 182 |
if __name__ == "__main__":
|
| 183 |
demo.launch()
|
|
|
|
| 1 |
"""
|
| 2 |
+
Flexible version: Works on both ZeroGPU and CPU Upgrade hardware
|
| 3 |
+
Automatically detects hardware and adjusts accordingly
|
| 4 |
"""
|
| 5 |
|
| 6 |
+
# Try to import spaces for ZeroGPU support
|
| 7 |
+
try:
|
| 8 |
+
import spaces
|
| 9 |
+
ZEROGPU_AVAILABLE = True
|
| 10 |
+
print("✅ ZeroGPU support enabled")
|
| 11 |
+
except ImportError:
|
| 12 |
+
ZEROGPU_AVAILABLE = False
|
| 13 |
+
print("ℹ️ ZeroGPU not available, using standard mode")
|
| 14 |
+
|
| 15 |
import os
|
| 16 |
import gradio as gr
|
| 17 |
from transformers import AutoModelForCausalLM, AutoTokenizer
|
|
|
|
| 49 |
if tokenizer.pad_token is None:
|
| 50 |
tokenizer.pad_token = tokenizer.eos_token
|
| 51 |
|
| 52 |
+
# Detect device
|
| 53 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
| 54 |
+
print(f"📍 Using device: {device}")
|
| 55 |
+
|
| 56 |
+
# Load model with appropriate settings
|
| 57 |
+
if device == "cuda":
|
| 58 |
+
# GPU available (CPU Upgrade with GPU or ZeroGPU)
|
| 59 |
+
model = AutoModelForCausalLM.from_pretrained(
|
| 60 |
+
MODEL_NAME,
|
| 61 |
+
token=HF_TOKEN,
|
| 62 |
+
torch_dtype=torch.float16, # Use float16 for GPU
|
| 63 |
+
low_cpu_mem_usage=True,
|
| 64 |
+
trust_remote_code=True,
|
| 65 |
+
device_map="auto",
|
| 66 |
+
)
|
| 67 |
+
else:
|
| 68 |
+
# CPU only
|
| 69 |
+
model = AutoModelForCausalLM.from_pretrained(
|
| 70 |
+
MODEL_NAME,
|
| 71 |
+
token=HF_TOKEN,
|
| 72 |
+
torch_dtype=torch.float32, # Use float32 for CPU
|
| 73 |
+
low_cpu_mem_usage=True,
|
| 74 |
+
trust_remote_code=True,
|
| 75 |
+
)
|
| 76 |
+
model.to(device)
|
| 77 |
|
| 78 |
+
model.eval()
|
| 79 |
print(f"✅ Model {MODEL_NAME} loaded successfully")
|
| 80 |
|
| 81 |
return model, tokenizer
|
| 82 |
|
| 83 |
|
| 84 |
+
def generate_response_impl(message, history):
|
| 85 |
+
"""Core generation logic (same for both ZeroGPU and CPU)"""
|
|
|
|
| 86 |
if not message or not message.strip():
|
| 87 |
return history
|
| 88 |
|
|
|
|
| 93 |
if current_model is None or current_tokenizer is None:
|
| 94 |
return history + [[message, "❌ 모델을 로드할 수 없습니다."]]
|
| 95 |
|
| 96 |
+
# Get device
|
| 97 |
+
device = next(current_model.parameters()).device
|
| 98 |
|
| 99 |
+
# Build conversation context (last 3 turns)
|
| 100 |
conversation = ""
|
| 101 |
+
for user_msg, bot_msg in history[-3:]:
|
| 102 |
if user_msg:
|
| 103 |
conversation += f"사용자: {user_msg}\n"
|
| 104 |
if bot_msg:
|
|
|
|
| 112 |
return_tensors="pt",
|
| 113 |
truncation=True,
|
| 114 |
max_length=512,
|
| 115 |
+
).to(device)
|
| 116 |
|
| 117 |
# Generate response
|
| 118 |
with torch.no_grad():
|
|
|
|
| 150 |
return history + [[message, f"❌ 오류: {error_msg[:200]}"]]
|
| 151 |
|
| 152 |
|
| 153 |
+
# Conditionally apply ZeroGPU decorator
|
| 154 |
+
if ZEROGPU_AVAILABLE:
|
| 155 |
+
@spaces.GPU(duration=120)
|
| 156 |
+
def generate_response(message, history):
|
| 157 |
+
"""GPU-accelerated response generation (ZeroGPU mode)"""
|
| 158 |
+
return generate_response_impl(message, history)
|
| 159 |
+
else:
|
| 160 |
+
def generate_response(message, history):
|
| 161 |
+
"""Standard response generation (CPU Upgrade mode)"""
|
| 162 |
+
return generate_response_impl(message, history)
|
| 163 |
+
|
| 164 |
+
|
| 165 |
def chat_wrapper(message, history):
|
| 166 |
"""Wrapper for Gradio ChatInterface"""
|
| 167 |
return generate_response(message, history)
|
| 168 |
|
| 169 |
|
| 170 |
+
# Determine hardware info for UI
|
| 171 |
+
hardware_info = "NVIDIA H200 (ZeroGPU)" if ZEROGPU_AVAILABLE else "CPU Upgrade (32GB RAM)"
|
| 172 |
+
print(f"✅ App initialized - Hardware: {hardware_info}")
|
| 173 |
|
| 174 |
# Create Gradio interface
|
| 175 |
with gr.Blocks(title="🤖 Llama-2-Ko Chatbot") as demo:
|
| 176 |
+
# Dynamic header based on hardware
|
| 177 |
+
if ZEROGPU_AVAILABLE:
|
| 178 |
+
header = """
|
| 179 |
+
# 🤖 Llama-2-Ko 7B Chatbot (ZeroGPU)
|
| 180 |
+
|
| 181 |
+
**모델**: Llama-2-Ko 7B (한글 대화형 모델)
|
| 182 |
+
**하드웨어**: NVIDIA H200 (ZeroGPU - 자동 할당)
|
| 183 |
+
|
| 184 |
+
**특징**:
|
| 185 |
+
- ⚡ GPU 가속으로 빠른 응답 (3-5초)
|
| 186 |
+
- 🇰🇷 한글 대화에 최적화
|
| 187 |
+
- 🔄 첫 응답은 모델 로딩으로 조금 더 소요될 수 있습니다
|
| 188 |
+
- 💰 PRO 구독 시 하루 25분 무료 사용
|
| 189 |
+
"""
|
| 190 |
+
else:
|
| 191 |
+
header = """
|
| 192 |
+
# 🤖 Llama-2-Ko 7B Chatbot (CPU Upgrade)
|
| 193 |
+
|
| 194 |
+
**모델**: Llama-2-Ko 7B (한글 대화형 모델)
|
| 195 |
+
**하드웨어**: CPU Upgrade (8 vCPU / 32 GB RAM)
|
| 196 |
+
|
| 197 |
+
**특징**:
|
| 198 |
+
- 🇰🇷 한글 대화에 최적화
|
| 199 |
+
- 🔄 첫 응답은 모델 로딩으로 조금 더 소요될 수 있습니다 (10-15초)
|
| 200 |
+
- ⏳ CPU 환경이므로 응답이 다소 느립니다 (30초~1분)
|
| 201 |
+
- 💰 시간당 $0.03 (월 약 $22)
|
| 202 |
+
"""
|
| 203 |
+
|
| 204 |
+
gr.Markdown(header)
|
| 205 |
|
| 206 |
chatbot = gr.Chatbot(height=400, type="tuples", show_label=False)
|
| 207 |
|
|
|
|
| 222 |
msg.submit(submit, [msg, chatbot], [chatbot, msg])
|
| 223 |
clear.click(lambda: [], outputs=chatbot)
|
| 224 |
|
| 225 |
+
# Dynamic footer based on hardware
|
| 226 |
+
if ZEROGPU_AVAILABLE:
|
| 227 |
+
footer = """
|
| 228 |
+
---
|
| 229 |
+
**참고사항 (ZeroGPU 모드)**:
|
| 230 |
+
- ZeroGPU는 요청 시 자동으로 GPU를 할당합니다
|
| 231 |
+
- PRO 구독자는 하루 25분 무료 사용 가능
|
| 232 |
+
- 첫 응답은 모델 로딩 시간 포함 (~10-15초)
|
| 233 |
+
- 이후 응답은 빠르게 생성됩니다 (~3-5초)
|
| 234 |
+
|
| 235 |
+
**테스트 예시**:
|
| 236 |
+
- "안녕하세요"
|
| 237 |
+
- "인공지능에 대해 설명해주세요"
|
| 238 |
+
- "오늘 날씨가 어때요?"
|
| 239 |
+
"""
|
| 240 |
+
else:
|
| 241 |
+
footer = """
|
| 242 |
+
---
|
| 243 |
+
**참고사항 (CPU Upgrade 모드)**:
|
| 244 |
+
- CPU 환경에서 실행되므로 응답이 느립니다 (30초~1분)
|
| 245 |
+
- 첫 응답은 모델 로딩 시간 포함 (~1-2분)
|
| 246 |
+
- 24시간 무제한 사용 가능 (시간당 $0.03)
|
| 247 |
+
- GPU 환경(ZeroGPU)으로 전환 시 더 빠른 응답 가능
|
| 248 |
+
|
| 249 |
+
**테스트 예시**:
|
| 250 |
+
- "안녕하세요"
|
| 251 |
+
- "인공지능에 대해 설명해주세요"
|
| 252 |
+
- "오늘 날씨가 어때요?"
|
| 253 |
+
"""
|
| 254 |
+
|
| 255 |
+
gr.Markdown(footer)
|
| 256 |
|
| 257 |
if __name__ == "__main__":
|
| 258 |
demo.launch()
|