Spaces:
Runtime error
Runtime error
File size: 4,146 Bytes
d11e1fe bec7021 dbd9820 1737ef1 037a839 1737ef1 037a839 200fee8 ec7f6a1 d11e1fe ec7f6a1 7f617c9 ec7f6a1 073d270 7f617c9 ec7f6a1 d11e1fe 2583cf2 d11e1fe ec7f6a1 8e038e1 2c6bd00 63ed81d ec7f6a1 ecd203a ec7f6a1 63ed81d ecd203a 6a9136a 037a839 63ed81d ec7f6a1 037a839 1737ef1 d11e1fe 97d2e91 359c625 63ed81d 359c625 63ed81d 359c625 2c6bd00 359c625 63ed81d 2c6bd00 63ed81d bec7021 ec7f6a1 5ac0022 bec7021 5ac0022 d11e1fe d00f6f0 d5e5243 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
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
@app.post("/chunk")
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)
|