ی عربی، نیم فاصله و PDF برعکس: سه دشمن پنهان جست وجوی فارسی در هوش مصنوعی!

13 آبان 1405 - خواندن 12 دقیقه - 60 بازدید

چرا چت بات های هوش مصنوعی متن فارسی را درست پیدا نمی کنند؟

این روزها خیلی از شرکت ها و سازمان ها چت بات هایی دارند که از روی سندهای خودشان جواب می دهند: دستیار پشتیبانی ای که آیین نامه ها را می خواند، چت باتی که از دل قراردادها و گزارش ها جواب پیدا می کند، یا ابزاری که به سوال کارمندان درباره مستندات داخلی پاسخ می دهد. اگر با یکی از این ها به فارسی کار کرده باشید، احتمالا دیده اید که گاهی جوابی را که مطمئنید در سندها هست پیدا نمی کند، یا با اطمینان کامل جوابی بی ربط می دهد.

خود من وقتی داشتم یک سامانه پرسش وپاسخ روی سندهای فارسی می ساختم، دقیقا به همین وضع خوردم. روی متن انگلیسی همه چیز بی دردسر کار می کرد، اما روی فارسی سندی که دقیقا جواب سوال را داشت گاهی اصلا پیدا نمی شد. بدترین بخش ماجرا این بود که هیچ خطایی دیده نمی شد: نه پیغامی، نه هشداری. سامانه فقط آرام و بی صدا بد کار می کرد. وقتی رد مشکل را گرفتم، فهمیدم ایراد نه از مدل هوش مصنوعی است و نه از پایگاه داده؛ ایراد از خود متن فارسی بود و از اینکه ابزارهای عمومی هیچ درکی از آن ندارند.

در این نوشته سه عامل اصلی این مشکل را توضیح می دهم و بعد سراغ راه حل هایی می روم که در عمل جواب می دهند.

این چت بات ها چطور کار می کنند؟

چت باتی که از روی سندها جواب می دهد معمولا دو مرحله دارد. اول، مثل یک موتور جست وجو، تکه های مرتبط با سوال را از میان سندها پیدا می کند. بعد، آن تکه ها را همراه سوال به مدل زبانی (همان مغز چت بات) می دهد تا جواب را بنویسد. به این روش در دنیای فنی RAG می گویند، کوتاه شده Retrieval-Augmented Generation، یعنی «تولید متن با کمک بازیابی».

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

سه دشمن پنهان: یک کلمه، چند شکل

برای ما که فارسی می خوانیم، «کتاب» همیشه «کتاب» است. اما برای کامپیوتر، دو کلمه فقط وقتی یکی اند که حرف به حرف و کد به کد یکی باشند. متن فارسی پر از کلمه هایی است که ظاهرشان یکی است ولی کدهایشان نه. سه تا از این دشمن ها از همه پنهان تر و رایج ترند:

  1. ی و ک عربی که روی صفحه با ی و ک فارسی فرقی ندارند؛
  2. نیم فاصله که یک کلمه را به چند شکل مختلف درمی آورد؛
  3. PDF برعکس که «کتاب» را به «باتک» تبدیل می کند.

دشمن اول: ی و ک عربی

صفحه کلیدها، سیستم عامل ها و سایت های مختلف گاهی به جای «ی» و «ک» فارسی، «ی» و «ک» عربی می نویسند. روی صفحه تقریبا هیچ فرقی دیده نمی شود، اما «کتاب» با کاف عربی و «کتاب» با کاف فارسی دو رشته کاملا متفاوت اند. اگر سند با یکی نوشته شده باشد و کاربر با دیگری جست وجو کند، جست وجوی کلیدواژه ای هیچ تطابقی پیدا نمی کند. همین داستان برای شکل های مختلف الف (ا، ا، ا) هم تکرار می شود.

دشمن دوم: نیم فاصله

نیم فاصله (ZWNJ) یکی از ظریف ترین بخش های خط فارسی است. «می روم» را می شود با نیم فاصله، با فاصله کامل («می روم») یا چسبیده («میروم») نوشت. «کتاب ها» و «کتاب ها» و «کتابها» هم همین طور. هر کدام از این ها برای ابزاری که متن را به کلمه ها می شکند، چیز متفاوتی است. در یکی «می» و «روم» دو کلمه جدا هستند و در دیگری یک کلمه.

دشمن سوم: PDF برعکس

