paint-brush
ওয়ার্ড এমবেডিংস: আরও ভালো উত্তরের জন্য আপনার চ্যাটবট প্রসঙ্গ দেওয়ার গোপন সসদ্বারা@tomfernblog
2,991 পড়া
2,991 পড়া

ওয়ার্ড এমবেডিংস: আরও ভালো উত্তরের জন্য আপনার চ্যাটবট প্রসঙ্গ দেওয়ার গোপন সস

দ্বারা Tomas Fernandez18m2023/07/26
Read on Terminal Reader
Read this story w/o Javascript

অতিদীর্ঘ; পড়তে

শব্দ এম্বেডিং এবং ChatGPT ব্যবহার করে কীভাবে একটি বিশেষজ্ঞ বট তৈরি করবেন তা শিখুন। আপনার চ্যাটবটের প্রতিক্রিয়া উন্নত করতে শব্দ ভেক্টরের শক্তি ব্যবহার করুন।
featured image - ওয়ার্ড এমবেডিংস: আরও ভালো উত্তরের জন্য আপনার চ্যাটবট প্রসঙ্গ দেওয়ার গোপন সস
Tomas Fernandez HackerNoon profile picture
0-item
1-item

এতে কোন সন্দেহ নেই যে OpenAI এর ChatGPT ব্যতিক্রমী বুদ্ধিমান — এটি আইনজীবীর বার পরীক্ষায় উত্তীর্ণ হয়েছে, এটি একজন ডাক্তারের মতো জ্ঞানের অধিকারী, এবং কিছু পরীক্ষায় এর আইকিউ 155 হয়েছে । যাইহোক, এটি অজ্ঞতা স্বীকার করার পরিবর্তে তথ্য জাল করার প্রবণতা রাখে। এই প্রবণতা, 2021 সালে এর জ্ঞান বন্ধ হওয়ার সাথে সাথে, GPT API ব্যবহার করে বিশেষ পণ্য তৈরিতে চ্যালেঞ্জ তৈরি করে।


কিভাবে আমরা এই বাধা অতিক্রম করতে পারি? কিভাবে আমরা GPT-3 এর মত মডেলে নতুন জ্ঞান দিতে পারি? আমার লক্ষ্য হল পাইথন, ওপেনএআই এপিআই এবং ওয়ার্ড এম্বেডিং নিযুক্ত করে একটি প্রশ্ন-উত্তরকারী বট তৈরি করে এই প্রশ্নগুলির সমাধান করা।

আমি কি বিল্ডিং হবে

আমি এমন একটি বট তৈরি করতে চাই যা একটি প্রম্পট থেকে ক্রমাগত ইন্টিগ্রেশন পাইপলাইন তৈরি করে, যা আপনি জানেন যে, সেমাফোর সিআই/সিডিতে YAML দিয়ে তৈরি করা হয়েছে


এখানে কর্মরত বটটির একটি উদাহরণ রয়েছে:

চলমান প্রোগ্রামের স্ক্রিনশট। স্ক্রিনে, কমান্ডটি কার্যকর করা হয়: python query.py "একটি সিআই পাইপলাইন তৈরি করুন যা ডকার হাবে একটি ডকার ইমেজ তৈরি করে এবং আপলোড করে", এবং প্রোগ্রামটি একটি সিআই পাইপলাইনের সাথে সম্পর্কিত YAML প্রিন্ট করে যা অনুরোধ করা ক্রিয়া সম্পাদন করে। চলমান প্রোগ্রামের স্ক্রিনশট। স্ক্রিনে, python query.py "Create a CI pipeline that builds and uploads a Docker image to Docker Hub" কার্যকর করা হয় এবং প্রোগ্রামটি একটি CI পাইপলাইনের সাথে সম্পর্কিত YAML প্রিন্ট করে যা অনুরোধ করা ক্রিয়া সম্পাদন করে।


DocsGPT , My AskAI , এবং Libraria- এর মতো প্রকল্পের স্পিরিট অনুযায়ী আমি GPT-3 মডেলটিকে Semaphore এবং কীভাবে পাইপলাইন কনফিগারেশন ফাইল তৈরি করতে হয় সে সম্পর্কে "শিক্ষা" দেওয়ার পরিকল্পনা করছি। আমি বিদ্যমান ডকুমেন্টেশন ব্যবহার করে এটি অর্জন করব।


আমি বট বিল্ডিংয়ের পূর্বে জ্ঞান গ্রহণ করব না এবং পরিষ্কার কোড বজায় রাখব যাতে আপনি এটিকে আপনার প্রয়োজনীয়তার সাথে মানিয়ে নিতে পারেন।

পূর্বশর্ত

এই টিউটোরিয়ালটি অনুসরণ করার জন্য আপনার বট কোডিং করার অভিজ্ঞতা বা নিউরাল নেটওয়ার্কের জ্ঞানের প্রয়োজন নেই। যাইহোক, আপনার প্রয়োজন হবে:


কিন্তু ChatGPT শিখতে পারে না, এটা কি?

