1 Punkte von GN⁺ 2024-11-19 | 1 Kommentare | Auf WhatsApp teilen
  • Fast GraphRAG ist ein vereinfachtes GraphRAG-Framework für agentenbasierte Such-Workflows mit hoher Präzision und guter Interpretierbarkeit und konzentriert sich darauf, fortgeschrittenes RAG an die Such-Pipeline anzubinden, ohne komplexe Agenten-Workflows direkt aufbauen zu müssen
  • Es macht Wissensgraphen für Menschen navigierbar, ermöglicht Abfragen, Visualisierung und Updates und erzeugt und verfeinert Graphen automatisch passend zu Domänen- und Ontologie-Anforderungen
  • Für Query-Antworten nutzt es graphbasierte Erkundung auf Basis von personalized PageRank, um relevante Informationen zu finden; das README verweist für einen Überblick über diesen Ansatz auf das HippoRAG-Paper
  • Im Kostenbeispiel für The Wizard of Oz werden für fast-graphrag $0.08 und für graphrag $0.48 angegeben; mit wachsender Datengröße und mehr Einfügungen soll die 6-fache Kostenersparnis noch besser werden
  • Es läuft mit Python 3.10.1 oder höher, unterstützt Installation aus dem Source sowie über PyPI und führt nach dem Setzen eines OpenAI-API-Keys Dokumenteinfügungen und Abfragen aus, wobei Wissen im selben Working Directory automatisch erhalten bleibt

Das von Fast GraphRAG bereitgestellte Such-Framework

  • Fast GraphRAG ist ein GraphRAG-Framework mit dem Ziel interpretierbaren und debuggbaren Wissens
  • Der Graph stellt Wissen in einer für Menschen erkundbaren Form bereit und unterstützt die folgenden Aufgaben
    • Abfragen
    • Visualisierung
    • Updates
  • Der Fokus liegt darauf, fortgeschrittene RAG-Funktionen bereitzustellen und zugleich den Aufwand zu verringern, Agenten-Workflows direkt aufzubauen und zu entwerfen

Hauptfunktionen

  • Es wurde für schnelle und kostengünstige Ausführung im großen Maßstab entworfen und zielt darauf ab, hohe Ressourcen- und Kostenanforderungen zu reduzieren
  • Es unterstützt dynamische Daten und erzeugt sowie verfeinert Graphen automatisch passend zu Domänen- und Ontologie-Anforderungen
  • Es unterstützt inkrementelle Updates, wenn sich Daten ändern, und ermöglicht so Echtzeit-Aktualisierungen
  • Es bietet intelligente Exploration, die graphbasierte Erkundung auf PageRank-Basis nutzt, um Genauigkeit und Zuverlässigkeit zu erhöhen
  • Insgesamt ist es asynchron aufgebaut und strebt durch vollständige Typunterstützung robuste und vorhersehbare Workflows an

Kostenbeispiel

  • Im Beispiel mit The Wizard of Oz werden für fast-graphrag $0.08 und für graphrag $0.48 angegeben
  • Das README beschreibt dies als 6-fache Kostenersparnis und sagt, dass der Spareffekt mit größerer Datenmenge und mehr Einfügungen weiter zunimmt

Installation und Ausführungsablauf

  • Die empfohlenen Installationswege teilen sich in Installation aus dem Source für Leistung und Installation über PyPI für Stabilität
    • Source-Installation: Repository klonen und dann poetry install
    • PyPI-Installation: pip install fast-graphrag
  • Im Quickstart wird zunächst die Umgebungsvariable OPENAI_API_KEY gesetzt
  • Nach dem Herunterladen des Texts von A Christmas Carol wird GraphRAG im Python-Code initialisiert
  • Die Beispielinitialisierung enthält unter anderem die folgenden Werte
    • working_dir="./book_example"
    • domain, das Figuren, Interaktionen, Orte und Beziehungen der Geschichte analysiert
    • eine Beispiel-Liste von Abfragen
    • die Entity-Typen ["Character", "Animal", "Place", "Object", "Activity", "Event"]
  • Mit grag.insert(f.read()) wird das Dokument eingefügt, und mit grag.query("Who is Scrooge?").response wird das Abfrageergebnis ausgegeben
  • Bei erneuter Initialisierung im selben Working Directory bleibt das Wissen automatisch erhalten
  • Um bei der Nutzung lokaler Modelle oder Ähnlichem die Zahl gleichzeitiger LLM-Verarbeitungsaufgaben zu steuern, kann optional eine Umgebungsvariable wie CONCURRENT_TASK_LIMIT=8 gesetzt werden

