JARVIS: asistente de voz local para Linux
Nucleo propio: oye con whisper.cpp, piensa con un modelo de Ollama, habla con Piper, y hace RAG sobre los apuntes del usuario. 100% local, sin cuentas ni claves. Escrito bajo una restriccion dura, 4 GB de VRAM: el cerebro y whisper comparten tarjeta y solo caben porque estan dimensionados para ello. El RAG usa embeddings estaticos con busqueda hibrida; la voz clonada se sirve de una cache de frases. Incluye instalador (install.sh), requisitos, y documentacion del stack, del manejo de root y de las acciones. Los apuntes indexados y el diario NO se incluyen: son privados y el .gitignore los bloquea.
This commit is contained in:
commit
8e4bc8ad94
125 changed files with 25033 additions and 0 deletions
51
config/probar_rag_temas.py
Normal file
51
config/probar_rag_temas.py
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Prueba el RAG con los temas recien ingestados de Wikipedia."""
|
||||
import os, sys, time
|
||||
sys.path.insert(0, "/app/share/newelle")
|
||||
sys.path.insert(0, os.path.expanduser(
|
||||
"~/.var/app/io.github.qwersyk.Newelle/config/pip"))
|
||||
from gi.repository import Gio # noqa: E402
|
||||
from newelle.handlers.rag.llamaindex_handler import LlamaIndexHanlder # noqa
|
||||
from newelle.handlers.embeddings.model2vec import Model2VecHandler # noqa
|
||||
|
||||
MODELOS = os.path.expanduser("~/.var/app/io.github.qwersyk.Newelle/config/models")
|
||||
PREGUNTAS = [
|
||||
"que es la criptografia de curva eliptica",
|
||||
"quien es Richard Stallman y el software libre",
|
||||
"que es el efecto invernadero y el cambio climatico",
|
||||
"que fue la guerra civil espanola",
|
||||
"que es un ataque de denegacion de servicio",
|
||||
]
|
||||
|
||||
|
||||
def main():
|
||||
settings = Gio.Settings.new("io.github.qwersyk.Newelle")
|
||||
rag = LlamaIndexHanlder(settings, MODELOS)
|
||||
if not rag.is_installed():
|
||||
print("faltan dependencias del RAG"); return 1
|
||||
rag.embedding = Model2VecHandler(settings, MODELOS)
|
||||
|
||||
class SinModelo:
|
||||
def load_model(self, *a, **k): return True
|
||||
rag.llm = SinModelo(); rag.secondary_llm = SinModelo()
|
||||
print("cargando el indice...", flush=True)
|
||||
rag.load_index()
|
||||
for pregunta in PREGUNTAS:
|
||||
print(f"\n### {pregunta}")
|
||||
ini = time.time()
|
||||
try:
|
||||
trozos = rag.get_context(pregunta, [])
|
||||
except Exception as e:
|
||||
print(f" fallo: {e}"); continue
|
||||
ms = (time.time() - ini) * 1000
|
||||
if not trozos:
|
||||
print(f" sin resultados ({ms:.0f} ms)"); continue
|
||||
print(f" {len(trozos)} trozos en {ms:.0f} ms:")
|
||||
for t in trozos[:2]:
|
||||
resumen = " ".join(str(t).split())[:280]
|
||||
print(f" · {resumen}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Loading…
Add table
Add a link
Reference in a new issue