Upload 19 files
Browse files- .gitattributes +8 -0
- 6์ฃผ์ฐจ_HuggingFace_์นผ๋ก๋ฆฌ์นด์ดํฐ.html +1107 -0
- README.md +79 -6
- __pycache__/model_config.cpython-313.pyc +0 -0
- app.py +215 -0
- calcal/.gitattributes +35 -0
- calcal/README.md +14 -0
- images/01_main.png +3 -0
- images/02_models.png +3 -0
- images/03_model_card.png +3 -0
- images/04_spaces.png +3 -0
- images/05_tokens.png +3 -0
- images/06_new_space.png +3 -0
- images/07_secrets.png +0 -0
- images/08_files.png +0 -0
- images/09_app_logs.png +3 -0
- images/10_write_token.png +3 -0
- images/11_running.png +0 -0
- model_config.py +35 -0
- requirements.txt +7 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,11 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
images/01_main.png filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
images/02_models.png filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
images/03_model_card.png filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
images/04_spaces.png filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
images/05_tokens.png filter=lfs diff=lfs merge=lfs -text
|
| 41 |
+
images/06_new_space.png filter=lfs diff=lfs merge=lfs -text
|
| 42 |
+
images/09_app_logs.png filter=lfs diff=lfs merge=lfs -text
|
| 43 |
+
images/10_write_token.png filter=lfs diff=lfs merge=lfs -text
|
6์ฃผ์ฐจ_HuggingFace_์นผ๋ก๋ฆฌ์นด์ดํฐ.html
ADDED
|
@@ -0,0 +1,1107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="ko">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="utf-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>6์ฃผ์ฐจ โ HuggingFace ร Spaces ร ์นผ๋ก๋ฆฌ ์นด์ดํฐ</title>
|
| 7 |
+
<style>
|
| 8 |
+
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
| 9 |
+
body {
|
| 10 |
+
font-family: 'Segoe UI', 'Apple SD Gothic Neo', sans-serif;
|
| 11 |
+
font-size: 16px; line-height: 1.7; color: #1a1a2e;
|
| 12 |
+
background: #f8f9fc; overflow-x: hidden;
|
| 13 |
+
}
|
| 14 |
+
a { color: #f59e0b; text-decoration: none; font-weight: 600; }
|
| 15 |
+
a:hover { text-decoration: underline; }
|
| 16 |
+
|
| 17 |
+
.page-wrapper { max-width: 920px; margin: 0 auto; padding: 2rem 1.5rem 6rem; }
|
| 18 |
+
|
| 19 |
+
/* Hero */
|
| 20 |
+
.hero {
|
| 21 |
+
background: linear-gradient(135deg, #f59e0b 0%, #ef4444 100%);
|
| 22 |
+
border-radius: 20px; padding: 3rem 2.5rem; margin-bottom: 2rem;
|
| 23 |
+
color: white; position: relative; overflow: hidden;
|
| 24 |
+
}
|
| 25 |
+
.hero::after {
|
| 26 |
+
content: '๐ค๐ฑ'; position: absolute; right: 2rem; top: 50%;
|
| 27 |
+
transform: translateY(-50%); font-size: 6rem; opacity: 0.2;
|
| 28 |
+
}
|
| 29 |
+
.hero .week-badge {
|
| 30 |
+
display: inline-block; background: rgba(255,255,255,0.25);
|
| 31 |
+
border: 1px solid rgba(255,255,255,0.5); border-radius: 999px;
|
| 32 |
+
padding: 0.3rem 1rem; font-size: 0.85rem; margin-bottom: 1rem;
|
| 33 |
+
}
|
| 34 |
+
.hero h1 { font-size: 2rem; font-weight: 700; margin-bottom: 0.5rem; }
|
| 35 |
+
.hero p { font-size: 1.05rem; opacity: 0.95; max-width: 600px; }
|
| 36 |
+
|
| 37 |
+
.objectives { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-bottom: 2.5rem; }
|
| 38 |
+
.obj-tag {
|
| 39 |
+
background: white; border: 2px solid #f59e0b; border-radius: 999px;
|
| 40 |
+
padding: 0.35rem 1rem; font-size: 0.85rem; color: #b45309; font-weight: 700;
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
/* Sections */
|
| 44 |
+
.class-section {
|
| 45 |
+
background: white; border-radius: 16px; padding: 2rem;
|
| 46 |
+
margin-bottom: 1.6rem; box-shadow: 0 2px 12px rgba(0,0,0,0.06);
|
| 47 |
+
border-left: 5px solid;
|
| 48 |
+
}
|
| 49 |
+
.class-section.s1 { border-color: #f59e0b; }
|
| 50 |
+
.class-section.s2 { border-color: #ef4444; }
|
| 51 |
+
.class-section.s3 { border-color: #8b5cf6; }
|
| 52 |
+
.class-section.s4 { border-color: #10b981; }
|
| 53 |
+
.class-section.s5 { border-color: #3b82f6; }
|
| 54 |
+
|
| 55 |
+
.section-label {
|
| 56 |
+
font-size: 0.75rem; font-weight: 700; letter-spacing: 0.1em;
|
| 57 |
+
text-transform: uppercase; margin-bottom: 0.3rem; color: #6b7280;
|
| 58 |
+
}
|
| 59 |
+
.s1 .section-label { color: #b45309; }
|
| 60 |
+
.s2 .section-label { color: #b91c1c; }
|
| 61 |
+
.s3 .section-label { color: #6d28d9; }
|
| 62 |
+
.s4 .section-label { color: #047857; }
|
| 63 |
+
.s5 .section-label { color: #1d4ed8; }
|
| 64 |
+
|
| 65 |
+
.section-title {
|
| 66 |
+
font-size: 1.4rem; font-weight: 700; margin-bottom: 1rem; color: #1a1a2e;
|
| 67 |
+
}
|
| 68 |
+
h3 { font-size: 1.05rem; margin: 1.4rem 0 0.6rem; color: #1a1a2e; }
|
| 69 |
+
p { margin-bottom: 0.8rem; }
|
| 70 |
+
ul, ol { padding-left: 1.4rem; margin-bottom: 0.8rem; }
|
| 71 |
+
li { margin-bottom: 0.3rem; }
|
| 72 |
+
strong { color: #b45309; }
|
| 73 |
+
|
| 74 |
+
/* Why box */
|
| 75 |
+
.why-box {
|
| 76 |
+
background: linear-gradient(135deg, #fef3c7 0%, #fed7aa 100%);
|
| 77 |
+
border-left: 4px solid #f59e0b;
|
| 78 |
+
padding: 1.2rem 1.4rem; border-radius: 10px; margin: 1rem 0;
|
| 79 |
+
}
|
| 80 |
+
.why-box .label {
|
| 81 |
+
font-size: 0.7rem; font-weight: 800; color: #b45309;
|
| 82 |
+
letter-spacing: 0.1em; text-transform: uppercase; margin-bottom: 0.4rem;
|
| 83 |
+
}
|
| 84 |
+
.why-box p:last-child { margin-bottom: 0; }
|
| 85 |
+
|
| 86 |
+
/* Concept grid */
|
| 87 |
+
.concept-grid {
|
| 88 |
+
display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
|
| 89 |
+
gap: 0.8rem; margin: 1rem 0;
|
| 90 |
+
}
|
| 91 |
+
.concept-card {
|
| 92 |
+
background: #fef3c7; border-radius: 12px; padding: 1rem;
|
| 93 |
+
text-align: center;
|
| 94 |
+
}
|
| 95 |
+
.concept-card .icon { font-size: 1.8rem; margin-bottom: 0.4rem; }
|
| 96 |
+
.concept-card .name { font-weight: 700; font-size: 0.95rem; color: #1a1a2e; margin-bottom: 0.3rem; }
|
| 97 |
+
.concept-card .desc { font-size: 0.78rem; color: #6b7280; line-height: 1.4; }
|
| 98 |
+
|
| 99 |
+
/* Compare table */
|
| 100 |
+
table {
|
| 101 |
+
width: 100%; border-collapse: collapse; margin: 1rem 0;
|
| 102 |
+
font-size: 0.9rem;
|
| 103 |
+
}
|
| 104 |
+
th, td {
|
| 105 |
+
border: 1px solid #e5e7eb; padding: 0.6rem 0.8rem; text-align: left;
|
| 106 |
+
vertical-align: top;
|
| 107 |
+
}
|
| 108 |
+
th { background: #fef3c7; font-weight: 700; color: #92400e; }
|
| 109 |
+
tr:nth-child(even) td { background: #fafafa; }
|
| 110 |
+
|
| 111 |
+
/* Code */
|
| 112 |
+
pre {
|
| 113 |
+
background: #1e293b; color: #e2e8f0; padding: 1rem 1.2rem;
|
| 114 |
+
border-radius: 10px; overflow-x: auto; font-size: 0.85rem;
|
| 115 |
+
margin: 0.8rem 0; line-height: 1.55;
|
| 116 |
+
}
|
| 117 |
+
code { font-family: 'Consolas', 'Monaco', monospace; }
|
| 118 |
+
p code, li code {
|
| 119 |
+
background: #fef3c7; color: #b45309; padding: 0.1rem 0.4rem;
|
| 120 |
+
border-radius: 4px; font-size: 0.88em;
|
| 121 |
+
}
|
| 122 |
+
.comment { color: #94a3b8; }
|
| 123 |
+
.kw { color: #f59e0b; }
|
| 124 |
+
.str { color: #86efac; }
|
| 125 |
+
|
| 126 |
+
/* TODO box */
|
| 127 |
+
.todo-box {
|
| 128 |
+
background: #fff7ed; border: 2px dashed #f59e0b;
|
| 129 |
+
border-radius: 10px; padding: 1rem 1.2rem; margin: 0.8rem 0;
|
| 130 |
+
}
|
| 131 |
+
.todo-box .num {
|
| 132 |
+
display: inline-block; background: #f59e0b; color: white;
|
| 133 |
+
width: 28px; height: 28px; border-radius: 50%;
|
| 134 |
+
text-align: center; line-height: 28px; font-weight: 700;
|
| 135 |
+
margin-right: 0.5rem;
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
/* Steps */
|
| 139 |
+
.step-list { counter-reset: step; list-style: none; padding: 0; }
|
| 140 |
+
.step-list li {
|
| 141 |
+
counter-increment: step; position: relative;
|
| 142 |
+
padding: 0.6rem 0 0.6rem 2.4rem; margin-bottom: 0.4rem;
|
| 143 |
+
}
|
| 144 |
+
.step-list li::before {
|
| 145 |
+
content: counter(step);
|
| 146 |
+
position: absolute; left: 0; top: 0.5rem;
|
| 147 |
+
width: 1.8rem; height: 1.8rem; background: #f59e0b;
|
| 148 |
+
color: white; border-radius: 50%; text-align: center;
|
| 149 |
+
line-height: 1.8rem; font-weight: 700; font-size: 0.85rem;
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
/* Q&A */
|
| 153 |
+
.qa { background: #f3f4f6; border-radius: 10px; padding: 1rem 1.2rem; margin: 0.8rem 0; }
|
| 154 |
+
.qa .q { font-weight: 700; color: #b91c1c; margin-bottom: 0.4rem; }
|
| 155 |
+
.qa .a { color: #374151; }
|
| 156 |
+
|
| 157 |
+
/* Glossary */
|
| 158 |
+
.glossary dt { font-weight: 700; color: #b45309; margin-top: 0.6rem; }
|
| 159 |
+
.glossary dd { margin-left: 1rem; color: #374151; font-size: 0.92rem; }
|
| 160 |
+
|
| 161 |
+
/* Mission */
|
| 162 |
+
.mission {
|
| 163 |
+
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
|
| 164 |
+
color: white; border-radius: 16px; padding: 2rem;
|
| 165 |
+
margin-top: 2rem;
|
| 166 |
+
}
|
| 167 |
+
.mission h2 { font-size: 1.5rem; margin-bottom: 1rem; }
|
| 168 |
+
.mission ul { list-style: none; padding: 0; }
|
| 169 |
+
.mission li { padding: 0.5rem 0 0.5rem 2rem; position: relative; }
|
| 170 |
+
.mission li::before {
|
| 171 |
+
content: 'โ'; position: absolute; left: 0;
|
| 172 |
+
font-size: 1.3rem; opacity: 0.9;
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
footer { text-align: center; color: #9ca3af; font-size: 0.85rem; margin-top: 3rem; }
|
| 176 |
+
</style>
|
| 177 |
+
</head>
|
| 178 |
+
<body>
|
| 179 |
+
<div class="page-wrapper">
|
| 180 |
+
|
| 181 |
+
<!-- HERO -->
|
| 182 |
+
<div class="hero">
|
| 183 |
+
<div class="week-badge">WEEK 06 ยท 2026 AI์น์ตํฉ</div>
|
| 184 |
+
<h1>HuggingFace๋ก AI ์ฑ ๋ง๋ค๊ณ ์ธ์์ ๊ณต๊ฐํ๊ธฐ</h1>
|
| 185 |
+
<p>์์ ์ฌ์ง ํ ์ฅ์ผ๋ก ์นผ๋ก๋ฆฌ๋ฅผ ์ถ์ ํ๋ ์ฑ์ ์ง์ ๋ง๋ค๊ณ ,
|
| 186 |
+
HuggingFace Space์ ๋ฐฐํฌํด ๋๊ตฌ๋ ์ ์ํ ์ ์๋ ๊ณต๊ฐ URL์ ๋ฐ๋๋ค.</p>
|
| 187 |
+
</div>
|
| 188 |
+
|
| 189 |
+
<!-- OBJECTIVES -->
|
| 190 |
+
<div class="objectives">
|
| 191 |
+
<span class="obj-tag">๐ค HF ์ํ๊ณ ์ดํด</span>
|
| 192 |
+
<span class="obj-tag">๐ง ๋ชจ๋ธ vs ๋ฐ์ดํฐ์
vs Space</span>
|
| 193 |
+
<span class="obj-tag">๐ผ๏ธ Inference API ํธ์ถ</span>
|
| 194 |
+
<span class="obj-tag">๐๏ธ Gradio UI</span>
|
| 195 |
+
<span class="obj-tag">๐ Space ๋ฐฐํฌ</span>
|
| 196 |
+
</div>
|
| 197 |
+
|
| 198 |
+
<!-- SECTION 1 -->
|
| 199 |
+
<section class="class-section s1">
|
| 200 |
+
<div class="section-label">SECTION 1 ยท WHY</div>
|
| 201 |
+
<h2 class="section-title">์ HuggingFace๋ฅผ ๋ฐฐ์์ผ ํ๋๊ฐ?</h2>
|
| 202 |
+
|
| 203 |
+
<p>HuggingFace๋ ๋จ์ํ "AI ๋ชจ๋ธ ๋ค์ด๋ก๋ ์ฌ์ดํธ"๊ฐ ์๋๋ค.
|
| 204 |
+
<strong>์ค๋๋ ์คํ์์ค AI ์ํ๊ณ์ GitHub</strong>์ ํด๋นํ๋ ํ๋ซํผ์ด๋ฉฐ,
|
| 205 |
+
์ ์ธ๊ณ ์ฐ๊ตฌ์/๊ธฐ์
์ด ๋ง๋ 100๋ง ๊ฐ ์ด์์ ๋ชจ๋ธยท๋ฐ์ดํฐ์
ยท๋ฐ๋ชจ๊ฐ ๋ชจ์ฌ ์๋ค.</p>
|
| 206 |
+
|
| 207 |
+
<div class="why-box">
|
| 208 |
+
<div class="label">ํ ์ค ์์ฝ</div>
|
| 209 |
+
<p>OpenAI/Anthropic ๊ฐ์ <strong>ํ์ํ(Closed) API</strong>๊ฐ "์ด๋ฏธ ๋ง๋ค์ด์ง ์ํ๊ธฐ"๋ผ๋ฉด,
|
| 210 |
+
HuggingFace๋ <strong>์คํ์์ค(Open-weight) ๋ชจ๋ธ์ ๊ณจ๋ผ์ ์ง์ ์กฐ๋ฆฝํ ์ ์๋ ๋ถํ ๊ฐ๊ฒ + ์์
์ฅ + ์ ์๊ด</strong>์ด๋ค.</p>
|
| 211 |
+
</div>
|
| 212 |
+
|
| 213 |
+
<h3>๐ ํ์์ผ๋ก์ HF๋ฅผ ๋ฐฐ์์ผ ํ๋ 5๊ฐ์ง ์ด์ </h3>
|
| 214 |
+
<ol>
|
| 215 |
+
<li><strong>๋น์ฉ 0์์ผ๋ก ์์</strong> โ ๊ฐ์
๋ง ํ๋ฉด Inference API/Space๋ฅผ ๋ฌด๋ฃ๋ก ์ธ ์ ์๋ค.
|
| 216 |
+
OpenAI์ฒ๋ผ ์นด๋ ๋ฑ๋ก๋, ์ถฉ์ ๋ ํ์ ์๋ค.</li>
|
| 217 |
+
<li><strong>๋ค์ํ ๋ชจ๋ฌ๋ฆฌํฐ</strong> โ GPT๋ฅ๋ ํ
์คํธ ์ค์ฌ์ด์ง๋ง, HF์๋
|
| 218 |
+
์ด๋ฏธ์ง ๋ถ๋ฅยท์์ฑ ์ธ์ยท๋ฒ์ญยทOCRยท์ธ๊ทธ๋ฉํ
์ด์
๋ฑ <em>ํน์ ์์
์ ํนํ๋ ์์ ๋ชจ๋ธ</em>์ด ์๋ง ๊ฐ ์๋ค.</li>
|
| 219 |
+
<li><strong>๋ชจ๋ธ์ ๋ด๋ถ๋ฅผ ๋ณผ ์ ์๋ค</strong> โ ๊ฐ์ค์น(weights)ยท๊ตฌ์กฐยทํ์ต ๋ฐ์ดํฐ๊น์ง ๊ณต๊ฐ๋์ด ์์ด
|
| 220 |
+
"AI๊ฐ ์ด๋ป๊ฒ ๋์ํ๋๊ฐ"๋ฅผ ์ค์ ๋ก ๋ค์ฌ๋ค๋ณผ ์ ์๋ค.</li>
|
| 221 |
+
<li><strong>ํ ์ค๋ก ๋ฐฐํฌ</strong> โ GitHub์ ์ฝ๋ ํธ์ํ๋ฏ Space์ ํธ์ํ๋ฉด ๊ณง๋ฐ๋ก ๊ณต๊ฐ URL์ด ์๊ธด๋ค.
|
| 222 |
+
์๋ฒ ์ค์ ยท๋๋ฉ์ธยทSSL ๊ฐ์ ์ธํ๋ผ ์ง์์ด ์์ด๋ ๋๋ค.</li>
|
| 223 |
+
<li><strong>์ด๋ ฅ์๊ฐ ๋๋ค</strong> โ ์ง์ ๋ง๋ Space๋ ์ฑ์ฉ ๋ด๋น์๋ ๊ต์์๊ฒ
|
| 224 |
+
"๋๋ AI๋ฅผ ์ธ ์ค ์๋ค"๋ฅผ ์ฆ๋ช
ํ๋ ๊ฐ์ฅ ๋น ๋ฅธ ๋ฐฉ๋ฒ์ด๋ค.</li>
|
| 225 |
+
</ol>
|
| 226 |
+
|
| 227 |
+
<h3>๐ OpenAI API vs HuggingFace</h3>
|
| 228 |
+
<table>
|
| 229 |
+
<tr><th>๊ด์ </th><th>OpenAI API</th><th>HuggingFace</th></tr>
|
| 230 |
+
<tr><td>๋ชจ๋ธ ์ข
๋ฅ</td><td>GPT ๊ณ์ด ๋ช ๊ฐ</td><td>100๋ง+ ์คํ ๋ชจ๋ธ</td></tr>
|
| 231 |
+
<tr><td>๋น์ฉ</td><td>ํ ํฐ๋น ๊ณผ๊ธ</td><td>๋ฌด๋ฃ ํฐ์ด (Inference API/Space)</td></tr>
|
| 232 |
+
<tr><td>๋ชจ๋ธ ๊ฐ์ค์น</td><td>๋น๊ณต๊ฐ</td><td>๋๋ถ๋ถ ๊ณต๊ฐ (๋ค์ด๋ก๋ ๊ฐ๋ฅ)</td></tr>
|
| 233 |
+
<tr><td>๋ก์ปฌ ์คํ</td><td>๋ถ๊ฐ๋ฅ</td><td>๊ฐ๋ฅ (transformers ๋ผ์ด๋ธ๋ฌ๋ฆฌ)</td></tr>
|
| 234 |
+
<tr><td>์ปค์คํฐ๋ง์ด์ฆ</td><td>ํ๋กฌ๏ฟฝ๏ฟฝ๏ฟฝํธ ์์ค</td><td>ํ์ธํ๋๊น์ง ๊ฐ๋ฅ</td></tr>
|
| 235 |
+
<tr><td>UI ๋ฐฐํฌ</td><td>์ง์ ๋ง๋ค์ด์ผ ํจ</td><td>Spaces๋ก ํ ๋ฒ์</td></tr>
|
| 236 |
+
</table>
|
| 237 |
+
|
| 238 |
+
<div class="why-box">
|
| 239 |
+
<p>AI ๋ชจ๋ธ ์ํ๊ณ๋ ํฌ๊ฒ ๋ ์ง์์ผ๋ก ๋๋ฉ๋๋ค. <br>
|
| 240 |
+
<strong>Closed ์ง์์ ๋ํ์ฃผ์๊ฐ OpenAI</strong>๋ผ๋ฉด,
|
| 241 |
+
<strong>Open ์ง์์ ๋ํ์ฃผ์๊ฐ HuggingFace</strong>์
๋๋ค.
|
| 242 |
+
</p>
|
| 243 |
+
</div>
|
| 244 |
+
</section>
|
| 245 |
+
|
| 246 |
+
<!-- SECTION 2 -->
|
| 247 |
+
<section class="class-section s2">
|
| 248 |
+
<div class="section-label">SECTION 2 ยท CONCEPT</div>
|
| 249 |
+
<h2 class="section-title">HuggingFace ์ํ๊ณ ํ๋์ ๋ณด๊ธฐ</h2>
|
| 250 |
+
|
| 251 |
+
<p>HF์ ์ฒ์ ๋ค์ด๊ฐ๋ฉด ๋ฉ๋ด๊ฐ ๋ง์ ์ด์ง๋ฝ๋ค. ์ฌ์ค ํต์ฌ์ <strong>4๊ฐ์ ๊ธฐ๋ฅ</strong>๋ฟ์ด๋ค.</p>
|
| 252 |
+
|
| 253 |
+
<div class="concept-grid">
|
| 254 |
+
<div class="concept-card">
|
| 255 |
+
<div class="icon">๐ง </div>
|
| 256 |
+
<div class="name">Models</div>
|
| 257 |
+
<div class="desc">ํ์ต๋ AI ๋ชจ๋ธ ์ ์ฅ์.<br>๊ฐ์ค์นยท์ฝ๋ยท์ฌ์ฉ๋ฒ ํฌํจ</div>
|
| 258 |
+
</div>
|
| 259 |
+
<div class="concept-card">
|
| 260 |
+
<div class="icon">๐</div>
|
| 261 |
+
<div class="name">Datasets</div>
|
| 262 |
+
<div class="desc">ํ์ต/ํ๊ฐ์ฉ ๋ฐ์ดํฐ์
.<br>ํ ์ค ์ฝ๋๋ก ๋ก๋ฉ ๊ฐ๋ฅ</div>
|
| 263 |
+
</div>
|
| 264 |
+
<div class="concept-card">
|
| 265 |
+
<div class="icon">๐</div>
|
| 266 |
+
<div class="name">Spaces</div>
|
| 267 |
+
<div class="desc">AI ๋ฐ๋ชจ๋ฅผ ํธ์คํ
ํ๋<br>๋ฌด๋ฃ ์น์ฑ ํ๋ซํผ</div>
|
| 268 |
+
</div>
|
| 269 |
+
<div class="concept-card">
|
| 270 |
+
<div class="icon">โก</div>
|
| 271 |
+
<div class="name">Inference API</div>
|
| 272 |
+
<div class="desc">๋ชจ๋ธ์ ๋ค์ด ์ ๋ฐ๊ณ <br>HTTP๋ก ๋ฐ๋ก ํธ์ถ</div>
|
| 273 |
+
</div>
|
| 274 |
+
</div>
|
| 275 |
+
|
| 276 |
+
<h3>๐ง Model Hub โ "AI ๋ชจ๋ธ์ GitHub"</h3>
|
| 277 |
+
<p>ํ ๋ชจ๋ธ ํ์ด์ง์๋ ๋ค์์ด ๋ค์ด ์๋ค:</p>
|
| 278 |
+
<ul>
|
| 279 |
+
<li><strong>Model Card</strong> โ ์ด ๋ชจ๋ธ์ด ๋ฌด์์ ํ๋์ง, ์ด๋ป๊ฒ ํ์ตํ๋์ง, ํ๊ณ๋ ๋ฌด์์ธ์ง ์ ํ ์ค๋ช
์</li>
|
| 280 |
+
<li><strong>Files and versions</strong> โ ๊ฐ์ค์น ํ์ผ(.safetensors), ํ ํฌ๋์ด์ , ์ค์ ํ์ผ</li>
|
| 281 |
+
<li><strong>Inference API ์์ ฏ</strong> โ ํ์ด์ง ์ฐ์ธก์์ ๋ฐ๋ก ๋ชจ๋ธ์ ํ
์คํธํด๋ณผ ์ ์๋ ๋ฐ์ค</li>
|
| 282 |
+
<li><strong>์ปค๋ฎค๋ํฐ ํญ</strong> โ ๋ค๋ฅธ ์ฌ์ฉ์์ ์ง๋ฌธ/์ด์</li>
|
| 283 |
+
</ul>
|
| 284 |
+
<p>์ค๋ ์ฐ๋ฆฌ๊ฐ ์ธ ๋ชจ๋ธ: <code>nateraw/food</code> โ Vision Transformer(ViT)๋ฅผ
|
| 285 |
+
Food-101 ๋ฐ์ดํฐ์
์ผ๋ก ํ์ธํ๋ํ ์์ ์ด๋ฏธ์ง ๋ถ๋ฅ๊ธฐ.</p>
|
| 286 |
+
|
| 287 |
+
<h3>๐ Spaces โ "AI ๋ฐ๋ชจ์ Vercel/Netlify"</h3>
|
| 288 |
+
<p>Space๋ ํ๋ง๋๋ก <strong>"AI ์ฑ์ ๊น ํธ์ ํ ๋ฒ์ผ๋ก ๋ฐฐํฌํด์ฃผ๋ ๋ฌด๋ฃ ํธ์คํ
"</strong>์ด๋ค.</p>
|
| 289 |
+
<ul>
|
| 290 |
+
<li>์ง์ SDK: <strong>Gradio</strong>(ํ์ด์ฌ UI), <strong>Streamlit</strong>, <strong>Static HTML</strong>, <strong>Docker</strong></li>
|
| 291 |
+
<li>๋ฌด๋ฃ ํ๋์จ์ด: 2 vCPU + 16GB RAM (CPU Basic)</li>
|
| 292 |
+
<li>๊ฐ Space๋ git ์ ์ฅ์์ด๋ฉฐ <code>https://huggingface.co/spaces/<์ ์ >/<์ด๋ฆ></code> ์ฃผ์๋ฅผ ๋ฐ๋๋ค</li>
|
| 293 |
+
<li>๋น๊ณต๊ฐ ํ ํฐ์ <em>Settings โ Secrets</em>์ ๋ฑ๋กํ๋ค (์ฝ๋์๋ ์ ๋ ์ ์ง ์์)</li>
|
| 294 |
+
</ul>
|
| 295 |
+
|
| 296 |
+
<h3>โก Inference API โ "๋ชจ๋ธ์ ๋ถ๋ฅด๋ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ"</h3>
|
| 297 |
+
<table>
|
| 298 |
+
<tr><th>๋ฐฉ์</th><th>์ฌ์ฉ ์์ </th><th>ํน์ง</th></tr>
|
| 299 |
+
<tr>
|
| 300 |
+
<td><strong>๋ก์ปฌ ์คํ</strong><br>(transformers)</td>
|
| 301 |
+
<td>๋ชจ๋ธ์ ๋ด ์ปดํจํฐ/์๋ฒ์ ๋ค์ด๋ก๋ํด ์ง์ ๋๋ฆผ</td>
|
| 302 |
+
<td>์๋ ๋น ๋ฆ, ๋น์ฉ 0, ๊ทธ๋ฌ๋ GPU/RAM ํ์</td>
|
| 303 |
+
</tr>
|
| 304 |
+
<tr>
|
| 305 |
+
<td><strong>Inference API</strong><br>(InferenceClient)</td>
|
| 306 |
+
<td>HF ์๋ฒ์ HTTP ์์ฒญ๋ง ๋ณด๋ด๊ณ ๊ฒฐ๊ณผ ๋ฐ์</td>
|
| 307 |
+
<td>์ค์น ๋ถํ์, ์์ ๋
ธํธ๋ถ์์๋ ๋์ โ
</td>
|
| 308 |
+
</tr>
|
| 309 |
+
</table>
|
| 310 |
+
<p>์ด๋ฒ ์ฃผ์ฐจ๋ ํ์(Inference API)๋ฅผ ์ด๋ค. ํ์์ฉ ๋
ธํธ๋ถ์ GPU๊ฐ ์์ด๋ ๋์ํ๊ธฐ ๋๋ฌธ์ด๋ค.</p>
|
| 311 |
+
</section>
|
| 312 |
+
|
| 313 |
+
<!-- SECTION 2.5 -->
|
| 314 |
+
<section class="class-section s4">
|
| 315 |
+
<div class="section-label">SECTION 2.5 ยท GUIDED TOUR</div>
|
| 316 |
+
<h2 class="section-title">HuggingFace ์ฌ์ดํธ ์์ ์ ๋ณต ๊ฐ์ด๋</h2>
|
| 317 |
+
|
| 318 |
+
<p>์ฒ์ ์ ์ํ๋ฉด ๋ฉ๋ด๊ฐ ๋๋ฌด ๋ง์ ๋นํฉํ๋ค. ์ด ์น์
์ <strong>"์ด๋๋ฅผ ํด๋ฆญํ๋ฉด ๋ฌด์์ด ๋์ค๋๊ฐ"</strong>๋ฅผ
|
| 319 |
+
์ง๋์ฒ๋ผ ์ ๋ฆฌํ ๊ฒ์ด๋ค. ๊ฐ์ ์ค์ ํ๋ฉด์ ๋์๋๊ณ ๊ฐ์ด ๋ฐ๋ผ๊ฐ์.</p>
|
| 320 |
+
|
| 321 |
+
<h3>๐ 1. ๋ฉ์ธ ํ์ด์ง โ ์๋จ ๋ด๋น๊ฒ์ด์
</h3>
|
| 322 |
+
<p><a href="https://huggingface.co">huggingface.co</a> ์ ์ ์ ์๋จ์ ๋ณด์ด๋ ๋ฉ๋ด:</p>
|
| 323 |
+
<img src="images/01_main.png" alt="HuggingFace ๋ฉ์ธ ํ์ด์ง" style="width:100%;max-width:900px;border:1px solid #e5e7eb;border-radius:8px;margin:0.6rem 0;">
|
| 324 |
+
<p style="color:#6b7280;font-size:0.9em;">์ ์ด๋ฏธ์ง์ ์๊น ๋ฒํธ โ ~โค๊ฐ ์๋ ํ์ ๋งค์นญ๋๋ค.</p>
|
| 325 |
+
<table>
|
| 326 |
+
<tr><th>๋ฒํธ</th><th>๋ฉ๋ด</th><th>๋ฌด์์ด ์๋๊ฐ</th><th>์ธ์ ํด๋ฆญํ๋</th></tr>
|
| 327 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#ef4444;color:white;text-align:center;font-weight:bold;">1</span></td><td><strong>Models</strong></td><td>100๋ง+ ์ฌ์ ํ์ต ๋ชจ๋ธ</td><td>"์ด๋ฐ ์ผ์ ํ๋ ๋ชจ๋ธ ์๋?" ๊ฒ์ํ ๋</td></tr>
|
| 328 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#f97316;color:white;text-align:center;font-weight:bold;">2</span></td><td><strong>Datasets</strong></td><td>ํ์ต/ํ๊ฐ์ฉ ๋ฐ์ดํฐ์
</td><td>๋ชจ๋ธ์ ์ง์ ํ์ต์ํฌ ๋</td></tr>
|
| 329 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#0ea5e9;color:white;text-align:center;font-weight:bold;">3</span></td><td><strong>Spaces</strong></td><td>๋ค๋ฅธ ์ฌ๋๋ค์ด ๋ง๋ AI ๋ฐ๋ชจ</td><td>์์ด๋์ด ์ป๊ณ ์ถ์ ๋ / ๋ด ์ฑ ๋ฐฐํฌํ ๋</td></tr>
|
| 330 |
+
<tr><td>โ</td><td><strong>Buckets</strong> <span style="background:#fbbf24;color:#78350f;font-size:0.7em;padding:2px 6px;border-radius:4px;">NEW</span></td><td>AI ํ์ฉ ์ค๋ธ์ ํธ ์คํ ๋ฆฌ์ง (TB๋น $8~18/์, Xet ์ค๋ณต์ ๊ฑฐ + CDN, <code>hf sync</code>๋ก git ์์ด ๋์ฉ๋ ๋๊ธฐํ)</td><td>๋์ฉ๋ ๋ชจ๋ธ/๋ฐ์ดํฐ์
์ S3 ๋์ HF์ ์ ์ฅํ ๋ โ ์์
์์๋ ๋ฌด์ OK</td></tr>
|
| 331 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#10b981;color:white;text-align:center;font-weight:bold;">4</span></td><td><strong>Docs</strong></td><td>๊ณต์ ๋ฌธ์</td><td>๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ๋ฒ ๋งํ ๋</td></tr>
|
| 332 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#8b5cf6;color:white;text-align:center;font-weight:bold;">5</span></td><td><strong>Pricing</strong></td><td>๋ฌด๋ฃ/์ ๋ฃ ํ๋</td><td>"PRO ๊ณ์ ๋ญ์ง" ๊ถ๊ธํ ๋</td></tr>
|
| 333 |
+
</table>
|
| 334 |
+
|
| 335 |
+
<h3>๐ง 2. Models ํญ ๊น์ด ํ๊ธฐ</h3>
|
| 336 |
+
<p><a href="https://huggingface.co/models">huggingface.co/models</a> ์ ์ โ ํ๋ฉด ๊ตฌ์ฑ์ ํฌ๊ฒ <strong>์ข์ธก ์ฌ์ด๋๋ฐ(ํํฐ)</strong> + <strong>๋ณธ๋ฌธ(๋ชจ๋ธ ๋ฆฌ์คํธ)</strong>์ด๊ณ , ๋ณธ๋ฌธ ์ฐ์ธก ์๋จ์ <strong>๊ฒ์์ฐฝ๊ณผ ์ ๋ ฌ ์ต์
</strong>์ด ๋ถ์ด์๋ค:</p>
|
| 337 |
+
<img src="images/02_models.png" alt="HuggingFace Models ํญ โ ์ข์ธก ํํฐ ์ฌ์ด๋๋ฐ, ๋ณธ๋ฌธ ๋ชจ๋ธ ๋ฆฌ์คํธ, ์ฐ์ธก ์๋จ ๊ฒ์/์ ๋ ฌ" style="width:100%;max-width:900px;border:1px solid #e5e7eb;border-radius:8px;margin:0.6rem 0;">
|
| 338 |
+
|
| 339 |
+
<p style="color:#6b7280;font-size:0.9em;">์ ์ด๋ฏธ์ง์ โ (๋นจ๊ฐ) ์ฌ์ด๋๋ฐ, โก(ํ๋) ๋ชจ๋ธ ๋ฆฌ์คํธ, โข(์ด๋ก) ๊ฒ์ยท์ ๋ ฌ ์์ญ์ด ํ์๋์ด ์๋ค.</p>
|
| 340 |
+
|
| 341 |
+
<h4 style="margin:0.8rem 0 0.4rem; color:#047857;"><span style="display:inline-block;width:22px;height:22px;border-radius:50%;background:#ef4444;color:white;text-align:center;font-weight:bold;font-size:0.85em;">1</span> ์ข์ธก ์ฌ์ด๋๋ฐ: ํํฐ ํจ๋</h4>
|
| 342 |
+
<ul>
|
| 343 |
+
<li><strong>Tasks</strong> โ ๋ชจ๋ธ์ด ํ๋ ์ผ๋ก ๊ฑฐ๋ฅด๊ธฐ. ๊ฐ์ฅ ๋ง์ด ์ฐ๋ ์นดํ
๊ณ ๋ฆฌ:
|
| 344 |
+
<ul>
|
| 345 |
+
<li><em>Multimodal</em>: Image-Text-to-Text, Visual QA</li>
|
| 346 |
+
<li><em>Computer Vision</em>: Image Classification, Object Detection, Image Segmentation</li>
|
| 347 |
+
<li><em>Natural Language Processing</em>: Text Generation, Translation, Summarization, Sentiment</li>
|
| 348 |
+
<li><em>Audio</em>: Speech Recognition (ASR), Text-to-Speech (TTS)</li>
|
| 349 |
+
</ul>
|
| 350 |
+
</li>
|
| 351 |
+
<li><strong>Libraries</strong> โ Transformers / Diffusers / GGUF ๋ฑ โ ์ผ๋จ ๊ธฐ๋ณธ๊ฐ(Transformers)์ผ๋ก ๋๋ฉด ๋จ</li>
|
| 352 |
+
<li><strong>Languages</strong> โ "korean" ์ฒดํฌํ๋ฉด ํ๊ตญ์ด ์ง์ ๋ชจ๋ธ๋ง ํ์</li>
|
| 353 |
+
<li><strong>Licenses</strong> โ ์์
์ ์ด์ฉ ๊ฐ๋ฅ ์ฌ๋ถ. <em>apache-2.0</em>, <em>mit</em> = ์์ ๋กญ๊ฒ ์ฌ์ฉ OK / <em>cc-by-nc</em> = ๋น์์
์ฉ๋ง</li>
|
| 354 |
+
</ul>
|
| 355 |
+
|
| 356 |
+
<h4 style="margin:0.8rem 0 0.4rem; color:#047857;"><span style="display:inline-block;width:22px;height:22px;border-radius:50%;background:#0ea5e9;color:white;text-align:center;font-weight:bold;font-size:0.85em;">2</span> ๋ณธ๋ฌธ: ๋ชจ๋ธ ๋ฆฌ์คํธ</h4>
|
| 357 |
+
<p>๊ฐ ์นด๋์๋ ๋ค์ ์ ๋ณด๊ฐ ๋ณด์ธ๋ค:</p>
|
| 358 |
+
<ul>
|
| 359 |
+
<li><strong>๋ชจ๋ธ ์ด๋ฆ</strong> = <code>์ ์ ID/๋ชจ๋ธ๋ช
</code> ํ์ (์: <code>nateraw/food</code>)</li>
|
| 360 |
+
<li><strong>โฅ ์ข์์ ์</strong> โ ์ปค๋ฎค๋ํฐ ์ธ๊ธฐ๋</li>
|
| 361 |
+
<li><strong>โ ๋ค์ด๋ก๋ ์</strong> โ ์ง๋ ํ ๋ฌ ์ฌ์ฉ๋ (๊ฐ์ฅ ์ ๋ขฐํ ๋งํ ์งํ)</li>
|
| 362 |
+
<li><strong>๋ง์ง๋ง ์
๋ฐ์ดํธ ๋ ์ง</strong> โ 1๋
๋์ ๋ชจ๋ธ์ ๋ ์ข์ ํ์ ๋ชจ๋ธ์ด ์์ ๊ฐ๋ฅ์ฑ</li>
|
| 363 |
+
</ul>
|
| 364 |
+
<div class="why-box">
|
| 365 |
+
<div class="label">์ด๋ณด์์ฉ ๋ชจ๋ธ ๊ณ ๋ฅด๋ ๋ฒ (3์ด ๋ฃฐ)</div>
|
| 366 |
+
<p>โ ๋ค์ด๋ก๋ ์ 1๋ง+ โก ์ข์์ 100+ โข ๋ผ์ด์ ์ค apache/mit โฃ ์ต๊ทผ 6๊ฐ์ ๋ด ์
๋ฐ์ดํธ<br>
|
| 367 |
+
โ 4๊ฐ ๋ค ๋ง์กฑํ๋ฉด ์ผ๋จ ๋ฏฟ๊ณ ์จ๋ ๋๋ค.</p>
|
| 368 |
+
</div>
|
| 369 |
+
|
| 370 |
+
<h4 style="margin:0.8rem 0 0.4rem; color:#047857;"><span style="display:inline-block;width:22px;height:22px;border-radius:50%;background:#10b981;color:white;text-align:center;font-weight:bold;font-size:0.85em;">3</span> ๋ณธ๋ฌธ ์ฐ์ธก ์๋จ: ๊ฒ์์ฐฝ + ์ ๋ ฌ</h4>
|
| 371 |
+
<ul>
|
| 372 |
+
<li><strong>๊ฒ์์ฐฝ</strong>: ํค์๋ ๊ฒ์ (์: "korean sentiment", "food", "whisper")</li>
|
| 373 |
+
<li><strong>Sort by</strong>: <em>Trending</em>(์์ฆ ๋จ๋ ๊ฒ) / <em>Most likes</em> / <em>Most downloads</em> / <em>Recently updated</em></li>
|
| 374 |
+
</ul>
|
| 375 |
+
|
| 376 |
+
<h3>๐ 3. ๋ชจ๋ธ ์นด๋ ํ์ด์ง ํด๋ถ๋</h3>
|
| 377 |
+
<p>์์: <a href="https://huggingface.co/nateraw/food">huggingface.co/nateraw/food</a> ํด๋ฆญ ์ ๋ณด์ด๋ ํ๋ฉด.</p>
|
| 378 |
+
<img src="images/03_model_card.png" alt="nateraw/food ๋ชจ๋ธ ์นด๋ ํ์ด์ง" style="width:100%;max-width:900px;border:1px solid #e5e7eb;border-radius:8px;margin:0.6rem 0;">
|
| 379 |
+
|
| 380 |
+
<p style="color:#6b7280;font-size:0.9em;">์ ์ด๋ฏธ์ง์ ์๊น ๋ฐ์ค โ โกโข ๊ฐ ์๋ ํ ํญ๋ชฉ๊ณผ ๋งค์นญ๋๋ค.</p>
|
| 381 |
+
<table>
|
| 382 |
+
<tr><th>๋ฒํธ</th><th>์์ญ</th><th>๋ด์ฉ</th><th>ํ์์ด ๋ด์ผ ํ ๋ถ๋ถ</th></tr>
|
| 383 |
+
<tr>
|
| 384 |
+
<td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#ef4444;color:white;text-align:center;font-weight:bold;">1</span></td>
|
| 385 |
+
<td><strong>ํญ ๋ฐ</strong> โ Model card / Files and versions / Training metrics / Community</td>
|
| 386 |
+
<td><em>Model card</em>๋ README.md ๋ ๋๋ง, <em>Files and versions</em>๋ ์ค์ ํ์ผ, <em>Training metrics</em>๋ ํ์ต ๊ณก์ , <em>Community</em>๋ ์ด์ ๊ฒ์ํ</td>
|
| 387 |
+
<td>๋จผ์ <em>Model card</em> ๋งจ ์ ํ๋ ์ค๋ก "๋ญ ํ๋ ๋ชจ๋ธ"์ธ์ง ํ์
โ <em>Files</em>์์ <code>config.json</code>ยท<code>*.safetensors</code> ํ์ธ โ <em>Community</em>์์ ํจ์ ์ ๋ณด ๊ฒ์</td>
|
| 388 |
+
</tr>
|
| 389 |
+
<tr>
|
| 390 |
+
<td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#0ea5e9;color:white;text-align:center;font-weight:bold;">2</span></td>
|
| 391 |
+
<td><strong>Inference Providers ๋ฐ์ค</strong> (์ฐ์ธก)</td>
|
| 392 |
+
<td><code>HF Inference API</code> ์ ๊ณต์ + ์์
๋ช
(์: <em>Image Classification</em>) ํ์. ์ ์ ๋ฐ์ค์ "Drag image file here or click to browse from your device"</td>
|
| 393 |
+
<td>์ฌ์ง์ ๋๋๊ทธ/ํด๋ฆญ ์
๋ก๋ํ๋ฉด ๋ผ๋ฒจยท์ ์๊ฐ ์ฆ์ ํ์. ์๋ <em>View Code Snippets</em> / <em>Maximize</em> ๋ฒํผ์ผ๋ก ์ฝ๋ ๋ณด๊ธฐยทํ๋</td>
|
| 394 |
+
</tr>
|
| 395 |
+
<tr>
|
| 396 |
+
<td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#10b981;color:white;text-align:center;font-weight:bold;">3</span></td>
|
| 397 |
+
<td><strong>Deploy</strong> / <strong>Use this model</strong> ๋ฒํผ (์๋จ ์ฐ์ธก)</td>
|
| 398 |
+
<td>์ฝ๋ ์ค๋ํซ ๋ณต๋ถ์ฉ ๋๋กญ๋ค์ด</td>
|
| 399 |
+
<td>Transformers / Inference Providers / Endpoints ์ฝ๋ ์๋ ์์ฑ โ ์ฐ๋ฆฌ ์ค์ต์ <em>Inference Providers</em>(=HF Inference API) ์ฌ์ฉ</td>
|
| 400 |
+
</tr>
|
| 401 |
+
<tr>
|
| 402 |
+
<td>โ</td>
|
| 403 |
+
<td>๋ชจ๋ธ ์นด๋ ํ๋จ ๋ฉํ์ ๋ณด</td>
|
| 404 |
+
<td>license, base_model, datasets, metrics</td>
|
| 405 |
+
<td><strong>license</strong> โ ์์
์ ์ฌ์ฉ ๊ฐ๋ฅ ์ฌ๋ถ ํ์ธ / <strong>base_model</strong> โ ์ด๋ค ๋ชจ๋ธ์ fine-tune ํ๋์ง ์ถ์ </td>
|
| 406 |
+
</tr>
|
| 407 |
+
</table>
|
| 408 |
+
|
| 409 |
+
<h3>๐ฎ 4. ์์ ฏ ์ฌ์ฉ๋ฒ โ ์ฝ๋ ํ ์ค ์์ด ๋ชจ๋ธ ํ
์คํธ</h3>
|
| 410 |
+
<p>๋ชจ๋ธ ์นด๋ ์ฐ์ธก์ ๋ฐ์ค๊ฐ <strong>Inference API ์์ ฏ</strong>์ด๋ค. ๋ชจ๋ฌ๋ฆฌํฐ๋ณ๋ก ์
๋ ฅ ๋ฐฉ์์ด ๋ค๋ฅด๋ค:</p>
|
| 411 |
+
<ul>
|
| 412 |
+
<li><strong>Image Classification</strong>: ์ฌ์ง ๋๋๊ทธ โ "Compute" โ top-5 ๋ผ๋ฒจ๊ณผ ์ ์๊ฐ ๋ง๋๊ทธ๋ํ๋ก ํ์</li>
|
| 413 |
+
<li><strong>Text Generation</strong>: ํ
์คํธ ์
๋ ฅ โ ๋ชจ๋ธ์ด ์ด์ด์ ์์ฑ</li>
|
| 414 |
+
<li><strong>Translation</strong>: ์๋ฌธ ์
๋ ฅ โ ๋ฒ์ญ ๊ฒฐ๊ณผ</li>
|
| 415 |
+
<li><strong>ASR</strong>: ์ค๋์ค ํ์ผ ์
๋ก๋ ๋๋ ๋ง์ดํฌ ๋
น์ โ ํ
์คํธ</li>
|
| 416 |
+
<li><strong>Object Detection</strong>: ์ฌ์ง โ ๋ฐ์ค๊ฐ ๊ทธ๋ ค์ง ๊ฒฐ๊ณผ ์ด๋ฏธ์ง</li>
|
| 417 |
+
</ul>
|
| 418 |
+
<div class="why-box">
|
| 419 |
+
<div class="label">์์ ฏ์ด ์ ๋ณด์ด๊ฑฐ๋ ์๋ฌ๊ฐ ๋ ๋</div>
|
| 420 |
+
<p>โ "Inference API has been turned off" โ ๋ชจ๋ธ ์ ์์๊ฐ ๋นํ์ฑํํ ๊ฒฝ์ฐ. ๋ค๋ฅธ ๋ชจ๋ธ๋ก ๊ฐ์ํ๋ค.<br>
|
| 421 |
+
โก ์ฒซ ํธ์ถ์์ ~20์ด ๋ฉ์ถค โ <strong>cold start</strong>. ํ ๋ฒ ๋ ๋๋ฅด๋ฉด ๋น ๋ฅด๋ค.<br>
|
| 422 |
+
โข "Loading..." ๋ฌดํ ๋ฐ๋ณต โ ๋ชจ๋ธ์ด ๋๋ฌด ํผ. ๋ ์์ ๋๊ธ ๋ชจ๋ธ ๊ฒ์.</p>
|
| 423 |
+
</div>
|
| 424 |
+
|
| 425 |
+
<h3>๐ ๏ธ 5. "Use this model" ๋ฒํผ โ ์ฝ๋ ์๋ ์์ฑ</h3>
|
| 426 |
+
<p>๋ชจ๋ธ ํ์ด์ง ์ฐ์ธก ์๋จ์ <strong></> Use this model</strong> ๋ฒํผ์ ๋๋ฅด๋ฉด ๋๋กญ๋ค์ด์์ ์ฌ์ฉ ๋ฐฉ์์ ๊ณ ๋ฅผ ์ ์๋ค:</p>
|
| 427 |
+
<table>
|
| 428 |
+
<tr><th>์ต์
</th><th>์๋ฏธ</th><th>์ด๋ฒ ์ฃผ์ฐจ์์</th></tr>
|
| 429 |
+
<tr><td><strong>Transformers</strong></td><td>๋ก์ปฌ ๋ค์ด๋ก๋ ํ ์ง์ ์คํ</td><td>โ (GPU ํ์)</td></tr>
|
| 430 |
+
<tr><td><strong>Inference API (Serverless)</strong></td><td>HF ์๋ฒ์ HTTP ํธ์ถ โ ๋ฌด๋ฃ</td><td>โ
<strong>์ฐ๋ฆฌ๊ฐ ์ฐ๋ ๋ฐฉ์</strong></td></tr>
|
| 431 |
+
<tr><td><strong>Inference Endpoints</strong></td><td>์ ์ฉ ์ธ์คํด์ค โ ์ ๋ฃ, ํญ์ ์ผ์ง</td><td>โ (์ค์๋น์ค์ฉ)</td></tr>
|
| 432 |
+
</table>
|
| 433 |
+
<p>๋ฒํผ์ ๋๋ฅด๋ฉด <strong>๋ณต๋ถ ๊ฐ๋ฅํ Python ์ฝ๋</strong>๊ฐ ๋ฐ๋ก ๋์จ๋ค. ์ฐ๋ฆฌ๊ฐ ์ธ ํจํด์ ์ด๋ ๊ฒ ์๊ฒผ๋ค:</p>
|
| 434 |
+
<pre><span class="kw">from</span> huggingface_hub <span class="kw">import</span> InferenceClient
|
| 435 |
+
|
| 436 |
+
client = InferenceClient(token=<span class="str">"hf_..."</span>)
|
| 437 |
+
result = client.image_classification(
|
| 438 |
+
<span class="str">"food.jpg"</span>,
|
| 439 |
+
model=<span class="str">"nateraw/food"</span>,
|
| 440 |
+
)
|
| 441 |
+
<span class="kw">print</span>(result)
|
| 442 |
+
<span class="comment"># [{'label': 'pizza', 'score': 0.92}, ...]</span></pre>
|
| 443 |
+
|
| 444 |
+
<h3>๐ 6. Spaces ํญ ํ์ฉ๋ฒ</h3>
|
| 445 |
+
<p><a href="https://huggingface.co/spaces">huggingface.co/spaces</a> โ ๋ค๋ฅธ ์ฌ๋๋ค์ด ๋ง๋ AI ๋ฐ๋ชจ ๋ชจ์.</p>
|
| 446 |
+
<img src="images/04_spaces.png" alt="HuggingFace Spaces โ Spaces of the week" style="width:100%;max-width:900px;border:1px solid #e5e7eb;border-radius:8px;margin:0.6rem 0;">
|
| 447 |
+
<p style="color:#6b7280;font-size:0.9em;">์ ์ด๋ฏธ์ง์ โ (๋นจ๊ฐ) ์นดํ
๊ณ ๋ฆฌ ํญ, โก(ํ๋) Spaces of the week ์นด๋ ๊ทธ๋ฆฌ๋, โข(์ด๋ก) ๊ฒ์ยทํํฐยท์ ๋ ฌ ์์ญ.</p>
|
| 448 |
+
<ul>
|
| 449 |
+
<li><span style="display:inline-block;width:22px;height:22px;border-radius:50%;background:#ef4444;color:white;text-align:center;font-weight:bold;font-size:0.85em;">1</span> <strong>์นดํ
๊ณ ๋ฆฌ ํญ</strong> โ Image Generation, Video Generation, Speech Synthesis ๋ฑ ์์
๋ณ๋ก ๋น ๋ฅด๊ฒ ๋๋ฌ๋ณด๊ธฐ</li>
|
| 450 |
+
<li><span style="display:inline-block;width:22px;height:22px;border-radius:50%;background:#0ea5e9;color:white;text-align:center;font-weight:bold;font-size:0.85em;">2</span> <strong>Spaces of the week (์นด๋ ๊ทธ๋ฆฌ๋)</strong> โ ๋งค์ฃผ ํ๋ ์ด์
. ์นด๋ ํด๋ฆญ โ ๋ฐ๋ชจ ์คํ. ์ฐ์ธก <strong>โฎ โ Duplicate this Space</strong>๋ก ๋ด ๊ณ์ ์ ๋ณต์ฌ โ ์ฝ๋ ์์ ๊ฐ๋ฅ</li>
|
| 451 |
+
<li><span style="display:inline-block;width:22px;height:22px;border-radius:50%;background:#10b981;color:white;text-align:center;font-weight:bold;font-size:0.85em;">3</span> <strong>Filter / Sort</strong> โ ์ด๋ฆ ๊ฒ์, Filters, Sort(Relevance / Trending / Most likes ๋ฑ)</li>
|
| 452 |
+
<li><strong>์นด๋ ํด๋ฆญ ์ Space ์์ธ ํ์ด์ง</strong>๋ก ์ด๋ โ ํ์ด์ง ์๋จ์ 4๊ฐ ํญ์ด ์๋ค:
|
| 453 |
+
<ul>
|
| 454 |
+
<li><strong>App</strong>: ์ค์ ๋ก ๋์๊ฐ๋ ๋ฐ๋ชจ ํ๋ฉด (Gradio/Streamlit UI)</li>
|
| 455 |
+
<li><strong>Files</strong>: ์์ค ์ฝ๋ (<code>app.py</code>, <code>requirements.txt</code> ๋ฑ). ์คํ์์ค๋ผ ๊ทธ๋๋ก ์ด๋ยท๋ณต์ฌ ๊ฐ๋ฅ</li>
|
| 456 |
+
<li><strong>Community</strong>: ์ง๋ฌธยท์ด์ ๊ฒ์ํ</li>
|
| 457 |
+
<li><strong>Settings</strong>: ์์ฑ์๋ง ๋ณด๋ ์ค์ (Secrets, ํ๋์จ์ด ์ ํ ๋ฑ)</li>
|
| 458 |
+
</ul>
|
| 459 |
+
๐ ์ด๋ฒ ์ฃผ์ฐจ์ ์ฐ๋ฆฌ๊ฐ ์ง์ ๋ฐฐํฌํ Space๋ <strong>๋๊ฐ์ 4๊ฐ ํญ ๊ตฌ์กฐ</strong>๋ฅผ ๊ฐ๊ฒ ๋๋ค. ์ฆ ์ง๊ธ ๋ณด๋ ๋จ์ Space๊ฐ ๊ณง ๋ด Space์ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค.</li>
|
| 460 |
+
</ul>
|
| 461 |
+
|
| 462 |
+
<h3>๐ 7. ํ ํฐ ๋ฐ๊ธ โ ํ ๋ฒ๋ง ํ๋ฉด ํ์ ์ฌ์ฉ</h3>
|
| 463 |
+
<img src="images/05_tokens.png" alt="Settings โ Access Tokens ํ์ด์ง" style="width:100%;max-width:900px;border:1px solid #e5e7eb;border-radius:8px;margin:0.6rem 0;">
|
| 464 |
+
<ol class="step-list">
|
| 465 |
+
<li>์ฐ์ธก ์๋จ ํ๋กํ ์ฌ์ง โ <strong>Settings</strong></li>
|
| 466 |
+
<li>์ข์ธก ๋ฉ๋ด์์ <strong>Access Tokens</strong></li>
|
| 467 |
+
<li><strong>+ Create new token</strong> ๋ฒํผ</li>
|
| 468 |
+
<li>Token type: <strong>Read</strong> (๊ฐ์ฅ ์์ , Inference API ํธ์ถ์ ์ถฉ๋ถ)</li>
|
| 469 |
+
<li>์ด๋ฆ์ ์์ ๋กญ๊ฒ (์: <code>week06-class</code>)</li>
|
| 470 |
+
<li>์์ฑ๋ ํ ํฐ <code>hf_xxxxxxxxxx...</code>๋ฅผ ์ฆ์ ๋ณต์ฌ โ <strong>๋ค์๋ ๋ชป ๋ณธ๋ค</strong></li>
|
| 471 |
+
</ol>
|
| 472 |
+
<div class="why-box">
|
| 473 |
+
<div class="label">โ ๏ธ ํ ํฐ ๋ณด์ 3์์น</div>
|
| 474 |
+
<p>โ <strong>์ฝ๋์ ์ ๋ ์ง์ ์ ์ง ์๋๋ค</strong> โ <code>.env</code> ํ์ผ ๋๋ Space Secrets ์ฌ์ฉ<br>
|
| 475 |
+
โก <strong>git์ ์ปค๋ฐํ์ง ์๋๋ค</strong> โ <code>.gitignore</code>์ <code>.env</code> ์ถ๊ฐ ํ์<br>
|
| 476 |
+
โข <strong>์ค์๋ก ๋
ธ์ถ๋๋ฉด ์ฆ์ Revoke</strong> โ ํ ํฐ ํ์ด์ง์์ ํด์งํต ์์ด์ฝ ํด๋ฆญ</p>
|
| 477 |
+
</div>
|
| 478 |
+
|
| 479 |
+
<h3>๐ 8. ๊ฒ์ ๊ฟํ (์ค์ )</h3>
|
| 480 |
+
<ul>
|
| 481 |
+
<li><strong>ํ๊ตญ์ด ๋ชจ๋ธ ์ฐพ๊ธฐ</strong>: ๊ฒ์์ฐฝ์ <code>korean</code> + Languages ํํฐ์์ <code>ko</code> ์ฒดํฌ</li>
|
| 482 |
+
<li><strong>๊ฐ๋ฒผ์ด ๋ชจ๋ธ ์ฐ์ </strong>: ๋ชจ๋ธ ์ด๋ฆ์ <code>tiny</code>, <code>small</code>, <code>base</code>, <code>distil</code>์ด ๋ค์ด๊ฐ ๊ฒ์ ๊ฒฝ๋ ๋ฒ์ </li>
|
| 483 |
+
<li><strong>์ต์ ๋ชจ๋ธ๋ง</strong>: Sort = "Recently updated" + 1์ฃผ์ผ ์ด๋ด</li>
|
| 484 |
+
<li><strong>ํน์ ํ์ฌ/์ฐ๊ตฌ์ ๋ชจ๋ธ</strong>: <code>google/</code>, <code>microsoft/</code>, <code>meta-llama/</code>, <code>openai/</code> ๊ฒ์</li>
|
| 485 |
+
<li><strong>Trending</strong> ํญ๋ง ๋ด๋ ์ผ์ฃผ์ผ์ 5๋ถ์ด๋ฉด AI ์
๊ณ ๋ํฅ์ด ์กํ๋ค</li>
|
| 486 |
+
</ul>
|
| 487 |
+
|
| 488 |
+
<h3>๐บ๏ธ 9. ์ค์ต ์ ์ฒดํฌ๋ฆฌ์คํธ (์์
์ค ํจ๊ป ์งํ)</h3>
|
| 489 |
+
<div class="todo-box">
|
| 490 |
+
<div><span class="num">โ</span>HF ๊ฐ์
์๋ฃ</div>
|
| 491 |
+
<div><span class="num">โ</span>ํ๋กํ ์ฌ์ง ๋ฑ๋ก (์ ํ, ๋ถ์๊ธฐ UP)</div>
|
| 492 |
+
<div><span class="num">โ</span>Read ํ ํฐ 1๊ฐ ๋ฐ๊ธ โ ์์ ํ ๊ณณ์ ์ ์ฅ</div>
|
| 493 |
+
<div><span class="num">โ</span><code>nateraw/food</code> ๋ชจ๋ธ ํ์ด์ง ์ด์ด๋ณด๊ณ ์์ ฏ์ ์ฌ์ง 1์ฅ ๋ฃ์ด๋ณด๊ธฐ</div>
|
| 494 |
+
<div><span class="num">โ</span>Trending Spaces์์ ๋ง์์ ๋๋ ๊ฑฐ 1๊ฐ ์ฐพ์๋ณด๊ธฐ</div>
|
| 495 |
+
</div>
|
| 496 |
+
</section>
|
| 497 |
+
|
| 498 |
+
<!-- SECTION 3 -->
|
| 499 |
+
<section class="class-section s3">
|
| 500 |
+
<div class="section-label">SECTION 3 ยท APP DESIGN</div>
|
| 501 |
+
<h2 class="section-title">์ฐ๋ฆฌ๊ฐ ๋ง๋ค ์ฑ: ์นผ๋ก๋ฆฌ ์นด์ดํฐ</h2>
|
| 502 |
+
|
| 503 |
+
<p>์์ ์ฌ์ง 1์ฅ โ ์์ ์ด๋ฆ + 1์ธ๋ถ ๊ธฐ์ค ์นผ๋ก๋ฆฌยทํ๋จ์ง ์ถ์ ๊ฐ์ ๋๋ ค์ฃผ๋ ์์ AI ์ฑ์ด๋ค.</p>
|
| 504 |
+
|
| 505 |
+
<h3>๐ ๋ฐ์ดํฐ ํ๋ฆ (Pipeline)</h3>
|
| 506 |
+
<pre><span class="comment"># [1] ์ฌ์ฉ์๊ฐ ์์ ์ฌ์ง ์
๋ก๋ (Gradio UI)
|
| 507 |
+
โ
|
| 508 |
+
# [2] HF Vision ๋ชจ๋ธ (nateraw/food) ์ด top-3 ์์ ํ๋ณด ๋ฐํ
|
| 509 |
+
โ e.g. [{label:"pizza", score:0.92}, ...]
|
| 510 |
+
# [3] LLM (Llama-3-8B-Instruct) ์๊ฒ
|
| 511 |
+
"์ด ์์์ 1์ธ๋ถ ์นผ๋ก๋ฆฌ/ํ๋จ์ง๋ฅผ JSON์ผ๋ก ์๋ ค์ค" ์์ฒญ
|
| 512 |
+
โ
|
| 513 |
+
# [4] JSON ํ์ฑ โ Gradio๊ฐ ๊ฒฐ๊ณผ ์นด๋๋ก ํ์</span></pre>
|
| 514 |
+
|
| 515 |
+
<h3>๐งฉ ๋ ๋ชจ๋ธ์ ์กฐํฉํ๋ ์ด์ </h3>
|
| 516 |
+
<div class="why-box">
|
| 517 |
+
<div class="label">์ค๊ณ ํฌ์ธํธ</div>
|
| 518 |
+
<p>์ด๋ฏธ์ง ๋ถ๋ฅ ๋ชจ๋ธ์ "์ด๊ฒ ํผ์๋ค"๋ ์์ง๋ง ์นผ๋ก๋ฆฌ๋ ๋ชจ๋ฅธ๋ค.<br>
|
| 519 |
+
๋ฐ๋๋ก LLM์ "ํผ์ 1์ธ๋ถ โ 285kcal"๋ ์์ง๋ง ์ฌ์ง์ ๋ชป ๋ณธ๋ค.<br>
|
| 520 |
+
<strong>๋ ๋ชจ๋ธ์ ํ์ดํ๋ผ์ธ์ผ๋ก ์ฐ๊ฒฐ</strong>ํ๋ ๊ฒ์ด ์ด๋ฒ ์ค์ต์ ํต์ฌ ์์ด๋์ด๋ค.
|
| 521 |
+
์ด๋ฐ ์์ผ๋ก ์์ ๋ชจ๋ธ ์ฌ๋ฌ ๊ฐ๋ฅผ ์ฎ๋ ํจํด์
|
| 522 |
+
<em>compound AI system</em>์ด๋ผ ๋ถ๋ฅธ๋ค.</p>
|
| 523 |
+
</div>
|
| 524 |
+
|
| 525 |
+
<h3>๐ ํ์ผ ๊ตฌ์กฐ</h3>
|
| 526 |
+
<pre>week06/
|
| 527 |
+
โโโ app.py <span class="comment"># Gradio ์ฑ ๋ณธ์ฒด (TODO 4๊ณณ์ ์ฑ์ ์์ฑ)</span>
|
| 528 |
+
โโโ model_config.py <span class="comment"># HF ๋ชจ๋ธ ์ด๋ฆ + InferenceClient ํฉํ ๋ฆฌ</span>
|
| 529 |
+
โโโ requirements.txt <span class="comment"># Space๊ฐ ์ค์นํ ์์กด์ฑ</span>
|
| 530 |
+
โโโ .env.example <span class="comment"># HF_TOKEN ํ
ํ๋ฆฟ</span>
|
| 531 |
+
โโโ README.md <span class="comment"># ์๋ถ๋ถ YAML์ด Space ์ค์ </span></pre>
|
| 532 |
+
</section>
|
| 533 |
+
|
| 534 |
+
<!-- SECTION 4 -->
|
| 535 |
+
<section class="class-section s4">
|
| 536 |
+
<div class="section-label">SECTION 4 ยท HANDS-ON</div>
|
| 537 |
+
<h2 class="section-title">์ค์ต: ์ฝ๋ ์ฑ์ฐ๊ธฐ โ ๋ก์ปฌ ์คํ โ ๋ฐฐํฌ</h2>
|
| 538 |
+
|
| 539 |
+
<h3>โ ์ฌ์ ์ค๋น</h3>
|
| 540 |
+
<ol class="step-list">
|
| 541 |
+
<li>HF ๊ฐ์
: <a href="https://huggingface.co/join">huggingface.co/join</a></li>
|
| 542 |
+
<li>ํ ํฐ ๋ฐ๊ธ: <a href="https://huggingface.co/settings/tokens">Settings โ Access Tokens โ New token</a> (Read ๊ถํ)</li>
|
| 543 |
+
<li><code>cp .env.example .env</code> ํ <code>HF_TOKEN=hf_...</code> ์
๋ ฅ</li>
|
| 544 |
+
<li><code>uv pip install -r requirements.txt</code></li>
|
| 545 |
+
</ol>
|
| 546 |
+
|
| 547 |
+
<h3>โก ์ฑ์์ผ ํ TODO 4๊ณณ (app.py) โ LangChain LCEL ๋ฒ์ </h3>
|
| 548 |
+
|
| 549 |
+
<div class="why-box">
|
| 550 |
+
<div class="label">์ LangChain?</div>
|
| 551 |
+
<p>5์ฃผ์ฐจ์์ LangGraph๋ฅผ ๋ฐฐ์ ๋ค. 6์ฃผ์ฐจ๋ ๊ฐ์ ์ํ๊ณ(LangChain)๋ก ์ด์ด๊ฐ๋ค.
|
| 552 |
+
LangChain์ <strong>LCEL(LangChain Expression Language)</strong>์ ํ์ด์ฌ์ <code>|</code> ์ฐ์ฐ์๋ก
|
| 553 |
+
<em>prompt โ llm โ parser</em>๋ฅผ ํ ์ค๋ก ์ฎ๋ ํํ์์ด๋ค.
|
| 554 |
+
์นผ๋ก๋ฆฌ ์นด์ดํฐ์ LLM ํํธ๊ฐ ๊ทธ๋๋ก <strong>์ฒด์ธ ๊ฐ์ฒด</strong>๊ฐ ๋๋ค.</p>
|
| 555 |
+
</div>
|
| 556 |
+
|
| 557 |
+
<div class="todo-box">
|
| 558 |
+
<div><span class="num">1</span><strong>SYSTEM_PROMPT</strong> โ ์์์ฌ ์ญํ + JSON ์คํค๋ง ๊ฐ์
|
| 559 |
+
<br><em>(ChatPromptTemplate์ ๋ค์ด๊ฐ๋ฏ๋ก JSON ์ค๊ดํธ๋ <code>{{ }}</code>๋ก ์ด์ค์ผ์ดํ)</em></div>
|
| 560 |
+
<pre><span class="kw">SYSTEM_PROMPT</span> = <span class="str">"""๋๋ ํ๊ตญ ์์์ฌ AI๋ค.
|
| 561 |
+
์ฌ์ฉ์๊ฐ ์์ ๋ถ๋ฅ ๊ฒฐ๊ณผ(top-k labels)๋ฅผ ์ฃผ๋ฉด,
|
| 562 |
+
๊ฐ์ฅ ๊ฐ๋ฅ์ฑ ๋์ ์์ 1๊ฐ์ 1์ธ๋ถ ๊ธฐ์ค ์์์ ๋ณด๋ฅผ ์ถ์ ํด
|
| 563 |
+
๋ฐ๋์ ๋ค์ JSON ์คํค๋ง๋ง ์ถ๋ ฅํ๋ผ. ๋ค๋ฅธ ํ
์คํธ/๋งํฌ๋ค์ด ๊ธ์ง.
|
| 564 |
+
|
| 565 |
+
{{"food": "์์๋ช
", "confidence": 0.0~1.0,
|
| 566 |
+
"calories_kcal": ์ ์, "carbs_g": ์ ์,
|
| 567 |
+
"protein_g": ์ ์, "fat_g": ์ ์,
|
| 568 |
+
"note": "์ถ์ ๊ทผ๊ฑฐ ํ ์ค"}}"""</span></pre>
|
| 569 |
+
</div>
|
| 570 |
+
|
| 571 |
+
<div class="todo-box">
|
| 572 |
+
<div><span class="num">2</span><strong>classify_food()</strong> โ HF ์ด๋ฏธ์ง ๋ถ๋ฅ ํธ์ถ
|
| 573 |
+
<br><em>(์ด๋ฏธ์ง ๋ถ๋ฅ๋ LangChain์ ๋ํผ๊ฐ ์์ด์ InferenceClient ์ง์ ์ฌ์ฉ)</em></div>
|
| 574 |
+
<pre>raw = client.<span class="kw">image_classification</span>(image, model=VISION_MODEL)</pre>
|
| 575 |
+
</div>
|
| 576 |
+
|
| 577 |
+
<div class="todo-box">
|
| 578 |
+
<div><span class="num">3</span><strong>_chain_lazy()</strong> โ LCEL ์ฒด์ธ ๋ง๋ค๊ธฐ (4๋จ๊ณ)</div>
|
| 579 |
+
<pre><span class="comment"># 3-1. HF Inference Endpoint ์์ฑ</span>
|
| 580 |
+
endpoint = <span class="kw">HuggingFaceEndpoint</span>(
|
| 581 |
+
repo_id=LLM_MODEL,
|
| 582 |
+
task=<span class="str">"text-generation"</span>,
|
| 583 |
+
max_new_tokens=300,
|
| 584 |
+
temperature=0.2,
|
| 585 |
+
huggingfacehub_api_token=get_token(),
|
| 586 |
+
)
|
| 587 |
+
|
| 588 |
+
<span class="comment"># 3-2. ์ฑํ
์ธํฐํ์ด์ค๋ก ๊ฐ์ธ๊ธฐ</span>
|
| 589 |
+
llm = <span class="kw">ChatHuggingFace</span>(llm=endpoint)
|
| 590 |
+
|
| 591 |
+
<span class="comment"># 3-3. ํ๋กฌํํธ ํ
ํ๋ฆฟ</span>
|
| 592 |
+
prompt = <span class="kw">ChatPromptTemplate</span>.from_messages([
|
| 593 |
+
(<span class="str">"system"</span>, SYSTEM_PROMPT),
|
| 594 |
+
(<span class="str">"human"</span>, <span class="str">"๋ค์์ ์ด๋ฏธ์ง ๋ถ๋ฅ๊ธฐ์ top-k ๊ฒฐ๊ณผ๋ค:\n{labels_json}"</span>),
|
| 595 |
+
])
|
| 596 |
+
|
| 597 |
+
<span class="comment"># 3-4. LCEL ํ์ดํ๋ผ์ธ โ ์ด ํ ์ค์ด ํต์ฌ!</span>
|
| 598 |
+
_chain = prompt | llm | <span class="kw">JsonOutputParser</span>()</pre>
|
| 599 |
+
</div>
|
| 600 |
+
|
| 601 |
+
<div class="todo-box">
|
| 602 |
+
<div><span class="num">4</span><strong>estimate_calories()</strong> โ ์ฒด์ธ ์คํ</div>
|
| 603 |
+
<pre>chain = _chain_lazy()
|
| 604 |
+
labels_json = json.dumps(labels, ensure_ascii=<span class="kw">False</span>)
|
| 605 |
+
<span class="kw">return</span> chain.<span class="kw">invoke</span>({<span class="str">"labels_json"</span>: labels_json})</pre>
|
| 606 |
+
</div>
|
| 607 |
+
|
| 608 |
+
<div class="why-box">
|
| 609 |
+
<div class="label">LCEL์ ์๋ฆ๋ค์</div>
|
| 610 |
+
<p><code>prompt | llm | JsonOutputParser()</code> โ ์ด ํ ์ค์ ๊ธฐ์ตํ์.<br>
|
| 611 |
+
โ prompt๊ฐ ์
๋ ฅ dict๋ฅผ ๋ฐ์ ๋ฉ์์ง ๋ฆฌ์คํธ๋ก ๋ณํ<br>
|
| 612 |
+
โก llm์ด ๋ฉ์์ง๋ฅผ ๋ฐ์ ์๋ต ์์ฑ<br>
|
| 613 |
+
โข JsonOutputParser๊ฐ ์๋ต์์ JSON๋ง ๋ฝ์ dict๋ก ๋๋ ค์ค<br>
|
| 614 |
+
์ด ์ธ ๋จ๊ณ๊ฐ ํ์ด์ฌ์ <code>|</code> ์ฐ์ฐ์ ํ๋๋ก ์กฐ๋ฆฝ๋๋ค.
|
| 615 |
+
๋์ค์ <em>retriever</em>, <em>tool</em>, <em>agent</em>๋ฅผ ์ถ๊ฐํด๋ ๊ฐ์ ๋ฐฉ์์ผ๋ก ๋์ด๋๋ค.</p>
|
| 616 |
+
</div>
|
| 617 |
+
|
| 618 |
+
<h3>โข ๋ก์ปฌ ์คํ</h3>
|
| 619 |
+
<pre>uv run python app.py
|
| 620 |
+
<span class="comment"># โ http://127.0.0.1:7860 ์ ์</span></pre>
|
| 621 |
+
|
| 622 |
+
<h3>โฃ Space ๋ฐฐํฌ</h3>
|
| 623 |
+
<p>์์ฑํ ์ฑ์ HuggingFace Space์ ์ฌ๋ ค ๊ณต๊ฐ URL๋ก ๋ง๋ ๋ค. ๋จ๊ณ๋ณ ์์ธ ๊ฐ์ด๋(Space ์์ฑ โ Secret ๋ฑ๋ก โ ํ์ผ ์
๋ก๋ โ ๋น๋ ๋ก๊ทธ โ ํธ๋ฌ๋ธ์ํ
โ ์ฌ๋ฐฐํฌ)๋ ์๋ ์ ์ฉ ์น์
์ผ๋ก ์ ๋ฆฌํด๋์๋ค.</p>
|
| 624 |
+
<p>๐ <a href="#section-deploy"><strong>SECTION 9 ยท DEPLOY โ HuggingFace Space ๋ฐฐํฌ A to Z</strong></a> ๋ก ์ด๋</p>
|
| 625 |
+
</section>
|
| 626 |
+
|
| 627 |
+
|
| 628 |
+
<!-- SECTION 5 -->
|
| 629 |
+
<section class="class-section s5">
|
| 630 |
+
<div class="section-label">SECTION 5 ยท DEEP DIVE</div>
|
| 631 |
+
<h2 class="section-title">์์ฃผ ๋์ค๋ ์ง๋ฌธ & ์ฉ์ด ์ ๋ฆฌ</h2>
|
| 632 |
+
|
| 633 |
+
<div class="qa">
|
| 634 |
+
<div class="q">Q. ์ LLM์๊ฒ "JSON๋ง ์ถ๋ ฅํ๋ผ"๊ณ ๊ฐ์ ํ๋์?</div>
|
| 635 |
+
<div class="a">LLM์ ์์ฐ์ด๋ฅผ ์ ๋ง๋ค์ง๋ง ์์ ๋กญ๊ฒ ๋๋ฉด ๋งค๋ฒ ํ์์ด ๋ฌ๋ผ์ง๋ค.
|
| 636 |
+
์ฑ์์๋ ํญ์ ๊ฐ์ ํค(<code>calories_kcal</code> ๋ฑ)๋ก ๊ฐ์ ๊บผ๋ด์ผ ํ๋ฏ๋ก
|
| 637 |
+
<strong>๊ตฌ์กฐํ๋ ์ถ๋ ฅ(structured output)</strong>์ด ํ์๋ค. ์์คํ
ํ๋กฌํํธ๋ก ์คํค๋ง๋ฅผ ๊ฐ์ ํ๋ ๊ฒ์ด ๊ฐ์ฅ ๋จ์ํ ๋ฐฉ๋ฒ.</div>
|
| 638 |
+
</div>
|
| 639 |
+
|
| 640 |
+
<div class="qa">
|
| 641 |
+
<div class="q">Q. ์นผ๋ก๋ฆฌ๊ฐ ์ ํํ๊ฐ์?</div>
|
| 642 |
+
<div class="a">์๋๋ค. LLM์ด ์ถ์ ํ "์ฐธ๊ณ ์ฉ ์์น"๋ค.
|
| 643 |
+
์ค์ ๋ค์ด์ดํธ ์ฑ์ด๋ผ๋ฉด USDA FoodData Central ๊ฐ์ <em>์ค์ ์์ DB</em>๋ฅผ ๋ถ์ฌ์ผ ํ๋ค.
|
| 644 |
+
์ด๋ฒ ์ฃผ์ฐจ๋ "AI ๋ชจ๋ธ ๋ ๊ฐ๋ฅผ ์ฎ๋ ํจํด"์ ์ตํ๋ ๊ฒ์ด ๋ชฉํ.</div>
|
| 645 |
+
</div>
|
| 646 |
+
|
| 647 |
+
<div class="qa">
|
| 648 |
+
<div class="q">Q. Inference API๊ฐ ๊ฐ์๊ธฐ 503 ์๋ฌ๋ฅผ ๋ฑ์ด์.</div>
|
| 649 |
+
<div class="a">๋ฌด๋ฃ ํฐ์ด ๋ชจ๋ธ์ ์ฌ์ฉ๋์ด ์์ ๋ ์ ๋ค์ด ์๋ค๊ฐ(<em>cold start</em>)
|
| 650 |
+
์ฒซ ํธ์ถ ์ ~20์ด ๋์ ๋ก๋ฉํ๋ค. ์ ์ ๊ธฐ๋ค๋ ธ๋ค๊ฐ ์ฌ์๋ํ๋ฉด ๋๋ค.
|
| 651 |
+
์ค์๋น์ค๋ผ๋ฉด <em>Inference Endpoints</em>(์ ๋ฃ, ํญ์ ์ผ์ง)๋ก ์ด์ ํด์ผ ํ๋ค.</div>
|
| 652 |
+
</div>
|
| 653 |
+
|
| 654 |
+
<div class="qa">
|
| 655 |
+
<div class="q">Q. Gradio ๋์ Streamlit์ ์จ๋ ๋๋์?</div>
|
| 656 |
+
<div class="a">๋ฌผ๋ก . Space ์์ฑ ์ SDK๋ง ๋ฐ๊ฟ์ฃผ๋ฉด ๋๋ค.
|
| 657 |
+
Gradio๋ "AI ๋ฐ๋ชจ"์, Streamlit์ "๋ฐ์ดํฐ ๋์๋ณด๋"์ ๋ ๊ฐํ๋ค.
|
| 658 |
+
์ด๋ฒ ์ฃผ์ฐจ๋ ์
์ถ๋ ฅ์ด ๋จ์ํด์ Gradio๊ฐ ๋ ๊ฐ๊ฒฐํ๋ค.</div>
|
| 659 |
+
</div>
|
| 660 |
+
|
| 661 |
+
<div class="qa">
|
| 662 |
+
<div class="q">Q. HF_TOKEN์ ๊น๋นกํ๊ณ git์ ํธ์ํ์ด์.</div>
|
| 663 |
+
<div class="a">์ฆ์ <a href="https://huggingface.co/settings/tokens">ํ ํฐ ํ์ด์ง</a>์์
|
| 664 |
+
<strong>ํด๋น ํ ํฐ์ Revoke</strong>ํ๊ณ ์๋ก ๋ฐ๊ธํ ๊ฒ. git history์ ๋จ์ ์์ด๋ ๋ฌดํจํ๋๋ฉด ์์ ํ๋ค.</div>
|
| 665 |
+
</div>
|
| 666 |
+
|
| 667 |
+
<h3>๐ ํต์ฌ ์ฉ์ด</h3>
|
| 668 |
+
<dl class="glossary">
|
| 669 |
+
<dt>Pre-trained model</dt>
|
| 670 |
+
<dd>๋๋์ ๋ฐ์ดํฐ๋ก ๋ฏธ๋ฆฌ ํ์ต๋ ๋ชจ๋ธ. ์ฐ๋ฆฌ๋ ์ฒ์๋ถํฐ ํ์ตํ์ง ์๊ณ ๊ทธ๋๋ก ๊ฐ์ ธ๋ค ์ด๋ค.</dd>
|
| 671 |
+
<dt>Fine-tuning</dt>
|
| 672 |
+
<dd>์ฌ์ ํ์ต ๋ชจ๋ธ ์์ ํน์ ๋๋ฉ์ธ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐ ๏ฟฝ๏ฟฝ๏ฟฝ์ต์ํค๋ ๊ฒ. <code>nateraw/food</code>๋ ViT๋ฅผ ์์ ์ฌ์ง์ผ๋ก ํ์ธํ๋ํ ๊ฒฐ๊ณผ.</dd>
|
| 673 |
+
<dt>Inference</dt>
|
| 674 |
+
<dd>ํ์ต๋ ๋ชจ๋ธ์ ์
๋ ฅ์ ๋ฃ์ด ์์ธก์ ์ป๋ ๋จ๊ณ. โ Training</dd>
|
| 675 |
+
<dt>Top-k</dt>
|
| 676 |
+
<dd>๋ถ๋ฅ ๋ชจ๋ธ์ด ๊ฐ์ฅ ๊ฐ๋ฅ์ฑ ๋๋ค๊ณ ํ๋จํ ์์ k๊ฐ ํ๋ณด. ๋จ์ผ ์ ๋ต๋ณด๋ค ํ๋ณด ์ฌ๋ฌ ๊ฐ๋ฅผ LLM์ ๋๊ธฐ๋ฉด ๋ ์์ ์ ์ด๋ค.</dd>
|
| 677 |
+
<dt>System prompt</dt>
|
| 678 |
+
<dd>LLM์๊ฒ "๋๋ ๋๊ตฌ์ด๋ฉฐ ์ด๋ป๊ฒ ํ๋ํด์ผ ํ๋๊ฐ"๋ฅผ ์ง์ํ๋ ์ฒซ ๋ฉ์์ง. ์ถ๋ ฅ ํ์ ๊ฐ์ ์ ์์ฃผ ์ฐ์ธ๋ค.</dd>
|
| 679 |
+
<dt>Cold start</dt>
|
| 680 |
+
<dd>์ ๋ค์ด ์๋ ๋ฌด๋ฃ ๋ชจ๋ธ์ด ์ฒ์ ๊นจ์ด๋๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ์ง์ฐ ์๊ฐ.</dd>
|
| 681 |
+
<dt>Compound AI system</dt>
|
| 682 |
+
<dd>์ฌ๋ฌ ๋ชจ๋ธ/๋๊ตฌ๋ฅผ ํ์ดํ๋ผ์ธ์ผ๋ก ์ฎ์ด ํ๋์ ์์
์ ์ํํ๋ ์์คํ
. ์ฐ๋ฆฌ ์นผ๋ก๋ฆฌ ์นด์ดํฐ(๋ถ๋ฅ๊ธฐ + LLM)๊ฐ ๊ฐ์ฅ ์์ ์์.</dd>
|
| 683 |
+
</dl>
|
| 684 |
+
</section>
|
| 685 |
+
|
| 686 |
+
<!-- SECTION 6 -->
|
| 687 |
+
<section class="class-section s1">
|
| 688 |
+
<div class="section-label">SECTION 6 ยท LAB A (20๋ถ)</div>
|
| 689 |
+
<h2 class="section-title">Lab A. HF Hub ํํ & ๋ชจ๋ธ ๋ฐํ</h2>
|
| 690 |
+
|
| 691 |
+
<p>HuggingFace๋ฅผ "์ฝ๋๋ก๋ง" ๋ง๋๋ฉด ์ ๋ ์ต์ํด์ง์ง ์๋๋ค.
|
| 692 |
+
๋จผ์ <strong>์น์ฌ์ดํธ๋ฅผ ์ง์ ์ผํ๋ชฐ์ฒ๋ผ ๋๋ฌ๋ณด๋ ๊ฒฝํ</strong>์ด ํ์ํ๋ค.</p>
|
| 693 |
+
|
| 694 |
+
<h3>๐บ๏ธ ์งํ ๋ฐฉ๋ฒ</h3>
|
| 695 |
+
<ol class="step-list">
|
| 696 |
+
<li><a href="https://huggingface.co/models">huggingface.co/models</a> ์ ์ โ ์ข์ธก ํํฐ์์ <strong>Tasks</strong> ํจ๋ ์ด๊ธฐ</li>
|
| 697 |
+
<li>์๋ 5๊ฐ ์นดํ
๊ณ ๋ฆฌ ์ค <strong>๋ณธ์ธ์ด ๋๋ฆฌ๋ 1๊ฐ</strong>๋ฅผ ๊ณ ๋ฅธ๋ค
|
| 698 |
+
<ul>
|
| 699 |
+
<li><strong>Image Classification</strong> (์: ๋๋ฌผยท์๋ฌผยท์๋ฅ ๋ถ๋ฅ)</li>
|
| 700 |
+
<li><strong>Object Detection</strong> (์ฌ์ง ์ ์ฌ๋ฌผ ๋ฐ์ค๋ก ์ก๊ธฐ)</li>
|
| 701 |
+
<li><strong>Automatic Speech Recognition</strong> (์์ฑ โ ํ
์คํธ, Whisper ๋ฑ)</li>
|
| 702 |
+
<li><strong>Translation</strong> (ํโ์, ํโ์ผ)</li>
|
| 703 |
+
<li><strong>Text-to-Image</strong> (Stable Diffusion ๊ณ์ด)</li>
|
| 704 |
+
</ul>
|
| 705 |
+
</li>
|
| 706 |
+
<li>ํด๋น ์นดํ
๊ณ ๋ฆฌ์์ <strong>๋ค์ด๋ก๋ ์๊ฐ ๋ง์ ๋ชจ๋ธ 1๊ฐ</strong>๋ฅผ ๊ณจ๋ผ ๋ชจ๋ธ ์นด๋๋ฅผ ์ ๋
ํ๋ค</li>
|
| 707 |
+
<li>๋ชจ๋ธ ํ์ด์ง ์ฐ์ธก์ <strong>Inference API ์์ ฏ</strong>์ ์ง์ ์
๋ ฅ์ ๋ฃ๊ณ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ๋ค</li>
|
| 708 |
+
<li>์๋ 5๊ฐ์ง๋ฅผ ์ ๋ฆฌํด ์ ์ฌ๋๊ณผ 1๋ถ์ฉ ๋ฐํํ๋ค</li>
|
| 709 |
+
</ol>
|
| 710 |
+
|
| 711 |
+
<h3>๐ ๋ฐํ ์นด๋ (์ ๋ฆฌ ์์)</h3>
|
| 712 |
+
<table>
|
| 713 |
+
<tr><th>ํญ๋ชฉ</th><th>์ ์ ๋ด์ฉ</th></tr>
|
| 714 |
+
<tr><td>๋ชจ๋ธ ์ด๋ฆ</td><td>์: <code>openai/whisper-large-v3</code></td></tr>
|
| 715 |
+
<tr><td>๋ฌด์์ ํ๋ ๋ชจ๋ธ?</td><td>ํ ์ค ์ค๋ช
</td></tr>
|
| 716 |
+
<tr><td>ํ์ต ๋ฐ์ดํฐ</td><td>๋ชจ๋ธ ์นด๋์ "Training data" ์น์
์์ฝ</td></tr>
|
| 717 |
+
<tr><td>์์ ฏ ํ
์คํธ ๊ฒฐ๊ณผ</td><td>๋ด๊ฐ ๋ฃ์ ์
๋ ฅ โ ์ถ๋ ฅ</td></tr>
|
| 718 |
+
<tr><td>์ด๊ฑธ๋ก ๋ง๋ค ์ ์๋ ์ฑ ์์ด๋์ด</td><td>1์ค</td></tr>
|
| 719 |
+
</table>
|
| 720 |
+
|
| 721 |
+
<div class="why-box">
|
| 722 |
+
<div class="label">๊ต์์ ์๋</div>
|
| 723 |
+
<p>์ด ํ๋์ ์ง์ง ๋ชฉ์ ์ "๋ชจ๋ธ์ ํ๋ ์ธ์ฐ๋ ๊ฒ"์ด ์๋๋ผ
|
| 724 |
+
<strong>"ํ์ํ ๋ HF์์ ์ ํฉํ ๋ชจ๋ธ์ ๊ฒ์ยทํ๊ฐํ ์ ์๋ ๊ฐ๊ฐ"</strong>์ ํค์ฐ๋ ๊ฒ์ด๋ค.
|
| 725 |
+
์์ผ๋ก ์ด๋ค AI ํ๋ก์ ํธ๋ ์ฒซ ๋จ๊ณ๋ ํญ์ "HF์ ๋น์ทํ ๋ชจ๋ธ์ด ์ด๋ฏธ ์๋๊ฐ?" ๊ฒ์์ด๋ค.</p>
|
| 726 |
+
</div>
|
| 727 |
+
</section>
|
| 728 |
+
|
| 729 |
+
<!-- SECTION 7 -->
|
| 730 |
+
<section class="class-section s2">
|
| 731 |
+
<div class="section-label">SECTION 7 ยท LAB B (20๋ถ)</div>
|
| 732 |
+
<h2 class="section-title">Lab B. ํ๋กฌํํธ ๊นจ๋จ๋ฆฌ๊ธฐ โ ๊ตฌ์กฐํ๋ ์ถ๋ ฅ์ ์ค์์ฑ</h2>
|
| 733 |
+
|
| 734 |
+
<p>"LLM์๊ฒ JSON์ ๋ฌ๋ผ๊ณ ํ๋ฉด JSON์ ์ค๋ค"๋ ๊ฑด <strong>๊ฑฐ์ง๋ง</strong>์ด๋ค.
|
| 735 |
+
ํ๋กฌํํธ๋ฅผ ์ฝํ๊ฒ ์ง๋ฉด ์ด๋ป๊ฒ ๋ฐ์ด๋๋์ง ์ง์ ๋ณด๊ณ , ์ด๋ป๊ฒ ๊ฐํํ๋์ง ๋ฐฐ์๋ณธ๋ค.</p>
|
| 736 |
+
|
| 737 |
+
<h3>๐ฌ ์คํ 1. ์ฝํ ํ๋กฌํํธ๋ก ๋๋ ค๋ณด๊ธฐ</h3>
|
| 738 |
+
<p>app.py์ <code>SYSTEM_PROMPT</code>๋ฅผ <strong>์ผ๋ถ๋ฌ ์๋์ฒ๋ผ ๋จ์ํ๊ฒ</strong> ๋ฐ๊พผ๋ค:</p>
|
| 739 |
+
<pre><span class="kw">SYSTEM_PROMPT</span> = <span class="str">"์์ ์นผ๋ก๋ฆฌ๋ฅผ ์๋ ค์ค."</span></pre>
|
| 740 |
+
<p>๊ทธ๋ฆฌ๊ณ ์์ ์ฌ์ง 5์ฅ์ ์ฐจ๋ก๋ก ๋ฃ์ด๋ณด๋ฉด์ ๋ค์์ ๊ด์ฐฐํ๋ค:</p>
|
| 741 |
+
<ul>
|
| 742 |
+
<li>JSON์ด ์์ ์ ๋์ค๋ ๊ฒฝ์ฐ</li>
|
| 743 |
+
<li>JSON ์๋ค์ <em>"Sure! Here's the answer:"</em> ๊ฐ์ ์ก๋ด์ด ๋ถ๋ ๊ฒฝ์ฐ</li>
|
| 744 |
+
<li>ํค ์ด๋ฆ์ด <code>calories</code>, <code>kcal</code>, <code>calorie_count</code>๋ก ๋งค๋ฒ ๋ค๋ฅธ ๊ฒฝ์ฐ</li>
|
| 745 |
+
<li>ํ๊ตญ์ด๋ก ๋ตํ ๋์ ์์ด๋ก ๋ตํ ๋ ํ์์ด ๋ค๋ฅธ ๊ฒฝ์ฐ</li>
|
| 746 |
+
</ul>
|
| 747 |
+
<p>โ ์ด๊ฒ์ด ๋ฐ๋ก <strong>์ฑ์ด ์ฃฝ๋ ์ง์ง ์ด์ </strong>๋ค. ๋ชจ๋ธ์ด "ํ๋ฆฐ ๋ต"์ ์ค์๊ฐ ์๋๋ผ "์์ธก ๋ถ๊ฐ๋ฅํ ํํ๋ก" ๋ตํ๊ธฐ ๋๋ฌธ.</p>
|
| 748 |
+
|
| 749 |
+
<h3>๐ก๏ธ ์คํ 2. ํ๋กฌํํธ ๊ฐํ 4๋จ๊ณ</h3>
|
| 750 |
+
<p>์๋ 4๊ฐ์ง ๊ธฐ๋ฒ์ <strong>ํ๋์ฉ ์ถ๊ฐํ๋ฉด์</strong> ๊ฒฐ๊ณผ๊ฐ ์ผ๋ง๋ ์์ ๋๋์ง ๋ณธ๋ค.</p>
|
| 751 |
+
|
| 752 |
+
<table>
|
| 753 |
+
<tr><th>๋จ๊ณ</th><th>๊ธฐ๋ฒ</th><th>์์ ๋ฌธ๊ตฌ</th></tr>
|
| 754 |
+
<tr><td>1</td><td><strong>์ญํ ๋ถ์ฌ</strong></td><td>"๋๋ ํ๊ตญ ์์์ฌ AI๋ค."</td></tr>
|
| 755 |
+
<tr><td>2</td><td><strong>์คํค๋ง ๋ช
์</strong></td><td>JSON ํค ์ด๋ฆ๊ณผ ํ์
์ ๋ชจ๋ ์ ๊ธฐ</td></tr>
|
| 756 |
+
<tr><td>3</td><td><strong>์์ ์ ๊ณต (few-shot)</strong></td><td>"์
๋ ฅ: pizza โ ์ถ๋ ฅ: {...}"</td></tr>
|
| 757 |
+
<tr><td>4</td><td><strong>๊ธ์ง์ฌํญ ๋ช
์</strong></td><td>"JSON ์ธ ์ด๋ค ํ
์คํธ๋ ์ถ๋ ฅ ๊ธ์ง. ๋งํฌ๋ค์ด ์ฝ๋๋ธ๋ก ๊ธ์ง."</td></tr>
|
| 758 |
+
</table>
|
| 759 |
+
|
| 760 |
+
<h3>๐ช ์ฑ๋ฆฐ์ง: ๋ณธ์ธ๋ง์ "๋ฐฉํ ํ๋กฌํํธ" ๋ง๋ค๊ธฐ</h3>
|
| 761 |
+
<div class="todo-box">
|
| 762 |
+
<div><span class="num">!</span><strong>๋ฏธ์
</strong> โ ๊ฐ์ ์ฌ์ง 10์ฅ์ ์ฐ์์ผ๋ก ๋ฃ์์ ๋
|
| 763 |
+
<strong>10๋ฒ ๋ชจ๋ ๊ฐ์ ํ์์ JSON</strong>์ด ๋์ค๊ฒ ๋ง๋ค์ด๋ผ.
|
| 764 |
+
์ฑ๊ณตํ๋ฉด ์ 4๋จ๊ณ ์ธ์ ๋ณธ์ธ์ด ์ถ๊ฐํ ํธ๋ฆญ์ 1์ค๋ก ์ ์ด ์ ์ฌ๋์๊ฒ ๊ณต์ .</div>
|
| 765 |
+
</div>
|
| 766 |
+
|
| 767 |
+
<div class="why-box">
|
| 768 |
+
<div class="label">์ค๋ฌด์์ ๋ ๊ฐ๋ ฅํ ๋ฐฉ๋ฒ</div>
|
| 769 |
+
<p>ํ๋กฌํํธ๋ก ๊ฐ์ ํ๋ ๊ฑด ์์ ๋ฐฉํธ์ด๋ค. ์ค์๋น์ค์์๋
|
| 770 |
+
<strong>JSON Schema mode</strong>(OpenAI), <strong>Tool calling</strong>,
|
| 771 |
+
<strong>Pydantic + Instructor</strong> ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์จ์
|
| 772 |
+
๋ชจ๋ธ์ด <em>๊ตฌ์กฐ ์์ฒด๋ฅผ ์ด๊ธธ ์ ์๊ฒ</em> ๋ง๋ ๋ค. ์ด๊ฑด ๋ค์ ํ๊ธฐ์ ์ฃผ์ .</p>
|
| 773 |
+
</div>
|
| 774 |
+
</section>
|
| 775 |
+
|
| 776 |
+
<!-- SECTION 8 -->
|
| 777 |
+
<section class="class-section s3">
|
| 778 |
+
<div class="section-label">SECTION 8 ยท LAB C (20๋ถ)</div>
|
| 779 |
+
<h2 class="section-title">Lab C. ๋ชจ๋ธ ๋ฐ๊ฟ์น๊ธฐ ์ฑ๋ฆฐ์ง</h2>
|
| 780 |
+
|
| 781 |
+
<p>"<code>nateraw/food</code>๊ฐ ์ ๋ง ์ต์ ์ธ๊ฐ?"
|
| 782 |
+
โ ๊ฐ์ ์ธํฐํ์ด์ค(Inference API)๋ฅผ ์ฐ๋ฉด ๋ชจ๋ธ์ ํ ์ค๋ง ๋ฐ๊ฟ๋ ๊ต์ฒด๋๋ค.
|
| 783 |
+
์ด ์ ์ฐํจ์ด HF์ ๊ฐ์ฅ ํฐ ๊ฐ์ ์ด๋ค.</p>
|
| 784 |
+
|
| 785 |
+
<h3>๐ฏ ์ฑ๋ฆฐ์ง ๊ท์น</h3>
|
| 786 |
+
<ol class="step-list">
|
| 787 |
+
<li><code>model_config.py</code>์ <code>VISION_MODEL</code> ํ ์ค๋ง ๋ฐ๊ฟ์
|
| 788 |
+
๋ค๋ฅธ ์์ ์ด๋ฏธ์ง ๋ถ๋ฅ ๋ชจ๋ธ๋ก ๊ต์ฒด</li>
|
| 789 |
+
<li>๊ฐ์ ์์ ์ฌ์ง 5์ฅ์ ๋ ๋ชจ๋ธ์ ๋ชจ๋ ๋๋ ค์ ๊ฒฐ๊ณผ๋ฅผ ๋น๊ตํ๋ก ์ ๋ฆฌ</li>
|
| 790 |
+
<li>"์ด๋ ๋ชจ๋ธ์ด ๋ ์ข์๋๊ฐ" + ๊ทธ ์ด์ ๋ฅผ 1์ค๋ก ์์ฑ</li>
|
| 791 |
+
</ol>
|
| 792 |
+
|
| 793 |
+
<h3>๐ ํ๋ณด ๋ชจ๋ธ (HF์์ "food classification" ๊ฒ์ ๊ฒฐ๊ณผ)</h3>
|
| 794 |
+
<table>
|
| 795 |
+
<tr><th>๋ชจ๋ธ</th><th>ํน์ง</th><th>ํ ์ค ํ</th></tr>
|
| 796 |
+
<tr>
|
| 797 |
+
<td><code>nateraw/food</code></td>
|
| 798 |
+
<td>ViT, Food-101 (101์ข
)</td>
|
| 799 |
+
<td>์ด๋ฒ ์ฃผ์ฐจ ๊ธฐ๋ณธ๊ฐ</td>
|
| 800 |
+
</tr>
|
| 801 |
+
<tr>
|
| 802 |
+
<td><code>Kaludi/food-category-classification-v2.0</code></td>
|
| 803 |
+
<td>๋๋ถ๋ฅ(Bread, Dessert ๋ฑ 11์ข
)</td>
|
| 804 |
+
<td>์ธ๋ฐํ์ง ์์ง๋ง ๋น ๋ฆ</td>
|
| 805 |
+
</tr>
|
| 806 |
+
<tr>
|
| 807 |
+
<td><code>prithivMLmods/Food-101-93M</code></td>
|
| 808 |
+
<td>SigLIP ๊ธฐ๋ฐ, ๋ ํฐ ๋ชจ๋ธ</td>
|
| 809 |
+
<td>์ ํ๋โ but cold startโ</td>
|
| 810 |
+
</tr>
|
| 811 |
+
<tr>
|
| 812 |
+
<td>๋ณธ์ธ์ด ๊ฒ์ํ ๋ชจ๋ธ</td>
|
| 813 |
+
<td>โ</td>
|
| 814 |
+
<td>๊ฐ์ฐ์ โญ</td>
|
| 815 |
+
</tr>
|
| 816 |
+
</table>
|
| 817 |
+
|
| 818 |
+
<h3>๐ ๋น๊ต ํ ์์</h3>
|
| 819 |
+
<table>
|
| 820 |
+
<tr><th>์ฌ์ง</th><th>๋ชจ๋ธ A top-1</th><th>๋ชจ๋ธ B top-1</th><th>์ค์ ์ ๋ต</th><th>์น์</th></tr>
|
| 821 |
+
<tr><td>์ฌ์ง 1</td><td>?</td><td>?</td><td>?</td><td>?</td></tr>
|
| 822 |
+
<tr><td>์ฌ์ง 2</td><td>?</td><td>?</td><td>?</td><td>?</td></tr>
|
| 823 |
+
<tr><td colspan="5">โฆ 5์ฅ๊น์ง</td></tr>
|
| 824 |
+
</table>
|
| 825 |
+
|
| 826 |
+
<h3>๐ค ๋ฐํ ์ง๋ฌธ</h3>
|
| 827 |
+
<ul>
|
| 828 |
+
<li>ํ์(๊น์น์ฐ๊ฐยท๋น๋น๋ฐฅ) ์ฌ์ง์ ์ด๋ ๋ชจ๋ธ์ด ๋ ์ ๋ง์ท๋๊ฐ? <em>์ ๊ทธ๋ด๊น?</em></li>
|
| 829 |
+
<li>๋ชจ๋ธ์ ๋ฐ๊ฟจ๋๋ LLM์ด ๋ง๋ค์ด๋ด๋ ์นผ๋ก๋ฆฌ ์ถ์ ๊ฐ๋ ๋ฌ๋ผ์ก๋๊ฐ?</li>
|
| 830 |
+
<li>"์ข์ ๋ชจ๋ธ"์ ๊ธฐ์ค์ ์ ํ๋๋ฟ์ธ๊ฐ? (์๋ยทํฌ๊ธฐยท๋ผ์ด์ ์ค๋ ๊ณ ๋ ค)</li>
|
| 831 |
+
</ul>
|
| 832 |
+
|
| 833 |
+
<div class="why-box">
|
| 834 |
+
<div class="label">ํต์ฌ ๊ตํ</div>
|
| 835 |
+
<p>์ค์ AI ์๋น์ค๋ฅผ ๋ง๋ค ๋๋ ๋ชจ๋ธ 1๊ฐ๋ก ๋๋ด์ง ์๋๋ค.
|
| 836 |
+
<strong>์ฌ๋ฌ ํ๋ณด๋ฅผ ๊ฐ์ ๋ฐ์ดํฐ์ ๋๋ ค๋ณด๊ณ ๋น๊ต(=๋ฒค์น๋งํน)</strong>ํ ๋ค ๊ณ ๋ฅธ๋ค.
|
| 837 |
+
์ค๋ ํ ์ผ์ด ๋ฐ๋ก ๊ทธ ๋ฏธ๋ ๋ฒ์ ์ด๋ค.
|
| 838 |
+
๊ทธ๋ฆฌ๊ณ HF์ ํ์ค ์ธํฐํ์ด์ค ๋๋ถ์ ๋น๊ต๊ฐ "ํ ์ค ์์ "์ผ๋ก ๋๋๋ค๋ ๊ฒ ํต์ฌ.</p>
|
| 839 |
+
</div>
|
| 840 |
+
</section>
|
| 841 |
+
|
| 842 |
+
|
| 843 |
+
<!-- SECTION 9 -->
|
| 844 |
+
<section class="class-section s5" id="section-deploy">
|
| 845 |
+
<div class="section-label">SECTION 9 ยท DEPLOY</div>
|
| 846 |
+
<h2 class="section-title">HuggingFace Space ๋ฐฐํฌ โ A to Z</h2>
|
| 847 |
+
|
| 848 |
+
<p>๋ก์ปฌ์์ ๋์์ ํ์ธํ๋ค๋ฉด ์ด์ ์ธ์์ ๊ณต๊ฐํ ์ฐจ๋ก๋ค.
|
| 849 |
+
HF Space๋ <strong>"git push ํ ๋ฒ์ผ๋ก ๊ณต๊ฐ URL"</strong>์ ์ฃผ๋ ๋ฌด๋ฃ ํธ์คํ
์ด๋ค.
|
| 850 |
+
๋ฐฉ๋ฒ์ 3๊ฐ์ง๊ฐ ์๋๋ฐ ์ฒซ ๋ฐฐํฌ๋ <strong>์น ๋๋๊ทธ</strong>๊ฐ ๊ฐ์ฅ ์ฝ๋ค.</p>
|
| 851 |
+
|
| 852 |
+
<div class="why-box">
|
| 853 |
+
<div class="label">์ค๋น๋ฌผ ์ฒดํฌ</div>
|
| 854 |
+
<p>โ HF ๊ณ์ โ Read ํ ํฐ(<code>hf_xxxx...</code>)
|
| 855 |
+
โ ๋ก์ปฌ์์ ๋์๊ฐ๋ ์์ฑ๋ <code>app.py</code>
|
| 856 |
+
โ ๋ฐฐํฌํ ํ์ผ 4๊ฐ: <code>app.py</code>, <code>model_config.py</code>, <code>requirements.txt</code>, <code>README.md</code></p>
|
| 857 |
+
</div>
|
| 858 |
+
|
| 859 |
+
<h3>๐๏ธ Step 1. Space ์์ฑํ๊ธฐ</h3>
|
| 860 |
+
<p><a href="https://huggingface.co/new-space">huggingface.co/new-space</a> ์ ์ โ ์๋ ํผ์ ์์์ ์๋๋ก ์ฑ์ด๋ค. โ ~โฅ ๋ฒํธ๊ฐ ์ด๋ฏธ์ง์ ํ์ ๋งค์นญ๋๋ค.</p>
|
| 861 |
+
<img src="images/06_new_space.png" alt="Create a new Space ํผ" style="width:100%;max-width:720px;border:1px solid #e5e7eb;border-radius:8px;margin:0.6rem 0;">
|
| 862 |
+
<table>
|
| 863 |
+
<tr><th>๋ฒํธ</th><th>ํญ๋ชฉ</th><th>๊ฐ</th></tr>
|
| 864 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#ef4444;color:white;text-align:center;font-weight:bold;">1</span></td><td><strong>Owner / Space name</strong></td><td>Owner๋ ๋ณธ์ธ ์ ์ ๋ช
์๋ ์ ํ / Space name์ <code>calorie-counter</code> ์
๋ ฅ</td></tr>
|
| 865 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#f97316;color:white;text-align:center;font-weight:bold;">2</span></td><td><strong>License</strong></td><td><code>apache-2.0</code> ์ ํ</td></tr>
|
| 866 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#0ea5e9;color:white;text-align:center;font-weight:bold;">3</span></td><td><strong>Select the Space SDK</strong></td><td><strong>Gradio</strong> โ ๏ธ (Docker/Static ์๋) โ ํ
ํ๋ฆฟ์ <em>Blank</em></td></tr>
|
| 867 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#10b981;color:white;text-align:center;font-weight:bold;">4</span></td><td><strong>Space hardware</strong></td><td><code>CPU Basic ยท Free</code> (๊ธฐ๋ณธ๊ฐ)</td></tr>
|
| 868 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#8b5cf6;color:white;text-align:center;font-weight:bold;">5</span></td><td><strong>Visibility</strong></td><td><code>Public</code> ์ ํ (๋จ์๊ฒ URL ๊ณต์ ํ๋ ค๋ฉด ํ์)</td></tr>
|
| 869 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#ec4899;color:white;text-align:center;font-weight:bold;">6</span></td><td><strong>Create Space</strong></td><td>๋งจ ์๋ ๋ฒํผ ํด๋ฆญ โ ๋น Space ์์ฑ ์๋ฃ</td></tr>
|
| 870 |
+
</table>
|
| 871 |
+
|
| 872 |
+
<h3>๐ Step 2. HF_TOKEN Secret ๋ฑ๋ก โ ๏ธ (์ด๊ฑฐ ๋นผ๋จน์ผ๋ฉด ๋ฐฐํฌ ํ ์๋ฌ)</h3>
|
| 873 |
+
<p>์ฐ๋ฆฌ ์ฑ์ Inference API๋ฅผ ํธ์ถํ๋ฏ๋ก Space ์์์๋ <code>HF_TOKEN</code>์ด ํ์ํ๋ค.
|
| 874 |
+
<strong>์ฝ๋์ ์ ์ผ๋ฉด ์ ๋ ์ ๋๊ณ </strong>, Secret์ผ๋ก ๋ฑ๋กํด์ผ ํ๋ค.</p>
|
| 875 |
+
<p>๋ฐฉ๊ธ ๋ง๋ Space ํ์ด์ง ์๋จ <strong>Settings</strong> ํญ โ ์๋๋ก ์คํฌ๋กคํ๋ฉด <strong>Variables and secrets</strong> ์น์
์ด ๋ณด์ธ๋ค.</p>
|
| 876 |
+
<img src="images/07_secrets.png" alt="Settings โ Variables and secrets" style="width:100%;max-width:900px;border:1px solid #e5e7eb;border-radius:8px;margin:0.6rem 0;">
|
| 877 |
+
<table>
|
| 878 |
+
<tr><th>๋ฒํธ</th><th>์์น</th><th>ํ ์ผ</th></tr>
|
| 879 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#ef4444;color:white;text-align:center;font-weight:bold;">1</span></td><td><strong>Variables and secrets ์น์
</strong></td><td>Variables(๊ณต๊ฐ ํ๋ฌธ)์ Secrets(์ํธํ) ๋ ์นธ์ด ์๋ค. ํ ํฐ์ <strong>Secrets</strong>์ ๋ฃ๋๋ค</td></tr>
|
| 880 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#10b981;color:white;text-align:center;font-weight:bold;">2</span></td><td><strong>New secret</strong> ๋ฒํผ (์ฐ์ธก ์๋จ)</td><td>ํด๋ฆญ โ ํ์
์์ Name: <code>HF_TOKEN</code> / Value: ๋ณธ์ธ ํ ํฐ <code>hf_xxxx...</code> โ Save</td></tr>
|
| 881 |
+
</table>
|
| 882 |
+
<div class="why-box">
|
| 883 |
+
<div class="label">Secret vs Variable ์ฐจ์ด</div>
|
| 884 |
+
<p><strong>Secret</strong> โ ๊ฐ์ด ์ํธํ๋์ด ๋ค์๋ ์กฐํ ๋ถ๊ฐ. ํ ํฐ/๋น๋ฐ๋ฒํธ์ฉ. ๋ฐํ์์ ํ๊ฒฝ๋ณ์๋ก ์ฃผ์
.<br>
|
| 885 |
+
<strong>Variable</strong> โ ํ๋ฌธ. ๋ชจ๋ธ ์ด๋ฆยทURL ๊ฐ์ ๊ณต๊ฐ ๊ฐ๋ฅํ ์ค์ ๊ฐ์ฉ.</p>
|
| 886 |
+
</div>
|
| 887 |
+
|
| 888 |
+
<h3>๐ค Step 3-A. ํ์ผ ์
๋ก๋ โ ๋ฐฉ๋ฒ โ ์น ๋๋๊ทธ (๊ฐ์ฅ ์ฌ์)</h3>
|
| 889 |
+
<img src="images/08_files.png" alt="Space Files ํญ โ Contribute ๋๋กญ๋ค์ด" style="width:100%;max-width:900px;border:1px solid #e5e7eb;border-radius:8px;margin:0.6rem 0;">
|
| 890 |
+
<table>
|
| 891 |
+
<tr><th>๋ฒํธ</th><th>์์น</th><th>ํ ์ผ</th></tr>
|
| 892 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#ef4444;color:white;text-align:center;font-weight:bold;">1</span></td><td><strong>Files</strong> ํญ (์๋จ ์ฐ์ธก)</td><td>Space ํ์ด์ง ์๋จ์ App/Files/Community/Settings ์ค Files ํด๋ฆญ</td></tr>
|
| 893 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#10b981;color:white;text-align:center;font-weight:bold;">2</span></td><td><strong>+ Contribute</strong> ๋๋กญ๋ค์ด (์ฐ์ธก ์๋จ)</td><td>ํด๋ฆญ โ <em>Upload files</em> ์ ํ โ ํ์๊ธฐ์์ <code>app.py</code>ยท<code>model_config.py</code>ยท<code>requirements.txt</code>ยท<code>README.md</code> 4๊ฐ ๋๋๊ทธ โ Commit ๋ฉ์์ง <code>init</code> โ <strong>Commit changes to main</strong></td></tr>
|
| 894 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#0ea5e9;color:white;text-align:center;font-weight:bold;">3</span></td><td><strong>ํ์ผ ๋ชฉ๋ก</strong> (๋ณธ๋ฌธ)</td><td>์
๋ก๋ ์ฑ๊ณต ์ ์ฌ๊ธฐ์ ํ์ผ์ด ์ญ ๋์ด๋๋ค. ์ดํ์ ํ์ผ ํด๋ฆญ โ ์ฐํ ์์ด์ฝ์ผ๋ก ๋ฐ๋ก ์์ ๊ฐ๋ฅ</td></tr>
|
| 895 |
+
</table>
|
| 896 |
+
<p>์ปค๋ฐ ํ ์๋์ผ๋ก <strong>App</strong> ํญ์ผ๋ก ์ด๋ โ ๋น๋ ๋ก๊ทธ๊ฐ ์ค์๊ฐ ํ์๋จ (2~4๋ถ).</p>
|
| 897 |
+
|
| 898 |
+
<h3>๐ป Step 3-B. ํ์ผ ์
๋ก๋ โ ๋ฐฉ๋ฒ โก git push (ํ์ค ๋ฐฉ์)</h3>
|
| 899 |
+
<p>์ค๋ฌด์์๋ ํญ์ ์ด ๋ฐฉ๋ฒ์ ์ด๋ค. Space๊ฐ <strong>์ง์ง git ์ ์ฅ์</strong>๋ผ๋ ๊ฑธ ๋๋ ์ ์๋ค.</p>
|
| 900 |
+
|
| 901 |
+
<h4>โ ๏ธ ๋จผ์ : <strong>Write ๊ถํ ํ ํฐ</strong> ๋ฐ๊ธ (git push ์ ์ฉ)</h4>
|
| 902 |
+
<p>์์ Step 2์์ ๋ง๋ <strong>Read ํ ํฐ</strong>์ Inference API ํธ์ถ์ฉ์ด๋ผ <code>git push</code>๊ฐ <em>not authorized</em>๋ก ๊ฑฐ์ ๋๋ค. push์ฉ <strong>Write ํ ํฐ์ ๋ฐ๋ก ํ๋ ๋</strong> ๋ง๋ค์ด์ผ ํ๋ค.</p>
|
| 903 |
+
<p><a href="https://huggingface.co/settings/tokens/new?tokenType=write">huggingface.co/settings/tokens/new?tokenType=write</a> ์ ์:</p>
|
| 904 |
+
<img src="images/10_write_token.png" alt="Create new Access Token โ Write ํ์
" style="width:100%;max-width:900px;border:1px solid #e5e7eb;border-radius:8px;margin:0.6rem 0;">
|
| 905 |
+
<table>
|
| 906 |
+
<tr><th>๋ฒํธ</th><th>ํญ๋ชฉ</th><th>๊ฐ</th></tr>
|
| 907 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#ef4444;color:white;text-align:center;font-weight:bold;">1</span></td><td><strong>Token type</strong></td><td><strong>Write</strong> ์ ํ (๊ธฐ๋ณธ์ Fine-grained). โ ๏ธ ์์ฑ ํ ๋ณ๊ฒฝ ๋ถ๊ฐ โ "This cannot be changed after token creation."</td></tr>
|
| 908 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#0ea5e9;color:white;text-align:center;font-weight:bold;">2</span></td><td><strong>Token name</strong></td><td>์์ ๋กญ๊ฒ (์: <code>week06-push</code>). ๊ธฐ์กด Read ํ ํฐ๊ณผ ๊ตฌ๋ถ๋๋ ์ด๋ฆ์ผ๋ก</td></tr>
|
| 909 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#10b981;color:white;text-align:center;font-weight:bold;">3</span></td><td><strong>Create token</strong></td><td>ํด๋ฆญ โ <code>hf_xxxx...</code> ๋ณต์ฌ. <strong>๋ค์๋ ๋ชป ๋ณธ๋ค</strong></td></tr>
|
| 910 |
+
</table>
|
| 911 |
+
<div class="why-box">
|
| 912 |
+
<div class="label">Read vs Write ํ ํฐ ์ธ์ ๋ญ ์ฐ๋</div>
|
| 913 |
+
<p><strong>Read</strong> โ Inference API ํธ์ถ / ๋ชจ๋ธ ๋ค์ด๋ก๋ (<code>.env</code>ยทSpace Secrets์ ๋ฃ๋ ๊ทธ ํ ํฐ)<br>
|
| 914 |
+
<strong>Write</strong> โ <code>git push</code>, Space ์์ฑยท์์ , ํ์ผ ์
๋ก๋ ๋ฑ <em>์ฐ๊ธฐ ์์
</em><br>
|
| 915 |
+
๐ ์ฉ๋๋ณ๋ก ๋ถ๋ฆฌํด๋๋ฉด Write ํ ํฐ๋ง ์ ์ถ๋ผ๋ API ํธ์ถ์ ์ ์ ํด์ง๋ค. ๋ณด์ โ</p>
|
| 916 |
+
</div>
|
| 917 |
+
<div class="why-box">
|
| 918 |
+
<div class="label">๐ git push ์ ์ด์ ์๊ฒฉ์ฆ๋ช
์บ์๊ฐ ๋จ์์๋ค๋ฉด (macOS)</div>
|
| 919 |
+
<p>์์ ์ email/๋น๋ฐ๋ฒํธ๋ก ์๋ชป ์
๋ ฅํ๋ค๋ฉด ํค์ฒด์ธ์ ์บ์๋ผ์ ๊ณ์ ์คํจํ๋ค. ํ ๋ฒ๋ง ๋น์์ฃผ์:</p>
|
| 920 |
+
<pre>printf <span class="str">"protocol=https\nhost=huggingface.co\n\n"</span> | git credential-osxkeychain erase</pre>
|
| 921 |
+
<p>๊ทธ ๋ค์ <code>git push</code> โ Username์ <strong>HF ์ ์ ๋ช
</strong>(์ด๋ฉ์ผ โ) / Password๋ <strong>๋ฐฉ๊ธ ๋ง๋ Write ํ ํฐ</strong>. ์ฑ๊ณตํ๋ฉด ํค์ฒด์ธ์ ์๋ ์ ์ฅ๋ผ ์ดํ์ ์ ๋ฌผ์ด๋ณธ๋ค.</p>
|
| 922 |
+
</div>
|
| 923 |
+
<pre><span class="comment"># ๐ ์์ ์ํ: week06/ (zip ํผ ํด๋) ์์ ์์ฑ ํ์ผ์ด ์ด๋ฏธ ์๋ค
|
| 924 |
+
# week06/
|
| 925 |
+
# โโโ app.py โ ๋ด๊ฐ ์ฑ์๋ฃ์ ์์ฑ๋ณธ
|
| 926 |
+
# โโโ model_config.py
|
| 927 |
+
# โโโ requirements.txt
|
| 928 |
+
# โโโ README.md
|
| 929 |
+
# โโโ images/...
|
| 930 |
+
|
| 931 |
+
# 1) week06/ ์์์ Space ์ ์ฅ์๋ฅผ ๋ด๋ ค๋ฐ๋๋ค
|
| 932 |
+
# โ calorie-counter/ ๋ผ๋ ํด๋๊ฐ ์๋ก ์๊ธด๋ค
|
| 933 |
+
git clone https://huggingface.co/spaces/<๋ณธ์ธ์ ์ ๋ช
>/calorie-counter
|
| 934 |
+
|
| 935 |
+
# ์ด ์์ ์ ํด๋ ๊ตฌ์กฐ:
|
| 936 |
+
# week06/
|
| 937 |
+
# โโโ app.py โ ์๋ณธ (์์ง ์ฌ๊ธฐ ์์)
|
| 938 |
+
# โโโ ...
|
| 939 |
+
# โโโ calorie-counter/ โ ๋ฐฉ๊ธ cloneํ Space ์ ์ฅ์
|
| 940 |
+
|
| 941 |
+
# 2) cloneํ ํด๋๋ก ์ด๋
|
| 942 |
+
cd calorie-counter
|
| 943 |
+
|
| 944 |
+
# 3) ํ ๋จ๊ณ ์(../ = week06/)์ ํ์ผ 4๊ฐ๋ฅผ ์ฌ๊ธฐ๋ก ๋ณต์ฌ
|
| 945 |
+
cp ../app.py .
|
| 946 |
+
cp ../model_config.py .
|
| 947 |
+
cp ../requirements.txt .
|
| 948 |
+
cp ../README.md .
|
| 949 |
+
|
| 950 |
+
# 4) ์ปค๋ฐ & ํธ์ โ ์ด ์๊ฐ HF๊ฐ ์๋์ผ๋ก ๋น๋ ์์
|
| 951 |
+
git add .
|
| 952 |
+
git commit -m <span class="str">"init: calorie counter with LangChain LCEL"</span>
|
| 953 |
+
git push
|
| 954 |
+
<span class="comment"># Username: ๋ณธ์ธ HF ์ ์ ๋ช
|
| 955 |
+
# Password: hf_xxxx... (๋น๋ฐ๋ฒํธ ์๋ ํ ํฐ!)</span></pre>
|
| 956 |
+
|
| 957 |
+
<h3>๐ Step 3-C. README.md์ YAML Frontmatter โ ํ์</h3>
|
| 958 |
+
<p>Space๋ README.md ๋งจ ์์ <strong>YAML ๋ธ๋ก</strong>์ผ๋ก ์ค์ ์ ์ฝ๋๋ค. ์ด ๋ธ๋ก์ด ์์ผ๋ฉด ๋น๋๊ฐ ์คํจํ๋ค.</p>
|
| 959 |
+
<pre><span class="str">---
|
| 960 |
+
title: HuggingFace Calorie Counter
|
| 961 |
+
emoji: ๐ฑ
|
| 962 |
+
colorFrom: pink
|
| 963 |
+
colorTo: yellow
|
| 964 |
+
sdk: gradio
|
| 965 |
+
sdk_version: 5.9.1
|
| 966 |
+
python_version: "3.11"
|
| 967 |
+
app_file: app.py
|
| 968 |
+
pinned: false
|
| 969 |
+
license: apache-2.0
|
| 970 |
+
---</span>
|
| 971 |
+
|
| 972 |
+
# 6์ฃผ์ฐจ: HuggingFace Space ์นผ๋ก๋ฆฌ ์นด์ดํฐ
|
| 973 |
+
...</pre>
|
| 974 |
+
<table>
|
| 975 |
+
<tr><th>ํค</th><th>์๋ฏธ</th></tr>
|
| 976 |
+
<tr><td><code>sdk</code></td><td>Space ๋ฐํ์ โ ๋ฐ๋์ <code>gradio</code></td></tr>
|
| 977 |
+
<tr><td><code>sdk_version</code></td><td>Gradio ๋ฒ์ โ ๋ก์ปฌ๊ณผ ๋ง์ถ๋ฉด ์์ </td></tr>
|
| 978 |
+
<tr><td><code>app_file</code></td><td>Space๊ฐ ์คํํ ํ์ด์ฌ ํ์ผ โ <code>app.py</code></td></tr>
|
| 979 |
+
<tr><td><code>emoji</code>, <code>colorFrom/To</code></td><td>Space ์นด๋ ๊พธ๋ฏธ๊ธฐ (์ ํ)</td></tr>
|
| 980 |
+
<tr><td><code>title</code></td><td>Space ํ์ด์ง ์ ๋ชฉ</td></tr>
|
| 981 |
+
</table>
|
| 982 |
+
|
| 983 |
+
<h3>๐ Step 4. ๋น๋ ๋ก๊ทธ ์ฝ๋ ๋ฒ</h3>
|
| 984 |
+
<p>Space <strong>App</strong> ํญ์์ ์ํ ๋ฑ์ง์ ๋ก๊ทธ ํจ๋์ ํจ๊ป ๋ณธ๋ค. ์๋๋ ์ค์ ๋ก ์๋ฌ๊ฐ ๋ ์์ ํ๋ฉด.</p>
|
| 985 |
+
<img src="images/09_app_logs.png" alt="Space App ํญ โ ์ํ ๋ฑ์ง + ๋ก๊ทธ ํจ๋" style="width:100%;max-width:900px;border:1px solid #e5e7eb;border-radius:8px;margin:0.6rem 0;">
|
| 986 |
+
<table>
|
| 987 |
+
<tr><th>๋ฒํธ</th><th>์์ญ</th><th>์๋ฏธ / ๋ณด๋ ๋ฒ</th></tr>
|
| 988 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#ef4444;color:white;text-align:center;font-weight:bold;">1</span></td><td><strong>์ํ ๋ฑ์ง</strong> (์๋จ, ์ ๋ชฉ ์)</td><td><code>Building</code>(๋น๋ ์ค) โ <code>Running</code>(์ด๋ก, ์ฑ๊ณต) โ <code>Runtime error</code>(๋นจ๊ฐ, ๋ฐํ์ ์ฃฝ์) โ <code>Sleeping ๐ค</code>(48h ๋ฌด์ ์). ์ฌ๊ธฐ๋ถํฐ ๋จผ์ ํ์ธ</td></tr>
|
| 989 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#f97316;color:white;text-align:center;font-weight:bold;">2</span></td><td><strong>App / Files / Community / Settings</strong> ํญ</td><td>App ํญ์ด ์ง๊ธ ํ์ฑํ๋จ (๋ฐ์ค). ๋ค๋ฅธ ํญ์ผ๋ก ์ธ์ ๋ ์ด๋ ๊ฐ๋ฅ</td></tr>
|
| 990 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#0ea5e9;color:white;text-align:center;font-weight:bold;">3</span></td><td><strong>๋ก๊ทธ ํญ ๋ฐ</strong> (Logs / Build / Container)</td><td><em>Build</em>: <code>pip install</code> ๋จ๊ณ(์์กด์ฑ ๋๋ฝ ์ ์ฌ๊ธฐ์ ์คํจ) / <em>Container</em>: ๋น๋ ์ฑ๊ณต ํ ๋ฐํ์ ๋ก๊ทธ(Python tracebackยทprint ์ถ๋ ฅ) / <em>Logs Endpoint</em>: ์๋ณธ ๋ก๊ทธ URL</td></tr>
|
| 991 |
+
<tr><td><span style="display:inline-block;width:24px;height:24px;border-radius:50%;background:#10b981;color:white;text-align:center;font-weight:bold;">4</span></td><td><strong>๋ก๊ทธ ๋ณธ๋ฌธ</strong></td><td>Running์ผ ๋ ์ฌ๊ธฐ์ Gradio UI๊ฐ ์๋ฒ ๋๋๊ณ , ์๋ฌ ์ traceback์ด ๋์จ๋ค. ์ ์์๋ <code>ModuleNotFoundError: No module named 'audioop'</code> โ ํ์ด์ฌ 3.13์์ pydub ํธํ ๋ฌธ์ </td></tr>
|
| 992 |
+
</table>
|
| 993 |
+
|
| 994 |
+
<h3>๐ Step 5. ๋์ ํ์ธ & ๋ฐฐํฌ๋ URL</h3>
|
| 995 |
+
<p>Running์ด ๋๋ฉด ์ด๋ฐ ํ๋ฉด์ด ๋ฌ๋ค. ์ด๋ก <code>โ Running</code> ๋ฑ์ง๊ฐ ๋ณด์ด๋ฉด ์ฑ๊ณต.</p>
|
| 996 |
+
<img src="images/11_running.png" alt="๋ฐฐํฌ ์ฑ๊ณต: Running ์ํ์ Gradio UI" style="width:100%;max-width:900px;border:1px solid #e5e7eb;border-radius:8px;margin:0.6rem 0;">
|
| 997 |
+
<div class="todo-box">
|
| 998 |
+
<div><span class="num">โ</span>์๋จ ์ํ ๋ฑ์ง๊ฐ <strong>Running</strong> (์ด๋ก)์ผ๋ก ๋ฐ๋</div>
|
| 999 |
+
<div><span class="num">โ</span>Gradio UI๊ฐ Space ํ์ด์ง ์์ ์๋ฒ ๋๋์ด ํ์๋จ</div>
|
| 1000 |
+
<div><span class="num">โ</span>์์ ์ฌ์ง 1์ฅ ๋๋๊ทธ โ 30~60์ด ํ ๋ถ๋ฅ ๊ฒฐ๊ณผ + JSON ํ์</div>
|
| 1001 |
+
</div>
|
| 1002 |
+
|
| 1003 |
+
<h4>๐ Space๊ฐ ๋ฐฐํฌ๋๋ฉด URL์ด 2๊ฐ ์๊ธด๋ค</h4>
|
| 1004 |
+
<table>
|
| 1005 |
+
<tr><th>์ข
๋ฅ</th><th>ํ์</th><th>์ธ์ ์ฐ๋</th></tr>
|
| 1006 |
+
<tr>
|
| 1007 |
+
<td><strong>โ ํ์ด์ง URL</strong><br>(HF ํ๋ธ ํ์ด์ง)</td>
|
| 1008 |
+
<td><code>https://huggingface.co/spaces/<์ ์ >/<์คํ์ด์ค๋ช
></code><br>์: <code>https://huggingface.co/spaces/jay-kim412/estimate_calories</code></td>
|
| 1009 |
+
<td>Space ํ๋กํ(์ข์์ยทCommunityยทFiles ํญ) + ์ฑ ์๋ฒ ๋๊ฐ ํจ๊ป ๋ณด์. ์น๊ตฌํํ
๊ณต์ ยท์ด๋ ฅ์์ ๋ถ์ผ ๋ ์ด๊ฑธ ์</td>
|
| 1010 |
+
</tr>
|
| 1011 |
+
<tr>
|
| 1012 |
+
<td><strong>โก ์ง์ ์ฑ URL</strong><br>(Gradio ํ์คํฌ๋ฆฐ)</td>
|
| 1013 |
+
<td><code>https://<์ ์ >-<์คํ์ด์ค๋ช
>.hf.space</code><br>์: <code>https://jay-kim412-estimate-calories.hf.space</code></td>
|
| 1014 |
+
<td>HF UI ์์ด ์ฑ๋ง ์ ์ฒดํ๋ฉด. iframe ์๋ฒ ๋ยท๋ชจ๋ฐ์ผ ๊ณต์ ์ ํธํจ. ์ ์ ๋ช
ยท์คํ์ด์ค๋ช
์ <code>_</code>๋ ์๋์ผ๋ก <code>-</code>๋ก ์นํ๋๋ค</td>
|
| 1015 |
+
</tr>
|
| 1016 |
+
</table>
|
| 1017 |
+
<div class="why-box">
|
| 1018 |
+
<div class="label">๐ก Custom domain์?</div>
|
| 1019 |
+
<p>Settings ํ์ด์ง์ <strong>Custom domain</strong> ํญ๋ชฉ์ด ๋ณด์ด๋๋ฐ, ๋ณธ์ธ ์์ ๋๋ฉ์ธ(<code>calorie.mydomain.com</code> ๋ฑ)์ Space์ ์ฐ๊ฒฐํ๋ ๊ธฐ๋ฅ์ด๋ค. <strong>PRO ๊ณ์ ์ ๋ฃ</strong> ์ ์ฉ์ด๋ผ ์์
์์๋ ๋ฌด์. ๋ฌด๋ฃ ๊ณ์ ์ ์ 2๊ฐ URL๋ก ์ถฉ๋ถํ๋ค.</p>
|
| 1020 |
+
</div>
|
| 1021 |
+
|
| 1022 |
+
<h3>๐ Step 6. ์์ฃผ ๊ฑธ๋ฆฌ๋ ํจ์ ๊ณผ ํด๊ฒฐ๋ฒ</h3>
|
| 1023 |
+
<table>
|
| 1024 |
+
<tr><th>์ฆ์</th><th>์์ธ</th><th>ํด๊ฒฐ</th></tr>
|
| 1025 |
+
<tr>
|
| 1026 |
+
<td>Build failed: <code>ModuleNotFoundError</code></td>
|
| 1027 |
+
<td>requirements.txt์ ๋๋ฝ</td>
|
| 1028 |
+
<td>ํ์ํ ํจํค์ง ์ถ๊ฐ ํ ์ฌํธ์</td>
|
| 1029 |
+
</tr>
|
| 1030 |
+
<tr>
|
| 1031 |
+
<td>Runtime: <code>HF_TOKEN ํ๊ฒฝ๋ณ์๊ฐ ๋น์ด์์ต๋๋ค</code></td>
|
| 1032 |
+
<td>Secrets ๋ฏธ๋ฑ๋ก</td>
|
| 1033 |
+
<td>Settings โ Variables and secrets ์ฌํ์ธ</td>
|
| 1034 |
+
</tr>
|
| 1035 |
+
<tr>
|
| 1036 |
+
<td>์ฒซ ํธ์ถ์์ 503 Service Unavailable</td>
|
| 1037 |
+
<td>LLM cold start (๋ฌด๋ฃ ํฐ์ด)</td>
|
| 1038 |
+
<td>30์ด ๋๊ธฐ ํ ๋ค์ ์๋. ๋ฐ๋ณต๋๋ฉด ๋ค๋ฅธ LLM์ผ๋ก ๊ต์ฒด</td>
|
| 1039 |
+
</tr>
|
| 1040 |
+
<tr>
|
| 1041 |
+
<td><code>meta-llama/Meta-Llama-3-8B-Instruct</code> ์ ๊ทผ ๊ฑฐ๋ถ</td>
|
| 1042 |
+
<td>Meta ๋ผ์ด์ ์ค ๋ฏธ๋์</td>
|
| 1043 |
+
<td><a href="https://huggingface.co/meta-llama/Meta-Llama-3-8B-Instruct">๋ชจ๋ธ ํ์ด์ง</a>์์ ๋์ ์ฒดํฌ ํ ์น์ธ ๋๊ธฐ</td>
|
| 1044 |
+
</tr>
|
| 1045 |
+
<tr>
|
| 1046 |
+
<td>Space๊ฐ <code>Sleeping ๐ค</code> ์ํ</td>
|
| 1047 |
+
<td>48์๊ฐ ํธ๋ํฝ ์์ผ๋ฉด ์๋ ํด๋ฉด</td>
|
| 1048 |
+
<td>ํ์ด์ง ์ ์๋ง ํด๋ ์๋์ผ๋ก ๊นจ์ด๋จ (30์ด)</td>
|
| 1049 |
+
</tr>
|
| 1050 |
+
<tr>
|
| 1051 |
+
<td>git push ์ <em>Authentication failed</em></td>
|
| 1052 |
+
<td>๋น๋ฐ๋ฒํธ๋ก ์๋</td>
|
| 1053 |
+
<td>Password ์๋ฆฌ์ <strong>HF ํ ํฐ</strong>(<code>hf_...</code>) ์
๋ ฅ</td>
|
| 1054 |
+
</tr>
|
| 1055 |
+
<tr>
|
| 1056 |
+
<td>๋น๋๋ ์ฑ๊ณตํ๋๋ฐ UI๊ฐ ์ ๋ธ</td>
|
| 1057 |
+
<td><code>app_file</code> ์ง์ ์ค๋ฅ</td>
|
| 1058 |
+
<td>README.md frontmatter์ <code>app_file: app.py</code> ํ์ธ</td>
|
| 1059 |
+
</tr>
|
| 1060 |
+
</table>
|
| 1061 |
+
|
| 1062 |
+
<h3>๐ Step 7. ์ฝ๋ ์์ ํ ์ฌ๋ฐฐํฌ</h3>
|
| 1063 |
+
<p>Space๋ git์ด๋ฏ๋ก <strong>๊ทธ๋ฅ ๋ค์ pushํ๋ฉด ์๋ ์ฌ๋น๋</strong>๋๋ค.</p>
|
| 1064 |
+
<pre><span class="comment"># ์น ์
๋ก๋ ๋ฐฉ์์ด๋ฉด</span>
|
| 1065 |
+
<span class="comment"># โ Files ํญ์์ ํด๋น ํ์ผ ํด๋ฆญ โ ์ฐํ ์์ด์ฝ(Edit) โ ์์ ํ Commit</span>
|
| 1066 |
+
|
| 1067 |
+
<span class="comment"># git ๋ฐฉ์์ด๋ฉด</span>
|
| 1068 |
+
git add app.py
|
| 1069 |
+
git commit -m <span class="str">"tweak: ํ๋กฌํํธ ๊ฐํ"</span>
|
| 1070 |
+
git push
|
| 1071 |
+
<span class="comment"># โ Space๊ฐ 1~2๋ถ ํ ์๋ ์ฌ์์</span></pre>
|
| 1072 |
+
|
| 1073 |
+
<h3>๐ฐ ๋น์ฉ ์๋ด (๋ฌด๋ฃ ํฐ์ด ์ ํ)</h3>
|
| 1074 |
+
<ul>
|
| 1075 |
+
<li><strong>Space ํธ์คํ
</strong>: ๋ฌด๋ฃ (CPU basic ๋ฌด์ ํ)</li>
|
| 1076 |
+
<li><strong>Inference API ํธ์ถ</strong>: ๋ฌด๋ฃ ๊ณ์ ์ ์๊ฐ๋น ์ ํ์ด ์์ (์ ํํ ์์น๋ ์์ฆ๋ณ ๋ณ๋)</li>
|
| 1077 |
+
<li>48์๊ฐ ๋ฏธ์ฌ์ฉ โ ์๋ Sleep โ ์ ์ ์ ์๋ ๊ธฐ์ (cold start 30~60์ด)</li>
|
| 1078 |
+
<li>ํญ์ ์ผ๋๋ ค๋ฉด <strong>ZeroGPU</strong>(PRO ๊ณ์ ) ๋๋ <strong>Inference Endpoints</strong> ์ ๋ฃ ์ ํ</li>
|
| 1079 |
+
</ul>
|
| 1080 |
+
|
| 1081 |
+
<div class="why-box">
|
| 1082 |
+
<div class="label">๐ ๋ฐฐํฌ ์๋ฃ ํ</div>
|
| 1083 |
+
<p>๊ณต๊ฐ URL์ GitHub ํ๋กํยท์ด๋ ฅ์ยท๋งํฌ๋์ธ์ ๋ถ์ด์.
|
| 1084 |
+
"HuggingFace์ ์ง์ ๋ฐฐํฌํ AI ์ฑ"์
|
| 1085 |
+
์ฑ์ฉ ๋ด๋น์์ ๊ต์์๊ฒ <strong>๋ง๋ณด๋ค ํจ์ฌ ๊ฐํ ์ฆ๋ช
</strong>์ด ๋๋ค.
|
| 1086 |
+
์ด๋ฒ ํ ๋ฒ์ ๋ฐฐํฌ ๊ฒฝํ์ด ์์ผ๋ก ๋ง๋ค ๋ชจ๋ AI ๋ฐ๋ชจ์ ํ
ํ๋ฆฟ์ด ๋๋ค.</p>
|
| 1087 |
+
</div>
|
| 1088 |
+
</section>
|
| 1089 |
+
|
| 1090 |
+
<!-- MISSION -->
|
| 1091 |
+
<div class="mission">
|
| 1092 |
+
<h2>๐ฏ ์ค๋ ์์
๋ฏธ์
</h2>
|
| 1093 |
+
<ul>
|
| 1094 |
+
<li>app.py์ TODO 3๊ณณ์ ๋ชจ๋ ์ฑ์ด๋ค</li>
|
| 1095 |
+
<li>๋ก์ปฌ์์ ์์ ์ฌ์ง 1์ฅ ์ด์์ผ๋ก ๋์ ํ์ธ</li>
|
| 1096 |
+
<li>HuggingFace Space์ ๋ฐฐํฌํด ๊ณต๊ฐ URL ๋ฐ๊ธฐ</li>
|
| 1097 |
+
<li>title/emoji/SYSTEM_PROMPT ์ค ํ๋ ์ด์ ๋ณธ์ธ๋ง์ ๋ฐฉ์์ผ๋ก ์ปค์คํฐ๋ง์ด์ฆ</li>
|
| 1098 |
+
<li>๊ฒฐ๊ณผ๋ฌผ: <strong>Space URL + ๊ฒฐ๊ณผ ์คํฌ๋ฆฐ์ท 1์ฅ + 2~3์ค ํ๊ณ </strong></li>
|
| 1099 |
+
</ul>
|
| 1100 |
+
</div>
|
| 1101 |
+
|
| 1102 |
+
<footer>
|
| 1103 |
+
2026 AI์น์ตํฉ ยท Week 06 ยท HuggingFace ร Spaces ยท ์นผ๋ก๋ฆฌ ์นด์ดํฐ
|
| 1104 |
+
</footer>
|
| 1105 |
+
</div>
|
| 1106 |
+
</body>
|
| 1107 |
+
</html>
|
README.md
CHANGED
|
@@ -1,14 +1,87 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
emoji:
|
| 4 |
colorFrom: pink
|
| 5 |
-
colorTo:
|
| 6 |
sdk: gradio
|
| 7 |
-
sdk_version:
|
|
|
|
| 8 |
app_file: app.py
|
| 9 |
pinned: false
|
| 10 |
license: apache-2.0
|
| 11 |
-
short_description: Calorie Calculator
|
| 12 |
---
|
| 13 |
|
| 14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: HuggingFace Calorie Counter
|
| 3 |
+
emoji: ๐ฑ
|
| 4 |
colorFrom: pink
|
| 5 |
+
colorTo: yellow
|
| 6 |
sdk: gradio
|
| 7 |
+
sdk_version: 5.9.1
|
| 8 |
+
python_version: "3.11"
|
| 9 |
app_file: app.py
|
| 10 |
pinned: false
|
| 11 |
license: apache-2.0
|
|
|
|
| 12 |
---
|
| 13 |
|
| 14 |
+
# 6์ฃผ์ฐจ: HuggingFace Space ์นผ๋ก๋ฆฌ ์นด์ดํฐ
|
| 15 |
+
|
| 16 |
+
์์ ์ฌ์ง์ ์
๋ก๋ํ๋ฉด HuggingFace Inference API๋ก ์์์ ์ธ์ํ๊ณ ,
|
| 17 |
+
LLM์ด 1์ธ๋ถ ๊ธฐ์ค ์นผ๋ก๋ฆฌ/ํ๋จ์ง๋ฅผ ์ถ์ ํ๋ Gradio ์ฑ์ด๋ค.
|
| 18 |
+
์์ฑ๋ ์ฑ์ ๊ทธ๋๋ก **HuggingFace Space** ์ ์ฌ๋ ค ๊ณต๊ฐ URL์ ๋ฐ์ ์ ์๋ค.
|
| 19 |
+
|
| 20 |
+
> ์ด ์๋ฃ์ ๊ธฐ์ ์ ๋ณด๋ 2026-04 ๊ธฐ์ค์
๋๋ค.
|
| 21 |
+
|
| 22 |
+
## ํ์ผ ๊ตฌ์กฐ
|
| 23 |
+
|
| 24 |
+
```
|
| 25 |
+
week06/
|
| 26 |
+
โโโ app.py # Gradio ์ฑ ๋ณธ์ฒด (TODO 4๊ณณ์ ์ฑ์ ์์ฑ)
|
| 27 |
+
โโโ model_config.py # HF ๋ชจ๋ธ ์ด๋ฆ ์์ + InferenceClient ํฉํ ๋ฆฌ
|
| 28 |
+
โโโ requirements.txt # Space๊ฐ ์ค์นํ ์์กด์ฑ
|
| 29 |
+
โโโ .env.example # HF_TOKEN ํ
ํ๋ฆฟ
|
| 30 |
+
โโโ README.md # ์ด ํ์ผ (์์ YAML์ด Space ์ค์ )
|
| 31 |
+
```
|
| 32 |
+
|
| 33 |
+
## ์คํ ๋ฐฉ๋ฒ (๋ก์ปฌ)
|
| 34 |
+
|
| 35 |
+
```bash
|
| 36 |
+
# 1) ํ ํฐ ๋ฐ๊ธ: https://huggingface.co/settings/tokens (Read ๊ถํ)
|
| 37 |
+
cp .env.example .env
|
| 38 |
+
# .env ํ์ผ์ ์ด์ด HF_TOKEN=hf_... ๋ก ์์
|
| 39 |
+
|
| 40 |
+
# 2) ์์กด์ฑ ์ค์น
|
| 41 |
+
uv pip install -r requirements.txt
|
| 42 |
+
|
| 43 |
+
# 3) ์คํ
|
| 44 |
+
uv run python app.py
|
| 45 |
+
# ๋ธ๋ผ์ฐ์ : http://127.0.0.1:7860
|
| 46 |
+
```
|
| 47 |
+
|
| 48 |
+
## TODO (app.py ์)
|
| 49 |
+
|
| 50 |
+
1. **`SYSTEM_PROMPT`** โ ์์์ฌ ์ญํ + JSON ์คํค๋ง ๊ฐ์ (ChatPromptTemplate ์์ ๋ค์ด๊ฐ๋ฏ๋ก ์ค๊ดํธ๋ `{{ }}`๋ก ์ด์ค์ผ์ดํ)
|
| 51 |
+
2. **`_chain_lazy()` ์ LCEL ์ฒด์ธ ์กฐ๋ฆฝ** (4๋จ๊ณ)
|
| 52 |
+
- 2-1. `HuggingFaceEndpoint` ์์ฑ (`repo_id=LLM_MODEL`, `task="text-generation"`, ํ ํฐ)
|
| 53 |
+
- 2-2. `ChatHuggingFace(llm=endpoint)` ๋ก ๊ฐ์ธ๊ธฐ
|
| 54 |
+
- 2-3. `ChatPromptTemplate.from_messages([("system", SYSTEM_PROMPT), ("human", "...{labels_json}")])`
|
| 55 |
+
- 2-4. `_chain = prompt | llm | JsonOutputParser()` ํ์ดํ ์ฐ๊ฒฐ
|
| 56 |
+
3. **`classify_food()`** โ `client.image_classification(tmp_path, model=VISION_MODEL)` ํธ์ถ
|
| 57 |
+
4. **`estimate_calories()`** โ `chain.invoke({"labels_json": labels_json})` ํธ์ถ
|
| 58 |
+
|
| 59 |
+
๋ค ๊ณณ์ ์ฑ์ฐ๋ฉด ์ฑ์ด ๋์ํ๋ค.
|
| 60 |
+
|
| 61 |
+
## HuggingFace Space ๋ฐฐํฌ ๋ฐฉ๋ฒ
|
| 62 |
+
|
| 63 |
+
1. https://huggingface.co/new-space ์์ **Gradio** SDK๋ก Space ์์ฑ
|
| 64 |
+
2. Space์ **Settings > Variables and secrets** ์ `HF_TOKEN` ๋ฑ๋ก
|
| 65 |
+
3. ํ์ผ ์
๋ก๋ (์น ๋๋๊ทธ or `git push`)
|
| 66 |
+
```bash
|
| 67 |
+
git clone https://huggingface.co/spaces/<๋ณธ์ธ>/<space-์ด๋ฆ>
|
| 68 |
+
cd <space-์ด๋ฆ>
|
| 69 |
+
cp ../week06/{app.py,model_config.py,requirements.txt,README.md} .
|
| 70 |
+
git add .
|
| 71 |
+
git commit -m "init"
|
| 72 |
+
git push
|
| 73 |
+
```
|
| 74 |
+
4. ๋ช ๋ถ ํ `https://huggingface.co/spaces/<๋ณธ์ธ>/<space-์ด๋ฆ>` ์ ์ํ์ฌ ๋์ ํ์ธ
|
| 75 |
+
|
| 76 |
+
## ๊ณผ์
|
| 77 |
+
|
| 78 |
+
- [ ] Space URL ์ ์ถ
|
| 79 |
+
- [ ] title/emoji/ํ๋กฌํํธ ์ค ํ๋ ์ด์ ์ปค์คํฐ๋ง์ด์ฆ
|
| 80 |
+
- [ ] ๊ฒฐ๊ณผ ์คํฌ๋ฆฐ์ท 1์ฅ + 2~3์ค ์ค๋ช
|
| 81 |
+
|
| 82 |
+
## ์ฌ์ฉ ๋ชจ๋ธ
|
| 83 |
+
|
| 84 |
+
| ์ญํ | ๋ชจ๋ธ |
|
| 85 |
+
|------|------|
|
| 86 |
+
| ์ด๋ฏธ์ง ๋ถ๋ฅ | `nateraw/food` |
|
| 87 |
+
| ์นผ๋ก๋ฆฌ ์ถ์ LLM | `meta-llama/Meta-Llama-3-8B-Instruct` |
|
__pycache__/model_config.cpython-313.pyc
ADDED
|
Binary file (1.49 kB). View file
|
|
|
app.py
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
6์ฃผ์ฐจ ์ค์ต: HuggingFace Space ์นผ๋ก๋ฆฌ ์นด์ดํฐ (LangChain LCEL ยท ํ์ ๋ฒ์ )
|
| 3 |
+
=====================================================================
|
| 4 |
+
์์ ์ฌ์ง์ ์
๋ก๋ํ๋ฉด
|
| 5 |
+
1) HF Inference API์ ์ด๋ฏธ์ง ๋ถ๋ฅ ๋ชจ๋ธ๋ก ์์์ ์ธ์ํ๊ณ
|
| 6 |
+
2) ๊ทธ ๊ฒฐ๊ณผ๋ฅผ LangChain ChatHuggingFace LLM์ ๋๊ฒจ ์นผ๋ก๋ฆฌ/์์์๋ฅผ ์ถ์ ํ ๋ค
|
| 7 |
+
3) Gradio UI๋ก ๋ณด์ฌ์ค๋ค.
|
| 8 |
+
|
| 9 |
+
ํต์ฌ ๋ณ๊ฒฝ: estimate_calories๋ LCEL ์ฒด์ธ(prompt | llm | parser)์ผ๋ก ๊ตฌ์ฑํ๋ค.
|
| 10 |
+
์ด ํ์ผ์ ๊ทธ๋๋ก HuggingFace Space(Gradio SDK)์ ์ฌ๋ฆฌ๋ฉด ๋ฐฐํฌ๋๋ค.
|
| 11 |
+
|
| 12 |
+
TODO ๋ก ํ์๋ ๋ถ๋ถ์ ์ฑ์ ์์ฑํ ๋ค,
|
| 13 |
+
1) ๋ก์ปฌ์์ ์คํํด๋ณด๊ณ
|
| 14 |
+
2) HuggingFace Space์ ๋ฐฐํฌํ๋ค.
|
| 15 |
+
|
| 16 |
+
๋ก์ปฌ ์คํ:
|
| 17 |
+
uv run python app.py
|
| 18 |
+
"""
|
| 19 |
+
|
| 20 |
+
from __future__ import annotations
|
| 21 |
+
|
| 22 |
+
import json
|
| 23 |
+
import os
|
| 24 |
+
import tempfile
|
| 25 |
+
from typing import Any
|
| 26 |
+
|
| 27 |
+
import gradio as gr
|
| 28 |
+
from gradio_client import utils as _gc_utils # noqa: E402
|
| 29 |
+
|
| 30 |
+
# --- workaround: gradio_client์ JSON Schema walker๊ฐ bool ์คํค๋ง๋ฅผ ๋ง๋๋ฉด
|
| 31 |
+
# ํฐ์ง๋ ๋ฒ๊ทธ(#10178) ์ฐํ. Label/JSON ์ปดํฌ๋ํธ๊ฐ ์์ฑํ๋
|
| 32 |
+
# additionalProperties: true ์คํค๋ง์์ ๋ฐ์ํ๋ค.
|
| 33 |
+
_orig_get_type = _gc_utils.get_type
|
| 34 |
+
def _safe_get_type(schema):
|
| 35 |
+
if isinstance(schema, bool):
|
| 36 |
+
return "Any"
|
| 37 |
+
return _orig_get_type(schema)
|
| 38 |
+
_gc_utils.get_type = _safe_get_type
|
| 39 |
+
|
| 40 |
+
_orig_j2p = _gc_utils._json_schema_to_python_type
|
| 41 |
+
def _safe_j2p(schema, defs=None):
|
| 42 |
+
if isinstance(schema, bool):
|
| 43 |
+
return "Any"
|
| 44 |
+
return _orig_j2p(schema, defs)
|
| 45 |
+
_gc_utils._json_schema_to_python_type = _safe_j2p
|
| 46 |
+
|
| 47 |
+
from dotenv import load_dotenv
|
| 48 |
+
from huggingface_hub import InferenceClient
|
| 49 |
+
from langchain_core.output_parsers import JsonOutputParser
|
| 50 |
+
from langchain_core.prompts import ChatPromptTemplate
|
| 51 |
+
from langchain_huggingface import ChatHuggingFace, HuggingFaceEndpoint
|
| 52 |
+
from PIL import Image
|
| 53 |
+
|
| 54 |
+
from model_config import LLM_MODEL, VISION_MODEL, get_token
|
| 55 |
+
|
| 56 |
+
load_dotenv()
|
| 57 |
+
|
| 58 |
+
TOP_K = 3
|
| 59 |
+
|
| 60 |
+
# ---------------------------------------------------------------------------
|
| 61 |
+
# TODO 1. ์์คํ
ํ๋กฌํํธ
|
| 62 |
+
# ---------------------------------------------------------------------------
|
| 63 |
+
# LLM ์ด '์์์ฌ AI' ์ญํ ์ ํ๊ณ , 1์ธ๋ถ ๊ธฐ์ค ์นผ๋ก๋ฆฌ/ํ๋จ์ง๋ฅผ JSON ์ผ๋ก ์ถ๋ ฅํ๋๋ก
|
| 64 |
+
# ์์คํ
ํ๋กฌํํธ๋ฅผ ์์ฑํ๋ผ.
|
| 65 |
+
# - ๋ฐ๋์ ์๋ JSON ์คํค๋ง๋ง ์ถ๋ ฅํ๋ผ๊ณ ๊ฐ์ ํ ๊ฒ
|
| 66 |
+
# {"food": str, "confidence": float, "calories_kcal": int,
|
| 67 |
+
# "carbs_g": int, "protein_g": int, "fat_g": int, "note": str}
|
| 68 |
+
# - ChatPromptTemplate ์ ๋ค์ด๊ฐ๋ฏ๋ก JSON ์์์ ์ค๊ดํธ๋ {{ }} ๋ก ์ด์ค์ผ์ดํํ ๊ฒ
|
| 69 |
+
SYSTEM_PROMPT = """ ๋๋ ํ๊ตญ ์์์ฌ AI๋ค.
|
| 70 |
+
์ฌ์ฉ์๊ฐ ์์ ๋ถ๋ฅ ๊ฒฐ๊ณผ(top-k labels)๋ฅผ ์ฃผ๋ฉด,
|
| 71 |
+
๊ฐ์ฅ ๊ฐ๋ฅ์ฑ ๋์ ์์ 1๊ฐ์ 1์ธ๋ถ ๊ธฐ์ค ์์์ ๋ณด๋ฅผ ์ถ์ ํด
|
| 72 |
+
๋ฐ๋์ ๋ค์ JSON ์คํค๋ง๋ง ์ถ๋ ฅํ๋ผ. ๋ค๋ฅธ ํ
์คํธ/๋งํฌ๋ค์ด ๊ธ์ง.
|
| 73 |
+
|
| 74 |
+
{{"food": "์์๋ช
", "confidence": 0.0~1.0,
|
| 75 |
+
"calories_kcal": ์ ์, "carbs_g": ์ ์,
|
| 76 |
+
"protein_g": ์ ์, "fat_g": ์ ์,
|
| 77 |
+
"note": "์ถ์ ๊ทผ๊ฑฐ ํ ์ค"}}"
|
| 78 |
+
|
| 79 |
+
"""
|
| 80 |
+
# -----------------------------------------------------------------------------
|
| 81 |
+
# ํด๋ผ์ด์ธํธ / ์ฒด์ธ lazy init
|
| 82 |
+
# -----------------------------------------------------------------------------
|
| 83 |
+
_vision_client: InferenceClient | None = None
|
| 84 |
+
_chain = None
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
def _vision_lazy() -> InferenceClient:
|
| 88 |
+
global _vision_client
|
| 89 |
+
if _vision_client is None:
|
| 90 |
+
_vision_client = InferenceClient(token=get_token())
|
| 91 |
+
return _vision_client
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
def _chain_lazy():
|
| 95 |
+
"""LCEL ์ฒด์ธ: prompt | ChatHuggingFace | JsonOutputParser"""
|
| 96 |
+
global _chain
|
| 97 |
+
if _chain is None:
|
| 98 |
+
# 3-1. HF Inference Endpoint ์์ฑ
|
| 99 |
+
endpoint = HuggingFaceEndpoint(
|
| 100 |
+
repo_id=LLM_MODEL,
|
| 101 |
+
task="text-generation",
|
| 102 |
+
max_new_tokens=300,
|
| 103 |
+
temperature=0.2,
|
| 104 |
+
huggingfacehub_api_token=get_token(),
|
| 105 |
+
)
|
| 106 |
+
|
| 107 |
+
# 3-2. ์ฑํ
์ธํฐํ์ด์ค๋ก ๊ฐ์ธ๊ธฐ
|
| 108 |
+
llm = ChatHuggingFace(llm=endpoint)
|
| 109 |
+
|
| 110 |
+
# 3-3. ํ๋กฌํํธ ํ
ํ๋ฆฟ
|
| 111 |
+
prompt = ChatPromptTemplate.from_messages([
|
| 112 |
+
("system", SYSTEM_PROMPT),
|
| 113 |
+
("human", "๋ค์์ ์ด๋ฏธ์ง ๋ถ๋ฅ๊ธฐ์ top-k ๊ฒฐ๊ณผ๋ค:\n{labels_json}"),
|
| 114 |
+
])
|
| 115 |
+
|
| 116 |
+
# 3-4. LCEL ํ์ดํ๋ผ์ธ โ ์ด ํ ์ค์ด ํต์ฌ!
|
| 117 |
+
_chain = prompt | llm | JsonOutputParser()
|
| 118 |
+
|
| 119 |
+
return _chain
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
# -----------------------------------------------------------------------------
|
| 123 |
+
# Step 1: ์ด๋ฏธ์ง ๋ถ๋ฅ (LangChain ์ถ์ํ ์์ โ InferenceClient ์ง์ ์ฌ์ฉ)
|
| 124 |
+
# -----------------------------------------------------------------------------
|
| 125 |
+
def classify_food(image: Image.Image) -> list[dict[str, Any]]:
|
| 126 |
+
"""HF ์ด๋ฏธ์ง ๋ถ๋ฅ ๋ชจ๋ธ์ PIL ์ด๋ฏธ์ง๋ฅผ ๋๊ฒจ top-k ๊ฒฐ๊ณผ๋ฅผ ๋ฐ๋๋ค."""
|
| 127 |
+
client = _vision_lazy()
|
| 128 |
+
|
| 129 |
+
# PIL ์ด๋ฏธ์ง๋ฅผ JPEG ์์ ํ์ผ๋ก ์ ์ฅ (hf-inference ๋ผ์ฐํฐ๊ฐ Content-Type ์ ์๊ตฌ).
|
| 130 |
+
with tempfile.NamedTemporaryFile(suffix=".jpg", delete=False) as tmp:
|
| 131 |
+
image.convert("RGB").save(tmp, format="JPEG")
|
| 132 |
+
tmp_path = tmp.name
|
| 133 |
+
|
| 134 |
+
try:
|
| 135 |
+
raw = client.image_classification(tmp_path, model=VISION_MODEL)
|
| 136 |
+
finally:
|
| 137 |
+
os.unlink(tmp_path)
|
| 138 |
+
|
| 139 |
+
results: list[dict[str, Any]] = []
|
| 140 |
+
for item in raw[:TOP_K]:
|
| 141 |
+
if isinstance(item, dict):
|
| 142 |
+
results.append({"label": item["label"], "score": float(item["score"])})
|
| 143 |
+
else:
|
| 144 |
+
results.append({"label": item.label, "score": float(item.score)})
|
| 145 |
+
return results
|
| 146 |
+
|
| 147 |
+
|
| 148 |
+
# -----------------------------------------------------------------------------
|
| 149 |
+
# Step 2: ์นผ๋ก๋ฆฌ/์์์ ์ถ์ (LCEL ์ฒด์ธ)
|
| 150 |
+
# -----------------------------------------------------------------------------
|
| 151 |
+
def estimate_calories(labels: list[dict[str, Any]]) -> dict[str, Any]:
|
| 152 |
+
chain = _chain_lazy()
|
| 153 |
+
labels_json = json.dumps(labels, ensure_ascii=False)
|
| 154 |
+
try:
|
| 155 |
+
chain = _chain_lazy()
|
| 156 |
+
labels_json = json.dumps(labels, ensure_ascii=False)
|
| 157 |
+
return chain.invoke({"labels_json": labels_json})
|
| 158 |
+
except Exception as e:
|
| 159 |
+
return {
|
| 160 |
+
"food": labels[0]["label"] if labels else "unknown",
|
| 161 |
+
"confidence": labels[0]["score"] if labels else 0.0,
|
| 162 |
+
"calories_kcal": 0,
|
| 163 |
+
"carbs_g": 0,
|
| 164 |
+
"protein_g": 0,
|
| 165 |
+
"fat_g": 0,
|
| 166 |
+
"note": f"์ฒด์ธ ์คํ ์คํจ: {type(e).__name__}: {str(e)[:120]}",
|
| 167 |
+
}
|
| 168 |
+
|
| 169 |
+
|
| 170 |
+
# -----------------------------------------------------------------------------
|
| 171 |
+
# Step 3: Gradio ์ฝ๋ฐฑ
|
| 172 |
+
# -----------------------------------------------------------------------------
|
| 173 |
+
def analyze(image):
|
| 174 |
+
if image is None:
|
| 175 |
+
return {}, {"error": "์ด๋ฏธ์ง๋ฅผ ๋จผ์ ์
๋ก๋ํด ์ฃผ์ธ์."}
|
| 176 |
+
labels = classify_food(image)
|
| 177 |
+
label_view = {item["label"]: item["score"] for item in labels}
|
| 178 |
+
nutrition = estimate_calories(labels)
|
| 179 |
+
return label_view, nutrition
|
| 180 |
+
|
| 181 |
+
|
| 182 |
+
# -----------------------------------------------------------------------------
|
| 183 |
+
# Step 4: UI
|
| 184 |
+
# -----------------------------------------------------------------------------
|
| 185 |
+
def build_ui() -> gr.Interface:
|
| 186 |
+
return gr.Interface(
|
| 187 |
+
fn=analyze,
|
| 188 |
+
inputs=gr.Image(type="pil", label="์์ ์ฌ์ง ์
๋ก๋"),
|
| 189 |
+
outputs=[
|
| 190 |
+
gr.Label(num_top_classes=TOP_K, label="์์ ๋ถ๋ฅ ๊ฒฐ๊ณผ"),
|
| 191 |
+
gr.JSON(label="์นผ๋ก๋ฆฌ & ์์์ ์ถ์ "),
|
| 192 |
+
],
|
| 193 |
+
title="๐ฑ HuggingFace Calorie Counter (LangChain LCEL)",
|
| 194 |
+
description=(
|
| 195 |
+
"์์ ์ฌ์ง์ ์
๋ก๋ํ๋ฉด HF Inference API๋ก ์์์ ์ธ์ํ๊ณ , "
|
| 196 |
+
"LangChain LCEL ์ฒด์ธ์ด 1์ธ๋ถ ๊ธฐ์ค ์นผ๋ก๋ฆฌ/์์์๋ฅผ ์ถ์ ํฉ๋๋ค. "
|
| 197 |
+
"๊ฒฐ๊ณผ๋ ์ฐธ๊ณ ์ฉ์
๋๋ค."
|
| 198 |
+
),
|
| 199 |
+
flagging_mode="never",
|
| 200 |
+
)
|
| 201 |
+
|
| 202 |
+
|
| 203 |
+
# ๋ชจ๋ ๋ ๋ฒจ demo (Space/HF ๋ฐํ์ ํธํ)
|
| 204 |
+
demo = build_ui()
|
| 205 |
+
|
| 206 |
+
if __name__ == "__main__":
|
| 207 |
+
# HF Space์์๋ SPACE_ID ํ๊ฒฝ๋ณ์๊ฐ ์ค์ ๋ผ ์์ด 0.0.0.0 ๋ฐ์ธ๋ฉ์ด ํ์ํ๋ค.
|
| 208 |
+
# ๋ก์ปฌ์์๋ 127.0.0.1.
|
| 209 |
+
is_space = bool(os.getenv("SPACE_ID"))
|
| 210 |
+
demo.launch(
|
| 211 |
+
server_name="0.0.0.0" if is_space else "127.0.0.1",
|
| 212 |
+
server_port=int(os.getenv("PORT", 7860)),
|
| 213 |
+
show_api=False,
|
| 214 |
+
ssr_mode=False,
|
| 215 |
+
)
|
calcal/.gitattributes
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
calcal/README.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: Calcal
|
| 3 |
+
emoji: ๐
|
| 4 |
+
colorFrom: pink
|
| 5 |
+
colorTo: blue
|
| 6 |
+
sdk: gradio
|
| 7 |
+
sdk_version: 6.11.0
|
| 8 |
+
app_file: app.py
|
| 9 |
+
pinned: false
|
| 10 |
+
license: apache-2.0
|
| 11 |
+
short_description: Calorie Calculator
|
| 12 |
+
---
|
| 13 |
+
|
| 14 |
+
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
images/01_main.png
ADDED
|
Git LFS Details
|
images/02_models.png
ADDED
|
Git LFS Details
|
images/03_model_card.png
ADDED
|
Git LFS Details
|
images/04_spaces.png
ADDED
|
Git LFS Details
|
images/05_tokens.png
ADDED
|
Git LFS Details
|
images/06_new_space.png
ADDED
|
Git LFS Details
|
images/07_secrets.png
ADDED
|
images/08_files.png
ADDED
|
images/09_app_logs.png
ADDED
|
Git LFS Details
|
images/10_write_token.png
ADDED
|
Git LFS Details
|
images/11_running.png
ADDED
|
model_config.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
6์ฃผ์ฐจ ๋ชจ๋ธ ์ค์ โ HuggingFace Inference API
|
| 3 |
+
===========================================
|
| 4 |
+
ํ ํฐ์ .env ์ HF_TOKEN ๋๋ HUGGINGFACEHUB_API_TOKEN ์์ ์ฝ๋๋ค.
|
| 5 |
+
HF Space์ ๋ฐฐํฌํ ๋๋ Settings > Secrets ์ HF_TOKEN ์ ๋ฑ๋กํ๋ค.
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
from __future__ import annotations
|
| 9 |
+
|
| 10 |
+
import os
|
| 11 |
+
|
| 12 |
+
from huggingface_hub import InferenceClient
|
| 13 |
+
|
| 14 |
+
# ์์ ์ด๋ฏธ์ง ๋ถ๋ฅ (ViT, food-101 ํ์ธํ๋)
|
| 15 |
+
VISION_MODEL = "nateraw/food"
|
| 16 |
+
|
| 17 |
+
# ์นผ๋ก๋ฆฌ/์์์ ์ถ์ ์ฉ ํ
์คํธ LLM
|
| 18 |
+
LLM_MODEL = "meta-llama/Meta-Llama-3-8B-Instruct"
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def get_token() -> str:
|
| 22 |
+
token = os.getenv("HF_TOKEN") or os.getenv("HUGGINGFACEHUB_API_TOKEN")
|
| 23 |
+
if not token:
|
| 24 |
+
raise SystemExit(
|
| 25 |
+
"HF_TOKEN(๋๋ HUGGINGFACEHUB_API_TOKEN) ํ๊ฒฝ๋ณ์๊ฐ ๋น์ด ์์ต๋๋ค.\n"
|
| 26 |
+
" 1) https://huggingface.co/settings/tokens ์์ Read ํ ํฐ ๋ฐ๊ธ\n"
|
| 27 |
+
" 2) .env ์ HF_TOKEN=hf_xxx ์ถ๊ฐ (๋ก์ปฌ)\n"
|
| 28 |
+
" 3) HF Space: Settings > Secrets ์ HF_TOKEN ๋ฑ๋ก"
|
| 29 |
+
)
|
| 30 |
+
return token
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def get_client() -> InferenceClient:
|
| 34 |
+
"""์ด๋ฏธ์ง ๋ถ๋ฅ์ฉ ํด๋ผ์ด์ธํธ."""
|
| 35 |
+
return InferenceClient(token=get_token())
|
requirements.txt
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
gradio>=5.0,<6
|
| 2 |
+
huggingface_hub>=0.24,<1.0
|
| 3 |
+
langchain>=0.3
|
| 4 |
+
langchain-core>=0.3
|
| 5 |
+
langchain-huggingface>=0.1
|
| 6 |
+
pillow>=10.0
|
| 7 |
+
python-dotenv>=1.0
|