Vertex AI এবং LangChain4j সহ জাভাতে জেমিনি

1. ভূমিকা

এই কোডল্যাবটি জেমিনি লার্জ ল্যাঙ্গুয়েজ মডেল (LLM) এর উপর ফোকাস করে, যা Google ক্লাউডে Vertex AI- তে হোস্ট করা হয়েছে। Vertex AI হল এমন একটি প্ল্যাটফর্ম যা Google ক্লাউডে সমস্ত মেশিন লার্নিং পণ্য, পরিষেবা এবং মডেলগুলিকে অন্তর্ভুক্ত করে৷

আপনি LangChain4j ফ্রেমওয়ার্ক ব্যবহার করে Gemini API এর সাথে ইন্টারঅ্যাক্ট করতে Java ব্যবহার করবেন। প্রশ্নের উত্তর, আইডিয়া জেনারেশন, এন্টিটি এবং স্ট্রাকচার্ড কন্টেন্ট এক্সট্রাকশন, রিট্রিভাল অগমেন্টেড জেনারেশন এবং ফাংশন কলিং এর জন্য LLM এর সুবিধা নিতে আপনি কংক্রিট উদাহরণ দিয়ে যাবেন।

জেনারেটিভ এআই কি?

জেনারেটিভ এআই নতুন বিষয়বস্তু যেমন টেক্সট, ছবি, সঙ্গীত, অডিও এবং ভিডিও তৈরি করতে কৃত্রিম বুদ্ধিমত্তার ব্যবহারকে বোঝায়।

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

জেনারেটিভ এআই কিভাবে কাজ করে?

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

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

সাধারণ জেনারেটিভ এআই অ্যাপ্লিকেশন কি কি?

জেনারেটিভ এআই ব্যবহার করা যেতে পারে:

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

গুগল ক্লাউডে কী জেনারেটিভ এআই অফার রয়েছে?

Vertex AI-এর সাথে, আপনি আপনার অ্যাপ্লিকেশনগুলিতে ফাউন্ডেশন মডেলগুলির সাথে যোগাযোগ করতে, কাস্টমাইজ করতে এবং এম্বেড করতে পারেন সামান্য থেকে কোন ML দক্ষতা ছাড়াই৷ আপনি মডেল গার্ডেনে ফাউন্ডেশন মডেলগুলি অ্যাক্সেস করতে পারেন, Vertex AI স্টুডিওতে একটি সাধারণ UI এর মাধ্যমে মডেলগুলি টিউন করতে পারেন, বা ডেটা সায়েন্স নোটবুকে মডেলগুলি ব্যবহার করতে পারেন৷

Vertex AI সার্চ এবং কথোপকথন ডেভেলপারদের জেনারেটিভ AI চালিত সার্চ ইঞ্জিন এবং চ্যাটবট তৈরি করার দ্রুততম উপায় অফার করে।

Gemini দ্বারা চালিত, Google ক্লাউডের জন্য Gemini হল একটি AI-চালিত সহযোগী Google ক্লাউড এবং IDE জুড়ে উপলব্ধ একটি AI-চালিত সহযোগী যা আপনাকে আরও দ্রুত, আরও কাজ করতে সাহায্য করে৷ জেমিনি কোড অ্যাসিস্ট কোড সম্পূর্ণতা, কোড জেনারেশন, কোড ব্যাখ্যা প্রদান করে এবং আপনাকে প্রযুক্তিগত প্রশ্ন জিজ্ঞাসা করতে এটির সাথে চ্যাট করতে দেয়।

মিথুন কি?

Gemini হল Google DeepMind দ্বারা ডেভেলপ করা জেনারেটিভ এআই মডেলের একটি পরিবার যা মাল্টিমোডাল ব্যবহারের ক্ষেত্রে ডিজাইন করা হয়েছে। মাল্টিমোডাল মানে এটি বিভিন্ন ধরণের সামগ্রী যেমন পাঠ্য, কোড, চিত্র এবং অডিও প্রক্রিয়া করতে এবং তৈরি করতে পারে।

b9913d011999e7c7.png

মিথুন বিভিন্ন বৈচিত্র্য এবং আকারে আসে:

  • জেমিনি আল্ট্রা : জটিল কাজের জন্য সবচেয়ে বড়, সবচেয়ে সক্ষম সংস্করণ।
  • জেমিনি ফ্ল্যাশ : দ্রুততম এবং সবচেয়ে সাশ্রয়ী, উচ্চ-ভলিউম কাজের জন্য অপ্টিমাইজ করা।
  • জেমিনি প্রো : মাঝারি আকারের, বিভিন্ন কাজ জুড়ে স্কেলিং করার জন্য অপ্টিমাইজ করা।
  • জেমিনি ন্যানো : সবচেয়ে দক্ষ, ডিভাইসে কাজ করার জন্য ডিজাইন করা হয়েছে।

মূল বৈশিষ্ট্য:

  • মাল্টিমোডালিটি : মিথুনের একাধিক তথ্য বিন্যাস বোঝা এবং পরিচালনা করার ক্ষমতা ঐতিহ্যগত পাঠ্য-শুধু ভাষার মডেলের বাইরে একটি উল্লেখযোগ্য পদক্ষেপ।
  • পারফরম্যান্স : জেমিনি আল্ট্রা বর্তমান অত্যাধুনিক অনেক বেঞ্চমার্ককে ছাড়িয়ে গেছে এবং চ্যালেঞ্জিং MMLU (ম্যাসিভ মাল্টিটাস্ক ল্যাঙ্গুয়েজ আন্ডারস্ট্যান্ডিং) বেঞ্চমার্কে মানব বিশেষজ্ঞদের ছাড়িয়ে যাওয়া প্রথম মডেল।
  • নমনীয়তা : বিভিন্ন মিথুন মাপ এটিকে বিভিন্ন ব্যবহারের ক্ষেত্রে অভিযোজনযোগ্য করে তোলে, বড় আকারের গবেষণা থেকে শুরু করে মোবাইল ডিভাইসে স্থাপনা পর্যন্ত।

আপনি কিভাবে জাভা থেকে Vertex AI-তে মিথুনের সাথে যোগাযোগ করতে পারেন?

আপনার দুটি বিকল্প আছে:

  1. জেমিনি লাইব্রেরির জন্য অফিসিয়াল Vertex AI Java API
  2. LangChain4j ফ্রেমওয়ার্ক।

এই কোডল্যাবে, আপনি LangChain4j ফ্রেমওয়ার্ক ব্যবহার করবেন।

LangChain4j ফ্রেমওয়ার্ক কি?

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

প্রকল্পটি ল্যাংচেইন পাইথন প্রকল্প দ্বারা অনুপ্রাণিত হয়েছিল কিন্তু জাভা বিকাশকারীদের পরিবেশন করার লক্ষ্যে।

bb908ea1e6c96ac2.png

আপনি কি শিখবেন

  • Gemini এবং LangChain4j ব্যবহার করার জন্য কীভাবে একটি জাভা প্রকল্প সেটআপ করবেন
  • কিভাবে আপনার প্রথম প্রম্পট মিথুন প্রোগ্রামে পাঠাবেন
  • কিভাবে মিথুন থেকে প্রতিক্রিয়া স্ট্রিম করা যায়
  • কীভাবে একজন ব্যবহারকারী এবং মিথুনের মধ্যে কথোপকথন তৈরি করবেন
  • টেক্সট এবং ইমেজ উভয় পাঠিয়ে একটি মাল্টিমোডাল প্রেক্ষাপটে মিথুন কিভাবে ব্যবহার করবেন
  • অসংগঠিত বিষয়বস্তু থেকে কীভাবে দরকারী কাঠামোগত তথ্য বের করা যায়
  • প্রম্পট টেমপ্লেটগুলি কীভাবে পরিচালনা করবেন
  • কিভাবে পাঠ্য শ্রেণীবিভাগ করা যায় যেমন অনুভূতি বিশ্লেষণ
  • কীভাবে আপনার নিজের নথির সাথে চ্যাট করবেন (পুনরুদ্ধার অগমেন্টেড জেনারেশন)
  • কীভাবে আপনার চ্যাটবটগুলিকে ফাংশন কলিংয়ের মাধ্যমে প্রসারিত করবেন
  • ওল্লামা এবং টেস্টকন্টেনারগুলির সাথে স্থানীয়ভাবে জেমা কীভাবে ব্যবহার করবেন

আপনি কি প্রয়োজন হবে

  • জাভা প্রোগ্রামিং ভাষার জ্ঞান
  • একটি Google ক্লাউড প্রকল্প
  • একটি ব্রাউজার, যেমন ক্রোম বা ফায়ারফক্স

2. সেটআপ এবং প্রয়োজনীয়তা

স্ব-গতিসম্পন্ন পরিবেশ সেটআপ

  1. Google ক্লাউড কনসোলে সাইন-ইন করুন এবং একটি নতুন প্রকল্প তৈরি করুন বা বিদ্যমান একটি পুনরায় ব্যবহার করুন৷ আপনার যদি ইতিমধ্যেই একটি Gmail বা Google Workspace অ্যাকাউন্ট না থাকে, তাহলে আপনাকে অবশ্যই একটি তৈরি করতে হবে।

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • প্রকল্পের নাম এই প্রকল্পের অংশগ্রহণকারীদের জন্য প্রদর্শনের নাম। এটি একটি অক্ষর স্ট্রিং যা Google API দ্বারা ব্যবহৃত হয় না। আপনি সবসময় এটি আপডেট করতে পারেন.
  • প্রোজেক্ট আইডি সমস্ত Google ক্লাউড প্রোজেক্ট জুড়ে অনন্য এবং অপরিবর্তনীয় (সেট করার পরে পরিবর্তন করা যাবে না)। ক্লাউড কনসোল স্বয়ংক্রিয়ভাবে একটি অনন্য স্ট্রিং তৈরি করে; সাধারণত আপনি এটা কি যত্ন না. বেশিরভাগ কোডল্যাবে, আপনাকে আপনার প্রকল্প আইডি উল্লেখ করতে হবে (সাধারণত PROJECT_ID হিসাবে চিহ্নিত)। আপনি যদি জেনারেট করা আইডি পছন্দ না করেন, তাহলে আপনি অন্য একটি এলোমেলো আইডি তৈরি করতে পারেন। বিকল্পভাবে, আপনি নিজের চেষ্টা করতে পারেন, এবং এটি উপলব্ধ কিনা দেখতে পারেন। এই ধাপের পরে এটি পরিবর্তন করা যাবে না এবং প্রকল্পের সময়কালের জন্য থাকে।
  • আপনার তথ্যের জন্য, একটি তৃতীয় মান আছে, একটি প্রকল্প নম্বর , যা কিছু API ব্যবহার করে। ডকুমেন্টেশনে এই তিনটি মান সম্পর্কে আরও জানুন।
  1. এরপরে, ক্লাউড রিসোর্স/এপিআই ব্যবহার করতে আপনাকে ক্লাউড কনসোলে বিলিং সক্ষম করতে হবে। এই কোডল্যাবের মাধ্যমে চালানোর জন্য খুব বেশি খরচ হবে না, যদি কিছু হয়। এই টিউটোরিয়ালের বাইরে বিলিং এড়াতে সংস্থানগুলি বন্ধ করতে, আপনি আপনার তৈরি করা সংস্থানগুলি মুছতে বা প্রকল্প মুছতে পারেন। নতুন Google ক্লাউড ব্যবহারকারীরা $300 USD বিনামূল্যের ট্রায়াল প্রোগ্রামের জন্য যোগ্য৷

ক্লাউড শেল শুরু করুন

যদিও Google ক্লাউড আপনার ল্যাপটপ থেকে দূরবর্তীভাবে পরিচালিত হতে পারে, এই কোডল্যাবে আপনি ক্লাউড শেল ব্যবহার করবেন, ক্লাউডে চলমান একটি কমান্ড লাইন পরিবেশ।