Beispiele und Konfigurationsoptionen

  • Der Ordner examples bietet Tutorials zu typischen Anwendungsfällen der Bibliothek
  • custom_llm.py ist ein einfaches Beispiel dafür, ein OpenAI-API-kompatibles Sprachmodell und den Embedder unterschiedlich zu konfigurieren
  • checkpointing.ipynb behandelt die Verwendung von Checkpoints, um irreversible Datenbeschädigung zu vermeiden
  • query_parameters.ipynb behandelt verschiedene Query-Parameter und zeigt, wie mit with_references=True Referenzen auf die in der Antwort verwendeten Informationen eingebunden werden

Designphilosophie und Explorationsansatz

  • Ziel ist es, die Zahl erfolgreicher GenAI-Anwendungen zu erhöhen; dafür werden Memory- und Daten-Tools entwickelt, damit LLM-Apps spezialisierte Such-Pipelines nutzen können, ohne komplexe Agenten-Workflows einrichten und pflegen zu müssen
  • Fast GraphRAG erkundet den Graphen mit dem personalized-PageRank-Algorithmus, um die Informationen zu finden, die für die Beantwortung der aktuellen Query am relevantesten sind
  • Als Überblick darüber, warum dieser Ansatz funktioniert, wird das HippoRAG paper als Referenz genannt

Open Source und Managed Service

  • Das Repository wird unter der MIT License bereitgestellt; Details stehen in LICENSE.txt
  • Als Möglichkeit für einen schnellen und zuverlässigen Einstieg wird ein Managed Service angeboten
  • Beim Managed Service sind die ersten 100 Requests pro Monat kostenlos, danach wird nutzungsbasiert abgerechnet
  • Wer mehr über den Managed Service erfahren möchte, kann eine demo buchen oder die docs lesen
  • Hinweise zum Beitragen stehen in CONTRIBUTING.md, Fragen können auf Discord gestellt werden

