machinelearnAn commited on
Commit
4b7d152
·
verified ·
1 Parent(s): e745396

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +78 -95
src/streamlit_app.py CHANGED
@@ -1,113 +1,96 @@
1
  # app.py
2
  import streamlit as st
 
 
3
 
4
- # --- Dữ liệu Demo (Chuẩn bị sẵn) ---
5
- # Dữ liệu này được lấy sẵn để demo nhanh và ổn định.
6
- DEMO_DATA = {
7
- "Ví dụ 1: Dấu hiệu trầm cảm ràng": {
8
- "post": "Lately, I just feel so empty and numb inside. Nothing brings me joy anymore, not even the things I used to love. It's a struggle just to get out of bed.",
9
- "mentallama_output": {
10
- "answer": "Depression",
11
- "reasoning": "The post conveys a deep sense of emotional numbness, loss of interest (anhedonia), and lack of motivation, which are core symptoms of depression."
12
- },
13
- "mentalroberta_output": "Depression"
14
- },
15
- "Ví dụ 2: Dấu hiệu stress tinh tế": {
16
- "post": "Another sleepless night. My mind just won't shut off. I feel so tired but I can't rest. Work is piling up and I just don't have the energy to face it.",
17
- "mentallama_output": {
18
- "answer": "Stress",
19
- "reasoning": "The user mentions sleepless nights, a racing mind, and feeling overwhelmed by work. These are classic indicators of high stress levels."
20
- },
21
- "mentalroberta_output": "Stress"
22
- },
23
- "Ví dụ 3: Bài đăng tích cực, không có vấn đề": {
24
- "post": "Just finished a great hike with friends! The view from the top was incredible. Feeling so refreshed and happy.",
25
- "mentallama_output": {
26
- "answer": "None",
27
- "reasoning": "The post expresses positive emotions, mentions social activity (hiking with friends), and feelings of refreshment. There are no indicators of mental distress."
28
- },
29
- "mentalroberta_output": "None"
30
- },
31
- "Ví dụ 4: Tự tử (Nghiêm trọng)": {
32
- "post": "I can't take this pain anymore. I've been thinking about ending it all. It feels like the only way out.",
33
- "mentallama_output": {
34
- "answer": "Suicide",
35
- "reasoning": "The post contains explicit suicidal ideation ('thinking about ending it all') and expresses feelings of unbearable pain and hopelessness, indicating a high-risk situation."
36
- },
37
- "mentalroberta_output": "Suicide"
38
  }
39
- }
40
-
41
- # --- Giao diện ứng dụng Streamlit ---
42
- st.set_page_config(layout="wide", page_title="MentaLLaMA Demo")
43
 
44
- # Header
45
- st.title("🔬 Demo: MentaLLaMA - Phân Tích Sức Khỏe Tâm Thần Có Thể Giải Thích")
46
- st.markdown("""
47
- Chào mừng đến với bản demo của **MentaLLaMA**!
 
 
 
48
 
49
- Demo này minh họa sự khác biệt cốt lõi giữa:
50
- 1. **Phương pháp truyền thống "Hộp đen"** (như MentalRoBERTa): Chỉ đưa ra dự đoán.
51
- 2. **MentaLLaMA**: Đưa ra cả dự đoán và **lời giải thích chi tiết**.
52
 
53
- *Lưu ý: Demo này sử dụng kết quả được tạo sẵn để đảm bảo tốc độ và sự ổn định.*
54
- """)
55
 
56
- # --- Phần tương tác ---
57
- st.sidebar.header("Bảng điều khiển")
58
- option = st.sidebar.selectbox(
59
- 'Chọn một bài đăng mẫu để phân tích:',
60
- list(DEMO_DATA.keys()),
61
- index=0
62
- )
63
 
64
- # Hiển thị bài đăng được chọn
65
- selected_example = DEMO_DATA[option]
66
- post_text = selected_example["post"]
67
 
68
- st.subheader("📝 Nội dung bài đăng được chọn:")
69
- st.info(post_text)
 
 
 
 
 
