Autonomiczne hostowanie Cognee: Testy wydajności modelu LLM

Testowanie Cognee z lokalnymi modelami LLM - rzeczywiste wyniki

Page content

Cognee to framework w języku Python do tworzenia grafów wiedzy z dokumentów za pomocą LLM. Ale działa on z modelami samowystawianymi?

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 dla lokalnych konfiguracji RAG oczekujących na automatyczne wyodrębnianie danych z PDF (np. list cen), nie powiodło się na moim sprzęcie. Wysoka zależność ramki od wyjścia strukturalnego sprawia, że trudno jest mniejszym modelom lokalnym działać niezawodnie.

Co to jest Cognee?

Cognee to otwarty framework w języku Python, zaprojektowany do tworzenia grafów wiedzy z niestrukturalnych dokumentów za pomocą LLM. Odpowiednio odmienia się od klasycznych systemów RAG, które po prostu dzielą i osadzają dokumenty, Cognee próbuje stworzyć zrozumienie semantyczne, wyodrębniając jednostki, relacje i pojęcia w bazę danych grafów. Taki podejście zgadza się z zaawansowanymi architekturami RAG, jak GraphRAG, które obiecują lepsze odzyskiwanie kontekstowe.

Ramka obsługuje wiele backendów:

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

Dla entuzjastów samowystawiania, kompatybilność Cognee z Ollama czyni ją przyciągająca 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 opiera się mocno na wyjściu strukturalnym, aby wyodrębniać informacje z dokumentów w spójny format. Przetwarzając dokument, LLM musi zwrócić poprawnie sformatowany JSON zawierający jednostki, relacje i metadane. To miejsce, gdzie wiele 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ą w większym stopniu typowe dla ekosystemu LLM, pracując z lokalnymi modelami.

Konfiguracja

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

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ść strukturalnych LLM, co czyni go naturalnym wyborem do zadań wyodrębniania grafów wiedzy.

Dostawca LLM: Użycie kompatybilnego z OpenAI API endpointu Ollama (/v1) umożliwia Cognee traktowanie go jak każdy inny usługę stylu OpenAI.

Model osadzania: Model SFR-Embedding-Mistral (4096 wymiarów) zapewnia wysokiej jakości osadzenia. Aby uzyskać więcej informacji na temat wyboru modeli osadzania i ich wydajności, modele Qwen3 oferują świetne alternatywy z silnymi możliwościami wielojęzycznymi.

Bazy danych: SQLite dla metadanych, LanceDB dla wektorów i Kuzu dla grafu wiedzy pozostawia wszystko lokalne 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 scraping dodaje możliwości skrapowania, a Playwright umożliwia przetwarzanie stron JavaScript.

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 czystą przestrzeń 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 semantycznych tagów, 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())

Oprócz klasycznego wyszukiwania wektorowego w systemach RAG, Cognee zapytania wysyła do grafu wiedzy, teoretycznie umożliwiając bardziej zaawansowane odzyskiwanie oparte na relacjach. Jest to podobne do działania zaawansowanych architektur RAG, ale wymaga pomyślnego wykonania początkowej konstrukcji grafu.

Wyniki testów: wydajność LLM

Przetestowałem Cognee z rzeczywistym przypadkiem użycia: wyodrębnianie informacji o produktach 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:

Modele testowane

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

  • Wynik: Nie powiodło się z błędami kodowania znaków
  • Problem: Zwrócił zniekształcone wyjście strukturalne z niepoprawnymi kodami znaków
  • Uwaga: Choć został specjalnie zaprojektowany do kompatybilności z otwartym źródłem, nie mógł utrzymać spójnego formatowania JSON

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

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

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

  • Wynik: Nie powiodło się w generowaniu wyjścia strukturalnego
  • Problem: Podobnie jak qwen3, nie potrafił zgodzić się z wymaganiami schematu BAML
  • Uwaga: Możliwości rozumowania nie pomagały w zgodności z formatem

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

  • Wynik: Nie powiodło się w generowaniu wyjścia strukturalnego
  • Problem: Nawet z większą liczbą parametrów, nie potrafił spójnie generować poprawnego JSON
  • Uwaga: Modele specjalistyczne do kodu nadal mieli trudności z ściślejszym zgodnością ze schematem

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

  • Wynik: Nie powiodło się w generowaniu wyjścia strukturalnego
  • Problem: Mniejszy model Mistral nie potrafił wykonać wymagań wyjścia strukturalnego

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

  • Wynik: Nie powiodło się w generowaniu wyjścia strukturalnego
  • Problem: Możliwości wizualne nie pomagały w wyodrębnianiu tabel z PDF w tym kontekście

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

  • Wynik: Nie ukończył przetwarzania po ponad 2 godzinach
  • Sprzęt: Konsumerski zestaw GPU
  • Problem: Model był zbyt duży do praktycznego samowystawiania, nawet jeśli mogłoby to w końcu zadziałać

