lukedaca commited on
Commit
2cf03e3
·
verified ·
1 Parent(s): ea1c860

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -40
app.py CHANGED
@@ -10,7 +10,6 @@ from llama_index.readers.web import SimpleWebPageReader
10
  from llama_index.embeddings.fastembed import FastEmbedEmbedding
11
 
12
 
13
- # --- KONFIGURACE OSOBNOSTI BOTA ---
14
  SYSTEM_PROMPT = """
15
  Jsi inteligentní český asistent, který pomáhá uživatelům hledat informace na zadaném webu.
16
  Tvé jméno je AI Rádce.
@@ -23,20 +22,19 @@ Pravidla pro tebe:
23
  4. Pamatuj si, co uživatel říkal v předchozích větách této konverzace.
24
  """.strip()
25
 
 
26
  st.set_page_config(page_title="AI Rádce s pamětí", layout="centered")
27
  st.title("🧠 Chytrý Chatbot (s pamětí)")
28
 
29
- # --- NASTAVENÍ ZDROJE DAT ---
30
  DEFAULT_URLS = ["https://cs.wikipedia.org/wiki/Umělá_inteligence"]
31
 
32
- # --- NASTAVENÍ MODELU (GGUF) ---
33
  MODEL_REPO = "QuantFactory/Meta-Llama-3-8B-Instruct-GGUF"
34
  MODEL_FILE = "Meta-Llama-3-8B-Instruct.Q4_K_M.gguf"
35
 
36
 
37
- # Sidebar: konfigurace
38
  with st.sidebar:
39
  st.header("Nastavení")
 
