Memperjuangkan seluruh dokumen boleh menangkap maklumat global, tetapi mungkin kehilangan butiran penting;
Chunking yang ditangguhkan menyediakan penyelesaian yang memisahkannya menjadi lebih kecil, lebih mudah sambil mengekalkan konteks dokumen penuh.
Artikel ini akan memperkenalkan penangguhan yang ditangguhkan sebagai alternatif yang lebih baik kepada kaedah chunking naif tradisional dan secara beransur -ansur menunjukkan kaedah pelaksanaannya.
Menggunakan Langchain's Rag
menyekat semula jadi dan batasannya dalam RAG
Masalahnya adalah bahawa kaedah chunking tradisional tidak menganggap kaedah persatuan maklumat apabila membahagikan dokumen. Sebagai contoh, dalam dokumentasi mengenai Paris, frasa "bandar ini" mungkin berbeza dari blok di mana "Paris" terletak. Tanpa konteks yang lengkap, model carian mungkin sukar untuk mengaitkan rujukan ini, mengakibatkan hasil yang tidak tepat. Dalam dokumen yang panjang, konteks kritikal tersebar di beberapa bahagian, yang lebih serius.
Chunking Tertunda: Memelihara Konteks dalam Segmentasi Dokumen
Kelebihan utama penangguhan yang ditangguhkan:
Melaksanakan penangguhan Chunking
<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>
Pertama, gunakan kekunci API Jina anda dan fungsi pembantu di bawah untuk memecahkan teks input ke dalam ketulan. Blok ini dilengkapi dengan anotasi span, yang membantu memecah embeddings dokumen kemudian. API Jina menggunakan sempadan semulajadi seperti perenggan atau rehat kalimat untuk memastikan bahawa blok itu bermakna dan mengekalkan maknanya.
<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>
<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>
Pertama, gunakan tagger yang serasi dengan model konteks yang panjang, seperti Jina's Embeddings-V2-Base-en, untuk memecahkan keseluruhan dokumen ke dalam tag. Seterusnya, buat embeddings untuk setiap tag menggunakan model penukar konteks yang panjang. Ini bermakna bahawa setiap perkataan atau penanda dalam dokumen mendapat penyembuhan uniknya untuk menangkap maknanya.
<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>
<code>torch.Size([1, 71, 768]) # 71 代表整个文档中的标记数</code>
Sebaik sahaja anda mempunyai embeddings tag untuk keseluruhan dokumen, anda boleh melakukan penangguhan yang ditangguhkan. Gunakan anotasi span dalam langkah satu untuk memecah tanda ini ke dalam ketulan yang lebih kecil. Kemudian, pengumpulan purata digunakan untuk purata embeds dalam setiap blok, mewujudkan satu embed untuk setiap blok. Kami kini mempunyai blok embeddings yang mengandungi maklumat konteks yang kuat dari keseluruhan dokumen.
<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>
<code>embeddings = late_chunking(model_output, [span_annotations])[0] len(embeddings)</code>
<code>3 # 与步骤 1 中的块数匹配</code>
untuk memahami kelebihan penangguhan yang tertunda, mari kita bandingkan dengan chunking tradisional:
<code>embeddings_traditional_chunking = model.encode(chunks)</code>
<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>
<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>
Seperti yang anda lihat di blok kedua dan ketiga, chunking tradisional menunjukkan skor persamaan sebanyak 70-75% berbanding dengan perkataan "Berlin". Walau bagaimanapun, dengan menggunakan chunking tertunda (mengekalkan konteks keseluruhan dokumen), skor ini meningkat kepada 82-84%. Ini menunjukkan bahawa penangguhan yang ditangguhkan melakukan pekerjaan yang lebih baik untuk memelihara konteks dan mewujudkan embeddings yang lebih bermakna, menghasilkan hasil carian yang lebih tepat.
Chunking yang ditangguhkan adalah peningkatan yang ketara kepada sistem pengambilan dokumen, terutamanya dalam saluran paip RAG. Chunking yang ditangguhkan mengekalkan konteks penuh di setiap blok dengan menunggu sehingga dokumen sepenuhnya tertanam sebelum memisahkan dokumen. Ini membawa kepada embeddings yang lebih tepat dan bermakna.
Melaksanakan RAG dengan Langchain untuk membuat chatbot untuk menjawab soalan mengenai dokumentasi teknikal. Terokai Projek
Atas ialah kandungan terperinci Lewat Chunking untuk Rag: Pelaksanaan dengan Jina Ai. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!