MODULE 03 / LESSON 19

Chunking در سیستم‌های RAG

مفهوم اصلی در یک سیستم RAG در محیط Production، اگرچه Vector Database ها برای Vector Retrieval بهینه شده‌اند، اما معمولاً برای افزایش کیفیت سیستم نیاز به بهینه‌سازی‌های بیشتری وجود دارد. یکی از مهم‌ترین تکنیک‌ها: Chunking است.…

نویسنده: محمد ابوطالبی۹۷۵ واژهماژول ۳: Vector Database

مفهوم اصلی

در یک سیستم RAG در محیط Production، اگرچه Vector Databaseها برای Vector Retrieval بهینه شده‌اند، اما معمولاً برای افزایش کیفیت سیستم نیاز به بهینه‌سازی‌های بیشتری وجود دارد.

یکی از مهم‌ترین تکنیک‌ها:

Chunking

است.


Chunking چیست؟

Chunking یعنی:

تقسیم کردن Documentهای متنی بزرگ موجود در Knowledge Base به بخش‌های کوچک‌تر (Chunk).

به جای اینکه یک Document بزرگ به صورت یک Vector ذخیره شود، آن را به چند قسمت کوچک‌تر تقسیم می‌کنیم و هر قسمت یک Vector جداگانه دریافت می‌کند.


چرا از Chunking استفاده می‌کنیم؟

سه دلیل اصلی وجود دارد:


1. محدودیت Embedding Modelها

بسیاری از Embedding Modelها محدودیت دارند و نمی‌توانند متن‌های بسیار طولانی را به Vector تبدیل کنند.

بنابراین Documentهای بزرگ باید به بخش‌های کوچک‌تر تقسیم شوند.


2. افزایش کیفیت Retrieval

اگر یک Document بسیار بزرگ را به یک Vector تبدیل کنیم:

  • معنی کلی Document ذخیره می‌شود.
  • اما جزئیات موضوعات داخل آن از بین می‌روند.

Chunking باعث می‌شود:

  • Vectorها دقیق‌تر باشند.
  • Retriever بتواند بخش مرتبط‌تر را پیدا کند.

3. کاهش حجم اطلاعات ارسال‌شده به LLM

بدون Chunking ممکن است کل Document به LLM ارسال شود.

نتیجه:

  • Context Window سریع پر می‌شود.
  • اطلاعات غیرمرتبط زیادی وارد Prompt می‌شود.

با Chunking:

فقط بخش مرتبط Document به LLM داده می‌شود.


مشکل Vector کردن Documentهای بزرگ

فرض کنید:

Knowledge Base شامل:

1000 کتاب

باشد.

اگر هر کتاب را به یک Vector تبدیل کنیم:

نتیجه:

1000 Vector

خواهد بود.


مشکل

یک Vector باید معنی کل کتاب را نمایش دهد.

اما یک کتاب شامل:

  • فصل‌های مختلف
  • موضوعات مختلف
  • صفحات مختلف

است.

در نتیجه:

Vector نمی‌تواند معنی دقیق یک فصل یا صفحه خاص را نشان دهد.

بلکه یک میانگین کلی از تمام محتوا ایجاد می‌کند.


نتیجه

کیفیت Search کاهش پیدا می‌کند.

همچنین Retriever به جای بخش مرتبط:

کل کتاب را برمی‌گرداند.

این موضوع باعث:

  • پر شدن Context Window LLM
  • افزایش اطلاعات غیرضروری

می‌شود.


راه‌حل: تقسیم Document به Chunk

به جای کتاب کامل:

آن را به بخش‌های کوچک‌تر تقسیم می‌کنیم.

مثلاً:

  • Page
  • Paragraph
  • Sentence

نتیجه:

به جای:

1000 Book

ممکن است داشته باشیم:

1,000,000 Paragraph

اما:

Vector Databaseها به راحتی می‌توانند این حجم Vector را مدیریت کنند.


انتخاب اندازه Chunk (Chunk Size)

یکی از مهم‌ترین تصمیم‌ها:

اندازه مناسب Chunk چقدر باشد؟


Chunk خیلی بزرگ

مثلاً:

تقسیم در سطح Chapter

مشکلات:

  • هنوز اطلاعات زیادی در یک Vector فشرده می‌شود.
  • معنی دقیق موضوعات کوچک‌تر مشخص نیست.
  • حجم زیادی وارد Context Window می‌شود.

Chunk خیلی کوچک

مثلاً:

تقسیم در سطح Word

مشکل:

Vectorها Context خود را از دست می‌دهند.

مثلاً:

یک کلمه بدون:

  • جمله قبل
  • جمله بعد
  • موضوع پاراگراف

معنی کافی ندارد.


حتی Chunk در سطح Sentence نیز ممکن است بیش از حد کوچک باشد.


اندازه مناسب Chunk

هیچ اندازه ثابت و ایده‌آلی برای همه پروژه‌ها وجود ندارد.

هدف:

ایجاد تعادل بین:

  • اطلاعات زیاد در یک Vector
  • اطلاعات کم در یک Vector

است.