و اما عجیب ترین دشمن: خیلی از تولیدکننده های PDF متن فارسی را به «ترتیب نمایشی» ذخیره می کنند، یعنی به همان ترتیبی که حروف از چپ به راست روی صفحه چیده شده اند. نتیجه این است که ابزارهای استاندارد استخراج متن، به جای «کتاب» تحویلتان می دهند «باتک». متنی که با این شکل ایندکس شود عملا برای جست وجو بی مصرف است و هیچ هشداری هم نمی بینید، مگر اینکه خودتان خروجی را با چشم نگاه کنید.

دشمن های کوچک تر: ارقام، علائم و املاهای چندگانه

کنار این سه دشمن اصلی، چند مزاحم کوچک تر هم هستند. متن فارسی ممکن است «۱۴۰۳» را با ارقام فارسی، «١٤٠٣» را با ارقام عربی یا «1403» را با ارقام لاتین داشته باشد. ویرگول و علامت سوال هم گاهی فارسی اند (، ؟) و گاهی لاتین.

بعضی کلمه ها در فارسی بیش از یک املای پذیرفته دارند: «اتاق» و «اطاق»، «هیئت» و «هیات»، «مسئله» و «مساله»، «تهران» و «طهران». هیچ کدام غلط نیست، ولی اگر سند «اطاق» نوشته باشد و کاربر «اتاق» بپرسد، جست وجوی کلیدواژه ای سند را از دست می دهد. این مشکل را با یکسان سازی حروف هم نمی شود حل کرد، چون اینجا خود حروف فرق دارند.

هر کدام از این مشکل ها به تنهایی کوچک به نظر می رسد. اما در یک مجموعه واقعی همه با هم پیش می آیند و نتیجه شان همان چت باتی است که جواب را پیدا نمی کند، بی آنکه بگوید چرا.

راه حل ها: پیش از جست وجو، متن را بشناسید

خبر خوب این است که هیچ کدام از این مشکل ها حل نشدنی نیستند. فقط باید پیش از اینکه متن به موتور جست وجو برسد، مرحله هایی مخصوص زبان فارسی در مسیر گذاشته شود. من این راه حل ها را در یک کتابخانه متن باز پایتون به اسم persian-rag پیاده کرده ام، اما ایده ها عمومی اند و در هر سامانه ای قابل پیاده سازی اند.

۱. یکسان سازی متن، اما قابل تنظیم

اولین و مهم ترین قدم، یکسان سازی (normalization) است: «ی» و «ی» به «ی»، «ک» به «ک» و شکل های مختلف الف به «ا» تبدیل شوند، نیم فاصله پیشوند «می» و پسوندهایی مثل «ها» و «ترین» درست شود، ارقام یکدست شوند و فاصله گذاری اطراف علائم مرتب شود. نکته مهم این است که همین کار باید هم روی سندها و هم روی پرسش کاربر انجام شود تا هر دو به یک شکل واحد برسند.

دو اصل را در این مرحله مهم می دانم. اول، هیچ قاعده ای نباید اجباری باشد؛ پروژه ای ممکن است ارقام لاتین بخواهد یا نخواهد به نیم فاصله ها دست زده شود. یکسان سازی ای که نشود کنترلش کرد، دیر یا زود جایی متن را خراب می کند. دوم، یکسان سازی باید «خودتوان» (idempotent) باشد، یعنی اگر دو بار روی یک متن اجرا شود، نتیجه با یک بار اجرا فرقی نکند.

برای نمونه، در پیاده سازی من خروجی یکسان سازی چنین است:

normalize("کتاب های می روم 123")
# کتاب های می روم ۱۲۳

۲. تشخیص و تعمیر متن برعکس PDF

متن برعکس را می شود به طور خودکار تشخیص داد. دو نشانه ساده کار را انجام می دهد: اینکه کلمه ها با کدام شکل های چسبان حروف شروع و تمام می شوند، و اینکه کلمه های پرتکرار فارسی رو به جلو دیده می شوند یا برعکس. اگر سطری برعکس تشخیص داده شد، برگردانده می شود؛ اما باید حواس تان باشد که عددها و متن لاتین جهت چپ به راست خودشان را نگه دارند، وگرنه «2024» به «4202» تبدیل می شود.

۳. جست وجوی ترکیبی: هم کلمه، هم معنا

دو روش اصلی برای جست وجو داریم. روش کلیدواژه ای یا BM25 (الگوریتم کلاسیک رتبه بندی بر اساس تطابق کلمه ها) که در پیدا کردن اسم ها، اصطلاح ها و عبارت های دقیق عالی است. و روش برداری که با embedding (نمایش عددی معنای متن) کار می کند و می تواند جمله های هم معنا با کلمه های متفاوت را هم پیدا کند.

