OpenAI-এ Git-এর সক্ষমতা বৃদ্ধি
Git বাস্তুতন্ত্রে বিনিয়োগের পাশাপাশি এজেন্টদের বিপুল পরিসরের কাজের উপযোগী সোর্স নিয়ন্ত্রণব্যবস্থা গড়ে তোলা.
গত এক বছরে আমাদের মনোরিপোর আকার ও এর ওপর চাহিদা বিস্ময়কর গতিতে বেড়েছে. Codex যে বিপুল পরিমাণ কাজ একসঙ্গে করা সম্ভব করছে, তা সামলাতে আমাদের সোর্স নিয়ন্ত্রণব্যবস্থা ঢেলে সাজানো দরকার—এটি স্পষ্ট ছিল.
প্রকৌশলের কোনো কাজে বাধা না দিয়ে বা আমাদের দলের Git ব্যবহারের ধরন না বদলিয়েই আমরা Git রিপোজিটরির নতুন ব্যাকএন্ড Pando তৈরি করেছি. OpenAI-এর মনোরিপোতে এখন সব উন্নয়নকাজ Pando-র মাধ্যমে চলে. Pando-র নকশায় দুটি উচ্চাকাঙ্ক্ষী লক্ষ্য ছিল: প্রথমত, সমান্তরালে আরও একক যোগ করে লেখার সক্ষমতা বাড়ানো, বিশেষত একসঙ্গে অনেক শাখায় পুশের জন্য. দ্বিতীয়ত, পড়ার থ্রুপুট সর্বোচ্চ করা, যাতে ক্লায়েন্ট এত দ্রুত ডেটা ডাউনলোড করতে পারে যে তার উপলব্ধ নেটওয়ার্ক ব্যান্ডউইডথ পুরোপুরি ব্যবহার হয়.
Git প্রোটোকল ও ক্লায়েন্টের সঙ্গে সামঞ্জস্য রেখেই আমরা এই লক্ষ্যগুলো পূরণ করেছি. ফলে প্রকৌশলী ও এজেন্ট—উভয়েই বিদ্যমান কর্মধারায় নির্বিঘ্নে Pando গ্রহণ করতে পেরেছে. বাস্তব ব্যবহারে Pando পুশের মধ্যক বিলম্ব প্রায় পাঁচ ভাগের এক ভাগে নামিয়ে এনেছে. এখন এটি প্রতিদিন প্রায় এক পেটাবাইট Git ডেটা সরবরাহ করে.
এখানে নতুন সোর্স নিয়ন্ত্রণব্যবস্থা তৈরির পেছনের কারণ এবং কেন আমরা Git-এর সঙ্গে সামঞ্জস্য রাখার সিদ্ধান্ত নিয়েছি, তা তুলে ধরব. Git-এর সক্ষমতা বাড়ানোর প্রচলিত পদ্ধতিগুলোর সঙ্গে আমাদের ব্যবস্থার তুলনা করব এবং OpenAI-এর ক্রমবর্ধমান চাহিদা মেটাতে Pando কেন বিশেষভাবে সক্ষম, তা ব্যাখ্যা করব. পরবর্তী পরিকল্পনা এবং এজেন্টদের বিপুল পরিসরের কাজ সমর্থন করতে Git-এ কীভাবে অবদান রাখব, তা নিয়েও আলোচনা করব.
Codex OpenAI-এ উন্নয়নকাজের পরিসর ও গতি বদলে দিয়েছে, প্রকৌশলীদের অনেক বেশি কাজ সমান্তরালে করার সুযোগ করে দিয়েছে. অর্থাৎ আরও বেশি শাখা ও পুশ, আরও মার্জ, এবং উন্নয়ন পরিবেশ, গবেষণার কাজ ও ধারাবাহিক সমন্বয় প্রক্রিয়া থেকে আরও ফেচ ও ক্লোন.
এই চাহিদাগুলো পরস্পরের প্রভাব আরও বাড়ায়. এখন একজন প্রকৌশলীর একসঙ্গে কয়েকটি পরিবর্তন ধারাবাহিক সমন্বয় প্রক্রিয়ার জন্য প্রস্তুত থাকে, আর প্রতিটি পুশ থেকে কয়েকটি কাজ একই কমিট ফেচ করতে শুরু করতে পারে.
গত বছরের শেষ দিক থেকে আমাদের মনোরিপোর সহায়ক ব্যবস্থাগুলো চাহিদার সঙ্গে তাল মেলাতে হিমশিম খাচ্ছিল. ধীর ফেচ ও পুশের পাশাপাশি মার্জ ব্যর্থ হচ্ছিল; কখনো কখনো নির্ভরযোগ্যতা ৯০%-এর নিচে নেমে যাচ্ছিল. আমরা কি Git-এর নিজের সীমায় পৌঁছেছিলাম, নাকি মনোরিপো থেকে সেবা দেওয়ার পদ্ধতির সীমায়? ইমেইলে কার্নেলের প্যাচ আদান-প্রদান করত যে সম্প্রদায়, সেখান থেকেই Git-এর জন্ম. দুই দশকেরও বেশি সময় ধরে সফটওয়্যার তৈরির ধরন বদলানোর সঙ্গে সঙ্গে ডেভেলপাররা Git-কে ঘিরে নিজেদের সরঞ্জাম মানিয়ে নিয়েছেন. নিজেদের মনোরিপোতে বাধার মুখে পড়তে শুরু করলে, সেই কাজের ওপর ভিত্তি করেই এগিয়ে যেতে পারাটা আমাদের কাছে গুরুত্বপূর্ণ ছিল.
আমরা পরিচিত কর্মধারা বজায় রেখেই ব্যাকএন্ড নতুন করে তৈরির পথ দেখতে পেলাম, যাতে ভিন্ন শাখায় পুশ সমান্তরালে সামলানো যায় এবং একই ইতিহাস একসঙ্গে অনেক পাঠককে দেওয়া যায়. সোর্স নিয়ন্ত্রণের কর্মধারার ভিত্তি হিসেবে Git-কে রাখার অর্থ ছিল, ক্লায়েন্টের উন্নতিগুলো OpenAI-এর বাইরেও কাজে লাগতে পারে. আমরা আমাদের Git-এর অনুলিপি(একটি নতুন উইন্ডোতে খোলে) থেকে সেই উন্নতিগুলো মূল প্রকল্পে দিতে চেয়েছি, যাতে বৃহত্তর সম্প্রদায়ও সেগুলো ব্যবহার করতে পারে.
সোর্স নিয়ন্ত্রণব্যবস্থার সক্ষমতা বাড়ানোর দুটি অপরিহার্য দিক আছে: অনেক লেখকের ভিন্ন শাখায় পুশ করা এবং অনেক পাঠকের একই ইতিহাস ফেচ করা. Pando দুটিই দক্ষভাবে সামলানোর জন্য তৈরি.
প্রথমত, Pando প্রতিটি শাখার হালনাগাদ আলাদাভাবে সমন্বয় করে. সম্পর্কহীন শাখার হালনাগাদ সমান্তরালে চলতে পারে, আর কোনো শাখা ফেচ করা পাঠক সেই সংস্করণের প্রয়োজনীয় ইতিহাস পায়. এখানে ছাড় দিতে হয় এই জায়গায়: একাধিক শাখা দেখা কোনো পাঠক সেগুলোর ভিন্ন মুহূর্তের অবস্থা দেখতে পারে.
দ্বিতীয়ত, প্রতিটি ক্লায়েন্টের জন্য আলাদা প্যাকফাইল তৈরির বদলে Pando বিভিন্ন ফেচে প্যাকফাইল পুনর্ব্যবহার করে. প্যাকফাইল হলো একাধিক অবজেক্ট একসঙ্গে সংকুচিত করার Git-এর বিন্যাস. ক্লায়েন্টকে তার কাছে থাকা কিছু অবজেক্ট আবার ডাউনলোড করতে হতে পারে, তবে সার্ভার অল্প গণনাতেই একই বাইট অনেক ক্লায়েন্টকে দিতে পারে.
এই সিদ্ধান্তগুলোর ফলে আমরা বিভিন্ন শাখায় লেখার সক্ষমতা বাড়াতে এবং ক্যাশ থেকে পড়ার অনুরোধ মেটাতে পারি. এগুলো কীভাবে একসঙ্গে কাজ করে তা বুঝতে, প্রথমে দেখা যাক Git কীভাবে ইতিহাস সংরক্ষণ ও স্থানান্তর করে.
Git-কে রিপোজিটরির দুটি অংশ সমন্বিত রাখতে হয়: অবজেক্ট ও রেফারেন্স.
Git রিপোজিটরি ফাইলের নির্দিষ্ট সময়ের অবস্থা ও সেগুলোকে যুক্ত করা ইতিহাস অবজেক্টের গ্রাফ হিসেবে সংরক্ষণ করে. অবজেক্ট হতে পারে ব্লব, ট্রি, কমিট বা ট্যাগ. ব্লব একটি ফাইলের বিষয়বস্তু ধরে রাখে, আর ট্রি নামের সঙ্গে ব্লব বা অন্য ট্রি যুক্ত করে ডিরেক্টরি কাঠামো গঠন করে. কমিট একটি রুট ট্রি ও শূন্য বা একাধিক মূল কমিট নির্দেশ করে, এভাবে আপনার রিপোজিটরির ইতিহাস গড়ে ওঠে.
অবজেক্টের ধরন ও বিষয়বস্তুর হ্যাশ দিয়ে তাকে শনাক্ত করা হয়. অবজেক্ট অপরিবর্তনীয়ও: পরিবর্তিত ফাইল নথিভুক্ত করলে নতুন ব্লব তৈরি হয়, আর অপরিবর্তিত ফাইল ও ডিরেক্টরি বিদ্যমান অবজেক্ট পুনর্ব্যবহার করতে পারে.
শাখা ও ট্যাগ হলো রেফারেন্স বা “রেফ”, যা কমিট নির্দেশ করে. কোনো শাখায় কমিট করলে নতুন কমিট তৈরি হয় এবং সেটিকে নির্দেশ করতে শাখার রেফ হালনাগাদ হয়.
Git অবজেক্ট আইডি দিয়ে একে অন্যকে নির্দেশ করে: কমিট নির্দেশ করে ট্রি, আর ট্রি নির্দেশ করে অন্য ট্রি ও ব্লব. refs/heads/main শাখাটি কমিট C2 নির্দেশ করে, যার মূল কমিট C1. C1 রুট ট্রি T1 নির্দেশ করে, যেখানে parser.py ব্লব B1-কে নির্দেশ করে. C2 রুট ট্রি T2 নির্দেশ করে, যেখানে parser.py ব্লব B2-কে নির্দেশ করে. উভয় রুট ট্রিতে docs/ একই ট্রি T3-কে নির্দেশ করে. এর README.md এন্ট্রি ব্লব B3 নির্দেশ করে, আর usage.md নির্দেশ করে ব্লব B4.
Git অবজেক্টকে হয় “আলাদা”, নয়তো “প্যাকবদ্ধ” অবস্থায় সংরক্ষণ করে. আলাদা অবজেক্টগুলো নিজ নিজ অবজেক্ট আইডি দিয়ে শনাক্ত করা পৃথক ফাইলে রাখা হয়. প্যাকবদ্ধ অবজেক্টগুলো একটি প্যাকফাইলে একসঙ্গে থাকে. ফলে একই ধরনের অবজেক্টকে পরস্পরের তুলনায় পার্থক্য হিসেবে সংরক্ষণ করা যায়.
Git ব্লবগুলো আলাদা ফাইলে রাখতে পারে, অথবা একটি ব্লবকে আরেকটির তুলনায় পার্থক্য হিসেবে এনকোড করে একসঙ্গে প্যাক করতে পারে.
Git-এ কোনো কমিট থেকে তার মূল কমিট, ট্রি ও ব্লবের লিংক ধরে কোনো অবজেক্ট খুঁজে পাওয়া গেলে, সেটি ওই কমিট থেকে পৌঁছানো যায় এমন অবজেক্ট. ফেচের সময় ক্লায়েন্ট সার্ভারকে জানায়, কোন কমিট সে চায় এবং কোনগুলো তার কাছে ইতিমধ্যে আছে. সার্ভার চাওয়া কমিটগুলো থেকে পৌঁছানো যায় এমন অবজেক্ট খুঁজে বের করে, ক্লায়েন্টের কাছে আছে বলে জানা অবজেক্ট বাদ দেয় এবং বাকিগুলো প্যাকফাইলে পাঠায়. এই বিন্যাসই Git ডিস্কে ব্যবহার করে. পূর্ণ ক্লোন শুরু হয় কোনো অবজেক্ট ছাড়াই, তাই ক্লোন করা ইতিহাস থেকে পৌঁছানো যায় এমন সব অবজেক্ট এতে লাগে.
পুশ সার্ভারকে এক বা একাধিক রেফ হালনাগাদ করতে বলে উল্টো দিকে অবজেক্ট স্থানান্তর করে. সার্ভারের কাছে থাকা অবজেক্ট আবার না পাঠাতে ক্লায়েন্ট সার্ভারের ঘোষিত রেফগুলো ব্যবহার করে. তাই পাঠানো প্যাক বিদ্যমান অবজেক্টের ওপর নির্ভর করতে পারে: শুধু প্যাকটি পেলেই নতুন ইতিহাস পুনর্গঠন করা যায় না.
Git রিপোজিটরির প্রতিলিপি রাখার অর্থ হলো, একাধিক সার্ভারে অবজেক্ট ও রেফারেন্স—দুটিই উপলব্ধ রাখা. কোনো প্রতিলিপি রেফারেন্সের নতুন মান সরবরাহ করার আগে, সেই মান থেকে পৌঁছানো যায় এমন অবজেক্টগুলো সরবরাহ করতে সক্ষম হতে হবে. সেবাটিকে প্রতিযোগী রেফারেন্স হালনাগাদও সমন্বয় করতে হয়—অর্থাৎ যেসব পুশ একই শাখাকে একই পুরোনো অগ্রপ্রান্ত থেকে ভিন্ন নতুন কমিটে নিতে চায়. যেসব ব্যবস্থা রিপোজিটরির সব লেখার ওপর একটি সার্বিক ক্রম চাপায়, সেগুলোতে সম্পর্কহীন শাখার পুশও একে অন্যের জন্য অপেক্ষা করতে পারে.
Pando-র নকশা করার সময় Git দিয়ে সোর্স নিয়ন্ত্রণের সক্ষমতা বাড়ানোর প্রচলিত পদ্ধতিগুলো যাচাই করেছি. একটিতে তিন-পর্যায়ের কমিট (৩পিসি—একাধিক নোডে কমিট সমন্বয়ের প্রোটোকল) দিয়ে রিপোজিটরির প্রতিলিপিগুলোর রেফ হালনাগাদ সমন্বয় করা হয়. অন্যটিতে ব্লব ভান্ডারে থাকা যৌথ আগাম-লিখন লগ (ওয়াল—পরিবর্তন প্রয়োগের আগে তার লিখিত নথি) দিয়ে হালনাগাদের ক্রম নির্ধারিত হয়.
আমাদের অনুকরণ করা তিন-পর্যায়ের কমিট নকশায় Git সেবা বেশ কয়েকটি প্রতিলিপিতে রিপোজিটরির সম্পূর্ণ অনুলিপি রাখে. যেকোনো সার্ভার পুশ পেলে, আগত প্যাকফাইল অনুলিপি করে সব প্রতিলিপিতে সমান্তরালে পাঠায়. পুশ প্রকাশ করতে সংখ্যাগরিষ্ঠ প্রতিলিপিকে রেফ হালনাগাদ গ্রহণ করতে হয়. এই কাজ পরিচালনাকারী সার্ভারটি সমন্বয়ক. সমন্বয়ক ও অন্য প্রতিটি প্রতিলিপির মধ্যে কয়েক দফা যোগাযোগ লাগে.
রেফারেন্স হালনাগাদ গ্রহণ করতে প্রতিটি প্রতিলিপি নিজের রেফ অনুলিপি লক করে এবং সেটি এখনো ক্লায়েন্টের প্রত্যাশিত কমিট নির্দেশ করছে কি না যাচাই করে. এরপর সমন্বয়ক গ্রহণকারী প্রতিলিপিগুলোকে কমিট-পূর্ব বার্তা পাঠায়. সংখ্যাগরিষ্ঠ প্রতিলিপি কমিট-পূর্ব বার্তার প্রাপ্তিস্বীকার করলে সমন্বয়ক তাদের হালনাগাদ করতে বলে. এরপর যেকোনো হালনাগাদ প্রতিলিপি নিজের স্থানীয় রিপোজিটরি থেকে শাখার নতুন অগ্রপ্রান্ত ঘোষণা করতে পারে.
সম্পূর্ণ প্রতিলিপি রাখায় স্থানীয়ভাবে পড়ার অনুরোধ মেটানো যায় এবং ক্লায়েন্ট যে প্রতিলিপিই বেছে নিক, সব রেফারেন্সের সামঞ্জস্যপূর্ণ অবস্থা পাবে—এটি নিশ্চিত হয়. ফলে রেফারেন্সগুলো একটি করে হালনাগাদ হয়, আর প্রতিটি পুশে প্রতিলিপিগুলোর মধ্যে রেফ হালনাগাদ সমন্বয় করতে কয়েক দফা বার্তা আদান-প্রদান লাগে.
ন্যূনতম প্রয়োজনীয় সংখ্যক প্রতিলিপির সাড়ার অপেক্ষা করতে হওয়ায়, পুশের সময় প্রতিলিপির ডিস্কের কর্মক্ষমতা ও যোগাযোগের বিলম্বের ওপর নির্ভরশীল হয়. লেখার পরিমাণ বাড়লে প্রতিলিপিগুলোকে আগত প্যাক এবং পড়ার অনুরোধ—দুটির সঙ্গেই তাল মেলাতে হয়.
আমাদের অনুকরণ করা ওয়াল-ভিত্তিক নকশায় Git সেবা ব্লব ভান্ডারের একটি যৌথ ম্যানিফেস্ট দিয়ে রিপোজিটরিজুড়ে হালনাগাদের ক্রম নির্ধারণ করে. সার্ভার পুশ পেলে আগত প্যাকফাইল ব্লব ভান্ডারে আপলোড করে এবং রিপোজিটরির স্থানীয় অনুলিপিতে রেফ হালনাগাদ প্রস্তুত করে. পুশ প্রকাশ করতে এটি ব্লব ভান্ডারে রাখা যৌথ ম্যানিফেস্টে একটি এন্ট্রি যোগ করে, যা রেফ হালনাগাদ নথিভুক্ত করে এবং প্যাকফাইল নির্দেশ করে. এরপর Git সার্ভার তুলনা-ও-অদলবদল ক্রিয়া দিয়ে ম্যানিফেস্ট হালনাগাদ করে. এটি হয় অবিভাজ্যভাবে ম্যানিফেস্ট প্রতিস্থাপন করে, নয়তো পরিবর্তন প্রত্যাখ্যান করে. এর মধ্যে অন্য কোনো লেখক সেটি হালনাগাদ করে থাকলে, সার্ভার মাঝখানে যোগ হওয়া এন্ট্রিগুলো পড়ে, নিজের রেফ হালনাগাদ এখনো বৈধ কি না যাচাই করে এবং আগে আপলোড করা প্যাকফাইল দিয়েই আবার চেষ্টা করে.
লেখকেরা সমান্তরালে প্যাকফাইল আপলোড করতে পারে, তবে সম্পর্কহীন শাখায় পুশ করলেও একই ম্যানিফেস্ট হালনাগাদ করতে হয়. সফল তুলনা-ও-অদলবদলের পূর্ণ আদান-প্রদানে লাগা সময়ই সীমা নির্ধারণ করে দেয়, রিপোজিটরি কত ঘনঘন নতুন ম্যানিফেস্ট প্রকাশ করতে পারবে. কম বিলম্বের ব্লব ভান্ডার এই ধাপ দ্রুত করে. গুচ্ছবদ্ধ করলে একটি ম্যানিফেস্ট একই সঙ্গে একাধিক রেফ হালনাগাদ করতে পারে, তবে হালনাগাদগুলো সারিতে জমে এবং বিলম্ব বাড়ে.
ব্লব ভান্ডার সমান্তরালে প্যাকফাইল গ্রহণ করতে পারলেও যৌথ ম্যানিফেস্টের হালনাগাদগুলো তখনো পরস্পরের সঙ্গে প্রতিযোগিতা করে. শুধু ব্লব ভান্ডারের সক্ষমতা বাড়িয়ে এই বাধা দূর হয় না. স্থানীয়ভাবে প্যাক সরবরাহ করার আগে প্রতিটি প্রতিলিপিকে তখনো ব্লব ভান্ডার থেকে প্যাক পড়তে ও সূচিবদ্ধ করতে হয়. আগত লেখার গতি এই কাজকে ছাড়িয়ে গেলে প্রতিলিপিগুলো পিছিয়ে পড়ে, আর সদ্য পুশ করা কমিট ফেচ করতে ক্লায়েন্টকে বেশি অপেক্ষা করতে হয়.
এই প্রেক্ষাপটেই আসে Pando. Git রিপোজিটরি থেকে সেবা দেওয়ার নতুন স্থাপত্য Pando. এর লক্ষ্য হলো একসঙ্গে অনেক ক্লায়েন্টের পুশ সামলানোর সক্ষমতা বাড়ানো. এটি যেভাবে কাজ করে:
Pando তৈরির আগে আমাদের ধারণা ছিল, Git নিয়ে আপস না করেই আমাদের চাহিদা মেটানো সম্ভব. তবে বেশির ভাগ Git ব্যবস্থা যেসব বিষয়কে আবশ্যক ধরে নেয়, তার কয়েকটিতে ছাড় দিতে হয়েছে:
রিপোজিটরিজুড়ে সামঞ্জস্য: সব রেফের একটি নির্দিষ্ট মুহূর্তের সামঞ্জস্যপূর্ণ অবস্থা তুলে ধরতে পুরো রিপোজিটরিজুড়ে সমন্বয় প্রয়োজন. যে ব্যবস্থা সব রেফের হালনাগাদকে একসঙ্গে ক্রমানুসারে সাজায়, সেখানে সম্পর্কহীন শাখায় পুশও একই সমন্বয়কেন্দ্র ব্যবহারের জন্য প্রতিযোগিতা করে.
প্রতিটি ক্লায়েন্টের জন্য আলাদা প্যাকফাইল: ভিন্ন স্থানীয় ইতিহাস থাকা দুটি ক্লায়েন্ট একই শাখা ফেচ করলে, তাদের কাছে ইতিমধ্যে থাকা অবজেক্ট আবার না পাঠাতে সার্ভারকে প্রত্যেকের জন্য আলাদা প্যাক তৈরি করতে হতে পারে. এই প্রতিক্রিয়াগুলো তৈরি করতে সিপিইউ ও ডিস্কে ইনপুট/আউটপুট লাগে, ফলে বিপুলসংখ্যক পাঠককে সেবা দেওয়ার সক্ষমতা বাড়ানো কঠিন হয়.
এর বদলে, লেখার সক্ষমতা বাড়াতে Pando শিথিল সামঞ্জস্যের একটি পদ্ধতি (কার্যকারণভিত্তিক সামঞ্জস্য) দেয় এবং পড়ার সক্ষমতা বাড়াতে প্যাকফাইল পুনর্ব্যবহার করে.
ক্লায়েন্ট কোনো শাখায় পুশ করলে, Pando আগত প্যাকফাইলকে অপরিবর্তনীয় ব্লব হিসেবে একটি ব্লব ভান্ডারে রাখে. শাখা যতবার এগোয়, Pando ততবার মেটাডেটা ভান্ডারে একটি রেফ সংস্করণ নথিভুক্ত করে. এতে থাকে নতুন অগ্রপ্রান্ত, সেটি সরবরাহকারী প্যাক এবং প্যাকটি যেসব আগের রেফ সংস্করণের ওপর নির্ভর করে. ব্লব ভান্ডার ও মেটাডেটা ভান্ডার—উভয়ের সক্ষমতাই সমান্তরালে আরও একক যোগ করে বাড়ানো যায়.
Pando থেকে কমিট বা রেফারেন্স ফেচ করতে ক্লায়েন্টে একগুচ্ছ রেফ সংস্করণ (প্যাকফাইল) পুনরায় প্রয়োগ করতে হয়. এতে ফেচ করা রেফ সংস্করণটি যে ক্লায়েন্ট তৈরি করেছিল, তার অবস্থা পুনর্গঠিত হয়. এতে পুরো রিপোজিটরিজুড়ে অপেক্ষাকৃত দুর্বল সামঞ্জস্য পাওয়া যায়, তবে প্রতিটি রেফের হালনাগাদ ধারাবাহিকভাবে সম্পন্ন হওয়ার সমতুল্য ফল নিশ্চিত হয়. শুধু একই রেফে একসঙ্গে পুশ করলেই ক্লায়েন্টগুলোর মধ্যে সংঘাত হয়. একাধিক শাখা পড়া কোনো ক্লায়েন্ট ধরে নিতে পারে না যে সেগুলো রিপোজিটরির একই মুহূর্তের অবস্থা দেখাচ্ছে.
ট্রাঙ্কে পুশ করলে এক বা একাধিক কমিটসহ একটি বর্ধিত প্যাক যোগ হয়. পার্শ্বশাখায় প্রতিটি পুশে টপিক শাখার আগের কমিটগুলো আবার অন্তর্ভুক্ত হয়, ফলে ঘোষিত ট্রাঙ্ক সংস্করণ থাকা ক্লায়েন্ট একটি প্যাকেই টপিক শাখাটি ফেচ করতে পারে.
এটি কার্যকারণভিত্তিক সামঞ্জস্যের একটি রূপ. একটি রেফারেন্স ফেচ করতে পাঠককে সেটির লেখকের ইতিহাস দেখতে হয়. পুশের সময় ক্লায়েন্ট ও সার্ভার কোন অভিন্ন ইতিহাসে একমত হবে, তা Pando নিয়ন্ত্রণ করে. এতে ক্লায়েন্টের তৈরি প্যাকফাইল আরও সহজে অন্যদেরও দেওয়া যায়.
ফলে Git-এর কাজ চলাকালে Pando সব রেফারেন্সের একই মুহূর্তের অবস্থা দেয় না, কিংবা ক্লোন বা ফেচের মধ্যে রেফ হালনাগাদের কোনো সার্বিক ক্রমও দেয় না. উদাহরণ হিসেবে ধরা যাক, একটি পূর্ণ ক্লোনের সমঝোতা প্রক্রিয়া চলার সময় foo ও bar—দুটি শাখাই হালনাগাদ হলো. সমঝোতার সময় একটি ক্লায়েন্ট foo-এর সংস্করণ ১ ও bar-এর সংস্করণ ২ দেখতে পারে, আর অন্যটি দেখতে পারে foo-এর সংস্করণ ২ ও bar-এর সংস্করণ ১. বাস্তবে ব্যবহারকারী ও এজেন্টরা রেফ হালনাগাদের সার্বিক ক্রমের ওপর নির্ভর করে না; তারা নির্ভর করে একটি নির্দিষ্ট রেফারেন্সের হালনাগাদের ক্রমের ওপর.
তিনটি সামঞ্জস্য পদ্ধতির এই সিমুলেশনে আমরা ১,০০০ ক্লায়েন্টকে প্রত্যেকে আলাদা শাখা বেছে নিয়ে বারবার স্বতন্ত্র কমিট পুশ করার ব্যবস্থা করেছি. তারপর মোট অতিবাহিত সময় ও পুশ থেকে ফেচ পর্যন্ত বিলম্ব মেপেছি. শেষের পরিমাপটি কাজের চাপ মূল্যায়নে গুরুত্বপূর্ণ, কারণ ব্যবহারকারী ও এজেন্টদের সহযোগিতা করতে বা সংস্করণ নিয়ন্ত্রণনির্ভর অন্য ব্যবস্থা ব্যবহার করতে কত সময়ে একটি পূর্ণ আদান-প্রদান সম্পন্ন হয়, তা এটি মাপে. এই সিমুলেশনে সাধারণ থেকে উচ্চমানের ভার্চুয়াল মেশিন ও ব্লব সংরক্ষণব্যবস্থার হার্ডওয়্যার অনুকরণ করা হয়েছে. এই সিমুলেশনে তিন-পর্যায়ের কমিটের জন্য রিপোজিটরিজুড়ে সামঞ্জস্যের শর্ত শিথিল করেছি.
Simulating Git Server Implementations
Follow each writer through repeated pushes, and separately measure when an independent reader can check out each commit.
আরও দুটি পদ্ধতির সঙ্গে Pando-র তুলনা করতে এই সিমুলেশন চালান. সাধারণ থেকে উচ্চমানের হার্ডওয়্যারের অবকাঠামো, ক্লায়েন্টের সংখ্যা ও অন্যান্য সেটিং বেছে নিয়ে তুলনা দেখুন.
অনুকরণ করা তিন-পর্যায়ের কমিট ব্যবস্থায় চাপ বাড়লে ডিস্কের পূর্ণ সক্ষমতা ব্যবহৃত হওয়ায় লেখার বিলম্ব অনেক বেড়ে যায়. একই কারণে আগাম-লিখন লগ ব্যবস্থায় পড়ার বিলম্ব অনেক বাড়ে, কারণ সার্ভারগুলো জার্নাল পড়ার চাহিদার সঙ্গে তাল মেলাতে হিমশিম খায়. আমাদের মনোরিপোতে বাস্তব পরীক্ষা এবং এই সিমুলেশন—উভয় ক্ষেত্রেই Pando চাপের মধ্যে কর্মক্ষমতা অক্ষুণ্ণ রেখে একসঙ্গে কয়েক হাজার ক্লায়েন্টের পুশ সমর্থন করে.
পুশ প্রক্রিয়াকরণের সময় Pando আগত প্যাকফাইল স্থানীয় রিপোজিটরিতে না খুলেই ব্লব ভান্ডারে ধারাবাহিকভাবে পাঠানোর পাশাপাশি যাচাই করে. ক্লায়েন্ট ফেচ শুরু করলে Pando পাঠকের প্রয়োজনীয় সংরক্ষিত প্যাকগুলো বেছে দেয়, আর পাঠক সেগুলো ডাউনলোড করে. কোনো সার্ভারকেই স্থানীয় রিপোজিটরিতে প্যাকফাইল প্রয়োগ করতে বা ব্যয়বহুল প্যাক খোলা ও তৈরির কাজ করতে হয় না. এই সার্ভারগুলো মূলত সমঝোতা ও প্যাকফাইল নির্বাচনের কাজ করে বলে Pando সার্ভার সাধারণ হার্ডওয়্যারেই চলতে পারে.
ফলে ক্লায়েন্ট, ক্লায়েন্ট ও Pando-র মধ্যকার নেটওয়ার্ক এবং ব্লব সংরক্ষণসেবার সর্বোচ্চ সক্ষমতা পর্যন্ত Pando-র সক্ষমতা বাড়ানো যায়. পর্যাপ্ত সক্ষমতা থাকলে স্বাধীন শাখায় কাজ করা প্রতিটি ক্লায়েন্ট নিজের সংযোগের সর্বোচ্চ গতিতে প্যাক স্থানান্তর করতে পারে. একই গতিতে আরও ক্লায়েন্টকে সেবা দিতে আমরা Pando সার্ভার যোগ করতে পারি এবং পাশাপাশি মেটাডেটা ও ব্লব ভান্ডারের সক্ষমতা বাড়াতে পারি.
Pushing and Fetching a Branch in Pando
Pando stores the writer’s packfile in blob storage and records the ref version in metadata service. On fetch, Pando selects the packs the reader needs, and Express serves them.
একটি এজেন্ট স্থানীয়ভাবে ফাইল সম্পাদনা ও কমিট তৈরি করে git push চালায়. এতে শাখা হালনাগাদের জন্য পরিবর্তনগুলো নিয়ে একটি প্যাকফাইল তৈরি হয়. Pando প্যাক গ্রহণ করে সেটি ধারাবাহিকভাবে ব্লব ভান্ডারে পাঠায়. একবার ডিকোড করেই আগত পুশ যাচাই করার পর Pando একাধিক কী-ভিত্তিক লেনদেন ব্যবহার করে মেটাডেটা ভান্ডারে রেফ সংস্করণ নথিভুক্ত করে এবং অবিভাজ্যভাবে রেফ পয়েন্টার হালনাগাদ করে. এর ফলে Pando “নিজের লেখা তথ্য নিজেই পড়তে পারার” সামঞ্জস্য নিশ্চিত করতে পারে. এই পুরো লেখার কাজে সংখ্যক মেটাডেটা পড়া ও লেখা প্রয়োজন.
অন্য কোনো ক্লায়েন্ট শাখাটি ফেচ করলে, তার কাছে ইতিমধ্যে থাকা ইতিহাস ব্যবহার করে Pando একগুচ্ছ সংরক্ষিত প্যাক বেছে নেয়. এই কাজে সংখ্যক মেটাডেটা পড়তে হয়, যেখানে হলো ক্লায়েন্টের কাছে যা আছে এবং সে যা চায়, তার মধ্যে রেফ সংস্করণে মাপা সর্বনিম্ন দূরত্ব. সার্ভার প্যাকফাইলের ইউআরআই ফেরত দেয়, আর ক্লায়েন্ট Express নামের একটি সেবার মাধ্যমে সেগুলো ডাউনলোড করে. সেবাটি আঞ্চলিক ক্যাশে প্যাকফাইল রাখে.
এই নকশা Pando-র স্থাপত্যের তিনটি কেন্দ্রীয় সেবার ওপর নির্ভর করে: পুশ, ফেচ ও সংকোচন.
ক্লায়েন্ট পুশ করলে প্রচলিত Git সার্ভার যেন পোকার খেলোয়াড়ের মতো নিজের সব তাস দেখিয়ে দেয়—তার কাছে থাকা প্রতিটি শাখা ক্লায়েন্টকে জানায়. এরপর ক্লায়েন্ট কমিট, ট্রি ও ব্লব জড়ো করে প্যাকফাইল বানায়. সার্ভারের কাছে ইতিমধ্যে আছে বলে জানা অবজেক্টগুলো এতে বাদ দেয়.
বেশি রেফ ঘোষণা করলে পুশের আকার ছোট হতে পারে. আবার এতে প্যাক পুনর্ব্যবহার কঠিনও হতে পারে, কারণ লেখক যে অবজেক্ট বাদ দিয়েছে, অন্য ক্লায়েন্টের কাছে তা না-ও থাকতে পারে.
Pando ভিন্ন পদ্ধতি অনুসরণ করে. সব তাস দেখানোর বদলে এটি ক্লায়েন্টের কাছে শুধু বাছাই করা কয়েকটি শাখা ঘোষণা করে. দুটি কারণে এমন করা হয়:
প্রতিটি রেফের সামঞ্জস্যপূর্ণ অবস্থা দেখানো ব্যয়বহুল. লাখ লাখ শাখা থাকলে শুধু রেফ ঘোষণার আকারই ১০০ মেবিবাইট ছাড়িয়ে যেতে পারে. এটি করতে প্রতিটি সার্ভারকে হয় হালনাগাদ ম্যাপিং রাখতে হয়, যার সমন্বয়ে উল্লেখযোগ্য বাড়তি কাজ লাগে; নয়তো এমন ডেটাবেস অনুসন্ধান চালাতে হয়, যার কাজ রেফের সংখ্যার সঙ্গে বাড়ে.
ক্লায়েন্টকে রেফের কেবল একটি অংশ জানালে, তার তৈরি প্যাক শুধু সেই তথ্যের ওপর নির্ভর করবে, যা বাদ দেওয়ার অনুমতি সার্ভার স্পষ্টভাবে দিয়েছে. নির্ভরতাগুলো নথিবদ্ধ রাখায় Pando একটি পুশে ক্লায়েন্টের তৈরি প্যাকফাইল পরবর্তী ফেচের উত্তরে দিয়ে পুনর্ব্যবহার করতে পারে.
Git সার্ভার যত বেশি রেফ ঘোষণা করে, পুশ করা ক্লায়েন্ট তত বেশি উৎসের অবজেক্ট বাদ দিতে পারে, ফলে আরও ছোট প্যাক তৈরি হয়. তবে এই প্যাকফাইল পুনর্ব্যবহার করতে সার্ভারকে নিশ্চিত করতে হয় যে ফেচ করা ক্লায়েন্টগুলোর কাছে প্রতিটি নির্ভরতা রয়েছে. নইলে প্যাকফাইলে ক্লায়েন্টের প্রয়োজনীয় অবজেক্ট বাদ পড়তে পারে.
অন্যদিকে, Git সার্ভার কোনো রেফই ঘোষণা না করলে ক্লায়েন্ট রিপোজিটরির পুরো ইতিহাসসহ প্যাকফাইল তৈরি করবে. অন্য যেকোনো ক্লায়েন্ট সেই প্যাকফাইল ব্যবহার করতে পারবে, কিন্তু বড় অসুবিধা হলো, যেকোনো শাখা ফেচ করাই কার্যত পূর্ণ ক্লোনে পরিণত হবে.
বেশি রেফ ঘোষণা করলে প্যাকফাইল ছোট হয়. মাত্র একটি রেফ ঘোষণা করেই আকারের বেশির ভাগ হ্রাস ঘটতে পারে.
পূর্বনির্ধারিতভাবে, ক্লায়েন্ট নতুন ফিচার শাখা পুশ করলে Pando ভিত্তি হিসেবে শুধু একটি নির্ধারিত ট্রাঙ্ক শাখা ঘোষণা করে. এতে রিপোজিটরিতে শাখা বাড়লেও ঘোষণার আকার একই থাকে, তবে কিছু ছাড় দিতে হয়. কোনো প্রকৌশলী একই শাখায় বহুবার পুশ করলে বা একটি ফিচার শাখার ওপর আরেকটি তৈরি করলে, ক্লায়েন্টকে ট্রাঙ্কের বাইরের সবকিছু আবার পাঠাতে হয়.
ফলে শাখায় পরপর পুশগুলোর আকার বাড়ে, সম্ভাব্য অপ্রয়োজনীয় পুনরাবৃত্ত অবজেক্ট থাকে এবং ক্লায়েন্টের বাড়তি ব্যান্ডউইডথ লাগে. আমাদের মনোরিপোতে এভাবে তৈরি প্যাকফাইলের মধ্যক আকার ছিল ২০ কিবিবাইটের নিচে, আর ৯৯তম পার্সেন্টাইল ছিল ৩ মেবিবাইটের নিচে. আমাদের জন্য এই ছাড় দেওয়া যুক্তিসংগত ছিল, কারণ ঘোষিত ট্রাঙ্কের ইতিহাস থাকা পাঠক ওই একটি প্যাকফাইল দিয়েই শাখা ফেচ করতে পারে.
ক্লায়েন্টের কাছে কোন রেফগুলো ঘোষণা করা হবে তা বেছে নেওয়ার পর Pando পুশ গ্রহণ করে এবং মেটাডেটা ভান্ডার হালনাগাদ করে. Pando মেটাডেটা হালনাগাদকে তাৎক্ষণিকভাবে সম্পন্ন করার অংশ ও পরে আলাদাভাবে সম্পন্ন করার অংশে ভাগ করে. তাৎক্ষণিক মেটাডেটা হালনাগাদ নিশ্চিত করে যে ক্লায়েন্ট সদ্য হালনাগাদ হওয়া কমিট সঙ্গে সঙ্গে ফেচ করতে পারে. এতে নতুন রেফ সংস্করণ লেখা হয় এবং রেফ পয়েন্টারের ম্যাপিং সেই সংস্করণে হালনাগাদ হয়. সংরক্ষিত থাকে নতুন অগ্রপ্রান্ত, প্যাকফাইল নিয়ে সমঝোতায় ব্যবহৃত নির্ভরতা ও পুশ করা প্যাকফাইলের লিংক.
একই সঙ্গে, পরে আলাদাভাবে সম্পন্ন করার কাজও একই লেনদেনে নথিভুক্ত হয়, যেমন সংকোচনের কাজ নির্ধারণ. খুব বড় পুশের ক্ষেত্রে কমিটগুলোর কেবল একটি অংশ তাৎক্ষণিকভাবে লেখা হয়. ফলে পুশের আকার যা-ই হোক, মেটাডেটা ভান্ডারে পড়া ও লেখার সংখ্যা ধ্রুব রাখা যায়.
গুরুত্বপূর্ণ বিষয় হলো, Pando সার্ভারগুলো সম্পর্কহীন রেফে পুশ স্বাধীনভাবে গ্রহণ করতে পারে. একমাত্র রেফ পয়েন্টার কী নিয়ে প্রতিযোগিতা হয়, যেটি আমরা তুলনা-ও-অদলবদলের মতো একটি অবিভাজ্য ক্রিয়া দিয়ে সুরক্ষিত রাখি. Pando সার্ভার, মেটাডেটা ভান্ডারের সক্ষমতা বৃদ্ধির একক বা ব্লব ভান্ডার যোগ করে আমরা লেখার থ্রুপুট বাড়াতে পারি.
ফেচ করার সময় ক্লায়েন্ট সার্ভারকে দুই সেট কমিট আইডি দেয়, যা প্রোটোকলে have ও want নামে পরিচিত. প্রচলিত Git সার্ভারে, ক্লায়েন্টের থাকা কমিটগুলো থেকে পৌঁছানো যায় এমন অবজেক্ট এবং চাওয়া কমিটগুলো থেকে পৌঁছানো যায় এমন অবজেক্টের সেটের পার্থক্য গণনা করা হয়. তারপর পার্থক্যের অবজেক্টগুলো সংকুচিত করে ক্লায়েন্টকে পাঠানো হয়. উন্মুক্ত সোর্সের Git সার্ভারে এই কাজ দ্রুত করার জন্য নানা স্থানীয় সূচি থাকলেও প্যাকফাইলগুলো তৈরির গণনা ব্যয়বহুল হতে পারে এবং সাধারণত এগুলো ক্যাশে রাখা কার্যকর হয় না.
এর বদলে Pando পুশের সময় নথিভুক্ত কমিট ম্যাপিং দিয়ে ক্লায়েন্টের have ও want খোঁজে এবং কমিটগুলো থাকা রেফ সংস্করণগুলোর সঙ্গে সেগুলো মেলায়. ওই প্রতিটি রেফ সংস্করণ Pando-র আগে গ্রহণ করা একটি প্যাকফাইলের সঙ্গে যুক্ত. সার্ভার এই তথ্য দিয়ে ক্লায়েন্টের প্রয়োজন নির্ধারণ করে এবং তার প্রয়োজনীয় সব অবজেক্ট থাকা প্যাকফাইলগুলো বেছে নেয়.
Planning fetches in Pando
Pando compares what a client has with what it wants, then selects the stored packfiles needed—including any missing branch dependencies.
Fetch 27 trunk packs.
Select a branch to include its trunk dependencies.
Pando Git প্রোটোকলে থাকা ও চাওয়া কমিটগুলোকে রেফ সংস্করণের একটি ক্রমের সঙ্গে মেলায়. পার্শ্বশাখা চাইলে ট্রাঙ্কে তার নির্ভরতার অংশগুলো পর্যন্তও প্রয়োজন হয়.
ক্লোন বা ফেচের এইচটিটিপি প্রতিক্রিয়ায় Git প্রোটোকল কেবল একটি প্যাকফাইল পাঠানোর অনুমতি দেয়. তবে Git প্রোটোকলের কম আলোচিত একটি সুবিধা, packfile-uri, সার্ভারকে বাড়তি প্যাক আলাদাভাবে ডাউনলোড করার লিংক ফেরত দিতে দেয়. Pando শুধু এই পদ্ধতিই ব্যবহার করে এবং মূল প্রতিক্রিয়ার ভেতরে একটি খালি প্যাকফাইল পাঠায়. এই সুবিধার সহায়তায় OpenAI মূল প্রকল্পে packfile-uri-এর বেশ কিছু উন্নতি যোগ করেছে.
OpenAI-এর ব্যবস্থাগুলো বহু ভৌগোলিক অঞ্চলে চলে, তাই প্রতিটি অঞ্চলে আমরা স্থানীয় ক্যাশসহ Pando ক্লাস্টার রাখি. Express নামের প্যাক সরবরাহসেবা আমাদের ব্লব ভান্ডারের তথ্য ক্যাশ করে, আর আলাদা একটি সেবা মেটাডেটা ভান্ডারের তথ্য ক্যাশ করে. এই ক্যাশগুলোর সাহায্যে Pando কমিট আইডির অনুরোধ বা রেফ পড়ার বিশেষ অনুরোধ পুরোপুরি ওই ক্লাস্টারের ক্যাশে থাকা তথ্য থেকেই মেটাতে পারে. প্যাকফাইলের অনুরোধ Express সার্ভারে পাঠাতে আমরা সামঞ্জস্যপূর্ণ হ্যাশিং ব্যবহার করি; ক্যাশেই তথ্য পাওয়ার হার ৯৯%-এর বেশি.
এই ক্যাশব্যবস্থা অত্যন্ত উচ্চ থ্রুপুট দেয়, যা ক্লায়েন্ট ও Pando-র মধ্যকার নেটওয়ার্কের পূর্ণ সক্ষমতা ব্যবহার করতে পারে. এই প্যাকফাইল ইউআরআই ও স্থানীয় ক্যাশ ব্যবহার করে আমরা যাচাই করেছি যে ক্লাউড সরবরাহকারীর শুধু সাধারণ ভার্চুয়াল মেশিন দিয়েই ক্লোন ও ফেচে ১০ গিগাবিট/সেকেন্ড নেটওয়ার্ক সংযোগের পূর্ণ সক্ষমতা ব্যবহার করা যায়.
বেশির ভাগ Git সার্ভারে বাড়তে থাকা রিপোজিটরির কর্মক্ষমতা বজায় রাখতে পুনরায় প্যাক তৈরি ও অব্যবহৃত ডেটা অপসারণ প্রয়োজন. দুটি ধাপেই জায়গা খালি হয়, তবে প্রচুর গণনা ও ইনপুট/আউটপুট লাগে.
OpenAI-এর মনোরিপোর মতো দ্রুত পরিবর্তনশীল রিপোজিটরিতে, শেষ ফেচের পর হওয়া প্রতিটি পুশের জন্য আলাদা প্যাকফাইল ইউআরআই পাঠানো বাস্তবসম্মত নয়. প্রতিদিন ট্রাঙ্ক হালনাগাদ রাখতে একটি ক্লায়েন্টকে কয়েক দশ হাজার প্যাকফাইল ডাউনলোড করতে হতো.
এর বদলে Pando পটভূমিতে প্যাক একত্র করে এই বাড়তি কাজ কমায়. এর নকশা লগ-কাঠামোভিত্তিক মার্জ ট্রির সংকোচন পদ্ধতির অনুরূপ. প্রতিটি পুশ একটি প্যাকফাইল তৈরি করে, যাকে Pando বলে “L0”. এটিই Pando-র পাঠানো ডেটার ক্ষুদ্রতম একক. সময়ের সঙ্গে পটভূমির কর্মপ্রক্রিয়াগুলো এই প্যাকফাইলকে পরপর কয়েকটি রেফ সংস্করণজুড়ে বিস্তৃত আচ্ছাদনে একত্র করে. L0 থেকে এগুলোর আকার জ্যামিতিক হারে বাড়ে. বর্তমানে আমাদের মনোরিপোতে L4 পর্যন্ত প্যাকফাইল আচ্ছাদন ব্যবহৃত হয়.
এই আচ্ছাদনগুলোর দুটি কাজ. কোনো আচ্ছাদন যথেষ্ট পূর্ণ হলে, একটি সংকোচন কর্মপ্রক্রিয়া সেটির দায়িত্ব নিয়ে একটিমাত্র প্যাকফাইল তৈরি করে. এতে প্যাকফাইলের ভেতরের অবজেক্ট পুনর্বিন্যস্ত হওয়ায় সংকোচনের অনুপাত উন্নত হয়. পাশাপাশি রেফ সংস্করণগুলোর ওপর ধাপ এড়িয়ে চলার তালিকা হিসেবে কাজ করে এটি ফেচের সমঝোতা প্রক্রিয়াও দ্রুত করে. প্রতিটি স্তরের সূচি একই সঙ্গে খুঁজে Pando লগারিদমিক সময়ে ক্লায়েন্টকে পাঠানোর প্যাকগুলো বেছে নিতে পারে. পুনরায় প্যাক করা হোক বা না হোক, এই প্যাকফাইল আচ্ছাদনগুলো ফেচ পরিকল্পনার আরও দক্ষ সমাধান দেয়, ফলে Pando-র থ্রুপুট ও বিলম্ব—উভয় সংক্রান্ত চাহিদাই কমে.
Compaction in Pando
Small packfiles are grouped into larger covers across levels, improving compression and speeding up fetches.
সংকোচন পটভূমিতে অনেক রেফ সংস্করণের প্যাকফাইল একত্র করে, ফলে কম ফাইল দিয়ে আরও দক্ষভাবে ফেচ করা যায়.
অনেক Git সার্ভারের বিপরীতে, এখানে প্রতিটি স্তরের প্যাকফাইল রেখে দেওয়া হয়; সেগুলো ফেলে দেওয়া বা অব্যবহৃত ডেটা হিসেবে সরানো হয় না. ক্লায়েন্ট ফেচের সময় যে have ও want জানায়, তার ভিত্তিতে প্রতিটি স্তরের প্যাক নিয়মিত সেবা দিতে ব্যবহৃত হয়. আর Pando-কে এপিআই হিসেবে ব্যবহার করা ক্লায়েন্টের ক্ষেত্রে, প্যাকফাইল থেকে যেকোনো অবজেক্ট পড়তে সাধারণত L4-এর তুলনায় L0 থেকে কম ডেটা পড়তে হয়, কারণ L0-তে সেটি সংকুচিত থাকার সম্ভাবনা কম.
Pando-র সংকোচন ক্লায়েন্টকে পাঠানো মোট ডেটার আকার অনেক কমায়. একই সঙ্গে ক্লায়েন্ট যতটা পিছিয়ে থাকে, তার তুলনায় প্যাক পরিকল্পনার কাজ সরলরৈখিকের চেয়েও কম হারে বাড়ে. বড় ও দ্রুত পরিবর্তনশীল রিপোজিটরির জন্য এটি বিশেষ গুরুত্বপূর্ণ; আমাদের ধারণা, সফটওয়্যার উন্নয়নে এমন রিপোজিটরিই নতুন স্বাভাবিক হয়ে উঠবে.
Codex দিয়ে আমরা Pando তৈরি করেছি—শুরু থেকে বাস্তব ব্যবহারে নিয়ে যেতে সময় লেগেছে মাত্র ১০ সপ্তাহ. Pando-র মূল অংশের নকশা করেছেন একজন প্রকৌশলী, বাস্তবায়ন করেছে এজেন্টদের দল, আর চালু করেছেন হাতে গোনা কয়েকজন প্রকৌশলী. এ বছরের এপ্রিলে Pando বাস্তব ব্যবহারের অনুরোধ সামলাতে শুরু করে. এটি OpenAI-এ ব্যবহৃত সোর্স নিয়ন্ত্রণ ব্যবস্থাপনার সরঞ্জামসমষ্টির একটি অংশ.
Pando-র নকশা যাচাই করতে আমরা নানা পদ্ধতি ব্যবহার করেছি. আমরা আরও নিরাপদ সফটওয়্যারের ভিত্তি গড়ার নীতিগুলো প্রয়োগ করেছি. একেবারে নতুন প্রকল্প হওয়ায় আমরা পুরোনো নির্ভরতা ছাড়াই Rust-এ Pando বাস্তবায়নের সিদ্ধান্ত নিয়েছি. এজেন্টরা যেন Git-এর মানক আচরণের সঙ্গে নিজেদের পরিবর্তন মিলিয়ে পরীক্ষা করতে পারে, সে জন্য আমরা সামঞ্জস্য যাচাইয়ের পরীক্ষাসমষ্টি লিখেছি. আমরা নির্ধারিত ফলদায়ী সিমুলেশন পরীক্ষার কার্যপরিধিও তৈরি করেছি, যাতে ব্যবস্থার অপরিবর্তনীয় শর্ত ও বৈশিষ্ট্য যাচাই করা যায়. এর সাহায্যে সমঝোতা ও প্যাক পরিকল্পনায় সূক্ষ্ম সমকালীন সংঘাত এবং আগের সক্ষমতার অবনতি শনাক্ত ও প্রশমিত করেছি.
অনেক মডেল এই ব্যবস্থায় অবদান রেখেছে. নতুন মডেল আসার সঙ্গে সঙ্গে আমরা সেগুলো দিয়ে Pando-র কর্মক্ষমতা ও নির্ভরযোগ্যতা বাড়িয়েছি. GPT‑6 Astra ব্যবহার করে এজেন্টরা Lean ও TLA+-তে “Pando-র তত্ত্ব” আনুষ্ঠানিকভাবে প্রকাশ করেছে. আমরা সেটি দিয়ে বাস্তবায়নের ত্রুটি খুঁজে সংশোধন করেছি এবং ব্যবস্থার বৈশিষ্ট্য প্রমাণ করেছি. Pando-র ব্যতিক্রমী পরিস্থিতি খুঁজে সংশোধন করতে একাধিক অবিচ্ছিন্ন সেশন শত শত ঘণ্টা চলেছে. Daybreak-সক্ষম মডেল দিয়ে Git ও Pando-র দুর্বলতা খুঁজতে আমরা দিনরাত এজেন্ট চালাই.
প্রথমে আমরা বিদ্যমান সোর্স নিয়ন্ত্রণব্যবস্থায় পড়া ও লেখা পৌঁছে দেওয়ার প্রক্সি হিসেবে Pando চালু করি. এতে Pando ও আগের ব্যবস্থা সমন্বিত রাখা সম্ভব হয়, ফলে সেবা বন্ধ না করেই নিরাপদে অনুরোধগুলো Pando-তে সরিয়ে নিতে পেরেছি.
ক্যাশিং নকশার অংশ হিসেবে Pando প্রক্সির মাধ্যমে পাঠানোর আগে পুনরাবৃত্ত অনুরোধ বাদ দিতে ও একাধিক অনুরোধ একত্র করতেও পারে. ফলে একবারে একটি করে ব্যবস্থা Pando-তে সরিয়ে নেওয়ার সময়ও বিদ্যমান সরঞ্জামগুলো সচল রাখতে পেরেছি. আরও কাজ Pando-তে সরিয়ে আনার সঙ্গে সঙ্গে সেগুলোর পুশে Pando-র ক্যাশ পূর্ণ হয়েছে এবং আগের ব্যাকএন্ডের নির্ভরযোগ্যতা বেড়েছে.
Pando ব্যবহারে সর্বোত্তম কর্মক্ষমতার জন্য আমরা ডেভেলপারদের মেশিনে ও ChatGPT ডেস্কটপ অ্যাপে Git-এর আমাদের সর্বজনীন সংস্করণ সরবরাহ শুরু করি. ক্লায়েন্টগুলোকে ধাপে ধাপে Pando-তে স্থানান্তর করতে আমরা Git-এর কমান্ড-লাইন ইন্টারফেস ঘিরে তৈরি একটি অভ্যন্তরীণ মোড়ক ব্যবহার করেছি. পরিবর্তনের অনুরোধ ও কোড পর্যালোচনা সামলানোর আরও অনেক সরঞ্জাম এবং স্বয়ংক্রিয় কাজের জন্য এপিআই তৈরি করেছি. Git-এর অনুরোধের পাশাপাশি পুরোনো এপিআই, ওয়েবহুক ও রিপোজিটরি ডাউনলোডনির্ভর শত শত সংযোগও স্থানান্তর করেছি.
এই স্থানান্তরে Codex নিজেই ডেভেলপার ও দলগুলোকে সাহায্য করেছে. বিদ্যমান চেকআউট প্রস্তুত করার এবং নতুন ব্যবস্থা ব্যবহারে এজেন্টদের পথ দেখানোর দক্ষতা তৈরি করেছি. ফলে ডেভেলপাররা শুধু Codex-কে বলেই তাঁদের উন্নয়ন পরিবেশ ও সেবা স্থানান্তর করাতে পেরেছেন.
Pando-তে যাওয়ার ফলে মার্জের নির্ভরযোগ্যতা বেড়েছে এবং পুশের মধ্যক বিলম্ব প্রায় ৮০% কমেছে.
মাত্র হাতে গোনা কয়েকটি সিপিইউ কোর দিয়ে Pando দিনে এক পেটাবাইট Git ডেটা সরবরাহ করতে পারে. Pando এক ঘণ্টায় ৫৭ টেরাবাইটেরও বেশি Git প্যাক সরবরাহ করেছে, যার ৯৯%-এর বেশি বাইট এসেছে স্থানীয় ডিস্ক ক্যাশ থেকে.
প্যাক পুনর্ব্যবহারের ফলে সরবরাহকারী নোডে অল্প গণনা করেই অনেক ক্লায়েন্ট একই রিপোজিটরির ইতিহাস ডাউনলোড করতে পারে. এই উদাহরণে একটি রিপোজিটরি দেখানো হয়েছে, তবে Pando আরও অনেক রিপোজিটরি সমর্থনের জন্য তৈরি. চাহিদা বাড়লে ডেটা সরবরাহ ও Git-এর সমঝোতা প্রক্রিয়ার সক্ষমতা আমরা আলাদাভাবে বাড়াতে পারি.
Git প্রোটোকল ও ক্লায়েন্টের ওপর Pando তৈরি করতে গিয়ে আমরা Git-এর নিজের ত্রুটি ও কর্মক্ষমতা উন্নয়নের সুযোগ শনাক্ত করেছি.
যেমন, Pando পুনর্ব্যবহারযোগ্য প্যাক সরাসরি ক্লায়েন্টকে দেয়. তাই এই প্যাক ডাউনলোড ও সূচিবদ্ধ করা ব্যবস্থাকে দ্রুত ও নির্ভরযোগ্য করে তোলার কেন্দ্রীয় অংশ হয়ে ওঠে. এই কাজে একসঙ্গে ডাউনলোড, বাধাপ্রাপ্ত স্থানান্তরের পর পরিষ্কার করা এবং ইতিমধ্যে সম্পন্ন ডাউনলোড আবার চালুর ক্ষেত্রে ব্যতিক্রমী সমস্যা ধরা পড়ে. আমরা ওই প্রক্রিয়াগুলো ঠিক করেছি, ফেচের জন্য বিদ্যমান প্যাক গ্রহণের সময় যাচাই যোগ করেছি এবং সেই কাজ মূল প্রকল্পে দিয়েছি.
সময় ও ব্যান্ডউইডথ কোথায় খরচ হচ্ছে, তা দেখাও দরকার ছিল. তাই packfile-uri ডাউনলোডের গতিবিধি অনুসরণ এবং প্যাক তৈরির বাইট গণনা যোগ করেছি. এতে ধীর ফেচের সময় প্যাক তৈরিতে যাচ্ছে, নাকি স্থানান্তরে—তা বোঝা সহজ হয়েছে.
OpenAI-এর Git বিল্ডে(একটি নতুন উইন্ডোতে খোলে) ক্লায়েন্ট স্বাধীন প্যাকগুলো সমান্তরালে ডাউনলোড ও সূচিবদ্ধ করতে পারে. আমরা “সুস্পষ্টভাবে থাকা কমিট”-এর ধারণা যোগ করেছি, যাতে সার্ভার কোনো শাখার বর্তমান অগ্রপ্রান্তকে সেই ইতিহাস থেকে আলাদাভাবে ঘোষণা করতে পারে, যা পুশ করা ক্লায়েন্ট তার প্যাক থেকে বাদ দিতে পারবে. Pando-তে এর ফলে ক্লায়েন্ট --force-with-lease দিয়ে ফিচার শাখার অবস্থান বদলায়নি বলে যাচাই করতে পারে এবং শুধু ট্রাঙ্কের ভিত্তিতে প্যাক বানাতে পারে. তারপর ট্রাঙ্কের ওই ইতিহাস থাকা যে কেউ একই প্যাক দিয়ে শাখাটি ফেচ করতে পারে.
এই উন্নতিগুলোর কয়েকটি ইতিমধ্যে মূল Git প্রকল্পে রয়েছে, আর অনেকগুলো রয়েছে আমাদের সর্বজনীন রিপোজিটরিতে. Pando-র বাইরেও উন্নতিগুলো কাজে লাগাতে আমরা Git সম্প্রদায়ের সঙ্গে কাজ চালিয়ে যাচ্ছি. আমাদের সর্বজনীন প্যাচ ট্র্যাকারে(একটি নতুন উইন্ডোতে খোলে) সেই কাজের অগ্রগতি দেখতে পারেন.
Git রিপোজিটরির সক্ষমতা বাড়ানোর প্রচলিত ধারণা নতুন করে বিবেচনা করে Pando আমাদের মনোরিপোর সক্ষমতা বাড়াতে সাহায্য করছে, প্রকৌশলী ও এজেন্টদের ব্যবহৃত Git কর্মধারা না বদলিয়েই. আমাদের মনোরিপোতে Pando আরও বেশি কাজ সমান্তরালে করার সুযোগ দিয়েছে, মার্জের নির্ভরযোগ্যতা বাড়িয়েছে এবং কোডের পরিবর্তন প্রকাশের সময় কমিয়েছে. মনোরিপোর বাইরেও OpenAI-এর ভেতরে Pando-র অন্য ব্যবহার খুঁজছি আমরা. এর মধ্যে রয়েছে এমন কাজ, যেখানে বিপুলসংখ্যক এজেন্টকে একটি যৌথ Git রিপোজিটরিতে সহযোগিতা করতে হয়.
প্রকৌশলী ও এজেন্টরা আরও বেশি সফটওয়্যার তৈরি করতে থাকলে, সোর্স নিয়ন্ত্রণে আমরা যে সীমায় পৌঁছেছি, OpenAI-এর বাইরেও আরও দল সেই সীমার মুখোমুখি হবে. Pando-কে সম্ভব করেছে যে প্রযুক্তি, তা ব্যবহারকারীদের সঙ্গে ভাগ করে নেওয়ার উপায় আমরা এখন খুঁজছি.
Git রিপোজিটরির ব্যবহারকারী ও পরিচালকদের দুই দশকের অভিজ্ঞতার ওপর ভিত্তি করে Pando গড়ে উঠেছে. আমরা Pando-র উন্নয়ন চালিয়ে যাব এবং উন্মুক্ত সোর্সের Git সম্প্রদায়ের সঙ্গে কাজ করে এমন উন্নতিগুলো সবার কাছে পৌঁছে দেব, যা বৃহত্তর পরিসরে Git ব্যবহারকারীদের উপকার করে.


