Autonomiczne hostowanie Cognee: Wybór LLM na Ollama

Testowanie Cognee z lokalnymi modelami LLM - rzeczywiste wyniki

Page content

Cognee to framework w Pythonie do budowania grafów wiedzy z dokumentów za pomocą LLM. Ale działa on z modelami samozhostowanymi?

Przetestowałem to z wieloma lokalnymi LLM, aby to ustalić.

cognee przetwarzanie pdf z procelist

To jest strona PDF z listą cen, którą próbowałem przetworzyć.

TL;DR

Cognee prawdopodobnie działa dobrze z inteligentnymi LLM o setkach miliardów parametrów, ale w przypadku lokalnych konfiguracji RAG, które mają automatycznie wyodrębniać dane z PDF (np. listy cen), nie wykonał się na moim sprzęcie. Wielka zależność frameworku od wyjścia strukturalnego sprawia, że trudno jest mniejszym modelom lokalnym działać niezawodnie.

Co to jest Cognee?

Cognee to otwarty framework w Pythonie zaprojektowany do budowania grafów wiedzy z niestrukturalnych dokumentów za pomocą LLM. W przeciwieństwie do tradycyjnych systemów RAG, które po prostu dzielą i osadzają dokumenty, Cognee stara się stworzyć zrozumienie semantyczne, wyodrębniając jednostki, relacje i koncepcje do bazy danych grafów. Ten podejście odpowiada zaawansowanym architekturom RAG, takim jak GraphRAG, które obiecują lepsze wyszukiwanie kontekstowe.

Framework wspiera wiele backendów:

  • Bazy wektorowe: LanceDB (domyślnie), z obsługą innych baz wektorowych
  • Bazy grafów: Kuzu (domyślnie), umożliwiające złożone zapytania o relacje
  • Dostawcy LLM: OpenAI, Anthropic, Ollama i inne
  • Frameworki wyjścia strukturalnego: BAML i Instructor do ograniczonego generowania

Dla entuzjastów samozhostowania, kompatybilność Cognee z Ollama czyni go przyciągającym dla lokalnych wdrożeń. Jednak diabeł tkwi w szczegółach - jak zobaczymy, wymagania dotyczące wyjścia strukturalnego tworzą znaczne wyzwania dla mniejszych modeli.

Dlaczego wyjście strukturalne ma znaczenie

Cognee bardzo mocno opiera się na wyjściu strukturalnym, aby wyodrębniać informacje z dokumentów w spójnym formacie. Przetwarzając dokument, LLM musi zwrócić poprawnie sformatowany JSON zawierający jednostki, relacje i metadane. To miejsce, gdzie wielu mniejszych modeli ma trudności.

Jeśli pracujesz z wyjściem strukturalnym w swoich projektach, zrozumienie tych ograniczeń jest kluczowe. Trudności, które napotkałem w Cognee, są odbiciem większych problemów w ekosystemie LLM przy pracy z lokalnymi modelami.

Konfiguracja

Oto moja działająca konfiguracja Cognee z Ollama. Zwróć uwagę na kluczowe ustawienia umożliwiające lokalną pracę:

TELEMETRY_DISABLED=1

# STRUCTURED_OUTPUT_FRAMEWORK="instructor"
STRUCTURED_OUTPUT_FRAMEWORK="BAML"  

# Konfiguracja LLM 
LLM_API_KEY="ollama"  
LLM_MODEL="gpt-oss:20b"
LLM_PROVIDER="ollama"  
LLM_ENDPOINT="http://localhost:11434/v1"
# LLM_MAX_TOKENS="25000"


# Konfiguracja osadzania
EMBEDDING_PROVIDER="ollama"  
EMBEDDING_MODEL="avr/sfr-embedding-mistral:latest"  
EMBEDDING_ENDPOINT="http://localhost:11434/api/embeddings"  
EMBEDDING_DIMENSIONS=4096  
HUGGINGFACE_TOKENIZER="Salesforce/SFR-Embedding-Mistral"  

# Konfiguracja BAML
BAML_LLM_PROVIDER="ollama"  
BAML_LLM_MODEL="gpt-oss:20b" 

BAML_LLM_ENDPOINT="http://localhost:11434/v1"


# Ustawienia bazy danych (domyślne)
DB_PROVIDER="sqlite"  
VECTOR_DB_PROVIDER="lancedb"  
GRAPH_DATABASE_PROVIDER="kuzu"

