LLM жүйелеріне арналған RDMA нүктеден нүктеге байланыс

Пайда болушы LLM байланыс үлгілерін шешуге арналған талғампаз құрал

АвторларPerplexity Research

LLM жүйелері дәстүрлі түрде оқыту мен инференстегі құрылымдалған параллель үлгілер үшін ұжымдық коммуникацияларға сүйеніп келді. Алайда disaggregated inference, Mixture-of-Experts (MoE) бағыттау және асинхронды reinforcement learning fine-tuning сияқты жаңа жүктемелер point-to-point коммуникацияның икемділігін талап етеді.

Біздің соңғы зерттеу жұмысымыз NVIDIA ConnectX-7 және AWS Elastic Fabric Adapter (EFA) қоса алғанда, әртүрлі Желілік Интерфейс Контроллерлерінде (NIC) жұмыс істейтін портативті RDMA негізіндегі байланыс кітапханасы TransferEngine-ді ұсынады. Біз оның тиімділігін Perplexity AI компаниясының үш өндірістік жүйесінде көрсетеміз:

Disaggregated Prefill және Decode: paged writes және UVM watchers қолдану арқылы KvCache-ті қабат-қабат тасымалдау, prefill және decode даналарының тәуелсіз масштабталуына мүмкіндік береді.

2 секундтан аз уақыт ішінде RL оқытудан кейінгі кезең үшін салмақты тасымалдау: оқыту және вывод түйіндері арасындағы өте жылдам салмақты синхрондау.

AWS EFA жүйесінде триллион параметрлі модельдерді қосу: ConnectX-7 жүйесінде ең озық кідіріске және AWS EFA-мен үйлесімді алғашқы өміршең іске асыруға қол жеткізе отырып, шашырау және бөгет примитивтерін пайдалана отырып, төмен кідірісті MoE тарату және біріктіру операциялары.

Бұл мақала осы жүйелерді жұмыс істейтін байланыс кітапханасы TransferEngine-нің өзіне арналған. arXiv сайтындағы толық зерттеу жұмысын оқып шығыңыз және GitHub арқылы кодты зерттеңіз.

Мотивация

Ұжымдық байланыстар тензорлық параллелизм және деректер параллелиөмі сияқты құрылымдық параллель үлгілерде озық болады, бірақ олардың пайда болушы жұмыс жүктемелеріне қолданылуын шектейтін шектеулер қояды:

Тұрақты құрам: Collective операциялар іске қосу кезінде жаһандық communication world орнатуды, барлық қатысушылар арасында синхрондалған баптауды талап етеді. Disaggregated inference үшін бұл мәселе тудырады, өйткені prefill және decode даналарының саны traffic patterns-ке жауап ретінде динамикалық түрде масштабталуы тиіс.

Бірдей тензор пішіндері: Ұжымдар барлық қатысушылар бірдей пішіндері мен деректер түрлері бар тензорларды алмастырады деп болжайды. MoE бағыттауда әрбір сарапшыға жіберілетін токендер саны деректерге байланысты және орындалу уақытында анықталады, бұл тығыз барлығынан-барлығына ұжымдарды ең нашар жағдайдағы буфер өлшемдеріне дейін толтыруға мәжбүр етеді.

Операцияларды ретке келтіру: Ұжымдық API-лер қолданбалар операциялар жиынтығы аяқталғанын білуі қажет болса да, синхрондалған семантиканы мәжбүрлейді. Мысалы, KvCache тасымалдауда префилл данасынан декодтау данасына дейінгі барлық беттер кез келген ретпен келее алады. Сол сияқты, RL салмақ жаңартуларында барлық салмақ тензорлары реттік шектеулерсіз дербес тасымалдануы мүмкін.

RDMA негізіндегі нүктеден нүктеге байланыс бұл шектеулерді табиғи түрде шешеді, бірақ үш кедергі оның қабылдануына жойған болатын:

