AD-Styles commited on
Commit
0668b2d
ยท
verified ยท
1 Parent(s): bc17230

Upload 3 files

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ 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
+ Maximizing[[:space:]]Muscle[[:space:]]Hypertrophy.pdf filter=lfs diff=lfs merge=lfs -text
Maximizing Muscle Hypertrophy.pdf ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:662b3f4fd341796bd79d517bb383fca4041288bd645f793d1bf3eb6eec2082d9
3
+ size 527026
app(1).py ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ from langchain_google_genai import ChatGoogleGenerativeAI, GoogleGenerativeAIEmbeddings
4
+ from langchain_community.document_loaders import PyPDFLoader
5
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
6
+ from langchain_chroma import Chroma
7
+ from langchain_core.prompts import ChatPromptTemplate
8
+
9
+ # 1. ๋ฌธ์„œ ๋กœ๋“œ ๋ฐ ๋ฒกํ„ฐ DB ๊ตฌ์ถ• (์„œ๋ฒ„ ๊ตฌ๋™ ์‹œ 1ํšŒ ๊ณ ์ •)
10
+ loader = PyPDFLoader("Maximizing Muscle Hypertrophy.pdf")
11
+ pages = loader.load_and_split()
12
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
13
+ splits = text_splitter.split_documents(pages)
14
+
15
+ embeddings = GoogleGenerativeAIEmbeddings(model="gemini-embedding-001")
16
+ vectorstore = Chroma.from_documents(documents=splits, embedding=embeddings)
17
+
18
+ # ๋ฏธ์…˜ 3: ๋„๋ฉ”์ธ ๋งž์ถค ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ
19
+ SYSTEM_PROMPT = """๋‹น์‹ ์€ ์Šคํฌ์ธ  ์˜์–‘ํ•™ ๋ฐ ๊ทผ๋น„๋Œ€(Muscle Hypertrophy) ํ›ˆ๋ จ ๋ถ„์•ผ์˜ ์ตœ๊ณ  ๊ถŒ์œ„์ž์ด์ž ๋…ผ๋ฌธ ๋ฆฌ๋ทฐ ์ „๋ฌธ๊ฐ€์ž…๋‹ˆ๋‹ค.
20
+ ์ œ๊ณต๋œ [๋…ผ๋ฌธ ์ปจํ…์ŠคํŠธ]๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์‚ฌ์šฉ์ž์˜ ์งˆ๋ฌธ์— ์ „๋ฌธ์ ์ด๊ณ  ๋ช…ํ™•ํ•˜๋ฉฐ ๊ฐ๊ด€์ ์ธ ์–ด์กฐ๋กœ ๋‹ต๋ณ€ํ•˜์„ธ์š”.
21
+
22
+ [์ œ์•ฝ ์กฐ๊ฑด]
23
+ 1. ๋ฐ˜๋“œ์‹œ ์ œ๊ณต๋œ ์ปจํ…์ŠคํŠธ ๋‚ด์˜ ์ •๋ณด๋งŒ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ต๋ณ€ํ•˜์„ธ์š”.
24
+ 2. ๋…ผ๋ฌธ์— ์—†๋Š” ๋‚ด์šฉ์„ ์งˆ๋ฌธํ•˜๋ฉด "ํ•ด๋‹น ๋‚ด์šฉ์€ ์ œ๊ณต๋œ ๋…ผ๋ฌธ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."๋ผ๊ณ  ๋ช…ํ™•ํžˆ ์„ ์„ ๊ทธ์œผ์„ธ์š”.
25
+ 3. ๊ทผ์œก ์„ฑ์žฅ ๊ธฐ์ „์ด๋‚˜ ํ›ˆ๋ จ๋ฒ•์„ ์„ค๋ช…ํ•  ๋•Œ๋Š” ์ผ๋ฐ˜์ธ๋„ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋‹จ๊ณ„๋ณ„๋กœ ๊ตฌ์กฐํ™”ํ•˜์—ฌ ์„ค๋ช…ํ•˜์„ธ์š”.
26
+ 4. ๋ชจ๋“  ๋‹ต๋ณ€์€ ํ•œ๊ตญ์–ด๋กœ ์ž‘์„ฑํ•˜๋ฉฐ, ์ฃผ์š” ์˜ํ•™ ๋ฐ ์šด๋™ํ•™ ์ „๋ฌธ ์šฉ์–ด๋Š” ๊ด„ํ˜ธ ์•ˆ์— ์˜๋ฌธ์„ ๋ณ‘๊ธฐํ•˜์„ธ์š” (์˜ˆ: ๋‹จ๋ฐฑ์งˆ ํ•ฉ์„ฑ(Protein Synthesis)).
27
+
28
+ [๋…ผ๋ฌธ ์ปจํ…์ŠคํŠธ]
29
+ {context}"""
30
+
31
+ qa_prompt = ChatPromptTemplate.from_messages([
32
+ ("system", SYSTEM_PROMPT),
33
+ ("placeholder", "{chat_history}"),
34
+ ("human", "{input}"),
35
+ ])
36
+
37
+ # Gradio์˜ ๋Œ€ํ™” ๊ธฐ๋ก ํ˜•์‹์„ LangChain์ด ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ณ€ํ™˜ํ•˜๋Š” ํ—ฌํผ ํ•จ์ˆ˜
38
+ def format_history(history):
39
+ formatted = []
40
+ for user_msg, ai_msg in history:
41
+ formatted.append(("human", user_msg))
42
+ formatted.append(("ai", ai_msg))
43
+ return formatted
44
+
45
+ # ๋ฏธ์…˜ 1, 2, 5 ํ†ตํ•ฉ: ์ŠคํŠธ๋ฆฌ๋ฐ, ๋™์  ์„ค์ •, ์ถœ์ฒ˜ ํŒŒ์‹ฑ
46
+ def chat_response(message, history, temperature, k, model_name):
47
+ # ๋ฏธ์…˜ 2: UI์—์„œ ๋„˜๊ฒจ๋ฐ›์€ k ๊ฐ’์œผ๋กœ ๊ฒ€์ƒ‰ ๋ฒ”์œ„ ๋™์  ์กฐ์ ˆ
48
+ docs = vectorstore.similarity_search(message, k=k)
49
+ context = "\n\n".join(doc.page_content for doc in docs)
50
+
51
+ # ๋ฏธ์…˜ 2: UI์—์„œ ๋„˜๊ฒจ๋ฐ›์€ ๋ชจ๋ธ๊ณผ ์˜จ๋„๋กœ LLM ๋™์  ์ƒ์„ฑ
52
+ llm = ChatGoogleGenerativeAI(model=model_name, temperature=temperature)
53
+
54
+ # ํ”„๋กฌํ”„ํŠธ ์กฐ๋ฆฝ
55
+ prompt_value = qa_prompt.invoke({
56
+ "context": context,
57
+ "chat_history": format_history(history),
58
+ "input": message
59
+ })
60
+
61
+ partial_message = ""
62
+ # ๋ฏธ์…˜ 5: llm.stream()์„ ํ™œ์šฉํ•œ ์‹ค์‹œ๊ฐ„ ์ŠคํŠธ๋ฆฌ๋ฐ ์ถœ๋ ฅ
63
+ for chunk in llm.stream(prompt_value):
64
+ partial_message += chunk.content
65
+ yield partial_message # ๊ธ€์ž๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ๋งˆ๋‹ค UI๋กœ ๋ฐ€์–ด๋ƒ„
66
+
67
+ # ๋ฏธ์…˜ 1: PyPDFLoader ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์—์„œ ์ถœ์ฒ˜ ๋ฐ ํŽ˜์ด์ง€ ์ถ”์ถœ (page๋Š” 0๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋ฏ€๋กœ +1)
68
+ sources = []
69
+ for doc in docs:
70
+ source_file = os.path.basename(doc.metadata.get('source', 'Unknown'))
71
+ page_num = doc.metadata.get('page', 0) + 1
72
+ sources.append(f"{source_file} (p.{page_num})")
73
+
74
+ # ๋ฆฌ์ŠคํŠธ ์ค‘๋ณต ์ œ๊ฑฐ ํ›„ ์ตœ์ข… ํ…์ŠคํŠธ ์กฐ๋ฆฝ
75
+ unique_sources = list(dict.fromkeys(sources))
76
+ source_str = "\n\n๐Ÿ“Ž **์ถœ์ฒ˜:** " + ", ".join(unique_sources)
77
+
78
+ # ์ตœ์ข…์ ์œผ๋กœ ๋‹ต๋ณ€ ๋์— ์ถœ์ฒ˜๋ฅผ ๋ง๋ถ™์—ฌ์„œ ์ „์†ก
79
+ yield partial_message + source_str
80
+
81
+ # ๋ฏธ์…˜ 4: ๋Œ€ํ™” ๋‚ด์—ญ ๋‹ค์šด๋กœ๋“œ ํŒŒ์ผ ์ƒ์„ฑ ํ•จ์ˆ˜
82
+ def download_chat_history(history):
83
+ file_path = "chat_history.txt"
84
+ with open(file_path, "w", encoding="utf-8") as f:
85
+ for user_msg, ai_msg in history:
86
+ f.write(f"๐Ÿง‘โ€๐Ÿ’ป ์‚ฌ์šฉ์ž: {user_msg}\n")
87
+ f.write(f"๐Ÿค– AI: {ai_msg}\n")
88
+ f.write("-" * 50 + "\n")
89
+ return file_path
90
+
91
+ # UI ๋ ˆ์ด์•„์›ƒ ๊ตฌ์„ฑ
92
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
93
+ gr.Markdown("## ๐Ÿ’ช ๊ทผ๋น„๋Œ€ ๊ทน๋Œ€ํ™” ๋…ผ๋ฌธ Q&A ๋ด‡ (Pro Version)")
94
+
95
+ # ๋ฏธ์…˜ 2: ์ ‘์„ ์ˆ˜ ์žˆ๋Š” ์„ค์ • ํŒจ๋„
96
+ with gr.Accordion("โš™๏ธ ์ฑ—๋ด‡ ์ƒ์„ธ ์„ค์ •", open=False):
97
+ with gr.Row():
98
+ model_dd = gr.Dropdown(choices=["gemini-2.0-flash", "gemini-1.5-pro", "gemini-1.5-flash"], value="gemini-2.0-flash", label="๐Ÿค– ๋ชจ๋ธ ์„ ํƒ")
99
+ temp_slider = gr.Slider(minimum=0.0, maximum=1.0, value=0.0, step=0.1, label="๐ŸŒก๏ธ Temperature (์ฐฝ์˜์„ฑ/ํ™˜๊ฐ ์กฐ์ ˆ)")
100
+ k_slider = gr.Slider(minimum=1, maximum=10, value=3, step=1, label="๐Ÿ“š ์ฐธ๊ณ ํ•  ๋ฌธ์„œ ์กฐ๊ฐ ์ˆ˜ (k)")
101
+
102
+ # ํ•ต์‹ฌ ์ฑ—๋ด‡ ์ธํ„ฐํŽ˜์ด์Šค (์„ค์ • ํŒจ๋„์˜ ๊ฐ’๋“ค์„ additional_inputs๋กœ ์—ฐ๊ฒฐ)
103
+ chat_interface = gr.ChatInterface(
104
+ fn=chat_response,
105
+ additional_inputs=[temp_slider, k_slider, model_dd],
106
+ chatbot=gr.Chatbot(height=500),
107
+ title="",
108
+ description="'Maximizing Muscle Hypertrophy' ๋…ผ๋ฌธ ๋‚ด์šฉ์„ ๋ฐ”ํƒ•์œผ๋กœ ๊ทผ์„ฑ์žฅ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์งˆ๋ฌธํ•ด ๋ณด์„ธ์š”."
109
+ )
110
+
111
+ # ๋ฏธ์…˜ 4: ๋Œ€ํ™” ๋‚ด์—ญ ๋‹ค์šด๋กœ๋“œ ์˜์—ญ
112
+ with gr.Row():
113
+ download_btn = gr.Button("๐Ÿ’พ ํ˜„์žฌ ๋Œ€ํ™” ๋‚ด์—ญ ์ €์žฅ ๋ฐ ๋‹ค์šด๋กœ๋“œ", variant="primary")
114
+ download_file = gr.File(label="๋‹ค์šด๋กœ๋“œ ์ค€๋น„ ์™„๋ฃŒ (๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด์„ธ์š”)")
115
+
116
+ # ๋ฒ„ํŠผ ํด๋ฆญ ์ด๋ฒคํŠธ (์ฑ„ํŒ…์ฐฝ์˜ ํžˆ์Šคํ† ๋ฆฌ๋ฅผ ๊ฐ€์ ธ์™€ ํŒŒ์ผ๋กœ ๋ณ€ํ™˜)
117
+ download_btn.click(
118
+ fn=download_chat_history,
119
+ inputs=[chat_interface.chatbot],
120
+ outputs=[download_file]
121
+ )
122
+
123
+ if __name__ == "__main__":
124
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ gradio>=4.0.0
2
+ langchain>=0.2.0
3
+ langchain-core>=0.2.0
4
+ langchain-community>=0.2.0
5
+ langchain-google-genai>=1.0.0
6
+ langchain-chroma>=0.1.1
7
+ langchain-text-splitters>=0.2.0
8
+ chromadb
9
+ pypdf