# Autoryzacja
REQUIRE_AUTHENTICATION=False
ENABLE_BACKEND_ACCESS_CONTROL=False

Kluczowe decyzje konfiguracyjne

Framework wyjścia strukturalnego: Przetestowałem BAML, który oferuje lepszy kontrolę nad schematami wyjścia w porównaniu do podstawowego monologowania. BAML jest specjalnie zaprojektowany do wyjścia strukturalnego z LLM, co czyni go naturalnym wyborem do zadań wyodrębniania grafów wiedzy.

Dostawca LLM: Użycie kompatybilnego z OpenAI API endpointu Ollama (/v1) pozwala Cognee traktować go jak każdy inny usługę OpenAI.

Model osadzania: Model SFR-Embedding-Mistral (4096 wymiarów) zapewnia wysokiej jakości osadzenia. Dla więcej informacji na temat wyboru modeli osadzania i ich wydajności, modele Qwen3 osadzania oferują doskonałe alternatywy z silną zdolnością wielojęzyczną.

Bazy danych: SQLite dla metadanych, LanceDB dla wektorów i Kuzu dla grafu wiedzy utrzymuje wszystko lokalnie bez zależności zewnętrznych.

Instalacja Cognee

Instalacja jest prosta za pomocą uv (lub pip). Zalecam użycie uv dla szybszego rozwiązywania zależności:

uv venv && source .venv/bin/activate
uv pip install cognee[ollama]
uv pip install cognee[baml]
uv pip install cognee[instructor]

uv sync --extra scraping
uv run playwright install
sudo apt-get install libavif16

Dodatki [ollama], [baml] i [instructor] instalują wymagane zależności do lokalnej pracy z LLM i wyjścia strukturalnego. Dodatek do skrapowania dodaje możliwości skrapowania stron, a Playwright umożliwia przetwarzanie stron renderowanych JavaScriptem.

Przykładowy kod i użycie

Oto podstawowy przepływ pracy do przetwarzania dokumentów z Cognee. Najpierw dodajemy dokumenty i budujemy graf wiedzy:

msy-add.py:

import cognee
import asyncio

async def main():

    # Utwórz czysty stan dla Cognee — zresetuj dane i stan systemu
    await cognee.prune.prune_data()
    await cognee.prune.prune_system(metadata=True)
    
    # Dodaj przykładowe treści
    await cognee.add(
        "/home/rg/prj/prices/msy_parts_price_20251224.pdf",
        node_set=["price_list", "computer_parts", "2025-12-24", "aud"]
    )
    
    # Przetwórz za pomocą LLM, aby zbudować graf wiedzy
    await cognee.cognify()

if __name__ == '__main__':
    asyncio.run(main())

Parametr node_set dostarcza tagów semantycznych, które pomagają kategoryzować dokument w grafie wiedzy. Metoda cognify() to miejsce, gdzie dzieje się magia (lub problemy) — wysyła fragmenty dokumentu do LLM do wyodrębniania jednostek i relacji.

msy-search.py:

import cognee
import asyncio

async def main():

    # Wyszukaj w grafie wiedzy
    results = await cognee.search(
        query_text="Jakie produkty są w liście cen?"
#       query_text="Jaka jest średnia cena za 32GB RAM (2x16GB modułów)?"
    )
    
    # Wydrukuj
    for result in results:
        print(result)

if __name__ == '__main__':
    asyncio.run(main())

W przeciwieństwie do tradycyjnego wyszukiwania wektorowego w systemach RAG, Cognee wyszukuje w grafie wiedzy, teoretycznie umożliwiając bardziej zaawansowane wyszukiwanie oparte na relacjach. Jest to podobne do sposobu działania zaawansowanych architektur RAG, ale wymaga, aby początkowa konstrukcja grafu powiodła się.

Wyniki testów: wydajność LLM

Przetestowałem Cognee w rzeczywistym przypadku użycia: wyodrębnianie informacji produktowych z PDF listy cen części komputerowych. Wydawało się to idealnym scenariuszem — strukturalne dane w formacie tabeli. Oto, co się wydarzyło z każdym modelem:

Testowane modele

