ব্রাউজারে AI মডেল ক্যাশে

বেশিরভাগ AI মডেলের অন্তত একটি জিনিস মিল রয়েছে: ইন্টারনেটের মাধ্যমে স্থানান্তরিত একটি সংস্থানের জন্য এগুলি মোটামুটি বড় । সবচেয়ে ছোট MediaPipe অবজেক্ট ডিটেকশন মডেল ( SSD MobileNetV2 float16 ) এর ওজন 5.6 MB এবং সবচেয়ে বড়টির প্রায় 25 MB।

ওপেন-সোর্স LLM gemma-2b-it-gpu-int4.bin ঘড়িতে 1.35 GB-এ এবং এটি একটি LLM-এর জন্য খুব ছোট বলে মনে করা হয়। জেনারেটিভ এআই মডেলগুলি বিশাল হতে পারে। এই কারণেই আজ প্রচুর AI ব্যবহার ক্লাউডে ঘটে। ক্রমবর্ধমানভাবে, অ্যাপ্লিকেশানগুলি অত্যন্ত অপ্টিমাইজ করা মডেলগুলি সরাসরি ডিভাইসে চলছে৷ ব্রাউজারে চলমান এলএলএম-এর ডেমো বিদ্যমান, এখানে ব্রাউজারে চলমান অন্যান্য মডেলের কিছু প্রোডাকশন-গ্রেড উদাহরণ রয়েছে:

এআই-চালিত অবজেক্ট সিলেকশন টুলের মাধ্যমে ওয়েবে অ্যাডোব ফটোশপ খোলা, তিনটি বস্তু বেছে নেওয়া হয়েছে: দুটি জিরাফ এবং একটি চাঁদ।

আপনার অ্যাপ্লিকেশনগুলির ভবিষ্যত লঞ্চগুলিকে দ্রুততর করতে, আপনাকে অন্তর্নিহিত HTTP ব্রাউজার ক্যাশের উপর নির্ভর না করে ডিভাইসে মডেল ডেটা স্পষ্টভাবে ক্যাশে করা উচিত৷

যদিও এই গাইডটি একটি চ্যাটবট তৈরি করার জন্য gemma-2b-it-gpu-int4.bin model ব্যবহার করে, পদ্ধতিটি অন্যান্য মডেল এবং ডিভাইসে অন্যান্য ব্যবহারের ক্ষেত্রের জন্য সাধারণীকরণ করা যেতে পারে। একটি মডেলের সাথে একটি অ্যাপ সংযোগ করার সবচেয়ে সাধারণ উপায় হল অ্যাপের বাকি সম্পদগুলির পাশাপাশি মডেলটি পরিবেশন করা। ডেলিভারি অপ্টিমাইজ করা অত্যন্ত গুরুত্বপূর্ণ।

সঠিক ক্যাশে হেডার কনফিগার করুন

আপনি যদি আপনার সার্ভার থেকে AI মডেল পরিবেশন করেন, তাহলে সঠিক Cache-Control হেডার কনফিগার করা গুরুত্বপূর্ণ। নিম্নলিখিত উদাহরণটি একটি কঠিন ডিফল্ট সেটিং দেখায়, যা আপনি আপনার অ্যাপের প্রয়োজনের জন্য তৈরি করতে পারেন।

Cache-Control: public, max-age=31536000, immutable

একটি এআই মডেলের প্রতিটি প্রকাশিত সংস্করণ একটি স্থির সম্পদ। অনুরোধের URL-এ ক্যাশে বাস্টিংয়ের সাথে একত্রিত দীর্ঘ max-age দেওয়া উচিত এমন সামগ্রী যা কখনই পরিবর্তন হয় না। আপনি যদি মডেলটি আপডেট করতে চান তবে আপনাকে অবশ্যই এটি একটি নতুন URL দিতে হবে।