1 Kommentare

 
GN⁺ 2024-11-19
Meinungen auf Hacker News
  • Neben PageRank gibt es einige interessante Zentralitätsmaße, die RAG bei strukturierten Daten beeinflussen können.
    Triangle Centrality berechnet die Zentralität, indem Dreiecke um einen Knoten gezählt werden. Dahinter steht die Idee, dass Dreiecke Beziehungen stark schließen, während offene Verbindungen Gewicht aus dem Zentrum abziehen und die Zentralität verwässern.
    https://arxiv.org/abs/2105.00110
    In dem Paper heißt es, es sei effizienter als andere Zentralitätsmaße wie PageRank. In einer Studie mit GraphBLAS war TC auf mehreren dünn besetzten Graphen bis zu 1,8 Milliarden Kanten jedoch langsamer als unsere Sparse-PageRank-Implementierung.
    Allerdings scheint TC mit größeren Graphen besser zu skalieren, und im Bereich von Billionen Kanten könnte es deutlich effizienter sein.
    https://fossies.org/linux/SuiteSparse/GraphBLAS/Doc/The_Grap...

    • Hier liegen Knoten/Kanten im Bereich von Millionen, daher ist Effizienz kein großes Problem.
      Der Flaschenhals bei der Antwortgenerierung wird ohnehin der Teil sein, den das LLM parst.
      PageRank ist der erste Schritt, aber ich würde auch gern genauere Alternativen testen.
      Hier wird personalisiertes PageRank verwendet, bei dem eine bestimmte Menge von Knoten Anfangsgewichte erhält. Ich frage mich, ob Triangle Centrality das ebenfalls unterstützt.
      Außerdem betrachten wir auch Kantengewichte; ich würde also gern wissen, ob auch das möglich ist.
    • Ich frage mich, ob ihr als Ersatz für PageRank Authority Rank ausprobiert habt.
      https://link.springer.com/content/pdf/10.1007/978-3-030-6097...
  • Ich habe in diesem Bereich ziemlich viel gearbeitet und dabei einiges gelernt.

    1. Wenn man zum Zeitpunkt der Erfassung mit einem LLM ein wenig Vorarbeit leisten kann, liefern schon BM25-basierte lexikalische Suchen sehr relevante Ergebnisse.
    2. Embeddings funktionieren nur dann gut, wenn die Größe der Anfrage ungefähr in derselben Größenordnung liegt wie das, was man in den Embedding-Speicher legt.
    3. Es funktioniert sehr gut, wenn man das LLM aus der Anfrage eine hypothetische Antwort erzeugen lässt und dann mit dieser hypothetischen Antwort eine Embedding-Suche durchführt.
      Ich habe diese drei Dinge kombiniert und eine ähnliche Stufe zur Zerlegung/Extraktion von Wissen gebaut. Daran habe ich einen Meta-Prompter gehängt, der Domain- und Entitätstypen praktisch automatisch erzeugt.
      LLMs treffen grundsätzlich schlecht die richtige Granularität für zerlegtes Wissen.
      Ein Trick ist, das LLM eine mermaid.js-Mindmap ausgeben zu lassen, um die Eingabe in einen hierarchischen Baum aufzuteilen, und es am Ende sagen zu lassen, welche Ebene die passende Wurzel für Wissensknoten ist.
      Danach generiert man Fragen, die sich mit dem Wissen in diesem Knoten beantworten lassen, und indexiert sowie embedet diesen Fragetext.
      Selbst wenn man Nutzeranfragen per reinem BM25 direkt gegen diese Fragen matcht, bekommt man gute Ergebnisse; ein hybrider Ansatz ist besser, aber der Unterschied ist nicht riesig.
      Wenn man zur Anfragezeit kein LLM verwendet, kann man auch die Embedding-Ähnlichkeit als Kostenfunktion für die Traversierung nutzen und hierarchisch von der Wurzel zu tieferen Knoten hinabsteigen.
    • Als ich früher eine ähnliche Baumstruktur ausprobiert habe, waren die Ergebnisse gut.
      Am Ende habe ich beschlossen, als Verallgemeinerung des Baums zu einem Graphen zu wechseln.
      Das Konzept, Embedding-Ähnlichkeit zu verwenden, um durch den Graphen zu „laufen“, halte ich für zentral; auch in FastGraphRAG integrieren wir das aktiv, indem wir Kanten je nach Anfrage gewichten.
      Es ist interessant zu sehen, wie verschiedene Lösungen auf ähnliche Designs konvergieren.
    • Es wäre gut, wenn du genauer erklären könntest, was mit „zum Zeitpunkt der Erfassung mit einem LLM ein wenig Vorarbeit“ gemeint ist und welches Ziel das hat.
      Die Idee, aus der Anfrage eine hypothetische Antwort zu erzeugen und dann mit dieser Antwort eine Embedding-Suche zu machen, ist interessant; ich werde sie in die Liste der Experimente aufnehmen.
    • Schön zu hören, dass der Ansatz, aus einer Anfrage eine hypothetische Antwort zu erzeugen und sie dann im RAG-Flow zu nutzen, in der Praxis gut funktioniert.
      Jetzt frage ich mich, ob es noch besser funktioniert, wenn man die hypothetische Antwort mit einem auf das Korpus feinabgestimmten LLM erzeugt.
    • Ich frage mich, ob der Text, der in den BM25-Index kommt, in Chunks aufgeteilt wird.
      Außerdem würde ich gern wissen, ob man beim Erzeugen der hypothetischen Antwort auch eine Antwort promptet, die zur „Chunk-Größe“ passt.
  • PageRank für eine bessere Zentralität zu nutzen, klingt gut, behebt aber weiterhin nicht den vermutlich unlösbaren Mangel von RAG, also den Grund, warum RAG grundsätzlich schwer zum Laufen zu bringen ist.
    Der Grund, warum alle RAG-DBs unter den Erwartungen bleiben, ist, dass RAG die Beziehungen zwischen Wörtern, die nötig sind, um die vom Nutzer gewünschten Informationen zu finden, im Kern nicht findet.
    Das klingt vielleicht seltsam, und man könnte meinen, der ursprüngliche „Attention“-Mechanismus sollte genau darin gut sein, aber in der Praxis reicht er nicht aus.
    Nehmen wir zum Beispiel an, ein Text sagt, dass eine Person namens „Sharon“ an mehreren physikalisch-chemischen Konferenzen teilgenommen hat, nennt aber ihren Beruf nicht explizit.
    Wenn man nach „Was ist Sharons Beruf?“ sucht, werden fast alle RAG-Ansätze vermutlich nicht „Beruf“, die Konferenzteilnahme und die Art der Konferenzen miteinander verknüpfen und daraus „Chemikerin“ schließen.
    Solche Fehler treten bei der Informationssuche mit RAG über viele Arten von Informationen hinweg auf.
    Am Ende wirken Lösungen wie die oben genannten so, als würden sie andere Abfragemethoden wie SQL oder PageRank mit mehr Schritten neu erfinden, und an diesem Punkt hat die Vektorisierung nicht mehr viel Sinn.

    • Ist diese Schlussfolgerung nicht die Aufgabe des LLM?
      Die RAG-Komponente muss nur den Artikel zu Sharon in einem großen Datensatz finden und ihn vollständig als Kontext an das LLM übergeben.
    • Gerade dieses Beispiel ist doch der Kern dieses Ansatzes.
      Wenn man sich das im Originalbeitrag zitierte HippoRAG-Paper ansieht, ist das motivierende Beispiel fast identisch, und auch die Evaluation ist größtenteils auf genau diese Art von Multi-Hop-Fragebeantwortung ausgerichtet.
    • Mit einem Wissensgraphen scheint das nicht unmöglich.
      Man holt die Entität Sharon und bekommt als zusätzlichen Kontext die Knoten und Kanten, die Sharon nahe sind.
      Danach ist es Aufgabe des LLM, und wenn der Beruf im gegebenen Kontext nicht enthalten ist, sollte es sagen: „Im gegebenen Kontext kann Sharons Beruf nicht gefunden werden.“
  • Aus Interesse habe ich mich registriert und ein paar PDF-Dokumente ins Dashboard hochgeladen.
    Der Use Case ist die Analyse von Compliance-Dokumenten aus der Fertigung in einem AI-Startup; damit das für uns nützlich ist, müssen wir verstehen, bis zu welcher Größenordnung es funktioniert und wie das Kostenmodell aussieht.
    Pro Kunde gibt es etwa 300.000 PDFs, und wir erwarten, dass sich monatlich rund 10 % des Dokumentbestands ändern.
    Jedes GraphRAG-System muss Dokumente in großem Maßstab verarbeiten; S3 könnten wir als Ingestion-Mechanismus nutzen, aber wir müssen Kosten und Verarbeitungszeit kennen, bis das System zu folgenden Zeitpunkten nutzbar ist:

    1. Initialer Load
    2. Regelmäßige Updates — zum Beispiel, wie das System Daten löscht
    • Ich denke, wir können helfen.
      Ich würde gern ausführlicher darüber sprechen; melde dich bitte unter antonio [at] circlemind.co.
  • Interessant; ich frage mich, wie groß ein domänenspezifischer Textkorpus sein muss, um einen nützlichen Knowledge Graph zu erhalten.
    Aider wendet schon seit einiger Zeit PageRank auf den Call Graph von Code-Repositories an.
    Jeder nichttriviale Code hat viel Graphstruktur, die PageRank stützt, und das funktioniert sehr gut, um den relevantesten Kontext im Projekt für die aktuelle Aufgabe zu finden.
    https://aider.chat/docs/repomap.html#optimizing-the-map

    • Ich habe es von Kurzgeschichten bis hin zu kompletten Dokumenten mit Millionen von Tokens ausprobiert, und beides scheint interessante Graphen zu erzeugen.
      Sobald mehr Leute es ausprobieren, würde ich gern Feedback hören.
    • Ich nutze Aider gern, habe aber noch nie erfolgreich eine repo map erstellt, egal ob die Codebasis Python, JS oder TS war.
      Ich frage mich, ob geplant ist, die Erstellung einer repo map erzwingen und sie inspizieren zu können.
  • Cool.
    Ich frage mich, wie der Graph gespeichert und abgefragt wird.
    Mit Graphdatenbanken bin ich vertraut, aber es sieht nicht nach einer Abhängigkeit aus.
    Außerdem interessiert mich, ob ihr für die Extraktion das sciphi triplex model ausprobiert habt.
    Als ich früher Extraktionen getestet habe, waren die Ergebnisse inkonsistent, wenn derselbe Chunk mehrfach hintereinander extrahiert wurde.

    • Der Graph wird derzeit mit python-igraph gespeichert.
      Die Codebasis ist so ausgelegt, dass sich mit einem schlanken Wrapper praktisch jede Graph-DB leicht integrieren lässt; in naher Zukunft wollen wir Dinge wie neo4j unterstützen.
      Triplex haben wir noch nicht ausprobiert, weil gpt4o-mini bisher schnell und genau genug war.
      Wir verwenden gpt4o-mini nicht nur für die Extraktion von Entitäten und Beziehungen, sondern auch für die Generierung von Beschreibungen und die Konfliktauflösung.
      Mit Fine-Tuning würden die Ergebnisse definitiv besser werden.
      Graph-Abfragen funktionieren so, dass zunächst eine Menge initialer Knoten gefunden wird, die für die gegebene Anfrage relevant sind; anschließend führen wir von diesen Knoten aus personalisiertes PageRank aus, um weitere relevante Passagen zu finden.
      Derzeit wählen wir die initialen Knoten per semantischer Suche sowohl über die gesamte Anfrage als auch über die aus der Anfrage extrahierten Entitäten aus, planen aber auch einige interessante Erweiterungen dafür.
  • Gute Idee.
    Persönlich glaube ich, dass klassisches Information Retrieval für RAG der richtige Weg ist.
    Vektorsuche ist gut, aber langsam und teuer, und Leute neigen dazu, sie wie Zauberpulver einzusetzen.
    Für unstrukturierte Daten funktioniert sie gut, aber für strukturierte Daten passt sie nicht unbedingt genauso gut.
    Wenn sie nicht sehr gut getunt ist, ist Vektorsuche auch nicht wesentlich besser als gut getunte klassische Abfragen.
    Ich habe in der Praxis gesehen, dass strukturierte Daten erst in unstrukturierte Daten umgewandelt wurden, um dann Vektorsuche oder Prompt Engineering darauf anzuwenden; insgesamt fühlt sich das etwas rückwärts an.
    Es funktioniert bis zu einem gewissen Grad, aber wahrscheinlich gibt es intelligentere Wege, zum selben Ergebnis zu kommen.
    Der Kern von Graph RAG ist, die Datenstruktur zu nutzen.
    Ob das nun SQL-Joins oder Graph-DB-Abfragen sind, ist nicht so entscheidend.
    Es dürfte auch wertvoll sein, einem LLM beizubringen, wie es Abfragen stellt, oder es mit bestehenden Search-/Query-APIs interagieren zu lassen.
    Schlechte Rankings kann man mit größeren Kontextfenstern ausgleichen und über mehrere Abfragen Hunderte oder mehr Ergebnisse holen.
    So zu skalieren dürfte deutlich schneller und günstiger sein als Vektorsuche.

  • Sieht gut aus, aber nachdem ich mir an anderen Abstraktionsschichten wie LangChain die Finger verbrannt habe, mache ich mir Sorgen wegen übermäßiger Vereinfachung.
    Ich frage mich, wie ihr verhindern wollt, dieselben Fehler zu wiederholen.

  • Ich frage mich, ob es Evaluationsmetriken-Scores für Retrieval und Generierung gibt.
    Zum Beispiel auf Datensätzen wie KILT oder NQ.
    Benchmark-Datensätze sind nicht alles, aber halbwegs gute Scores und Inferenzzeiten zu zeigen, würde sehr dabei helfen, ein Framework überzeugend zu machen oder Ingenieure bei der Auswahl zu unterstützen.
    Als freiberuflicher NLP-Engineer habe ich viele RAG-Pipelines gebaut, und diese Arbeit werde ich selbst ausprobieren.

  • Ich baue derzeit einen Q&A-Chatbot und habe Schwierigkeiten mit folgendem Szenario:
    Wenn ein Nutzer fragt: „Was meinst du mit dem vorherigen Satz, den du gerade gesagt hast?“, frage ich mich, wie dieses Framework die richtige kleine Teilmenge an Rohwissen abrufen und ins LLM integrieren kann, um eine relevante Antwort zu erzeugen.
    Ohne Abhängigkeit von externen Frameworks war es schwierig, dieses Problem zu lösen.
    https://www.reddit.com/r/LocalLLaMA/comments/1gtzdid/d_optim...
    Ich würde gern wissen, wie dieses Framework dieses Problem löst und den Prozess vereinfachen kann.

    • Nach mehreren Experimenten hat in Chat-Anwendungen einzig gut funktioniert, die letzten 4–5 Nachrichten mitzugeben und, wenn möglich, den gesamten Gesprächsverlauf zu übergeben, damit das LLM die Frage im Gesprächskontext zusammenfasst.
      Ohne das schlug es häufig fehl, wenn Nutzer Fragen stellten wie „Erkläre Punkt 2 genauer“ oder „Gib ein detailliertes Beispiel für das oben Genannte“.
      Die aktuelle Implementierung nutzt drei Indizes, gibt die Anfrage und frühere Nachrichten mit und lässt das LLM sie in Folgendes zerlegen:
      vollständige Anfrage, BM25-optimierte Frage, Keywords, für semantische Suche optimierte Frage.
      Danach führen wir RAG und Re-Ranking aus und geben die Top-N-Passagen zusammen mit der vollständigen Anfrage an einen zweiten LLM-Call weiter.
    • Wenn Nutzer so etwas fragen, sollte der Agent nicht RAG aufrufen, sondern nur anhand des Gesprächsverlaufs antworten.
      Der Fokus sollte auf der Orchestrierungsschicht liegen.
      Schau dir ReAct Agents an; man kann das mit LangGraph oder Bedrock Agents bauen.
    • Ich frage mich, ob ihr ausprobiert habt, das LLM per Tool-Nutzung oder direkter Abfrage entscheiden zu lassen, ob Wissenssuche verwendet werden soll.