Кітапхана шектеулері: torch.distributed және NCCL Send/Recv сияқты нүктеден нүктеге API-лерді қамтамасыз еткенімен, бұл операциялар әлі де ұжымдық семантика мен шектеулерді мұра етеді.

Аппараттык құралдардың әртүрлілігі: Сенімді қосылым (RC) тасымалдауы бар NVIDIA ConnectX NIC-тері реттелген жеткізілімге кепілдік беретін ең танымал RDMA қондырғысы болып табылады. AWS сияқты бұлттық провайдерлер әртүрлі аппараттық құралдарды пайдаланады, Scalable Reliable Datagram (SRD) тасымалдауы бар Elastic Fabric Adapter (EFA) хабарларды тәртіпсіз жеткізеді. EFA сонымен қатар 400 Гбит/с өткізу қабілетіне қол жеткізу үшін төрт 100 Гбит/с NIC (немесе екі 200 Гбит/с NIC) біріктіруді талап етеді.

Бағдарламалық қамтамасыз етудің портативтілігі: Қолданыстағы RDMA кітапханалары жеткізушінің бекітіп қоюынан зардап шегеді. DeepEP тек ConnectX жүйесінде қолжетімді GPU бастамашылық еткен RDMA (IBGDA) талап етеді. NVSHMEM EFA жүйесінде ауыр өнімділік нашарлауын көрсетеді. Mooncake және NIXL сияқты кітапханаларда EFA қолдауы жоқ немесе ерте әзірлеу сатысында қалады. Нәтижесінде LLM выводы үшін провайдераралық өміршең шешім жоқ.

TransferEngine

TransferEngine бұл кедергілерді төрт негізгі мүмкіндік арқылы шешеді:

Жалпы тасымалдау жорамалдары: Белгілі бір NIC-ті нысанаға алудың орнына, TransferEngine негізгі тасымалдау сенімді, бірақ тәртіпсіз, яғни RC және SRD тасымалдаулары қамтамасыз ететін кепілдіктердің қиылысы деп болжайды.

ImmCounter синхрондауы: Хабар алмасу ретіне сүйенбей жұмыс істейтін аяқталу туралы хабарландыруға арналған жаңа примитив, бұл бірдей кодқа реттелген (RC) және реттелмеген (SRD) тасымалдауларда жұмыс істеуге мүмкіндік береді.

Бірнеше NIC қолдауы: Өткізу қабілетін максималды ету үшін тасымалдауларды автоматты түрде шардтайтын әр GPU үшін бірнеше NIC-ті мөлдір басқару.

Минималды API беті: Күрделі байланыс үлгілерін құруға жеткілікті шағын операциялар жиынтығы.

Request пен callback жолдарын, CPU worker-лерді, UVM буферлерін, GPU-ларды және NIC-терді екі GPU/NUMA домені бойынша көрсететін TransferEngine жүйелік дизайны.

TransferEngine әр GPU үшін бір жұмыс тредин (worker thread) тудырады. Әрбір жұмысшы аппараттық платформаға байланысты 1-4 RDMA NIC үйлестіретін DomainGroup басқарады (бір ConnectX-7 400 Гбит/с ұсынады, ал EFA төрт 100 Гбит/с адаптерді немесе екі 200 Гбит/с адаптерді талап етеді). DomainGroup ішінде әрбір Domain аппараттық құралға тән және бір NIC басқарады, кезек жұбын басқаруды, жұмысты жіберуді және аяқталуды сұрауды өңдейді.

Әрбір TransferEngine данасы пирді анықтау және табу үшін бір негізгі мекенжайды көрсетеді. Қашықтағы пирлер желілік мекенжайларды кодтайтын және жолақтан тыс байланыс үшін сериализациялануы мүмкін NetAddr құрылымдарымен алмасады. Жүйедегі барлық пирлер GPU үшін бірдей NIC санын пайдалануы тиіс. Бұл біркелкі конфигурация TransferEngine-ге тасымалдауларды ақылды түрде шардтауға мүмкіндік береді: тасымалдауды бастаған кезде көз де, мақсат та қандай NIC қолжетімді екенін жақсы біледі, бұл барлық адаптерлер бойынша автоматты түрде жүктемені теңестіруге мүмкіндік береді.