যখন ব্যবহারকারী পৃষ্ঠাটি পুনরায় লোড করে, তখন ক্লায়েন্ট একটি পুনর্বিবেচনার অনুরোধ পাঠায়, যদিও সার্ভার জানে যে সামগ্রীটি স্থিতিশীল। immutable নির্দেশ স্পষ্টভাবে নির্দেশ করে যে পুনর্বিবেচনা অপ্রয়োজনীয়, কারণ বিষয়বস্তু পরিবর্তন হবে না। immutable নির্দেশিকাটি ব্রাউজার এবং মধ্যস্থতাকারী ক্যাশে বা প্রক্সি সার্ভার দ্বারা ব্যাপকভাবে সমর্থিত নয় , তবে সর্বজনীনভাবে বোধগম্য max-age নির্দেশের সাথে এটিকে একত্রিত করে, আপনি সর্বাধিক সামঞ্জস্যতা নিশ্চিত করতে পারেন। public প্রতিক্রিয়া নির্দেশিকা নির্দেশ করে যে প্রতিক্রিয়া একটি ভাগ করা ক্যাশে সংরক্ষণ করা যেতে পারে।

Chrome DevTools একটি AI মডেলের অনুরোধ করার সময় Hugging Face দ্বারা পাঠানো প্রোডাকশন Cache-Control হেডারগুলি প্রদর্শন করে৷ ( সূত্র )

ক্যাশে এআই মডেল ক্লায়েন্ট-সাইড

আপনি যখন একটি AI মডেল পরিবেশন করেন, তখন ব্রাউজারে মডেলটিকে স্পষ্টভাবে ক্যাশে করা গুরুত্বপূর্ণ৷ এটি নিশ্চিত করে যে ব্যবহারকারী অ্যাপটি পুনরায় লোড করার পরে মডেল ডেটা সহজেই উপলব্ধ।

আপনি এটি অর্জন করতে ব্যবহার করতে পারেন কৌশল একটি সংখ্যা আছে. নিম্নলিখিত কোড নমুনার জন্য, ধরে নিন প্রতিটি মডেল ফাইল মেমরিতে blob নামে একটি Blob অবজেক্টে সংরক্ষণ করা হয়েছে।

কর্মক্ষমতা বোঝার জন্য, প্রতিটি কোড নমুনা performance.mark() এবং performance.measure() পদ্ধতি দিয়ে টীকা করা হয়। এই ব্যবস্থাগুলি ডিভাইস-নির্ভর এবং সাধারণীকরণযোগ্য নয়।

Chrome DevTools অ্যাপ্লিকেশন > স্টোরেজ এ, IndexedDB, ক্যাশে স্টোরেজ এবং ফাইল সিস্টেমের জন্য সেগমেন্ট সহ ব্যবহারের চিত্রটি পর্যালোচনা করুন। প্রতিটি সেগমেন্টকে 1354 মেগাবাইট ডেটা খরচ করতে দেখানো হয়েছে, যা মোট 4063 মেগাবাইট।

আপনি ব্রাউজারে AI মডেল ক্যাশে করতে নিম্নলিখিত APIগুলির মধ্যে একটি ব্যবহার করতে বেছে নিতে পারেন: Cache API , Origin Private File System API , এবং IndexedDB APIসাধারণ সুপারিশ হল ক্যাশে API ব্যবহার করা , কিন্তু এই নির্দেশিকাটি সমস্ত বিকল্পের সুবিধা এবং অসুবিধাগুলি নিয়ে আলোচনা করে৷

ক্যাশে API

ক্যাশে API Request এবং Response অবজেক্ট জোড়ার জন্য স্থায়ী সঞ্চয়স্থান সরবরাহ করে যা দীর্ঘস্থায়ী মেমরিতে ক্যাশে করা হয়। যদিও এটি সার্ভিস ওয়ার্কার্স স্পেক এ সংজ্ঞায়িত করা হয়েছে , আপনি মূল থ্রেড বা নিয়মিত কর্মী থেকে এই API ব্যবহার করতে পারেন। এটি একটি পরিষেবা কর্মী প্রসঙ্গের বাইরে ব্যবহার করতে, একটি Request অবজেক্টের পরিবর্তে একটি সিন্থেটিক URL এর সাথে যুক্ত একটি সিন্থেটিক Response বস্তুর সাথে Cache.put() পদ্ধতিতে কল করুন৷

