GenesiGenesiWiki
Features

Mesh walkthrough: borrow another machine's GPU

Two ways to use someone else's GPU, which one you want, and the exact steps for each.

How to run a model using the GPU of another machine — including when the two are in different buildings.

Every step says what it does and what you should see. If the expected output does not appear, stop there: each step fails for a different reason, and carrying on only makes the diagnosis harder.

First: which of the two do you want?

Genesi can borrow another machine's GPU in two completely different ways. Almost everyone wants the first one.

Serve (Turbo over HTTP)Pool (VRAM over RPC)
Commandgenesi-mesh serve ongenesi-mesh worker on
What crosses the networkTextLayer activations, every token
Use it whenThe model fits on the GPU machineThe model fits on neither machine alone
SpeedNetwork barely mattersBounded by round-trip latency
Runs the modelThe GPU machineSplit across both

If the model fits on the machine with the GPU, use Serve. Pooling that same model is dramatically slower, and not by a little.

Measured on a real two-machine setup: a 1.9 GB model, client in a VM with no GPU, worker on an RTX 3050 with 6.7 GB free, over a direct LAN link. Pooling worked exactly as designed — the weights landed on the remote GPU. The GPU then sat at 2–3% utilisation, idle, waiting on a 9 ms round trip, while roughly 1.2 MB/s of tensor traffic bought almost no work. The bottleneck is the round trip, and no amount of tuning moves it.

Pooling earns its keep for one thing only: running a model that otherwise could not run at all.

Which machine is which

The GPU machineThe other one
In Serve modeRuns the model and serves the APIJust a client; talks HTTP
In Pool mode (worker)Lends its VRAM, runs rpc-serverHolds the model, runs llama-server
Needs a GPUYesNo

The GPU machine cannot be a virtual machine. A VM does not have the host's GPU. The other machine can be a VM — it needs no GPU at all.


Prerequisites (both modes)

Install a llama.cpp with the RPC backend on each machine — CUDA on NVIDIA, Vulkan elsewhere. The backends do not have to match; each machine executes on whatever its own build has.

sudo pacman -Syu genesi-llama-cpp-cuda   # NVIDIA
sudo pacman -Syu genesi-llama-cpp        # AMD / Intel / generic

What must match is the llama.cpp version. Both packages are pinned to one upstream commit for exactly this reason: two machines on different builds hang forever at "loading model" with nothing printed on either end. Mesh now refuses such a pairing outright rather than letting it hang. Update both machines together.

Check each machine:

genesi-mesh doctor

doctor probes the live system, not just the config: whether the ports are actually listening, and whether a firewall is dropping them. It distinguishes refused (reachable, nothing listening — start the service) from blocked (no answer at all — open the port), which is the difference between two very different afternoons.


The GPU machine runs the model; the other one just talks to it.

On the GPU machine, start serving

sudo genesi-mesh serve on

What it does: points Turbo at the network instead of loopback, opens port 11435 under whichever firewall is actually running, and enables the service. All three, reporting each — doing them by hand is three steps that are each easy to half-do.

Expected: confirmation of each step. If it says it found no active firewall manager, that is information, not a failure: a rule written to a stopped ufw prints "Rules updated", exits 0 and filters nothing.

Turbo has no authentication. Leaving loopback is a deliberate decision; only do it on a network you control.

Pair the machines

Follow Pairing below, then come back.

On the other machine, just use it

genesi-ai-turbo serve llama3.2:3b

There is nothing to configure. The mesh advertises which peers are serving Turbo, and a machine with no usable GPU automatically uses a peer's rather than building a CPU server next to an idle remote GPU. It prints which one it picked.

Force a local server anyway with --local (or GENESI_TURBO_LOCAL=1).

Confirm

genesi-mesh peers

A peer serving Turbo is tagged [turbo: <model>], naming what it is running.

By default each machine picks the best Turbo available. To decide for yourself:

