مدلهای هوش مصنوعی مستقیماً با مفهوم کلمات، جملهها یا تصاویر به همان شکلی که انسان آنها را درک میکند کار نمیکنند.
در نهایت، کامپیوتر باید اطلاعات را به شکل عدد دریافت کند.
Embedding روشی است که یک داده مانند متن، جمله، تصویر یا حتی یک محصول را به مجموعهای از اعداد تبدیل میکند.
این مجموعه اعداد را معمولاً یک Vector یا بردار مینامیم.
برای مثال، جمله:
Python یک زبان برنامهنویسی محبوب است.
ممکن است به شکلی شبیه این تبدیل شود:
[0.18, -0.42, 0.73, 0.11, ...]
البته Embeddingهای واقعی معمولاً شامل صدها یا هزاران عدد هستند.
نکته مهم این نیست که هر عدد بهتنهایی چه معنایی دارد.
نکته مهم، موقعیت کلی این Vector نسبت به Vectorهای دیگر است.
چرا متن را به Vector تبدیل میکنیم؟
فرض کنید سه جمله داریم:
Python برای توسعه Backend استفاده میشود.
Django یک Framework برای توسعه وب با Python است.
امروز هوا بارانی است.
از نظر معنایی، دو جمله اول به یکدیگر نزدیکتر هستند.
اما اگر فقط کلمات را مقایسه کنیم، تشخیص این شباهت همیشه ساده نیست.
Embedding تلاش میکند معنای کلی داده را در قالب یک بردار عددی نمایش دهد.
در نتیجه Vector مربوط به دو جمله اول معمولاً به یکدیگر نزدیکتر خواهد بود و جمله مربوط به آبوهوا در بخش دیگری از فضای برداری قرار میگیرد.
اینجاست که Embedding از چیزی شبیه «تبدیل متن به عدد» به ابزاری بسیار کاربردی تبدیل میشود.
Vector چیست؟
Vector در سادهترین تعریف، مجموعهای از اعداد است.
مثلاً:
[0.2, 0.8]
یک Vector دوبعدی است.
و:
[0.2, 0.8, -0.1]
یک Vector سهبعدی است.
در مدلهای Embedding معمولاً با Vectorهایی با ابعاد بسیار بیشتر سروکار داریم.
مثلاً ممکن است یک مدل برای هر متن یک Vector با 768 یا 1536 مقدار تولید کند.
به تعداد مقادیر موجود در Vector، Dimension گفته میشود.
فضای برداری یا Vector Space چیست؟
اگر هر Embedding را یک نقطه در یک فضای چندبعدی در نظر بگیریم، تمام Embeddingها در یک Vector Space قرار میگیرند.
برای درک ساده، یک فضای دوبعدی را تصور کنید.
ممکن است کلمات مرتبط با برنامهنویسی نزدیک یکدیگر قرار بگیرند:
- Python
- Django
- FastAPI
- JavaScript
- Programming
و مفاهیم مربوط به غذا در ناحیه دیگری باشند:
- Pizza
- Burger
- Pasta
- Restaurant
در مدل واقعی، این فضا دو یا سه بعد ندارد و ممکن است صدها یا هزاران Dimension داشته باشد.
خوشبختانه قرار نیست آن را در ذهن تجسم کنیم. مغز انسان برای تصور فضای 1536بعدی طراحی نشده و احتمالاً تصمیم عاقلانهای هم بوده است.
Embedding چگونه معنای متن را نمایش میدهد؟
مدل Embedding روی حجم زیادی از داده آموزش میبیند.
در طول آموزش، مدل یاد میگیرد که مفاهیم مرتبط را در Vector Space به یکدیگر نزدیک کند.
برای مثال:
- software developer
- backend engineer
- programmer
از نظر معنایی به هم مرتبط هستند.
اما:
banana
ارتباط کمتری با آنها دارد.
در نتیجه Distance یا فاصله Vectorهای سه عبارت اول معمولاً کمتر خواهد بود.
Embedding با Token چه تفاوتی دارد؟
در مقاله قبلی درباره LLM گفتیم که متن ابتدا به Token تبدیل میشود.
Token و Embedding دو مفهوم متفاوت هستند.
Tokenization متن را به قطعات کوچکتر تقسیم میکند.
مثلاً:
Machine Learning
ممکن است به چند Token تبدیل شود.
اما Embedding آن Tokenها یا حتی کل متن را به نمایش عددی تبدیل میکند.
به شکل ساده میتوان فرآیند را اینطور دید:
Token واحد ورودی است، اما Embedding نمایش عددی معناست.
Semantic Similarity چیست؟
یکی از مهمترین کاربردهای Embedding محاسبه شباهت معنایی یا Semantic Similarity است.
فرض کنید کاربر جستوجو میکند:
چطور سرعت API را افزایش بدهم؟
در دیتابیس مقالهای داریم با عنوان:
روشهای بهینهسازی Performance در Backend
این دو عبارت دقیقاً از کلمات یکسانی استفاده نکردهاند.
یک Search ساده مبتنی بر Keyword ممکن است ارتباط آنها را بهخوبی تشخیص ندهد.
اما Embedding میتواند تشخیص دهد که هر دو درباره یک مفهوم مشابه هستند.
Cosine Similarity چیست؟
برای تشخیص میزان شباهت دو Vector، روشهای مختلفی وجود دارد.
یکی از رایجترین روشها Cosine Similarity است.
Cosine Similarity زاویه بین دو Vector را بررسی میکند.
اگر دو Vector در جهت مشابهی باشند، مقدار Similarity آنها بیشتر خواهد بود.
بهصورت مفهومی:
مقدار Cosine Similarity معمولاً بین -1 و 1 قرار میگیرد، هرچند بسته به نوع Embedding و Normalization ممکن است در عمل بیشتر با مقادیر مثبت سروکار داشته باشیم.
مقدار نزدیکتر به 1 معمولاً نشاندهنده شباهت بیشتر است.
یک مثال ساده از Cosine Similarity با Python
برای فهم مفهوم، میتوانیم Cosine Similarity را خودمان پیادهسازی کنیم:
import math
def cosine_similarity(vector_a, vector_b):
dot_product = sum(
a * b for a, b in zip(vector_a, vector_b)
)
magnitude_a = math.sqrt(
sum(a * a for a in vector_a)
)
magnitude_b = math.sqrt(
sum(b * b for b in vector_b)
)
if magnitude_a == 0 or magnitude_b == 0:
return 0.0
return dot_product / (magnitude_a * magnitude_b)
حالا:
vector_a = [0.8, 0.2, 0.1]
vector_b = [0.75, 0.25, 0.15]
print(cosine_similarity(vector_a, vector_b))
چون دو Vector جهت نسبتاً مشابهی دارند، مقدار Similarity آنها نیز بالا خواهد بود.
در پروژه واقعی معمولاً لازم نیست این محاسبه را دستی انجام دهید، اما دانستن منطق پشت آن کمک میکند بفهمیم Vector Search واقعاً چه کاری انجام میدهد.
Semantic Search چیست؟
یکی از مهمترین کاربردهای Embedding ساخت Semantic Search است.
در جستوجوی سنتی معمولاً دنبال کلمات مشابه میگردیم.
مثلاً اگر کاربر جستوجو کند:
Django authentication
سیستم دنبال اسنادی میگردد که این کلمات را داشته باشند.
اما Semantic Search تلاش میکند معنای Query را با معنای اسناد مقایسه کند.
فرآیند معمولاً به این شکل است:
به همین دلیل Semantic Search میتواند نتایجی پیدا کند که لزوماً کلمات دقیق Query را ندارند ولی از نظر مفهوم مرتبط هستند.
مثال واقعی برای یک وبلاگ
فرض کنیم در Borna Dev مقالههایی با موضوعات زیر داریم:
چطور APIهای Django را سریعتر کنیم؟
Caching چیست و چه زمانی از Redis استفاده کنیم؟
JWT Authentication چگونه کار میکند؟
Clean Code چیست؟
کاربر جستوجو میکند:
بهینه کردن سرعت بکاند
جستوجوی Keyword ممکن است مقاله اول را پیدا نکند، چون عبارت «بهینه کردن سرعت بکاند» دقیقاً در عنوان وجود ندارد.
اما Semantic Search میتواند Embedding جستوجوی کاربر را با Embedding مقالات مقایسه کند و مقاله Performance را به عنوان نتیجه مرتبط برگرداند.
Vector Database چه ارتباطی با Embedding دارد؟
زمانی که تعداد Embeddingها کم باشد، میتوان آنها را در حافظه یا حتی یک دیتابیس معمولی ذخیره کرد.
اما اگر صدها هزار یا میلیونها Vector داشته باشیم، پیدا کردن نزدیکترین Vectorها به شکل عادی گران میشود.
اینجاست که Vector Database وارد ماجرا میشود.
Vector Database برای ذخیره و جستوجوی سریع Vectorها طراحی شده است.
به زبان ساده:
در مقاله بعدی این مجموعه، Vector Database را بهصورت کاملتر بررسی میکنیم.
Embedding چه ارتباطی با RAG دارد؟
Embedding یکی از اجزای کلیدی بسیاری از سیستمهای RAG است.
RAG مخفف:
Retrieval-Augmented Generation
است.
در یک سیستم RAG معمولاً اسناد ابتدا به قسمتهای کوچکتر تقسیم میشوند.
سپس برای هر بخش Embedding ساخته میشود.
وقتی کاربر سؤال میپرسد:
- از سؤال Embedding ساخته میشود.
- نزدیکترین اسناد پیدا میشوند.
- اسناد مرتبط در اختیار LLM قرار میگیرند.
- مدل با استفاده از آن اطلاعات پاسخ تولید میکند.
بهصورت ساده:
به همین دلیل Embedding پایه بسیاری از سیستمهای سؤال و جواب روی داده اختصاصی است.
Chunking چیست؟
فرض کنید یک سند ۲۰ صفحهای داریم.
معمولاً ایده خوبی نیست که کل سند را یک Embedding واحد در نظر بگیریم.
بهتر است سند را به بخشهای کوچکتر تقسیم کنیم.
به این فرآیند Chunking گفته میشود.
مثلاً:
Document
↓ Chunking
Chunk 1
Chunk 2
Chunk 3
Chunk 4
سپس برای هر Chunk یک Embedding جدا ساخته میشود.
این کار کمک میکند هنگام Search دقیقاً بخشی از سند پیدا شود که به سؤال کاربر مرتبط است.
اندازه Chunk چقدر باید باشد؟
یک اندازه ثابت برای همه پروژهها وجود ندارد.
Chunk خیلی کوچک ممکن است Context کافی نداشته باشد.
Chunk خیلی بزرگ هم ممکن است چند موضوع مختلف را در یک Vector ترکیب کند.
بنابراین Chunk Size باید بر اساس نوع محتوا آزمایش شود.
برای مثال یک مقاله فنی ممکن است براساس:
- Heading
- Paragraph
- Section
تقسیم شود.
در بسیاری از پروژهها تقسیم براساس ساختار معنایی محتوا بهتر از بریدن متن صرفاً براساس تعداد کاراکتر است.
آیا Embedding اطلاعات اصلی را ذخیره میکند؟
Embedding جایگزین اطلاعات اصلی نیست.
اگر از یک مقاله Embedding بسازیم، نباید متن مقاله را حذف کنیم و بگوییم:
خب، حالا همهچیز داخل این 768 عدد است.
Embedding بیشتر برای مقایسه و Retrieval کاربرد دارد.
معمولاً سیستم هر دو مورد را ذخیره میکند:
- Vector
- +
- Original Content
- +
- Metadata
Metadata ممکن است شامل مواردی مثل:
- document_id
- title
- url
- category
- created_at
باشد.
وقتی Vector Search یک نتیجه پیدا میکند، از Metadata برای دسترسی به محتوای واقعی استفاده میکنیم.
Metadata Filtering چیست؟
گاهی Similarity بهتنهایی کافی نیست.
فرض کنید یک سیستم جستوجوی مقاله داریم.
کاربر فقط میخواهد بین مقالههای دسته Backend جستوجو کند.
در این حالت میتوانیم Semantic Search را با Filter ترکیب کنیم:
category = backend
سپس فقط Vectorهای همان دسته بررسی شوند.
این تکنیک در سیستمهای واقعی بسیار مهم است.
کاربردهای Embedding
Embedding فقط برای Chatbot استفاده نمیشود.
کاربردهای مهم آن شامل Semantic Search، سیستمهای RAG، Recommendation System، تشخیص محتوای مشابه، دستهبندی متن، خوشهبندی داده، یافتن Duplicateها و Match کردن دادههای مرتبط است.
برای مثال یک فروشگاه میتواند محصولاتی با توضیحات مشابه را پیدا کند.
یک سیستم پشتیبانی میتواند Ticketهای مشابه را گروهبندی کند.
یک سایت محتوا میتواند مقالههای مرتبط را پیشنهاد دهد.
استفاده از Embedding برای مقالههای مرتبط
فرض کنیم یک کاربر در حال خواندن مقاله:
REST API چیست؟
است.
میتوان Embedding مقاله فعلی را با Embedding تمام مقالههای دیگر مقایسه کرد.
سپس نزدیکترین موارد را به عنوان:
مطالب مرتبط
نمایش داد.
این روش میتواند بهتر از ارتباط ساده براساس Tag عمل کند، چون شباهت معنایی واقعی محتوا را در نظر میگیرد.
Embedding برای Recommendation System
Embedding فقط برای متن نیست.
میتوان برای:
- User
- Product
- Movie
- Article
- Image
هم Embedding ایجاد کرد.
مثلاً اگر یک کاربر چند مقاله درباره Django، API و PostgreSQL خوانده باشد، سیستم میتواند نمایش عددی علایق کاربر را با Embedding مقالهها مقایسه کند و محتوای مرتبطتر پیشنهاد دهد.
Embedding مدلهای مختلف با هم سازگار نیستند
یکی از نکات مهم در پروژههای واقعی این است که Vector تولیدشده توسط دو مدل مختلف الزاماً قابل مقایسه نیست.
برای مثال اگر اسناد را با:
Embedding Model A
ذخیره کردهاید، نباید Query را با:
Embedding Model B
تبدیل کنید و انتظار داشته باشید Search درست کار کند.
تمام Vectorهایی که قرار است با هم مقایسه شوند باید در یک فضای برداری سازگار باشند.
معمولاً یعنی باید از همان Embedding Model استفاده شوند.
اگر Embedding Model را تغییر دهیم چه میشود؟
اگر مدل Embedding پروژه را تغییر دهید، در بسیاری از موارد باید Embeddingهای قبلی را دوباره تولید کنید.
به این فرآیند میتوان Re-Embedding گفت.
برای پروژههای بزرگ این موضوع میتواند:
- زمان
- هزینه
- پردازش
- Storage
قابل توجهی نیاز داشته باشد.
بنابراین انتخاب Embedding Model تصمیمی است که بهتر است قبل از ذخیره میلیونها Vector کمی دربارهاش فکر کنیم. یک رسم عجیب در مهندسی نرمافزار، ولی گاهی مفید است.
Dimension بیشتر همیشه بهتر نیست
ممکن است تصور کنیم:
Vector بزرگتر = نتیجه بهتر
اما همیشه اینطور نیست.
Embedding با Dimension بالاتر ممکن است:
- Storage بیشتری مصرف کند
- Search را سنگینتر کند
- Memory بیشتری نیاز داشته باشد
کیفیت Embedding به مدل و نوع مسئله وابسته است، نه فقط تعداد Dimensionها.
Similarity Score را چگونه تفسیر کنیم؟
یکی از اشتباهات رایج این است که یک Threshold ثابت را برای همه پروژهها استفاده کنیم.
مثلاً:
similarity > 0.8
و نتیجه بگیریم هر چیزی بالاتر از آن مرتبط است.
معنای Score به موارد مختلفی بستگی دارد:
- Embedding Model
- نوع داده
- Similarity Metric
- Domain
- نوع Query
بهتر است Threshold با داده واقعی پروژه تست شود.
آیا Embedding همیشه جواب درست میدهد؟
خیر.
Embedding میتواند مفاهیم مشابه را نزدیک کند، اما کامل نیست.
ممکن است در موارد زیر مشکل ایجاد شود:
- متن بسیار کوتاه
- اصطلاحات تخصصی
- نامهای خاص
- اعداد و شناسهها
- کد
- دادههای چندزبانه
به همین دلیل سیستمهای Search واقعی اغلب از روشهای ترکیبی استفاده میکنند.
Hybrid Search چیست؟
گاهی ترکیب Semantic Search و Keyword Search نتیجه بهتری میدهد.
به این روش معمولاً Hybrid Search گفته میشود.
مثلاً Query زیر را در نظر بگیرید:
Django error 23505
بخش 23505 یک مقدار دقیق است.
در اینجا Keyword Search میتواند اهمیت زیادی داشته باشد.
اما برای بخش مفهومی Query، Semantic Search مفید است.
بنابراین:
Keyword Search
+
Vector Search
=
Hybrid Search
در بسیاری از پروژههای واقعی ترکیب این دو روش از استفاده صرف از Vector Search بهتر است.
Embedding و اطلاعات حساس
متن قبل از تبدیل شدن به Vector ممکن است شامل اطلاعات حساس باشد.
بنابراین نباید تصور کنیم چون خروجی فقط مجموعهای از اعداد است، تمام مسائل Privacy حل شدهاند.
هنگام ساخت سیستمهای Embedding باید مواردی مثل:
- PII
- اطلاعات کاربران
- اسناد خصوصی
- اسرار تجاری
را با سیاست امنیتی مناسب مدیریت کنیم.
همچنین باید مشخص باشد داده به چه Embedding Service یا زیرساختی ارسال میشود.
معماری ساده یک سیستم Semantic Search
یک معماری ساده میتواند به شکل زیر باشد:
هنگام Search:
این ساختار پایه بسیاری از سیستمهای Semantic Search مدرن است.
معماری ساده RAG
اگر همین سیستم را به LLM متصل کنیم:
تقریباً وارد معماری پایه RAG شدهایم.
به همین دلیل یادگیری Embedding قبل از Vector Database و RAG مسیر منطقیتری است.
چه زمانی از Embedding استفاده نکنیم؟
Embedding برای هر نوع جستوجویی راهحل مناسب نیست.
اگر قرار است کاربر دقیقاً بر اساس:
- user_id
- order_number
- SKU
- status
جستوجو کند، Query معمولی دیتابیس بسیار منطقیتر است.
برای پیدا کردن:
order_id = 84371
نیازی نداریم این عدد را به یک فضای معنایی چندصدبعدی بفرستیم.
Embedding زمانی ارزشمند است که معنا و شباهت برای ما مهم باشد.
تفاوت Embedding و LLM
Embedding Model و LLM هر دو میتوانند بخشی از سیستم AI باشند، اما وظیفه آنها متفاوت است.
Embedding Model معمولاً:
Input -> Vector
تولید میکند.
اما LLM:
Input -> Generated Text
تولید میکند.
در یک سیستم RAG هر دو کنار هم استفاده میشوند.
Embedding برای پیدا کردن اطلاعات مرتبط و LLM برای تولید پاسخ براساس آن اطلاعات.
آیا Embedding فقط برای انگلیسی کار میکند؟
خیر.
مدلهای Embedding چندزبانه میتوانند زبانهای مختلف را پردازش کنند.
حتی برخی مدلها میتوانند مفهوم مشابه را بین زبانهای مختلف نزدیک کنند.
برای مثال:
software development
و:
توسعه نرمافزار
ممکن است Embeddingهای نسبتاً نزدیکی داشته باشند.
البته کیفیت پشتیبانی از زبان فارسی به مدل مورد استفاده بستگی دارد و باید با داده واقعی پروژه تست شود.
چگونه یک Embedding Model انتخاب کنیم؟
انتخاب مدل مناسب به نیاز پروژه بستگی دارد.
به جای اینکه فقط دنبال «قویترین مدل» باشیم، بهتر است مواردی مثل کیفیت Retrieval، پشتیبانی از زبان موردنظر، سرعت، هزینه، Dimension خروجی و امکان اجرای Local را بررسی کنیم.
بهترین مدل مدلی است که روی داده واقعی پروژه نتیجه خوبی بدهد.
Benchmark عمومی مفید است، ولی داده پروژه شما رأی نهایی را میدهد.
چگونه کیفیت Embedding را ارزیابی کنیم؟
فرض کنید یک موتور جستوجوی Semantic ساختهایم.
باید مجموعهای از Queryهای واقعی ایجاد کنیم و مشخص کنیم برای هر Query چه نتایجی باید مرتبط باشند.
سپس میتوانیم بررسی کنیم:
- آیا نتیجه درست در رتبههای اول است؟
- آیا نتایج نامرتبط زیاد هستند؟
- آیا Queryهای فارسی درست کار میکنند؟
- آیا اصطلاحات تخصصی پروژه تشخیص داده میشوند؟
بدون Evaluation، تغییر مدل Embedding بیشتر شبیه انتخاب مدل براساس اسم جذاب آن است.
جمعبندی
Embedding یکی از مهمترین مفاهیم در سیستمهای مدرن هوش مصنوعی است.
Embedding دادههایی مثل متن را به Vector تبدیل میکند تا بتوان شباهت معنایی بین آنها را محاسبه کرد.
مفاهیم اصلی که باید به خاطر داشته باشیم عبارتاند از:
Embedding نمایش عددی یک داده است.
Vector مجموعهای از اعداد است که موقعیت یک داده را در Vector Space نشان میدهد.
Similarity Search نزدیکترین Vectorها را پیدا میکند.
Cosine Similarity یکی از روشهای رایج برای اندازهگیری شباهت است.
Semantic Search بر اساس معنا جستوجو میکند، نه فقط کلمات یکسان.
Chunking اسناد بزرگ را به بخشهای کوچکتر برای Embedding تبدیل میکند.
Vector Database برای ذخیره و جستوجوی سریع حجم زیادی از Embeddingها استفاده میشود.
Embedding همان پلی است که دادههای انسانی مثل متن را به دنیایی تبدیل میکند که الگوریتمها بتوانند در آن شباهت معنایی را محاسبه کنند.
در مقاله بعدی این مجموعه سراغ Vector Database میرویم و بررسی میکنیم این بردارها را چگونه ذخیره و میان میلیونها Embedding جستوجو کنیم.
