After making the giant models fit, we returned to models that did not need all eight GPUs for one copy. Would the second quad make one request faster, or would it be more useful serving another request? We compared cross-socket tensor parallelism, independent replicas and MoE expert parallelism. The answer depended on both the model and the user count, and one apparent hardware limit turned out to be our proxy.
Qwen3.8-27B · FP8 weights · FP8 KV Qwen3.6-35B-A3B · FP8 weights · FP8 KV vLLM 0.31.0 · 8× H200 NVL
The question
We first ran a common 256K-configured grid on three eight-GPU deployments, using vLLM 0.31.0, FP8 weights and FP8 KV. Two layouts used dense Qwen3.8-27B; the DEP8 layout used MoE Qwen3.6-35B-A3B. That first comparison asks what those complete deployments deliver. It cannot attribute every difference to parallelism because the model changes too. The later same-model tables are the stronger evidence for choosing a layout.
- 8 replicas (TP1 × 8): Qwen3.8-27B, one independent vLLM server per GPU, each pinned to its own socket's CPUs, with a small round-robin proxy in front.
- TP8: Qwen3.8-27B as one engine with every layer split across all eight GPUs (
--tensor-parallel-size 8), withNCCL_P2P_LEVEL=SYSso NCCL uses direct GPU-to-GPU traffic between the sockets [S24]. - DEP8: Qwen3.6-35B-A3B, a mixture-of-experts model, with
--data-parallel-size 8 --enable-expert-parallel. Attention runs as eight data-parallel copies, and the experts are split across all eight GPUs [S05] [S04].
The grid: 1,024-token prompts with 1,024-token answers at 1, 64 and 256 users at once, 8,192-token prompts at 64 users, and for TP8 an extra 16-user point. DEP8 runs a different model (a 35B MoE with about 3B active parameters, against a 27B dense model), so TP8 vs replicas is the like-for-like comparison, and DEP8 shows what the MoE layout does on the same node.
The node: two islands
This matters more than anything else here. The eight GPUs are two groups of four. Inside a group, every pair has six bonded NVLinks (NV6). Between the groups there is no NVLink: traffic crosses PCIe and the link between the two CPU sockets (SYS) (Part 1). NVIDIA's guidance for bridged H200 NVL cards is to keep each NVLink group within one CPU domain [S01], and this server does that, so any layout that spans all eight GPUs has to cross sockets.

Cross-island GPU-to-GPU traffic didn't even work properly at first. With the Intel IOMMU in translated mode, direct writes between the sockets failed, and NCCL quietly fell back to host shared memory. We switched to IOMMU passthrough (intel_iommu=on iommu=pt) and rebooted, following NCCL's troubleshooting guidance. After that, cross-socket copies ran at 38.5 GB/s and an 8-GPU all_reduce with NCCL_P2P_LEVEL=SYS reached 83.1 GB/s of bus bandwidth, against 337 GB/s inside one quad (our measurements, Part 1 has the details and logs). The TP8 run below depends on that fix.

Results: users vs throughput and speed