ক্লাউড শেল সক্রিয় করুন

  1. ক্লাউড কনসোল থেকে, ক্লাউড শেল সক্রিয় করুন ক্লিক করুন 853e55310c205094.png .

3c1dabeca90e44e5.png

যদি এটি আপনার প্রথমবার ক্লাউড শেল শুরু হয়, তাহলে এটি কী তা বর্ণনা করে আপনাকে একটি মধ্যবর্তী স্ক্রীন উপস্থাপন করা হবে। যদি আপনি একটি মধ্যবর্তী স্ক্রীনের সাথে উপস্থাপিত হন, তবে চালিয়ে যান ক্লিক করুন।

9c92662c6a846a5c.png

ক্লাউড শেলের সাথে সংযোগ করতে এবং সংযোগ করতে এটির মাত্র কয়েক মুহূর্ত লাগবে৷

9f0e51b578fecce5.png

এই ভার্চুয়াল মেশিনটি প্রয়োজনীয় সমস্ত বিকাশের সরঞ্জাম দিয়ে লোড করা হয়েছে। এটি একটি ক্রমাগত 5 GB হোম ডিরেক্টরি অফার করে এবং Google ক্লাউডে চলে, যা নেটওয়ার্ক কর্মক্ষমতা এবং প্রমাণীকরণকে ব্যাপকভাবে উন্নত করে। এই কোডল্যাবে আপনার অনেক কাজ, যদি সব না হয়, ব্রাউজার দিয়ে করা যেতে পারে।

একবার ক্লাউড শেলের সাথে সংযুক্ত হয়ে গেলে, আপনি দেখতে পাবেন যে আপনি প্রমাণীকৃত হয়েছেন এবং প্রকল্পটি আপনার প্রকল্প আইডিতে সেট করা আছে।

  1. আপনি প্রমাণীকৃত কিনা তা নিশ্চিত করতে ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালান:
gcloud auth list

কমান্ড আউটপুট

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. gcloud কমান্ড আপনার প্রকল্প সম্পর্কে জানে তা নিশ্চিত করতে ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালান:
gcloud config list project

কমান্ড আউটপুট

[core]
project = <PROJECT_ID>

যদি এটি না হয়, আপনি এই কমান্ড দিয়ে এটি সেট করতে পারেন:

gcloud config set project <PROJECT_ID>

কমান্ড আউটপুট

Updated property [core/project].

3. আপনার উন্নয়ন পরিবেশ প্রস্তুত করা

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

Vertex AI APIs সক্ষম করুন

Google ক্লাউড কনসোলে, নিশ্চিত করুন যে আপনার প্রোজেক্টের নামটি আপনার Google ক্লাউড কনসোলের শীর্ষে প্রদর্শিত হচ্ছে। যদি তা না হয়, তাহলে প্রজেক্ট সিলেক্টর খুলতে একটি প্রজেক্ট নির্বাচন করুন ক্লিক করুন এবং আপনার উদ্দেশ্যপ্রণোদিত প্রকল্প নির্বাচন করুন।

আপনি Google ক্লাউড কনসোলের Vertex AI বিভাগ থেকে বা ক্লাউড শেল টার্মিনাল থেকে Vertex AI APIs সক্ষম করতে পারেন।

Google ক্লাউড কনসোল থেকে সক্ষম করতে, প্রথমে, Google ক্লাউড কনসোল মেনুর Vertex AI বিভাগে যান:

451976f1c8652341.png

Vertex AI ড্যাশবোর্ডে সমস্ত প্রস্তাবিত API সক্রিয় করুন ক্লিক করুন৷

এটি বেশ কয়েকটি API সক্রিয় করবে, কিন্তু কোডল্যাবের জন্য সবচেয়ে গুরুত্বপূর্ণ হল aiplatform.googleapis.com

বিকল্পভাবে, আপনি নিম্নলিখিত কমান্ডের সাহায্যে ক্লাউড শেল টার্মিনাল থেকে এই API সক্রিয় করতে পারেন:

gcloud services enable aiplatform.googleapis.com

Github সংগ্রহস্থল ক্লোন করুন

ক্লাউড শেল টার্মিনালে, এই কোডল্যাবের জন্য সংগ্রহস্থল ক্লোন করুন:

git clone https://github.com/glaforge/gemini-workshop-for-java-developers.git

প্রকল্পটি চালানোর জন্য প্রস্তুত কিনা তা পরীক্ষা করতে, আপনি "হ্যালো ওয়ার্ল্ড" প্রোগ্রাম চালানোর চেষ্টা করতে পারেন।

আপনি শীর্ষ স্তরের ফোল্ডারে আছেন তা নিশ্চিত করুন:

cd gemini-workshop-for-java-developers/ 

গ্রেডল র‍্যাপার তৈরি করুন:

gradle wrapper

gradlew দিয়ে চালান:

./gradlew run

আপনি নিম্নলিখিত আউটপুট দেখতে হবে:

..
> Task :app:run
Hello World!

ক্লাউড এডিটর খুলুন এবং সেটআপ করুন

ক্লাউড শেল থেকে ক্লাউড কোড এডিটর দিয়ে কোডটি খুলুন:

42908e11b28f4383.png

ক্লাউড কোড এডিটরে, File -> Open Folder নির্বাচন করে কোডল্যাব উত্স ফোল্ডারটি খুলুন এবং কোডল্যাব উত্স ফোল্ডারে নির্দেশ করুন (যেমন /home/username/gemini-workshop-for-java-developers/ )।

জাভার জন্য Gradle ইনস্টল করুন

ক্লাউড কোড এডিটর গ্র্যাডলের সাথে সঠিকভাবে কাজ করতে, জাভা এক্সটেনশনের জন্য গ্রেডল ইনস্টল করুন।

প্রথমে, Java Projects বিভাগে যান এবং প্লাস চিহ্ন টিপুন:

84d15639ac61c197.png

Gradle for Java নির্বাচন করুন:

34d6c4136a3cc9ff.png

Install Pre-Release নির্বাচন করুন:

3b044fb450cccb7.png

একবার ইনস্টল হয়ে গেলে, আপনি Disable এবং Uninstall বোতামগুলি দেখতে পাবেন:

46410fe86d777f9c.png

অবশেষে, নতুন সেটিংস প্রয়োগ করতে কর্মক্ষেত্র পরিষ্কার করুন:

31e27e9bb61d975d.png

এটি আপনাকে ওয়ার্কশপটি পুনরায় লোড করতে এবং মুছতে বলবে। এগিয়ে যান এবং Reload and delete নির্বাচন করুন:

d6303bc49e391dc.png

আপনি যদি একটি ফাইল খোলেন, উদাহরণস্বরূপ App.java, আপনি এখন দেখতে পাবেন যে সম্পাদকটি সিনট্যাক্স হাইলাইটিংয়ের সাথে সঠিকভাবে কাজ করছে:

fed1b1b5de0dff58.png

আপনি এখন মিথুনের বিরুদ্ধে কিছু নমুনা চালানোর জন্য প্রস্তুত!

পরিবেশ ভেরিয়েবল সেটআপ করুন

Terminal -> New Terminal নির্বাচন করে ক্লাউড কোড এডিটরে একটি নতুন টার্মিনাল খুলুন। কোড উদাহরণ চালানোর জন্য প্রয়োজনীয় দুটি পরিবেশ ভেরিয়েবল সেট আপ করুন:

  • PROJECT_ID — আপনার Google ক্লাউড প্রকল্প আইডি
  • অবস্থান — যে অঞ্চলে মিথুন মডেল স্থাপন করা হয়েছে

নিম্নরূপ ভেরিয়েবল রপ্তানি করুন:

export PROJECT_ID=$(gcloud config get-value project)
export LOCATION=us-central1

4. প্রথমে মিথুন মডেলকে কল করুন

এখন যেহেতু প্রকল্পটি সঠিকভাবে সেট আপ করা হয়েছে, এটি জেমিনি API কল করার সময়।

app/src/main/java/gemini/workshop ডিরেক্টরিতে QA.java দেখুন:

package gemini.workshop;

import dev.langchain4j.model.vertexai.VertexAiGeminiChatModel;
import dev.langchain4j.model.chat.ChatLanguageModel;

public class QA {
    public static void main(String[] args) {
        ChatLanguageModel model = VertexAiGeminiChatModel.builder()
            .project(System.getenv("PROJECT_ID"))
            .location(System.getenv("LOCATION"))
            .modelName("gemini-1.5-flash-001")
            .build();

        System.out.println(model.generate("Why is the sky blue?"));
    }
}

এই প্রথম উদাহরণে, আপনাকে VertexAiGeminiChatModel ক্লাস আমদানি করতে হবে, যা ChatModel ইন্টারফেস প্রয়োগ করে।

main পদ্ধতিতে, আপনি VertexAiGeminiChatModel এর জন্য নির্মাতা ব্যবহার করে চ্যাট ভাষার মডেল কনফিগার করেন এবং উল্লেখ করুন:

  • প্রকল্প
  • অবস্থান
  • মডেলের নাম ( gemini-1.5-flash-001 )।

এখন যেহেতু ভাষা মডেল প্রস্তুত, আপনি generate() পদ্ধতিতে কল করতে পারেন এবং আপনার প্রম্পট, আপনার প্রশ্ন বা নির্দেশাবলী এলএলএম-এ পাঠাতে পারেন। এখানে, আপনি আকাশকে কী নীল করে তোলে সে সম্পর্কে একটি সহজ প্রশ্ন জিজ্ঞাসা করুন।

বিভিন্ন প্রশ্ন বা কাজ চেষ্টা করার জন্য এই প্রম্পটটি পরিবর্তন করতে দ্বিধা বোধ করুন।

সোর্স কোড রুট ফোল্ডারে নমুনা চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.QA

আপনি এই এক অনুরূপ একটি আউটপুট দেখতে হবে:

The sky appears blue because of a phenomenon called Rayleigh scattering.
When sunlight enters the atmosphere, it is made up of a mixture of
different wavelengths of light, each with a different color. The
different wavelengths of light interact with the molecules and particles
in the atmosphere in different ways.

The shorter wavelengths of light, such as those corresponding to blue
and violet light, are more likely to be scattered in all directions by
these particles than the longer wavelengths of light, such as those
corresponding to red and orange light. This is because the shorter
wavelengths of light have a smaller wavelength and are able to bend
around the particles more easily.

As a result of Rayleigh scattering, the blue light from the sun is
scattered in all directions, and it is this scattered blue light that we
see when we look up at the sky. The blue light from the sun is not
actually scattered in a single direction, so the color of the sky can
vary depending on the position of the sun in the sky and the amount of
dust and water droplets in the atmosphere.

অভিনন্দন, আপনি মিথুনকে আপনার প্রথম কল করেছেন!

স্ট্রিমিং প্রতিক্রিয়া

আপনি কি লক্ষ্য করেছেন যে প্রতিক্রিয়াটি কয়েক সেকেন্ড পরে একযোগে দেওয়া হয়েছিল? স্ট্রিমিং রেসপন্স ভেরিয়েন্টের জন্য ধন্যবাদ ক্রমান্বয়ে সাড়া পাওয়াও সম্ভব। স্ট্রিমিং প্রতিক্রিয়া, মডেলটি উপলব্ধ হওয়ার সাথে সাথে টুকরো টুকরো প্রতিক্রিয়া প্রদান করে।

এই কোডল্যাবে, আমরা নন-স্ট্রিমিং রেসপন্সের সাথে লেগে থাকব কিন্তু এটা কিভাবে করা যায় তা দেখতে স্ট্রিমিং রেসপন্স দেখে নেওয়া যাক।

