Benchmarking 6 Open LLMs on a 2-Machine RPC Cluster (Consumer GPUs, ~96GB VRAM)
In the endless pursuit of "bigger, bigger, and even bigger," I finally reached this point: two machines directly connected via a local area network, using RPC scheduling to split and load the model layer by layer across
In the endless pursuit of "bigger, bigger, and even bigger," I finally reached this point: two machines directly connected via a local area network, using RPC scheduling to split and load the model layer by layer across both hosts.
The reason is simpleβI have a limited budget. Buying a professional-grade graphics card with 96GB of VRAM would definitely not pass my wife's approval. So for consumer-level GPU users on a budget like me, linking multiple machines and GPUs via RPC is currently the only realistic option.
The setup itself is straightforward: connect two machines with an Ethernet cable. I used a nominally 5Gbps CAT6A cable, and the actual tested bandwidth is about 4.7Gbpsβyielding a throughput of around 500 MB/s. Under this bandwidth, llama.cpp's RPC chain invocation is currently the only viable choice (a Thunderbolt 5 adapter is on the way; once it arrives, it should close some of the performance gap).
The ambient temperature during testing was 35Β°C; the CPU reached 76Β°C, and the RTX 5090 (power-limited to 450W) peaked at 68Β°C.
No special optimizations were made at the architecture levelβI just got the official RPC server running end-to-end first, leaving optimizations for later.
Hardware Setup
| Host | GPU | VRAM |
|---|---|---|
| Host 1 | RTX 5080 | 16GB |
| Host 1 | RTX 5060 Ti Γ2 | 16GB Γ 2 |
| Host 2 | RTX 5090 | 32GB |
| Host 2 | RTX 5060 Ti | 16GB |
This totals approximately 96GB of VRAM, with the two hosts directly connected via a CAT6A network cable.
Pitfall Record: tensor-split Order
Once the two machines were connected, it was time to pick the models. With a 96GB budget, there isn't actually much room for choiceβyou have to consider production-level concurrency requirements (according to current market expectations, a 96GB setup is considered a poor investment if it can't support a team of 8-15 people), while also balancing KV context size and model precision.
When running the first model (Qwen3.6-35B-A3B Q8_0), I noticed the main card (5090) was using less than 7GB of VRAMβa massive waste. At the time, --tensor-split was set to 32,16,16,16,16, intending to allocate the largest share to the main card. But the actual device order was:
[ local - RPC : 5080 , local - RPC : 5060Ti , local - RPC : 5060Ti , 5090 , 5060Ti ]
In other words, the remote RPC cards were placed at the front, while the local main card was at the endβthe exact opposite of what I expected. This is why the VRAM allocation didn't land on the 5090 as intended.
Candidate Models
| Model | Quantization | Type / Active Params | Layers | Model Size | Thinking Mode |
|---|---|---|---|---|---|
| qwen36 Β· Qwen3.6-35B-A3B | Q8_0 | MoE, 3B active | Split into 5 layers | ~42GB | Disabled |
| llama33 Β· Llama-3.3-70B | Q6_K | Dense | 80 layers, split into 5 parts | ~73GB | No thinking capability |
| qwen25 Β· Qwen2.5-72B | Q6_K | Dense | 80 layers | ~80GB | No thinking capability |
| glm Β· GLM-4.5-Air | Q4_K_M | MoE | 46 layers | ~73GB | No thinking capability |
| qwen235 Β· Qwen3-235B-A22B-2507 | Q2_K_XL | MoE | 94 layers | ~88GB | Disabled |
| gpt-oss-120b | MXFP4 | MoE | 36 layers | ~65GB | Cannot disable, set to "low" |
The comparison between Qwen3.6-35B-A3B and Llama-3.3-70B perfectly illustrates the architectural differences. Llama is a Dense modelβevery token activates all 80 layers of parameters, so the overhead introduced by splitting across 5 GPUs plus one cross-machine network hop is magnified by about 9 times. In practice, its speed is only about 10 tok/sβbarely enough for one person doing translation work (close to reading speed), but with noticeable latency. On the other hand, Qwen3.6 is an MoE model, activating only 3B parameters per token; the computation involved in running it on the same 5 GPUs is significantly lower.
Methodology
With thinking mode disabled, the models were evaluated across 5 dimensions:
| Dimension | Measurement Content | Test Cases | Scoring Method |
|---|---|---|---|
| 1. Speed / Concurrency | TTFT (Time to First Token), Decode TPS, Performance degradation at 1/2/4 concurrency | Automated load test | Fully automated (tok/s, TTFT ms) |
| 2. Translation Error Rate | Rare/error-prone characters (from real novel corpora), JP to ZH, including classic mistranslation traps | 101 | Fully automated (compared vs standard translation β error rate) |
| 3. Code Understanding | High difficulty: Bug troubleshooting, behavior prediction, hierarchical allocator implementation, TP bandwidth reasoning, bash traps, refactoring | 6 | Manual scoring (based on checkpoints) |
| 4. Hallucination Rate | False premises, fake citations, fabricated terms/APIs, unknowable questions, translation trapsβall fact-checked | 24 | Heuristic + manual judgment |
| 5. Translation Proofreading/Correction | Proofreading and correction, polishing fidelity, terminology consistency | 9 | Scored separately from scratch translation |
The judge was primarily Claude 3.5 Sonnet (Opus 4.8 equivalent internally), supplemented by partial manual review.
A few notes:
- I could only run models my hardware could handle; models under 48GB were tested in previous articles.
- This is a personal test, and the test case design inherently carries some subjectivity.
- All tests were single runs, with no voting mechanisms or self-reflectionβaccuracy relied entirely on the model's own restraint. If popular multi-path reasoning verification were applied, accuracy would likely improve, but this requires more compute and time, so it wasn't done here.
- The sample sizes in dimensions 3, 4, and 5 are very small (6/24/9 questions respectively). Any disputed judgment is enough to change the rankings. Please view the "Overall Comparison" conclusions below as a directional signal rather than a statistically significant difference.
VRAM Usage per Model (Initial Test Run)
| Model | Host 1 (5080 + 5060TiΓ2) | Host 2 (5090 + 5060Ti) |
|---|---|---|
| Qwen3.6-35B-A3B Q8_0 | 13.0GB / 14.0GB / 8.3GB | 6.9GB / 7.9GB |
| Llama-3.3-70B Q6_K | 12.4GB / 11.1GB / 13.8GB | 22.7GB (13%) / 13.7GB (23%) |
| Qwen2.5-72B Q6_K | 13.4GB / β / β | 24.7GB / 14.8GB / 12.0GB (100%) |
| GLM-4.5-Air Q4_K_M | 11.2GB / 10.1GB (100%) / 10.1GB | 28.0GB / 8.7GB |
| Qwen3-235B-A22B-2507 Q2_K_XL | 14.8GB / 14.8GB / 14.2GB | 28.8GB / 13.4GB |
| gpt-oss-120b MXFP4 | 11.0GB / 11.3GB (57%) / 9.1GB | 26.8GB / 8.0GB |
Note: In-host GPU ordering and VRAM allocation ratios are heavily influenced by --tensor-split and loading sequence; host/card allocation is not fixed across modelsβit reflects the actual RPC scheduling results in a specific run.
Overall Comparison Summary
| Model (Quant) | Type / Active | Decode tok/s (short ctx) | Max Usable Context | Error Rate β | Code Understanding | Hallucination Rate β | Proofreading |
|---|---|---|---|---|---|---|---|
| Qwen3.6-35B-A3B Q8_0 | MoE 3B | 88 | 128K | 35.6% | 83% | 18.8% | 100% |
| gpt-oss-120b MXFP4 | MoE 5.1B | 94 | 128K | 45.5% | 75% | 56.3% β | 83.3% |
| GLM-4.5-Air Q4_K_M | MoE 12B | 53 | 65K | 40.6% | 100% | 70.8% β | 94% |
| Qwen3-235B-A22B-2507 Q2_K_XL | MoE 22B | 31 | 8K β | 35.6% | 58% | 35.4% | 89% |
| Qwen2.5-72B Q6_K | Dense | 10 | 32K | 42.6% | 83% | 54.2% | 100% |
| Llama-3.3-70B Q6_K | Dense | 11 | 98K | 54.5% β | 67% | 75.0% β | 78% |
(Note: "Max Usable Context" reflects the measured upper limit under the specific resource allocation, not the model's inherent capability limit.)
Core Conclusion: In a CAT6A (5Gbps) network and llama.cpp RPC chain invocation environment, Qwen3.6-35B-A3B Q8_0 is the best-performing model overall in this testβit ranks at the top in speed, concurrency degradation, translation error rate, and hallucination suppression.
Final Thoughts
After finishing the Qwen2.5 run, I looked back at the VRAM usage and realized that the SAM/CLIP small models left over from earlier tests hadn't actually been completely offloaded. This is a good reminder: in an environment running multiple models mixed together, you should always manually verify the VRAM that "should be freed," rather than blindly trusting that a process exit will definitely clean it up.
Another thought worth recording: Qwen3.6-35B-A3B Q8_0 only took up about 42GB of VRAM, which means it could actually run entirely on a single machine. This left me in deep thoughtβI went through all this trouble to build a dual-node RPC cluster, only to end up essentially running a model that a single machine could handle? I'll continue pondering this question when the Thunderbolt 5 adapters arrive for the next benchmarking post.
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.