セルフホスティングされたCognee:LLM性能テスト

ローカルLLMでCogneeをテストする - 実際の結果

目次

CogneeはPythonフレームワークで、LLMを使用してドキュメントから知識グラフを構築するためのものです。 しかし、これは自社ホストされたモデルと互換性があるのでしょうか?

私は複数のローカルLLMで試してみた。

cognee processing pdf with procelist

これは私が処理しようとした価格一覧のPDFページです。

TL;DR

Cogneeはおそらく数百億のパラメータを持つスマートなLLMと組み合わせてうまく機能しますが、自社ホストされたRAGの設定でPDF(例えば価格一覧)から自動的にデータを抽出することを期待する場合、私のハードウェアでは失敗しました。このフレームワークは構造化された出力に大きく依存しており、より小さなローカルモデルが信頼性高く動作するには課題があります。

Cogneeとは?

Cogneeは、LLMを使用して非構造化ドキュメントから知識グラフを構築するように設計されたオープンソースのPythonフレームワークです。伝統的なRAGシステムが単にドキュメントをチャンク化して埋め込むのとは異なり、Cogneeはエンティティ、関係性、概念をグラフデータベースに抽出して、意味的理解を試みます。このアプローチは、GraphRAGなどの高度なRAGアーキテクチャと一致しており、より良い文脈検索を約束します。

このフレームワークは複数のバックエンドをサポートしています:

  • ベクトルデータベース:LanceDB(デフォルト)、他ベクトルストアもサポート
  • グラフデータベース:Kuzu(デフォルト)、複雑な関係性クエリを可能に
  • LLMプロバイダ:OpenAI、Anthropic、Ollama、他
  • 構造化された出力フレームワーク:BAMLおよびInstructorによる制約付き生成

自社ホスティングを好むユーザーにとって、CogneeのOllamaとの互換性はローカルデプロイメントに魅力的です。しかし、詳細に注意が必要です。次の通り、構造化された出力の要件は小さなモデルにとって大きな課題になります。

構造化された出力がなぜ重要なのか

Cogneeはドキュメントから情報を一貫したフォーマットで抽出するために構造化された出力に大きく依存しています。ドキュメントを処理する際、LLMはエンティティ、関係性、メタデータを含む適切にフォーマットされたJSONを返す必要があります。ここが多くの小さなモデルが苦労する点です。

構造化された出力をあなたのプロジェクトで使用している場合、これらの制約を理解することは非常に重要です。私がCogneeで遭遇した課題は、ローカルモデルを使用するLLMエコシステムにおけるより広範な問題と一致しています。

設定構成

これが私のOllamaと組み合わせたCogneeの動作構成です。ローカル操作を可能にするために重要な設定を注目してください:

TELEMETRY_DISABLED=1

# STRUCTURED_OUTPUT_FRAMEWORK="instructor"
STRUCTURED_OUTPUT_FRAMEWORK="BAML"  

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


# 埋め込み設定
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"  

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

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


# データベース設定(デフォルト)
DB_PROVIDER="sqlite"  
VECTOR_DB_PROVIDER="lancedb"  
GRAPH_DATABASE_PROVIDER="kuzu"

# 認証
REQUIRE_AUTHENTICATION=False
ENABLE_BACKEND_ACCESS_CONTROL=False

主要な設定選択

構造化された出力フレームワーク:私はBAMLを試しました。これは基本的なプロンプトよりも出力スキーマの制御を提供します。BAMLは構造化されたLLM出力に特化しており、知識グラフ抽出タスクに自然な適合性があります。

LLMプロバイダ:OllamaのOpenAI互換APIエンドポイント(/v1)を使用することで、Cogneeは他のOpenAIスタイルのサービスとして扱うことができます。

埋め込みモデル:SFR-Embedding-Mistralモデル(4096次元)は高品質な埋め込みを提供します。埋め込みモデルの選択とパフォーマンスについての詳細については、Qwen3の埋め込みモデルは多言語能力が強く、優れた代替手段です。

データベース:SQLiteはメタデータ用、LanceDBはベクトル用、Kuzuは知識グラフ用に使用することで、外部依存なしにすべてをローカルに保つことができます。

Cogneeのインストール

uv(またはpip)を使用してインストールは簡単です。uvを使用することを強くお勧めします。これは依存関係の解決が速いためです:

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

[ollama][baml][instructor]はローカルLLM操作と構造化された出力に必要な依存関係をインストールします。scrapingはウェブスクレイピング機能を追加し、PlaywrightはJavaScriptレンダリングされたページの処理を可能にします。