এই নির্দেশিকা একটি ইন-মেমরি blob অনুমান করে। ক্যাশে কী এবং blob উপর ভিত্তি করে একটি সিন্থেটিক Response হিসাবে একটি জাল URL ব্যবহার করুন৷ আপনি যদি সরাসরি মডেলটি ডাউনলোড করেন, তাহলে আপনি একটি fetch() অনুরোধ করার ফলে Response পাবেন তা ব্যবহার করবেন।

উদাহরণস্বরূপ, ক্যাশে এপিআই দিয়ে একটি মডেল ফাইল কীভাবে সংরক্ষণ এবং পুনরুদ্ধার করা যায় তা এখানে।

const storeFileInSWCache = async (blob) => {
  try {
    performance.mark('start-sw-cache-cache');
    const modelCache = await caches.open('models');
    await modelCache.put('model.bin', new Response(blob));
    performance.mark('end-sw-cache-cache');

    const mark = performance.measure(
      'sw-cache-cache',
      'start-sw-cache-cache',
      'end-sw-cache-cache'
    );
    console.log('Model file cached in sw-cache.', mark.name, mark.duration.toFixed(2));
  } catch (err) {
    console.error(err.name, err.message);
  }
};

const restoreFileFromSWCache = async () => {
  try {
    performance.mark('start-sw-cache-restore');
    const modelCache = await caches.open('models');
    const response = await modelCache.match('model.bin');
    if (!response) {
      throw new Error(`File model.bin not found in sw-cache.`);
    }
    const file = await response.blob();
    performance.mark('end-sw-cache-restore');
    const mark = performance.measure(
      'sw-cache-restore',
      'start-sw-cache-restore',
      'end-sw-cache-restore'
    );
    console.log(mark.name, mark.duration.toFixed(2));
    console.log('Cached model file found in sw-cache.');
    return file;
  } catch (err) {    
    throw err;
  }
};

অরিজিন প্রাইভেট ফাইল সিস্টেম API

অরিজিন প্রাইভেট ফাইল সিস্টেম (OPFS) একটি স্টোরেজ এন্ডপয়েন্টের জন্য তুলনামূলকভাবে তরুণ স্ট্যান্ডার্ড । এটি পৃষ্ঠার উত্স থেকে ব্যক্তিগত, এবং এইভাবে ব্যবহারকারীর কাছে অদৃশ্য, নিয়মিত ফাইল সিস্টেমের বিপরীতে। এটি একটি বিশেষ ফাইলে অ্যাক্সেস প্রদান করে যা পারফরম্যান্সের জন্য অত্যন্ত অপ্টিমাইজ করা হয় এবং এর বিষয়বস্তুতে লেখার অ্যাক্সেস অফার করে।

উদাহরণস্বরূপ, OPFS-এ একটি মডেল ফাইল কীভাবে সংরক্ষণ এবং পুনরুদ্ধার করতে হয় তা এখানে।

const storeFileInOPFS = async (blob) => {
  try {
    performance.mark('start-opfs-cache');
    const root = await navigator.storage.getDirectory();
    const handle = await root.getFileHandle('model.bin', { create: true });
    const writable = await handle.createWritable();
    await blob.stream().pipeTo(writable);
    performance.mark('end-opfs-cache');
    const mark = performance.measure(
      'opfs-cache',
      'start-opfs-cache',
      'end-opfs-cache'
    );
    console.log('Model file cached in OPFS.', mark.name, mark.duration.toFixed(2));
  } catch (err) {
    console.error(err.name, err.message);
  }
};