ChatGPT, বা আরও সঠিকভাবে, GPT-3 এবং GPT-4, বৃহৎ ভাষা মডেলগুলি (LLM) তাদের শক্তি প্রদান করে, সেপ্টেম্বর 2021 এর কাছাকাছি কাটঅফ তারিখ সহ একটি বিশাল ডেটাসেটে প্রশিক্ষণ দেওয়া হয়েছে।


মোটকথা, GPT-3 সেই তারিখের পরের ঘটনা সম্পর্কে খুব কমই জানে। আমরা একটি সহজ প্রম্পট দিয়ে এটি যাচাই করতে পারি:

ChatGPT এর স্ক্রিনশট 2022 সালের বিশ্বকাপ কে জিতেছে তা ChatGPT জানে না।


যদিও কিছু ওপেনএআই মডেল ফাইন-টিউনিং এর মধ্য দিয়ে যেতে পারে, আরও উন্নত মডেল, যেমন যেগুলি আগ্রহী, তা পারে না; আমরা তাদের প্রশিক্ষণের তথ্য বাড়াতে পারি না।


আমরা কিভাবে GPT-3 এর প্রশিক্ষণ ডেটার বাইরে উত্তর পেতে পারি? একটি পদ্ধতিতে এর পাঠ্য বোঝার ক্ষমতাকে কাজে লাগানো জড়িত; প্রাসঙ্গিক প্রসঙ্গের সাথে প্রম্পট উন্নত করে, আমরা সম্ভবত সঠিক উত্তর পেতে পারি।


নীচের উদাহরণে, আমি FIFA এর অফিসিয়াল সাইট থেকে প্রসঙ্গ সরবরাহ করছি এবং প্রতিক্রিয়া উল্লেখযোগ্যভাবে আলাদা:

প্রশ্নের উত্তরে দ্বিতীয় প্রচেষ্টা সরবরাহ করা প্রসঙ্গে, ChatGPT সঠিকভাবে উত্তর দিতে পারে।


আমরা অনুমান করতে পারি যে পর্যাপ্ত প্রাসঙ্গিক প্রসঙ্গ দেওয়া হলে মডেলটি যেকোনো প্রম্পটে সাড়া দিতে পারে। প্রশ্নটি রয়ে গেছে: একটি নির্বিচারে প্রম্পট দেওয়া প্রাসঙ্গিক কী তা আমরা কীভাবে জানতে পারি? এটি মোকাবেলা করার জন্য, আমাদের অন্বেষণ করতে হবে কি শব্দ এমবেডিং

শব্দ এমবেডিং কি?

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


এম্বেডিং গণনা করতে, আমাদের একটি নিউরাল নেটওয়ার্কের প্রয়োজন হবে যেমন word2vec বা text-embeding-ada-002 । এই নেটওয়ার্কগুলিকে প্রচুর পরিমাণে পাঠ্যের উপর প্রশিক্ষিত করা হয়েছে এবং প্রশিক্ষণের ডেটাতে নির্দিষ্ট প্যাটার্নগুলি যে ফ্রিকোয়েন্সিগুলির সাথে প্রদর্শিত হয় তা বিশ্লেষণ করে শব্দগুলির মধ্যে সম্পর্ক খুঁজে পেতে পারে৷


ধরা যাক আমাদের নিম্নলিখিত শব্দ রয়েছে:

  • বিড়াল
  • কুকুর
  • বল
  • গৃহ


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

শব্দ

ভেক্টর

প্রসঙ্গ

বিড়াল

[০.১, ০.২, ০.৩, ০.৪, ০.৫]

প্রাণী, বস্তু, ছোট জিনিস

কুকুর

[০.৬, ০.৭, ০.৮, ০.৯, ১.০]

প্রাণী, বস্তু, বড় জিনিস

বল

[০.২, ০.৪, ০.৬, ০.৮, ১.০]

বস্তু, খেলনা, ছোট জিনিস

গৃহ

[০.৩, ০.৬, ০.৯, ১.২, ১.৫]

বিল্ডিং, বাড়ি, বড় জিনিস

একবার আমাদের কাছে প্রতিটি শব্দের ভেক্টর আছে, আমরা পাঠ্যের অর্থ উপস্থাপন করতে সেগুলি ব্যবহার করতে পারি। উদাহরণস্বরূপ, "বিড়াল বল তাড়া করেছে" বাক্যটিকে ভেক্টর [0.1, 0.2, 0.3, 0.4, 0.5] + [0.2, 0.4, 0.6, 0.8, 1.0] = [0.3, 0.6, 0.9, 1.2] হিসাবে উপস্থাপন করা যেতে পারে , 1.5]। এই ভেক্টরটি এমন একটি বাক্যকে উপস্থাপন করে যা একটি প্রাণীকে একটি বস্তুকে তাড়া করে।