例のコードと使用法

Cogneeを使用してドキュメントを処理するための基本ワークフローを以下に示します。まず、ドキュメントを追加し知識グラフを構築します:

msy-add.py:

import cognee
import asyncio

async def main():

    # Cogneeのためのクリーンなスレートを作成 - データとシステム状態をリセット
    await cognee.prune.prune_data()
    await cognee.prune.prune_system(metadata=True)
    
    # サンプルコンテンツを追加
    await cognee.add(
        "/home/rg/prj/prices/msy_parts_price_20251224.pdf",
        node_set=["price_list", "computer_parts", "2025-12-24", "aud"]
    )
    
    # LLMを使用して知識グラフを構築
    await cognee.cognify()

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

node_setパラメータは、ドキュメントを知識グラフでカテゴリ化するための語義タグを提供します。cognify()メソッドは魔法(または問題)が起こる場所です。これはドキュメントチャンクをLLMに送信してエンティティと関係性を抽出します。

msy-search.py:

import cognee
import asyncio

async def main():

    # 知識グラフを検索
    results = await cognee.search(
        query_text="価格一覧にどのような製品がありますか?"
#       query_text="32GB RAM(2x16GBモジュール)の平均価格はどのくらいですか?"
    )
    
    # 表示
    for result in results:
        print(result)

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

伝統的なRAGシステムのベクトル検索とは異なり、Cogneeは知識グラフをクエリします。理論的には、より複雑な関係性に基づく検索が可能になります。これは高度なRAGアーキテクチャの動作方法と類似していますが、初期のグラフ構築が成功する必要があります。

テスト結果:LLMのパフォーマンス

私はCogneeを現実的なユースケースで試しました:コンピュータ部品の価格一覧PDFから製品情報を抽出すること。これは理想的なシナリオのように見えます:タブル形式の構造化されたデータ。各モデルで何が起こったかは以下の通りです:

テストしたモデル

1. gpt-oss:20b(200億パラメータ)

  • 結果:文字エンコーディングエラーで失敗
  • 問題:不正な文字コードで構造化された出力を返しました
  • 注意:オープンソース互換性のために特に設計されていますが、一貫したJSONフォーマットを維持できませんでした

2. qwen3:14b(140億パラメータ)

  • 結果:構造化された出力を生成できませんでした
  • 問題:モデルはテキストを生成しましたが、必要なJSONスキーマではなかった
  • 注意:Qwenモデルは通常良好に動作しますが、このタスクでは構造化された出力能力を超えてしまいました

3. deepseek-r1:14b(140億パラメータ)

  • 結果:構造化された出力を生成できませんでした
  • 問題:qwen3と同様に、BAMLスキーマ要件に従うことができませんでした
  • 注意:論理的思考能力はフォーマットの遵守には役立ちませんでした

4. devstral:24b(240億パラメータ)

  • 結果:構造化された出力を生成できませんでした
  • 問題:パラメータがより多くても、有効なJSONを一貫して生成できませんでした
  • 注意:専門的なコードモデルでも厳密なスキーマ遵守には苦労しました

5. ministral-3:14b(140億パラメータ)

  • 結果:構造化された出力を生成できませんでした
  • 問題:Mistralの小さなモデルは構造化された出力の要件を処理できませんでした

6. qwen3-vl:30b-a3b-instruct(300億パラメータ)

  • 結果:構造化された出力を生成できませんでした
  • 問題:視覚能力はこの文脈でのPDFテーブル抽出には役立ちませんでした

7. gpt-oss:120b(1200億パラメータ)

  • 結果:2時間以上かけて処理が完了しませんでした
  • ハードウェア:コンシューマーグラフィックカードセットアップ
  • 問題:モデルは実用的な自社ホスティングに適していなかったため、最終的に動作したとしても、そのハードウェアでは実現不可能でした

主な発見

チャンクサイズの制限:Ollamaを使用してドキュメントを処理する際、Cogneeは4,000トークンのチャンクを使用します。複雑なドキュメントや、より大きなコンテキストウィンドウを持つモデルでは、これは不必要に制限されているように見えます。このフレームワークではこのパラメータを簡単に調整する方法が提供されていません。

構造化された出力の要件:この問題の核心はモデルの知性ではなく、フォーマットの遵守です。これらのモデルはコンテンツを理解できますが、抽出プロセス全体を通して一貫したJSONスキーマを維持することは困難です。これは、ローカルモデルが出力制約を遵守するというより広範な課題と一致しています。

