ব্লগ

ছবি-ভারী এজেন্ট টার্নকে মেমোরির মধ্যে রাখা

একটি প্রোডাকশন এজেন্ট টার্ন ৯৫২ MB-তে মেমোরি শেষ করেছিল, যখন সে ছয়টি ক্যাটালগ স্ক্যান থেকে পণ্য কেটে আলাদা করছিল এবং সেই ক্রপগুলো দেখছিল। একটি মাত্র লিক ছিল না — তিনটি ছিল। প্রতিটি মডেল কলে টার্নের ছবিগুলো পূর্ণ আকারে আবার পাঠানো হতো; মডেল কল করার লাইব্রেরি প্রতিটি অনুরোধ টার্ন শেষ না হওয়া পর্যন্ত জীবিত রাখত; আর এজেন্ট ফ্রেমওয়ার্কের ট্রেসিং পুরো টার্নজুড়ে প্রতিটি কলের ইনপুট, ছবিসহ, রেখে দিত। আমরা তিনটিই ঠিক করেছি: পাঠানোর আগে ছবি ছোট করা হয়, আর প্রতিটি কলের ছবি কল শেষ হওয়ামাত্র ছেড়ে দেওয়া হয়।

এজেন্ট ছবি কীভাবে দেখে

Mythex-এ বানানোর সময় এজেন্ট আপনার প্রজেক্টের ক্লাউড স্যান্ডবক্সের ভেতরে কাজ করে। সে ছবি দেখতে পারে — আপনার সংযুক্ত একটি স্ক্রিনশট, একটি মকআপ, প্রজেক্টের একটি ফাইল, বা সে নিজে যে ছবি তৈরি করেছে — সেগুলো কথোপকথনের সঙ্গে মডেলের কাছে পাঠিয়ে।

একটি টার্ন হলো আপনার একটি বার্তার জবাবে এজেন্ট যা কিছু করে তার সবকিছু। একটি টার্নের মধ্যে এজেন্ট মডেলকে অনেকবার কল করে: চিন্তা করে, একটি টুল চালায়, ফলাফল দেখে, আবার চিন্তা করে। প্রতিটি কল এ পর্যন্ত কথোপকথন পাঠায়, আর তাতে টার্নের ছবিগুলোও থাকে, বেস64 হিসেবে এনকোড করা (যা প্রায় এক-তৃতীয়াংশ বড় হয়ে যায়)।

যে টার্নটি ক্র্যাশ করেছিল, সেটি যুক্তিসঙ্গত কাজই করছিল। সে ছয়টি ক্যাটালগ স্ক্যান নিয়েছিল, প্রতিটি প্রায় ২.৪ MB, তা থেকে আলাদা পণ্য কেটেছিল, এবং ক্রপগুলো আবার পড়ে ঠিক আছে কি না যাচাই করছিল। তাতে অনেকগুলো মডেল কল ছিল, প্রতিটিতে কয়েকটি বড় ছবি।

কারণ ১: প্রতিটি কল পূর্ণ আকারের ছবি আবার পাঠাত

প্রতিটি মডেল কল তার অনুরোধের বডি নতুন করে বানাত, টার্নের ছবিগুলো পূর্ণ আকারে — প্রতি কলে প্রায় ২০ MB বেস64। বডিটি এজেন্টের মেমোরিতে একটি স্ট্রিং হিসেবে তৈরি হয়, তাই প্রতিটি কল আরও প্রায় ২০ MB বরাদ্দ করত।

আর পূর্ণ আকারে পাঠানোর কোনো লাভও ছিল না। মডেল নিজেই ছবি প্রায় ১,৩০০ পিক্সেলের লম্বা দিকে ছোট করে নেয়, তাই অতিরিক্ত পিক্সেল শুধু মেমোরি ও আপলোডের সময় খরচ করত।

সমাধান: একবার ছোট করো, ছোট করে পাঠাও

  • ৪০০ KB-র বেশি ছবি পাঠানোর আগে একটি JPEG-এ রূপান্তরিত হয়, যার লম্বা দিক সর্বোচ্চ ১,৫৬৮ পিক্সেল। ছোট ছবি যেমন আছে তেমনই যায়।
  • রূপান্তর হয় ImageMagick দিয়ে, যা প্রতিটি Mythex স্যান্ডবক্সে থাকে, এবং প্রতি ফাইলে একবার চলে। যে টার্ন প্রতি কলে একই স্ক্যান দেখায়, সে ছোট করা কপিটি পুনরায় ব্যবহার করে। ক্যাশটি ফাইলের পথ, আকার ও পরিবর্তনের সময় দিয়ে চিহ্নিত, তাই সম্পাদিত ফাইল আবার রূপান্তরিত হয়। এর নিজস্ব আকারের সীমাও আছে, যাতে এটিই মেমোরি ভরাট করতে না পারে।
  • একটি মডেল কলে ছবির বাজেট ১৬ MB থেকে ৬ MB-তে নামে।

একই ছয়টি স্ক্যান এখন প্রতি কলে ১৯.৭ MB-র বদলে ৪.৪ MB খরচ করে।

কারণ ২: মডেল ক্লায়েন্ট কোনো অনুরোধ ছাড়ত না

প্রতিটি অনুরোধের আকারই শুধু অংশ ছিল না। মেমোরি কল-পর-কল বাড়ছিল। আমাদের স্টেজিং পরিবেশে একই ধরনের টার্ন সম্পূর্ণ গার্বেজ কালেকশনের পরেও ৩৬৯ MB জীবিত মেমোরি ধরে রেখেছিল — অর্থাৎ সেই বিন্দু যেখানে নাগালের বাইরের সবকিছু মুক্ত হয়ে যায়। হিপ স্যাম্পলিং দেখাল পুরো বৃদ্ধিটি ছিল মডেল ক্লায়েন্ট লাইব্রেরির সেই অংশে, যা অনুরোধের বডি এনকোড করে।

কারণ ছিল একটি abort listener। আপনি Stop চাপলে টার্নের abort signal ফায়ার হয়, এবং সেটি শোনা প্রতিটি অনুরোধ বাতিল হয়। আমরা প্রতিটি অনুরোধে ওই একটি টার্ন-ব্যাপী signal পাঠাতাম। ক্লায়েন্ট লাইব্রেরি যে signal দেওয়া হয় তাতে একটি “abort” listener যোগ করে — এবং কখনো সরায় না।

ফলে একটি টার্নের প্রতিটি অনুরোধ টার্নের signal থেকে নাগালযোগ্য থেকে যেত, টার্ন চলা পর্যন্ত: listener, যা controller ধরে রাখে, যা অনুরোধ ধরে রাখে, যা ছবিসহ পুরো অনুরোধের বডি ধরে রাখে।

সমাধান: প্রতি অনুরোধে একটি signal

এখন প্রতিটি অনুরোধ নিজস্ব signal পায়। সেটি টার্নের signal-এর সঙ্গে কেবল চলমান থাকাকালীন যুক্ত হয় — স্ট্রিমিং রেসপন্সের ক্ষেত্রে, শেষ chunk পড়া পর্যন্ত — এবং ঠিক পরে বিচ্ছিন্ন হয়। Stop এখনও চলমান অনুরোধে পৌঁছায়, কিন্তু টার্নের signal একসময়ে একটির বেশি listener ধরে না।

টেস্টগুলো তিনটি অংশই ঢেকে রাখে:

  • ১২ কলের পরে টার্নের signal-এ কোনো listener অবশিষ্ট থাকে না। ফিক্সের আগে ছিল ১২টি।
  • ৮ MB করে ১৫টি অনুরোধের ওপর মেমোরি স্থির থাকে। আগে বেড়েছিল ১২৮ MB।
  • Stop এখনও স্ট্রিমের মাঝপথে একটি অনুরোধ বাতিল করে।

কারণ ৩: ট্রেসিং প্রতিটি কলের ইনপুট ধরে রাখত

