Lab 05-04 · Cluster RPC¶
Obiettivo¶
Far girare un modello usando la memoria (e, se c'è, la GPU) di un'altra macchina attraverso il backend RPC di ggml:
avviare ggml-rpc-server sull'host remoto, collegarlo con --rpc, verificare la distribuzione dei pesi e misurare il
prezzo che si paga in velocità. Lo stesso esercizio funziona su una sola macchina con due terminali (o due container):
è la forma usata negli esempi che seguono.
Prerequisiti¶
- Due macchine sulla stessa rete locale fidata (A = principale, B = remota), oppure una macchina sola con due terminali.
- Su entrambe i binari del tarball della release (es.
llama-b11046-bin-ubuntu-x64.tar.gz, modulo 01) o una build con-DGGML_RPC=ON. Il binario dell'installerllamanon ha il backend RPC: il suo--helpnon mostra--rpc. - Il modello scaricato sulla macchina A (B riceve i tensori dalla rete, non legge il file).
Materiale¶
| Cosa | Fonte | Dimensione |
|---|---|---|
| Modello di prova | ggml-org/Qwen3.5-0.8B-GGUF → Qwen3.5-0.8B-Q8_0.gguf (Apache 2.0) |
795 MB |
| Modello "che non entra" (variante) | ggml-org/gemma-3-12b-it-GGUF:Q4_K_M |
6,96 GB |
| Binari | tarball della release in ~/llama-lab/rel/llama-b11046/ (contiene ggml-rpc-server, llama-cli, llama-server, llama-bench e libggml-rpc.so) |
16 MB |
Output atteso:
load_backend: loaded RPC backend from …/libggml-rpc.so
load_backend: loaded CPU backend from …/libggml-cpu-haswell.so
Usage: ggml-rpc-server [options]
-t, --threads N number of threads for the CPU device (default: 3)
-d, --device <dev1,dev2,...> comma-separated list of devices
-H, --host HOST host to bind to (default: 127.0.0.1)
-p, --port PORT port to bind to (default: 50052)
-c, --cache enable local file cache
Procedura¶
-
Sulla macchina B (o nel terminale 1): avvia il server. In locale usa
127.0.0.1; su due macchine usa l'indirizzo LAN di B (-H 192.168.1.20) e solo su una rete fidata:Output atteso:
Starting RPC server v7.0.0 endpoint : 127.0.0.1:50052 local cache : n/a Devices: CPU: AMD EPYC Processor (with IBPB) (11960 MiB, 11960 MiB free) transport : TCPSu una macchina con GPU compare invece
CUDA0: NVIDIA … (32109 MiB, 31588 MiB free); con-d CUDA0oCUDA_VISIBLE_DEVICESscegli quali dispositivi esporre. -
Sulla macchina A (terminale 2): il dispositivo remoto è visibile?
Il dispositivo si chiama
RPC0(poiRPC1… per altri server, in ordine di elenco). Sul server compareAccepted client connection/Client connection closed. -
Genera attraverso la rete.
M=$(ls ~/.cache/huggingface/hub/models--ggml-org--Qwen3.5-0.8B-GGUF/snapshots/*/Qwen3.5-0.8B-Q8_0.gguf) $R/llama-cli --rpc 127.0.0.1:50052 -m "$M" -st -p "ciao" -n 20 -t 3 -rea offOutput su una macchina a 6 vCPU senza GPU:
Il caricamento è più lento del normale: i pesi vengono inviati al server RPC (785 MB su loopback in pochi secondi; su una LAN a 1 Gbit/s circa 8 secondi, per un modello da 7 GB oltre un minuto).
-
Dove sono finiti i pesi? Ripeti con
-v(log completo) e cerca i buffer:$R/llama-cli --rpc 127.0.0.1:50052 -m "$M" -st -p "ciao" -n 5 -rea off -v 2>&1 | grep -E "RPC0|CPU_Mapped|offloaded|buffer size"Di default llama.cpp distribuisce pesi e KV cache tra dispositivi locali e remoti in proporzione alla memoria libera;
-nglconta anche il dispositivo RPC come "GPU". Con-tsimponi le proporzioni:-ts 1,0(tutto sul primo dispositivo),-ts 1,1(metà e metà). Prova-ngl all -ts 0,1per mandare tutto al server remoto e confronta la rigaGeneration:con il passo 3. -
Il server HTTP con backend remoto. Tutto ciò che vale per
llama-clivale perllama-server:Termina con Ctrl+C e leggi
llama_memory_breakdown_print: c'è una riga perRPC0. -
Cache locale (variante). Su B riavvia con
-c: alla seconda esecuzione i tensori grandi vengono letti da~/.cache/llama.cpp/rpcinvece che ricevuti dalla rete. Cronometra il caricamento prima e dopo. -
Chiudi tutto. Ctrl+C sul server RPC, oppure:
Un server RPC dimenticato acceso è un rischio (vedi sotto).
Verifica del risultato¶
-
--list-devicesmostraRPC0con la memoria del server. - Il modello ha risposto attraverso RPC e hai annotato pp/tg.
- Hai confrontato la velocità con lo stesso comando senza
--rpc: la differenza è il costo della rete (in locale piccolo, su LAN grande). - Hai spento il server RPC e verificato con
pgrep -af rpc-serverche non ci sia più.
Nessuna autenticazione: rete fidata soltanto
ggml-rpc-server non ha password, token né TLS; il README ufficiale lo definisce proof of concept, fragile e
insicuro e dice di non avviarlo mai su una rete aperta. Chi raggiunge la porta può usare la tua GPU e la tua RAM
a piacere. Regole: -H 127.0.0.1 o indirizzo di LAN isolata, firewall che accetta solo la macchina A, oppure un
tunnel SSH (ssh -L 50052:localhost:50052 utente@B) o una VPN; spegnere il server quando non serve.
Domande e varianti¶
- Perché la generazione via RPC è più lenta anche quando il server ha una GPU veloce? Pensa a cosa attraversa la rete a ogni token (attivazioni tra i layer) e con quale latenza.
- Con due macchine:
-ts 3,1(A tiene il 75 %) contro-ts 1,3. Quale ordine è meglio se A ha la GPU più veloce? - Due server RPC:
--rpc B:50052,C:50052. In quale ordine compaiono in--list-devices? GGML_RPC_DEBUG=1 ggml-rpc-server …mostra ogni comando ricevuto: conta quanti messaggi servono per generare 5 token.- Due container sulla stessa macchina: crea una rete (
docker network create rpc), avvia due container Ubuntu con il tarball montato in/opt/llamae usa i nomi dei container come host (--rpc rpc-b:50052). Stesse regole di sicurezza: la rete è interna a Docker, non pubblicare la porta con-p. - Con una GPU su B e un modello che non entra nella VRAM di A (gemma-3-12b), confronta: tutto su A con
-nglparziale contro A+B via RPC. Chi vince dipende dalla rete: con 1 Gbit/s quasi sempre l'ibrido locale, con 10 Gbit/s o Thunderbolt/RDMA il cluster.
Consegna¶
Il log di avvio del server (le righe Devices:), l'uscita di --list-devices, la riga [ Prompt … | Generation … ]
con e senza --rpc, e cinque righe di conclusioni: quando useresti RPC e quali misure di sicurezza adotteresti.