genesi-mesh use              # what is selected, and what is in effect
sudo genesi-mesh use local   # always run here
sudo genesi-mesh use old-pc  # pin one machine

A pinned peer that stops serving falls back to this machine, not to another peer, and switches back on its own when it returns.


Mode B — Pool VRAM

Only when the model fits on neither machine alone.

On the GPU machine, prove it can lend before involving the network

sudo systemctl enable --now genesi-meshd
genesi-mesh selftest

What it does: starts a real rpc-server and connects a real client to it, entirely within this one machine.

Expected: PASS — this machine can serve its GPU to the mesh.

A failure here is local — driver or build. Fix it before adding a second machine.

Start lending VRAM

sudo genesi-mesh worker on

Expected: genesi-mesh status shows worker: ON (listening on ...).

Verify it is really listening — the config saying "on" is not proof the process started:

ss -tlnp | grep 50052

rpc-server has no authentication either. worker on moves the bind off loopback; restrict it to your VPN by setting rpc_bind = <your-vpn-ip> in /etc/genesi-mesh/mesh.conf, then sudo systemctl reload genesi-meshd.

Pair, then run

After Pairing:

genesi-ai-turbo serve

Expected: [mesh] pooling across: <address>:50052.

If pooling is not used, Turbo now says why — no peers, no --rpc support, too big even pooled, or the model already fits locally. Silence used to be the only answer, which was indistinguishable from the feature not existing.

Mesh pools against free VRAM, not the size of the card. A worker busy running its own model on the very GPU it is lending has almost nothing to give, and announcing capacity instead of availability made loads fail at allocation time after transferring everything.

Confirm the remote GPU is working

On the GPU machine, while the other one generates:

watch -n1 nvidia-smi

The AI Mode Monitor's Mesh tab also states plainly whether Turbo is currently using the mesh or running locally.


Pairing

Needed by both modes.

Put both machines on one network

sudo pacman -S tailscale
sudo systemctl enable --now tailscaled
sudo tailscale up
tailscale ip -4

Skip if both machines are already on one router. Sign in with the same account on both, and note each address.

Mandatory checkpoint, from one machine:

ping <the-other-address>

If this does not answer, stop. Nothing below fixes an unreachable machine.

Create the trusted network

On the first machine:

sudo genesi-mesh init

Copy the secret it prints. On the second:

sudo genesi-mesh join <the-secret>

Both machines end up with an identical secret. That is the goal, not a bug — a shared secret is how the two ends authenticate each other.

Register the address (required on a VPN)

sudo genesi-mesh peer <the-other-address>

On both machines, each pointing at the other.

What it does: discovery uses UDP multicast, which no VPN forwards. This sends the announcement straight to the address by unicast, which every VPN carries.

Without this, genesi-mesh peers stays empty forever on a VPN. It is the most common way a correct setup looks broken. On a shared LAN it is unnecessary.

Confirm

genesi-mesh peers
Peers (1)
  genesi-x8664    100.64.162.89    CUDA    6871 free of 8192 MiB   worker [turbo: llama3.2:3b]

If the peer appears, you are paired. If not, fix it here.

All of this is also available without a terminal, in the Mesh tab of the AI Mode Monitor: the sharing toggles, registering a machine by address, create/join, and the doctor.


Where it usually gets stuck

SymptomCauseFix
rpc-server: missingllama.cpp without GGML_RPC=ONInstall genesi-llama-cpp or -cuda
selftest failsLocal driver or build problemFix before involving the network
Hangs at "loading model"Mismatched llama.cpp versionsUpdate both machines
peers empty on a VPNMulticast does not cross itgenesi-mesh peer <ip> on both
peers empty on one LANFirewallgenesi-mesh doctor names the zone
Connects, then fails to allocateThe worker's GPU is busyFree it, or pick a smaller model
Pooling works but is very slowRound-trip bound — expectedUse Serve instead if the model fits
A command seems to hangYou ran genesi-meshd (the daemon)Use genesi-mesh, without the d