শব্দ এমবেডিংগুলিকে বহুমাত্রিক স্থান হিসাবে কল্পনা করা যেতে পারে যেখানে একই অর্থ সহ শব্দ বা বাক্যগুলি একসাথে কাছাকাছি থাকে। যেকোন ইনপুট টেক্সটের অনুরূপ অর্থ খুঁজতে আমরা ভেক্টরের মধ্যে "দূরত্ব" গণনা করতে পারি।

ভেক্টরের ত্রিমাত্রিক উপস্থাপনা। প্রথমটি 'পুরুষ-মহিলা' লেবেলযুক্ত এবং এতে ডেটা পয়েন্ট রয়েছে পুরুষ-মহিলা এবং রাজা-রাণী, দ্বিতীয়টি 'ক্রিয়া-কাল' লেবেলযুক্ত এবং হাঁটা-হাঁটা সাঁতার-সাঁতারের মতো ক্রিয়া রয়েছে। শেষটি 'দেশ-রাজধানী' লেবেলযুক্ত এবং তাদের দেশের সাথে সংযুক্ত বেশ কয়েকটি রাজধানী রয়েছে ভেক্টর স্পেস হিসাবে এমবেডিংয়ের 3D উপস্থাপনা। বাস্তবে, এই স্থানগুলির শত শত বা হাজার হাজার মাত্রা থাকতে পারে। সূত্র: মিট এআই এর মাল্টিটুল: ভেক্টর এমবেডিংস


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

টোকেন সহ নিউরাল নেটওয়ার্ক এম্বেড করা

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


একটি টোকেন পাঠ্যের ক্ষুদ্রতম একক যা মডেল দ্বারা প্রক্রিয়া করা যেতে পারে। টোকেন শব্দ, অক্ষর, বিরাম চিহ্ন, চিহ্ন বা শব্দের অংশ হতে পারে।


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

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

এমবেডিং ব্যবহার করে একটি স্মার্ট বট ডিজাইন করা

এমবেডিংগুলি কী তা এখন আমরা বুঝতে পেরেছি, পরবর্তী প্রশ্ন হল: কীভাবে তারা আমাদের একটি স্মার্ট বট তৈরি করতে সাহায্য করতে পারে?


প্রথমে, আসুন আমরা সরাসরি GPT-3 API ব্যবহার করলে কী ঘটে তা বিবেচনা করা যাক। ব্যবহারকারী একটি প্রম্পট জারি করে, এবং মডেলটি তার ক্ষমতার সর্বোত্তম সাড়া দেয়।

ডায়াগ্রাম ব্যবহারকারী এবং GPT-3 এর মধ্যে মিথস্ক্রিয়া দেখাচ্ছে। ব্যবহারকারী একটি প্রম্পট পাঠায়, মডেল সাড়া দেয়।


যাইহোক, যখন আমরা সমীকরণে প্রসঙ্গ যোগ করি, তখন জিনিসগুলি পরিবর্তিত হয়। উদাহরণস্বরূপ, প্রসঙ্গ দেওয়ার পরে যখন আমি ChatGPT কে বিশ্বকাপ বিজয়ী সম্পর্কে জিজ্ঞাসা করি, তখন এটি সমস্ত পার্থক্য তৈরি করে।


সুতরাং, একটি স্মার্ট বট তৈরি করার পরিকল্পনাটি নিম্নরূপ:

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

একটি বটের আরও জটিল বাস্তবায়ন। ব্যবহারকারী একটি চ্যাটবট অ্যাপে প্রম্পট পাঠায়, যা একটি প্রসঙ্গ ডাটাবেস অনুসন্ধান করে এবং প্রম্পটটিকে সমৃদ্ধ করতে এটি ব্যবহার করে। প্রম্পটটি GPT-3 এ পাঠানো হয় এবং এর প্রতিক্রিয়া ব্যবহারকারীর কাছে পাঠানো হয়।


ডাটাবেস ডিজাইন করে বেশিরভাগ প্রকল্পের মতই শুরু করা যাক।

এমবেডিং সহ একটি জ্ঞান ডেটাবেস তৈরি করা

আমাদের প্রসঙ্গ ডাটাবেস মূল ডকুমেন্টেশন এবং তাদের নিজ নিজ ভেক্টর অন্তর্ভুক্ত করা আবশ্যক. নীতিগতভাবে, আমরা এই কাজের জন্য যেকোনো ধরনের ডাটাবেস নিয়োগ করতে পারি, কিন্তু একটি ভেক্টর ডাটাবেস হল কাজের জন্য সর্বোত্তম হাতিয়ার।


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


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

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


একটি প্রসঙ্গ ডাটাবেস তৈরি করতে, আমি করব:

  1. সমস্ত উৎস ডকুমেন্টেশন সংগ্রহ করুন.
  2. অপ্রাসঙ্গিক নথিগুলি ফিল্টার করুন।
  3. প্রতিটি নথির জন্য এমবেডিং গণনা করুন।
  4. ডাটাবেসে ভেক্টর, মূল পাঠ্য এবং অন্যান্য প্রাসঙ্গিক মেটাডেটা সংরক্ষণ করুন।

