1 puntos por GN⁺ 2024-11-19 | 1 comentarios | Compartir por WhatsApp
  • Fast GraphRAG es un framework GraphRAG simplificado para flujos de trabajo de búsqueda basados en agentes, interpretables y de alta precisión, enfocado en incorporar RAG avanzado a pipelines de búsqueda sin tener que construir directamente flujos de trabajo de agentes complejos
  • Convierte los grafos de conocimiento en una forma explorable por humanos, permite consultarlos, visualizarlos y actualizarlos, y genera y refina grafos automáticamente según los requisitos del dominio y la ontología
  • Para responder consultas, usa exploración de grafos basada en personalized PageRank para encontrar información relevante; el README enlaza el paper de HippoRAG como panorama general de este enfoque
  • En el ejemplo de costos, con The Wizard of Oz, fast-graphrag cuesta $0.08 y graphrag cuesta $0.48; se afirma que el ahorro de costos de 6 veces mejora aún más a medida que aumentan el tamaño de los datos y la cantidad de inserciones
  • Funciona con Python 3.10.1 o superior, admite instalación desde el código fuente y desde PyPI, y, tras configurar la clave de la API de OpenAI, permite insertar documentos y hacer consultas, manteniendo automáticamente el conocimiento en el mismo directorio de trabajo

El framework de búsqueda que ofrece Fast GraphRAG

  • Fast GraphRAG es un framework GraphRAG orientado a conocimiento interpretable y depurable
  • El grafo ofrece el conocimiento en una forma que las personas pueden explorar y admite las siguientes operaciones:
    • Consultas
    • Visualización
    • Actualizaciones
  • Se enfoca en ofrecer capacidades RAG avanzadas mientras reduce la carga de construir y diseñar directamente flujos de trabajo de agentes

Funciones principales

  • Está diseñado para ejecutarse a gran escala de forma rápida y de bajo costo, reduciendo requisitos pesados de recursos o costos
  • Admite datos dinámicos, generando y refinando grafos automáticamente según los requisitos del dominio y la ontología
  • Cuando los datos cambian, admite actualizaciones incrementales, lo que permite actualizaciones en tiempo real
  • Ofrece exploración inteligente que aprovecha la exploración de grafos basada en PageRank para mejorar la precisión y la confiabilidad
  • En general es asíncrono y apunta a flujos de trabajo robustos y predecibles mediante soporte completo de tipos

Ejemplo de costos

  • En el ejemplo que usa The Wizard of Oz, el costo de fast-graphrag se presenta como $0.08 y el de graphrag como $0.48
  • El README lo describe como un ahorro de costos de 6 veces, y afirma que el efecto de ahorro mejora aún más a medida que aumentan el tamaño de los datos y la cantidad de inserciones

Instalación y flujo de ejecución

  • Las formas de instalación recomendadas se dividen en instalación desde el código fuente para rendimiento e instalación desde PyPI para estabilidad
    • Instalación desde el código fuente: clonar el repositorio y luego ejecutar poetry install
    • Instalación desde PyPI: pip install fast-graphrag
  • El ejemplo de inicio rápido primero configura la variable de entorno OPENAI_API_KEY
  • Después de descargar el texto de A Christmas Carol, se inicializa GraphRAG desde código Python
  • La inicialización de ejemplo incluye los siguientes valores:
    • working_dir="./book_example"
    • un domain que analiza los personajes, interacciones, lugares y relaciones de la historia
    • una lista de consultas de ejemplo
    • tipos de entidades ["Character", "Animal", "Place", "Object", "Activity", "Event"]
  • Se inserta el documento con grag.insert(f.read()) y se imprime el resultado de la consulta con grag.query("Who is Scrooge?").response
  • Si se inicializa de nuevo en el mismo directorio de trabajo, el conocimiento se conserva automáticamente
  • Para controlar la cantidad de tareas LLM concurrentes en casos como el uso de modelos locales, se puede configurar opcionalmente una variable de entorno como CONCURRENT_TASK_LIMIT=8

Ejemplos y opciones de configuración

  • La carpeta examples ofrece tutoriales de casos de uso comunes de la biblioteca
  • custom_llm.py es un ejemplo simple para configurar de manera distinta un modelo de lenguaje compatible con la API de OpenAI y un embedder
  • checkpointing.ipynb cubre el uso de checkpoints para evitar daños irreversibles en los datos
  • query_parameters.ipynb cubre distintos parámetros de consulta y muestra cómo incluir referencias de la información usada en las respuestas con with_references=True