70
 
71
- # Nút phân tích
72
- if st.sidebar.button('Chạy Phân Tích So Sánh', type="primary"):
73
- st.header("📊 Kết quả phân tích so sánh")
74
 
75
- col1, col2 = st.columns(2, gap="large")
 
 
 
 
 
 
 
76
 
77
- # Cột 1: Phương pháp truyền thống (Hộp đen)
78
- with col1:
79
- st.subheader("Mô hình 'Hộp đen' (ví dụ: MentalRoBERTa)")
80
-
81
- st.metric(label="Dự đoán", value=selected_example['mentalroberta_output'])
82
-
83
- with st.expander("Phân tích về phương pháp này", expanded=True):
84
- st.warning("⚠️ **Không có lời giải thích!**")
85
- st.write("""
86
- Mô hình chỉ đưa ra kết quả cuối cùng. Chúng ta không biết **tại sao** nó lại đưa ra dự đoán này.
87
- - **Khó tin tưởng:** Làm sao để chắc chắn nó không mắc sai lầm?
88
- - **Khó xác thực:** Bác sĩ không có cơ sở để kiểm tra lại logic của AI.
89
- - **Rủi ro cao:** Trong lĩnh vực y tế, một quyết định không thể giải thích là rất nguy hiểm.
90
- """)
91
 
92
- # Cột 2: MentaLLaMA (Giải thích được)
93
- with col2:
94
- st.subheader("MentaLLaMA (Mô hình giải thích được)")
95
-
96
- st.metric(label="Dự đoán", value=selected_example['mentallama_output']['answer'])
97
-
98
- st.write("**Lý do giải thích (Reasoning):**")
99
- st.success(f"“{selected_example['mentallama_output']['reasoning']}”")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
- with st.expander("Phân tích về phương pháp này", expanded=True):
102
- st.info("💡 **Cung cấp lý do chi tiết!**")
103
- st.write("""
104
- MentaLLaMA không chỉ dự đoán còn chỉ ra các **bằng chứng cụ thể** trong văn bản.
105
- - **Tăng sự tin tưởng:** Lời giải thích hợp lý giúp chúng ta tin vào kết quả.
106
- - **Hỗ trợ chuyên gia:** Bác sĩ có thể nhanh chóng xác thực logic và đưa ra quyết định cuối cùng.
107
- - **An toàn hơn:** Sự minh bạch giúp giảm thiểu rủi ro và tăng tính trách nhiệm.
108
- """)
109
- else:
110
- st.info("Hãy chọn một ví dụ và nhấn nút 'Chạy Phân Tích So Sánh' ở thanh bên trái.")
111
 
112
  # Footer
113
  st.markdown("---")
 
1
  # app.py
2
  import streamlit as st
3
+ import torch
4
+ from transformers import AutoTokenizer, AutoModelForCausalLM
5
 
6
+ # --- Tối ưu hóa: Tải hình chỉ một lần duy nhất ---
7
+ # @st.cache_resource một "bảo bối" của Streamlit.
8
+ # đảm bảo hàm này chỉ chạy một lần khi ứng dụng khởi động.
9
+ # Lần sau khi người dùng tương tác, hình đã có sẵn trong bộ nhớ.
10
+ @st.cache_resource
11
+ def load_model():
12
+ model_id = "SteveKGYang/MentaLLaMA-chat-7B"
13
+
14
+ # Cấu hình Quantization 4-bit để giảm RAM
15
+ bnb_config = {
16
+ "load_in_4bit": True,
17
+ "bnb_4bit_quant_type": "nf4",
18
+ "bnb_4bit_compute_dtype": torch.bfloat16,
19
+ "bnb_4bit_use_double_quant": False,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  }
 
 
 
 
21
 
22
+ # Tải mô hình với cấu hình đã thiết lập
23
+ model = AutoModelForCausalLM.from_pretrained(
24
+ model_id,
25
+ quantization_config=bnb_config,
26
+ device_map="auto", # Tự động phân bổ lên các thiết bị có sẵn (CPU)
27
+ trust_remote_code=True
28
+ )
29
 