1. gpt-oss:20b (20 miliardów parametrów)

  • Wynik: Nie powiodło się z błędami kodowania znaków
  • Problem: Zwrócił zepsuty strukturalny output z błędami kodowania znaków
  • Uwaga: Choć został specjalnie zaprojektowany dla kompatybilności z open source, nie mógł utrzymać spójnego formatowania JSON

2. qwen3:14b (14 miliardów parametrów)

  • Wynik: Nie wygenerował strukturalnego outputu
  • Problem: Model generował tekst, ale nie w wymaganym schemacie JSON
  • Uwaga: Modele Qwen zazwyczaj dobrze działają, ale to zadanie przekraczało ich możliwości wyjścia strukturalnego

3. deepseek-r1:14b (14 miliardów parametrów)

  • Wynik: Nie wygenerował strukturalnego outputu
  • Problem: Podobnie jak qwen3, nie potrafił zgodzić się z wymaganiami schematu BAML
  • Uwaga: Zdolności do rozumowania nie pomogły w zgodności z formatem

4. devstral:24b (24 miliardy parametrów)

  • Wynik: Nie wygenerował strukturalnego outputu
  • Problem: Nawet z większą liczbą parametrów, nie potrafił spójnie generować prawidłowego JSON
  • Uwaga: Modele specjalistyczne do kodu nadal mieli trudności z ściślejszym zgodnością z formatem

5. ministral-3:14b (14 miliardów parametrów)

  • Wynik: Nie wygenerował strukturalnego outputu
  • Problem: Mniejszy model Mistral nie potrafił obsługiwać wymagań wyjścia strukturalnego

6. qwen3-vl:30b-a3b-instruct (30 miliardów parametrów)

  • Wynik: Nie wygenerował strukturalnego outputu
  • Problem: Zdolności wizualne nie pomogły w wyodrębnianiu tabel PDF w tym kontekście

7. gpt-oss:120b (120 miliardów parametrów)

  • Wynik: Nie zakończył przetwarzania po ponad 2 godzinach
  • Sprzęt: Ustawienie GPU konsumenta
  • Problem: Model był zbyt duży do praktycznego samozhostowania, nawet jeśli mógłby w końcu zadziałać

Kluczowe wnioski

Ograniczenie wielkości fragmentu: Cognee używa fragmentów 4k tokenów przy przetwarzaniu dokumentów z Ollama. Dla złożonych dokumentów lub modeli z większymi oknami kontekstu, to wydaje się niepotrzebnie ograniczające. Framework nie oferuje łatwego sposobu na dostosowanie tego parametru.

Wymagania dotyczące wyjścia strukturalnego: Główne wyzwanie nie jest inteligencją modelu, ale zgodnością formatu. Te modele mogą zrozumieć treść, ale utrzymanie spójnego schematu JSON w całym procesie wyodrębniania okazuje się trudne. To odpowiada większym wyzwaniom w uzyskiwaniu lokalnych modeli, które szanują ograniczenia wyjścia.

Rozważenia sprzętowe: Nawet jeśli wystarczająco duży model mógłby działać (np. gpt-oss:120b), wymagania sprzętowe czynią to nierealnym dla większości scenariuszy samozhostowania. Musiałbyś mieć znaczne pamięć GPU i moc obliczeniową.

Porównanie z najlepszymi praktykami wyjścia strukturalnego

Ta doświadczenie potwierdza lekcje z pracy z wyjściem strukturalnym na różnych dostawcach LLM. Komercyjne API od OpenAI, Anthropic i Google często mają wbudowane mechanizmy do wymuszania schematów wyjścia, podczas gdy modele lokalne wymagają bardziej zaawansowanych podejść, takich jak próbkowanie oparte na gramatyce lub wiele przejść walidacyjnych.

Dla głębszego analizy wybierania odpowiedniego LLM dla Cognee na Ollama, w tym szczegółowe porównania różnych rozmiarów modeli i ich cech wydajnościowych, dostępne są kompleksowe przewodniki, które mogą pomóc Ci podejmować świadome decyzje.

Alternatywne podejścia do samozhostowanego RAG

Jeśli jesteś zdecydowany na samozhostowanie i potrzebujesz wyodrębniania danych strukturalnych z dokumentów, rozważ te alternatywy:

1. Tradycyjny RAG z prostszym wyodrębnianiem