Filosofía de diseño y método de exploración

  • El objetivo es aumentar la cantidad de aplicaciones GenAI exitosas; para ello, se afirma que crean herramientas de memoria y datos que permiten a las apps LLM aprovechar pipelines de búsqueda especializados sin configurar ni mantener flujos de trabajo de agentes complejos
  • Fast GraphRAG explora el grafo con el algoritmo personalized PageRank para encontrar la información más relevante para responder la consulta actual
  • Como panorama general de por qué funciona este enfoque, presenta como referencia el paper de HippoRAG

Código abierto y servicio administrado

  • El repositorio se ofrece bajo MIT License, y los detalles están en LICENSE.txt
  • Ofrece un servicio administrado como forma de empezar de manera rápida y confiable
  • El servicio administrado incluye las primeras 100 solicitudes gratis cada mes; después, se cobra según el uso
  • Para saber más sobre el servicio administrado, se puede reservar una demo o consultar la documentación
  • La guía para contribuir está en CONTRIBUTING.md, y las preguntas se pueden hacer en Discord

1 comentarios

 
GN⁺ 2024-11-19
Opiniones en Hacker News
  • Además de PageRank, hay varias métricas de centralidad interesantes que pueden influir en RAG sobre datos estructurados.
    Entre ellas, Triangle Centrality calcula la centralidad contando los triángulos alrededor de un nodo, basándose en la idea de que los triángulos cierran fuertemente las relaciones, mientras que las conexiones abiertas le quitan peso al centro y diluyen la centralidad.
    https://arxiv.org/abs/2105.00110
    En el paper dicen que es más eficiente que otras centralidades como PageRank, pero en un estudio que usó GraphBLAS, TC fue más lento que nuestra implementación dispersa de PageRank en varios grafos dispersos de hasta 1.800 millones de aristas.
    Aun así, parece que TC escala mejor a medida que el grafo crece, y es muy posible que sea más eficiente en el rango de billones de aristas.
    https://fossies.org/linux/SuiteSparse/GraphBLAS/Doc/The_Grap...

    • Aquí los nodos/aristas están en el orden de millones, así que la eficiencia no es un gran problema.
      De todos modos, el cuello de botella en la generación de respuestas será la parte que parsea el LLM.
      PageRank es el primer paso, pero también me gustaría probar alternativas más precisas.
      Aquí se usa PageRank personalizado, así que se asignan pesos iniciales a un conjunto específico de nodos; me pregunto si Triangle Centrality también admite eso.
      Además, también se consideran pesos en las aristas, así que quisiera saber si eso también es posible.
    • Me pregunto si probaron Authority Rank como reemplazo de PageRank.
      https://link.springer.com/content/pdf/10.1007/978-3-030-6097...
  • He trabajado bastante en esta área y aprendí algunas cosas.

    1. Si puedes hacer un poco de trabajo con un LLM en el momento de la ingesta, solo con búsqueda léxica basada en BM25 se obtienen resultados muy relevantes.
    2. Los embeddings solo funcionan bien cuando el tamaño de la consulta es aproximadamente del mismo orden que lo que se guarda en el almacén de embeddings.
    3. Hacer que el LLM genere una respuesta hipotética a partir de la consulta y luego buscar embeddings con esa respuesta hipotética funciona muy bien.
      Combiné estas tres cosas para crear una etapa similar de descomposición/extracción de conocimiento, y le agregué un metaprompter para que generara prácticamente de forma automática el dominio/tipo de entidad.
      Por defecto, los LLM no aciertan bien el nivel correcto de granularidad del conocimiento descompuesto.
      Un truco es pedirle al LLM que emita un mapa mental en mermaid.js, que divida la entrada en un árbol jerárquico y que al final indique qué nivel es la raíz adecuada para los nodos de conocimiento.
      Luego se generan preguntas que puedan responderse con el conocimiento dentro de ese nodo, y se indexa y también se embebe el texto de esas preguntas.
      Hacer matching directo de la consulta del usuario contra esas preguntas con BM25 puro ya da buenos resultados, y un enfoque híbrido es mejor, aunque la diferencia no es enorme.
      Si no se usa un LLM en el momento de la consulta, también se puede descender jerárquicamente desde la raíz hacia nodos más profundos usando la similitud de embeddings como función de costo de recorrido.
    • Cuando experimenté antes con una estructura de árbol similar, obtuve buenos resultados.
      Al final decidí pasar a un grafo como generalización del árbol.
      Considero que el concepto central es usar la similitud de embeddings para “caminar” el grafo, y en FastGraphRAG también lo estamos integrando activamente mediante pesos en las aristas según la consulta.
      Es interesante ver cómo varias soluciones convergen hacia diseños parecidos.
    • Sería bueno que explicaras más qué es ese “un poco de trabajo con un LLM en el momento de la ingesta” y cuál es su objetivo.
      La idea de generar una respuesta hipotética a partir de la consulta y luego hacer búsqueda de embeddings con esa respuesta es interesante, y voy a agregarla a la lista de experimentos.
    • Me alegra escuchar que el enfoque de crear una respuesta hipotética a partir de la consulta y usarla en el flujo de RAG realmente funciona bien.
      Ahora me pregunto si generar la respuesta hipotética con un LLM ajustado finamente al corpus funcionaría aún mejor.
    • Me pregunto si el texto que entra al índice BM25 se divide en chunks.
      También quisiera saber si, al crear la respuesta hipotética, se le pide al modelo una respuesta ajustada al “tamaño de chunk”.
  • Usar PageRank para una mejor centralidad suena bien, pero sigue sin resolver el defecto probablemente irresoluble de RAG, es decir, la razón por la que RAG es fundamentalmente difícil de hacer funcionar.
    La razón por la que todas las bases de datos RAG rinden por debajo de lo esperado es que RAG, en esencia, no logra encontrar las relaciones entre palabras necesarias para hallar la información que el usuario quiere.
    Sonará extraño, y uno pensaría que el mecanismo original de “atención” debería ser bueno para esto, pero en la práctica no alcanza.
    Por ejemplo, supongamos que en un texto se dice que una persona llamada ‘Sharon’ asistió a varias conferencias de fisicoquímica, pero no se menciona explícitamente su profesión.
    Si buscas “¿cuál es la profesión de Sharon?”, es muy probable que casi todos los enfoques RAG no logren conectar ‘profesión’, asistencia a conferencias y el tipo de conferencias para inferir ‘química’.
    Este tipo de error aparece en muchos tipos de información al recuperar datos con RAG.
    En última instancia, soluciones como la anterior parecen reinventar, con más pasos, otros métodos de consulta como SQL o PageRank, y en ese punto la vectorización ya no tiene mucho sentido.

    • Me parece que esa inferencia es responsabilidad del LLM.
      El componente RAG solo tiene que encontrar en un gran dataset el artículo relacionado con Sharon y pasárselo completo al LLM como contexto.
    • De hecho, este ejemplo es justamente el punto central de este enfoque.
      Si miras el paper de HippoRAG citado en el post original, el ejemplo motivador es casi idéntico, y la evaluación también está orientada principalmente a preguntas y respuestas multihop de este tipo.
    • Con un grafo de conocimiento, no parece imposible.
      Se obtiene la entidad Sharon y, como contexto adicional, se reciben los nodos y aristas cercanos a Sharon.
      Después, el resto es tarea del LLM, y si en el contexto dado no está la profesión, debería decir: “No se puede encontrar la profesión de Sharon en el contexto proporcionado”.
  • Me pareció interesante, así que me registré y subí algunos documentos PDF al dashboard.
    Nuestro caso de uso es analizar documentos de cumplimiento relacionados con manufactura en una startup de IA, y para que esto nos sea útil necesitamos entender hasta qué escala funciona y cuál es el modelo de costos.
    Tenemos alrededor de 300 mil PDF por cliente, y esperamos que cerca del 10% del conjunto de documentos cambie cada mes.
    Cualquier sistema GraphRAG tendría que procesar documentos a gran escala; podríamos usar S3 como mecanismo de ingesta, pero necesitamos saber el costo y el tiempo de procesamiento hasta que el sistema quede utilizable en estos momentos:

    1. Carga inicial
    2. Actualizaciones periódicas — por ejemplo, cómo elimina datos el sistema
    • Creo que podríamos ayudar.
      Me gustaría hablarlo con más detalle; escríbeme a antonio [at] circlemind.co
  • Interesante; me pregunto qué tan grande debe ser un corpus de texto específico de dominio para obtener un grafo de conocimiento útil.
    Aider lleva tiempo aplicando PageRank al grafo de llamadas de repositorios de código.
    Cualquier código no trivial tiene mucha estructura de grafo para sustentar PageRank, y funciona muy bien para encontrar el contexto más relevante dentro del proyecto relacionado con la tarea actual.
    https://aider.chat/docs/repomap.html#optimizing-the-map

    • Hemos probado desde novelas cortas hasta documentos completos de millones de tokens, y ambos parecen generar grafos interesantes.
      Cuando más gente empiece a usarlo, nos gustaría escuchar sus comentarios.
    • Uso Aider con buenos resultados, pero nunca he logrado que genere correctamente un repo map, ya sea que el codebase esté en Python, JS o TS.
      Me pregunto si hay planes para permitir forzar la generación del repo map e inspeccionarlo.
  • Genial.
    Me da curiosidad cómo se almacena y se consulta el grafo.
    Estoy familiarizado con las bases de datos de grafos, pero no parece que sean una dependencia.
    También me pregunto si probaron el modelo sciphi triplex para la extracción.
    Cuando hice extracciones antes, si extraía el mismo chunk varias veces seguidas, los resultados no eran consistentes.

    • Actualmente el grafo se almacena con python-igraph.
      El codebase está diseñado para que sea fácil integrar cualquier base de datos de grafos escribiendo un wrapper ligero, y tenemos previsto dar soporte a cosas como neo4j en un futuro cercano.
      Todavía no hemos probado triplex, porque gpt4o-mini por ahora ha sido lo suficientemente rápido y preciso.
      Usamos gpt4o-mini no solo para la extracción de entidades y relaciones, sino también para generar descripciones y resolver conflictos.
      Con fine-tuning, los resultados seguramente mejorarían.
      La consulta del grafo funciona encontrando primero un conjunto inicial de nodos relevantes para la consulta dada y luego ejecutando PageRank personalizado desde esos nodos para encontrar otros pasajes relacionados.
      Actualmente elegimos los nodos iniciales con búsqueda semántica tanto sobre la consulta completa como sobre las entidades extraídas de la consulta, pero también tenemos planeadas algunas extensiones interesantes para este enfoque.
  • Buena idea.
    Personalmente, creo que la recuperación de información tradicional es el camino a seguir para RAG.
    La búsqueda vectorial es buena, pero lenta y cara, y la gente tiende a usarla como si fuera polvo mágico.
    Funciona bien con datos no estructurados, pero no necesariamente encaja tan bien con datos estructurados.
    A menos que esté muy bien ajustada, la búsqueda vectorial tampoco es mucho mejor que una consulta tradicional bien ajustada.
    He visto en la práctica intentos de convertir datos estructurados en datos no estructurados para luego hacer búsqueda vectorial o prompt engineering, y en general se siente un poco al revés.
    Puede funcionar hasta cierto punto, pero probablemente haya una forma más inteligente de obtener el mismo resultado.
    La esencia de Graph RAG es aprovechar la estructura de los datos.
    No importa demasiado si eso es un join de SQL o una consulta a una base de datos de grafos.
    También habría valor en enseñarle al LLM cómo consultar, o en hacerlo interactuar con APIs existentes de búsqueda/consulta.
    Los rankings deficientes se pueden compensar con tamaños de contexto más grandes y trayendo cientos o más resultados mediante varias consultas.
    Escalar de esa forma sería mucho más rápido y barato que la búsqueda vectorial.

  • Se ve bien, pero me preocupa la sobresimplificación porque ya me quemé con otras capas de abstracción como LangChain.
    Me pregunto cómo planean evitar repetir los mismos errores.

  • Me pregunto si tienen puntajes de métricas de evaluación para recuperación y generación.
    Por ejemplo, con datasets como KILT o NQ.
    Los datasets de benchmark no lo son todo, pero mostrar puntajes razonablemente buenos y tiempos de inferencia ayudaría mucho a convencer sobre el framework o a que los ingenieros lo elijan.
    Como ingeniero freelance de procesamiento de lenguaje natural he construido muchos pipelines RAG, y pienso probar esto directamente.

  • Actualmente estoy construyendo un chatbot de Q&A y me está costando manejar el siguiente escenario:
    cuando el usuario pregunta “¿qué quisiste decir con la oración anterior que acabas de mencionar?”, me pregunto cómo este framework puede recuperar el subconjunto pequeño correcto de conocimiento bruto e integrarlo en el LLM para producir una respuesta relevante.
    Me resultó difícil resolver este problema sin depender de frameworks externos.
    https://www.reddit.com/r/LocalLLaMA/comments/1gtzdid/d_optim...
    Quisiera saber cómo este framework puede resolver este problema y simplificar el proceso.

    • Después de varios experimentos, lo único que funcionó bien en aplicaciones estilo chat fue pasar los 4 o 5 mensajes más recientes y, si es posible, todo el historial de conversación, y luego pedirle al LLM que resumiera la pregunta dentro del contexto de la conversación.
      Sin esto, fallaba con frecuencia cuando el usuario preguntaba cosas como “explícame más el punto 2” o “dame un ejemplo detallado de lo anterior”.
      La implementación actual tiene tres índices; se le proporciona la consulta y los mensajes anteriores al LLM y se le pide descomponerlo en:
      solicitud completa, pregunta optimizada para BM25, palabras clave y pregunta optimizada para búsqueda semántica.
      Después se hace RAG y reranking, y se pasan los N pasajes principales junto con la solicitud completa a una segunda llamada al LLM.
    • Si el usuario hace una pregunta así, el agente no debería llamar a RAG, sino responder solo con el historial de conversación.
      Hay que concentrarse en la etapa de orquestación.
      Puedes buscar agentes ReAct; se pueden construir con LangGraph o Bedrock Agents.
    • Me pregunto si han probado dejar que el LLM decida si usar o no la búsqueda de conocimiento, ya sea mediante uso de herramientas o consultas directas.