fix: lightrag combatibility
This commit is contained in:
@@ -117,7 +117,6 @@ LLM_BINDING_API_KEY=your_api_key
|
|||||||
# LMSTUDIO_API_HOST=http://localhost:1234/v1
|
# LMSTUDIO_API_HOST=http://localhost:1234/v1
|
||||||
# LMSTUDIO_API_KEY=lm-studio
|
# LMSTUDIO_API_KEY=lm-studio
|
||||||
# MODEL_CHOICE=your-model-name
|
# MODEL_CHOICE=your-model-name
|
||||||
# VISION_MODEL_CHOICE=your-vision-model-name
|
|
||||||
# EMBEDDING_MODEL_CHOICE=text-embedding-nomic-embed-text-v1.5
|
# EMBEDDING_MODEL_CHOICE=text-embedding-nomic-embed-text-v1.5
|
||||||
### LM Studio working directory (separate from main RAG storage)
|
### LM Studio working directory (separate from main RAG storage)
|
||||||
# LMSTUDIO_WORKING_DIR=./rag_storage_lmstudio
|
# LMSTUDIO_WORKING_DIR=./rag_storage_lmstudio
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
LM Studio Integration Example with RAG-Anything
|
LM Studio Integration Example with RAG-Anything
|
||||||
|
|
||||||
This example demonstrates how to integrate LM Studio with RAG-Anything for local
|
This example demonstrates how to integrate LM Studio with RAG-Anything for local
|
||||||
multimodal document processing and querying.
|
text document processing and querying.
|
||||||
|
|
||||||
Requirements:
|
Requirements:
|
||||||
- LM Studio running locally with server enabled
|
- LM Studio running locally with server enabled
|
||||||
@@ -14,13 +14,13 @@ Create a .env file with:
|
|||||||
LMSTUDIO_API_HOST=http://localhost:1234/v1
|
LMSTUDIO_API_HOST=http://localhost:1234/v1
|
||||||
LMSTUDIO_API_KEY=lm-studio
|
LMSTUDIO_API_KEY=lm-studio
|
||||||
MODEL_CHOICE=your-model-name
|
MODEL_CHOICE=your-model-name
|
||||||
VISION_MODEL_CHOICE=your-vision-model-name # Optional for vision tasks
|
|
||||||
EMBEDDING_MODEL_CHOICE=text-embedding-nomic-embed-text-v1.5 # Default LM Studio embedding model
|
EMBEDDING_MODEL_CHOICE=text-embedding-nomic-embed-text-v1.5 # Default LM Studio embedding model
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import uuid
|
||||||
import asyncio
|
import asyncio
|
||||||
from typing import List, Dict, Any, Optional
|
from typing import List, Dict, Optional
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from openai import AsyncOpenAI
|
from openai import AsyncOpenAI
|
||||||
|
|
||||||
@@ -35,7 +35,6 @@ from lightrag.llm.openai import openai_complete_if_cache
|
|||||||
LM_BASE_URL = os.getenv('LMSTUDIO_API_HOST', 'http://localhost:1234/v1')
|
LM_BASE_URL = os.getenv('LMSTUDIO_API_HOST', 'http://localhost:1234/v1')
|
||||||
LM_API_KEY = os.getenv('LMSTUDIO_API_KEY', 'lm-studio')
|
LM_API_KEY = os.getenv('LMSTUDIO_API_KEY', 'lm-studio')
|
||||||
LM_MODEL_NAME = os.getenv('MODEL_CHOICE', 'openai/gpt-oss-20b')
|
LM_MODEL_NAME = os.getenv('MODEL_CHOICE', 'openai/gpt-oss-20b')
|
||||||
LM_VISION_MODEL_NAME = os.getenv('VISION_MODEL_CHOICE', LM_MODEL_NAME)
|
|
||||||
LM_EMBED_MODEL = os.getenv('EMBEDDING_MODEL_CHOICE', 'text-embedding-nomic-embed-text-v1.5')
|
LM_EMBED_MODEL = os.getenv('EMBEDDING_MODEL_CHOICE', 'text-embedding-nomic-embed-text-v1.5')
|
||||||
|
|
||||||
async def lmstudio_llm_model_func(prompt: str, system_prompt: Optional[str] = None,
|
async def lmstudio_llm_model_func(prompt: str, system_prompt: Optional[str] = None,
|
||||||
@@ -51,49 +50,6 @@ async def lmstudio_llm_model_func(prompt: str, system_prompt: Optional[str] = No
|
|||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def lmstudio_vision_model_func(prompt: str, system_prompt: Optional[str] = None,
|
|
||||||
history_messages: List[Dict] = None, image_data: Optional[str] = None,
|
|
||||||
messages: Optional[List[Dict]] = None, **kwargs) -> str:
|
|
||||||
"""Top-level Vision/Multimodal function for LightRAG (pickle-safe)."""
|
|
||||||
try:
|
|
||||||
if messages:
|
|
||||||
return await openai_complete_if_cache(
|
|
||||||
model=LM_VISION_MODEL_NAME,
|
|
||||||
prompt="",
|
|
||||||
system_prompt=None,
|
|
||||||
history_messages=[],
|
|
||||||
messages=messages,
|
|
||||||
base_url=LM_BASE_URL,
|
|
||||||
api_key=LM_API_KEY,
|
|
||||||
**kwargs,
|
|
||||||
)
|
|
||||||
elif image_data:
|
|
||||||
vision_messages = []
|
|
||||||
if system_prompt:
|
|
||||||
vision_messages.append({"role": "system", "content": system_prompt})
|
|
||||||
if history_messages:
|
|
||||||
vision_messages.extend(history_messages)
|
|
||||||
vision_messages.append({
|
|
||||||
"role": "user",
|
|
||||||
"content": [
|
|
||||||
{"type": "text", "text": prompt},
|
|
||||||
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{image_data}"}},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
return await openai_complete_if_cache(
|
|
||||||
model=LM_VISION_MODEL_NAME,
|
|
||||||
prompt="",
|
|
||||||
system_prompt=None,
|
|
||||||
history_messages=[],
|
|
||||||
messages=vision_messages,
|
|
||||||
base_url=LM_BASE_URL,
|
|
||||||
api_key=LM_API_KEY,
|
|
||||||
**kwargs,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return await lmstudio_llm_model_func(prompt, system_prompt, history_messages, **kwargs)
|
|
||||||
except Exception:
|
|
||||||
return await lmstudio_llm_model_func(prompt, system_prompt, history_messages, **kwargs)
|
|
||||||
|
|
||||||
async def lmstudio_embedding_async(texts: List[str]) -> List[List[float]]:
|
async def lmstudio_embedding_async(texts: List[str]) -> List[List[float]]:
|
||||||
"""Top-level embedding function for LightRAG (pickle-safe)."""
|
"""Top-level embedding function for LightRAG (pickle-safe)."""
|
||||||
@@ -114,19 +70,20 @@ class LMStudioRAGIntegration:
|
|||||||
self.base_url = os.getenv('LMSTUDIO_API_HOST', 'http://localhost:1234/v1')
|
self.base_url = os.getenv('LMSTUDIO_API_HOST', 'http://localhost:1234/v1')
|
||||||
self.api_key = os.getenv('LMSTUDIO_API_KEY', 'lm-studio')
|
self.api_key = os.getenv('LMSTUDIO_API_KEY', 'lm-studio')
|
||||||
self.model_name = os.getenv('MODEL_CHOICE', 'openai/gpt-oss-20b')
|
self.model_name = os.getenv('MODEL_CHOICE', 'openai/gpt-oss-20b')
|
||||||
self.vision_model = os.getenv('VISION_MODEL_CHOICE', self.model_name)
|
|
||||||
self.embedding_model = os.getenv('EMBEDDING_MODEL_CHOICE', 'text-embedding-nomic-embed-text-v1.5')
|
self.embedding_model = os.getenv('EMBEDDING_MODEL_CHOICE', 'text-embedding-nomic-embed-text-v1.5')
|
||||||
|
|
||||||
|
|
||||||
# RAG-Anything configuration
|
# RAG-Anything configuration
|
||||||
|
# Use a fresh working directory each run to avoid legacy doc_status schema conflicts
|
||||||
self.config = RAGAnythingConfig(
|
self.config = RAGAnythingConfig(
|
||||||
working_dir="./rag_storage_lmstudio",
|
working_dir=f"./rag_storage_lmstudio_demo/{uuid.uuid4()}",
|
||||||
parser="mineru",
|
parser="mineru",
|
||||||
parse_method="auto",
|
parse_method="auto",
|
||||||
enable_image_processing=True,
|
enable_image_processing=False,
|
||||||
enable_table_processing=True,
|
enable_table_processing=True,
|
||||||
enable_equation_processing=True,
|
enable_equation_processing=True,
|
||||||
)
|
)
|
||||||
|
print(f"📁 Using working_dir: {self.config.working_dir}")
|
||||||
|
|
||||||
self.rag = None
|
self.rag = None
|
||||||
|
|
||||||
@@ -190,13 +147,7 @@ class LMStudioRAGIntegration:
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def llm_model_func_factory(self):
|
# Deprecated factory helpers removed to reduce redundancy
|
||||||
"""Deprecated: keep for backward compatibility; returns top-level function."""
|
|
||||||
return lmstudio_llm_model_func
|
|
||||||
|
|
||||||
def vision_model_func_factory(self):
|
|
||||||
"""Deprecated: keep for backward compatibility; returns top-level function."""
|
|
||||||
return lmstudio_vision_model_func
|
|
||||||
|
|
||||||
def embedding_func_factory(self):
|
def embedding_func_factory(self):
|
||||||
"""Create a completely serializable embedding function."""
|
"""Create a completely serializable embedding function."""
|
||||||
@@ -214,9 +165,15 @@ class LMStudioRAGIntegration:
|
|||||||
self.rag = RAGAnything(
|
self.rag = RAGAnything(
|
||||||
config=self.config,
|
config=self.config,
|
||||||
llm_model_func=lmstudio_llm_model_func,
|
llm_model_func=lmstudio_llm_model_func,
|
||||||
vision_model_func=lmstudio_vision_model_func,
|
|
||||||
embedding_func=self.embedding_func_factory(),
|
embedding_func=self.embedding_func_factory(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Compatibility: avoid writing unknown field 'multimodal_processed' to LightRAG doc_status
|
||||||
|
# Older LightRAG versions may not accept this extra field in DocProcessingStatus
|
||||||
|
async def _noop_mark_multimodal(doc_id: str):
|
||||||
|
return None
|
||||||
|
self.rag._mark_multimodal_processing_complete = _noop_mark_multimodal
|
||||||
|
|
||||||
print("✅ RAG-Anything initialized successfully!")
|
print("✅ RAG-Anything initialized successfully!")
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -297,7 +254,8 @@ Key benefits include:
|
|||||||
await self.rag.insert_content_list(
|
await self.rag.insert_content_list(
|
||||||
content_list=content_list,
|
content_list=content_list,
|
||||||
file_path="lmstudio_integration_demo.txt",
|
file_path="lmstudio_integration_demo.txt",
|
||||||
doc_id="demo-content-001",
|
# Use a unique doc_id to avoid collisions and doc_status reuse across runs
|
||||||
|
doc_id=f"demo-content-{uuid.uuid4()}",
|
||||||
display_stats=True
|
display_stats=True
|
||||||
)
|
)
|
||||||
print("✅ Sample content added to knowledge base")
|
print("✅ Sample content added to knowledge base")
|
||||||
|
|||||||
Reference in New Issue
Block a user