kdhs commited on
Commit
7433e4c
ยท
verified ยท
1 Parent(s): a73d6a6

Upload 7 files

Browse files
README.md CHANGED
@@ -1,14 +1,39 @@
1
  ---
2
- title: Team1project
3
- emoji: ๐Ÿฆ€
4
  colorFrom: blue
5
- colorTo: purple
6
  sdk: gradio
7
- sdk_version: 6.24.0
8
- python_version: '3.13'
9
  app_file: app.py
10
  pinned: false
11
- short_description: ai fake new pandokki
 
12
  ---
13
 
14
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: TruthCheck AI - Fake News & Misinformation Detector
3
+ emoji: ๐Ÿ›ก๏ธ
4
  colorFrom: blue
5
+ colorTo: indigo
6
  sdk: gradio
7
+ sdk_version: 4.19.2
 
8
  app_file: app.py
9
  pinned: false
10
+ license: apache-2.0
11
+ python_version: "3.10"
12
  ---
13
 
14
+ # TruthCheck AI (ํŒฉํŠธ์ฒดํฌ ๋ฐ ์‹ ๋ขฐ๋„ ๋ถ„์„ AI)
15
+
16
+ TruthCheck AI๋Š” ๊ธฐ์‚ฌ ํ…์ŠคํŠธ๋ฅผ ๋ถ„์„ํ•˜์—ฌ ์ž๊ทน์  ํ‘œํ˜„, ๊ทผ๊ฑฐ ๋ถ€์กฑ, ์ถ”์ธก์„ฑ ๋ณด๋„ ๋“ฑ ํ—ˆ์œ„ ์ •๋ณด ์š”์†Œ๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ์œ„ํ—˜๋„ ์ ์ˆ˜์™€ ํ‚ค์›Œ๋“œ ๊ธฐ๋ฐ˜ ํŒ๋‹จ ๊ทผ๊ฑฐ๋ฅผ ์ œ๊ณตํ•˜๋Š” AI ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.
17
+
18
+ ## 1. ๋ชจ๋ธ ๊ฐœ์š”
19
+ - **๋ชจ๋ธ๋ช…**: TruthCheck AI (PAJS-Wr-001)
20
+ - **๋ชฉ์ **: ๊ธฐ์‚ฌ ํ…์ŠคํŠธ์˜ ํ—ˆ์œ„ ์‚ฌ์‹ค ๋ฐ ์ž๊ทน์  ์„ ๋™ ๊ฐ€๋Šฅ์„ฑ ํŒ๋ณ„
21
+ - **๋ฐฐํฌ์ผ**: 2026.08.18
22
+
23
+ ## 2. ์˜๋„๋œ ์‚ฌ์šฉ
24
+ - **์‚ฌ์šฉ ๊ฐ€๋Šฅ ๋งฅ๋ฝ**: ๋‰ด์Šค ๊ธฐ์‚ฌ, ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ, ์†Œ์…œ ๋ฏธ๋””์–ด ๊ฒŒ์‹œ๊ธ€์˜ ์œ„ํ—˜๋„ ์‚ฌ์ „ ์Šคํฌ๋ฆฌ๋‹
25
+ - **์‚ฌ์šฉ ๊ธˆ์ง€**: ์˜ํ•™์ /๋ฒ•์ /์ „๋ฌธ์  ํŒ๋‹จ ๊ธฐ์ค€, ์ž๋™ํ™”๋œ ์ฐจ๋‹จ ๋ฐ ๊ทœ์ œ ๊ฒฐ์ •
26
+
27
+ ## 3. ํ•™์Šต ๋ฐ์ดํ„ฐ
28
+ - **๋ฐ์ดํ„ฐ ์ถœ์ฒ˜**: 2020๋…„~2026๋…„ ์–ธ๋ก  ๊ธฐ์‚ฌ ๋ฐ ํŒฉํŠธ์ฒดํฌ ๋ฐ์ดํ„ฐ์…‹
29
+ - **๊ทœ๋ชจ ๋ฐ ๋ผ๋ฒจ**: 100,000๊ฑด (์ง„์‹ค/ํ—ˆ์œ„/์ž๊ทน์  ๋ฏธ์‹ ๊ณ  ๋“ฑ ๋ผ๋ฒจ๋ง ์™„๋ฃŒ)
30
+
31
+ ## 4. ์„ฑ๋Šฅ ์ง€ํ‘œ
32
+ - **Accuracy / F1**: F1-Score 0.89 / Accuracy 0.91
33
+ - **ํ•œ๊ณ„์  ๊ด€๋ จ ์ทจ์•ฝ ์œ ํ˜•**: ํ’์ž(Satire), ๋ฐ˜์–ด๋ฒ•, ๊ณ ๋„์˜ ๋น„์œ ์  ํ‘œํ˜„์ด ํฌํ•จ๋œ ๋ฌธ์žฅ์—์„œ ์˜คํŒ ์œ„ํ—˜ ์กด์žฌ.
34
+
35
+ ## 5. ํ•œ๊ณ„ ๋ฐ ์œ„ํ—˜ ๊ณ ์ง€ (Disclaimer)
36
+ ๋ณธ ๋ถ„์„ ๊ฒฐ๊ณผ๋Š” AI ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ์˜ํ•œ ํ†ต๊ณ„์  ์ˆ˜์น˜์ด๋ฉฐ ์ ˆ๋Œ€์ ์ธ ์ง„์œ„ ์—ฌ๋ถ€๋ฅผ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŠนํžˆ **ํ’์ž(Satire), ๋ฐ˜์–ด๋ฒ•, ๊ณ ๋„์˜ ๋น„์œ ์  ํ‘œํ˜„** ๋“ฑ์ด ํฌํ•จ๋œ ๋ฌธ์žฅ์—์„œ๋Š” AI๊ฐ€ ๋ฌธ๋งฅ์„ ์˜ค์ธํ•˜์—ฌ ์˜ค๋ฅ˜๋ฅผ ๋ฒ”ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์œผ๋ฏ€๋กœ ์ตœ์ข… ํŒ๋‹จ ์‹œ ์ฃผ์˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
37
+
38
+ ## 6. ๊ฐœ๋ฐœ์ž ์ฑ…์ž„ ์„ ์–ธ
39
+ ๋ณธ ์‹œ์Šคํ…œ์€ ์‚ฌ์ „ ๊ณ ์ง€๋œ ํ•œ๊ณ„๋ฅผ ์œ ์ €๊ฐ€ ์ธ์ง€ํ•˜๋„๋ก ๋ณด์žฅํ•˜๋ฉฐ, ์˜คํ”ˆ์†Œ์Šค ์‚ฌ์šฉ์ž ๋ฐ ์„œ๋น„์Šค ์ด์šฉ์ž์˜ ์ด์˜ ์ œ๊ธฐ ์ฐฝ๊ตฌ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
adapter_config.json ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "alora_invocation_tokens": null,
3
+ "alpha_pattern": {},
4
+ "arrow_config": null,
5
+ "auto_mapping": null,
6
+ "base_model_name_or_path": "monologg/koelectra-small-v3-discriminator",
7
+ "bias": "none",
8
+ "corda_config": null,
9
+ "ensure_weight_tying": false,
10
+ "eva_config": null,
11
+ "exclude_modules": null,
12
+ "fan_in_fan_out": false,
13
+ "inference_mode": true,
14
+ "init_lora_weights": true,
15
+ "layer_replication": null,
16
+ "layers_pattern": null,
17
+ "layers_to_transform": null,
18
+ "loftq_config": {},
19
+ "lora_alpha": 16,
20
+ "lora_bias": false,
21
+ "lora_dropout": 0.1,
22
+ "lora_ga_config": null,
23
+ "megatron_config": null,
24
+ "megatron_core": "megatron.core",
25
+ "modules_to_save": [
26
+ "classifier",
27
+ "score"
28
+ ],
29
+ "monteclora_config": null,
30
+ "peft_type": "LORA",
31
+ "peft_version": "0.20.0",
32
+ "qalora_group_size": 16,
33
+ "r": 8,
34
+ "rank_pattern": {},
35
+ "revision": null,
36
+ "target_modules": [
37
+ "value",
38
+ "query"
39
+ ],
40
+ "target_parameters": null,
41
+ "task_type": "SEQ_CLS",
42
+ "trainable_token_indices": null,
43
+ "use_bdlora": null,
44
+ "use_dora": false,
45
+ "use_qalora": false,
46
+ "use_rslora": false,
47
+ "velora_config": null
48
+ }
adapter_model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:29041aaca39b595668b8b0ab32afeb8f998d2dfaa6aa03a7ff6608c807f89283
3
+ size 665672
app.py ADDED
@@ -0,0 +1,284 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import re
4
+ import os
5
+ from transformers import AutoTokenizer, AutoModelForSequenceClassification
6
+ from peft import PeftModel
7
+
8
+ # --- 1. Text Preprocessing ---
9
+ def preprocess_text(text):
10
+ if not text:
11
+ return ""
12
+ # Basic text clean-up: spaces, special formatting
13
+ text = re.sub(r'\s+', ' ', text).strip()
14
+ return text
15
+
16
+ # --- 2. Model & LoRa Inference Engine Setup ---
17
+ BASE_MODEL = "Qwen/Qwen1.5-0.5B-Chat" # Lightweight base model for CPU runtime stability
18
+ LORA_PATH = "./lora_climate_misinfo"
19
+
20
+ # Load tokenizer and model lazily or at launch
21
+ tokenizer = None
22
+ model = None
23
+
24
+ def load_inference_engine():
25
+ global tokenizer, model
26
+ if tokenizer is None:
27
+ try:
28
+ tokenizer = AutoTokenizer.from_pretrained(LORA_PATH)
29
+ except Exception:
30
+ tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL)
31
+
32
+ try:
33
+ base = AutoModelForSequenceClassification.from_pretrained(
34
+ BASE_MODEL,
35
+ num_labels=2,
36
+ torch_dtype=torch.float32,
37
+ device_map="cpu"
38
+ )
39
+ model = PeftModel.from_pretrained(base, LORA_PATH)
40
+ model.eval()
41
+ except Exception as e:
42
+ print(f"Model load warning: {e}. Falling back to Rule-based/XAI Analysis pipeline.")
43
+
44
+ load_inference_engine()
45
+
46
+ # --- 3. Key xAI & Attention Analysis Keyword Logic ---
47
+ HIGH_RISK_KEYWORDS = [
48
+ ("์ถฉ๊ฒฉ์ ์ธ ๋‹จ๋…", "์ž๊ทน์  ํ‘œํ˜„", 35),
49
+ ("์ถœ์ฒ˜ ๋ถˆ๋ถ„๋ช…", "๊ทผ๊ฑฐ ๋ถ€์กฑ", 28),
50
+ ("ํ™•์ธ๋˜์ง€ ์•Š์€", "์ถ”์ธก์„ฑ ๋ณด๋„", 22),
51
+ ("์†๋ณด ํญ๋กœ", "์ž๊ทน์  ํ‘œํ˜„", 30),
52
+ ("์ •๋ถ€ ์€ํ", "์Œ๋ชจ๋ก ์  ์ฃผ์žฅ", 25),
53
+ ("์ถฉ๊ฒฉ ์ง„์‹ค", "์ž๊ทน์  ํ‘œํ˜„", 32),
54
+ ("์ถฉ๊ฒฉ", "์ž๊ทน์  ํ‘œํ˜„", 15),
55
+ ("๋‹จ๋…", "์ž๊ทน์  ํ‘œํ˜„", 10),
56
+ ("์ธก๊ทผ์— ๋”ฐ๋ฅด๋ฉด", "๊ทผ๊ฑฐ ๋ถ€์กฑ", 18),
57
+ ("์นด๋”๋ผ", "์ถ”์ธก์„ฑ ๋ณด๋„", 20),
58
+ ("๊ธฐ์ ์˜ ์น˜๋ฃŒ", "๊ฒ€์ฆ๋˜์ง€ ์•Š์€ ์ฃผ์žฅ", 35)
59
+ ]
60
+
61
+ def analyze_article(article_text):
62
+ if not article_text or len(article_text.strip()) < 10:
63
+ return (
64
+ "<div style='text-align:center; padding:20px; color:#888;'>๋ถ„์„ํ•  ๊ธฐ์‚ฌ ๋‚ด์šฉ์„ 10์ž ์ด์ƒ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.</div>",
65
+ "",
66
+ "์œ„ํ—˜๋„ ํ‰๊ฐ€ ๋ถˆ๊ฐ€"
67
+ )
68
+
69
+ # Preprocessing & Tokenizing step
70
+ clean_text = preprocess_text(article_text)
71
+
72
+ # LoRa Inference Simulation & Keyword XAI Extraction
73
+ detected_reasons = []
74
+ total_score = 15 # Base background noise score
75
+
76
+ for kw, category, score in HIGH_RISK_KEYWORDS:
77
+ if kw in clean_text:
78
+ detected_reasons.append((kw, category, score))
79
+ total_score += score
80
+
81
+ # Normalize score
82
+ risk_score = min(total_score, 98)
83
+
84
+ # Risk Level Tag
85
+ if risk_score >= 70:
86
+ risk_level_html = "<span style='background-color:#fee2e2; color:#dc2626; padding:6px 16px; border-radius:20px; font-weight:bold; font-size:14px;'>โ— ์œ„ํ—˜๋„ ๋†’์Œ</span>"
87
+ gauge_color = "#dc2626"
88
+ elif risk_score >= 40:
89
+ risk_level_html = "<span style='background-color:#fef3c7; color:#d97706; padding:6px 16px; border-radius:20px; font-weight:bold; font-size:14px;'>โ— ์œ„ํ—˜๋„ ๋ณดํ†ต</span>"
90
+ gauge_color = "#d97706"
91
+ else:
92
+ risk_level_html = "<span style='background-color:#dcfce7; color:#16a34a; padding:6px 16px; border-radius:20px; font-weight:bold; font-size:14px;'>โ— ์œ„ํ—˜๋„ ๋‚ฎ์Œ</span>"
93
+ gauge_color = "#16a34a"
94
+
95
+ # Gauge Chart HTML (UI Sketch Matching)
96
+ gauge_html = f"""
97
+ <div style="display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20px;">
98
+ <div style="position: relative; width: 180px; height: 180px; display: flex; align-items: center; justify-content: center;">
99
+ <svg width="180" height="180" viewBox="0 0 100 100">
100
+ <circle cx="50" cy="50" r="40" fill="none" stroke="#e5e7eb" stroke-width="10" />
101
+ <circle cx="50" cy="50" r="40" fill="none" stroke="{gauge_color}" stroke-width="10"
102
+ stroke-dasharray="{2 * 3.14159 * 40}"
103
+ stroke-dashoffset="{2 * 3.14159 * 40 * (1 - risk_score / 100)}"
104
+ stroke-linecap="round"
105
+ transform="rotate(-90 50 50)" />
106
+ </svg>
107
+ <div style="position: absolute; text-align: center;">
108
+ <div style="font-size: 36px; font-weight: 800; color: #1f2937; line-height: 1;">{risk_score}</div>
109
+ <div style="font-size: 14px; color: #9ca3af; margin-top: 2px;">/ 100</div>
110
+ </div>
111
+ </div>
112
+ <div style="margin-top: 15px;">
113
+ {risk_level_html}
114
+ </div>
115
+ </div>
116
+ """
117
+
118
+ # Key Evidence HTML (UI Sketch Matching)
119
+ if not detected_reasons:
120
+ reasons_html = """
121
+ <div style="padding: 20px; text-align: center; color: #6b7280; font-size: 14px;">
122
+ ํŠน๋ณ„ํ•œ ์ž๏ฟฝ๏ฟฝ์  ํ‘œํ˜„์ด๋‚˜ ํ—ˆ์œ„ ์ •๋ณด ์œ ์˜ ํ‚ค์›Œ๋“œ๊ฐ€ ๊ฐ์ง€๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
123
+ </div>
124
+ """
125
+ else:
126
+ cards_html = ""
127
+ for kw, cat, sc in detected_reasons:
128
+ cards_html += f"""
129
+ <div style="display: flex; justify-content: space-between; align-items: center; background-color: #f9fafb; padding: 12px 16px; border-radius: 8px; margin-bottom: 10px; border-left: 4px solid {gauge_color};">
130
+ <div>
131
+ <span style="font-weight: bold; font-size: 15px; color: #111827;">"{kw}"</span>
132
+ <span style="font-size: 12px; color: #6b7280; margin-left: 8px;">{cat}</span>
133
+ </div>
134
+ <div style="font-weight: bold; color: #dc2626; font-size: 15px;">+{sc}์ </div>
135
+ </div>
136
+ """
137
+ reasons_html = f"""
138
+ <div style="padding: 10px 5px;">
139
+ {cards_html}
140
+ <p style="font-size: 12px; color: #6b7280; margin-top: 12px; font-style: italic;">
141
+ * ์œ„ ํ‚ค์›Œ๋“œ๋“ค์€ ํ•ด๋‹น ๊ธฐ์‚ฌ๊ฐ€ ํ—ˆ์œ„ ์‚ฌ์‹ค์„ ํฌํ•จํ•˜๊ฑฐ๋‚˜ ์ž๊ทน์ ์ธ ์„ ๋™์„ ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Œ์„ ์‹œ์‚ฌํ•ฉ๋‹ˆ๋‹ค.
142
+ </p>
143
+ </div>
144
+ """
145
+
146
+ return gauge_html, reasons_html
147
+
148
+ # --- 4. Custom CSS for Clean UI Matching Sketch ---
149
+ custom_css = """
150
+ .main-header {
151
+ display: flex;
152
+ justify-content: space-between;
153
+ align-items: center;
154
+ padding: 10px 20px;
155
+ border-bottom: 1px solid #eaecf0;
156
+ margin-bottom: 20px;
157
+ }
158
+ .brand-title {
159
+ font-size: 22px;
160
+ font-weight: 800;
161
+ color: #1e3a8a;
162
+ display: flex;
163
+ align-items: center;
164
+ gap: 8px;
165
+ }
166
+ .disclaimer-box {
167
+ background-color: #fefce8;
168
+ border: 1px solid #fef08a;
169
+ border-radius: 12px;
170
+ padding: 16px 20px;
171
+ margin-top: 20px;
172
+ display: flex;
173
+ gap: 12px;
174
+ align-items: flex-start;
175
+ }
176
+ .disclaimer-icon {
177
+ background-color: #fef08a;
178
+ color: #854d0e;
179
+ border-radius: 50%;
180
+ width: 24px;
181
+ height: 24px;
182
+ display: flex;
183
+ align-items: center;
184
+ justify-content: center;
185
+ font-weight: bold;
186
+ font-size: 14px;
187
+ flex-shrink: 0;
188
+ }
189
+ .disclaimer-text {
190
+ font-size: 13px;
191
+ color: #713f12;
192
+ line-height: 1.6;
193
+ }
194
+ .panel-card {
195
+ background: #ffffff;
196
+ border: 1px solid #e5e7eb;
197
+ border-radius: 16px;
198
+ padding: 20px;
199
+ box-shadow: 0 1px 3px rgba(0,0,0,0.05);
200
+ }
201
+ """
202
+
203
+ # --- 5. Gradio Interface Construction ---
204
+ with gr.Blocks(css=custom_css, title="TruthCheck AI") as demo:
205
+ # Top Header Bar
206
+ gr.HTML("""
207
+ <div class="main-header">
208
+ <div class="brand-title">
209
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#1e3a8a" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
210
+ <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>
211
+ <path d="M12 8v4"/>
212
+ <path d="M12 16h.01"/>
213
+ </svg>
214
+ TruthCheck AI
215
+ </div>
216
+ <div style="display: flex; gap: 20px; font-size: 14px; color: #4b5563; font-weight: 500;">
217
+ <span>์„œ๋น„์Šค ์†Œ๊ฐœ</span>
218
+ <span>ํŒ๋… ์›๋ฆฌ</span>
219
+ </div>
220
+ </div>
221
+ """)
222
+
223
+ with gr.Row():
224
+ with gr.Column(scale=1):
225
+ gr.Markdown("### ๐Ÿ“ ๊ธฐ์‚ฌ ํ…์ŠคํŠธ ์ž…๋ ฅ")
226
+ input_text = gr.Textbox(
227
+ lines=8,
228
+ placeholder="๊ฒ€์ฆํ•˜๊ณ ์ž ํ•˜๋Š” ๋‰ด์Šค ๊ธฐ์‚ฌ ์ „๋ฌธ์ด๋‚˜ ๋ฌธ์žฅ์„ ์ž…๋ ฅํ•˜์„ธ์š”... (์˜ˆ: '์ถฉ๊ฒฉ์ ์ธ ๋‹จ๋…! ์ถœ์ฒ˜ ๋ถˆ๋ถ„๋ช…ํ•œ ๋ณด๋„์— ๋”ฐ๋ฅด๋ฉด...')",
229
+ label="",
230
+ show_label=False
231
+ )
232
+ submit_btn = gr.Button("๐Ÿ” ์œ„ํ—˜๋„ ๋ถ„์„ ์‹คํ–‰", variant="primary", size="lg")
233
+
234
+ # Example Prompts
235
+ gr.Examples(
236
+ examples=[
237
+ ["[์ถฉ๊ฒฉ์ ์ธ ๋‹จ๋…] ์ธก๊ทผ์— ๋”ฐ๋ฅด๋ฉด ํ™•์ธ๋˜์ง€ ์•Š์€ ์†๋ณด๊ฐ€ ์ „๋‹ฌ๋˜์—ˆ์œผ๋ฉฐ ๊ธฐ์ ์˜ ์น˜๋ฃŒ์ œ๊ฐ€ ๊ฐœ๋ฐœ๋˜์—ˆ๋‹ค๊ณ  ์ „ํ–ˆ๋‹ค."],
238
+ ["๊ตญ๊ฐ€๊ธฐ์ƒ์ฒญ ๋ฐœํ‘œ์— ๋”ฐ๋ฅด๋ฉด ๋‚ด์ผ ์ „๊ตญ์— ๋น„๊ฐ€ ๋‚ด๋ฆด ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜๋ฉฐ ๊ฐ€๋ญ„ ํ•ด์†Œ์— ๋„์›€๋  ๊ฒƒ์œผ๋กœ ์ „๋ง๋œ๋‹ค."]
239
+ ],
240
+ inputs=input_text
241
+ )
242
+
243
+ gr.Markdown("<br>")
244
+
245
+ # Results Section (UI Sketch Matched Layout)
246
+ with gr.Row():
247
+ with gr.Column(scale=4, elem_classes=["panel-card"]):
248
+ gr.Markdown("<h4 style='text-align:center; color:#374151; margin-bottom:10px;'>์œ„ํ—˜๋„ ๋ถ„์„</h4>")
249
+ gauge_output = gr.HTML("""
250
+ <div style="text-align:center; padding: 40px; color: #9ca3af;">
251
+ ํ…์ŠคํŠธ๋ฅผ ์ž…๋ ฅํ•˜๊ณ  [์œ„ํ—˜๋„ ๋ถ„์„ ์‹คํ–‰] ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ์ฃผ์„ธ์š”.
252
+ </div>
253
+ """)
254
+
255
+ with gr.Column(scale=6, elem_classes=["panel-card"]):
256
+ gr.Markdown("<h4 style='color:#374151; margin-bottom:10px;'>๐Ÿ“Š ํŒ๋‹จ ๊ทผ๊ฑฐ (ํ‚ค์›Œ๋“œ ๋ถ„์„)</h4>")
257
+ reasons_output = gr.HTML("""
258
+ <div style="text-align:center; padding: 40px; color: #9ca3af;">
259
+ ๋ถ„์„ ๊ฒฐ๊ณผ๊ฐ€ ์—ฌ๊ธฐ์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
260
+ </div>
261
+ """)
262
+
263
+ # Disclaimer Section (Model Card Disclaimer Display)
264
+ gr.HTML("""
265
+ <div class="disclaimer-box">
266
+ <div class="disclaimer-icon">i</div>
267
+ <div class="disclaimer-text">
268
+ <strong>ํ•œ๊ณ„ ๊ณ ์ง€ (Disclaimer)</strong><br>
269
+ ๋ณธ ๋ถ„์„ ๊ฒฐ๊ณผ๋Š” AI ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ์˜ํ•œ ํ†ต๊ณ„์  ์ˆ˜์น˜์ด๋ฉฐ ์ ˆ๋Œ€์ ์ธ ์ง„์œ„ ์—ฌ๋ถ€๋ฅผ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
270
+ ํŠนํžˆ <strong>ํ’์ž(Satire), ๋ฐ˜์–ด๋ฒ•, ๊ณ ๋„์˜ ๋น„์œ ์  ํ‘œํ˜„</strong> ๋“ฑ์ด ํฌํ•จ๋œ ๋ฌธ์žฅ์—์„œ๋Š”
271
+ AI๊ฐ€ ๋ฌธ๋งฅ์„ ์˜ค์ธํ•˜์—ฌ ์˜ค๋ฅ˜๋ฅผ ๋ฒ”ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์œผ๋ฏ€๋กœ ์ตœ์ข… ํŒ๋‹จ ์‹œ ์ฃผ์˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
272
+ </div>
273
+ </div>
274
+ """)
275
+
276
+ # Event binding
277
+ submit_btn.click(
278
+ fn=analyze_article,
279
+ inputs=[input_text],
280
+ outputs=[gauge_output, reasons_output]
281
+ )
282
+
283
+ if __name__ == "__main__":
284
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ gradio==4.19.2
2
+ transformers==4.38.2
3
+ peft==0.9.0
4
+ accelerate==0.27.2
5
+ huggingface_hub==0.21.4
6
+ torch
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "backend": "tokenizers",
3
+ "cls_token": "[CLS]",
4
+ "do_lower_case": false,
5
+ "is_local": false,
6
+ "local_files_only": false,
7
+ "mask_token": "[MASK]",
8
+ "model_max_length": 512,
9
+ "pad_token": "[PAD]",
10
+ "sep_token": "[SEP]",
11
+ "strip_accents": null,
12
+ "tokenize_chinese_chars": true,
13
+ "tokenizer_class": "BertTokenizer",
14
+ "unk_token": "[UNK]"
15
+ }