OllamaでLLMを選択する:Self-Hosting Cognee

ローカルLLMを使用してCogneeをテストする - 実際の結果

目次

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

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

cognee processing pdf with procelist

これは私が処理しようと試みた価格リストのPDFページです。

TL;DR

Cogneeはおそらく数百億のパラメータを持つスマートなLLMと非常にうまく動作する可能性がありますが、PDFからデータを自動的に抽出する予定のセルフホストされたRAG構成(例えば価格リスト)については、私のハードウェアでは失敗しました。このフレームワークが構造化された出力に強く依存しているため、小さなローカルモデルが信頼性を持って動作するのは難しいです。

Cogneeとは?

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

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

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

セルフホスティング愛好家にとっては、CogneeがOllamaとの互換性があるため、ローカルデプロイメントに魅力的です。しかし、詳細に注意する必要があります - これから見ていくように、構造化出力の要件は小さなモデルにとって大きな課題をもたらします。

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

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

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

設定構成

CogneeとOllamaでの私の作業中の構成を以下に示します。ローカル運用を可能にするために重要な設定を注意深く見てください:

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時間以上かけて処理が完了しなかった
  • ハードウェア:コンシューマーグラフィックカード
  • 問題:モデルは実用的なセルフホスト使用には大きすぎて、最終的には動作したかもしれないが、実際には不可能だった

主な発見

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

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

ハードウェアの考慮:十分に大きなモデルが動作する可能性(gpt-oss:120b)があったとしても、ハードウェアの要件は大多数のセルフホストシナリオでは実用的ではありません。大量のGPUメモリと処理能力が必要です。

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

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

Cogneeに適したLLMの選択:Ollamaでのローカルデプロイに関するより詳しい分析が必要な場合は、さまざまなモデルサイズとその性能特性を比較した包括的なガイドが利用可能です。

セルフホストされたRAGの代替アプローチ

セルフホスティングにコミットし、ドキュメントから構造化データを抽出する必要がある場合は、以下の代替方法を検討してください:

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

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

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

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アーキテクチャと実装

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

埋め込みとリランク

より良い埋め込みとリランクにより検索品質を向上させる:

ツールとリソース

外部リソース