Fixed Size Chunking

ساده‌ترین روش Chunking:

Fixed Size Chunking

است.

در این روش:

ابتدا اندازه Chunk مشخص می‌شود.

مثلاً:

250 Character

تقسیم:

Chunk 1:

Character 1 تا 250

Chunk 2:

Character 251 تا 500

Chunk 3:

Character 501 تا 750

و به همین ترتیب.


مشکل Fixed Size Chunking

مشکل این است که:

محل تقسیم همیشه منطقی نیست.

ممکن است:

  • وسط یک کلمه قطع شود.
  • دو بخش مرتبط یک پاراگراف از هم جدا شوند.

Overlap در Chunking

برای حل مشکل از:

Chunk Overlap

استفاده می‌شود.

یعنی:

بخشی از هر Chunk با Chunk قبلی و بعدی مشترک باشد.


مثال

Chunk Size:

250 Character

Overlap:

25 Character

تقسیم:

Chunk 1:

1 تا 250

Chunk 2:

226 تا 475

Chunk 3:

451 تا 700

در این مثال:

Overlap برابر:

10%

است.


مزایای Overlap

Overlap باعث می‌شود:

  • کلمات در مرز Chunkها قطع نشوند.
  • Context اطراف کلمات حفظ شود.

کلمات وسط Chunk:

  • Context قبل و بعد را دارند.

کلمات نزدیک مرز:

  • در دو Chunk ظاهر می‌شوند.

در نتیجه احتمال پیدا شدن همراه با Context مناسب بیشتر می‌شود.


تأثیر میزان Overlap

افزایش Overlap معمولاً:

باعث افزایش کیفیت Retrieval می‌شود.

اما هزینه دارد:

  • تعداد Vectorها افزایش پیدا می‌کند.
  • اطلاعات تکراری بیشتری ذخیره می‌شود.

Recursive Character Text Splitting

یک روش پویا‌تر:

Recursive Character Text Splitting

است.


ایده اصلی

به جای اندازه ثابت، متن بر اساس یک Character خاص تقسیم می‌شود.

مثال:

تقسیم بر اساس:

newline character

یعنی محل پایان پاراگراف‌ها.


مزیت Recursive Splitting

این روش ساختار Document را بهتر حفظ می‌کند.

نتیجه:

  • احتمال اینکه مفاهیم مرتبط در یک Chunk باقی بمانند بیشتر است.

محدودیت Recursive Splitting

اندازه Chunkها ثابت نیست.

ممکن است:

  • بعضی Chunkها بسیار بزرگ شوند.
  • بعضی Chunkها بسیار کوچک شوند.

بسته به محل قرارگیری جداکننده‌ها.


Chunking بر اساس نوع Document

اگر Knowledge Base شامل انواع مختلف Document باشد، می‌توان روش متفاوتی برای هر نوع استفاده کرد.

مثال:


HTML

تقسیم بر اساس:

  • Paragraph Tag
  • Header Tag

Python Code

تقسیم بر اساس:

  • Function Definition

Text Document

تقسیم بر اساس:

  • Newline Character

Metadata در Chunking

اگر Documentها Metadata داشته باشند:

Chunkهای ساخته‌شده باید Metadata منبع اصلی را به ارث ببرند.

مثلاً:

Document اصلی:

  • عنوان
  • نویسنده
  • تاریخ

Chunkها نیز باید این اطلاعات را داشته باشند.

همچنین می‌توان اطلاعات مکان Chunk را اضافه کرد.

مثلاً:

  • شماره صفحه
  • موقعیت در Document

کتابخانه‌های Chunking

روش‌هایی مانند:

  • Fixed Size Chunking با Overlap
  • Character Splitting

آن‌قدر ساده هستند که می‌توان آن‌ها را دستی پیاده‌سازی کرد.

اما کتابخانه‌های آماده‌ای نیز برای این کار وجود دارند.


پیشنهاد شروع

برای شروع یک سیستم RAG:

پیشنهاد مناسب:

Chunk Size ≈ 500 characters

با:

Overlap = 50 تا 100 characters

است.


جمع‌بندی

  • Chunking یعنی تقسیم Documentهای بزرگ به بخش‌های کوچک‌تر.
  • Chunking باعث افزایش کیفیت Retrieval و کاهش مصرف Context Window می‌شود.
  • تبدیل یک Document کامل به یک Vector معمولاً باعث از دست رفتن جزئیات معنایی می‌شود.
  • Chunk خیلی بزرگ باعث کاهش دقت می‌شود.
  • Chunk خیلی کوچک باعث از دست رفتن Context می‌شود.
  • Fixed Size Chunking ساده‌ترین روش است.
  • Overlap بین Chunkها باعث حفظ Context در مرزها می‌شود.
  • Recursive Character Text Splitting ساختار Document را بهتر حفظ می‌کند.
  • نوع Document می‌تواند روش Chunking مناسب را تعیین کند.
  • نقطه شروع مناسب معمولاً Chunk حدود ۵۰۰ کاراکتر با ۵۰ تا ۱۰۰ کاراکتر Overlap است.