Maison > Périphériques technologiques > IA > Chunking tardif pour le chiffon: mise en œuvre avec Jina AI

Chunking tardif pour le chiffon: mise en œuvre avec Jina AI

尊渡假赌尊渡假赌尊渡假赌
Libérer: 2025-03-02 09:05:11
original
264 Les gens l'ont consulté

Late Chunking for RAG: Implementation With Jina AI

Les applications de génération améliorée (RAG) de récupération ont toujours un compromis entre deux approches: intégrer l'ensemble du document pour un meilleur contexte, ou le décomposer en morceaux plus petits pour une récupération plus précise.

Emballage de l'ensemble du document peut capturer des informations globales, mais peut perdre des détails importants; tandis que les blocs plus courts peuvent préserver les détails, mais ignorer souvent le contexte global.

Le groupe retardé fournit une solution qui le divise en morceaux plus petits et plus faciles tout en maintenant le contexte complet du document.

Cet article introduira le regroupement retardé comme une meilleure alternative à la méthode de section naïve traditionnelle et démontre progressivement sa méthode de mise en œuvre.

en utilisant le chiffon de Langchain

Utiliser la génération améliorée de récupération (RAG) et Langchain pour intégrer des données externes avec des modèles de grande langue (LLM). Explorez les cours

Blocage naturel et ses limites de chiffon

Dans le pipeline de chiffons, les documents sont décomposés en morceaux plus petits avant d'être intégrés et stockés dans une base de données vectorielle. Chaque bloc est traité indépendamment et est utilisé pour la récupération au moment de la requête. Cependant, cette approche de «secteur naïf» perd souvent un contexte à longue distance important.

Le problème est que la méthode de section traditionnelle ne tient pas compte de la méthode d'information de l'association lors de la segmentation des documents. Par exemple, dans la documentation sur Paris, l'expression «cette ville» peut finir par être différente du bloc où se trouve «Paris». Sans contexte complet, le modèle de recherche peut être difficile à corréler ces références, ce qui entraîne des résultats inexacts. Dans de longs documents, les contextes critiques sont dispersés sur plusieurs sections, ce qui est encore plus grave.

Chunking retardé: préserver le contexte dans la segmentation des documents

Le groupe retardé résout ce problème en modifiant le temps pour diviser le document. Le set retardé n'est pas de diviser le document en morceaux en premier, mais d'intégrer l'ensemble du document à l'aide d'un modèle de contexte long. Ce n'est qu'après cela que cela divise le document en petits morceaux.

Principaux avantages du regroupement retardé:

  • Garder le contexte: le regroupement retardé garantit que chaque bloc conserve le contexte global en incorporant d'abord l'ensemble du document. De cette façon, les références et les concaténations dans le texte restent intactes dans l'intégration du bloc.
  • Meilleure recherche: les incorporations de blocs créées par le groupe retardé sont plus riches et plus précises, améliorant ainsi les résultats de recherche dans les systèmes de chiffon car le modèle a une meilleure compréhension du document.
  • Traitement du texte long: très utile pour les documents longs que les modèles traditionnels ne peuvent pas être traités immédiatement en raison des limitations de balises.