40
  urls_text = st.text_area(
41
  "URL zdroje (1 URL na řádek)",
42
  value="\n".join(DEFAULT_URLS),
@@ -47,10 +45,9 @@ with st.sidebar:
47
  max_new_tokens = st.slider("Max nových tokenů (rychlost)", 32, 256, 128, 16)
48
  context_window = st.select_slider("Context window", options=[1024, 2048, 3072, 4096], value=2048)
49
 
50
- # Výkon: HF CPU typicky 2–4 jádra; víc často nepomůže
51
  cpu_cnt = os.cpu_count() or 2
52
- n_threads = st.slider("Počet vláken (threads)", 1, min(8, cpu_cnt), min(4, cpu_cnt), 1)
53
- n_batch = st.select_slider("Batch", options=[64, 128, 256, 512], value=256)
54
 
55
  if st.button("🧹 Resetovat konverzaci"):
56
  st.session_state.pop("messages", None)
@@ -58,39 +55,65 @@ with st.sidebar:
58
  st.rerun()
59
 
60
 
61
- @st.cache_resource
62
- def load_index_and_llm(urls_tuple: tuple[str, ...], ctx_win: int, max_tok: int, threads: int, batch: int) -> VectorStoreIndex:
63
  """
64
- Načte model + vytvoří index. Cache je sdílená.
65
- Paměť chatu NEcacheujeme (bude per-session).
66
  """
67
- # 1) stáhnout GGUF do HF cache
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  model_path = hf_hub_download(repo_id=MODEL_REPO, filename=MODEL_FILE)
69
 
70
- # 2) LLM (llama.cpp) parametry pro rychlost na CPU
71
- llm = LlamaCPP(
72
- model_path=model_path,
73
- temperature=0.1,
74
- max_new_tokens=max_tok,
75
- context_window=ctx_win,
76
- n_threads=threads,
77
- n_batch=batch,
78
- verbose=False,
79
- )
80
 
81
- # 3) Nastavení LlamaIndex
82
  Settings.llm = llm
83
  Settings.embed_model = FastEmbedEmbedding(model_name="BAAI/bge-small-en-v1.5")
84
 
85
- # 4) Data z webu + index
86
  docs = SimpleWebPageReader(html_to_text=True).load_data(list(urls_tuple))
87
- index = VectorStoreIndex.from_documents(docs)
88
- return index
89
 
90
 
91
  def make_chat_engine() -> object:
92
- """Vytvoří chat engine s pamětí pro konkrétní session."""
93
- index = load_index_and_llm(tuple(urls), context_window, max_new_tokens, n_threads, n_batch)
 
94
  memory = ChatMemoryBuffer.from_defaults(token_limit=min(3000, context_window))
95
 
96
  return index.as_chat_engine(
@@ -101,7 +124,6 @@ def make_chat_engine() -> object:
101
  )
102
 
103
 
104
- # Inicializace enginu
105
  if "chat_engine" not in st.session_state:
106
  with st.spinner("Startuji mozek bota... (načítám model a web)"):
107
  try:
@@ -110,7 +132,7 @@ if "chat_engine" not in st.session_state:
110
  st.error(f"Chyba při inicializaci: {e}")
111
  st.stop()
112
 
113
- # Historie zpráv
114
  if "messages" not in st.session_state:
115
  st.session_state.messages = []
116
 
@@ -119,41 +141,35 @@ for msg in st.session_state.messages:
119
  st.markdown(msg["content"])
120
 
121
 
122
- # --- CHAT LOOP (se streamováním) ---
123
  prompt = st.chat_input("Zeptej se (např: Co umíš?)...")
124
  if prompt:
125
- # user message
126
  st.session_state.messages.append({"role": "user", "content": prompt})
127
  with st.chat_message("user"):
128
  st.markdown(prompt)
129
 
130
- # assistant streaming response
131
  with st.chat_message("assistant"):
132
  placeholder = st.empty()
133
  full = ""
134
- started = time.time()
135
 
136
  with st.spinner("Přemýšlím..."):
137
  try:
138
  stream = st.session_state.chat_engine.stream_chat(prompt)
139
-
140
- # stream.response_gen generuje text po částech
141
  for chunk in stream.response_gen:
142
  full += chunk
143
  placeholder.markdown(full)
144
 
145
- # kdyby stream nevrátil nic (edge-case), aspoň něco
146
  if not full.strip():
147
- full = getattr(stream, "response", None) or "Omlouvám se, nedostal jsem žádná data k odpovědi."
148
  placeholder.markdown(full)
149
 
150
  except Exception as e:
151
  full = f"Chyba při generování odpovědi: {e}"
152
  placeholder.markdown(full)
153
 
154
- elapsed = time.time() - started
155
- st.caption(f"Hotovo za {elapsed:.1f}s")
156
 
157
  st.session_state.messages.append({"role": "assistant", "content": full})
158
 
159
 
 
 
10
  from llama_index.embeddings.fastembed import FastEmbedEmbedding
11
 
12
 
 
13
  SYSTEM_PROMPT = """
14
  Jsi inteligentní český asistent, který pomáhá uživatelům hledat informace na zadaném webu.
15
  Tvé jméno je AI Rádce.
 
22
  4. Pamatuj si, co uživatel říkal v předchozích větách této konverzace.
23
  """.strip()
24
 
25
+
26
  st.set_page_config(page_title="AI Rádce s pamětí", layout="centered")
27
  st.title("🧠 Chytrý Chatbot (s pamětí)")
28
 
 
29
  DEFAULT_URLS = ["https://cs.wikipedia.org/wiki/Umělá_inteligence"]
30
 
 
31
  MODEL_REPO = "QuantFactory/Meta-Llama-3-8B-Instruct-GGUF"
32
  MODEL_FILE = "Meta-Llama-3-8B-Instruct.Q4_K_M.gguf"
33
 
34
 
 
35
  with st.sidebar:
36
  st.header("Nastavení")
37
+
38
  urls_text = st.text_area(
39
  "URL zdroje (1 URL na řádek)",
40
  value="\n".join(DEFAULT_URLS),
 
45
  max_new_tokens = st.slider("Max nových tokenů (rychlost)", 32, 256, 128, 16)
46
  context_window = st.select_slider("Context window", options=[1024, 2048, 3072, 4096], value=2048)
47
 
 
48
  cpu_cnt = os.cpu_count() or 2
49
+ threads = st.slider("Počet vláken (threads)", 1, min(8, cpu_cnt), min(4, cpu_cnt), 1)
50
+ batch = st.select_slider("Batch", options=[64, 128, 256, 512], value=256)
51
 
52
  if st.button("🧹 Resetovat konverzaci"):
53
  st.session_state.pop("messages", None)
 
55
  st.rerun()
56
 
57
 
58
+ def create_llm(model_path: str, ctx_win: int, max_tok: int, n_threads: int, n_batch: int) -> LlamaCPP:
 
59
  """
60
+ Kompatibilní konstrukce LlamaCPP napříč verzemi llama-index.
61
+ Některé verze nepřijímají n_threads/n_batch přímo, ale jen přes model_kwargs.
62
  """
63
+ # 1) zkusit přímé parametry (novější/verze dle wrapperu)
64
+ try:
65
+ return LlamaCPP(
66
+ model_path=model_path,
67
+ temperature=0.1,
68
+ max_new_tokens=max_tok,
69
+ context_window=ctx_win,
70
+ n_threads=n_threads,
71
+ n_batch=n_batch,
72
+ verbose=False,
73
+ )
74
+ except TypeError:
75
+ pass
76
+
77
+ # 2) fallback přes model_kwargs (časté u LlamaIndex wrapperu)
78
+ try:
79
+ return LlamaCPP(
80
+ model_path=model_path,
81
+ temperature=0.1,
82
+ max_new_tokens=max_tok,
83
+ context_window=ctx_win,
84
+ model_kwargs={"n_threads": n_threads, "n_batch": n_batch},
85
+ verbose=False,
86
+ )
87
+ except TypeError:
88
+ # 3) poslední fallback – jen threads (někdy n_batch není podporovaný)
89
+ return LlamaCPP(
90
+ model_path=model_path,
91
+ temperature=0.1,
92
+ max_new_tokens=max_tok,
93
+ context_window=ctx_win,
94
+ model_kwargs={"n_threads": n_threads},
95
+ verbose=False,
96
+ )
97
+
98
+
99
+ @st.cache_resource
100
+ def load_index_and_settings(urls_tuple: tuple[str, ...], ctx_win: int, max_tok: int, n_threads: int, n_batch: int) -> VectorStoreIndex:
101
+ # stáhnout GGUF do HF cache
102
  model_path = hf_hub_download(repo_id=MODEL_REPO, filename=MODEL_FILE)
103
 
104
+ llm = create_llm(model_path, ctx_win, max_tok, n_threads, n_batch)
 
 
 
 
 
 
 
 
 
105
 
 
106
  Settings.llm = llm
107
  Settings.embed_model = FastEmbedEmbedding(model_name="BAAI/bge-small-en-v1.5")
108
 
 
109
  docs = SimpleWebPageReader(html_to_text=True).load_data(list(urls_tuple))
110
+ return VectorStoreIndex.from_documents(docs)
 
111
 
112
 
113
  def make_chat_engine() -> object:
114
+ index = load_index_and_settings(tuple(urls), context_window, max_new_tokens, threads, batch)
115
+
116
+ # paměť per-session (NEcacheovat)
117
  memory = ChatMemoryBuffer.from_defaults(token_limit=min(3000, context_window))
118
 
119
  return index.as_chat_engine(
 
124
  )
125
 
126
 
 
127
  if "chat_engine" not in st.session_state:
128
  with st.spinner("Startuji mozek bota... (načítám model a web)"):
129
  try:
 
132
  st.error(f"Chyba při inicializaci: {e}")
133
  st.stop()
134
 
135
+
136
  if "messages" not in st.session_state:
137
  st.session_state.messages = []
138
 
 
141
  st.markdown(msg["content"])
142
 
143
 
 
144
  prompt = st.chat_input("Zeptej se (např: Co umíš?)...")
145
  if prompt:
 
146
  st.session_state.messages.append({"role": "user", "content": prompt})
147
  with st.chat_message("user"):
148
  st.markdown(prompt)
149
 
 
150
  with st.chat_message("assistant"):
151
  placeholder = st.empty()
152
  full = ""
153
+ t0 = time.time()
154
 
155
  with st.spinner("Přemýšlím..."):
156
  try:
157
  stream = st.session_state.chat_engine.stream_chat(prompt)
 
 
158
  for chunk in stream.response_gen:
159
  full += chunk
160
  placeholder.markdown(full)
161
 
 
162
  if not full.strip():
163
+ full = getattr(stream, "response", None) or "Nedostal jsem žádná data k odpovědi."
164
  placeholder.markdown(full)
165
 
166
  except Exception as e:
167
  full = f"Chyba při generování odpovědi: {e}"
168
  placeholder.markdown(full)
169
 
170
+ st.caption(f"Hotovo za {time.time() - t0:.1f}s")
 
171
 
172
  st.session_state.messages.append({"role": "assistant", "content": full})
173
 
174
 
175
+