fedora:aplikacje:ollama
Różnice
Różnice między wybraną wersją a wersją aktualną.
| Poprzednia rewizja po obu stronachPoprzednia wersjaNowa wersja | Poprzednia wersja | ||
| fedora:aplikacje:ollama [2026/10/30 20:06] – [Agenci] sindap | fedora:aplikacje:ollama [2026/11/09 21:25] (aktualna) – [Ollama w Podman] sindap | ||
|---|---|---|---|
| Linia 53: | Linia 53: | ||
| python -m venv agent_llm | python -m venv agent_llm | ||
| source agent_llm/ | source agent_llm/ | ||
| - | pip install langchain-ollama | + | pip install langchain-ollama |
| </ | </ | ||
| - | <code python> | + | ==== Agent testowy ==== |
| + | |||
| + | <code python | ||
| from langchain_ollama import ChatOllama | from langchain_ollama import ChatOllama | ||
| from langchain_core.messages import HumanMessage | from langchain_core.messages import HumanMessage | ||
| Linia 71: | Linia 73: | ||
| print(" | print(" | ||
| print(response.content) | print(response.content) | ||
| + | </ | ||
| + | |||
| + | <code bash> | ||
| + | python test_agent.py | ||
| + | </ | ||
| + | |||
| + | ==== Agent bazujący na treści z konkretnego pliku pdf ==== | ||
| + | |||
| + | <code python agent_chat.py > | ||
| + | from langchain_ollama import ChatOllama, OllamaEmbeddings | ||
| + | from langchain_core.messages import HumanMessage | ||
| + | from langchain_community.document_loaders import PyPDFLoader | ||
| + | from langchain_text_splitters import RecursiveCharacterTextSplitter | ||
| + | from langchain_chroma import Chroma | ||
| + | import os | ||
| + | |||
| + | pdf_path = " | ||
| + | |||
| + | if not os.path.exists(pdf_path): | ||
| + | print(f" | ||
| + | exit() | ||
| + | |||
| + | print(" | ||
| + | print(f" | ||
| + | loader = PyPDFLoader(pdf_path) | ||
| + | docs = loader.load() | ||
| + | |||
| + | print(f" | ||
| + | text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, | ||
| + | splits = text_splitter.split_documents(docs) | ||
| + | |||
| + | print(" | ||
| + | embeddings = OllamaEmbeddings(model=" | ||
| + | vectorstore = Chroma.from_documents(documents=splits, | ||
| + | retriever = vectorstore.as_retriever() | ||
| + | |||
| + | llm = ChatOllama(model=" | ||
| + | |||
| + | print(" | ||
| + | print(" | ||
| + | |||
| + | # Pętla konwersacji | ||
| + | while True: | ||
| + | try: | ||
| + | pytanie = input(" | ||
| + | if not pytanie.strip(): | ||
| + | continue | ||
| + | if pytanie.lower() in [" | ||
| + | print(" | ||
| + | break | ||
| + | |||
| + | # Szukamy fragmentów pasujących do pytania | ||
| + | relevant_docs = retriever.invoke(pytanie) | ||
| + | kontekst = " | ||
| + | |||
| + | # Tworzymy prompt dla modelu | ||
| + | prompt = f""" | ||
| + | Jeśli nie masz tej informacji w tekście, napisz, że jej nie znasz. | ||
| + | |||
| + | Tekst z dokumentu PDF: | ||
| + | {kontekst} | ||
| + | |||
| + | Pytanie: {pytanie} | ||
| + | """ | ||
| + | |||
| + | response = llm.invoke([HumanMessage(content=prompt)]) | ||
| + | print(f" | ||
| + | |||
| + | except KeyboardInterrupt: | ||
| + | print(" | ||
| + | break | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== Agent bazujący na treści z plików pdf z podkatalogu pdf ==== | ||
| + | |||
| + | <code python agent_hybrid.py> | ||
| + | import warnings | ||
| + | warnings.filterwarnings(" | ||
| + | |||
| + | from langchain_ollama import ChatOllama, OllamaEmbeddings | ||
| + | from langchain_core.messages import HumanMessage | ||
| + | from langchain_community.document_loaders import DirectoryLoader, | ||
| + | from langchain_text_splitters import RecursiveCharacterTextSplitter | ||
| + | from langchain_chroma import Chroma | ||
| + | from langchain_community.retrievers import BM25Retriever | ||
| + | import os | ||
| + | |||
| + | folder_path = " | ||
| + | |||
| + | if not os.path.exists(folder_path): | ||
| + | print(f" | ||
| + | exit() | ||
| + | |||
| + | print(" | ||
| + | print(f" | ||
| + | |||
| + | loader = DirectoryLoader(folder_path, | ||
| + | docs = loader.load() | ||
| + | |||
| + | if not docs: | ||
| + | print(" | ||
| + | exit() | ||
| + | |||
| + | print(f" | ||
| + | |||
| + | print(" | ||
| + | text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, | ||
| + | splits = text_splitter.split_documents(docs) | ||
| + | |||
| + | print(" | ||
| + | embeddings = OllamaEmbeddings(model=" | ||
| + | vectorstore = Chroma.from_documents(documents=splits, | ||
| + | chroma_retriever = vectorstore.as_retriever(search_kwargs={" | ||
| + | |||
| + | # Indeks słów kluczowych (BM25) do dokładnych numerów i indeksów | ||
| + | bm25_retriever = BM25Retriever.from_documents(splits) | ||
| + | bm25_retriever.k = 5 | ||
| + | |||
| + | # Własna funkcja łącząca oba podejścia (hybryda) | ||
| + | def hybrid_retrieve(query, | ||
| + | docs_chroma = chroma_retriever.invoke(query) | ||
| + | docs_bm25 = bm25_retriever.invoke(query) | ||
| + | | ||
| + | # Łączymy wyniki, usuwając duplikaty po treści | ||
| + | seen = set() | ||
| + | combined = [] | ||
| + | for doc in docs_bm25 + docs_chroma: | ||
| + | if doc.page_content not in seen: | ||
| + | seen.add(doc.page_content) | ||
| + | combined.append(doc) | ||
| + | return combined[: | ||
| + | |||
| + | llm = ChatOllama(model=" | ||
| + | |||
| + | print(" | ||
| + | print(" | ||
| + | |||
| + | while True: | ||
| + | try: | ||
| + | pytanie = input(" | ||
| + | if not pytanie.strip(): | ||
| + | continue | ||
| + | if pytanie.lower() in [" | ||
| + | print(" | ||
| + | break | ||
| + | |||
| + | # Pobieramy dokumenty hybrydowo | ||
| + | relevant_docs = hybrid_retrieve(pytanie) | ||
| + | kontekst = " | ||
| + | |||
| + | prompt = f""" | ||
| + | Jeśli nie masz tej informacji w tekstach, napisz, że jej nie znasz. | ||
| + | |||
| + | Teksty źródłowe: | ||
| + | {kontekst} | ||
| + | |||
| + | Pytanie: {pytanie} | ||
| + | """ | ||
| + | |||
| + | response = llm.invoke([HumanMessage(content=prompt)]) | ||
| + | print(f" | ||
| + | |||
| + | except KeyboardInterrupt: | ||
| + | print(" | ||
| + | break | ||
| + | </ | ||
| + | |||
| + | ===== Ollama w Podman ===== | ||
| + | |||
| + | <code bash> | ||
| + | sudo dnf install -y nvidia-container-toolkit | ||
| + | sudo mkdir -p /etc/cdi | ||
| + | sudo nvidia-ctk cdi generate --output=/ | ||
| + | </ | ||
| + | |||
| + | <code bash> | ||
| + | nvidia-ctk cdi list | ||
| + | INFO[0000] Found 3 CDI devices | ||
| + | nvidia.com/ | ||
| + | nvidia.com/ | ||
| + | nvidia.com/ | ||
| + | </ | ||
| + | |||
| + | <code bash> | ||
| + | podman run --rm --security-opt=label=disable --device=nvidia.com/ | ||
| + | </ | ||
| + | |||
| + | <code bash> | ||
| + | podman run -d --name ollama --device=nvidia.com/ | ||
| + | </ | ||
| + | |||
| + | <code bash> | ||
| + | podman exec -it ollama ollama list | ||
| + | NAME ID SIZE MODIFIED | ||
| + | SpeakLeash/ | ||
| + | qwen: | ||
| + | qwen2.5-coder: | ||
| + | deepseek-coder: | ||
| + | llama3: | ||
| + | deepseek-coder: | ||
| + | </ | ||
| + | |||
| + | <code bash> | ||
| + | podman exec -it ollama ollama run deepseek-coder: | ||
| + | </ | ||
| + | |||
| + | Jeżeli rozmiar modelu jest mniejszy niż rozmiar pamięci GPU to model korzysta z GPU. | ||
| + | <code bash> | ||
| + | podman exec ollama ollama ps | ||
| + | NAME | ||
| + | deepseek-coder: | ||
| + | </ | ||
| + | |||
| + | Przy większych modelach obliczenia są realizowane przez GPU i CPU | ||
| + | <code bash> | ||
| + | podman exec ollama ollama ps | ||
| + | NAME ID SIZE PROCESSOR | ||
| + | SpeakLeash/ | ||
| </ | </ | ||
fedora/aplikacje/ollama.1793387184.txt.gz · ostatnio zmienione: przez sindap
