Anwesend Ich habe Sie durch die Einrichtung einer sehr einfachen Lappenpipeline in Python geführtmit OpenAIs API, Langchain und Ihren lokalen Dateien. In diesem Beitrag werde ich die Grundlagen des Erstellens von Einbettungen aus Ihren lokalen Dateien mit Langchain erstellen, sie in einer Vektor -Datenbank mit FAISS speichern, API -Anrufe zur OpenAI -API tätigen und letztendlich Antworten generieren, die für Ihre Dateien related sind. 🌟

Bild des Autors

In diesem einfachen Beispiel zeige ich jedoch nur, wie man eine winzige .txt -Datei verwendet. In diesem Beitrag werde ich weiter darauf eingehen, wie Sie größere Dateien mit Ihrer RAG -Pipeline verwenden können, indem Sie dem Prozess einen zusätzlichen Schritt hinzufügen – Chunking.

Was ist mit Chunking?

Das Chunking bezieht sich auf den Prozess, einen Textual content in kleinere Textstücke zu analysieren – in den Kunkern -, die dann in Einbettungen umgewandelt werden. Dies ist sehr wichtig, da es uns ermöglicht, Einbetten für größere Dateien effektiv zu verarbeiten und zu erstellen. Alle Einbettungsmodelle sind mit verschiedenen Einschränkungen für die Größe des übergebenen Textes ausgestattet – ich werde in einem Second mehr Particulars zu diesen Einschränkungen eingehen. Diese Einschränkungen ermöglichen eine bessere Leistung und Reaktionen mit geringer Latenz. Für den Fall, dass der von uns bereitgestellte Textual content diese Größeneinschränkungen nicht entspricht, wird er abgeschnitten oder abgelehnt.

Wenn wir eine Lag -Pipeline -Lesung erstellen wollten, z. B. von Leo Tolstoy’s Krieg und Frieden Textual content (ein ziemlich großes Buch) Wir könnten es nicht direkt laden und in eine einzelne Einbettung umwandeln. Stattdessen müssen wir zuerst das tun Chunking – Erstellen Sie kleinere Textbrocken und erstellen Sie für jeden Einbettungen. Jedes Chunk liegt unter den Größengrenzen des von uns verwendeten Einbettungsmodells, ermöglicht es uns, jede Datei effektiv in Einbettungen umzuwandeln. Additionally a etwas mehr Die realistische Landschaft einer Lappenpipeline würde wie folgt aussehen:

Bild des Autors

Es gibt mehrere Parameter, um den Chunking -Prozess weiter anzupassen und an unsere spezifischen Anforderungen zu passen. Ein Schlüsselparameter des Chunking -Prozesses ist der Chunkgrößewas es uns ermöglicht, anzugeben, wie groß die Größe jedes Stücks ist (in Zeichen oder in Token). Der Trick hier ist, dass die von uns erstellten Stücke klein genug sein müssen, um innerhalb der Größenbeschränkungen der Einbettung verarbeitet zu werden, aber gleichzeitig sollten sie auch groß genug sein, um aussagekräftige Informationen einzubeziehen.

Nehmen wir beispielsweise an, wir möchten den folgenden Satz verarbeiten Krieg und Friedenwo Prinz Andrew über die Schlacht nachdenkt:

Bild des Autors

Nehmen wir auch an, wir haben die folgenden (ziemlich kleinen) Brocken erstellt:

Bild des Autors

Dann, wenn wir so etwas fragen würden „Was bedeutet Prinz Andrew jetzt mit“ alles gleich „?“, Wir haben möglicherweise keine gute Antwort, weil der Chunk „Aber ist es jetzt nicht alles gleich?“ dachte er. Enthält keinen Kontext und ist vage. Im Gegensatz dazu wird die Bedeutung über mehrere Stücke verstreut. Auch wenn es der Frage ähnelt, die wir stellen und möglicherweise abgerufen werden, enthält es keine Bedeutung, um eine relevante Antwort zu erstellen. Die Auswahl der entsprechenden Chunk -Größe für den Chunking -Prozess im Einklang mit der Artwork der Dokumente, die wir für den Lag verwenden, kann die Qualität der Antworten, die wir erhalten, weitgehend beeinflussen. Im Allgemeinen sollte der Inhalt eines Chunk für ein menschliches Lesen ohne andere Informationen sinnvoll sein, um auch in der Lage zu sein, für das Modell sinnvoll zu sein. Letztendlich gibt es ein Kompromiss für die Staugröße-die Stücke müssen klein genug sein, um die Größenbeschränkungen des Einbettungsmodells zu erfüllen, aber groß genug, um die Bedeutung zu erhalten.

• • •

Ein weiterer signifikanter Parameter ist die Chunk -Überlappung. So viel Überlappung möchten wir, dass die Stücke miteinander führen. Zum Beispiel in der Krieg und Frieden Beispiel, wir würden so etwas wie die folgenden Brocken bekommen, wenn wir uns für eine Stücke von 5 Zeichen entschieden haben.

Bild des Autors