API дизайны

TransferEngine негізгі RDMA интерфейстерінің күрделілігін абстракциялайтын минималды API ұсынады.

rust
#[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: Қабылдау буферлерінің жиынтығын орналастырады. Хабар келген кезде, қабылданған деректермен кері шақыру шақырылады. Буфер кері шақыру аяқталғаннан кейін автоматты түрде жиынтыққа қайтарылады.

Бір жақты жазу

Көлемді деректерді тасымалдау үшін TransferEngine нөлдік көшірмелі бір жақты жазу операцияларын қамтамасыз етеді:

submit_single_write: Көзден мақсатқа үздіксіз аймақты тасымалдайды

submit_paged_writes: Индекстермен, қадамдармен және ығысулармен көрсетілген үздіксіз емес беттерді тасымалдайды

Екі операция да аяқталғаннан кейін алушыға атомдық түрде жеткізілетін қосымша 32 биттік дереу мәнді қабылдайды.

Қозғалтқыш өткізу қабілетін максималды ету үшін үлкен тасымалдауларды бірнеше NIC арасында автоматты түрде шардтайды.

Пир топтары және көлемді операциялар

Бірнеше пирге бағытталған операциялар үшін (MoE бағыттауда жиі кездеседі) TransferEngine оңтайландырылған примитивтерді ұсынады:

add_peer_group: Жылдам іздеу үшін пир мекенжайларының жиынтығын алдын ала тіркейді

submit_scatter: Топтағы әрбір пирге әртүрлі деректер бөліктерін жібереді

submit_barrier: Барлық пирлерге тек дереу хабарландыру жібереді (нөлдік байттық тасымалдау)

Бұл операциялар ішкі деректер құрылымдарын кэштеу және RDMA жұмыс сұрауларын шаблон жасау арқылы төмен кідіріс үшін оңтайландырылған, қайталанатын орнату шығындарын болдырмайды.

UVM Watcher: GPU-дан CPU-ға сигнал беру

LLM жүйелеріндегі негізгі міндет - RDMA тасымалдауларын GPU прогресімен үйлестіру. Идеал жағдайда деректерді тасымалдау GPU нәтиже шығарған бойда басталуы тиіс, бірақ CPU-дан GPU-ды сұрау тиімсіз.

TransferEngine мұны UVM Watchers көмегімен шешеді: GPU ядролары (тіпті CUDA графтары ішінде де) жаңартыла алатын және GDRCopy көмегімен CPU тиімді сұрай алатын біріктірілген виртуалды жад орындары. UVM бақылаушысы бөлінген кезде, GPU мәнді жаңартқан сайын шақырылатын кері шақыру тіркеледі.

Бұл қабат-қабат KvCache тасымалдау сияқты үлгілерді қосады: әрбір трансформер қабаты аяқталғаннан кейін GPU бақылаушыны ұлғайтады, бұл кейінгі қабаттар есептеуді жалғастырып жатқанда сол қабаттың KvCache-ін RDMA арқылы тасымалдауды бастайды.

Аяқталу туралы хабарландыру

TransferEngine бастамашы жағы үшін де (submit_write шақырушысы) және алушы жағы үшін де (Жазу операцияларының нысанасы) аяқталу туралы хабарландыру механизмдерін ұсынады.

Бастамашы тарапынан хабарландыру: Жазу операциясы жіберілген кезде, шақырушы кері шақыру функциясы немесе атомдық жалауша арқылы аяқталған кезде хабардар болуды таңдай алады. Бұл хабарландыру деректердің көз буферінен сәтті тасымалданғанын растайды.

