با WebLLM یک چت بات محلی و آفلاین بسازید

تاریخ انتشار: 13 ژانویه 2024

این دومین مورد از یک سری سه قسمتی در LLM ها و چت بات ها است. مقاله قبلی مزایا و معایب LLMهای درون دستگاهی و درون مرورگر را مورد بحث قرار داد.

اکنون که هوش مصنوعی سمت سرویس گیرنده را بهتر درک کرده اید، آماده هستید تا WebLLM را به یک برنامه وب لیست کارها اضافه کنید. می توانید کد را در شاخه web-llm مخزن GitHub پیدا کنید.

WebLLM یک زمان اجرا مبتنی بر وب برای LLM است که توسط Machine Learning Compilation ارائه شده است. می توانید WebLLM را به عنوان یک برنامه مستقل امتحان کنید. این برنامه از برنامه های چت مبتنی بر ابر، مانند Gemini الهام گرفته شده است، اما استنتاج LLM به جای ابر در دستگاه شما اجرا می شود. پیام‌ها و داده‌های شما هرگز از دستگاه شما خارج نمی‌شوند و می‌توانید مطمئن باشید که برای آموزش مدل‌ها استفاده نمی‌شوند.

برای انجام استنتاج مدل بر روی دستگاه، WebLLM WebAssembly و WebGPU را ترکیب می کند. در حالی که WebAssembly امکان محاسبات کارآمد در واحد پردازش مرکزی (CPU) را فراهم می کند، WebGPU به توسعه دهندگان امکان دسترسی سطح پایین به واحد پردازش گرافیکی دستگاه (GPU) را می دهد.

Browser Support

  • کروم: 113.
  • لبه: 113.
  • پیش نمایش فناوری فایرفاکس: پشتیبانی می شود.
  • پیش نمایش فناوری سافاری: پشتیبانی می شود.

Source

WebLLM را نصب کنید

WebLLM به صورت بسته npm در دسترس است. با اجرای npm install @mlc-ai/web-llm می توانید این بسته را به برنامه لیست کارهای خود اضافه کنید.

یک مدل انتخاب کنید

در مرحله بعد، باید در مورد یک LLM برای اجرای محلی تصمیم بگیرید. مدل های مختلف موجود است.

برای تصمیم گیری، باید اصطلاحات و ارقام کلیدی زیر را بدانید:

  • Token: کوچکترین واحد متنی که یک LLM می تواند پردازش کند.
  • پنجره زمینه: حداکثر تعداد نشانه هایی که مدل می تواند پردازش کند.
  • پارامترها یا وزن ها: متغیرهای داخلی که در طول تمرین یاد می گیرند، به میلیاردها شمارش می شوند.
  • Quantization: تعداد بیت هایی که وزن ها را نشان می دهند. بیت های بیشتر به معنای دقت بالاتر، اما همچنین استفاده بیشتر از حافظه است.
  • فرمت های اعداد ممیز شناور: اعداد شناور 32 بیتی (با دقت کامل، F32) دقت بهتری را ارائه می دهند، در حالی که اعداد شناور 16 بیتی (نیمه دقیق، F16) سرعت بالاتر و مصرف حافظه کمتری دارند اما به سخت افزار سازگار نیاز دارند.

این عبارات کلیدی معمولاً بخشی از نام مدل هستند. برای مثال، Llama-3.2-3B-Instruct-q4f32_1-MLC حاوی اطلاعات زیر است:

  • مدل LLaMa 3.2 است.
  • مدل دارای 3 میلیارد پارامتر است.
  • این برای آموزش و دستیاران سبک سریع تنظیم شده است (Instruct).
  • از کوانتیزاسیون یکنواخت 4 بیتی (q4) (_1) استفاده می کند.
  • دارای اعداد ممیز شناور با دقت کامل و 32 بیتی است.
  • این یک نسخه ویژه است که توسط Machine Learning Compilation ایجاد شده است.

ممکن است لازم باشد مدل‌های مختلفی را آزمایش کنید تا مشخص کنید کدام مورد برای شما مناسب است.

مدلی با 3 میلیارد پارامتر و 4 بیت در هر پارامتر در حال حاضر می تواند حجم فایلی به اندازه 1.4 گیگابایت در زمان نوشتن این مقاله داشته باشد که برنامه باید قبل از اولین استفاده آن را در دستگاه کاربر بارگیری کند. کار با مدل های 3B امکان پذیر است، اما وقتی صحبت از قابلیت های ترجمه یا دانش چیزهای بی اهمیت می شود، مدل های 7B نتایج بهتری ارائه می دهند. اگرچه با 3.3 گیگابایت و بالاتر، آنها به طور قابل توجهی بزرگتر هستند.

برای ایجاد موتور WebLLM و شروع دانلود مدل برای چت ربات لیست کارهای خود، کد زیر را به برنامه خود اضافه کنید:

import {CreateMLCEngine} from '@mlc-ai/web-llm';
const engine = await CreateMLCEngine('Llama-3.2-3B-Instruct-q4f32_1-MLC', {
  initProgressCallback: ({progress}) =>  console.log(progress);
});