All numbers are our measurement.
- Eight copies beat one engine split eight ways, everywhere. At 64 users the 8 replicas produced 3,912 tokens/s at 13.3 ms per token, and TP8 634 at 25.2 ms. At 256 users it was at least 6,388 against 2,565 (the replica point is proxy-limited, see below).
- TP8 didn't even help a single user. One request alone took 13.2 ms per token on TP8 and 11.5 ms on one GPU of the replica layout. Every layer of a TP8 model ends in an
all_reduceacross all eight GPUs, so every token waits on the cross-socket link, which carries about a quarter of the in-quad bandwidth by our nccl-tests numbers. We think that's why, but we didn't profile it. - TP8 decode was spiky. At 64 users its median was 25.2 ms per token, but the p99 was 273 ms (the replicas' p99 was 13.9 ms).
- DEP8 was the fastest single user and the biggest total, at 9.9 ms per token alone and 7,582 tokens/s at 256 users (31.3 ms per token each). That's a smaller-active-parameter model, so it's not a verdict on DEP vs replicas. The vLLM docs describe this layout for MoE models: attention replicated per data-parallel rank, experts sharded across all ranks [S05].
- The replicas' 256-user point is limited by our own proxy, so it's a lower bound. Median first token was 117 ms, but the p90 was 131 s, and the engines' counters, summed over all eight, never showed more than 102 requests running while 256 were in flight. Our proxy opens its upstream connections through aiohttp's default connector, which allows 100 simultaneous connections aiohttp docs: TCPConnector, limit defaults to 100. So roughly 150 requests waited in the proxy, not in vLLM. The 64-user points are under that limit and unaffected. A fair 256-user replica number needs a rerun with that limit lifted.
Longer prompts: 8K in, 1K out, 64 users

With 8K-token prompts the replicas produced 3,001 tokens/s (17.5 ms per token) and DEP8 2,445 (23.6 ms). The TP8 point is left out: its engine counters show a 7.3% prefix-cache hit rate in a grid meant to start cold, so it fails our cache rule (cold_cache_hit in final.csv).
The 16-user anomaly
We added a 16-user point to the TP8 run because 8-GPU runs elsewhere in the campaign had shown 200-290 ms per token at batch 16. It reproduced: 182.5 ms per token and 83.5 tokens/s for the whole node. Sixteen users together got barely more than one user alone (75.0 tokens/s), and far less than 64 users (634 tokens/s). It wasn't a few bad steps. The median gap between tokens was 183.7 ms and the p99 193.8 ms, so every step was slow. No errors in the server log, all 48/48 requests completed, and the median first token was 532 ms (our measurement).
WARNING [symm_mem.py:107] SymmMemCommunicator: symmetric memory multicast operations are not supported.
WARNING [custom_all_reduce.py:265] Custom allreduce is disabled because it's not supported on more than two PCIe-only GPUs.
WARNING [flashinfer_all_reduce.py:108] Failed to initialize FlashInfer All Reduce workspace: [SymmDeviceMemory] Device
does not support multicasting.. This is expected on GPUs without NVSwitch (e.g., NVLink bridge-only or PCIe topologies).
WARNING [flashinfer_all_reduce.py:216] FlashInfer mnnvl allreduce workspace unavailable (likely no NVSwitch multicast
support); falling back to trtllm backend for single node.
INFO [flashinfer_all_reduce.py:224] Initialized FlashInfer Allreduce norm fusion workspace with backend=trtllm
... 'pass_config': {... 'fuse_allreduce_rms': True, ...}The suspected cause. By default, vLLM fuses each layer's all_reduce with the RMSNorm that follows it (fuse_allreduce_rms). Its preferred fused kernel needs NVLink multicast across every GPU in the tensor-parallel group, which only an NVSwitch provides. Our log shows exactly that check failing, followed by a fallback to the trtllm fused backend. A public bug report on the same hardware class (8× H200 NVL, two bridged NVLink islands, TP8) describes this fallback as working but very slow: 719.6 ms median inter-token latency at 32 concurrent requests with fusion on, against 20.7 ms with fuse_allreduce_rms turned off [S96]. The proposed fix in vLLM PR #48075 checks for multicast and, if it's missing, turns the fusion off and uses plain NCCL plus a separate RMSNorm. The PR's own H200 NVL numbers: 733 ms with the forced trtllm path, 21 ms with the fix. As of this build the PR is still open.
The upstream report gave us a testable hypothesis, but our pattern did not fully match it. TP8 was slow at 16 users, near-normal at one user (13.2 ms/token), and mostly fast but spiky at 64 and 256. We therefore treated the fused all-reduce fallback as a suspect and ran two interventions. The completed A/B below did not reproduce the upstream improvement: neither disabling the fusion nor disabling FlashInfer all-reduce removed our cliff.
The fusion-off A/B: neither fix helped
| Arm (Qwen3.8-27B TP8, NCCL_P2P_LEVEL=SYS) | 1 user ms/token | 16 users out tok/s | 16 users ms/token | 64 users out tok/s | Run |
|---|---|---|---|---|---|
| Baseline (fusion on) | 13.2 | 83.5 | 182.5 | 634 | 1010-153414 |
| fuse_allreduce_rms false (vLLM #48071 workaround) | 13.6 | 79.7 | 191.9 | 635 | 1010-165539 |
| VLLM_ALLREDUCE_USE_FLASHINFER=0 | 13.3 | 79.7 | 191.7 | 632 | 1010-172355 |
Both interventions reproduced the 16-user cliff: about 192 ms/token versus 182 ms in the baseline, with little movement at one or 64 users. They failed our proposed pass rule of at least a 3× improvement at 16 users, so we did not carry the workaround into the giant-model launches. This weakens the specific fusion-fallback hypothesis for our configuration; it does not prove that every possible interaction with that path is irrelevant. The unresolved next step was a profile of the TP8 16-user cell.
Four GPUs or eight? Same users, twice the hardware
The question a buyer actually asks: if the users don't change, what do the other four GPUs buy? We ran the same 1K/1K user steps (1, 64 and 256 users at once) and the 8K-prompt step at 64 users on one quad and on the whole node. The 4-GPU layouts ran on Saturday 10 Oct; the 8-GPU ones on Saturday evening and, for the layouts marked new below, on Sunday 11 Oct. All numbers are our own measurements.
In vLLM, a MoE model with --enable-expert-parallel spreads its experts over TP × DP GPUs, so TEP4 × DP2 means four-way tensor parallel attention, two data-parallel ranks and experts split eight ways vLLM docs: expert parallel deployment. Our TP4 × DP2 for the dense Qwen3.8-27B keeps each TP4 engine inside one NVLink quad, so no tensor traffic crosses the sockets.

| Model | Layout | 1 user ms/token | 64 users tok/s | 256 users tok/s | 256 users tok/s per GPU | 256 users ms/token | 8K prompt, 64 users tok/s | 8K, 64 users TTFT ms | Run |
|---|---|---|---|---|---|---|---|---|---|
| Qwen3.8-27B | 4 GPUs · 4 copies (TP1) | 11.5 | 3,531 | 5,314 | 1,328 | 17.6 | 2,261 | 744 | 1010-010602 |
| Qwen3.8-27B | 4 GPUs · 2 copies (TP2) | 8.3 | 4,017 | 5,897 | 1,474 | 16.2 | 2,223 | 556 | 1010-012340 |
| Qwen3.8-27B | 8 GPUs · 8 copies (TP1) | 11.4 | 3,885 | 11,268 | 1,409 | 18.8 | 2,871 | 715 | 1010-205644 |
| Qwen3.8-27B | 8 GPUs · 4 copies (TP2) | 8.3 | 4,775 | 12,328 | 1,541 | 17.8 | 3,198 | 516 | 1010-211609 |
| Qwen3.8-27B | 8 GPUs · TP4 × DP2 (one engine per island) **(new, 11 Oct)** | 6.3 | 5,117 | 11,439 | 1,430 | 20.4 | 3,426 | 344 | 1011-071732 |
| Qwen3.8-27B | 8 GPUs · TP8 across islands | 13.2 | 634 | 2,565 | 321 | 62.3 | - | - | 1010-153414 |
| Qwen3.6-35B-A3B | 4 GPUs · 4 copies (TP1) | 4.4 | 5,887 | 8,533 | 2,133 | 11.2 | 4,842 | 260 | 1010-015516 |
| Qwen3.6-35B-A3B | 4 GPUs · DEP4 (DP4 attention + EP4) | 6.0 | 4,470 | 9,228 | 2,307 | 26.2 | 3,021 | 301 | 1010-022232 |
| Qwen3.6-35B-A3B | 8 GPUs · 8 copies (TP1) **(new, 11 Oct)** | 4.4 | 7,444 | 18,391 | 2,299 | 12.2 | 6,818 | 257 | 1011-070943 |
| Qwen3.6-35B-A3B | 8 GPUs · DEP8 (DP8 attention + EP8) | 9.9 | 3,657 | 7,582 | 948 | 31.3 | 2,445 | 384 | 1010-163633 |
| Qwen3.6-35B-A3B | 8 GPUs · TEP4 × DP2 (TP4, EP8) **(new, 11 Oct)** | 7.7 | 3,410 | 6,646 | 831 | 36.5 | - | - | 1011-065213 |
The extra quad paid when the workload could use it. At 256 users, Qwen3.8-27B replicas produced 11,268 tokens/s on eight GPUs versus 5,314 on four (2.1×). TP2 pairs produced 12,328 versus 5,897 (2.1×). At 64 users the replica gain was only 1.1×, 3,885 versus 3,531. One request still uses one copy, so simply adding copies is not a single-request acceleration technique.
For Qwen3.6-35B-A3B, DEP8 produced less than DEP4 at 256 users: 7,582 versus 9,228 tokens/s. Cross-socket expert communication is a plausible contributor, but we did not profile it. Eight independent one-GPU copies reached 18,391 tokens/s, 2.2× four copies. TEP4×DP2 reached 6,646, or 0.88× DEP8. On the same eight GPUs the independent copies therefore delivered 2.8× TEP4×DP2 and 2.4× DEP8 at 256 users, and also led at one and 64 users. That is the direct same-model evidence for avoiding unnecessary distributed experts in this short-prompt grid.
Qwen3.8-27B made the choice less absolute. Two quad-local TP4 engines delivered 11,439 tokens/s at 256 users (1.02× eight one-GPU copies) and 6.3 ms/token for one user. This was the strongest measured Qwen3.8-27B layout at 64 users, including 8K prompts: 3,426 tokens/s with a 344 ms first token. Keeping each tensor-parallel group within a quad was materially better than our cross-socket TP8 run. Qwen3.6 TEP4×DP2 has no valid 8K point because prefix-cache hits contaminated that run.
Fit the model, then replicate the queue.
One run per layout, one node, short random prompts with distinct warm-up prompts. The 4-GPU runs used the same grid and software, early on Saturday 10 Oct. Replica layouts sit behind our round-robin proxy; on the 4-GPU replica runs we had no counter for requests actually running, so we can't rule out the same proxy cap there. Throughput per GPU is total output divided by the GPUs the layout occupies, not a measure of how busy each GPU was. None of these layout runs had a needle check of its own; under our rule each inherits the latest check for the same model at the same 256K maximum context, which passed 3/3 for both Qwen models.
The GLM-5.3-Flash 8-GPU layouts (TP4 × DP2, TP8, TP8 + DCP8) were planned for this chapter and dropped on Sunday to fit the 16:00 IST deadline.
In our main grid, Qwen3.6's dp4 layouts are labelled data-parallel attention + TP4 experts (no EP). Without --enable-expert-parallel, vLLM forms the expert layers into one tensor-parallel group across the data-parallel ranks [S04]. The dense Qwen3.8-27B's dp4 is four plain data-parallel copies.
Replica size and precision (Sunday 02:26 to 04:08 IST)
Same Qwen3.8-27B, 256K maximum context, vLLM 0.31.0, all eight GPUs in use, with a round-robin proxy in front. We compared one copy per GPU (8 × TP1) against one copy per GPU pair (4 × TP2), each in FP8 and in an INT4 build, plus ThinkingCap-Qwen3.8-27B (a fine-tune of the same base, FP8) as 8 × TP1. Each run had a fresh server, distinct warm-up prompts, a needle gate (all passed 1.0), the 1K/1K user grid, a 250K-token document at 1 and 4 users, and 250 GSM8K questions.
| Model · layout | 1 user ms/token | 256 users out tok/s | 256 users ms/token | 250K doc TTFT p50 | 250K doc ms/token | KV pool (all copies) | GSM8K (250) | Run |
|---|---|---|---|---|---|---|---|---|
| FP8 · 8 × TP1 | 11.4 | 11,268 | 18.8 | 44.4 s | 16.8 | 23.32M | 0.744 | 1010-205644 |
| FP8 · 4 × TP2 | 8.3 | 12,328 | 17.8 | 25.2 s | 13.1 | 27.12M | 0.740 | 1010-211609 |
| INT4 · 8 × TP1 | 11.4 | 10,841 | 19.7 | 55.8 s | 17.0 | 26.09M | 0.716 | 1010-213412 |
| INT4 · 4 × TP2 | 9.0 | 10,891 | 20.5 | 30.5 s | 14.1 | 28.52M | 0.752 | 1010-215751 |
| ThinkingCap FP8 · 8 × TP1 | 11.5 | 11,309 | 18.8 | 44.2 s | 16.9 | 23.32M | 0.768 | 1010-221630 |
What it shows. At 256 short-chat users the two layouts were close (about 11.3K vs 12.3K output tokens/s in FP8). Pairs gave the fastest single user and the shortest time to first token on a 250K-token document (pairs split the prefill), and a bigger KV pool (27.1M vs 23.3M tokens across all copies), because each copy's weights are spread over two GPUs. INT4 bought more KV room but not more speed here: it was slower than FP8 at 256 users in both layouts. ThinkingCap ran at the same speed as the base model in every cell, which is what you'd expect from a fine-tune with identical architecture and precision. Its GSM8K score was a little higher (0.768 vs 0.744), but on 250 questions that gap is about one standard error, so we don't call it a quality difference.
One run per cell, one node. GSM8K on 250 questions has a standard error of about 2.7 points, so scores within about 3 points of each other are a tie. The KV pool is what vLLM reported at start-up, summed over copies.
Every point
All measured points (results/final.csv)
| Layout | In/out tokens | Users | Completed | Out tok/s | Per GPU | TTFT p50 | TTFT p90 | ms/token p50 | ms/token p99 | Note |
|---|---|---|---|---|---|---|---|---|---|---|
| Qwen3.8-27B · 8 replicas (TP1 ×8) + load balancer | 1,024/1,024 | 1 | 16/16 | 87 | 11 | 0.08 s | 0.14 s | 11.5 | 11.5 | |
| Qwen3.8-27B · 8 replicas (TP1 ×8) + load balancer | 1,024/1,024 | 64 | 256/256 | 3,912 | 489 | 0.12 s | 0.57 s | 13.3 | 13.9 | |
| Qwen3.8-27B · 8 replicas (TP1 ×8) + load balancer | 1,024/1,024 | 256 | 1024/1024 | 6,388 | 798 | 0.12 s | 130.50 s | 14.5 | 15.3 | proxy-capped (about 100 running) |
| Qwen3.8-27B · 8 replicas (TP1 ×8) + load balancer | 8,192/1,024 | 64 | 256/256 | 3,001 | 375 | 0.73 s | 3.22 s | 17.5 | 24.8 | |
| Qwen3.8-27B · TP8 across both islands (NCCL_P2P_LEVEL=SYS) | 1,024/1,024 | 1 | 16/16 | 75 | 9 | 0.14 s | 0.21 s | 13.2 | 13.2 | |
| Qwen3.8-27B · TP8 across both islands (NCCL_P2P_LEVEL=SYS) | 1,024/1,024 | 16 | 48/48 | 83 | 10 | 0.53 s | 0.81 s | 182.5 | 184.6 | anomaly |
| Qwen3.8-27B · TP8 across both islands (NCCL_P2P_LEVEL=SYS) | 1,024/1,024 | 64 | 256/256 | 634 | 79 | 0.22 s | 2.10 s | 25.2 | 272.8 | |
| Qwen3.8-27B · TP8 across both islands (NCCL_P2P_LEVEL=SYS) | 1,024/1,024 | 256 | 1024/1024 | 2,565 | 321 | 0.34 s | 7.26 s | 62.3 | 110.9 | |
| Qwen3.8-27B · TP8 across both islands (NCCL_P2P_LEVEL=SYS) | 8,192/1,024 | 64 | 256/256 | - | - | - | - | - | - | excluded: cache hits in a cold grid |
| Qwen3.6-35B-A3B · DEP8 (DP8 attention + EP8 experts) | 1,024/1,024 | 1 | 16/16 | 101 | 13 | 0.12 s | 0.14 s | 9.9 | 10.1 | |
| Qwen3.6-35B-A3B · DEP8 (DP8 attention + EP8 experts) | 1,024/1,024 | 64 | 256/256 | 3,657 | 457 | 0.12 s | 0.86 s | 14.9 | 16.9 | |
| Qwen3.6-35B-A3B · DEP8 (DP8 attention + EP8 experts) | 1,024/1,024 | 256 | 1024/1024 | 7,582 | 948 | 0.15 s | 2.30 s | 31.3 | 38.0 | |
| Qwen3.6-35B-A3B · DEP8 (DP8 attention + EP8 experts) | 8,192/1,024 | 64 | 256/256 | 2,445 | 306 | 0.38 s | 4.97 s | 23.6 | 31.3 |
One grid, three runs, one node, all our measurement. The 1K and 8K prompts are random tokens, with prefix caching on but distinct warm-up prompts. DEP8 runs a different (MoE) model from the other two. TP8 used NCCL_P2P_LEVEL=SYS, the replicas and DEP8 used NCCL defaults. No long-context points are in this grid yet. The suspected cause of the TP8 anomaly comes from public reports and our log lines, not from a profile.
- Compare replicas before extending a small model across sockets. In the initial grid, eight Qwen3.8-27B replicas gave 6.2× TP8’s throughput at 64 users and at least 2.5× at the proxy-capped 256-user point, with faster single-user decode. Quad-local TP4 and TP2 pairs then showed that the useful choice was the size of each independent serving group, not simply “parallelism versus replicas.”
- Use startup warnings to form a hypothesis, then keep the negative result. The multicast/fallback warnings resembled a public H200 NVL issue. Our two fusion interventions still produced roughly 192 ms/token at 16 users. The resemblance did not establish the cause, and the cliff remained unresolved in this campaign.
- Keep the same-model comparison in view. DEP8 reached 7,582 tokens/s at 256 users, but the later eight-replica Qwen3.6 run reached 18,391. Its strong showing against a different dense model in the first table was not evidence that DEP8 was the best way to serve that MoE.
- Check the harness before the hardware. Our replica proxy quietly capped itself at about 100 requests in flight. The engines' running-request counters showed it, and the latency numbers alone would have blamed the replicas.
Before tuning further, audit the failures
The replica results were useful only after we separated a proxy cap, cache contamination and an unresolved TP8 cliff from real model behaviour. Part 7 collects that diagnostic record, including the fixes that worked and the plausible hypotheses that did not.
Sources
Bracketed ids [S..] refer to the campaign bibliography (docs/SOURCES.md). Numbers not attributed to a source are our own measurements on this node.
- [S24] NVIDIA, NCCL environment variables
- [S05] vLLM project, Expert Parallel Deployment (docs)
- [S04] vLLM project, Data Parallel Deployment (docs)
- [S01] NVIDIA, H200 NVL product brief (PB-12243): NVLink bridge topology guidance
- [S96] vLLM project, https://github.com/vllm-project/vllm/issues/48071
- aiohttp, https://docs.aiohttp.org/en/stable/client_reference.html#tcpconnector (aiohttp docs: TCPConnector, limit defaults to 100)
- qtris123, https://github.com/vllm-project/vllm/pull/48075 (vLLM PR #48075)
- vLLM, https://docs.vllm.ai/en/latest/serving/expert_parallel_deployment.html (vLLM docs: expert parallel deployment)