Алушы тарапынан хабарландыру: Негізгі жаңалық - бұл ImmCounter, 32 биттік дереу нөмірлермен индекстелген есептегіштерді қадағалайтын компонент. Жазу операциясы дереу мәнді тасымалдаған кезде, алушының ImmCounter мәні деректер жеткізілген кезде атомдық түрде артады. expect_imm_count функциясы алушыға белгілі бір дереу мән нысана санаққа жеткен кезде іске қосылатын кері шақыруды тіркеуге мүмкіндік береді. Есептегіштерді GDRCopy арқылы GPU-мен мөлдір түрде синхрондауға, тікелей сұрауға немесе кері шақырулар арқылы бақылауға болады.

Бұл алушы жағының механизмі хабар алмасу ретін талап етпей сенімді синхрондауды қамтамасыз етеді. Ол ConnectX NIC-терінде де (RC тасымалдауы арқылы реттелген жеткізілімге кепілдік береді) және EFA NIC-терінде де (SRD тасымалдауы арқылы хабарларды тәртіпсіз жеткізеді) бірдей жақсы жұмыс істейді.

Іске асыру

TransferEngine Rust тілінде іске асырылған, кідірісті азайту және жоғары пропускная способностьке қол жеткізу үшін бөлулерді, трединдерді және синхрондауды мұқият оңтайландырады. Қозғалтқыш әр DomainGroup үшін бір жұмыс тредин тудырады, олардың әрқайсысы құрылғылар қосылған NUMA түйініндегі CPU ядросына бекітіліп, жоспарлау және жадқа қол жеткізу кідірісін барынша азайтады. Доменге тән деректер құрылымдары жадтың дұрыс NUMA түйінінде резервтелгенін қамтамасыз ету үшін бекітілгеннен кейін бөлінеді. Бір жұмыс треді 4 Domain-ге дейін басқарады (әрқайсысы бір NIC басқарады), ал басқа арналған тред UVM бақылаушыларын жаңарту үшін GPU сұрайды. Тредтер аралық байланыс блоктаусыз кезектер арқылы жүзеге асырылады.

API сұрауларды тиісті құрылғыға қызмет көрсететін DomainGroup-ке бағыттайды, ал біріншісы хостқа да қызмет көрсетеді. Қатаң циклде domain worker жаңа жұмысты poll жасап, жаңа сұрауларды жіберуге басымдық береді. Аппараттық құрал мен конфигурацияға байланысты, сұраулар қолжетімді Domainдер арасында shard-тарға бөлініп, load-balanced болады. Composite сұраудың бірінші Write операциясы бірден NIC-тің send queue-сына жіберіледі. Жаңа сұраулар таусылғаннан кейін, worker күтіп тұрған операциялардың progress-ін жалғастырып, аппараттық pipeline-ды толтыру үшін write операцияларын жібереді. Одан кейін completion queue-лар аяқталған тасымалдарды және counter-лердің бірден артуын сұрау үшін poll жасалады. Event-тер transfer notification-ларын жеткізу үшін жинақталып, тасымалды барлық топтар ортақ пайдаланатын dedicated callback thread-ке береді.

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 көрсеткіші арқылы 4 жұмыс сұрауына дейін байланыстырады, NIC-ке есік қоңырауы соғу санын азайтады.

Босаңсытылган тәртіп: NIC пен GPU жады арасындағы тәртіпсіз PCIe транзакцияларына рұқсат беру үшін IBV_ACCESS_RELAXED_ORDERING қосады.

Қорытынды

Әртүрлі RDMA тасымалдаулары бойынша кепілдіктердің қиылысын нысанаға алу және ImmCounter арқылы ретке тәуелсіз синхрондауды енгізу арқылы TransferEngine LLM жүйелеріндегі нүктеден нүктеге байланыс үшін портативті негізді ұсынады. Кітапхана ашық кодты және GitHub сайтында қолжетімді, және біз қауымдастықты оны масштабталатын машиналық оқыту жүйелеріндегі пайда болушы байланыс үлгілері үшін зерттеуге және соның негізінде құруға шақырамыз.

Дәйексөз

BibTeX
@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}
}