Spaces:
Runtime error
Runtime error
from fastapi import FastAPI | |
from pydantic import BaseModel | |
from typing import Optional | |
# ✅ Modules LlamaIndex – version >= 0.10.0+ | |
from llama_index.core.settings import Settings | |
from llama_index.core import Document | |
from llama_index.llms.llama_cpp import LlamaCPP | |
from llama_index.core.node_parser import SemanticSplitterNodeParser | |
# ✅ Pour l'embedding LOCAL via transformers | |
from transformers import AutoTokenizer, AutoModel | |
import torch | |
import torch.nn.functional as F | |
import os | |
app = FastAPI() | |
# ✅ Configuration locale du cache HF pour Hugging Face | |
# ✅ Définir un chemin autorisé pour le cache (à l'intérieur du container Hugging Face) | |
CACHE_DIR = "/app/cache" | |
os.environ["HF_HOME"] = CACHE_DIR | |
os.environ["TRANSFORMERS_CACHE"] = CACHE_DIR | |
os.environ["HF_MODULES_CACHE"] = CACHE_DIR | |
os.environ["HF_HUB_CACHE"] = CACHE_DIR | |
# ✅ Configuration du modèle d’embedding local (ex: BGE / Nomic / GTE etc.) | |
MODEL_NAME = "BAAI/bge-small-en-v1.5" | |
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, cache_dir=CACHE_DIR) | |
model = AutoModel.from_pretrained(MODEL_NAME, cache_dir=CACHE_DIR) | |
def get_embedding(text: str): | |
with torch.no_grad(): | |
inputs = tokenizer(text, return_tensors="pt", truncation=True, padding=True) | |
outputs = model(**inputs) | |
embeddings = outputs.last_hidden_state[:, 0] | |
return F.normalize(embeddings, p=2, dim=1).squeeze().tolist() | |
# ✅ Données entrantes du POST | |
class ChunkRequest(BaseModel): | |
text: str | |
source_id: Optional[str] = None | |
titre: Optional[str] = None | |
source: Optional[str] = None | |
type: Optional[str] = None | |
async def chunk_text(data: ChunkRequest): | |
try: | |
# ✅ Vérification du texte reçu | |
print(f"✅ Texte reçu ({len(data.text)} caractères) : {data.text[:200]}...") | |
print("✅ ✔️ Reçu – On passe à la configuration du modèle LLM...") | |
# ✅ Chargement du modèle LLM depuis Hugging Face (GGUF distant) | |
llm = LlamaCPP( | |
model_url="https://huggingface.co/TheBloke/CodeLlama-7B-Instruct-GGUF/resolve/main/codellama-7b-instruct.Q4_K_M.gguf", | |
temperature=0.1, | |
max_new_tokens=512, | |
context_window=2048, | |
generate_kwargs={"top_p": 0.95}, | |
model_kwargs={"n_gpu_layers": 1}, | |
) | |
print("✅✅ Le modèle CodeLlama-7B-Instruct Q4_K_M a été chargé sans erreur...") | |
print("✅ ✔️ Modèle LLM chargé sans erreur on continue...") | |
# ✅ Définition d’un wrapper simple pour l’embedding local | |
class SimpleEmbedding: | |
def get_text_embedding(self, text: str): | |
return get_embedding(text) | |
# ✅ Nouvelle configuration (⚠️ ne plus utiliser ServiceContext) | |
Settings.llm = llm | |
Settings.embed_model = SimpleEmbedding() | |
print("✅ LLM et embedding configurés - prêt pour le split") | |
print("✅ Début du split sémantique...", flush=True) | |
# ✅ Utilisation du Semantic Splitter avec le LLM actuel | |
parser = SemanticSplitterNodeParser.from_defaults(llm=llm) | |
doc = Document(text=data.text) | |
try: | |
nodes = parser.get_nodes_from_documents([doc]) | |
print(f"✅ Nombre de chunks générés : {len(nodes)}") | |
print(f"🧩 Exemple chunk : {nodes[0].text[:100]}...") | |
except Exception as e: | |
import traceback | |
traceback.print_exc() | |
print(f"❌ Erreur lors du split sémantique : {e}") | |
return {"error": str(e)} | |
# ✅ Résultat complet pour l’API | |
return { | |
"chunks": [node.text for node in nodes], | |
"metadatas": [node.metadata for node in nodes], | |
"source_id": data.source_id, | |
"titre": data.titre, | |
"source": data.source, | |
"type": data.type, | |
"error": None # ← essentiel pour que n8n voie "rien à signaler" | |
} | |
except Exception as e: | |
return {"error": str(e)} | |
if __name__ == "__main__": | |
import uvicorn | |
uvicorn.run("app:app", host="0.0.0.0", port=7860) | |