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_balancing migruje 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 s numa_pte_updates in /proc/vmstat, skús sysctl kernel.numa_balancing=0.
  • NCCL na dvojitej zásuvke — sada NCCL_SOCKET_IFNAME k riadiacej sieťovej karte a NCCL_IB_HCA k 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:

  1. Stanovte si základnú líniu – nccl-tests all_reduce_perf, vLLM benchmark_throughput.py, čas tréningového kroku. Zapíšte si čísla.
  2. Zmeň jednu vec.
  3. Znovu spustite ten istý benchmark trikrát kvôli šumu.
  4. Ak je medián výrazne lepší, ponechajte ho. Ak nie, vráťte ho späť.
  5. 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:

  1. Nastavte regulátor CPU na performance. Overiť pomocou cpupower frequency-infoNajväčšie víťazstvo bez akýchkoľvek nákladov.
  2. beh numactl --hardware a nvidia-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.
  3. Sada vm.max_map_count a nofile limitov. Tieto opatrenia zabraňujú zlyhaniam, nie pomalosti. Urobte ich pred prvou výrobnou sériou.
  4. Sada transparent_hugepage=madvise na príkazovom riadku jadra.
  5. Prerušenia sieťovej karty Pin k lokálnemu uzlu NUMA sieťovej karty pomocou set_irq_affinity.shZakázať irqbalance ak ste tak urobili.
  6. Len pre inferenčné rámčeky: deaktivovať hlboké C-stavy prostredníctvom intel_idle.max_cstate=1 processor.max_cstate=1.
  7. Ladenie sieťových vyrovnávacích pamätí iba ak ste namerali úzke hrdlo na úložnej alebo streamovacej trase 25/100 GbE.
  8. Preskočiť 1 GB explicitných obrovských stránok pokiaľ nemáte benchmark ukazujúci tlak TLB.
  9. 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.