const restoreFileFromOPFS = async () => {
  try {
    performance.mark('start-opfs-restore');
    const root = await navigator.storage.getDirectory();
    const handle = await root.getFileHandle('model.bin');
    const file = await handle.getFile();
    performance.mark('end-opfs-restore');
    const mark = performance.measure(
      'opfs-restore',
      'start-opfs-restore',
      'end-opfs-restore'
    );
    console.log('Cached model file found in OPFS.', mark.name, mark.duration.toFixed(2));
    return file;
  } catch (err) {    
    throw err;
  }
};

IndexedDB API

IndexedDB ব্রাউজারে অবিরাম পদ্ধতিতে নির্বিচারে ডেটা সংরক্ষণের জন্য একটি সু-প্রতিষ্ঠিত মান। এটি কিছুটা জটিল API এর জন্য কুখ্যাতভাবে পরিচিত, তবে idb-keyval এর মতো একটি র্যাপার লাইব্রেরি ব্যবহার করে আপনি IndexedDB কে একটি ক্লাসিক কী-মান স্টোরের মতো আচরণ করতে পারেন।

যেমন:

import { get, set } from 'https://cdn.jsdelivr.net/npm/idb-keyval@latest/+esm';

const storeFileInIDB = async (blob) => {
  try {
    performance.mark('start-idb-cache');
    await set('model.bin', blob);
    performance.mark('end-idb-cache');
    const mark = performance.measure(
      'idb-cache',
      'start-idb-cache',
      'end-idb-cache'
    );
    console.log('Model file cached in IDB.', mark.name, mark.duration.toFixed(2));
  } catch (err) {
    console.error(err.name, err.message);
  }
};

const restoreFileFromIDB = async () => {
  try {
    performance.mark('start-idb-restore');
    const file = await get('model.bin');
    if (!file) {
      throw new Error('File model.bin not found in IDB.');
    }
    performance.mark('end-idb-restore');
    const mark = performance.measure(
      'idb-restore',
      'start-idb-restore',
      'end-idb-restore'
    );
    console.log('Cached model file found in IDB.', mark.name, mark.duration.toFixed(2));
    return file;
  } catch (err) {    
    throw err;
  }
};

স্থায়ী হিসাবে স্টোরেজ চিহ্নিত করুন

ক্রমাগত সঞ্চয়স্থান ব্যবহার করার অনুমতির অনুরোধ করতে এই ক্যাশিং পদ্ধতিগুলির যেকোনো একটির শেষে navigator.storage.persist() এ কল করুন। এই পদ্ধতিটি এমন একটি প্রতিশ্রুতি ফেরত দেয় যা অনুমতি দেওয়া হলে true এবং অন্যথায় false হয়ে যায়। ব্রাউজার-নির্দিষ্ট নিয়মের উপর নির্ভর করে ব্রাউজার অনুরোধটি মানতে পারে বা নাও করতে পারে

if ('storage' in navigator && 'persist' in navigator.storage) {
  try {
    const persistent = await navigator.storage.persist();
    if (persistent) {
      console.log("Storage will not be cleared except by explicit user action.");
      return;
    }
    console.log("Storage may be cleared under storage pressure.");  
  } catch (err) {
    console.error(err.name, err.message);
  }
}

বিশেষ ক্ষেত্রে: একটি হার্ড ডিস্কে একটি মডেল ব্যবহার করুন

আপনি ব্রাউজার স্টোরেজের বিকল্প হিসাবে ব্যবহারকারীর হার্ড ডিস্ক থেকে সরাসরি এআই মডেল উল্লেখ করতে পারেন। এই কৌশলটি গবেষণা-কেন্দ্রিক অ্যাপগুলিকে ব্রাউজারে প্রদত্ত মডেলগুলি চালানোর সম্ভাব্যতা প্রদর্শন করতে সাহায্য করতে পারে বা শিল্পীদের বিশেষজ্ঞ সৃজনশীলতা অ্যাপগুলিতে স্ব-প্রশিক্ষিত মডেলগুলি ব্যবহার করার অনুমতি দেয়৷

ফাইল সিস্টেম অ্যাক্সেস API

ফাইল সিস্টেম অ্যাক্সেস API এর সাথে, আপনি হার্ড ডিস্ক থেকে ফাইলগুলি খুলতে পারেন এবং একটি FileSystemFileHandle পেতে পারেন যা আপনি IndexedDB-তে টিকে থাকতে পারেন৷

এই প্যাটার্নের সাথে, ব্যবহারকারীকে শুধুমাত্র একবার মডেল ফাইলে অ্যাক্সেস দিতে হবে। স্থায়ী অনুমতির জন্য ধন্যবাদ, ব্যবহারকারী স্থায়ীভাবে ফাইলটিতে অ্যাক্সেস মঞ্জুর করতে পারেন৷ অ্যাপটি পুনরায় লোড করার পরে এবং একটি প্রয়োজনীয় ব্যবহারকারীর অঙ্গভঙ্গি, যেমন একটি মাউস ক্লিক, FileSystemFileHandle হার্ড ডিস্কের ফাইলে অ্যাক্সেস সহ IndexedDB থেকে পুনরুদ্ধার করা যেতে পারে।

ফাইল অ্যাক্সেসের অনুমতিগুলি জিজ্ঞাসা করা হয় এবং প্রয়োজনে অনুরোধ করা হয়, যা ভবিষ্যতে পুনরায় লোডের জন্য এটিকে নির্বিঘ্ন করে তোলে। নিচের উদাহরণে দেখানো হয়েছে কিভাবে হার্ডডিস্ক থেকে একটি ফাইলের জন্য একটি হ্যান্ডেল পেতে হয় এবং তারপর হ্যান্ডেলটি সংরক্ষণ ও পুনরুদ্ধার করতে হয়।

import { fileOpen } from 'https://cdn.jsdelivr.net/npm/browser-fs-access@latest/dist/index.modern.js';
import { get, set } from 'https://cdn.jsdelivr.net/npm/idb-keyval@latest/+esm';

button.addEventListener('click', async () => {
  try {
    const file = await fileOpen({
      extensions: ['.bin'],
      mimeTypes: ['application/octet-stream'],
      description: 'AI model files',
    });
    if (file.handle) {
      // It's an asynchronous method, but no need to await it.
      storeFileHandleInIDB(file.handle);
    }
    return file;
  } catch (err) {
    if (err.name !== 'AbortError') {
      console.error(err.name, err.message);
    }
  }
});

const storeFileHandleInIDB = async (handle) => {
  try {
    performance.mark('start-file-handle-cache');
    await set('model.bin.handle', handle);
    performance.mark('end-file-handle-cache');
    const mark = performance.measure(
      'file-handle-cache',
      'start-file-handle-cache',
      'end-file-handle-cache'
    );
    console.log('Model file handle cached in IDB.', mark.name, mark.duration.toFixed(2));
  } catch (err) {
    console.error(err.name, err.message);
  }
};

const restoreFileFromFileHandle = async () => {
  try {
    performance.mark('start-file-handle-restore');
    const handle = await get('model.bin.handle');
    if (!handle) {
      throw new Error('File handle model.bin.handle not found in IDB.');
    }
    if ((await handle.queryPermission()) !== 'granted') {
      const decision = await handle.requestPermission();
      if (decision === 'denied' || decision === 'prompt') {
        throw new Error(Access to file model.bin.handle not granted.');
      }
    }
    const file = await handle.getFile();
    performance.mark('end-file-handle-restore');
    const mark = performance.measure(
      'file-handle-restore',
      'start-file-handle-restore',
      'end-file-handle-restore'
    );
    console.log('Cached model file handle found in IDB.', mark.name, mark.duration.toFixed(2));
    return file;
  } catch (err) {    
    throw err;
  }
};

এই পদ্ধতিগুলি পারস্পরিক একচেটিয়া নয়। এমন একটি কেস হতে পারে যেখানে আপনি উভয়ই ব্রাউজারে একটি মডেলকে স্পষ্টভাবে ক্যাশে করেন এবং ব্যবহারকারীর হার্ড ডিস্ক থেকে একটি মডেল ব্যবহার করেন৷

ডেমো

আপনি MediaPipe LLM ডেমোতে বাস্তবায়িত তিনটি নিয়মিত কেস স্টোরেজ পদ্ধতি এবং হার্ড ডিস্ক পদ্ধতি দেখতে পাবেন।

বোনাস: খণ্ডে একটি বড় ফাইল ডাউনলোড করুন

আপনার যদি ইন্টারনেট থেকে একটি বড় AI মডেল ডাউনলোড করতে হয়, ডাউনলোডটিকে আলাদা খণ্ডে সমান্তরাল করুন, তারপর ক্লায়েন্টে আবার একসাথে সেলাই করুন।

এখানে একটি সহায়ক ফাংশন যা আপনি আপনার কোডে ব্যবহার করতে পারেন। আপনি শুধুমাত্র এটি url পাস করতে হবে. chunkSize (ডিফল্ট: 5MB), maxParallelRequests (ডিফল্ট: 6), progressCallback ফাংশন (যা downloadedBytes এবং মোট fileSize রিপোর্ট করে), এবং AbortSignal সিগন্যালের জন্য signal সবই ঐচ্ছিক।

আপনি আপনার প্রকল্পে নিম্নলিখিত ফাংশনটি অনুলিপি করতে পারেন বা npm প্যাকেজ থেকে fetch-in-chunks প্যাকেজ ইনস্টল করতে পারেন

async function fetchInChunks(
  url,
  chunkSize = 5 * 1024 * 1024,
  maxParallelRequests = 6,
  progressCallback = null,
  signal = null
) {
  // Helper function to get the size of the remote file using a HEAD request
  async function getFileSize(url, signal) {
    const response = await fetch(url, { method: 'HEAD', signal });
    if (!response.ok) {
      throw new Error('Failed to fetch the file size');
    }
    const contentLength = response.headers.get('content-length');
    if (!contentLength) {
      throw new Error('Content-Length header is missing');
    }
    return parseInt(contentLength, 10);
  }

  // Helper function to fetch a chunk of the file
  async function fetchChunk(url, start, end, signal) {
    const response = await fetch(url, {
      headers: { Range: `bytes=${start}-${end}` },
      signal,
    });
    if (!response.ok && response.status !== 206) {
      throw new Error('Failed to fetch chunk');
    }
    return await response.arrayBuffer();
  }

  // Helper function to download chunks with parallelism
  async function downloadChunks(
    url,
    fileSize,
    chunkSize,
    maxParallelRequests,
    progressCallback,
    signal
  ) {
    let chunks = [];
    let queue = [];
    let start = 0;
    let downloadedBytes = 0;

    // Function to process the queue
    async function processQueue() {
      while (start < fileSize) {
        if (queue.length < maxParallelRequests) {
          let end = Math.min(start + chunkSize - 1, fileSize - 1);
          let promise = fetchChunk(url, start, end, signal)
            .then((chunk) => {
              chunks.push({ start, chunk });
              downloadedBytes += chunk.byteLength;

              // Update progress if callback is provided
              if (progressCallback) {
                progressCallback(downloadedBytes, fileSize);
              }

              // Remove this promise from the queue when it resolves
              queue = queue.filter((p) => p !== promise);
            })
            .catch((err) => {              
              throw err;              
            });
          queue.push(promise);
          start += chunkSize;
        }
        // Wait for at least one promise to resolve before continuing
        if (queue.length >= maxParallelRequests) {
          await Promise.race(queue);
        }
      }

      // Wait for all remaining promises to resolve
      await Promise.all(queue);
    }

    await processQueue();

    return chunks.sort((a, b) => a.start - b.start).map((chunk) => chunk.chunk);
  }

  // Get the file size
  const fileSize = await getFileSize(url, signal);

  // Download the file in chunks
  const chunks = await downloadChunks(
    url,
    fileSize,
    chunkSize,
    maxParallelRequests,
    progressCallback,
    signal
  );

  // Stitch the chunks together
  const blob = new Blob(chunks);

  return blob;
}

export default fetchInChunks;

আপনার জন্য সঠিক পদ্ধতি নির্বাচন করুন

এই নির্দেশিকাটি ব্রাউজারে AI মডেলগুলিকে কার্যকরভাবে ক্যাশ করার জন্য বিভিন্ন পদ্ধতির অন্বেষণ করেছে, একটি কাজ যা ব্যবহারকারীর অভিজ্ঞতা এবং আপনার অ্যাপের কার্যকারিতা বাড়ানোর জন্য অত্যন্ত গুরুত্বপূর্ণ। ক্রোম স্টোরেজ টিম AI মডেলগুলিতে দ্রুত অ্যাক্সেস নিশ্চিত করতে, লোডের সময় কমাতে এবং প্রতিক্রিয়াশীলতা উন্নত করতে সর্বোত্তম কার্যক্ষমতার জন্য ক্যাশে API-এর সুপারিশ করে৷

OPFS এবং IndexedDB কম ব্যবহারযোগ্য বিকল্প। OPFS এবং IndexedDB API-কে ডেটা সংরক্ষণ করার আগে সিরিয়ালাইজ করতে হবে। IndexedDB কে ডেটা পুনরুদ্ধার করার সময় ডিসিরিয়ালাইজ করতে হবে, এটি বড় মডেলগুলি সংরক্ষণ করার জন্য সবচেয়ে খারাপ জায়গা করে তোলে।

কুলুঙ্গি অ্যাপ্লিকেশনগুলির জন্য, ফাইল সিস্টেম অ্যাক্সেস API ব্যবহারকারীর ডিভাইসে ফাইলগুলিতে সরাসরি অ্যাক্সেস অফার করে, যারা তাদের নিজস্ব AI মডেলগুলি পরিচালনা করেন তাদের জন্য আদর্শ৷

আপনি যদি আপনার AI মডেল সুরক্ষিত করতে চান তবে এটি সার্ভারে রাখুন। একবার ক্লায়েন্টে সংরক্ষণ করা হলে, DevTools বা OFPS DevTools এক্সটেনশনের সাথে ক্যাশে এবং ইনডেক্সডডিবি উভয় থেকে ডেটা বের করা তুচ্ছ। এই স্টোরেজ APIগুলি নিরাপত্তার ক্ষেত্রে সহজাতভাবে সমান। আপনি মডেলটির একটি এনক্রিপ্ট করা সংস্করণ সঞ্চয় করতে প্রলুব্ধ হতে পারেন, কিন্তু তারপরে আপনাকে ক্লায়েন্টের কাছে ডিক্রিপশন কী পেতে হবে, যা আটকানো যেতে পারে। এর মানে হল আপনার মডেল চুরি করার জন্য একজন খারাপ অভিনেতার প্রচেষ্টা কিছুটা কঠিন, কিন্তু অসম্ভব নয়।

আমরা আপনাকে একটি ক্যাশিং কৌশল বেছে নিতে উত্সাহিত করি যা আপনার অ্যাপের প্রয়োজনীয়তা, লক্ষ্য দর্শকদের আচরণ এবং ব্যবহৃত AI মডেলগুলির বৈশিষ্ট্যগুলির সাথে সামঞ্জস্য করে। এটি নিশ্চিত করে যে আপনার অ্যাপ্লিকেশনগুলি প্রতিক্রিয়াশীল এবং বিভিন্ন নেটওয়ার্ক অবস্থা এবং সিস্টেমের সীমাবদ্ধতার অধীনে শক্তিশালী।


স্বীকৃতি

এটি জোশুয়া বেল, রিলি গ্রান্ট, ইভান স্টেড, নাথান মেমট, অস্টিন সুলিভান, এতিয়েন নোয়েল, আন্দ্রে বান্দারা, আলেকজান্দ্রা ক্লেপার, ফ্রাঙ্কোইস বিউফোর্ট, পল কিনলান এবং রাচেল অ্যান্ড্রু দ্বারা পর্যালোচনা করা হয়েছিল।