Zamiast budować złożony graf wiedzy od początku, użyj tradycyjnego RAG z dzieleniem dokumentów i wyszukiwaniem wektorowym. Dla wyodrębniania danych strukturalnych:

  • Parsuj tabele bezpośrednio za pomocą bibliotek takich jak pdfplumber lub tabula-py
  • Użyj prostszych monologów, które nie wymagają ściślejszej zgodności z schematem
  • Zaimplementuj walidację po przetwarzaniu w Pythonie zamiast polegania na formacie wyjścia LLM

2. Specjalistyczne modele osadzania

Jakość Twoich osadzeń znacząco wpływa na wydajność wyszukiwania. Rozważ użycie wysokiej jakości modeli osadzania, które dobrze działają lokalnie. Nowoczesne modele osadzania, takie jak oferowane przez Qwen3, zapewniają doskonałą wsparcie wielojęzycznego i mogą znacząco poprawić dokładność Twojego systemu RAG.

3. Ponowne rankowanie dla lepszych wyników

Nawet z prostszymi architekturami RAG, dodanie kroku ponownego rankowania może znacząco poprawić wyniki. Po początkowym wyszukiwaniu wektorowym, model ponownego rankowania może lepiej ocenić odpowiedność. Taki dwuskładnikowy podejście często przewyższa bardziej złożone systemy jednokrokowe, szczególnie przy pracy z ograniczonym sprzętem.

4. Hybrydowe strategie wyszukiwania

Połączenie wyszukiwania wektorowego z tradycyjnym wyszukiwaniem słów kluczowych (BM25) często daje lepsze wyniki niż każde z nich oddzielnie. Wiele nowoczesnych baz wektorowych obsługuje wyszukiwanie hybrydowe z domyślną konfiguracją.

5. Rozważ alternatywy dla baz wektorowych

Jeśli budujesz system RAG od podstaw, ocenić różne bazy wektorowe na podstawie swoich potrzeb. Opcje obejmują od lekkich baz danych wbudowanych po systemy rozproszone zaprojektowane do skalowania produkcyjnego.

Rozważenia dotyczące wdrażania w kontenerach

Dla produkcyjnego samozhostowania, konteneryzacja swojego ustawienia RAG upraszcza wdrażanie i skalowanie. Gdy uruchamiasz Cognee lub podobne frameworki z Ollama:

# Uruchom Ollama w kontenerze
docker run -d --gpus=all -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama

# Pobierz swoje modele
docker exec -it ollama ollama pull gpt-oss:20b

# Skonfiguruj Cognee, aby połączyć się z punktem końcowym kontenera

Upewnij się, że poprawnie skonfigurujesz przechodzenie GPU i montaż woluminów dla trwałości modeli.

Nauczona lekcja

1. Dopasuj narzędzia do sprzętu: Cognee jest zaprojektowany do LLM w skali chmurowej. Jeśli samozhostujesz na sprzęcie konsumenta, prostsze architektury mogą być bardziej praktyczne.

2. Wyjście strukturalne to trudne: Uzyskanie spójnej zgodności z schematem z lokalnymi LLM nadal jest trudne. Jeśli Twoja aplikacja krytycznie zależy od wyjścia strukturalnego, albo użyj komercyjnych API, albo zaimplementuj solidną walidację i logikę ponownego próbowania.

3. Testuj wczesnie: Przed zaangażowaniem się w framework, przetestuj go z Twoim konkretnym przypadkiem użycia i sprzętem. To, co działa w demonstracjach, może nie działać w skali lub z Twoimi dokumentami.

4. Rozważ podejścia hybrydowe: Użyj komercyjnych API do złożonych zadań wyodrębniania i lokalnych modeli do prostszych zapytań, aby zrównoważyć koszt i możliwości.

Ciekawe czytanie

Wyjście strukturalne z LLM

Zrozumienie wyjścia strukturalnego jest kluczowe dla frameworków takich jak Cognee. Te artykuły zagłębiają się w uzyskiwaniu spójnych, zgodnych z schematem odpowiedzi od LLM:

Architektura i implementacja RAG

Dla alternatywnych lub uzupełniających podejść do wyodrębniania i odzyskiwania wiedzy:

Osadzanie i ponowne rankowanie

Poprawianie jakości odzyskiwania poprzez lepsze osadzanie i ponowne rankowanie:

Narzędzia i zasoby

Zasoby zewnętrzne