자체 호스팅 Cognee: LLM 성능 테스트

로컬 LLM을 사용하여 Cognee 테스트 - 실제 결과

Page content

Cognee는 문서에서 지식 그래프를 생성하기 위한 Python 프레임워크입니다. 하지만 이 프레임워크는 자체 호스팅된 모델과 호환되는가요?

저는 여러 로컬 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는 자바스크립트 렌더링된 페이지 처리를 가능하게 합니다.

예제 코드 및 사용법

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시간 이상 소요 후 처리 완료되지 않음
  • 하드웨어: 소비자 GPU 설정
  • 문제: 모델이 너무 커서 실질적인 자체 호스팅 사용에 실용적이지 않음, 이론적으로는 작동할 수 있음

주요 발견

조각 크기 제한: Cognee는 Ollama와 함께 문서를 처리할 때 4k 토큰 조각을 사용합니다. 복잡한 문서나 더 큰 맥락 창을 갖는 모델에 대해 이는 불필요하게 제한적입니다. 프레임워크는 이 매개변수를 조정하기 위한 간단한 방법을 제공하지 않습니다.

구조화된 출력 요구사항: 핵심 문제는 모델의 지능이 아니라 형식 준수입니다. 이 모델들은 내용을 이해할 수 있지만, 추출 과정에서 일관된 JSON 스키마를 유지하는 것이 어렵습니다. 이는 로컬 모델이 출력 제약을 준수하도록 하는 데 있어 더 광범위한 문제와 일치합니다.

하드웨어 고려사항: 충분히 큰 모델(예: gpt-oss:120b)이 작동할 수 있을지라도, 하드웨어 요구사항은 대부분의 자체 호스팅 시나리오에 실용적이지 않습니다. 대규모 GPU 메모리와 처리 능력이 필요합니다.

구조화된 출력 최고 실천 방법과 비교

이 경험은 다양한 LLM 제공업체와 함께 구조화된 출력을 다루는 데 있어 배운 교훈을 다시 강화합니다. OpenAI, Anthropic, Google의 상업용 API는 일반적으로 출력 스키마를 강제하는 내장 메커니즘을 갖지만, 로컬 모델은 문법 기반 샘플링이나 여러 검증 단계와 같은 더 복잡한 접근법이 필요합니다.

Cognee에서 Ollama를 사용할 때 적절한 LLM 선택에 대한 보다 깊은 분석, 다양한 모델 크기 및 성능 특성에 대한 상세한 비교가 포함된 포괄적인 가이드가 제공됩니다. 이 가이드를 통해 결정을 내릴 수 있습니다.

자체 호스팅된 RAG 대안

자체 호스팅을 고수하고 문서에서 구조화된 데이터를 추출해야 한다면, 다음 대안을 고려해 보세요:

1. 간단한 추출을 위한 전통적인 RAG

복잡한 지식 그래프를 처음부터 생성하는 대신, 전통적인 RAG를 사용하여 문서 조각화 및 벡터 검색을 수행하세요. 구조화된 데이터 추출을 위해:

  • pdfplumber 또는 tabula-py와 같은 라이브러리를 사용하여 표를 직접 파싱
  • 엄격한 스키마 준수를 요구하지 않는 간단한 프롬프트 사용
  • 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 아키텍처 및 구현

지식 추출 및 검색에 대한 대안 또는 보완적인 접근법:

임베딩 및 재정렬

더 나은 임베딩과 재정렬을 통해 검색 품질을 향상:

도구 및 자원

외부 자원