Dies ist auch eine sehr wichtige Entscheidung, die wir treffen müssen, weil:

  • Größere Überlappung bedeutet mehr Anrufe und Token, die für die Einbettung der Erstellung aufgewendet werden, was teurer + langsamer bedeutet
  • Kleinere Überlappung bedeutet eine höhere Wahrscheinlichkeit, relevante Informationen zwischen den Chunk -Grenzen zu verlieren

Die Auswahl der richtigen Chunk -Überlappung hängt weitgehend von der Artwork des Textes ab, den wir verarbeiten möchten. Beispielsweise ist ein Rezeptbuch, in dem die Sprache einfach und unkompliziert ist, höchstwahrscheinlich keine exotische Chunking -Methodik. Auf der anderen Seite wie ein klassisches Literaturbuch wie Krieg und Friedenwo die Sprache sehr komplex ist und die Bedeutung in verschiedenen Absätzen und Abschnitten miteinander verbunden ist, erfordert höchstwahrscheinlich einen nachdenklicheren Ansatz für das Knacken, damit der Lappen sinnvolle Ergebnisse erzielt.

• • •

Aber was ist, wenn wir nur einen einfacheren Lappen brauchen, der zu ein paar Dokumenten aufblickt, die zu den Größenbeschränkungen jedes Einbettungsmodells, das wir in nur einem Stück verwenden, entsprechen? Benötigen wir noch den Stückenschritt oder können wir einfach eine einzige Einbettung für den gesamten Textual content machen? Die kurze Antwort lautet, dass es immer besser ist, den Chunking -Schritt auszuführen, selbst für eine Wissensbasis, die zu den Größengrenzen passt. Das liegt daran, dass wir beim Umgang mit großen Dokumenten dem Downside des bekommen in der Mitte verloren – Fehlende relevante Informationen, die in großen Dokumenten und den jeweiligen großen Einbettungen enthalten sind.

Was sind diese mysteriösen „Größenbeschränkungen“?

Eine Anfrage an ein Einbettungsmodell kann im Allgemeinen ein oder mehrere Textbrocken enthalten. Es gibt verschiedene Arten von Einschränkungen, die wir relativ auf die Größe des Textes berücksichtigen müssen, für das wir Einbettungen und seine Verarbeitung erstellen müssen. Jede dieser verschiedenen Arten von Grenzen nimmt je nach von uns verwendeten Einbettungsmodell unterschiedliche Werte. Insbesondere sind diese:

  • Chunkgrößeoder auch maximale Token professional Eingang oder Kontextfenster. Dies ist die maximale Größe in Token für jeden Chunk. Zum Beispiel für Openai’s text-embedding-3-small Einbettungsmodell, die Die Größenbeschränkung der Stücke beträgt 8.191 Token. Wenn wir ein Stück liefern, das größer als die Grenze für die Stücke ist, wird es in den meisten Fällen stillschweigend‼ ️ (eine Einbettung wird erstellt, jedoch nur für den ersten Teil, der der Klopfengrößengrenze entspricht), ohne Fehler zu erzeugen.
  • Anzahl der Brocken professional Anfrageoder auch Anzahl der Eingänge. Die Anzahl der Stücke gibt auch eine Begrenzung, die in jeder Anfrage aufgenommen werden kann. Zum Beispiel haben alle Einbettungsmodelle von OpenAI eine Grenze von 2.048 Eingängen – dh,, maximal 2.048 Stücke professional Anfrage.
  • Gesamtstoken professional Anfrage: Es gibt auch eine Einschränkung der Gesamtzahl der Token aller Stücke in einer Anfrage. Für alle Modelle von Openai,, Die maximale Anzahl der Token in allen Stücken in einer einzigen Anfrage beträgt 300.000 Token.

Was passiert additionally, wenn unsere Dokumente mehr als 300.000 Token sind? Wie Sie sich vielleicht vorgestellt haben, ist die Antwort, dass wir mehrere aufeinanderfolgende/parallele Anfragen von 300.000 Token oder weniger stellen. Viele Python -Bibliotheken tun dies automatisch hinter den Kulissen. Zum Beispiel Langchains OpenAIEmbeddings Dass ich in meinem vorherigen Beitrag verwende, ist automatisch die Dokumente, die wir bereitstellen, in Stapel unter 300.000 Token, da die Dokumente bereits in Teilen bereitgestellt werden.

Lesen Sie größere Dateien in die RAG -Pipeline

Werfen wir einen Blick darauf Krieg und Frieden Textual content als Dokument zum Abrufen im Lappen. Die Daten, die ich benutze – Leo Tolstoy’s Krieg und Frieden Textual content – ist als gemeinfrei lizenziert und kann in gefunden werden Projekt Gutenberg.

Lassen Sie uns zunächst versuchen, aus dem zu lesen Krieg und Frieden Textual content ohne Setup zum Knacken. Für dieses Tutorial müssen Sie die installiert haben langchainAnwesend openaiUnd faiss Python -Bibliotheken. Wir können die erforderlichen Pakete problemlos wie folgt installieren:

pip set up openai langchain langchain-community langchain-openai faiss-cpu

Nachdem die erforderlichen Bibliotheken installiert sind, sieht unser Code für einen sehr einfachen Lappen so aus und funktioniert intestine für eine kleine und einfache .txt -Datei in der text_folder.

from openai import OpenAI # Chat_GPT API key 
api_key = "your key" 

# initialize LLM
llm = ChatOpenAI(openai_api_key=api_key, mannequin="gpt-4o-mini", temperature=0.3)

# loading paperwork for use for RAG 
text_folder =  "RAG information"  

paperwork = ()
for filename in os.listdir(text_folder):
    if filename.decrease().endswith(".txt"):
        file_path = os.path.be part of(text_folder, filename)
        loader = TextLoader(file_path)
        paperwork.prolong(loader.load())

# generate embeddings
embeddings = OpenAIEmbeddings(openai_api_key=api_key)

# create vector database w FAISS 
vector_store = FAISS.from_documents(paperwork, embeddings)
retriever = vector_store.as_retriever()


def foremost():
    print("Welcome to the RAG Assistant. Kind 'exit' to give up.n")
    
    whereas True:
        user_input = enter("You: ").strip()
        if user_input.decrease() == "exit":
            print("Exiting…")
            break

        # get related paperwork
        relevant_docs = retriever.invoke(user_input)
        retrieved_context = "nn".be part of((doc.page_content for doc in relevant_docs))

        # system immediate
        system_prompt = (
            "You're a useful assistant. "
            "Use ONLY the next data base context to reply the consumer. "
            "If the reply just isn't within the context, say you do not know.nn"
            f"Context:n{retrieved_context}"
        )

        # messages for LLM 
        messages = (
            {"position": "system", "content material": system_prompt},
            {"position": "consumer", "content material": user_input}
        )

        # generate response
        response = llm.invoke(messages)
        assistant_message = response.content material.strip()
        print(f"nAssistant: {assistant_message}n")

if __name__ == "__main__":
    foremost()

Aber wenn ich das hinzufüge Krieg und Frieden .TXT -Datei im selben Ordner und versuchen Sie, eine Einbettung direkt dafür zu erstellen. Ich erhalte den folgenden Fehler:

Bild des Autors

Ughh 🙃

Additionally, was passiert hier? Langchains OpenAIEmbeddingsKann den Textual content nicht in separate, weniger als 300.000 Token -Iterationen aufteilen, da wir ihn nicht in Stücken zur Verfügung gestellt haben. Es spaltet nicht den Chunk, der 777.181 Token beträgt, was zu einer Anfrage führt, die die maximal professional Anfrage von 300.000 Token überschreitet.

• • •

Versuchen wir nun, den Chunking -Prozess einzurichten, um mehrere Einbettungen aus dieser großen Datei zu erstellen. Dazu werde ich die verwenden text_splitter Bibliothek von Langchain und insbesondere der RecursiveCharacterTextSplitter. In RecursiveCharacterTextSplitterDie Chunk -Größe und die Chunk -Überlappungsparameter werden als eine Reihe von Zeichen angegeben, aber andere Splitter wie TokenTextSplitter oder OpenAITokenSplitter Erlauben Sie auch, diese Parameter als eine Anzahl von Token einzurichten.

So können wir eine Instanz des Textsplitters wie unten einrichten:

splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)

… Und nutzen Sie es dann, um unser ursprüngliches Dokument in Stücke aufzuteilen…

split_docs = ()
for doc in paperwork:
    chunks = splitter.split_text(doc.page_content)
    for chunk in chunks:
        split_docs.append(Doc(page_content=chunk))

… Und dann verwenden Sie diese Stücke, um die Einbettungen zu erstellen…

paperwork= split_docs

# create embeddings + FAISS index
embeddings = OpenAIEmbeddings(openai_api_key=api_key)
vector_store = FAISS.from_documents(paperwork, embeddings)
retriever = vector_store.as_retriever()

.....

… Und voila 🌟

Jetzt kann unser Code das bereitgestellte Dokument effektiv analysieren, auch wenn es etwas größer ist, und relevante Antworten liefern.

Bild des Autors

In meinem Kopf

Die Auswahl eines Chunking -Ansatzes, der der Größe und Komplexität der Dokumente entspricht, die wir in unsere Lag -Pipeline einfügen möchten, ist entscheidend für die Qualität der Antworten, die wir erhalten. Natürlich gibt es verschiedene andere Parameter und verschiedene Chunking -Methoden, die man berücksichtigen muss. Das Verständnis und die feine Stimmungsgröße und -überlappung bilden jedoch die Grundlage für den Bau von Lag-Pipelines, die aussagekräftige Ergebnisse erzielen.

• • •

Liebte diesen Beitrag? Haben Sie ein interessantes Daten oder ein KI -Projekt?

Lass uns Freunde sein! Mach mit

📰Substanz 📝Medium 💼LinkedInKaufen Sie mir einen Kaffee!

• • •

Von admin

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert