শুরুতে লোকাল লার্জ ল্যাঙ্গুয়েজ মডেলগুলো বিদ্যুতগতিতে কাজ করছে বলে মনে হয়। আপনি একটি 7B বা 13B প্যারামিটার মডেল লোড করলেন, একটি ছোট প্রম্পট দিলেন এবং স্ক্রিনে টোকেনগুলো বেশ স্বাচ্ছন্দ্যে প্রবাহিত হতে লাগল। তারপর আপনি একটি দীর্ঘ কোড ব্লক পেস্ট করলেন, অথবা আপনার চ্যাট হিস্ট্রি অনেক বড় হয়ে গেল, আর মডেলটি ধীর হয়ে যেতে শুরু করল। এই ধীরগতি খুব একটা ধীরে আসে না। এটি অনেকটা খাদের মতো। এক মুহূর্তের জন্য GPU টোকেন তৈরি করছে; পরের মুহূর্তেই আপনার সিস্টেম মনিটরে মেমরি প্রেশার বাড়তে দেখা যাচ্ছে এবং জেনারেশন থমকে যাচ্ছে। কোনো সুনির্দিষ্ট ফর্মুলা দিয়ে আপনি ঠিক কখন এটি ঘটবে তা আগে থেকে বলতে পারবেন না। আপনার একমাত্র নির্ভরযোগ্য নির্দেশক হলো হার্ডওয়্যার নিজেই।

কনটেক্সটের লুকানো খরচ

আপনার তৈরি করা প্রতিটি টোকেন KV cache-এ স্টেট যোগ করে। এই ক্যাশটি prefill এবং generation পর্যায়ের সময় গণনা করা কী (keys) এবং ভ্যালু (values) সংরক্ষণ করে, এবং এটি আপনার মডেল ওয়েটস, অ্যাটেনশন বাফার এবং রানটাইম ওভারহেডের পাশাপাশি মেমরিতে অবস্থান করে। ১২ GB বা ১৬ GB VRAM বিশিষ্ট একটি সাধারণ কনজিউমার GPU-তে, KV cache শেষ পর্যন্ত অন্যান্য সবকিছুর সাথে জায়গা নিয়ে লড়াই করে। যখন ডেডিকেটেড ভিডিও মেমরি পূর্ণ হয়ে যায়, অপারেটিং সিস্টেম কোনো এরর (error) দেখিয়ে থেমে যায় না। এটি নিঃশব্দে অতিরিক্ত ডেটা শেয়ার্ড মেমরিতে পাঠিয়ে দেয়, যা PCIe বাসের মাধ্যমে GPU এবং সিস্টেম RAM-এর মধ্যে ডেটা আদান-প্রদান করে। ফাইল ট্রান্সফারের জন্য এই বাসটি দ্রুত হলেও, একটি গ্রাফিক্স কার্ডের ভেতরের মেমরি ব্যান্ডউইথের তুলনায় এটি অত্যন্ত ধীর। এর ফলাফল পারফরম্যান্সের সামান্য হ্রাস নয়, বরং এটি একটি সম্পূর্ণ বিপর্যয়।

পারফরম্যান্সের সেই খাদের কিনারা পৌঁছে গেছে তা বোঝার তিনটি সংকেত

মডেলটি চলাকালীন আপনার হার্ডওয়্যার মনিটরগুলো লক্ষ্য করুন। পারফরম্যান্সের সেই খাদের কিনারা স্পর্শ করার সাথে সাথে আপনি তিনটি স্পষ্ট সংকেত দেখতে পাবেন।

  • শেয়ার্ড VRAM বৃদ্ধি পাওয়া। এটি এমন মেমরি যা GPU ড্রাইভার ডেডিকেটেড ভিডিও RAM থেকে সরিয়ে হোস্ট অপারেটিং সিস্টেম দ্বারা পরিচালিত পুলে পাঠিয়ে দেয়। এই মেট্রিকটি শূন্যের উপরে উঠলেই বুঝবেন আপনি সীমা অতিক্রম করেছেন।
  • সিস্টেম RAM-এর ব্যবহার বেড়ে যাওয়া। অতিরিক্ত ডেটা কোথাও না কোথাও জমা হতে হয়, আর সেই গন্তব্য হলো আপনার মেইন মেমরি। মডেল যখন টোকেন জেনারেট করে তখন যদি আপনার RAM ব্যবহার বাড়ে, তবে বুঝতে হবে ডেটা GPU থেকে অফলোড করা হচ্ছে।
  • Eval স্পিড অর্ধেক বা তার বেশি কমে যাওয়া। ১০% ধীরগতি মানে হতে পারে থার্মাল থ্রটলিং (thermal throttling) বা ব্যাকগ্রাউন্ড প্রসেস। কিন্তু ৫০% বা তার বেশি পতন মানে হলো বটলনেক (bottleneck) এখন টেনসর কোর থেকে সরে মেমরি ব্যান্ডউইথ এবং PCIe ল্যাটেন্সিতে চলে এসেছে। যখন দেখবেন জেনারেশন ডাবল ডিজিট থেকে সিঙ্গেল ডিজিটে নেমে এসেছে, তখন বুঝবেন আপনি ইতিমধ্যেই খাদের নিচে পড়ে গেছেন।

কেন আপনার দ্রুত করা বেঞ্চমার্ক সম্ভবত ভুল তথ্য দিচ্ছে

একটি ছোট স্মোক টেস্ট আপনাকে ভুল আত্মবিশ্বাস দিতে পারে। আপনি যদি মাত্র ১০০-টোকেন প্রম্পট দিয়ে মডেলটি বেঞ্চমার্ক করেন, ভালো থ্রুপুট (throughput) দেখেন এবং কাজ শেষ বলে মনে করেন, তবে আপনি আসলে কেবল শুরুর সুসময়টিই পরিমাপ করেছেন। তখন KV cache প্রায় খালি থাকে। দীর্ঘ prefill-এর কারণে লেয়ারগুলো চাপের মুখে পড়ে না। প্রকৃত মেমরি ফুটপ্রিন্ট কেবল তখনই প্রকাশ পায় যখন মডেলটি একটি বড় প্রম্পট প্রসেস করে এবং ক্যাশটি তার প্রকৃত কার্যক্ষম আকারে পূর্ণ হয়। আপনাকে অবশ্যই গভীর prefill এবং দীর্ঘ জেনারেশন রান দিয়ে পরীক্ষা করতে হবে। কনটেক্সটকে আসলে জমতে দিন। কেবল তখনই মেমরি প্রেশার স্থিতিশীল হবে এবং আপনাকে প্রকৃত সীমাটি দেখাবে।

llama.cpp দিয়ে আপনার লিমিট খুঁজে বের করা

আপনি যদি llama.cpp-এর মাধ্যমে মডেল চালান, তবে সাধারণ গাণিতিক হিসাব এবং ধৈর্যশীল পরীক্ষার মাধ্যমে আপনি আপনার সীমানাটি পরিমাপ করতে পারেন।

১. শেয়ার্ড মেমরি ব্যবহার পরিমাপ করুন।
একটি ন্যূনতম প্রম্পট দিয়ে আপনার বেসলাইন ডেডিকেটেড VRAM রেকর্ড করুন, তারপর একটি দীর্ঘ-কনটেক্সট টাস্ক চালান এবং সর্বোচ্চ (peak) মানটি নোট করুন। পিক ভ্যালু থেকে বেসলাইন বিয়োগ করুন। এই পার্থক্যটিই হলো আপনার GPU থেকে শেয়ার্ড সিস্টেম মেমরিতে ছড়িয়ে পড়া ডেটা।

২. আপনার RAM ডেল্টা গণনা করুন।
সিস্টেম RAM-এর ক্ষেত্রেও একই বিয়োগফল নির্ণয় করুন। দীর্ঘ রান চলাকালীন পিক RAM থেকে আপনার বেসলাইন RAM বিয়োগ করুন। এই সংখ্যাটি আপনাকে ঠিক বলে দেবে কতটুকু ডেটা ভিডিও কার্ড থেকে আপনার মেইন মেমরিতে ঠেলে দেওয়া হয়েছে। এটি বাসের মাধ্যমে হওয়া ডেটা লিক বা অপচয়কে পরিমাপ করে।

৩. Eval স্পিড কমে যাওয়ার সময় পরিমাপ করুন।
মডেলটি একটি দীর্ঘ ডকুমেন্ট প্রসেস করার আগের টোকেন-পার-সেকেন্ড রেটের সাথে পরের রেটটি তুলনা করুন। আপনি দেখতে পারেন কনটেক্সট যখন নতুন ছিল তখন মডেলটি প্রতি সেকেন্ডে ১৭টি টোকেন জেনারেট করছিল, কিন্তু ক্যাশ ফুলে যাওয়ার পর তা মাত্র ২টিতে নেমে এসেছে। এই ১৫-টোকেনের পতনই হলো আপনার জন্য আগাম সতর্কবার্তা।

ব্রেকিং পয়েন্ট বা ভেঙে পড়ার মুহূর্তটি নির্ণয় করা

কার্ভটি সঠিকভাবে ম্যাপ করার জন্য, একটি মাত্র ডেটা পয়েন্টের ওপর নির্ভর করবেন না। ১৬,০০০ টোকেন, ৩২,০০০ টোকেন, এবং ৬৫,০০০ টোকেন-এ তিনটি আলাদা ট্রায়াল চালান। দুটি পয়েন্ট একটি রেখা নির্দেশ করতে পারে, কিন্তু দুটি বিন্দু কেবল একটি অনুমান মাত্র। তৃতীয় পয়েন্টটি প্রমাণ করে যে আপনি পরিমাপের নয়েজ (noise) দেখছেন নাকি প্রকৃত মেমরি ওয়াল (memory wall) দেখছেন। আপনার মডেল, কোয়ান্টাইজেশন লেয়ার (quantization layer) এবং GPU-এর নির্দিষ্ট কম্বিনেশনে প্রতিটি অতিরিক্ত এক হাজার টোকেন কতটুকু অতিরিক্ত মেমরি খরচ করে তা গণনা করতে প্রতিটি রানের ফলাফলের পার্থক্য বের করুন।

একবার আপনি সেই ঢাল (slope) পেয়ে গেলে, আপনি সামনের দিকে প্রজেকশন করতে পারবেন। আপনার প্রতি-টোকেন খরচ নিন, এটিকে টার্গেট কনটেক্সট লেন্থ (target context length) দিয়ে গুণ করুন, ইউনিট পরিবর্তনের জন্য ১০২৪ দিয়ে ভাগ করুন এবং ফলাফলটি আপনার বেস মডেলের VRAM লোডের সাথে যোগ করুন। সমীকরণটি দেখতে এরকম:

Model VRAM load + (tokens × memory per token ÷ 1024) = Theoretical VRAM usage

এই প্রজেকশন কোনো ভবিষ্যৎবাণী নয়। এটি প্রকৃত আচরণ থেকে প্রাপ্ত একটি নির্দেশিকা। একটি পূর্ণাঙ্গ প্রোডাকশন রান শুরু করার আগে আপনার সর্বোচ্চ সীমা (ceiling) অনুমান করতে এটি ব্যবহার করুন।

কেন তাত্ত্বিক সূত্রগুলো ব্যর্থ হয় এবং কোয়ান্টাইজেশন কী সমাধান করতে পারে

পাঠ্যপুস্তকের সূত্রগুলো লোকাল ইনফারেন্সের (local inference) জটিল বাস্তবতাকে উপেক্ষা করে। বিভিন্ন আর্কিটেকচার ভিন্ন ভিন্ন উপায়ে অ্যাটেনশন বাফার (attention buffers) বরাদ্দ করে। আপনার অপারেটিং সিস্টেম ডিসপ্লে ড্রাইভার, কম্পোজিটর এবং CUDA কনটেক্সটের জন্য VRAM সংরক্ষণ করে। ড্রাইভারের সংস্করণগুলো শেয়ার্ড মেমরি (shared memory) ব্যবহারের তীব্রতা পরিবর্তন করে। একটি তাত্ত্বিক সমীকরণ এটি জানতে পারে না যে দুপুর ২টায় অনেকগুলো ট্যাব খোলা থাকা ব্রাউজারসহ আপনার মেশিনে আসলে কতটুকু VRAM খালি আছে। আপনাকে আপনার নির্দিষ্ট হার্ডওয়্যারে মডেলটি চালাতে হবে এবং মিটারগুলো পর্যবেক্ষণ করতে হবে।

কোয়ান্টাইজেশন আংশিক উপশম দেয়। KV ক্যাশকে f16 থেকে q8_0-তে নিয়ে গেলে এর মেমরি ফুটপ্রিন্ট অর্ধেক হয়ে যায়, অথচ প্রায় সব ব্যবহারিক কাজের জন্য প্রিসিশন (precision) যথেষ্ট উচ্চ থাকে। এই পরিবর্তনটি আপনাকে কিছুটা হেডরুম (headroom) দেয়। তবে এটি আপনাকে সম্পূর্ণ সুরক্ষা দেয় না। আপনি যত টোকেন ইনপুট দেবেন, ক্যাশটি একইভাবে রৈখিকভাবে (linearly) বাড়তে থাকবে। শেষ পর্যন্ত, এমনকি হ্রাস করা আকারও আপনার উপলব্ধ ডেডিকেটেড মেমরিকে ছাড়িয়ে যাবে এবং সিস্টেম RAM-এ স্পিলওভার (spillover) শুরু হবে। কনটেক্সট উইন্ডো সীমাবদ্ধ করা হলে বা ডেটা আসা বন্ধ হলে কেবল এই চাপটি থামবে।

আসল শিক্ষা

মার্কেটিং স্লাইড, প্যারামিটার সংখ্যা বা সাধারণ গাণিতিক হিসাবের ওপর ভরসা করবেন না। মডেলটি লোড করুন। আপনার সিস্টেম মনিটর খুলুন। একটি ৬৫,০০০-টোকেনের থ্রেড চালান, RAM কীভাবে বাড়ছে তা দেখুন এবং প্রতি সেকেন্ডে কত টোকেন প্রসেস হচ্ছে তা গণনা করুন। আপনার নির্দিষ্ট স্ক্রিনে এবং আপনার নির্দিষ্ট GPU-তে যে সংখ্যাগুলো দেখাচ্ছে, কেবল সেই সংখ্যাগুলোই গুরুত্বপূর্ণ। কনটেক্সট সব সময় জয়ী হয়। আপনার কাজ হলো আপনার মেশিনে ঠিক কখন এটি জয়ী হয় তা জানা।