app/src/main/java/gemini/workshop ডিরেক্টরিতে StreamQA.java এ আপনি স্ট্রিমিং প্রতিক্রিয়া দেখতে পাবেন:

package gemini.workshop;

import dev.langchain4j.model.chat.StreamingChatLanguageModel;
import dev.langchain4j.model.vertexai.VertexAiGeminiStreamingChatModel;
import dev.langchain4j.model.StreamingResponseHandler;

public class StreamQA {
    public static void main(String[] args) {
        StreamingChatLanguageModel model = VertexAiGeminiStreamingChatModel.builder()
            .project(System.getenv("PROJECT_ID"))
            .location(System.getenv("LOCATION"))
            .modelName("gemini-1.5-flash-001")
            .build();
        
        model.generate("Why is the sky blue?", new StreamingResponseHandler<>() {
            @Override
            public void onNext(String text) {
                System.out.println(text);
            }

            @Override
            public void onError(Throwable error) {
                error.printStackTrace();
            }
        });
    }
}

এইবার, আমরা স্ট্রিমিং ক্লাস ভেরিয়েন্টগুলি আমদানি করি VertexAiGeminiStreamingChatModel যা StreamingChatLanguageModel ইন্টারফেস প্রয়োগ করে৷ আপনার একটি StreamingResponseHandler ও প্রয়োজন হবে।

এবার, generate() পদ্ধতির স্বাক্ষর একটু ভিন্ন। একটি স্ট্রিং রিটার্ন করার পরিবর্তে, রিটার্ন টাইপটি অকার্যকর। প্রম্পট ছাড়াও, আপনাকে একটি স্ট্রিমিং প্রতিক্রিয়া হ্যান্ডলার পাস করতে হবে। এখানে, আপনি onNext(String text) এবং onError(Throwable error) দুটি পদ্ধতি সহ একটি বেনামী অভ্যন্তরীণ শ্রেণী তৈরি করে ইন্টারফেসটি বাস্তবায়ন করেন। প্রতিবার প্রতিক্রিয়ার একটি নতুন অংশ পাওয়া গেলে পূর্ববর্তীটিকে বলা হয়, যখন কোনো ত্রুটি ঘটে তবেই পরবর্তীটিকে কল করা হয়।

চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.StreamQA

আপনি পূর্ববর্তী ক্লাসের অনুরূপ উত্তর পাবেন, কিন্তু এবার, আপনি লক্ষ্য করবেন যে উত্তরটি সম্পূর্ণ উত্তর প্রদর্শনের জন্য অপেক্ষা না করে আপনার শেলে ক্রমান্বয়ে উপস্থিত হচ্ছে।

অতিরিক্ত কনফিগারেশন

কনফিগারেশনের জন্য, আমরা শুধুমাত্র প্রকল্প, অবস্থান এবং মডেলের নাম সংজ্ঞায়িত করেছি, তবে মডেলের জন্য আপনি নির্দিষ্ট করতে পারেন এমন অন্যান্য পরামিতি রয়েছে:

  • temperature(Float temp) - আপনি প্রতিক্রিয়াটি কতটা সৃজনশীল করতে চান তা নির্ধারণ করতে (0 কম সৃজনশীল এবং প্রায়শই বেশি বাস্তব, যখন 1 আরও সৃজনশীল আউটপুটগুলির জন্য)
  • topP(Float topP) - সম্ভাব্য শব্দ নির্বাচন করতে যার মোট সম্ভাব্যতা সেই ফ্লোটিং পয়েন্ট সংখ্যা পর্যন্ত যোগ করে (0 এবং 1 এর মধ্যে)
  • topK(Integer topK) — পাঠ্য সমাপ্তির জন্য সর্বাধিক সম্ভাব্য শব্দের মধ্যে এলোমেলোভাবে একটি শব্দ নির্বাচন করতে (1 থেকে 40 পর্যন্ত)
  • maxOutputTokens(Integer max) — মডেল দ্বারা প্রদত্ত উত্তরের সর্বাধিক দৈর্ঘ্য নির্দিষ্ট করতে (সাধারণত, 4টি টোকেন প্রায় 3টি শব্দ উপস্থাপন করে)
  • maxRetries(Integer retries) — যদি আপনি প্রতি কোটা প্রতি অনুরোধ অতিক্রম করেন, বা প্ল্যাটফর্মটি কিছু প্রযুক্তিগত সমস্যার সম্মুখীন হয়, আপনি মডেলটি 3 বার কলটি পুনরায় চেষ্টা করতে পারেন

এখন পর্যন্ত, আপনি মিথুনকে একটি একক প্রশ্ন করেছেন, কিন্তু আপনি একটি বহুমুখী কথোপকথনও করতে পারেন। এটিই আপনি পরবর্তী বিভাগে অন্বেষণ করবেন।

5. মিথুনের সাথে চ্যাট করুন

আগের ধাপে, আপনি একটি একক প্রশ্ন জিজ্ঞাসা করেছেন। এখন সময় এসেছে একজন ব্যবহারকারী এবং এলএলএম-এর মধ্যে সত্যিকারের কথোপকথনের। প্রতিটি প্রশ্ন ও উত্তর একটি বাস্তব আলোচনা গঠনের জন্য পূর্ববর্তী প্রশ্নগুলির উপর ভিত্তি করে তৈরি করতে পারে।

app/src/main/java/gemini/workshop ফোল্ডারে Conversation.java দেখুন:

package gemini.workshop;

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.vertexai.VertexAiGeminiChatModel;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.service.AiServices;

import java.util.List;

public class Conversation {
    public static void main(String[] args) {
        ChatLanguageModel model = VertexAiGeminiChatModel.builder()
            .project(System.getenv("PROJECT_ID"))
            .location(System.getenv("LOCATION"))
            .modelName("gemini-1.5-flash-001")
            .build();

        MessageWindowChatMemory chatMemory = MessageWindowChatMemory.builder()
            .maxMessages(20)
            .build();

        interface ConversationService {
            String chat(String message);
        }

        ConversationService conversation =
            AiServices.builder(ConversationService.class)
                .chatLanguageModel(model)
                .chatMemory(chatMemory)
                .build();

        List.of(
            "Hello!",
            "What is the country where the Eiffel tower is situated?",
            "How many inhabitants are there in that country?"
        ).forEach( message -> {
            System.out.println("\nUser: " + message);
            System.out.println("Gemini: " + conversation.chat(message));
        });
    }
}

এই শ্রেণীতে কিছু নতুন আকর্ষণীয় আমদানি:

  • MessageWindowChatMemory — একটি ক্লাস যা কথোপকথনের বহুমুখী দিক পরিচালনা করতে সাহায্য করবে এবং পূর্ববর্তী প্রশ্ন ও উত্তরগুলি স্থানীয় স্মৃতিতে রাখবে
  • AiServices — এমন একটি ক্লাস যা চ্যাট মডেল এবং চ্যাট মেমরিকে একত্রিত করবে

মূল পদ্ধতিতে, আপনি মডেল, চ্যাট মেমরি এবং এআই পরিষেবা সেট আপ করতে যাচ্ছেন। মডেলটি যথারীতি প্রকল্প, অবস্থান এবং মডেলের নাম তথ্যের সাথে কনফিগার করা হয়েছে।

চ্যাট মেমরির জন্য, আমরা একটি মেমরি তৈরি করতে MessageWindowChatMemory এর নির্মাতা ব্যবহার করি যা শেষ 20টি বার্তা আদান প্রদান করে। এটি কথোপকথনের উপর একটি স্লাইডিং উইন্ডো যার প্রসঙ্গ স্থানীয়ভাবে আমাদের জাভা ক্লাস ক্লায়েন্টে রাখা হয়।

তারপরে আপনি AI service তৈরি করুন যা চ্যাট মেমরির সাথে চ্যাট মডেলকে আবদ্ধ করে।

লক্ষ্য করুন কিভাবে AI পরিষেবা আমাদের সংজ্ঞায়িত একটি কাস্টম ConversationService ইন্টারফেস ব্যবহার করে, যেটি LangChain4j প্রয়োগ করে, এবং এটি একটি String ক্যোয়ারী নেয় এবং একটি String প্রতিক্রিয়া প্রদান করে।

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

নমুনা চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.Conversation

আপনি এইগুলির অনুরূপ তিনটি উত্তর দেখতে হবে:

User: Hello!
Gemini: Hi there! How can I assist you today?

User: What is the country where the Eiffel tower is situated?
Gemini: France

User: How many inhabitants are there in that country?
Gemini: As of 2023, the population of France is estimated to be around 67.8 million.

আপনি এক-পালা প্রশ্ন জিজ্ঞাসা করতে পারেন বা মিথুনের সাথে বহু-পালা কথোপকথন করতে পারেন তবে এখনও পর্যন্ত, ইনপুটটি কেবল পাঠ্য ছিল। ইমেজ সম্পর্কে কি? আসুন পরবর্তী ধাপে ছবিগুলি অন্বেষণ করি৷

6. মিথুনের সাথে মাল্টিমোডালিটি

মিথুন একটি মাল্টিমডাল মডেল। এটি কেবল পাঠ্যকে ইনপুট হিসাবে গ্রহণ করে না, তবে এটি ছবি বা এমনকি ভিডিওগুলিকেও ইনপুট হিসাবে গ্রহণ করে। এই বিভাগে, আপনি টেক্সট এবং ছবি মিশ্রিত করার জন্য একটি ব্যবহার কেস দেখতে পাবেন।

আপনার কি মনে হয় মিথুন এই বিড়ালটিকে চিনবে?

af00516493ec9ade.png

বরফের মধ্যে একটি বিড়ালের ছবি উইকিপিডিয়া https://upload.wikimedia.org/wikipedia/commons/b/b6/Felis_catus-cat_on_snow.jpg থেকে নেওয়া

app/src/main/java/gemini/workshop ডিরেক্টরিতে Multimodal.java দেখুন:

package gemini.workshop;

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.vertexai.VertexAiGeminiChatModel;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.data.message.ImageContent;
import dev.langchain4j.data.message.TextContent;

public class Multimodal {

    static final String CAT_IMAGE_URL =
        "https://upload.wikimedia.org/wikipedia/" +
        "commons/b/b6/Felis_catus-cat_on_snow.jpg";


    public static void main(String[] args) {
        ChatLanguageModel model = VertexAiGeminiChatModel.builder()
            .project(System.getenv("PROJECT_ID"))
            .location(System.getenv("LOCATION"))
            .modelName("gemini-1.5-flash-001")
            .build();

        UserMessage userMessage = UserMessage.from(
            ImageContent.from(CAT_IMAGE_URL),
            TextContent.from("Describe the picture")
        );

        Response<AiMessage> response = model.generate(userMessage);

        System.out.println(response.content().text());
    }
}

আমদানিতে, লক্ষ্য করুন আমরা বিভিন্ন ধরণের বার্তা এবং বিষয়বস্তুর মধ্যে পার্থক্য করি। একটি UserMessage একটি TextContent এবং একটি ImageContent বিষয়বস্তু উভয়ই থাকতে পারে। এটি খেলার মাল্টিমোডালিটি: টেক্সট এবং ইমেজ মিশ্রিত করা। মডেলটি একটি Response ফেরত পাঠায় যাতে একটি AiMessage রয়েছে।

তারপর আপনি content() এর মাধ্যমে প্রতিক্রিয়া থেকে AiMessage পুনরুদ্ধার করবেন এবং তারপর বার্তাটির পাঠ্য text() এর জন্য ধন্যবাদ।

নমুনা চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.Multimodal

ছবির নামটি অবশ্যই আপনাকে ছবিটিতে কী রয়েছে তার একটি ইঙ্গিত দিয়েছে তবে মিথুন আউটপুট নিম্নলিখিতগুলির মতো:

A cat with brown fur is walking in the snow. The cat has a white patch of fur on its chest and white paws. The cat is looking at the camera.

ইমেজ এবং টেক্সট প্রম্পট মিশ্রিত করা আকর্ষণীয় ব্যবহারের ক্ষেত্রে খোলে। আপনি এমন অ্যাপ্লিকেশন তৈরি করতে পারেন যা করতে পারে:

  • ছবিতে পাঠ্য চিনুন।
  • একটি ছবি প্রদর্শন করা নিরাপদ কিনা তা পরীক্ষা করুন।
  • ছবির ক্যাপশন তৈরি করুন।
  • প্লেইন টেক্সট বর্ণনা সহ চিত্রগুলির একটি ডাটাবেসের মাধ্যমে অনুসন্ধান করুন।

ইমেজ থেকে তথ্য আহরণ ছাড়াও, আপনি অসংগঠিত পাঠ্য থেকে তথ্য আহরণ করতে পারেন। যে আপনি পরবর্তী বিভাগে শিখতে যাচ্ছেন কি.

7. কাঠামোবিহীন পাঠ্য থেকে কাঠামোগত তথ্য বের করুন

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

ধরা যাক আপনি একজন ব্যক্তির নাম এবং বয়স বের করতে চান, সেই ব্যক্তির জীবনী বা বিবরণ দেওয়া হয়েছে। আপনি LLM-কে একটি চতুরভাবে টুইক করা প্রম্পটের সাহায্যে আনস্ট্রাকচার্ড টেক্সট থেকে JSON বের করার নির্দেশ দিতে পারেন (এটিকে সাধারণত "প্রম্পট ইঞ্জিনিয়ারিং" বলা হয়)।

app/src/main/java/gemini/workshopExtractData.java দেখুন:

package gemini.workshop;

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.vertexai.VertexAiGeminiChatModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.UserMessage;

public class ExtractData {

    static record Person(String name, int age) {}

    interface PersonExtractor {
        @UserMessage("""
            Extract the name and age of the person described below.
            Return a JSON document with a "name" and an "age" property, \
            following this structure: {"name": "John Doe", "age": 34}
            Return only JSON, without any markdown markup surrounding it.
            Here is the document describing the person:
            ---
            {{it}}
            ---
            JSON:
            """)
        Person extractPerson(String text);
    }

    public static void main(String[] args) {
        ChatLanguageModel model = VertexAiGeminiChatModel.builder()
            .project(System.getenv("PROJECT_ID"))
            .location(System.getenv("LOCATION"))
            .modelName("gemini-1.5-flash-001")
            .temperature(0f)
            .topK(1)
            .build();

        PersonExtractor extractor = AiServices.create(PersonExtractor.class, model);

        Person person = extractor.extractPerson("""
            Anna is a 23 year old artist based in Brooklyn, New York. She was born and 
            raised in the suburbs of Chicago, where she developed a love for art at a 
            young age. She attended the School of the Art Institute of Chicago, where 
            she studied painting and drawing. After graduating, she moved to New York 
            City to pursue her art career. Anna's work is inspired by her personal 
            experiences and observations of the world around her. She often uses bright 
            colors and bold lines to create vibrant and energetic paintings. Her work 
            has been exhibited in galleries and museums in New York City and Chicago.    
            """
        );

        System.out.println(person.name());  // Anna
        System.out.println(person.age());   // 23
    }
}

চলুন এই ফাইলের বিভিন্ন ধাপ দেখে নেওয়া যাক:

  • একটি Person রেকর্ড একটি ব্যক্তির (নাম এবং বয়স) বর্ণনা বিবরণ প্রতিনিধিত্ব করার জন্য সংজ্ঞায়িত করা হয়.
  • PersonExtractor ইন্টারফেস একটি পদ্ধতি দ্বারা সংজ্ঞায়িত করা হয় যা একটি অসংগঠিত পাঠ্য স্ট্রিং প্রদান করে, একটি Person উদাহরণ প্রদান করে।
  • extractPerson() একটি @UserMessage টীকা দিয়ে টীকা করা হয় যা এটির সাথে একটি প্রম্পট যুক্ত করে। এটি সেই প্রম্পট যা মডেলটি তথ্য বের করার জন্য ব্যবহার করবে, এবং একটি JSON নথির আকারে বিশদগুলি ফেরত দেবে, যা আপনার জন্য পার্স করা হবে এবং একটি Person উদাহরণে আনমার্শাল করা হবে।

এখন main() পদ্ধতির বিষয়বস্তু দেখি:

  • চ্যাট মডেল তাত্ক্ষণিক হয়. লক্ষ্য করুন যে আমরা একটি অত্যন্ত নির্ধারক উত্তর নিশ্চিত করতে শূন্যের একটি খুব কম temperature এবং শুধুমাত্র একটির topK ব্যবহার করি। এটি মডেলটিকে আরও ভালভাবে নির্দেশাবলী অনুসরণ করতে সহায়তা করে৷ বিশেষ করে, আমরা চাই না যে জেমিনি অতিরিক্ত মার্কডাউন মার্কআপ দিয়ে JSON প্রতিক্রিয়া মোড়ক করুক।
  • LangChain4j এর AiServices ক্লাসের জন্য একটি PersonExtractor অবজেক্ট তৈরি করা হয়েছে।
  • তারপরে, আপনি কেবল Person person = extractor.extractPerson(...) অসংগঠিত পাঠ্য থেকে ব্যক্তির বিবরণ বের করতে এবং নাম এবং বয়স সহ একটি Person উদাহরণ ফিরে পেতে পারেন।

নমুনা চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.ExtractData

আপনি নিম্নলিখিত আউটপুট দেখতে হবে:

Anna
23

হ্যাঁ, এই আন্না এবং তারা 23!

এই AiServices পদ্ধতির সাহায্যে আপনি দৃঢ়ভাবে টাইপ করা বস্তুর সাথে কাজ করেন। আপনি LLM-এর সাথে সরাসরি যোগাযোগ করছেন না। পরিবর্তে, আপনি কংক্রিট ক্লাসের সাথে কাজ করছেন, যেমন এক্সট্রাক্ট করা ব্যক্তিগত তথ্যের প্রতিনিধিত্ব করার জন্য Person রেকর্ড, এবং আপনার কাছে একটি extractPerson() পদ্ধতি সহ একটি PersonExtractor অবজেক্ট রয়েছে যা একটি Person উদাহরণ প্রদান করে। এলএলএম এর ধারণাটি বিমূর্ত হয়ে গেছে এবং জাভা বিকাশকারী হিসাবে আপনি কেবল সাধারণ ক্লাস এবং অবজেক্টগুলিকে ম্যানিপুলেট করছেন।

8. প্রম্পট টেমপ্লেট সহ কাঠামো প্রম্পট

আপনি যখন নির্দেশাবলী বা প্রশ্নগুলির একটি সাধারণ সেট ব্যবহার করে একটি LLM এর সাথে ইন্টারঅ্যাক্ট করেন, তখন সেই প্রম্পটের একটি অংশ থাকে যা কখনই পরিবর্তিত হয় না, অন্য অংশগুলিতে ডেটা থাকে। উদাহরণস্বরূপ, আপনি যদি রেসিপি তৈরি করতে চান, আপনি একটি প্রম্পট ব্যবহার করতে পারেন যেমন "আপনি একজন প্রতিভাবান শেফ, অনুগ্রহ করে নিম্নলিখিত উপাদানগুলির সাথে একটি রেসিপি তৈরি করুন: ...", এবং তারপরে আপনি উপাদানগুলিকে এর শেষে যুক্ত করবেন যে পাঠ্য প্রম্পট টেমপ্লেটগুলি এর জন্যই - প্রোগ্রামিং ভাষায় ইন্টারপোলেটেড স্ট্রিংগুলির মতো। একটি প্রম্পট টেমপ্লেটে স্থানধারক রয়েছে যা আপনি এলএলএম-এ একটি নির্দিষ্ট কলের জন্য সঠিক ডেটা দিয়ে প্রতিস্থাপন করতে পারেন।

আরও সুনির্দিষ্টভাবে, আসুন app/src/main/java/gemini/workshop ডিরেক্টরিতে TemplatePrompt.java অধ্যয়ন করি:

package gemini.workshop;

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.vertexai.VertexAiGeminiChatModel;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.model.input.PromptTemplate;
import dev.langchain4j.model.output.Response;

import java.util.HashMap;
import java.util.Map;

public class TemplatePrompt {
    public static void main(String[] args) {
        ChatLanguageModel model = VertexAiGeminiChatModel.builder()
            .project(System.getenv("PROJECT_ID"))
            .location(System.getenv("LOCATION"))
            .modelName("gemini-1.5-flash-001")
            .maxOutputTokens(500)
            .temperature(0.8f)
            .topK(40)
            .topP(0.95f)
            .maxRetries(3)
            .build();

        PromptTemplate promptTemplate = PromptTemplate.from("""
            You're a friendly chef with a lot of cooking experience.
            Create a recipe for a {{dish}} with the following ingredients: \
            {{ingredients}}, and give it a name.
            """
        );

        Map<String, Object> variables = new HashMap<>();
        variables.put("dish", "dessert");
        variables.put("ingredients", "strawberries, chocolate, and whipped cream");

        Prompt prompt = promptTemplate.apply(variables);

        Response<AiMessage> response = model.generate(prompt.toUserMessage());

        System.out.println(response.content().text());
    }
}

যথারীতি, আপনি VertexAiGeminiChatModel মডেল কনফিগার করেন, উচ্চ তাপমাত্রা সহ উচ্চ স্তরের সৃজনশীলতা এবং উচ্চ টপপি এবং টপকে মান। তারপর আপনি আমাদের প্রম্পটের স্ট্রিং পাস করে এর from() স্ট্যাটিক পদ্ধতির সাথে একটি PromptTemplate তৈরি করুন এবং ডবল কার্লি-ব্রেসেস প্লেসহোল্ডার ভেরিয়েবল ব্যবহার করুন: এবং

আপনি apply() কল করে চূড়ান্ত প্রম্পট তৈরি করেন যা কী/মান জোড়ার একটি মানচিত্র নেয় যা স্থানধারকের নাম এবং এটির সাথে প্রতিস্থাপন করার জন্য স্ট্রিং মান উপস্থাপন করে।

সবশেষে, আপনি সেই প্রম্পট থেকে একটি ব্যবহারকারী বার্তা তৈরি করে জেমিনি মডেলের generate() পদ্ধতিকে কল করুন, prompt.toUserMessage() নির্দেশনা সহ।

নমুনা চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.TemplatePrompt

আপনার একটি উত্পন্ন আউটপুট দেখতে হবে যা এইটির মতো দেখাচ্ছে:

**Strawberry Shortcake**

Ingredients:

* 1 pint strawberries, hulled and sliced
* 1/2 cup sugar
* 1/4 cup cornstarch
* 1/4 cup water
* 1 tablespoon lemon juice
* 1/2 cup heavy cream, whipped
* 1/4 cup confectioners' sugar
* 1/4 teaspoon vanilla extract
* 6 graham cracker squares, crushed

Instructions:

1. In a medium saucepan, combine the strawberries, sugar, cornstarch, 
water, and lemon juice. Bring to a boil over medium heat, stirring 
constantly. Reduce heat and simmer for 5 minutes, or until the sauce has 
thickened.
2. Remove from heat and let cool slightly.
3. In a large bowl, combine the whipped cream, confectioners' sugar, and 
vanilla extract. Beat until soft peaks form.
4. To assemble the shortcakes, place a graham cracker square on each of 
6 dessert plates. Top with a scoop of whipped cream, then a spoonful of 
strawberry sauce. Repeat layers, ending with a graham cracker square.
5. Serve immediately.

**Tips:**

* For a more elegant presentation, you can use fresh strawberries 
instead of sliced strawberries.
* If you don't have time to make your own whipped cream, you can use 
store-bought whipped cream.

মানচিত্রে dish এবং ingredients মান পরিবর্তন করতে নির্দ্বিধায় এবং তাপমাত্রা, topK এবং tokP পরিবর্তন করুন এবং কোডটি পুনরায় চালান। এটি আপনাকে LLM-তে এই পরামিতিগুলি পরিবর্তন করার প্রভাব পর্যবেক্ষণ করতে দেবে।

প্রম্পট টেমপ্লেটগুলি এলএলএম কলগুলির জন্য পুনরায় ব্যবহারযোগ্য এবং প্যারামিটারাইজযোগ্য নির্দেশাবলী পাওয়ার একটি ভাল উপায়। আপনি ডেটা পাস করতে পারেন এবং আপনার ব্যবহারকারীদের দ্বারা প্রদত্ত বিভিন্ন মানের জন্য প্রম্পট কাস্টমাইজ করতে পারেন।

9. কয়েক শট প্রম্পটিং সহ পাঠ্য শ্রেণিবিন্যাস

এলএলএমগুলি পাঠ্যকে বিভিন্ন বিভাগে শ্রেণিবদ্ধ করতে বেশ ভাল। আপনি পাঠ্যের কিছু উদাহরণ এবং তাদের সম্পর্কিত বিভাগ প্রদান করে সেই কাজে একজন এলএলএমকে সাহায্য করতে পারেন। এই পদ্ধতিকে প্রায়ই কয়েক শট প্রম্পটিং বলা হয়।

একটি নির্দিষ্ট ধরনের টেক্সট শ্রেণীবিভাগ করার জন্য app/src/main/java/gemini/workshop ডিরেক্টরিতে TextClassification.java দেখুন: অনুভূতি বিশ্লেষণ।

package gemini.workshop;

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.vertexai.VertexAiGeminiChatModel;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.model.input.Prompt;

package gemini.workshop;

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.vertexai.VertexAiGeminiChatModel;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.model.input.PromptTemplate;
import dev.langchain4j.model.output.Response;

import java.util.Map;

public class TextClassification {
    public static void main(String[] args) {
        ChatLanguageModel model = VertexAiGeminiChatModel.builder()
            .project(System.getenv("PROJECT_ID"))
            .location(System.getenv("LOCATION"))
            .modelName("gemini-1.5-flash-001")
            .maxOutputTokens(10)
            .maxRetries(3)
            .build();

        PromptTemplate promptTemplate = PromptTemplate.from("""
            Analyze the sentiment of the text below. Respond only with one word to describe the sentiment.

            INPUT: This is fantastic news!
            OUTPUT: POSITIVE

            INPUT: Pi is roughly equal to 3.14
            OUTPUT: NEUTRAL

            INPUT: I really disliked the pizza. Who would use pineapples as a pizza topping?
            OUTPUT: NEGATIVE

            INPUT: {{text}}
            OUTPUT: 
            """);

        Prompt prompt = promptTemplate.apply(
            Map.of("text", "I love strawberries!"));

        Response<AiMessage> response = model.generate(prompt.toUserMessage());

        System.out.println(response.content().text());
    }
}

main() পদ্ধতিতে, আপনি যথারীতি জেমিনি চ্যাট মডেল তৈরি করেন, কিন্তু একটি ছোট সর্বোচ্চ আউটপুট টোকেন নম্বর সহ, কারণ আপনি শুধুমাত্র একটি সংক্ষিপ্ত প্রতিক্রিয়া চান: পাঠ্যটি POSITIVE , NEGATIVE বা NEUTRAL

তারপর, আপনি ইনপুট এবং আউটপুটগুলির কয়েকটি উদাহরণ সম্পর্কে মডেলকে নির্দেশ দিয়ে কয়েক-শট প্রম্পটিং কৌশল সহ একটি পুনরায় ব্যবহারযোগ্য প্রম্পট টেমপ্লেট তৈরি করুন। এটি মডেলটিকে প্রকৃত আউটপুট অনুসরণ করতে সহায়তা করে। মিথুন একটি পূর্ণ প্রস্ফুটিত বাক্য দিয়ে উত্তর দেবে না, পরিবর্তে, শুধুমাত্র একটি শব্দ দিয়ে উত্তর দেওয়ার নির্দেশ দেওয়া হয়েছে।

আপনি apply() পদ্ধতিতে ভেরিয়েবল প্রয়োগ করুন, আসল প্যারামিটার দিয়ে প্লেসহোল্ডার প্রতিস্থাপন করুন ( "I love strawberries" ), এবং সেই টেমপ্লেটটিকে toUserMessage() দিয়ে একটি ব্যবহারকারীর বার্তায় পরিণত করুন।

নমুনা চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.TextClassification

আপনি একটি একক শব্দ দেখতে হবে:

POSITIVE

স্ট্রবেরি প্রেমের মত দেখাচ্ছে একটি ইতিবাচক অনুভূতি!

10. পুনরুদ্ধার অগমেন্টেড জেনারেশন

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

সেজন্য রিট্রিভাল অগমেন্টেড জেনারেশন (RAG) এর মত পন্থাগুলি অতিরিক্ত তথ্য প্রদান করতে সাহায্য করে যা একজন LLM এর ব্যবহারকারীদের অনুরোধ পূরণ করতে, আরও সাম্প্রতিক তথ্যের সাথে উত্তর দিতে বা প্রশিক্ষণের সময় অ্যাক্সেসযোগ্য নয় এমন ব্যক্তিগত তথ্যের সাথে উত্তর দিতে হতে পারে। .

কথোপকথনে ফিরে আসা যাক। এই সময়, আপনি আপনার নথি সম্পর্কে প্রশ্ন জিজ্ঞাসা করতে সক্ষম হবে. আপনি একটি চ্যাটবট তৈরি করবেন যা আপনার নথিগুলিকে ছোট ছোট টুকরো ("খণ্ড") ধারণ করে একটি ডাটাবেস থেকে প্রাসঙ্গিক তথ্য পুনরুদ্ধার করতে সক্ষম হবে এবং সেই তথ্যটি মডেল দ্বারা তার উত্তরগুলিকে ভিত্তি করার জন্য ব্যবহার করা হবে, শুধুমাত্র এতে থাকা জ্ঞানের উপর নির্ভর না করে এর প্রশিক্ষণ।

RAG-তে, দুটি পর্যায় রয়েছে:

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

cd07d33d20ffa1c8.png

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

a1d2e2deb83c6d27.png

আপনার নথি প্রস্তুত করুন

এই নতুন ডেমোর জন্য, আপনি "মনোযোগ আপনার প্রয়োজন" গবেষণাপত্র সম্পর্কে প্রশ্ন জিজ্ঞাসা করবেন। এটি ট্রান্সফরমার নিউরাল নেটওয়ার্ক আর্কিটেকচার বর্ণনা করে, যা Google দ্বারা অগ্রণী, যেভাবে আজকাল সমস্ত আধুনিক বৃহৎ ভাষার মডেল প্রয়োগ করা হয়।

কাগজটি ইতিমধ্যেই ভান্ডারে মনোযোগের জন্য ডাউনলোড করা হয়েছে।

চ্যাটবট বাস্তবায়ন করুন

আসুন 2-ফেজ পদ্ধতিটি কীভাবে তৈরি করা যায় তা অন্বেষণ করি: প্রথমে ডকুমেন্ট ইনজেশন সহ, এবং তারপর ক্যোয়ারী সময় যখন ব্যবহারকারীরা ডকুমেন্ট সম্পর্কে প্রশ্ন জিজ্ঞাসা করে।

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

এছাড়াও, এই উদাহরণে আমরা একটি ইন-মেমরি ভেক্টর ডাটাবেস ব্যবহার করব। একটি বাস্তব উত্পাদনের দৃশ্যে, ইনজেশন এবং অনুসন্ধানের পর্যায়গুলি দুটি স্বতন্ত্র অ্যাপ্লিকেশনে আলাদা করা হবে এবং ভেক্টরগুলি একটি স্বতন্ত্র ডাটাবেসে টিকে থাকে।

ডকুমেন্ট ইনজেশন

ডকুমেন্ট ইনজেশন পর্বের প্রথম ধাপ হল পিডিএফ ফাইলটি সনাক্ত করা যা আমরা ইতিমধ্যে ডাউনলোড করেছি এবং এটি পড়ার জন্য একটি PdfParser প্রস্তুত করুন:

URL url = new URI("https://github.com/glaforge/gemini-workshop-for-java-developers/raw/main/attention-is-all-you-need.pdf").toURL();
ApachePdfBoxDocumentParser pdfParser = new ApachePdfBoxDocumentParser();
Document document = pdfParser.parse(url.openStream());

সাধারণ চ্যাট ভাষার মডেল তৈরি করার পরিবর্তে, আপনি একটি এমবেডিং মডেলের একটি উদাহরণ তৈরি করেন। এটি একটি নির্দিষ্ট মডেল যার ভূমিকা টেক্সট টুকরা (শব্দ, বাক্য বা এমনকি অনুচ্ছেদ) এর ভেক্টর উপস্থাপনা তৈরি করা। এটি টেক্সট প্রতিক্রিয়া ফেরত দেওয়ার পরিবর্তে ফ্লোটিং পয়েন্ট সংখ্যার ভেক্টর প্রদান করে।

VertexAiEmbeddingModel embeddingModel = VertexAiEmbeddingModel.builder()
    .endpoint(System.getenv("LOCATION") + "-aiplatform.googleapis.com:443")
    .project(System.getenv("PROJECT_ID"))
    .location(System.getenv("LOCATION"))
    .publisher("google")
    .modelName("textembedding-gecko@003")
    .maxRetries(3)
    .build();

এরপরে, একসাথে কাজ করার জন্য আপনার কয়েকটি ক্লাসের প্রয়োজন হবে:

  • পিডিএফ ডকুমেন্টটি খণ্ডে লোড করুন এবং বিভক্ত করুন।
  • এই সমস্ত অংশগুলির জন্য ভেক্টর এম্বেডিং তৈরি করুন।
InMemoryEmbeddingStore<TextSegment> embeddingStore = 
    new InMemoryEmbeddingStore<>();

EmbeddingStoreIngestor storeIngestor = EmbeddingStoreIngestor.builder()
    .documentSplitter(DocumentSplitters.recursive(500, 100))
    .embeddingModel(embeddingModel)
    .embeddingStore(embeddingStore)
    .build();
storeIngestor.ingest(document);

InMemoryEmbeddingStore এর একটি উদাহরণ, একটি ইন-মেমরি ভেক্টর ডাটাবেস, ভেক্টর এম্বেডিংগুলি সংরক্ষণ করার জন্য তৈরি করা হয়েছে।

DocumentSplitters ক্লাসের জন্য নথিটি খণ্ডে বিভক্ত করা হয়েছে। এটি পিডিএফ ফাইলের পাঠ্যকে 500 অক্ষরের স্নিপেটে বিভক্ত করতে যাচ্ছে, 100 অক্ষরের ওভারল্যাপ সহ (নিম্নলিখিত অংশের সাথে, বিট এবং টুকরো করে শব্দ বা বাক্য কাটা এড়াতে)।

স্টোর ইনজেস্টার ডকুমেন্ট স্প্লিটার, ভেক্টর গণনা করার জন্য এমবেডিং মডেল এবং ইন-মেমরি ভেক্টর ডাটাবেসকে লিঙ্ক করে। তারপর, ingest() পদ্ধতিটি ইনজেশন করার যত্ন নেবে।

এখন, প্রথম পর্যায় শেষ হয়েছে, নথিটি তাদের যুক্ত ভেক্টর এম্বেডিংয়ের সাথে পাঠ্য খণ্ডে রূপান্তরিত হয়েছে এবং ভেক্টর ডাটাবেসে সংরক্ষিত হয়েছে।

প্রশ্ন করা

এটা প্রশ্ন জিজ্ঞাসা করার জন্য প্রস্তুত পেতে সময়! কথোপকথন শুরু করতে একটি চ্যাট মডেল তৈরি করুন:

ChatLanguageModel model = VertexAiGeminiChatModel.builder()
        .project(System.getenv("PROJECT_ID"))
        .location(System.getenv("LOCATION"))
        .modelName("gemini-1.5-flash-001")
        .maxOutputTokens(1000)
        .build();

এম্বেডিং মডেলের সাথে ভেক্টর ডাটাবেস ( embeddingStore ভেরিয়েবলে) লিঙ্ক করার জন্য আপনার একটি পুনরুদ্ধার শ্রেণীও প্রয়োজন। এর কাজ হল ব্যবহারকারীর প্রশ্নের জন্য একটি ভেক্টর এমবেডিং গণনা করে ভেক্টর ডাটাবেস অনুসন্ধান করা, ডাটাবেসে অনুরূপ ভেক্টর খুঁজে বের করা:

EmbeddingStoreContentRetriever retriever =
    new EmbeddingStoreContentRetriever(embeddingStore, embeddingModel);

মূল পদ্ধতির বাইরে, একটি ইন্টারফেস তৈরি করুন যা একজন LLM বিশেষজ্ঞ সহকারীকে উপস্থাপন করে, এটি এমন একটি ইন্টারফেস যা AiServices ক্লাস আপনার মডেলের সাথে ইন্টারঅ্যাক্ট করার জন্য প্রয়োগ করবে:

interface LlmExpert {
    String ask(String question);
}

এই মুহুর্তে, আপনি একটি নতুন AI পরিষেবা কনফিগার করতে পারেন:

LlmExpert expert = AiServices.builder(LlmExpert.class)
    .chatLanguageModel(model)
    .chatMemory(MessageWindowChatMemory.withMaxMessages(10))
    .contentRetriever(retriever)
    .build();

এই পরিষেবাটি একসাথে আবদ্ধ:

  • চ্যাট ভাষার মডেল যা আপনি আগে কনফিগার করেছেন।
  • কথোপকথনের ট্র্যাক রাখতে একটি চ্যাট মেমরি
  • পুনরুদ্ধারকারী একটি ভেক্টর এমবেডিং ক্যোয়ারীকে ডাটাবেসের ভেক্টরের সাথে তুলনা করে।
  • একটি প্রম্পট টেমপ্লেট স্পষ্টভাবে বলে যে চ্যাট মডেলের প্রদত্ত তথ্যের উপর ভিত্তি করে উত্তর দেওয়া উচিত (যেমন ডকুমেন্টেশনের প্রাসঙ্গিক অংশগুলি যার ভেক্টর এম্বেডিং ব্যবহারকারীর প্রশ্নের ভেক্টরের অনুরূপ)।
.retrievalAugmentor(DefaultRetrievalAugmentor.builder()
    .contentInjector(DefaultContentInjector.builder()
        .promptTemplate(PromptTemplate.from("""
            You are an expert in large language models,\s
            you excel at explaining simply and clearly questions about LLMs.

            Here is the question: {{userMessage}}

            Answer using the following information:
            {{contents}}
            """))
        .build())
    .contentRetriever(retriever)
    .build())

আপনি অবশেষে আপনার প্রশ্ন জিজ্ঞাসা করতে প্রস্তুত!

List.of(
    "What neural network architecture can be used for language models?",
    "What are the different components of a transformer neural network?",
    "What is attention in large language models?",
    "What is the name of the process that transforms text into vectors?"
).forEach(query ->
    System.out.printf("%n=== %s === %n%n %s %n%n", query, expert.ask(query)));
);

সম্পূর্ণ উত্স কোডটি app/src/main/java/gemini/workshop ডিরেক্টরিতে RAG.java রয়েছে:

নমুনা চালান:

./gradlew -q run -DjavaMainClass=gemini.workshop.RAG

আউটপুটে, আপনার আপনার প্রশ্নের উত্তর দেখতে হবে:

=== What neural network architecture can be used for language models? === 

 Transformer architecture 


=== What are the different components of a transformer neural network? === 

 The different components of a transformer neural network are:

1. Encoder: The encoder takes the input sequence and converts it into a 
sequence of hidden states. Each hidden state represents the context of 
the corresponding input token.
2. Decoder: The decoder takes the hidden states from the encoder and 
uses them to generate the output sequence. Each output token is 
generated by attending to the hidden states and then using a 
feed-forward network to predict the token's probability distribution.
3. Attention mechanism: The attention mechanism allows the decoder to 
attend to the hidden states from the encoder when generating each output 
token. This allows the decoder to take into account the context of the 
input sequence when generating the output sequence.
4. Positional encoding: Positional encoding is a technique used to 
inject positional information into the input sequence. This is important 
because the transformer neural network does not have any inherent sense 
of the order of the tokens in the input sequence.
5. Feed-forward network: The feed-forward network is a type of neural 
network that is used to predict the probability distribution of each 
output token. The feed-forward network takes the hidden state from the 
decoder as input and outputs a vector of probabilities. 


=== What is attention in large language models? === 

Attention in large language models is a mechanism that allows the model 
to focus on specific parts of the input sequence when generating the 
output sequence. This is important because it allows the model to take 
into account the context of the input sequence when generating each output token.

Attention is implemented using a function that takes two sequences as 
input: a query sequence and a key-value sequence. The query sequence is 
typically the hidden state from the previous decoder layer, and the 
key-value sequence is typically the sequence of hidden states from the 
encoder. The attention function computes a weighted sum of the values in 
the key-value sequence, where the weights are determined by the 
similarity between the query and the keys.

The output of the attention function is a vector of context vectors, 
which are then used as input to the feed-forward network in the decoder. 
The feed-forward network then predicts the probability distribution of 
the next output token.

Attention is a powerful mechanism that allows large language models to 
generate text that is both coherent and informative. It is one of the 
key factors that has contributed to the recent success of large language 
models in a wide range of natural language processing tasks. 


=== What is the name of the process that transforms text into vectors? === 

The process of transforming text into vectors is called **word embedding**.

Word embedding is a technique used in natural language processing (NLP) 
to represent words as vectors of real numbers. Each word is assigned a 
unique vector, which captures its meaning and semantic relationships 
with other words. Word embeddings are used in a variety of NLP tasks, 
such as machine translation, text classification, and question 
answering.

There are a number of different word embedding techniques, but one of 
the most common is the **skip-gram** model. The skip-gram model is a 
neural network that is trained to predict the surrounding words of a 
given word. By learning to predict the surrounding words, the skip-gram 
model learns to capture the meaning and semantic relationships of words.

Once a word embedding model has been trained, it can be used to 
transform text into vectors. To do this, each word in the text is 
converted to its corresponding vector. The vectors for all of the words 
in the text are then concatenated to form a single vector, which 
represents the entire text.

Text vectors can be used in a variety of NLP tasks. For example, text 
vectors can be used to train machine translation models, text 
classification models, and question answering models. Text vectors can 
also be used to perform tasks such as text summarization and text 
clustering. 

11. ফাংশন কলিং

এমন কিছু পরিস্থিতিও রয়েছে যেখানে আপনি একটি এলএলএমকে বাহ্যিক সিস্টেমে অ্যাক্সেস পেতে চান, যেমন একটি দূরবর্তী ওয়েব এপিআই যা তথ্য পুনরুদ্ধার করে বা কোনও ক্রিয়া রয়েছে, বা কোনও ধরণের গণনা সম্পাদন করে এমন পরিষেবাগুলি। যেমন:

দূরবর্তী ওয়েব এপিআই:

  • গ্রাহক আদেশ ট্র্যাক এবং আপডেট করুন।
  • কোনও ইস্যু ট্র্যাকারে টিকিট সন্ধান করুন বা তৈরি করুন।
  • স্টক কোটস বা আইওটি সেন্সর পরিমাপের মতো রিয়েল টাইম ডেটা আনুন।
  • একটি ইমেইল পাঠান.

গণনা সরঞ্জাম:

  • আরও উন্নত গণিত সমস্যার জন্য একটি ক্যালকুলেটর।
  • চলমান কোডের জন্য কোড ব্যাখ্যা যখন এলএলএমএস যুক্তিযুক্ত যুক্তি প্রয়োজন।
  • প্রাকৃতিক ভাষার অনুরোধগুলিকে এসকিউএল কোয়েরিতে রূপান্তর করুন যাতে কোনও এলএলএম কোনও ডাটাবেস জিজ্ঞাসা করতে পারে।

ফাংশন কলিং হ'ল মডেলটির পক্ষে তার পক্ষে এক বা একাধিক ফাংশন কল করার জন্য অনুরোধ করার ক্ষমতা, সুতরাং এটি আরও তাজা ডেটা সহ কোনও ব্যবহারকারীর প্রম্পটকে যথাযথভাবে উত্তর দিতে পারে।

কোনও ব্যবহারকারীর কাছ থেকে একটি নির্দিষ্ট প্রম্পট দেওয়া এবং বিদ্যমান ফাংশনগুলির জ্ঞান যা সেই প্রসঙ্গে প্রাসঙ্গিক হতে পারে, একটি এলএলএম একটি ফাংশন কল অনুরোধের সাথে উত্তর দিতে পারে। এলএলএমকে সংহত করার অ্যাপ্লিকেশনটি তারপরে ফাংশনটি কল করতে পারে এবং তারপরে একটি প্রতিক্রিয়া সহ এলএলএম -তে জবাব দেয় এবং এলএলএম তারপরে একটি পাঠ্য উত্তর দিয়ে জবাব দিয়ে ফিরে ব্যাখ্যা করে।

ফাংশন কলিংয়ের চারটি পদক্ষেপ

আসুন ফাংশন কলিংয়ের একটি উদাহরণ দেখুন: আবহাওয়ার পূর্বাভাস সম্পর্কে তথ্য পাওয়া।

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

নিচের চিত্রটি দেখুন:

31e0c2aba5e6f21c.png

1⃣ প্রথম, একজন ব্যবহারকারী প্যারিসের আবহাওয়া সম্পর্কে জিজ্ঞাসা করেন। চ্যাটবট অ্যাপটি জানে যে এলএলএমকে জিজ্ঞাসাটি পূরণ করতে সহায়তা করার জন্য এমন এক বা একাধিক ফাংশন রয়েছে যা এর নিষ্পত্তি রয়েছে। চ্যাটবট উভয়ই প্রাথমিক প্রম্পট পাঠায়, পাশাপাশি কল করা যেতে পারে এমন ফাংশনগুলির তালিকাও প্রেরণ করে। এখানে, getWeather() নামে একটি ফাংশন যা অবস্থানের জন্য একটি স্ট্রিং প্যারামিটার নেয়।

8863be53a73c4a70.png

যেহেতু এলএলএম আবহাওয়ার পূর্বাভাস সম্পর্কে জানে না, পাঠ্যের মাধ্যমে জবাব দেওয়ার পরিবর্তে এটি একটি ফাংশন এক্সিকিউশন অনুরোধটি ফেরত পাঠায়। চ্যাটবটকে অবশ্যই "Paris" দিয়ে অবস্থান প্যারামিটার হিসাবে getWeather() ফাংশনটিতে কল করতে হবে।

D1367CC69C07B14D.PNG

2⃣ চ্যাটবটটি এলএলএমের পক্ষে এই কাজ করে, ফাংশন প্রতিক্রিয়াটি পুনরুদ্ধার করে। এখানে, আমরা কল্পনা করি যে প্রতিক্রিয়াটি {"forecast": "sunny"}

73A5F2ED19F47D8.PNG

3⃣ চ্যাটবট অ্যাপ্লিকেশনটি JSON প্রতিক্রিয়াটিকে এলএলএম -তে ফেরত পাঠায়।

20832CB1EE6FBFEB.PNG

4⃣ এলএলএম জেএসওএন এর প্রতিক্রিয়াটি দেখে, সেই তথ্যের ব্যাখ্যা করে এবং শেষ পর্যন্ত প্যারিসে আবহাওয়া রৌদ্রোজ্জ্বল পাঠ্যটি দিয়ে জবাব দেয়।

কোড হিসাবে প্রতিটি পদক্ষেপ

প্রথমত, আপনি যথারীতি মিথুন মডেলটি কনফিগার করবেন:

ChatLanguageModel model = VertexAiGeminiChatModel.builder()
    .project(System.getenv("PROJECT_ID"))
    .location(System.getenv("LOCATION"))
    .modelName("gemini-1.5-flash-001")
    .maxOutputTokens(100)
    .build();

আপনি একটি সরঞ্জাম স্পেসিফিকেশন নির্দিষ্ট করুন যা ফাংশনটি বর্ণনা করে যা বলা যেতে পারে:

ToolSpecification weatherToolSpec = ToolSpecification.builder()
    .name("getWeatherForecast")
    .description("Get the weather forecast for a location")
    .addParameter("location", JsonSchemaProperty.STRING,
        JsonSchemaProperty.description("the location to get the weather forecast for"))
    .build();

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

আসুন প্যারিসের আবহাওয়া সম্পর্কে প্রাথমিক প্রশ্নটি প্রেরণ করে পদক্ষেপ #1 শুরু করুন:

List<ChatMessage> allMessages = new ArrayList<>();

// 1) Ask the question about the weather
UserMessage weatherQuestion = UserMessage.from("What is the weather in Paris?");
allMessages.add(weatherQuestion);

পদক্ষেপ #2 এ, আমরা মডেলটি ব্যবহার করতে চাই সেই সরঞ্জামটি পাস করি এবং মডেলটি খুব কার্যকর করার অনুরোধের সাথে জবাব দেয়:

// 2) The model replies with a function call request
Response<AiMessage> messageResponse = model.generate(allMessages, weatherToolSpec);
ToolExecutionRequest toolExecutionRequest = messageResponse.content().toolExecutionRequests().getFirst();
System.out.println("Tool execution request: " + toolExecutionRequest);
allMessages.add(messageResponse.content());

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

// 3) We send back the result of the function call
ToolExecutionResultMessage toolExecResMsg = ToolExecutionResultMessage.from(toolExecutionRequest,
    "{\"location\":\"Paris\",\"forecast\":\"sunny\", \"temperature\": 20}");
allMessages.add(toolExecResMsg);

এবং পদক্ষেপ #4 এ, এলএলএম ফাংশন এক্সিকিউশন ফলাফল সম্পর্কে শিখেছে এবং তারপরে একটি পাঠ্য প্রতিক্রিয়া সংশ্লেষ করতে পারে:

// 4) The model answers with a sentence describing the weather
Response<AiMessage> weatherResponse = model.generate(allMessages);
System.out.println("Answer: " + weatherResponse.content().text());

আউটপুট হল:

Tool execution request: ToolExecutionRequest { id = null, name = "getWeatherForecast", arguments = "{"location":"Paris"}" }
Answer:  The weather in Paris is sunny with a temperature of 20 degrees Celsius.

আপনি সরঞ্জাম এক্সিকিউশন অনুরোধের উপরের আউটপুট, পাশাপাশি উত্তর দেখতে পারেন।

সম্পূর্ণ উত্স কোডটি app/src/main/java/gemini/workshop ডিরেক্টরিতে FunctionCalling.java রয়েছে:

নমুনা চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.FunctionCalling

আপনি নিম্নলিখিত অনুরূপ একটি আউটপুট দেখতে হবে:

Tool execution request: ToolExecutionRequest { id = null, name = "getWeatherForecast", arguments = "{"location":"Paris"}" }
Answer:  The weather in Paris is sunny with a temperature of 20 degrees Celsius.

12. ল্যাংচেইন 4 জে ফাংশন কলিং পরিচালনা করে

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

যাইহোক, ল্যাংচেইন 4 জে একটি উচ্চ-স্তরের বিমূর্ততাও সরবরাহ করে যা ফাংশন কলগুলি আপনার জন্য স্বচ্ছভাবে পরিচালনা করতে পারে, যখন কথোপকথনটি যথারীতি পরিচালনা করে।

একক ফাংশন কল

আসুন FunctionCallingAssistant.java , টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো

প্রথমত, আপনি এমন একটি রেকর্ড তৈরি করেছেন যা ফাংশনের প্রতিক্রিয়া ডেটা কাঠামোর প্রতিনিধিত্ব করবে:

record WeatherForecast(String location, String forecast, int temperature) {}

প্রতিক্রিয়াটিতে অবস্থান, পূর্বাভাস এবং তাপমাত্রা সম্পর্কে তথ্য রয়েছে।

তারপরে আপনি এমন একটি ক্লাস তৈরি করেন যা আপনি মডেলটিতে উপলব্ধ করতে চান এমন প্রকৃত ফাংশন রয়েছে:

static class WeatherForecastService {
    @Tool("Get the weather forecast for a location")
    WeatherForecast getForecast(@P("Location to get the forecast for") String location) {
        if (location.equals("Paris")) {
            return new WeatherForecast("Paris", "Sunny", 20);
        } else if (location.equals("London")) {
            return new WeatherForecast("London", "Rainy", 15);
        } else {
            return new WeatherForecast("Unknown", "Unknown", 0);
        }
    }
}

নোট করুন যে এই শ্রেণিতে একটি একক ফাংশন রয়েছে, তবে এটি @Tool টীকা দিয়ে টীকাযুক্ত যা মডেল কল করার জন্য অনুরোধ করতে পারে তার ফাংশনের বর্ণনার সাথে মিলে যায়।

ফাংশনের পরামিতিগুলি (এখানে একটি একক) এছাড়াও টিকা দেওয়া হয়, তবে এই সংক্ষিপ্ত @P টীকা দিয়ে, যা প্যারামিটারের বিবরণও দেয়। আপনি যতটা ফাংশন চান ততগুলি যুক্ত করতে পারেন, আরও জটিল পরিস্থিতিতে তাদের মডেলটিতে উপলব্ধ করতে।

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

যেমনটি আমরা দেখেছি যখন আপনি পূর্ববর্তী পদ্ধতির মধ্যে কোনও ToolSpecification তৈরি করেছেন, কোনও ফাংশন কী করে তা নথিভুক্ত করা গুরুত্বপূর্ণ এবং পরামিতিগুলি কী সম্পর্কিত তা বর্ণনা করে। এটি মডেলটিকে কীভাবে এবং কখন এই ফাংশনটি ব্যবহার করা যেতে পারে তা বুঝতে সহায়তা করে।

এরপরে, ল্যাংচেইন 4 জে আপনাকে এমন একটি ইন্টারফেস সরবরাহ করতে দেয় যা আপনি চুক্তির সাথে সম্পর্কিত যে আপনি মডেলের সাথে ইন্টারঅ্যাক্ট করতে ব্যবহার করতে চান তার সাথে সম্পর্কিত। এখানে, এটি একটি সাধারণ ইন্টারফেস যা ব্যবহারকারী বার্তার প্রতিনিধিত্ব করে এমন একটি স্ট্রিং নেয় এবং মডেলের প্রতিক্রিয়ার সাথে সম্পর্কিত একটি স্ট্রিং দেয়:

interface WeatherAssistant {
    String chat(String userMessage);
}

ল্যাংচেইন 4 জে এর UserMessage (ব্যবহারকারী বার্তার জন্য) বা AiMessage (একটি মডেলের প্রতিক্রিয়ার জন্য), বা এমনকি একটি TokenStream জড়িত আরও জটিল স্বাক্ষরগুলি ব্যবহার করাও সম্ভব, যদি আপনি আরও উন্নত পরিস্থিতিগুলি পরিচালনা করতে চান, কারণ এই আরও জটিল অবজেক্টগুলিতে অতিরিক্ত অতিরিক্ত রয়েছে টোকেনের সংখ্যা ইত্যাদির মতো তথ্য ইত্যাদি। তবে সরলতার জন্য, আমরা কেবল ইনপুটটিতে স্ট্রিং এবং আউটপুটে স্ট্রিং নেব।

আসুন main() পদ্ধতিটি শেষ করি যা সমস্ত টুকরো একসাথে আবদ্ধ করে:

public static void main(String[] args) {
    ChatLanguageModel model = VertexAiGeminiChatModel.builder()
        .project(System.getenv("PROJECT_ID"))
        .location(System.getenv("LOCATION"))
        .modelName("gemini-1.5-flash-001")
        .maxOutputTokens(100)
        .build();

    WeatherForecastService weatherForecastService = new WeatherForecastService();

    WeatherAssistant assistant = AiServices.builder(WeatherAssistant.class)
        .chatLanguageModel(model)
        .chatMemory(MessageWindowChatMemory.withMaxMessages(10))
        .tools(weatherForecastService)
        .build();

    System.out.println(assistant.chat("What is the weather in Paris?"));
}

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

এখন, আপনি চ্যাট মডেল, চ্যাট মেমরি এবং সরঞ্জাম (যেমন। এর ফাংশন সহ আবহাওয়ার পূর্বাভাস পরিষেবা) বাঁধতে আবার AiServices ক্লাসটি ব্যবহার করেন। AiServices এমন একটি বস্তু ফেরত দেয় যা আপনার সংজ্ঞায়িত আপনার WeatherAssistant ইন্টারফেসকে প্রয়োগ করে। একমাত্র জিনিসটি হ'ল সেই সহকারীটির chat() পদ্ধতি কল করা। এটি অনুরোধ করার সময়, আপনি কেবল পাঠ্য প্রতিক্রিয়াগুলি দেখতে পাবেন, তবে ফাংশন কল অনুরোধগুলি এবং ফাংশন কল প্রতিক্রিয়াগুলি বিকাশকারীদের কাছ থেকে দৃশ্যমান হবে না এবং সেই অনুরোধগুলি স্বয়ংক্রিয়ভাবে এবং স্বচ্ছভাবে পরিচালনা করা হবে। যদি জেমিনি মনে করেন যে কোনও ফাংশন কল করা উচিত, তবে এটি ফাংশন কল অনুরোধের সাথে জবাব দেবে এবং ল্যাংচেইন 4 জে আপনার পক্ষে স্থানীয় ফাংশনটিকে কল করার যত্ন নেবে।

নমুনা চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.FunctionCallingAssistant

আপনি নিম্নলিখিত অনুরূপ একটি আউটপুট দেখতে হবে:

OK. The weather in Paris is sunny with a temperature of 20 degrees.

এটি একটি একক ফাংশনের উদাহরণ ছিল।

একাধিক ফাংশন কল

আপনার একাধিক ফাংশনও থাকতে পারে এবং ল্যাংচেইন 4 জে আপনার পক্ষে একাধিক ফাংশন কলগুলি পরিচালনা করতে দিন। একাধিক ফাংশন উদাহরণের জন্য MultiFunctionCallingAssistant.java একবার দেখুন।

মুদ্রা রূপান্তর করার জন্য এটির একটি ফাংশন রয়েছে:

@Tool("Convert amounts between two currencies")
double convertCurrency(
    @P("Currency to convert from") String fromCurrency,
    @P("Currency to convert to") String toCurrency,
    @P("Amount to convert") double amount) {

    double result = amount;

    if (fromCurrency.equals("USD") && toCurrency.equals("EUR")) {
        result = amount * 0.93;
    } else if (fromCurrency.equals("USD") && toCurrency.equals("GBP")) {
        result = amount * 0.79;
    }

    System.out.println(
        "convertCurrency(fromCurrency = " + fromCurrency +
            ", toCurrency = " + toCurrency +
            ", amount = " + amount + ") == " + result);

    return result;
}