একটি হিপ স্ন্যাপশটে তৃতীয় ধারকটি দেখা গেল: প্রতি মডেল কলে প্রায় ৬ MB। এটি আসছিল এজেন্ট ফ্রেমওয়ার্কের ইভেন্ট স্ট্রিমিং থেকে। এটি টার্নের প্রতিটি মডেল কল টার্নের চাইল্ড হিসেবে রেকর্ড করত, ইনপুটসহ, টার্ন শেষ না হওয়া পর্যন্ত। প্রতিটি কলের প্রতিটি ছবি সেখানে মেমোরিতে থাকত।

সমাধান: কল ফেরত দেওয়ার পর ছবির ডেটা খালি করা

ছবিগুলো শুধু একটি নির্দিষ্ট মডেল কলের জন্য তৈরি বার্তাগুলোতে যুক্ত হয়। সেগুলো কথোপকথনের সংরক্ষিত অবস্থায় কখনো রাখা হয় না। তাই একবার কল ফেরত এলে ওই বার্তাগুলোর ছবির ডেটা খালি করা নিরাপদ। ট্রেস কলের একটি টেক্সট রেকর্ড রাখে; পিক্সেল যায়।

একটি বিষয় গুরুত্বপূর্ণ ছিল: ছবিগুলো স্থানে (in place) খালি করতে হয়। ট্রেসার একটি বার্তার একই ছবির ডেটায় একাধিক রেফারেন্সের মাধ্যমে পৌঁছাতে পারে, তাই একটি নতুন, খালি তালিকা বসালে মূল ডেটা — পিক্সেলসহ — তবু নাগালযোগ্য থেকে যেত। সংরক্ষিত কথোপকথন-অবস্থা কখনো বদলানো হয় না।

একটি টেস্ট এজেন্টের গ্রাফকে একই ইভেন্ট স্ট্রিমিংয়ের অধীনে চালায়, প্রতি কলে ৪ MB ছবি সহ। ফিক্স ছাড়া ১৬ কলে মেমোরি ৭৭ MB বেড়েছিল। ফিক্সসহ তা স্থির থাকে।

আমরা যা শিখেছি

  • মেমোরির সমস্যা স্তরে স্তরে আসতে পারে। তিনটি আলাদা কারণ প্রতিটি ছবি বেশিক্ষণ ধরে রাখছিল, এবং টার্নটি মেমোরির মধ্যে থাকার আগে তিনটিই দূর করতে হয়েছিল।
  • লাইব্রেরিকে যা দেওয়া হয় তা ধরে রাখা হতে পারে। একটি signal ও একটি ট্রেস দুটোই তাদের দেওয়া কলের চেয়ে বেঁচে ছিল। মেমোরি প্রতি কলে বাড়লে দেখুন কল কোন দীর্ঘজীবী অবজেক্ট ছোঁয়।
  • যা অপর পক্ষ ফেলে দেবে, তা পাঠাবেন না। মডেল যে পিক্সেল এমনিতেই বাদ দিত, তা আমাদের প্রতি কলে মেমোরি খরচ করাত।
  • মেমোরি সরাসরি পরীক্ষা করুন। প্রতিটি ফিক্সের সঙ্গে এমন একটি টেস্ট ছিল যা হিপের বৃদ্ধি বা listener-এর সংখ্যা মাপে, তাই রিগ্রেশন একটি সংখ্যায় দেখা যায়, ক্র্যাশে নয়।

এজেন্টের এই মেমোরি-গল্প অল্প সময়ের মধ্যে দ্বিতীয়বার; প্রথমটি ছিল একটি প্রোগ্রেস লেবেল, যা ৪১,০০০ বার পুনরায় পাঠানো হয়েছিল। এজেন্ট কী ও কীভাবে কাজ করে তা জানতে আমাদের AI এজেন্ট গাইড এবং চ্যাট ডকস দেখুন।

Mythex · Pricing · AI দিয়ে যা খুশি বানান · ওয়েবসাইট ও অ্যাপের টেমপ্লেট · Mythex-এর তুলনা · AI অ্যাপ তৈরির শব্দকোষ · AI অ্যাপ তৈরির বিনামূল্যের টুল · English

English አማርኛ العربية Български Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)