LLM সিস্টেমের জন্য RDMA পয়েন্ট-টু-পয়েন্ট যোগাযোগ
উদীয়মান LLM যোগাযোগের প্যাটার্নগুলি মোকাবেলার জন্য মার্জিত টুল
প্রশিক্ষণ এবং অনুমান প্রক্রিয়ায় কাঠামোগত সমান্তরাল প্যাটার্নের জন্য এলএলএম (LLM) সিস্টেমগুলো ঐতিহ্যগতভাবে যৌথ যোগাযোগের ওপর নির্ভর করে আসছে। তবে, উদীয়মান ওয়ার্কলোডগুলো, যেমন ডিসঅ্যাগ্রিগেটেড ইনফারেন্স, মিক্সচার-অব-এক্সপার্টস (MoE) রাউটিং, এবং অ্যাসিনক্রোনাস রিইনফোর্সমেন্ট লার্নিং ফাইন-টিউনিং, পয়েন্ট-টু-পয়েন্ট যোগাযোগের নমনীয়তা দাবি করে।
আমাদের সর্বশেষ গবেষণাপত্র TransferEngine উপস্থাপন করে, যা একটি বহনযোগ্য RDMA-ভিত্তিক যোগাযোগ লাইব্রেরি এবং NVIDIA ConnectX-7 ও AWS Elastic Fabric Adapter (EFA) সহ বিভিন্ন Network Interface Controller (NIC)-এর মধ্যে কাজ করে। আমরা Perplexity AI-তে তিনটি প্রোডাকশন সিস্টেমে এর কার্যকারিতা প্রদর্শন করেছি:
ডিসঅ্যাগ্রিগেটেড প্রিফিল এবং ডিকোড: পেজড রাইটস এবং UVM ওয়াচার ব্যবহার করে লেয়ার-বাই-লেয়ার KvCache স্থানান্তর, যা প্রিফিল এবং ডিকোড ইনস্ট্যান্সগুলোকে স্বাধীনভাবে স্কেল করতে দেয়।
২ সেকেন্ডের কম সময়ে RL পোস্ট-ট্রেনিংয়ের জন্য ওয়েট ট্রান্সফার: প্রশিক্ষণ এবং অনুমান নোডের মধ্যে অত্যন্ত দ্রুত ওয়েট সিনক্রোনাইজেশন।
AWS EFA-তে ট্রিলিয়ন-প্যারামিটার মডেল সক্ষম করা: স্ক্যাটার এবং ব্যারিয়ার প্রিমিটিভ ব্যবহার করে কম-ল্যাটেন্সি MoE ডিসপাচ এবং কম্বাইন অপারেশন, ConnectX-7-এ অত্যাধুনিক ল্যাটেন্সি এবং AWS EFA-এর সাথে সামঞ্জস্যপূর্ণ প্রথম কার্যকর বাস্তবায়ন অর্জন করা।
এই নিবন্ধটি TransferEngine-এর ওপর ফোকাস করে, যা এই সিস্টেমগুলোকে চালিতকারী যোগাযোগের লাইব্রেরি। arXiv-এ সম্পূর্ণ গবেষণা পত্রটি পড়ুন এবং GitHub-এ কোডটি অন্বেষণ করুন।
অনুপ্রেরণা
যৌথ যোগাযোগগুলো টেনসর প্যারালালিজম এবং ডেটা প্যারালালিজমের মতো কাঠামোগত সমান্তরাল প্যাটার্নে উৎকর্ষ সাধন করে, তবে তারা এমন কিছু সীমাবদ্ধতা আরোপ করে যা উদীয়মান ওয়ার্কলোডগুলিতে তাদের প্রযোজ্যতার পরিধি সীমিত করে:
নির্দিষ্ট সদস্যপদ: যৌথ যোগাযোগগুলোর জন্য প্রাথমিকীকরণের সময়ে একটি বৈশ্বিক যোগাযোগের জগৎ স্থাপন করা প্রয়োজন, যেখানে সমস্ত অংশগ্রহণকারীদের মধ্যে সিঙ্ক্রোনাইজড সেটআপ থাকে। ডিসঅ্যাগ্রিগেটেড ইনফারেন্সের জন্য এটি সমস্যাযুক্ত কারণ ট্র্যাফিক প্যাটার্নের প্রতিক্রিয়ায় প্রিফিল এবং ডিকোড ইনস্ট্যান্সের সংখ্যা গতিশীলভাবে স্কেল করতে হবে।
অভিন্ন টেনসর আকৃতি: যৌথ যোগাযোগগুলি ধরে নেয় যে সমস্ত অংশগ্রহণকারীরা অভিন্ন আকৃতি এবং ডেটা টাইপের টেনসর বিনিময় করে। MoE রাউটিং-এ, প্রতিটি এক্সপার্টের কাছে পাঠানো ডেটার পরিমাণ ডেটা-নির্ভর এবং রানটাইমে আবিষ্কৃত হয়, যা ঘন অল-টু-অল যৌথ যোগাযোগগুলোকে সবচেয়ে খারাপ অবস্থার বাফার সাইজে প্যাড করতে বাধ্য করে।
অপারেশন অর্ডারিং: যৌথ API গুলি সিঙ্ক্রোনাইজড সেমান্টিকস প্রয়োগ করে, এমনকি যখন অ্যাপ্লিকেশনগুলির কেবল এটি জানার প্রয়োজন হয় যে এক সেট অপারেশন সম্পন্ন হয়েছে। উদাহরণস্বরূপ, KvCache স্থানান্তরে, প্রিফিল ইনস্ট্যান্স থেকে ডিকোড ইনস্ট্যান্সের সমস্ত পেজ যেকোনো ক্রমে আসতে পারে। একইভাবে, RL ওয়েট আপডেটে, অর্ডারিং সীমাবদ্ধতা ছাড়াই সমস্ত ওয়েট টেনসর স্বাধীনভাবে স্থানান্তরিত হতে পারে।
RDMA-ভিত্তিক পয়েন্ট-টু-পয়েন্ট যোগাযোগ স্বাভাবিকভাবেই এই সীমাবদ্ধতাগুলিকে সমাধান করে, তবে তিনটি বাধা এর গ্রহণকে বাধাগ্রস্ত করেছে:
লাইব্রেরি সীমাবদ্ধতা: যদিও torch.distributed এবং NCCL Send/Recv-এর মতো পয়েন্ট-টু-পয়েন্ট API প্রদান করে, তবুও এই অপারেশনগুলি যৌথ সেমান্টিকস এবং সীমাবদ্ধতাগুলি উত্তরাধিকার সূত্রে প্রাপ্ত করে।
হার্ডওয়্যার বৈচিত্র্য: নির্ভরযোগ্য সংযোগ (RC) ট্রান্সপোর্ট সহ NVIDIA ConnectX NIC হলো সবচেয়ে সাধারণ RDMA সেটআপ, যা অর্ডারের মধ্যে ডেলিভারি নিশ্চিত করে। AWS-এর মতো ক্লাউড প্রদানকারীরা বিভিন্ন হার্ডওয়্যার ব্যবহার করে, স্কেলেবল রিলিয়ায়েবল ডাটাগ্রাম (SRD) ট্রান্সপোর্ট সহ Elastic Fabric Adapter (EFA) আউট-অফ-অর্ডার বার্তা সরবরাহ করে। EFA-এর 400 Gbps ব্যান্ডউইথ অর্জনের জন্য চারটি 100 Gbps NIC (বা দুটি 200 Gbps NIC) একত্রিত করা প্রয়োজন।
সফটওয়্যার পোর্টেবিলিটি: বিদ্যমান RDMA লাইব্রেরিগুলি ভেন্ডর লক-ইন-এর শিকার। DeepEP-এর জন্য শুধুমাত্র ConnectX-এ উপলব্ধ GPU-উদ্যোগী RDMA (IBGDA) প্রয়োজন। NVSHMEM EFA-তে মারাত্মক কর্মক্ষমতা হ্রাস প্রদর্শন করে। Mooncake এবং NIXL-এর মতো লাইব্রেরিগুলিতে EFA সমর্থন নেই বা প্রাথমিক বিকাশে রয়েছে। ফলে, LLM অনুমানের জন্য কোনো কার্যকর ক্রস-প্রোভাইডার সমাধান বিদ্যমান নেই।
TransferEngine
TransferEngine চারটি মূল ক্ষমতার মাধ্যমে এই বাধাগুলিকে সমাধান করে:
সাধারণ ট্রান্সপোর্ট অনুমান: একটি নির্দিষ্ট NIC-কে লক্ষ্য করার পরিবর্তে, TransferEngine শুধুমাত্র এই ধারণ করে যে অন্তর্নিহিত ট্রান্সপোর্ট নির্ভরযোগ্য কিন্তু অনর্ডার্ড, অর্থাৎ RC এবং SRD উভয় ট্রান্সপোর্ট দ্বারা প্রদত্ত গ্যারান্টির ছেদ।
ImmCounter সিঙ্ক্রোনাইজেশন: সমাপ্তি বিজ্ঞপ্তির জন্য একটি অভিনব প্রিমিটিভ যা বার্তার অর্ডারের উপর নির্ভর না করে কাজ করে, একই কোডকে অর্ডার্ড (RC) এবং অনর্ডার্ড (SRD) উভয় ট্রান্সপোর্টে চলতে সক্ষম করে।
মাল্টি-NIC সমর্থন: প্রতি জিপিইউতে একাধিক NIC-এর স্বচ্ছ ব্যবস্থাপনা, ব্যান্ডউইথ সর্বাধিক করার জন্য স্বয়ংক্রিয়ভাবে স্থানান্তরের শার্ডিং করা।
ন্যূনতম API উপরিভাগ: জটিল যোগাযোগের প্যাটার্ন তৈরির জন্য যথেষ্ট ছোট অপারেশনগুলির একটি সেট।
TransferEngine প্রতি জিপিইউতে একটি কর্মী থ্রেড তৈরি করে। প্রতিটি কর্মী একটি DomainGroup পরিচালনা করে যা হার্ডওয়্যার প্ল্যাটফর্মের উপর নির্ভর করে 1 থেকে 4টি RDMA NIC সমন্বয় করে (একটি একক ConnectX-7 400 Gbps প্রদান করে, যেখানে EFA-এর চারটি 100 Gbps অ্যাডাপ্টার বা দুটি 200 Gbps অ্যাডাপ্টার প্রয়োজন)। একটি DomainGroup-এর মধ্যে, প্রতিটি Domain হার্ডওয়্যার-নির্দিষ্ট এবং একটি একক NIC পরিচালনা করে, কিউ পেয়ার ব্যবস্থাপনা, কাজের জমা দেওয়া এবং সমাপ্তি পোলিং পরিচালনা করে।
প্রতিটি TransferEngine ইনস্ট্যান্স পিয়ার সনাক্তকরণ এবং আবিষ্কারের জন্য একটি একক প্রধান ঠিকানা প্রকাশ করে। দূরবর্তী পিয়ারগুলি NetAddr স্ট্রাক্ট বিনিময় করে যা নেটওয়ার্ক ঠিকানা এনকোড করে এবং আউট-অফ-ব্যান্ড যোগাযোগের জন্য সিরিয়ালাইজ করা যেতে পারে। সিস্টেমের সমস্ত পিয়ারকে প্রতি জিপিইউতে একই সংখ্যক NIC ব্যবহার করতে হবে। এই অভিন্ন কনফিগারেশন TransferEngine-কে বুদ্ধিমানভাবে শার্ড ট্রান্সফার করার অনুমতি দেয়: একটি ট্রান্সফার শুরু করার সময়, উৎস এবং গন্তব্য উভয়ই ঠিক জানে কোন NIC গুলি উপলব্ধ রয়েছে, যা সমস্ত অ্যাডাপ্টার জুড়ে স্বয়ংক্রিয় লোড ব্যালেন্সিং সক্ষম করে।
API ডিজাইন
TransferEngine একটি ন্যূনতম API প্রকাশ করে যা অন্তর্নিহিত RDMA ইন্টারফেসগুলির জটিলতাকে বিমূর্ত করে।
#[serde] struct NetAddr(Bytes);
#[serde] struct MrDesc{ ptr: u64, rkeys: Vec<(NetAddr, u64)> }
struct MrHandle(NonNull<c_void>); type Offset = u64;
struct Pages{ indices: Vec<u32>, stride: u64, offset: Offset }
struct PeerGroupHandle(u64);
struct ScatterDst{ len: u64, src: Offset, dst: (MrDesc,Offset)}
enum OnDone { Callback(fn () -> ()), Flag(Atomic<bool>) }
trait TransferEngine {
fn main_address() -> NetAddr;
// Memory Region Management
fn reg_mr(ptr, len, device) -> (MrHandle, MrDesc);
// Two-sided Send/Recv
fn submit_send(addr: NetAddr, msg: &[u8], cb: fn () -> ());
fn submit_recvs(len: u64, cnt: u64, cb: fn (&[u8]) -> ());
// One-sided Write
fn expect_imm_count(imm: u32, count: u32, cb: fn () -> ());
fn submit_single_write(len: u64, imm: Option<u32>
src: (MrHandle, Offset), dst: (MrDesc, Offset), OnDone);
fn submit_paged_writes(page_len: u64, imm: Option<u32>,
src: (MrHandle, Pages), dst: (MrDesc, Pages), OnDone);
// One-sided Write to a group of peers
fn add_peer_group(addrs: Vec<NetAddr>) -> PeerGroupHandle;
fn submit_scatter(h: Option<PeerGroupHandle>, OnDone,
imm: Option<u32>, src: MrHandle, dst: Vec<ScatterDst>);
fn submit_barrier(h: Option<PeerGroupHandle>, OnDone,
imm: u32, dst: Vec<MrDesc>);
// Watcher for CPU-GPU synchronization
fn alloc_uvm_watcher(cb: fn(u64,u64) -> ()) -> NonNull<u64>;
}API বেশ কয়েকটি মূল উপাদান নিয়ে গঠিত:সহ
মেমরি রেজিস্ট্রেশন
RDMA অপারেশনগুলির জন্য ডেটা স্থানান্তরের আগে NIC-এ মেমরি অঞ্চল নিবন্ধিত হওয়া প্রয়োজন। reg_mr ফাংশন একটি পয়েন্টার, দৈর্ঘ্য এবং ডিভাইস নেয়, যা দুটি হ্যান্ডল প্রদান করে:
MrHandle: স্থানান্তরের উৎস হিসাবে ব্যবহৃত একটি স্থানীয় হ্যান্ডেল
MrDesc: একটি সিরিয়ালাইজেবল ডিস্ক্রিপ্টর যা নিবন্ধিত মেমরিতে লেখার ক্ষমতা দেওয়ার জন্য দূরবর্তী পিয়ারগুলির সাথে বিনিময় করা যেতে পারে
MrDesc স্ট্রাকচারে দূরবর্তী নেটওয়ার্ক ঠিকানা এবং দূরবর্তী কী (প্রতি NIC-তে একটি) এর একটি তালিকা রয়েছে যা মেমরি অঞ্চলে দূরবর্তী অ্যাক্সেস প্রদান করে। এই ডিজাইনটি স্বাভাবিকভাবেই মাল্টি-NIC সেটআপ পরিচালনা করে।
দ্বিমুখী Send/Recv
ছোট বার্তা এবং RPC-শৈলীর কন্ট্রোল প্লেন বার্তার জন্য, TransferEngine submit_send এবং submit_recvs প্রদান করে:
submit_send: NetAddr দ্বারা চিহ্নিত একটি দূরবর্তী পিয়ারে বার্তা পাঠায়। বার্তাটি অভ্যন্তরীণভাবে অনুলিপি করা হয়, তাই কলকারী তাৎক্ষণিকভাবে বাফারটি পুনরায় ব্যবহার বা প্রকাশ করতে পারে।
submit_recvs: রিসিভ বাফারের একটি পুল পোস্ট করে। যখন একটি বার্তা আসে, তখন প্রাপ্ত ডেটা সহ একটি কলব্যাক আহ্বান করা হয়। কলব্যাক সম্পূর্ণ হওয়ার পরে বাফারটি স্বয়ংক্রিয়ভাবে পুলে ফিরে আসে।
একমুখী Write
বাল্ক ডেটা স্থানান্তরের জন্য, TransferEngine জিরো-কপি একমুখী রাইট অপারেশন প্রদান করে:
submit_single_write: উৎস থেকে গন্তব্যে একটি ধারাবাহিক অঞ্চল স্থানান্তর করে
submit_paged_writes: সূচক, স্ট্রাইড এবং অফসেট দ্বারা নির্দিষ্ট করা অ-ধারাবাহিক পেজ স্থানান্তর করে
উভয় অপারেশন একটি ঐচ্ছিক 32-বিট অবিলম্বে মান গ্রহণ করে যা সমাপ্তির পরে পরমাণুভাবে রিসিভারকে সরবরাহ করা হয়।
ইঞ্জিনটি ব্যান্ডউইথ সর্বাধিক করার জন্য স্বয়ংক্রিয়ভাবে একাধিক NIC জুড়ে বড় স্থানান্তরগুলি শার্ড করে।
পিয়ার গ্রুপ এবং বাল্ক অপারেশন
একাধিক পিয়ারকে লক্ষ্য করে করা অপারেশনগুলির জন্য (MoE রাউটিং-এ সাধারণ), TransferEngine অপ্টিমাইজড প্রিমিটিভ প্রদান করে:
add_peer_group: দ্রুত লুকআপের জন্য পিয়ার ঠিকানার একটি সেট প্রাক-নিবন্ধন করে
submit_scatter: গ্রুপের প্রতিটি পিয়ারে বিভিন্ন ডেটা স্লাইস পাঠায়
submit_barrier: সমস্ত পিয়ারে একটি অবিলম্বে-মাত্র বিজ্ঞপ্তি পাঠায় (জিরো-বাইট স্থানান্তর)
পুনরাবৃত্তিমূলক সেটআপ ওভারহেড এড়িয়ে, অভ্যন্তরীণ ডেটা স্ট্রাকচার ক্যাশ করে এবং RDMA কাজের অনুরোধ টেমপ্লেট করে কম ল্যাটেন্সির জন্য এই অপারেশনগুলি অপ্টিমাইজ করা হয়।
UVM ওয়াচার: GPU-থেকে-CPU সিগন্যালিং
LLM সিস্টেমগুলিতে একটি মূল চ্যালেঞ্জ হলো GPU প্রগতির সাথে RDMA স্থানান্তর সমন্বয় করা। আদর্শভাবে, জিপিইউ আউটপুট তৈরি করার সাথে সাথেই ডেটা স্থানান্তর শুরু হওয়া উচিত, কিন্তু সিপিইউ থেকে জিপিইউ পোল করা অদক্ষ।
TransferEngine UVM Watchers দিয়ে এর সমাধান করে: ইউনিফাইড ভার্চুয়াল মেমরি অবস্থান যা GPU কার্নেল দ্বারা আপডেট করা যেতে পারে (এমনকি CUDA গ্রাফের মধ্যেও) এবং GDRCopy ব্যবহার করে CPU দ্বারা দক্ষতার সাথে পোল করা যেতে পারে। যখন একটি UVM ওয়াচার বরাদ্দ করা হয়, তখন একটি কলব্যাক নিবন্ধিত হয় যা GPU মান আপডেট করার সাথে সাথেই আহ্বান করা হয়।
এটি লেয়ার-বাই-লেয়ার KvCache স্থানান্তরের মতো প্যাটার্নগুলি সক্ষম করে: প্রতিটি ট্রান্সফরমার লেয়ার সম্পূর্ণ হওয়ার পরে, জিপিইউ ওয়াচার বৃদ্ধি করে, পরবর্তী লেয়ারগুলি গণনা চালিয়ে যাওয়ার সময় সেই লেয়ারের KvCache-এর একটি RDMA স্থানান্তর ট্রিগার করে।
সমাপ্তি বিজ্ঞপ্তি
TransferEngine ইনিশিয়েটর দিক (submit_write-এর কলকারী) এবং রিসিভার দিক (Write অপারেশনগুলির লক্ষ্য) উভয়ের জন্যই সমাপ্তি বিজ্ঞপ্তি মেকানিজম সরবরাহ করে।
ইনিশিয়েটর-দিকের বিজ্ঞপ্তি: যখন একটি রাইট অপারেশন জমা দেওয়া হয়, তখন কলকারী একটি কলব্যাক ফাংশন বা একটি অ্যাটমিক ফ্ল্যাগের মাধ্যমে সমাপ্তির পরে বিজ্ঞপ্তি পাওয়ার জন্য বেছে নিতে পারে। এই বিজ্ঞপ্তিটি নিশ্চিত করে যে উৎস বাফার থেকে ডেটা সফলভাবে স্থানান্তরিত হয়েছে।
রিসিভার-দিকের বিজ্ঞপ্তি: মূল উদ্ভাবন হলো ImmCounter, একটি উপাদান যা 32-বিট তাত্ক্ষণিক নম্বর দ্বারা সূচিত কাউন্টার ট্র্যাক করে। যখন একটি রাইট অপারেশন একটি তাত্ক্ষণিক মান বহন করে, তখন ডেটা ডেলিভারির পরে রিসিভারের ImmCounter পারমাণবিক ভাবে বৃদ্ধি পায়। expect_imm_count ফাংশন রিসিভারকে একটি কলব্যাক নিবন্ধন করার অনুমতি দেয় যা একটি নির্দিষ্ট তাত্ক্ষণিক মান লক্ষ্য কাউন্টারে পৌঁছালে ফায়ার হয়। কাউন্টারগুলি GDRCopy-এর মাধ্যমে জিপিইউ-এর সাথে স্বচ্ছভাবে সিঙ্ক্রোনাইজ করা যেতে পারে, সরাসরি পোল করা যেতে পারে বা কলব্যাকের মাধ্যমে পর্যবেক্ষণ করা যেতে পারে।
এই রিসিভার-দিকের মেকানিজম বার্তার অর্ডারিংয়ের প্রয়োজন ছাড়াই নির্ভরযোগ্য সিঙ্ক্রোনাইজেশন প্রদান করে। এটি ConnectX NICs (যা RC ট্রান্সপোর্টের মাধ্যমে ইন-অর্ডার ডেলিভারি নিশ্চিত করে) এবং EFA NICs (যা SRD ট্রান্সপোর্টের মাধ্যমে আউট-অফ-অর্ডার বার্তা সরবরাহ করে) উভয় ক্ষেত্রেই সমানভাবে ভালো কাজ করে।
বাস্তবায়ন
TransferEngine রাস্টে বাস্তবায়িত হয়েছে, ল্যাটেন্সি কমাতে এবং উচ্চ থ্রুপুট অর্জনের জন্য বরাদ্দ, থ্রেডিং এবং সিঙ্ক্রোনাইজেশন সাবধানে অপ্টিমাইজ করছে। ইঞ্জিনটি প্রতিটি DomainGroup-এর জন্য একটি কর্মী থ্রেড তৈরি করে, প্রতিটি ডিভাইস সংযুক্ত NUMA নোডের একটি CPU কোরে পিন করা হয়, যা সময়সূচী এবং মেমরি অ্যাক্সেস ল্যাটেন্সি উভয়ই কম করে। একটি ডোমেইনের জন্য নির্দিষ্ট ডেটা স্ট্রাকচারগুলি পিন করার পরে বরাদ্দ করা হয় যাতে সঠিক NUMA নোডে মেমরি সংরক্ষিত থাকে তা নিশ্চিত করা যায়। একটি কর্মী থ্রেড ৪টি Domain পর্যন্ত পরিচালনা করে (প্রত্যেকটি একটি একক NIC পরিচালনা করে), অন্য একটি উৎসর্গীকৃত থ্রেড UVM ওয়াচার আপডেট করতে GPU পোল করে। ক্রস-থ্রেড যোগাযোগ লক-মুক্ত কিউগুলির মাধ্যমে সম্পন্ন হয়।
API যথাযথ পরিবেশনকারী ডিভাইসটিকে পরিবেশনকারী DomainGroup-এ অনুরোধগুলি ফরোয়ার্ড করে, যার মধ্যে প্রথমটি হোস্টকেও পরিবেশন করে। একটি টাইট লুপে, ডোমেন কর্মী নতুন কাজের জন্য পোল করে, নতুন অনুরোধ জমা দেওয়াকে অগ্রাধিকার দেয়। হার্ডওয়্যার এবং কনফিগারেশনের উপর নির্ভর করে, অনুরোধগুলি উপলব্ধ Domain জুড়ে শার্ড এবং লোড-ব্যালেন্স করা হয়। একটি কম্পোজিট অনুরোধের প্রথম রাইটটি অবিলম্বে NIC-এর সেন্ড কিউতে পোস্ট করা হয়। একবার নতুন অনুরোধগুলি শেষ হয়ে গেলে, কর্মী মুলতুবি থাকা অপারেশনগুলি অগ্রসর হতে এগিয়ে যায়, হার্ডওয়্যার পাইপলাইন পূরণ করতে রাইট পোস্ট করে। পরবর্তীতে, সমাপ্ত স্থানান্তর এবং তাত্ক্ষণিক কাউন্টার বৃদ্ধি সম্পর্কে প্রশ্ন করার জন্য সমাপ্তি কিউগুলি পোল করা হয়। প্রতি-স্থানান্তর বিজ্ঞপ্তি সরবরাহ করার জন্য ইভেন্টগুলি একত্রিত করা হয়, সমস্ত গ্রুপ দ্বারা ভাগ করা একটি উৎসর্গীকৃত কলব্যাক থ্রেডে স্থানান্তর হস্তান্তর করা হয়।
একটি DomainGroup-এর ভিতরে শার্ডিং নমনীয়। স্থানান্তরগুলি সূচক দ্বারা নির্দিষ্ট NIC কে লক্ষ্য করতে পারে। একটি একক রাইট বিভক্ত করা যেতে পারে। পেজড ট্রান্সফার, স্ক্যাটার এবং ব্যারিয়ার অপারেশন, যা সমস্ত একাধিক রাইটে অনুবাদ করে, সমস্ত NIC জুড়ে শার্ড হতে পারে।
হার্ডওয়্যার-নির্দিষ্ট অপ্টিমাইজেশান
TransferEngine-এর মধ্যে Domainগুলি বিশেষায়িত এবং তাদের নিয়ন্ত্রণের অধীনে হার্ডওয়্যারের জন্য অপ্টিমাইজ করা হয়েছে:
AWS EFA: EFA বাস্তবায়নে libfabric ব্যবহার করা হয়, যা DomainGroup-এর মধ্যে প্রতি NIC একটি ফ্যাব্রিক ডোমেন পরিচালনা করে। মূল বাস্তবায়ন সিদ্ধান্ত এবং অপ্টিমাইজেশনের মধ্যে রয়েছে:
জিরো-সাইজ রাইট: EFA শূন্য-আকারের রাইটের জন্যও বৈধ লক্ষ্য ডিস্ক্রিপ্টর প্রয়োজন করে RDMA স্পেসিফিকেশন থেকে বিচ্যুত হয়। অতএব, TransferEngine সমস্ত স্থানান্তরের জন্য বৈধ ডিস্ক্রিপ্টর প্রয়োগ করে।
কাজের অনুরোধ টেমপ্লেটিং: পোস্ট করার আগে libfabric স্ট্রাকচারগুলির সাধারণ ক্ষেত্রগুলি প্রাক-জনবহুল এবং ধরে রাখে, বাল্ক স্থানান্তর এবং পিয়ার গ্রুপ অপারেশনগুলির জন্য প্রতি-অপারেশন ওভারহেড হ্রাস করে
NVIDIA ConnectX-7: ConnectX-7 বাস্তবায়ন RC ট্রান্সপোর্ট সহ libibverbs ব্যবহার করে। মূল বাস্তবায়ন সিদ্ধান্ত এবং অপ্টিমাইজেশনের মধ্যে রয়েছে:
হ্যান্ডশেকগুলির জন্য UD কিউ পেয়ার: প্রতিটি Domain RC সংযোগ হ্যান্ডশেক বিনিময় করতে একটি আনরিলায়েবল ডাটাগ্রাম (UD) কিউ পেয়ার ব্যবহার করে।
আলাদা RC কিউ পেয়ার: প্রতি পিয়ারে 2টি RC কিউ পেয়ার তৈরি করে, একটি দ্বিমুখী Send/Recv অপারেশনগুলির জন্য এবং অন্যটি একমুখী Write এবং WriteImm অপারেশনগুলির জন্য। এই পৃথকীকরণের প্রয়োজন কারণ Recv এবং WriteImm উভয় সমাপ্তিই পোস্টিং অর্ডারে কাজের অনুরোধগুলি ব্যবহার করে, হস্তক্ষেপ ছাড়াই WriteImm সমর্থন করার সময় উচ্চ-স্তরের Recv সেমান্টিকস অনুমতি দেয়।
কাজের অনুরোধ টেমপ্লেটিং: বাল্ক স্থানান্তর এবং পিয়ার গ্রুপের জন্য কাজের অনুরোধ স্ট্রাকচারের সাধারণ ক্ষেত্রগুলি প্রাক-জনবহুল করে।
কাজের অনুরোধ চেইনিং: ibv_send_wr-এর next পয়েন্টারের মাধ্যমে ৪টি কাজের অনুরোধ পর্যন্ত লিঙ্ক করে, NIC-তে ডোরবেল রিংয়ের সংখ্যা হ্রাস করে।
রিলাক্সড অর্ডারিং: NIC এবং GPU মেমরির মধ্যে আউট-অফ-অর্ডার PCIe লেনদেনের অনুমতি দিতে IBV_ACCESS_RELAXED_ORDERING সক্ষম করে।
উপসংহার
বিভিন্ন RDMA ট্রান্সপোর্ট জুড়ে গ্যারান্টির ছেদকে লক্ষ্য করে এবং ImmCounter-এর মাধ্যমে অর্ডার-স্বাধীন সিঙ্ক্রোনাইজেশন প্রবর্তন করে, TransferEngine LLM সিস্টেমে পয়েন্ট-Tু-পয়েন্ট যোগাযোগের জন্য একটি পোর্টেবল ভিত্তি প্রদান করে। লাইব্রেরিটি ওপেন সোর্স এবং GitHub-এ উপলব্ধ, এবং আমরা সম্প্রদায়কে বড় মাপের মেশিন লার্নিং সিস্টেমে উদীয়মান যোগাযোগের প্যাটার্নের জন্য এটি অন্বেষণ করতে এবং এর উপর ভিত্তি করে তৈরি করতে উৎসাহিত করি।
উদ্ধৃতি
@online{perplexity2025RdmaPointToPointCommunicationForLlmSystems,
author = {{Perplexity} and Nandor Licker and Kevin Hu and Vladimir Zaytsev and Lequn Chen},
title = {{RDMA point-to-point communication for LLM systems}},
date = {2025-11-05},
url = {https://www.perplexity.ai/hub/blog/rdma-point-to-point-communication-for-llm-systems}
}