স্টকের মান পেতে অন্য একটি ফাংশন:

@Tool("Get the current value of a stock in US dollars")
double getStockPrice(@P("Stock symbol") String symbol) {
    double result = 170.0 + 10 * new Random().nextDouble();

    System.out.println("getStockPrice(symbol = " + symbol + ") == " + result);

    return result;
}

প্রদত্ত পরিমাণে শতাংশ প্রয়োগ করতে অন্য একটি ফাংশন:

@Tool("Apply a percentage to a given amount")
double applyPercentage(@P("Initial amount") double amount, @P("Percentage between 0-100 to apply") double percentage) {
    double result = amount * (percentage / 100);

    System.out.println("applyPercentage(amount = " + amount + ", percentage = " + percentage + ") == " + result);

    return result;
}

তারপরে আপনি এই সমস্ত ফাংশন এবং একটি মাল্টিটুলস ক্লাস একত্রিত করতে পারেন এবং "এএপিএল স্টক মূল্যের 10% কী মার্কিন ডলারে থেকে ইউরোতে রূপান্তরিত?" এর মতো প্রশ্ন জিজ্ঞাসা করতে পারেন? "

public static void main(String[] args) {
    ChatLanguageModel model = VertexAiGeminiChatModel.builder()
        .project(System.getenv("PROJECT_ID"))
        .location(System.getenv("LOCATION"))
        .modelName("gemini-1.5-flash-001")
        .maxOutputTokens(100)
        .build();

    MultiTools multiTools = new MultiTools();

    MultiToolsAssistant assistant = AiServices.builder(MultiToolsAssistant.class)
        .chatLanguageModel(model)
        .chatMemory(withMaxMessages(10))
        .tools(multiTools)
        .build();

    System.out.println(assistant.chat(
        "What is 10% of the AAPL stock price converted from USD to EUR?"));
}

এটি নিম্নরূপ চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.MultiFunctionCallingAssistant

এবং আপনার একাধিক ফাংশন বলা উচিত:

getStockPrice(symbol = AAPL) == 172.8022224055534
convertCurrency(fromCurrency = USD, toCurrency = EUR, amount = 172.8022224055534) == 160.70606683716468
applyPercentage(amount = 160.70606683716468, percentage = 10.0) == 16.07060668371647
10% of the AAPL stock price converted from USD to EUR is 16.07060668371647 EUR.

এজেন্টদের দিকে

জেমিনির মতো বৃহত ভাষার মডেলগুলির জন্য ফাংশন কলিং একটি দুর্দান্ত এক্সটেনশন প্রক্রিয়া। এটি আমাদের প্রায়শই "এজেন্ট" বা "এআই সহায়ক" নামে পরিচিত আরও জটিল সিস্টেমগুলি তৈরি করতে সক্ষম করে। এই এজেন্টগুলি বাহ্যিক এপিআইগুলির মাধ্যমে এবং বাহ্যিক পরিবেশের পার্শ্ব প্রতিক্রিয়া হতে পারে এমন পরিষেবাগুলির সাথে বাহ্যিক বিশ্বের সাথে যোগাযোগ করতে পারে (যেমন ইমেল প্রেরণ, টিকিট তৈরি করা ইত্যাদি)

এই জাতীয় শক্তিশালী এজেন্ট তৈরি করার সময়, আপনার দায়িত্বের সাথে এটি করা উচিত। স্বয়ংক্রিয় ক্রিয়া করার আগে আপনার একটি মানব-ইন-লুপ বিবেচনা করা উচিত। বাহ্যিক বিশ্বের সাথে যোগাযোগ করে এমন এলএলএম-চালিত এজেন্টদের ডিজাইন করার সময় সুরক্ষাটি মনে রাখা গুরুত্বপূর্ণ।

13. ওলামা এবং টেস্টকন্টাইনারদের সাথে জেমমা চালানো

এখনও অবধি, আমরা জেমিনি ব্যবহার করছি তবে এর ছোট্ট বোনের মডেল জেমমাও রয়েছে।

জেমমা হ'ল লাইটওয়েটের একটি পরিবার, জেমিনি মডেলগুলি তৈরি করতে ব্যবহৃত একই গবেষণা এবং প্রযুক্তি থেকে নির্মিত অত্যাধুনিক ওপেন মডেলগুলির একটি পরিবার। জেমমা বিভিন্ন আকারের সাথে দুটি বৈচিত্র্য জেমমা 1 এবং জেমমা 2 এ উপলব্ধ। জেমমা 1 দুটি আকারে উপলব্ধ: 2 বি এবং 7 বি। জেমমা 2 দুটি আকারে উপলব্ধ: 9 বি এবং 27 বি। তাদের ওজন অবাধে উপলভ্য এবং তাদের ছোট আকারের অর্থ আপনি এটি নিজের থেকে চালাতে পারেন এমনকি এমনকি আপনার ল্যাপটপেও বা ক্লাউড শেলেও।

আপনি কিভাবে জেমমা চালাবেন?

জেমমা চালানোর অনেকগুলি উপায় রয়েছে: মেঘে, একটি বোতামের ক্লিকের সাথে ভার্টেক্স এআইয়ের মাধ্যমে বা কিছু জিপিইউ সহ GKE, তবে আপনি স্থানীয়ভাবে এটি চালাতে পারেন।

স্থানীয়ভাবে জেমমা চালানোর জন্য একটি ভাল বিকল্প হ'ল ওলামার সাথে, এমন একটি সরঞ্জাম যা আপনাকে লামা 2, মিস্ট্রাল এবং আপনার স্থানীয় মেশিনে আরও অনেকের মতো ছোট মডেল চালাতে দেয়। এটি ডকারের মতো তবে এলএলএমগুলির জন্য।

আপনার অপারেটিং সিস্টেমের জন্য নির্দেশ অনুসরণ করে ওলামা ইনস্টল করুন।

আপনি যদি লিনাক্স পরিবেশ ব্যবহার করছেন তবে আপনাকে এটি ইনস্টল করার পরে প্রথমে ওলামাকে সক্ষম করতে হবে।

ollama serve > /dev/null 2>&1 & 

স্থানীয়ভাবে ইনস্টল হয়ে গেলে, আপনি একটি মডেল টানতে কমান্ডগুলি চালাতে পারেন:

ollama pull gemma:2b

মডেলটি টানার জন্য অপেক্ষা করুন। এতে কিছু সময় লাগতে পারে।

মডেল চালান:

ollama run gemma:2b

এখন, আপনি মডেলের সাথে ইন্টারঅ্যাক্ট করতে পারেন:

>>> Hello!
Hello! It's nice to hear from you. What can I do for you today?

প্রম্পট থেকে প্রস্থান করতে Ctrl+d টিপুন

টেস্টকন্টেনারগুলিতে ওল্লায় জেমমা চালাচ্ছেন

স্থানীয়ভাবে ওল্লামা ইনস্টল ও চালানোর পরিবর্তে, আপনি টেস্টকন্টেনারদের দ্বারা পরিচালিত একটি ধারক মধ্যে ওলামা ব্যবহার করতে পারেন।

টেস্টকন্টাইনাররা কেবল পরীক্ষার জন্যই কার্যকর নয়, তবে আপনি এটি পাত্রে কার্যকর করার জন্যও ব্যবহার করতে পারেন। এমনকি একটি নির্দিষ্ট OllamaContainer রয়েছে যা আপনি সুবিধা নিতে পারেন!

এখানে পুরো ছবি:

2382c05a48708dfd.png

বাস্তবায়ন

আসুন GemmaWithOllamaContainer.java , টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো

প্রথমত, আপনাকে জেমমা মডেলটিতে টানতে একটি উত্পন্ন ওলামা ধারক তৈরি করতে হবে। এই চিত্রটি ইতিমধ্যে আগের রান থেকে বিদ্যমান বা এটি তৈরি করা হবে। যদি চিত্রটি ইতিমধ্যে বিদ্যমান থাকে তবে আপনি কেবল টেস্টকন্টাইনারদের বলতে যাচ্ছেন যে আপনি আপনার রত্ন-চালিত বৈকল্পিকের সাথে ডিফল্ট ওলামা চিত্রটির বিকল্প করতে চান:

private static final String TC_OLLAMA_GEMMA_2_B = "tc-ollama-gemma-2b";

// Creating an Ollama container with Gemma 2B if it doesn't exist.
private static OllamaContainer createGemmaOllamaContainer() throws IOException, InterruptedException {

    // Check if the custom Gemma Ollama image exists already
    List<Image> listImagesCmd = DockerClientFactory.lazyClient()
        .listImagesCmd()
        .withImageNameFilter(TC_OLLAMA_GEMMA_2_B)
        .exec();

    if (listImagesCmd.isEmpty()) {
        System.out.println("Creating a new Ollama container with Gemma 2B image...");
        OllamaContainer ollama = new OllamaContainer("ollama/ollama:0.1.26");
        ollama.start();
        ollama.execInContainer("ollama", "pull", "gemma:2b");
        ollama.commitToImage(TC_OLLAMA_GEMMA_2_B);
        return ollama;
    } else {
        System.out.println("Using existing Ollama container with Gemma 2B image...");
        // Substitute the default Ollama image with our Gemma variant
        return new OllamaContainer(
            DockerImageName.parse(TC_OLLAMA_GEMMA_2_B)
                .asCompatibleSubstituteFor("ollama/ollama"));
    }
}

এরপরে, আপনি একটি ওলামা পরীক্ষার ধারক তৈরি এবং শুরু করুন এবং তারপরে আপনি যে মডেলটি ব্যবহার করতে চান তার সাথে ধারকটির ঠিকানা এবং পোর্টের দিকে নির্দেশ করে একটি ওলামা চ্যাট মডেল তৈরি করুন। শেষ অবধি, আপনি কেবল model.generate(yourPrompt) :

public static void main(String[] args) throws IOException, InterruptedException {
    OllamaContainer ollama = createGemmaOllamaContainer();
    ollama.start();

    ChatLanguageModel model = OllamaChatModel.builder()
        .baseUrl(String.format("http://%s:%d", ollama.getHost(), ollama.getFirstMappedPort()))
        .modelName("gemma:2b")
        .build();

    String response = model.generate("Why is the sky blue?");

    System.out.println(response);
}

এটি নিম্নরূপ চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.GemmaWithOllamaContainer

প্রথম রানটি ধারকটি তৈরি করতে এবং চালাতে কিছুটা সময় নেবে তবে একবার হয়ে গেলে আপনার জেমমা প্রতিক্রিয়া দেখা উচিত:

INFO: Container ollama/ollama:0.1.26 started in PT2.827064047S
The sky appears blue due to Rayleigh scattering. Rayleigh scattering is a phenomenon that occurs when sunlight interacts with molecules in the Earth's atmosphere.

* **Scattering particles:** The main scattering particles in the atmosphere are molecules of nitrogen (N2) and oxygen (O2).
* **Wavelength of light:** Blue light has a shorter wavelength than other colors of light, such as red and yellow.
* **Scattering process:** When blue light interacts with these molecules, it is scattered in all directions.
* **Human eyes:** Our eyes are more sensitive to blue light than other colors, so we perceive the sky as blue.

This scattering process results in a blue appearance for the sky, even though the sun is actually emitting light of all colors.

In addition to Rayleigh scattering, other atmospheric factors can also influence the color of the sky, such as dust particles, aerosols, and clouds.

আপনার মেঘের শেলটিতে জেমমা চলছে!

14. অভিনন্দন

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

এরপর কি?

শক্তিশালী এলএলএম ইন্টিগ্রেশন সহ আপনার অ্যাপ্লিকেশনগুলিকে বাড়ানোর আপনার পালা!

আরও পড়া

রেফারেন্স ডক্স