প্রসঙ্গ ডাটাবেসে তথ্য সংরক্ষণের প্রক্রিয়া চিত্রিত করে চিত্র। উৎস নথিটি এমবেডিং নিউরাল নেটওয়ার্কে পাঠানো হয়। ডাটাবেস মূল পাঠ্য সহ ভেক্টর সংরক্ষণ করে।

নথিগুলিকে ভেক্টরে রূপান্তর করা হচ্ছে

প্রথমে, আমাকে OpenAI API কী দিয়ে একটি পরিবেশ ফাইল শুরু করতে হবে। এই ফাইলটি কখনই সংস্করণ নিয়ন্ত্রণে প্রতিশ্রুতিবদ্ধ হওয়া উচিত নয়, কারণ API কীটি ব্যক্তিগত এবং আপনার অ্যাকাউন্টের সাথে সংযুক্ত৷

 export OPENAI_API_KEY=YOUR_API_KEY

পরবর্তী, আমি আমার পাইথন অ্যাপ্লিকেশনের জন্য একটি ভার্চুয়ালেনভ তৈরি করব:

 $ virtualenv venv $ source venv/bin/activate $ source .env

এবং OpenAI প্যাকেজ ইনস্টল করুন:

 ```bash $ pip install openai numpy

আসুন "ডকার কন্টেইনার" স্ট্রিংটির জন্য এমবেডিং গণনা করার চেষ্টা করি। আপনি এটি পাইথন REPL বা পাইথন স্ক্রিপ্ট হিসাবে চালাতে পারেন:

 $ python >>> import openai >>> embeddings = openai.Embedding.create(input="Docker Containers", engine="text-embedding-ada-002") >>> embeddings JSON: { "data": [ { "embedding": [ -0.00530336843803525, 0.0013223182177171111, ... 1533 more items ..., -0.015645816922187805 ], "index": 0, "object": "embedding" } ], "model": "text-embedding-ada-002-v2", "object": "list", "usage": { "prompt_tokens": 2, "total_tokens": 2 } }

আপনি দেখতে পাচ্ছেন, OpenAI-এর মডেল 1536টি আইটেম ধারণকারী একটি embedding তালিকার সাথে প্রতিক্রিয়া জানায় — টেক্সট-এমবেডিং-এডা-002-এর ভেক্টর আকার।

পাইনকোনে এমবেডিংগুলি সংরক্ষণ করা হচ্ছে

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


আমার Pinecone অ্যাকাউন্ট তৈরি করার পরে এবং আমার API কী এবং পরিবেশ পুনরুদ্ধার করার পরে, আমি আমার .env ফাইলে উভয় মান যোগ করি।

Pinecone API কী প্রজন্মের স্ক্রিনশট

এখন .env আমার Pinecone এবং OpenAI গোপনীয়তা থাকা উচিত।

 export OPENAI_API_KEY=YOUR_API_KEY # Pinecone secrets export PINECONE_API_KEY=YOUR_API_KEY export PINECONE_ENVIRONMENT=YOUR_PINECONE_DATACENTER

তারপর, আমি পাইথনের জন্য পাইনকোন ক্লায়েন্ট ইনস্টল করি:

 $ pip install pinecone-client

আমি একটি ডাটাবেস আরম্ভ করতে হবে; এগুলি হল db_create.py স্ক্রিপ্টের বিষয়বস্তু:

 # db_create.py import pinecone import openai import os index_name = "semaphore" embed_model = "text-embedding-ada-002" api_key = os.getenv("PINECONE_API_KEY") env = os.getenv("PINECONE_ENVIRONMENT") pinecone.init(api_key=api_key, environment=env) embedding = openai.Embedding.create( input=[ "Sample document text goes here", "there will be several phrases in each batch" ], engine=embed_model ) if index_name not in pinecone.list_indexes(): print("Creating pinecone index: " + index_name) pinecone.create_index( index_name, dimension=len(embedding['data'][0]['embedding']), metric='cosine', metadata_config={'indexed': ['source', 'id']} )

স্ক্রিপ্টটি ডাটাবেস তৈরি করতে কয়েক মিনিট সময় নিতে পারে।

 $ python db_create.py

এর পরে, আমি টিকটকেন প্যাকেজটি ইনস্টল করব। উৎস নথিতে কতগুলি টোকেন আছে তা গণনা করতে আমি এটি ব্যবহার করব। এটি গুরুত্বপূর্ণ কারণ এমবেডিং মডেল শুধুমাত্র 8191 টোকেন পর্যন্ত পরিচালনা করতে পারে।

 $ pip install tiktoken

প্যাকেজ ইনস্টল করার সময়, আসুন একটি সুন্দর-সুদর্শন অগ্রগতি বার তৈরি করতে tqdm ইনস্টল করি।

 $ pip install tqdm

এখন আমাকে ডাটাবেসে নথিগুলি আপলোড করতে হবে। এর জন্য স্ক্রিপ্ট বলা হবে index_docs.py । আসুন প্রয়োজনীয় মডিউলগুলি আমদানি করে এবং কিছু ধ্রুবক সংজ্ঞায়িত করে শুরু করি:

 # index_docs.py # Pinecone db name and upload batch size index_name = 'semaphore' upsert_batch_size = 20 # OpenAI embedding and tokenizer models embed_model = "text-embedding-ada-002" encoding_model = "cl100k_base" max_tokens_model = 8191

পরবর্তী, টোকেন গণনা করার জন্য আমাদের একটি ফাংশন প্রয়োজন হবে। OpenAI পৃষ্ঠায় একটি টোকেন কাউন্টার উদাহরণ রয়েছে:

 import tiktoken def num_tokens_from_string(string: str) -> int: """Returns the number of tokens in a text string.""" encoding = tiktoken.get_encoding(encoding_model) num_tokens = len(encoding.encode(string)) return num_tokens

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

 import re def extract_yaml(text: str) -> str: """Returns list with all the YAML code blocks found in text.""" matches = [m.group(1) for m in re.finditer("```yaml([\w\W]*?)```", text)] return matches

আমি ফাংশন সঙ্গে সম্পন্ন করছি. এর পরে, এটি মেমরিতে ফাইলগুলি লোড করবে এবং উদাহরণগুলি বের করবে:

 from tqdm import tqdm import sys import os import pathlib repo_path = sys.argv[1] repo_path = os.path.abspath(repo_path) repo = pathlib.Path(repo_path) markdown_files = list(repo.glob("**/*.md")) + list( repo.glob("**/*.mdx") ) print(f"Extracting YAML from Markdown files in {repo_path}") new_data = [] for i in tqdm(range(0, len(markdown_files))): markdown_file = markdown_files[i] with open(markdown_file, "r") as f: relative_path = markdown_file.relative_to(repo_path) text = str(f.read()) if text == '': continue yamls = extract_yaml(text) j = 0 for y in yamls: j = j+1 new_data.append({ "source": str(relative_path), "text": y, "id": f"github.com/semaphore/docs/{relative_path}[{j}]" })

এই মুহুর্তে, সমস্ত YAMLs new_data তালিকায় সংরক্ষণ করা উচিত। চূড়ান্ত পদক্ষেপ হল Pinecone এ এমবেডিংগুলি আপলোড করা।

 import pinecone import openai api_key = os.getenv("PINECONE_API_KEY") env = os.getenv("PINECONE_ENVIRONMENT") pinecone.init(api_key=api_key, enviroment=env) index = pinecone.Index(index_name) print(f"Creating embeddings and uploading vectors to database") for i in tqdm(range(0, len(new_data), upsert_batch_size)): i_end = min(len(new_data), i+upsert_batch_size) meta_batch = new_data[i:i_end] ids_batch = [x['id'] for x in meta_batch] texts = [x['text'] for x in meta_batch] embedding = openai.Embedding.create(input=texts, engine=embed_model) embeds = [record['embedding'] for record in embedding['data']] # clean metadata before upserting meta_batch = [{ 'id': x['id'], 'text': x['text'], 'source': x['source'] } for x in meta_batch] to_upsert = list(zip(ids_batch, embeds, meta_batch)) index.upsert(vectors=to_upsert)

একটি রেফারেন্স হিসাবে, আপনি ডেমো সংগ্রহস্থলে সম্পূর্ণ index_docs.py ফাইলটি খুঁজে পেতে পারেন

ডাটাবেস সেটআপের সাথে শেষ করতে সূচী স্ক্রিপ্টটি চালাই:

 $ git clone https://github.com/semaphoreci/docs.git /tmp/docs $ source .env $ python index_docs.py /tmp/docs

ডাটাবেস পরীক্ষা করা হচ্ছে

Pinecone ড্যাশবোর্ডের ডাটাবেসে ভেক্টর দেখাতে হবে।

পাইনকোন ড্যাশবোর্ডের স্ক্রিনশট মোট 79টি ভেক্টর সহ ডাটাবেস দেখাচ্ছে

আমরা নিম্নলিখিত কোড সহ ডাটাবেস অনুসন্ধান করতে পারি, যা আপনি স্ক্রিপ্ট হিসাবে বা পাইথন REPL-এ সরাসরি চালাতে পারেন:

 $ python >>> import os >>> import pinecone >>> import openai # Compute embeddings for string "Docker Container" >>> embeddings = openai.Embedding.create(input="Docker Containers", engine="text-embedding-ada-002") # Connect to database >>> index_name = "semaphore" >>> api_key = os.getenv("PINECONE_API_KEY") >>> env = os.getenv("PINECONE_ENVIRONMENT") >>> pinecone.init(api_key=api_key, environment=env) >>> index = pinecone.Index(index_name) # Query database >>> matches = index.query(embeddings['data'][0]['embedding'], top_k=1, include_metadata=True) >>> matches['matches'][0] {'id': 'github.com/semaphore/docs/docs/ci-cd-environment/docker-authentication.md[3]', 'metadata': {'id': 'github.com/semaphore/docs/docs/ci-cd-environment/docker-authentication.md[3]', 'source': 'docs/ci-cd-environment/docker-authentication.md', 'text': '\n' '# .semaphore/semaphore.yml\n' 'version: v1.0\n' 'name: Using a Docker image\n' 'agent:\n' ' machine:\n' ' type: e1-standard-2\n' ' os_image: ubuntu1804\n' '\n' 'blocks:\n' ' - name: Run container from Docker Hub\n' ' task:\n' ' jobs:\n' ' - name: Authenticate docker pull\n' ' commands:\n' ' - checkout\n' ' - echo $DOCKERHUB_PASSWORD | docker login ' '--username "$DOCKERHUB_USERNAME" --password-stdin\n' ' - docker pull /\n' ' - docker images\n' ' - docker run /\n' ' secrets:\n' ' - name: docker-hub\n'}, 'score': 0.796259582, 'values': []}

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

বট বিল্ডিং

আমাদের কাছে ডেটা আছে, এবং আমরা জানি কিভাবে এটি অনুসন্ধান করতে হয়। এর বট কাজ করা যাক.

প্রম্পট প্রক্রিয়াকরণের পদক্ষেপগুলি হল:

  1. ব্যবহারকারীর প্রম্পট নিন।
  2. এর ভেক্টর গণনা করুন।
  3. ডাটাবেস থেকে প্রাসঙ্গিক প্রসঙ্গ পুনরুদ্ধার করুন।
  4. প্রসঙ্গ সহ ব্যবহারকারীর প্রম্পট GPT-3 এ পাঠান।
  5. ব্যবহারকারীর কাছে মডেলের প্রতিক্রিয়া ফরোয়ার্ড করুন।

বটের জন্য ডেটা প্রবাহের চিত্র। বাম দিকে ব্যবহারকারীর প্রম্পট প্রবেশ করে, যা এম্বেডিং নিউরাল নেটওয়ার্ক দ্বারা প্রক্রিয়া করা হয়, তারপর প্রসঙ্গ ডাটাবেসে পাঠানো হয়। অনুসন্ধানে প্রাসঙ্গিক পাঠ্য পাওয়া যায় যা GPT-3 মডেলে পাঠানো হয়। মডেলের আউটপুট চূড়ান্ত উত্তর হিসাবে ব্যবহারকারীর কাছে পাঠানো হয়। যথারীতি, আমি complete.py এ কিছু ধ্রুবক সংজ্ঞায়িত করে শুরু করব, বটের প্রধান স্ক্রিপ্ট:

 # complete.py # Pinecone database name, number of matched to retrieve # cutoff similarity score, and how much tokens as context index_name = 'semaphore' context_cap_per_query = 30 match_min_score = 0.75 context_tokens_per_query = 3000 # OpenAI LLM model parameters chat_engine_model = "gpt-3.5-turbo" max_tokens_model = 4096 temperature = 0.2 embed_model = "text-embedding-ada-002" encoding_model_messages = "gpt-3.5-turbo-0301" encoding_model_strings = "cl100k_base" import pinecone import os # Connect with Pinecone db and index api_key = os.getenv("PINECONE_API_KEY") env = os.getenv("PINECONE_ENVIRONMENT") pinecone.init(api_key=api_key, environment=env) index = pinecone.Index(index_name)

এর পরে, আমি OpenAI উদাহরণে দেখানো টোকেন গণনা করার জন্য ফাংশন যোগ করব। প্রথম ফাংশনটি একটি স্ট্রিং-এ টোকেন গণনা করে, যখন দ্বিতীয়টি বার্তাগুলিতে টোকেন গণনা করে। আমরা একটু পরে বিস্তারিত বার্তা দেখতে পাব. আপাতত, আসুন শুধু বলি এটি একটি কাঠামো যা কথোপকথনের অবস্থাকে মেমরিতে রাখে।

 import tiktoken def num_tokens_from_string(string: str) -> int: """Returns the number of tokens in a text string.""" encoding = tiktoken.get_encoding(encoding_model_strings) num_tokens = len(encoding.encode(string)) return num_tokens def num_tokens_from_messages(messages): """Returns the number of tokens used by a list of messages. Compatible with model """ try: encoding = tiktoken.encoding_for_model(encoding_model_messages) except KeyError: encoding = tiktoken.get_encoding(encoding_model_strings) num_tokens = 0 for message in messages: num_tokens += 4 # every message follows {role/name}\n{content}\n for key, value in message.items(): num_tokens += len(encoding.encode(value)) if key == "name": # if there's a name, the role is omitted num_tokens += -1 # role is always required and always 1 token num_tokens += 2 # every reply is primed with assistant return num_tokens

নিম্নলিখিত ফাংশন GPT-3 এর জন্য একটি সমৃদ্ধ প্রম্পট ফেরত দিতে আসল প্রম্পট এবং প্রসঙ্গ স্ট্রিং নেয়:

 def get_prompt(query: str, context: str) -> str: """Return the prompt with query and context.""" return ( f"Create the continuous integration pipeline YAML code to fullfil the requested task.\n" + f"Below you will find some context that may help. Ignore it if it seems irrelevant.\n\n" + f"Context:\n{context}" + f"\n\nTask: {query}\n\nYAML Code:" )

get_message ফাংশন প্রম্পটটিকে API এর সাথে সামঞ্জস্যপূর্ণ একটি বিন্যাসে ফর্ম্যাট করে:

 def get_message(role: str, content: str) -> dict: """Generate a message for OpenAI API completion.""" return {"role": role, "content": content}

মডেলটি কীভাবে প্রতিক্রিয়া দেখায় তা প্রভাবিত করে এমন তিনটি ধরণের ভূমিকা রয়েছে:

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


এখন আকর্ষক অংশ জন্য. get_context ফাংশন প্রম্পট নেয়, ডাটাবেসকে জিজ্ঞাসা করে এবং এই শর্তগুলির মধ্যে একটি পূরণ না হওয়া পর্যন্ত একটি প্রসঙ্গ স্ট্রিং তৈরি করে:

  • সম্পূর্ণ টেক্সটটি context_tokens_per_query ছাড়িয়ে গেছে, আমি প্রসঙ্গটির জন্য যে স্থান সংরক্ষিত করেছি।
  • অনুসন্ধান ফাংশন অনুরোধ করা সমস্ত মিল পুনরুদ্ধার করে।
  • match_min_score নিচে একটি মিল আছে এমন ম্যাচগুলি উপেক্ষা করা হয়।
 import openai def get_context(query: str, max_tokens: int) -> list: """Generate message for OpenAI model. Add context until hitting `context_token_limit` limit. Returns prompt string.""" embeddings = openai.Embedding.create( input=[query], engine=embed_model ) # search the database vectors = embeddings['data'][0]['embedding'] embeddings = index.query(vectors, top_k=context_cap_per_query, include_metadata=True) matches = embeddings['matches'] # filter and aggregate context usable_context = "" context_count = 0 for i in range(0, len(matches)): source = matches[i]['metadata']['source'] if matches[i]['score'] < match_min_score: # skip context with low similarity score continue context = matches[i]['metadata']['text'] token_count = num_tokens_from_string(usable_context + '\n---\n' + context) if token_count < context_tokens_per_query: usable_context = usable_context + '\n---\n' + context context_count = context_count + 1 print(f"Found {context_count} contexts for your query") return usable_context

পরবর্তী এবং চূড়ান্ত ফাংশন, complete , OpenAI-তে API অনুরোধ জারি করে এবং মডেলের প্রতিক্রিয়া প্রদান করে।

 def complete(messages): """Query the OpenAI model. Returns the first answer. """ res = openai.ChatCompletion.create( model=chat_engine_model, messages=messages, temperature=temperature ) return res.choices[0].message.content.strip()

এখানেই শেষ; এখন আমাকে শুধুমাত্র কমান্ড লাইন আর্গুমেন্টের সাথে মোকাবিলা করতে হবে এবং ফাংশনগুলিকে সঠিক ক্রমে কল করতে হবে:

 import sys query = sys.argv[1] context = get_context(query, context_tokens_per_query) prompt = get_prompt(query, context) # initialize messages list to send to OpenAI API messages = [] messages.append(get_message('user', prompt)) messages.append(get_message('system', 'You are a helpful assistant that writes YAML code for Semaphore continuous integration pipelines and explains them. Return YAML code inside code fences.')) if num_tokens_from_messages(messages) >= max_tokens_model: raise Exception('Model token size limit reached') print("Working on your query... ") answer = complete(messages) print("Answer:\n") print(answer) messages.append(get_message('assistant', answer))

স্ক্রিপ্টটি চালানোর এবং এটির ভাড়া কেমন তা দেখার সময় এসেছে:

 $ python complete.py "Create a CI pipeline that builds and uploads a Docker image to Docker Hub"

ফলাফল হলো:

 version: v1.0 name: Docker Build and Push agent: machine: type: e1-standard-2 os_image: ubuntu1804 blocks: - name: "Build and Push Docker Image" task: jobs: - name: "Docker Build and Push" commands: - checkout - docker build -t /: . - echo "$DOCKERHUB_PASSWORD" | docker login -u "$DOCKERHUB_USERNAME" --password-stdin - docker push /: promotions: - name: Deploy to production pipeline_file: deploy-production.yml auto_promote: when: "result = 'passed' and branch = 'master'"

এটি প্রথম ভাল ফলাফল। আমরা প্রদত্ত প্রসঙ্গ উদাহরণ থেকে মডেলটি সিনট্যাক্স অনুমান করেছে।

বট এর ক্ষমতা সম্প্রসারণ সম্পর্কে চিন্তা

মনে রাখবেন যে আমি একটি শালীন লক্ষ্য নিয়ে শুরু করেছি: YAML পাইপলাইন লেখার জন্য একজন সহকারী তৈরি করা। আমার ভেক্টর ডাটাবেসে সমৃদ্ধ বিষয়বস্তু সহ, আমি সেমাফোর (অথবা যে কোনও পণ্য - ডক্সকে /tmp এ ক্লোন করা মনে রাখবেন?) সম্পর্কে যেকোনো প্রশ্নের উত্তর দিতে বটটিকে সাধারণীকরণ করতে পারি।


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


সুতরাং, এক অর্থে, আমাদের প্রয়োজন মেটানোর জন্য বটটিকে সূক্ষ্ম-টিউন করার সাথে জড়িত একটি শিল্প — এবং প্রচুর পরীক্ষা এবং ত্রুটি রয়েছে৷ আমরা প্রসঙ্গ সীমা নিয়ে পরীক্ষা করতে পারি, নিম্নমানের সামগ্রী সরাতে পারি, সারসংক্ষেপ করতে পারি এবং মিলের স্কোর সামঞ্জস্য করে অপ্রাসঙ্গিক প্রসঙ্গ ফিল্টার করতে পারি।

একটি সঠিক চ্যাটবট বাস্তবায়ন

আপনি হয়তো লক্ষ্য করেছেন যে আমার বট আমাদের ChatGPT-এর মতো প্রকৃত কথোপকথন করতে সক্ষম করে না। আমরা একটি প্রশ্ন জিজ্ঞাসা করি এবং একটি উত্তর পাই।


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

 messages = [] while True: query = input('Type your prompt:\n') context = get_context(query, context_tokens_per_query) prompt = get_prompt(query, context) messages.append(get_message('user', prompt)) messages.append(get_message('system', 'You are a helpful assistant that writes YAML code for Semaphore continuous integration pipelines and explains them. Return YAML code inside code fences.')) if num_tokens_from_messages(messages) >= max_tokens_model: raise Exception('Model token size limit reached') print("Working on your query... ") answer = complete(messages) print("Answer:\n") print(answer) # remove system message and append model's answer messages.pop() messages.append(get_message('assistant', answer))

দুর্ভাগ্যবশত, এই বাস্তবায়ন বরং প্রাথমিক। এটি বর্ধিত কথোপকথন সমর্থন করবে না কারণ প্রতিটি ইন্টারঅ্যাকশনের সাথে টোকেন সংখ্যা বৃদ্ধি পায়। শীঘ্রই, আমরা GPT-3-এর জন্য 4096-টোকেন সীমাতে পৌঁছব, আরও সংলাপ রোধ করব।


সুতরাং, আমাদের অনুরোধটি টোকেন সীমার মধ্যে রাখার কিছু উপায় খুঁজে বের করতে হবে। কয়েকটি কৌশল অনুসরণ করে:

  • পুরানো বার্তা মুছুন. যদিও এটি সবচেয়ে সহজ সমাধান, এটি কথোপকথনের "মেমরি" শুধুমাত্র সাম্প্রতিক বার্তাগুলিতে সীমাবদ্ধ করে।
  • পূর্ববর্তী বার্তা সারসংক্ষেপ. আমরা "মডেল জিজ্ঞাসা করুন" ব্যবহার করতে পারি আগের বার্তাগুলিকে ঘনীভূত করতে এবং সেগুলিকে মূল প্রশ্ন ও উত্তরগুলির জন্য প্রতিস্থাপন করতে। যদিও এই পদ্ধতিটি প্রশ্নগুলির মধ্যে খরচ এবং ব্যবধান বাড়ায়, এটি কেবল অতীতের বার্তাগুলি মুছে ফেলার তুলনায় উচ্চতর ফলাফল তৈরি করতে পারে।
  • মিথস্ক্রিয়া সংখ্যার উপর একটি কঠোর সীমা সেট করুন।
  • GPT-4 API-এর সাধারণ উপলভ্যতার জন্য অপেক্ষা করুন, যা শুধুমাত্র স্মার্ট নয় কিন্তু দ্বিগুণ টোকেন ক্ষমতা রয়েছে।
  • "gpt-3.5-turbo-16k" এর মতো একটি নতুন মডেল ব্যবহার করুন যা 16k পর্যন্ত টোকেন পরিচালনা করতে পারে

উপসংহার

শব্দ এমবেডিং এবং একটি ভাল প্রসঙ্গ ডেটাবেসের মাধ্যমে বটের প্রতিক্রিয়াগুলিকে উন্নত করা সম্ভব। এটি অর্জন করতে, আমাদের ভাল মানের ডকুমেন্টেশন প্রয়োজন। একটি বট তৈরিতে যথেষ্ট পরিমাণে ট্রায়াল এবং ত্রুটি জড়িত যা আপাতদৃষ্টিতে বিষয়বস্তুর একটি উপলব্ধি রাখে।


আমি আশা করি শব্দ এম্বেডিং এবং বৃহৎ ভাষার মডেলগুলির এই গভীর অন্বেষণ আপনাকে আপনার প্রয়োজনীয়তা অনুসারে কাস্টমাইজ করা আরও শক্তিশালী বট তৈরি করতে সহায়তা করবে৷


শুভ বিল্ডিং!


এছাড়াও এখানে প্রকাশিত.