Kluczowe wnioski

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

Wymagania dotyczące wyjścia strukturalnego: Główne pytanie nie jest inteligencją modelu, ale zgodnością z formatem. Te modele mogą zrozumieć treść, ale utrzymanie spójnego schematu JSON w całym procesie wyodrębniania udaje się trudno. To zgadza się z większymi wyzwaniami w uzyskiwaniu lokalnych modeli, które szanują ograniczenia wyjścia.

Rozważania 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 w większości scenariuszy samowystawiania. Musiałbyś mieć znaczne ilości pamięci GPU i mocy obliczeniowej.

Porównanie z najlepszymi praktykami wyjścia strukturalnego

Ta doświadczenie wzmacnia lekcje z pracy z wyjściem strukturalnym wśród różnych dostawców 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łębszej analizy wybierania odpowiedniego LLM dla Cognee na Ollama, w tym szczegółowe porównania różnych rozmiarów modeli i ich cech wydajnościowych, są dostępne kompleksowe przewodniki, które mogą pomóc w podejmowaniu świadomego decyzji.

Alternatywne podejścia do samowystawianego RAG

Jeśli jesteś zaangażowany w samowystawianie i potrzebujesz wyodrębnienia danych strukturalnych z dokumentów, rozważ te alternatywy:

1. Klasyczny RAG z prostszym wyodrębnieniem

Zamiast budować złożony graf wiedzy na wstępie, użyj klasycznego RAG z fragmentowaniem 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 przetworzeniu w Pythonie zamiast polegania na formacie wyjścia LLM

2. Specjalistyczne modele osadzania

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

3. Ponowne rangowanie dla lepszych wyników

Nawet z prostszymi architekturami RAG, dodanie kroku ponownego rangowania może znacząco poprawić wyniki. Po początkowym wyszukiwaniu wektorowym, model ponownego rangowania może lepiej ocenić zgodność. Taki dwuetapowy podejście często przewyższa bardziej złożone systemy jednostopniowe, zwłaszcza przy ograniczonym sprzęcie.

4. Hybrydowe strategie wyszukiwania

Kombinowanie wyszukiwania wektorowego z klasycznym wyszukiwaniem słów kluczowych (BM25) często daje lepsze wyniki niż każdy z osobna. Wiele nowoczesnych baz wektorowych obsługuje wyszukiwanie hybrydowe z domyślną konfiguracją.

5. Rozważ alternatywy dla magazynów wektorowych

Jeśli budujesz system RAG od podstaw, ocenić różne magazyny wektorowe na podstawie swoich potrzeb. Opcje obejmują od lekkich baz danych wbudowanych do systemów rozproszonych zaprojektowanych do skalowania produkcyjnego.

Rozważania dotyczące wdrażania w kontenerach

Dla produkcyjnego samowystawiania, konteneryzacja swojego systemu RAG upraszcza wdrażanie i skalowanie. Przy uruchamianiu Cognee lub podobnych ramów z Ollama:

# Uruchom Ollama w kontenerze
docker run -d --gpus=all -v ollama:/root/.ollama -p 114线: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 odpowiednio skonfigurujesz przekazywanie GPU i montowanie woluminów dla trwałości modeli.

Nauczona lekcja

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

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

3. Testuj wczesnie: Przed zaangażowaniem się w ramkę, przetestuj ją z Twoim konkretnym przypadkiem użycia i sprzętem. To, co działa w demonstracjach, może nie działać w dużych skalach 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.

Powiązana lektura

Wyjście strukturalne z LLM

Zrozumienie wyjścia strukturalnego jest kluczowe dla ramów takich jak Cognee. Te artykuły głęboko analizują uzyskiwanie spójnych, zgodnych ze schematem odpowiedzi od LLM:

Architektura i implementacja RAG

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

Osadzanie i ponowne rangowanie

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

Narzędzia i zasoby

Zasoby zewnętrzne