هیچ کدام به تنهایی کافی نیست. راه رایج این است که هر دو اجرا شوند و رتبه بندی هایشان با Reciprocal Rank Fusion یا RRF (ادغام رتبه ها بر اساس جایگاه هر سند در هر فهرست) ترکیب شود. مزیت RRF این است که به مقیاس امتیازها کاری ندارد و فقط به رتبه ها نگاه می کند.

۴. جست وجو با املاهای مختلف

برای مشکل «اتاق/اطاق» یکسان سازی جواب نمی دهد، چون هیچ کدام غلط نیست. راه حل این است که از روی پرسش کاربر، شکل های املایی دیگر ساخته شود، با هر کدام جداگانه جست وجو شود و نتیجه ها دوباره با RRF ادغام شوند. پرسش اصلی باید وزن بیشتری بگیرد تا همیشه اولویت داشته باشد.

۵. ایندکس را به مدلش قفل کنید

یک خطای بی صدای دیگر: ایندکس را با یک مدل embedding می سازید و بعدا با مدل دیگری جست وجو می کنید. بردارها با هم سازگار نیستند، اما ممکن است ابعادشان یکی باشد و هیچ خطایی نگیرید؛ فقط نتیجه ها بی معنی می شوند. راه حل ساده است: نام مدل را کنار ایندکس ذخیره کنید و اگر مدل دیگری سراغش آمد، خطا بدهید. بهتر است سامانه با صدای بلند شکست بخورد تا اینکه آرام اشتباه کند.

این راه حل ها چقدر اثر دارند؟

برای اندازه گیری، یک مجموعه آزمون کوچک فارسی ساختم (persian-rag-bench که طراحی آن را در یادداشتی جداگانه توضیح داده ام): ۳۴ متن و ۴۲ پرسش که ۱۲ تایشان عمدا با املای متفاوت از متن نوشته شده اند.

در جست وجوی کلیدواژه ای BM25، جست وجو با املاهای مختلف معیار Hit@1 (سهم پرسش هایی که جواب درست در رتبه اول آمده) را از 0.881 به 0.952 رساند.

انتخاب مدل embedding هم اثر بزرگی دارد. دو مدل چندزبانه را مقایسه کردم؛ معیار nDCG@10 است (کیفیت ترتیب ده نتیجه اول):

  • مجموعه آزمون خودم: paraphrase-multilingual-MiniLM-L12-v2 برابر 0.8637 و multilingual-e5-small برابر 0.9881
  • زیرمجموعه فارسی MIRACL (dev): paraphrase-multilingual-MiniLM-L12-v2 برابر 0.4424 و multilingual-e5-small برابر 0.7461
  • PQuAD (validation): paraphrase-multilingual-MiniLM-L12-v2 برابر 0.6437 و multilingual-e5-small برابر 0.9242

عدد MIRACL روی یک پیکره محدود از ۶٬۴۰۵ متن داوری شده برای ۶۳۲ پرسش به دست آمده، نه روی کل پیکره MIRACL، پس با عددهای منتشرشده آن قابل مقایسه نیست.

محدودیت ها

این عددها را باید با احتیاط خواند:

  • مجموعه آزمون را خودم ساخته ام و کوچک است. با ۴۲ پرسش، جابه جا شدن فقط یک پرسش Hit@k را حدود ۲٫۴ واحد درصد تغییر می دهد.
  • امتیازها روی این مجموعه نزدیک سقف اند و برای مقایسه مدل های قوی چندان تفکیک کننده نیست.
  • ارزیابی املایی فقط بر ۱۲ پرسش دستی تکیه دارد.
  • در وزن دهی شکل های املایی هنوز یک ایراد باز هست: هر شکل وزن ۱ می گیرد و پرسش اصلی وزن ۲، اما مجموع وزن چند شکل می تواند از پرسش اصلی بیشتر شود.
  • برای تعمیر متن PDF، رتبه بندی دوباره و دقت ارجاع ها هنوز ارزیابی عددی ندارم.

جمع بندی

اگر چت بات یا موتور جست وجوی شما روی متن فارسی کار می کند، پیش از عوض کردن مدل، این سه دشمن پنهان را بررسی کنید: حروف عربی، نیم فاصله و PDF برعکس. یکسان سازی دقیق متن در هر دو طرف، تعمیر PDF، جست وجوی ترکیبی و در نظر گرفتن املاهای مختلف، اغلب بیش از هر تغییر دیگری کیفیت جواب ها را بالا می برد.

منابع و لینک ها

نوشته های مرتبط