متد CreateMLCEngine رشته مدل و یک شی پیکربندی اختیاری را می گیرد. با استفاده از روش initProgressCallback ، می توانید پیشرفت دانلود مدل را پرس و جو کنید تا زمانی که کاربران منتظر هستند، آن را به کاربران ارائه دهید.

Cache API: LLM خود را به صورت آفلاین اجرا کنید

مدل در حافظه پنهان وب سایت شما دانلود می شود. Cache API همراه با Service Workers برای اجرای آفلاین وب سایت یا برنامه وب شما معرفی شد. این بهترین مکانیسم ذخیره سازی برای حافظه پنهان مدل های هوش مصنوعی است. برخلاف کش HTTP، Cache API یک کش قابل برنامه ریزی است که به طور کامل تحت کنترل توسعه دهنده است.

پس از دانلود، WebLLM فایل های مدل را به جای درخواست از طریق شبکه، از API Cache می خواند و WebLLM را کاملاً آفلاین می کند.

مانند تمام فضای ذخیره‌سازی وب‌سایت، حافظه پنهان در هر مبدأ جدا می‌شود. این بدان معنی است که دو مبدا، example.com و example.net ، نمی‌توانند فضای ذخیره‌سازی یکسانی را به اشتراک بگذارند. اگر آن دو وب سایت می خواستند از یک مدل استفاده کنند، باید مدل را جداگانه دانلود کنند.

می توانید کش را با استفاده از DevTools با رفتن به Application > Storage و باز کردن حافظه پنهان بررسی کنید.

مکالمه را تنظیم کنید

مدل را می توان با مجموعه ای از دستورات اولیه مقداردهی کرد. معمولاً سه نقش پیام وجود دارد:

  • اعلان سیستم : این اعلان رفتار، نقش و شخصیت مدل را تعریف می کند. همچنین می‌تواند برای اتصال به زمین، یعنی تغذیه داده‌های سفارشی به مدلی که بخشی از مجموعه آموزشی آن نیست (مانند داده‌های خاص دامنه شما) استفاده شود. شما فقط می توانید یک دستور سیستم را مشخص کنید.
  • درخواست کاربر : درخواست هایی که توسط کاربر وارد می شود.
  • درخواست دستیار : پاسخ‌های دستیار، اختیاری است.

درخواست‌های کاربر و دستیار را می‌توان با ارائه مثال‌هایی از زبان طبیعی به LLM در مورد نحوه رفتار یا پاسخگویی آن برای درخواست N-shot استفاده کرد.

در اینجا یک نمونه حداقلی برای تنظیم مکالمه برای برنامه لیست کارها آورده شده است:

const messages = [
  { role: "system",
    content: `You are a helpful assistant. You will answer questions related to
    the user's to-do list. Decline all other requests not related to the user's
    todos. This is the to-do list in JSON: ${JSON.stringify(todos)}`
  },
  {role: "user", content: "How many open todos do I have?"}
];

به سوال اولت جواب بده

قابلیت تکمیل چت به عنوان یک ویژگی در موتور WebLLM ایجاد شده قبل از ( engine.chat.completions ) در معرض دید قرار می گیرد. پس از دانلود مدل، می توانید استنتاج مدل را با فراخوانی متد create() در این ویژگی اجرا کنید. برای مورد استفاده خود، می‌خواهید پاسخ‌ها را به صورت جریانی پخش کنید تا کاربر بتواند در حین تولید شروع به خواندن کند و زمان انتظار درک شده را کاهش دهد:

const chunks = await engine.chat.completions.create({  messages,  stream: true, });

این متد یک AsyncGenerator باز می گرداند، یک زیر کلاس از کلاس AsyncIterator پنهان. از حلقه for await...of استفاده delta تا منتظر تکه‌ها باشید.

let reply = '';

for await (const chunk of chunks) {
  reply += chunk.choices[0]?.delta.content ?? '';
  console.log(reply);
}

به نظر می رسد که وب همیشه باید با پاسخ های جریانی سروکار داشته باشد. می توانید از API هایی مانند DOMImplementation برای کار با این پاسخ های جریانی و به روز رسانی موثر HTML خود استفاده کنید.

نتایج صرفاً مبتنی بر رشته هستند. اگر می خواهید آنها را به عنوان JSON یا سایر فرمت های فایل تفسیر کنید، ابتدا باید آنها را تجزیه کنید.

با این حال، WebLLM محدودیت‌هایی دارد: برنامه قبل از اولین استفاده باید یک مدل بزرگ را دانلود کند، که نمی‌توان آن را در بین مبدا به اشتراک گذاشت، بنابراین ممکن است برنامه وب دیگری مجبور شود دوباره همان مدل را دانلود کند. در حالی که WebGPU عملکرد استنتاج تقریباً بومی را به دست می آورد، به سرعت کامل بومی نمی رسد.

نسخه ی نمایشی

این اشکالات توسط Prompt API، یک API اکتشافی پیشنهاد شده توسط Google که در سمت کلاینت نیز اجرا می شود، برطرف می شود، اما از یک مدل مرکزی دانلود شده در Chrome استفاده می کند. این بدان معنی است که چندین برنامه می توانند از یک مدل با سرعت کامل استفاده کنند.

در مقاله بعدی درباره افزودن قابلیت‌های chatbot با استفاده از Prompt API بیشتر بخوانید.