Ladenie jadra Linuxu pre servery s umelou inteligenciou: Čo v skutočnosti hýbe procesom
Predvolené jadro Ubuntu na HWE stacku 6.8 alebo 6.11 je postačujúce pre približne 80 % úloh umelej inteligencie. Tento článok sa venuje zvyšným 20 % – viacsocketovému EPYC s ôsmimi GPU, serveru vLLM s... vm.max_map_count stena pod záťažou alebo inferenčný server, ktorého latencia chvosta je spotrebovaná prechodmi C-stavu CPU.
Väčšina verejných rád týkajúcich sa „ladenia Linuxu pre AI“ je recyklovanými pokynmi pre databázu z roku 2015 a nezanedbateľný zlomok z nich potichu zhoršuje latenciu inferencie. Nižšie je uvedená menšia, úprimná sada zmien, ktoré skutočne pomáhajú na zariadení s K-AI triedy Kentino (4–8 GPU na Xeon alebo EPYC, Ubuntu 22.04 / 24.04, jadro 6.x). Predpokladá sa, že ovládač a CUDA stack sú nainštalované podľa... L01 a L02.
Čestná hierarchia výhier
Pred akýmikoľvek zmenami v sysctl sa zamerajte na veľkosť výhry:
| Zmena | Typické víťazstvo v oblasti inferencie / trénovania |
|---|---|
| Umiestnenie procesov s ohľadom na NUMA | 10 – 30 % na viaczásuvkové krabice |
Regulátor CPU performance (Od powersave) |
5–15 % na servírovacie krabice, nižšia TTFT |
| Zakázanie hlbokých C-stavov | Mikrosekundy vypnutia P99, +30–50 W v kľude / zásuvka |
THP nastavené na madvise
|
1–5 % na PyTorch, menej stání pod úrovňou odchodu zákazníkov |
vm.max_map_count, ulimit -n
|
Zabraňuje prevráteniu servírovania pod záťažou |
| Afinita IRQ k lokálnemu uzlu NUMA | 5–15 % na sieťových trasách DataLoader / RDMA |
Veľkosť vyrovnávacej pamäte TCP (rmem_max, wmem_max) |
Záleží len pre úložisko/streamovanie >25 GbE |
| Všetko ostatné | 0–3 %, často šum |
Ak si z tohto článku nič iné neodnesiete: Dve veľké výhry sú povedomie o NUMA a regulátor CPU. Všetko ostatné je zaokrúhľovacia chyba, pokiaľ ste ju nemerali.
Regulátor CPU: najlacnejších 5–15 % na stole
Predvolené nastavenie Ubuntu je powersave (intel_pstate) alebo ondemand (acpi_cpufreq) v závislosti od ovládača. Obe rampy sa reaktívne nastavujú, čo predstavuje 5 – 15 % nákladov na inferenčné TTFT a na prípravu na strane CPU okolo vLLM forward pass – tokenizácia, plánovanie, vzorkovanie logitov.
Pre servírovaciu krabicu nastavte performance a zabudnúť:
sudo apt install -y cpufrequtils
echo 'GOVERNOR="performance"' | sudo tee /etc/default/cpufrequtils
sudo systemctl restart cpufrequtils
# Verify
for c in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do cat $c; done | sort -u
Na EPYC Genoa / Turin s jadrom 6.5+, amd-pstate vodič nahrádza acpi-cpufreqRovnaký nápad, nastavte scaling_governor na performance. Tým novším amd-pstate-epp režim udržiava výkon a zároveň umožňuje zvýšenie výkonu na jadro; ponechajte EPP na performance, Nie balance_performance.
Upozornenie: na tréningovom boxe s trvalým ~100% využitím GPU sú CPU aj tak zaťažené a regulátor je menej dôležitý. Veľkou výhodou sú inferenčné servery, ktoré sú medzi požiadavkami nečinné a potrebujú okamžite naštartovať.
NUMA: rozdiel medzi rýchlym a priemerným EPYC boxom
Jednosocketové servery Xeon alebo EPYC nemajú o čom premýšľať – jeden uzol NUMA, každý prístup k pamäti je lokálny. Dvojsocketové boxy sú miestom, kde žije tých 10 – 30 %.
Predvolený plánovač s radosťou umiestni vLLM workera na socket 0 a prepíše ho do pamäte alokovanej na sockete 1 pomocou chyby stránky – každé načítanie je medzisocketový skok UPI / Infinity Fabric. Pre model so stovkami GB váh, ktoré sa prechádzajú raz na token, je to reálne.
Skontrolujte:
numactl --hardware # node count, sizes, distance matrix
nvidia-smi topo -m # GPU↔CPU NUMA affinity
cat /sys/class/net/<iface>/device/numa_node # NIC NUMA affinity
Vzor, ktorý chcete – a ktorý NCCL automaticky detekuje – je GPU N pripnutý k uzlu NUMA, ktorý hostí jeho koreňový komplex PCIe, nie k druhému socketu. Pre manuálne spustený proces inferencie pripnite CPU aj pamäť k lokálnemu uzlu:
# vLLM on a 2-socket EPYC, GPUs 0–3 on NUMA node 0
numactl --cpunodebind=0 --membind=0 \
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3.3-70B-Instruct --tensor-parallel-size 4
Dva súvisiace gombíky:
-
kernel.numa_balancingmigruje stránky smerom k CPU, ktoré sa ich dotýka. Užitočné pre všeobecné pracovné zaťaženia, občas kontraproduktívne pre AI: predbežné doplnenie prejde váhy raz, jadro migruje stránky a ďalšia požiadavka ich stiahne späť. Predvolene ponechajte zapnuté (1); ak jitter koreluje snuma_pte_updatesin/proc/vmstat, skússysctl kernel.numa_balancing=0. -
NCCL na dvojitej zásuvke — sada
NCCL_SOCKET_IFNAMEk riadiacej sieťovej karte aNCCL_IB_HCAk sieťovej karte (NIC) na rovnakom uzle NUMA ako grafické karty (GPU). Nesprávna sieťová karta ticho znižuje priepustnosť medzi uzlami na polovicu.
Jednosocketový server EPYC 9004/9005: celú túto časť ignorujte.
Priehľadné obrovské stránky: madvise, Nie always
THP oportunisticky skladá 4 KB stránky do 2 MB stránok, čím znižuje tlak na TLB. PyTorch a ovládač CUDA z toho profitujú len mierne. Pasca je... always režim pri prerušovanom čítaní pamäte – jadro zastaví vlákno na 50 – 100 ms, čím zhutní pamäť, čím sa eliminuje akákoľvek latencia SLO.
Správne nastavenie je madvise: aplikácie, ktoré vedia, čo robia, volajú madvise(MADV_HUGEPAGE) na dlhodobých alokáciách a získajte THP; nič iné to nedokáže. Nastavte cez /etc/default/grub:
GRUB_CMDLINE_LINUX_DEFAULT="... transparent_hugepage=madvise"
update-grub && rebootDefragmentácia by mala zodpovedať — defer+madvise umožňuje zhutňovanie prebiehať na pozadí, a nie v ceste alokovacieho vlákna:
echo defer+madvise | sudo tee /sys/kernel/mm/transparent_hugepage/defrag
Pre vLLM / SGLang / TensorRT-LLM v produkčnom prostredí, madvise je správna predvolená hodnota. PyTorch s CUDA Unified Memory (výskumný kód) niekedy využíva výhody always – pred prevrátením zmerajte.
Explicitné obrovské stránky s veľkosťou 1 GB: iba ak ste ich zmerali
Explicitné obrovské stránky rezervované pri bootovaní cez hugetlbfs prinášajú malú dodatočnú výhodu pre veľmi veľké váhy LLM elimináciou chýb TLB pri skenovaní váh. Háčik: pamäť je rezervovaná vopred a nie je k dispozícii pre zvyšok systému, aplikácia musí byť zostavená tak, aby ju používala, a zisk je 1 – 3 % pre väčšinu obslužných úloh.
GRUB_CMDLINE_LINUX_DEFAULT="... default_hugepagesz=1G hugepagesz=1G hugepages=64"
Oplatí sa to pre TensorRT-LLM box, kde engine sa zmestí do pripnutej pamäte a vy sa naháňate za poslednými percentami TTFT. Neoplatí sa to pre všeobecný vLLM server, ktorý vymieňa modely alebo akýkoľvek tréningový box. Preskočte pri prvej zostave; vráťte sa iba ak perf stat -e dTLB-load-misses zobrazuje tlak TLB a máte rezervu v RAM.
vm.max_map_count a nofile: steny, ktoré vLLM zasiahne vo veľkom meradle
štandardné vm.max_map_count v Ubuntu je to 65530 – počet rôznych mapovaní pamäte, ktoré môže proces uchovávať. vLLM obsluhujúci rozsiahly model s vysokou súbežnosťou alebo akýkoľvek framework používajúci veľa mmapčrepy bezpečnostných zariadení, preletí okolo a zomrie s Cannot allocate memoryHodnota 262144 odvodená z Elasticsearch je absolútne minimum; pre vLLM obsluhujúci 70B+ so stovkami súbežných sekvencií je potrebné nastaviť hodnotu 1048576. Nestojí to nič – mäkký limit, nie rezervácia.
štandardné ulimit -n na Ubuntu je to 1024. Komicky málo: vLLM, Triton, PyTorch DataLoader workers, NCCL a vrstva gRPC medzi nimi otvárajú stovky FD každý. Dosiahnite limit a získate EMFILE: too many open files a proces, ktorý sa potichu zasekáva.
# /etc/sysctl.d/99-ai-server.conf
vm.max_map_count = 1048576
# /etc/security/limits.d/99-ai-server.conf
* soft nofile 1048576
* hard nofile 1048576
# /etc/systemd/system.conf.d/99-limits.conf
[Manager]
DefaultLimitNOFILE=1048576
sudo sysctl --system a systemctl daemon-reexecOveriť s ulimit -n a cat /proc/<pid>/limits.
Afinita IRQ: pripnutie prerušení sieťovej karty k lokálnym CPU
Na sieťovej karte ConnectX-6/7 s pripojením 100 GbE, ktorá podporuje streamovanie dátových súborov alebo prevádzku RDMA s rýchlosťou viac ako 10 GB/s, musia prerušenia pristáť na procesoroch (a) na rovnakom uzle NUMA ako sieťová karta a (b) nie na rovnakých jadrách, na ktorých sú spustené procesy DataLoader. Predvolená hodnota irqbalance odvádza prijateľnú prácu; pri veľkej záťaži nie.
Najčistejšie riešenie je od Mellanoxu. set_irq_affinity.sh z mlnx-tools:
sudo systemctl disable --now irqbalance
sudo /usr/sbin/set_irq_affinity.sh enp1s0f0 # all NIC-local cores
sudo /usr/sbin/set_irq_affinity_cpulist.sh 4-11 enp1s0f0 # pin to specific cores
Zlým krokom je odísť irqbalance bežiace na krabici, ktorú ste tiež manuálne pripnuli – hádajú sa. Vyberte si jednu. Obsluhujúca krabica s jednou alebo dvoma RDMA sieťovými kartami: manuálne pripnutie, vypnutie irqbalanceUniverzálna krabica s mnohými rozhraniami: nechajte irqbalance ďalej s --banirq vylúčiť kritickú sieťovú kartu.
Vyrovnávacie pamäte sieťového jadra: iba pre rýchle úložiská / streamovacie cesty
Pre inferenčný server s jedným uzlom, ktorý komunikuje s klientmi cez obyčajný TCP pri nízkych rýchlostiach, je predvolená net.core.rmem_max / wmem_max 208 KB je v poriadku. Pre uzol, ktorý čerpá trénovacie dáta zo 100 GbE NFS alebo úložiska objektov, alebo pre frontend vLLM za vyrovnávačom záťaže s vysokým RPS, sú predvolené hodnoty stropom vášho produktu s pomerom šírky pásma a oneskorenia. Počiatočná sada pre zariadenie pripojené k 100 GbE:
# /etc/sysctl.d/99-ai-network.conf
net.core.rmem_max = 268435456
net.core.wmem_max = 268435456
net.ipv4.tcp_rmem = 4096 87380 268435456
net.ipv4.tcp_wmem = 4096 65536 268435456
net.core.netdev_max_backlog = 250000
net.core.somaxconn = 65535
Maximálne 256 MB je pre rackové pripojenie 100 GbE (BDP je ~1.25 MB) prehnané, ale neškodné – automatické ladenie TCP zväčšuje vyrovnávacie pamäte iba podľa potreby až do limitu. V RDMA (RoCE / IB) pre dátovú cestu tieto gombíky nehrajú rolu – RDMA obchádza TCP stack jadra. Stále sú dôležité pre rovinu správy, NFS a sťahovanie modelov.
C-stavy: latencia vs. nečinný výkon
Pre obslužný box citlivý na latenciu je najlacnejším zlepšením latencie chvosta po regulátore CPU vypnutie hlbokých C-stavov. Vstup/výstup C6 je v desiatkach mikrosekúnd; pre požiadavku, ktorá by mala odpovedať do 30 ms, CPU vychádzajúci z C6 na spracovanie vzorkovania po tokene pridáva badateľný jitter.
GRUB_CMDLINE_LINUX_DEFAULT="... intel_idle.max_cstate=1 processor.max_cstate=1"
update-grub && rebootOveriť s cpupower idle-info — k dispozícii by mali byť iba C0 a C1. Náklady: 30–50 W nečinného výkonu na zásuvku pretože jadrá nikdy neprejdú do hlbokého spánku. Na dvojsocketovom serveri s 8 GPU je to 60 – 100 W permanentnej réžie – triviálne oproti 3.5 – 4.5 kW trvalej spotreby GPU pri zaťažení.
Aplikujte na inferenčné servery citlivé na latenciu a robotické cesty v reálnom čase. Preskočte tréningové boxy (latencia nezáleží, spotreba energie v nečinnosti sa sčítava za mesiace) a dávkové úlohy.
Ladenie jadra súvisiace so súborovým systémom (ukážka L04)
Hrstka fs.* sysctls záleží:
fs.aio-max-nr = 1048576 # default 65536 too low for vLLM weight loaders
fs.inotify.max_user_watches = 524288 # tooling that watches checkpoint dirs
fs.aio-max-nr je ten, ktorý sa zahryzne – frameworky vykonávajúce asynchrónny I/O s mnohými shardmi (DALI, zavádzače hmotnosti vLLM) prepália predvolenú hodnotu 65536 na veľkých modeloch. Samotný výber súborového systému (XFS vs ZFS vs ext4), možnosti pripojenia a O_DIRECT sémantika žije v L04.
Zakázanie nepotrebných modulov jadra
Bezhlavý server nemá žiadne moduly na načítanie pre Bluetooth, zvuk, webkameru, bezdrôtové pripojenie, joystick ani tlačový server. Každý z nich predstavuje viac kódu na útočnej ploche a malé oneskorenie pri zavádzaní. Samostatne triviálne; spoločne je o čistejšom serveri jednoduchšie uvažovať.
# /etc/modprobe.d/blacklist-ai-server.conf
blacklist bluetooth
blacklist btusb
blacklist snd_hda_intel
blacklist uvcvideo
blacklist joydev
# Plus
sudo systemctl disable --now bluetooth.service cups.service avahi-daemon.service \
ModemManager.service whoopsie.service apport.service
Bootovanie klesne z ~30 s na ~10 s na typickej zostave EPYC a lsmod stáva sa čitateľným. Nulový vplyv na výkon inferencie, mierne zníženie útočnej plochy.
Dva profily: inferencia verzus tréning
Tvar ladenia je skutočne odlišný. Náčrty pre vkladanie:
Inferencia (/etc/sysctl.d/99-ai-inference.conf)
vm.max_map_count = 1048576
vm.swappiness = 1
vm.overcommit_memory = 1
kernel.numa_balancing = 1
fs.aio-max-nr = 1048576
net.core.rmem_max = 268435456
net.core.wmem_max = 268435456
net.ipv4.tcp_rmem = 4096 87380 268435456
net.ipv4.tcp_wmem = 4096 65536 268435456
net.core.netdev_max_backlog = 250000
net.core.somaxconn = 65535
Navyše na príkazovom riadku jadra: transparent_hugepage=madvise intel_idle.max_cstate=1 processor.max_cstate=1Guvernér: performance. IRQ sieťových kariet pripnuté k lokálnym jadrám NUMA, irqbalance off.
Školenie (/etc/sysctl.d/99-ai-training.conf)
vm.max_map_count = 1048576
vm.swappiness = 1
vm.overcommit_memory = 1
kernel.numa_balancing = 0 # page migration mid-epoch is just churn
fs.aio-max-nr = 1048576
fs.inotify.max_user_watches = 524288
net.core.rmem_max = 536870912
net.core.wmem_max = 536870912
net.ipv4.tcp_rmem = 4096 131072 536870912
net.ipv4.tcp_wmem = 4096 131072 536870912
Príkazový riadok jadra: transparent_hugepage=madvise (preskočte pripínanie C-stavu – tréning je viazaný na priepustnosť, spotreba energie v nečinnosti sa v priebehu týždňov sčítava). Regulátor: performance ak máte rozpočet na energiu. NCCL je pripnutý k lokálnej NUMA cez NCCL_IB_HCA.
Pasca „Všetko som naladil a spomalilo sa to“
Najčastejším spôsobom zlyhania je výpis z cargo-kultu: skopírujte sto sysctl súborov z blogového príspevku, reštartujte počítač, pozorujte horší výkon a neviete, ktorý gombík uvoľniť. Metóda, ktorá funguje:
- Stanovte si základnú líniu –
nccl-tests all_reduce_perf, vLLMbenchmark_throughput.py, čas tréningového kroku. Zapíšte si čísla. - Zmeň jednu vec.
- Znovu spustite ten istý benchmark trikrát kvôli šumu.
- Ak je medián výrazne lepší, ponechajte ho. Ak nie, vráťte ho späť.
- Zmenu a dôvod zdokumentujte v systéme riadenia verzií vedľa súboru sysctl.
Videli sme produkčné boxy so 40 riadkami ladenia sysctl, ktoré boli spolu o 2 % pomalšie ako predvolené nastavenia Ubuntu – každá jednotlivá zmena bola neutrálna alebo horšia, ale operátor si bol istý, že „ladenie pomáha“.
Červený klobúk tuned 2.27 lodí explicitne ai-inference a ai-training profily a je to dôveryhodná skratka na RHEL / Rocky. Ubuntu ju nedodáva; apt install tuned funguje, ale je menej prepracovaný. V Ubuntu, ručne vložené drop-iny v /etc/sysctl.d/ a čistý príkazový riadok GRUBu sa ľahšie audituje a presne viete, čo je nastavené.
Čo urobiť ďalej
Rozumná postupnosť ladenia jadra pre novú zostavu Kentino K-AI, v poradí podľa priority:
-
Nastavte regulátor CPU na
performance. Overiť pomocoucpupower frequency-infoNajväčšie víťazstvo bez akýchkoľvek nákladov. -
beh
numactl --hardwareanvidia-smi topo -m. Pred pripojením čohokoľvek pochopte topológiu. V prípade dvojzásuvných rozvádzačov si naplánujte, ktoré grafické karty budú fungovať s ktorým uzlom NUMA. -
Sada
vm.max_map_countanofilelimitov. Tieto opatrenia zabraňujú zlyhaniam, nie pomalosti. Urobte ich pred prvou výrobnou sériou. -
Sada
transparent_hugepage=madvisena príkazovom riadku jadra. -
Prerušenia sieťovej karty Pin k lokálnemu uzlu NUMA sieťovej karty pomocou
set_irq_affinity.shZakázaťirqbalanceak ste tak urobili. -
Len pre inferenčné rámčeky: deaktivovať hlboké C-stavy prostredníctvom
intel_idle.max_cstate=1 processor.max_cstate=1. - Ladenie sieťových vyrovnávacích pamätí iba ak ste namerali úzke hrdlo na úložnej alebo streamovacej trase 25/100 GbE.
- Preskočiť 1 GB explicitných obrovských stránok pokiaľ nemáte benchmark ukazujúci tlak TLB.
- Porovnávacie meranie pred a po každej zmene. Jedna vec naraz. Dokument.
Krížové odkazy: L01 pre pripnutie ovládača a jadra, L02 pre CUDA / kontajnerový zásobník, L04 pre vrstvu súborového systému, L05 na monitorovanie.
Ladenie jadra v modernom Linuxe je väčšinou jednorazová konfigurácia, nie priebežná optimalizačná hra. Správne nastavte governor, umiestnenie NUMA a limity. Zvyšok preskočte, pokiaľ váš benchmark nehovorí inak.
Toto je súčasť Kentino Wiki, referenčnej série o umelej inteligencii, robotike a systémoch, ktoré ich spájajú. Komentáre a opravy sú vítané na info@kentino.com.