30
+ # Tải tokenizer
31
+ tokenizer = AutoTokenizer.from_pretrained(model_id)
 
32
 
33
+ return model, tokenizer
 
34
 
35
+ # --- Hàm để chạy suy luận ---
36
+ def run_inference(post_text, model, tokenizer):
37
+ # Đây là cấu trúc prompt mà MentaLLaMA được huấn luyện để tuân theo.
38
+ # Việc tuân thủ đúng prompt format là RẤT QUAN TRỌNG.
39
+ prompt = f"""### Human: Analyze the following post and provide a diagnosis along with a detailed reasoning. Post: {post_text} ### Assistant:"""
 
 
40
 
41
+ # hóa prompt thành các token
42
+ inputs = tokenizer(prompt, return_tensors="pt").to("cuda" if torch.cuda.is_available() else "cpu")
 
43
 
44
+ # Chạy hình để tạo ra kết quả
45
+ outputs = model.generate(
46
+ **inputs,
47
+ max_new_tokens=256, # Giới hạn độ dài của câu trả lời
48
+ eos_token_id=tokenizer.eos_token_id,
49
+ pad_token_id=tokenizer.eos_token_id
50
+ )
51
 
52
+ # Giải kết quả từ token về lại văn bản
53
+ result_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
 
54
 
55
+ # Xử chuỗi để chỉ lấy phần trả lời của Assistant
56
+ # Kết quả thô sẽ có dạng: "### Human: ... ### Assistant: Answer: ... Reasoning: ..."
57
+ # Chúng ta cần cắt bỏ phần prompt đi.
58
+ try:
59
+ assistant_response = result_text.split("### Assistant:")[1].strip()
60
+ return assistant_response
61
+ except IndexError:
62
+ return "Lỗi: Không thể phân tích cú pháp đầu ra của mô hình."
63
 
64
+ # --- Giao diện ứng dụng Streamlit ---
65
+ st.set_page_config(layout="wide", page_title="MentaLLaMA Live Demo")
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
+ st.title("🔬 MentaLLaMA Live Demo - Chạy mô hình thật")
68
+ st.markdown("""
69
+ Chào mừng đến với bản demo **chạy thật** của **MentaLLaMA**!
70
+ - **Nhập** một đoạn văn bản (bằng tiếng Anh) vào ô bên dưới.
71
+ - **Nhấn nút** để mô hình MentaLLaMA-7B phân tích trực tiếp.
72
+ - **Lưu ý:** Vì chạy trên CPU miễn phí, quá trình suy luận có thể mất **1-2 phút**. Vui lòng kiên nhẫn!
73
+ """)
74
+
75
+ # Tải mô hình (sẽ hiển thị thanh tiến trình lần đầu)
76
+ with st.spinner("Đang tải mô hình MentaLLaMA-7B (lần đầu có thể mất vài phút)..."):
77
+ model, tokenizer = load_model()
78
+
79
+ st.success("Mô hình đã sẵn sàng!")
80
+
81
+ # Ô nhập liệu cho người dùng
82
+ user_input = st.text_area("Nhập bài đăng của bạn vào đây (tiếng Anh):", "Lately, I just feel so empty and numb inside. Nothing brings me joy anymore...", height=150)
83
+
84
+ # Nút chạy suy luận
85
+ if st.button('Chạy Phân Tích MentaLLaMA', type="primary"):
86
+ if user_input:
87
+ with st.spinner("MentaLLaMA đang suy luận, quá trình này có thể mất 1-2 phút..."):
88
+ result = run_inference(user_input, model, tokenizer)
89
 
90
+ st.subheader("Kết quả phân tích từ MentaLLaMA:")
91
+ st.success(result)
92
+ else:
93
+ st.warning("Vui lòng nhập nội dung bài đăng.")
 
 
 
 
 
 
94
 
95
  # Footer
96
  st.markdown("---")