ハードウェアの考慮:十分に大きなモデル(例えばgpt-oss:120b)が動作する可能性がある場合でも、ハードウェアの要件により、大多数の自社ホスティングシナリオでは実用的ではありません。あなたは相当なGPUメモリと処理能力が必要になります。

構造化された出力のベストプラクティスとの比較

この経験は、さまざまなLLMプロバイダで構造化された出力に取り組む際の教訓を強化します。OpenAI、Anthropic、Googleなどの商用APIは出力スキーマを強制するための組み込みメカニズムを持っていますが、ローカルモデルは文法に基づくサンプリングや複数の検証パスなどのより高度なアプローチが必要です。

CogneeでOllamaを使用する際の正しいLLMの選択について、詳細な比較とさまざまなモデルサイズとパフォーマンス特性の分析を含む包括的なガイドがあります。これにより、あなたが情報に基づいた決定を下すのに役立ちます。

自社ホスティングRAGの代替アプローチ

自社ホスティングにこだわってドキュメントから構造化データを抽出する必要がある場合は、以下のような代替アプローチを検討してください:

1. 伝統的なRAGと単純な抽出

知識グラフを事前に構築する代わりに、伝統的なRAGを使用してドキュメントをチャンク化しベクトル検索を行ってください。構造化データの抽出には:

  • pdfplumbertabula-pyなどのライブラリを使用してテーブルを直接解析
  • きびしくスキーマ遵守を必要としない単純なプロンプトを使用
  • PythonでLLM出力フォーマットに依存する代わりにポスト処理検証を実装

2. 専門的な埋め込みモデル

あなたの埋め込みの品質は検索パフォーマンスに大きく影響します。ローカルでうまく動作する高パフォーマンスの埋め込みモデルを使用してみてください。Qwen3の提供する現代的な埋め込みモデルは、優れた多言語サポートを提供し、RAGシステムの正確性を劇的に向上させることができます。

3. リランキングによる結果の改善

シンプルなRAGアーキテクチャでも、リランキングステップを追加することで結果を大幅に改善できます。ベクトル検索で初期取得した後、リランカーモデルが関連性をより正確に評価できます。この二段階アプローチは、制限されたハードウェアで作業する際、より複雑な単一ステージシステムよりも多くの場合、優れたパフォーマンスを示します。

4. ハイブリッド検索戦略

ベクトル検索と伝統的なキーワード検索(BM25)を組み合わせることで、それぞれ単独よりも良い結果が得られることが多いです。多くの現代のベクトルデータベースはハイブリッド検索をデフォルトでサポートしています。

5. ベクトルストアの代替

RAGシステムをゼロから構築する場合は、あなたのニーズに応じてさまざまなベクトルストアを評価してください。選択肢は軽量な埋め込みデータベースから、生産規模に設計された分散システムまで幅広くあります。

ドッカー展開の考慮事項

生産用の自社ホスティングでは、RAG設定をコンテナ化して展開とスケーリングを簡略化します。CogneeやOllamaと同様のフレームワークを使用して実行する際には:

# コンテナでOllamaを実行
docker run -d --gpus=all -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama

# モデルをプル
docker exec -it ollama ollama pull gpt-oss:20b

# Cogneeをコンテナエンドポイントに接続するように設定

GPUの透過とボリュームマウントを適切に設定してモデルの永続性を確保してください。

学んだこと

1. ツールとハードウェアを一致させる:CogneeはクラウドスケールLLMのために設計されています。消費者ハードウェアで自社ホスティングを実施する場合は、より単純なアーキテクチャが実用的かもしれません。

2. 構造化された出力は難しい:ローカルLLMから一貫したスキーマ遵守を得ることは依然として困難です。構造化された出力に強く依存するアプリケーションでは、商用APIを使用するか、信頼性の高い検証と再試行ロジックを実装してください。

3. 早期にテストする:フレームワークにコミットする前に、あなたの特定のユースケースとハードウェアでテストしてください。デモで動作するものが、スケールアップやあなたのドキュメントで動作しない可能性があります。

4. ハイブリッドアプローチを検討する:複雑な抽出タスクでは商用APIを使用し、単純なクエリではローカルモデルを使用することで、コストと能力のバランスを取ってください。

関連読書

LLMでの構造化された出力

Cogneeなどのフレームワークでは構造化された出力の理解が非常に重要です。以下の記事ではLLMから一貫した、スキーマ遵守の応答を得る方法について深く掘り下げています:

RAGアーキテクチャと実装

知識抽出と検索のための代替または補完的なアプローチ:

埋め込みとリランキング

埋め込みとリランキングを使用して検索品質を向上させる:

ツールとリソース

外部リソース