En utilisant de longs modèles de contexte comme Jinai / Jina-Embeddings-V2-Base-en (en soutenant jusqu'à 8192 marques), le regroupement retardé permet d'intégrer efficacement les grandes pièces de texte avant qu'elles ne soient divisées en blocs.

Implémentation de la chasse retardée

Il s'agit d'un guide étape par étape pour mettre en œuvre un groupe retardé à l'aide du modèle d'intégration de contexte long de Jina. Vous pouvez obtenir gratuitement la clé d'API de Jina ici, et nous utiliserons le texte d'entrée suivant comme démonstration:

<code>input_text = """Berlin is the capital and largest city of Germany, both by area and by population.
Its more than 3.85 million inhabitants make it the European Union's most populous city, as measured by population within city limits.
The city is also one of the states of Germany, and is the third smallest state in the country in terms of area."""</code>
Copier après la connexion

Étape 1: Obtenez les commentaires du bloc et de l'étendue

Tout d'abord, utilisez votre clé API Jina et la fonction d'assistance ci-dessous pour diviser le texte d'entrée en morceaux. Ces blocs sont livrés avec des annotations de span, ce qui aide à diviser les intégres de documents plus tard. L'API de Jina utilise des frontières naturelles telles que les ruptures de paragraphe ou de phrases pour garantir que le bloc est significatif et conserve sa signification.

<code>import json
import requests

def custom_tokenize_jina_api(input_text: str):
    url = '<https:></https:>'
    headers = {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ENTER_YOUR_JINA_API_KEY'
    }
    data = {
        "content": input_text,
        "tokenizer": "o200k_base",
        "return_tokens": "true",
        "return_chunks": "true",
        "max_chunk_length": "1000"
    }
    # Make the API request
    response = requests.post(url, headers=headers, json=data)
    response_data = response.json()
    chunks = response_data.get("chunks", [])
    i = 1
    j = 1
    span_annotations = []
    for x in response_data['tokens']:
        if j == 1:
            j = len(x)
        else:
            j = len(x) + i
        span_annotations.append((i, j))
        i = j
    return chunks, span_annotations
chunks, span_annotations = custom_tokenize_jina_api(input_text)

print(chunks)
print(span_annotations)</code>
Copier après la connexion
<code>['Berlin is the capital and largest city of Germany, both by area and by population.\n\n', "Its more than 3.85 million inhabitants make it the European Union's most populous city, as measured by population within city limits.\n\n", 'The city is also one of the states of Germany, and is the third smallest state in the country in terms of area.']
[(1, 17), (17, 44), (44, 69)]</code>
Copier après la connexion

Étape 2: Tokenize le texte et générer un document de niveau de balise incorporer

Tout d'abord, utilisez un tagger compatible avec le modèle de contexte long, tel que les intégres Embeddings-V2-Base-en, pour diviser l'ensemble du document en balises. Ensuite, créez des incorporations pour chaque balise en utilisant le modèle de convertisseur de contexte long. Cela signifie que chaque mot ou marqueur du document obtient son intégration unique pour capturer sa signification.

<code>from transformers import AutoModel
from transformers import AutoTokenizer

# load model and tokenizer
tokenizer = AutoTokenizer.from_pretrained('jinaai/jina-embeddings-v2-base-en', trust_remote_code=True)
model = AutoModel.from_pretrained('jinaai/jina-embeddings-v2-base-en', trust_remote_code=True)
inputs = tokenizer(input_text, return_tensors='pt')
model_output = model(**inputs)
model_output[0].shape</code>
Copier après la connexion
<code>torch.Size([1, 71, 768]) # 71 代表整个文档中的标记数</code>
Copier après la connexion

Étape 3: Delay Chunking

Une fois que vous avez des incorporations de balises pour l'ensemble du document, vous pouvez faire un groupe retardé. Utilisez l'annotation de la portée à l'étape un pour diviser ces marques en morceaux plus petits. Ensuite, la mise en commun moyenne est appliquée à la moyenne des intégres dans chaque bloc, créant une seule intégration pour chaque bloc. Nous avons maintenant des incorporations de blocs qui contiennent les informations de contexte puissantes de l'ensemble du document.

<code>def late_chunking(
    model_output: 'BatchEncoding', span_annotation: list, max_length=None
):
    token_embeddings = model_output[0]
    outputs = []
    for embeddings, annotations in zip(token_embeddings, span_annotation):
        if (
            max_length is not None
        ):  # remove annotations which go bejond the max-length of the model
            annotations = [
                (start, min(end, max_length - 1))
                for (start, end) in annotations
                if start = 1
        ]
        pooled_embeddings = [
            embedding.detach().cpu().numpy() for embedding in pooled_embeddings
        ]
        outputs.append(pooled_embeddings)
    return outputs</code>
Copier après la connexion
<code>embeddings = late_chunking(model_output, [span_annotations])[0]
len(embeddings)</code>
Copier après la connexion
<code>3 # 与步骤 1 中的块数匹配</code>
Copier après la connexion

Étape 4: Comparaison de la chasse retardée et des résultats de section traditionnels

pour comprendre les avantages du regroupement retardé, comparons-le à la chasse traditionnelle:

<code>embeddings_traditional_chunking = model.encode(chunks)</code>
Copier après la connexion
<code>import numpy as np

cos_sim = lambda x, y: np.dot(x, y) / (np.linalg.norm(x) * np.linalg.norm(y))
q = "Berlin"
berlin_embedding = model.encode(q)

print(q)
print('\n')
for chunk, new_embedding, trad_embeddings in zip(chunks, embeddings, embeddings_traditional_chunking):
  print(chunk.strip())
  print(f'Late chunking:', cos_sim(berlin_embedding, new_embedding))
  print(f'Traditional chunking:', cos_sim(berlin_embedding, trad_embeddings))
  print("------------------------------------------------------------------")</code>
Copier après la connexion
<code>Berlin

Berlin is the capital and largest city of Germany, both by area and by population.
Late chunking: 0.84954596
Traditional chunking: 0.84862185
------------------------------------------------------------------
Its more than 3.85 million inhabitants make it the European Union's most populous city, as measured by population within city limits.
Late chunking: 0.82489026
Traditional chunking: 0.70843375
------------------------------------------------------------------
The city is also one of the states of Germany, and is the third smallest state in the country in terms of area.
Late chunking: 0.84980094
Traditional chunking: 0.7534553
------------------------------------------------------------------</code>
Copier après la connexion

Comme vous pouvez le voir dans les deuxième et troisième blocs, le groupe traditionnel montre des scores de similitude de 70 à 75% par rapport au mot "Berlin". Cependant, en utilisant un morceau retardé (en maintenant le contexte de l'ensemble du document), ces scores sont passés à 82 à 84%. Cela suggère que le regroupement retardé fait un meilleur travail de préservation du contexte et de création d'incorporation plus significative, ce qui a donné des résultats de recherche plus précis.

Conclusion

Le regroupement retardé est une amélioration significative du système de récupération de documents, en particulier dans le pipeline de chiffons. Le groupe retardé préserve le contexte complet de chaque bloc en attendant que le document soit entièrement intégré avant de diviser le document. Cela conduit à des intérêts plus précis et significatifs.

Projet: construire un chatbot de chiffon pour les documents techniques

Implémentez le chiffon avec Langchain pour créer un chatbot pour répondre aux questions sur la documentation technique. Explorez le projet

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal