Article

LLM Tensor Parallel Inference Deployment: Reducing Cross-GPU Jitter with Parallelism, NCCL, and Topology Awareness

A practical guide to Tensor Parallel, Pipeline Parallel, NCCL communication, and topology-aware tuning for large model cross-GPU inference deployment. Covers parallelism selection, node networking, stress testing metrics, and pre-launch checks to help teams reduce multi-GPU service jitter.

Background: Fitting the Model Doesn’t Mean Stable Service

As model sizes grow from 7B/13B to 70B/100B+, a single GPU often becomes insufficient. Teams typically consider two options: upgrade to GPUs with more memory, or shard the model across multiple GPUs. The former is simple but costly; the latter is flexible but shifts the problem from “is memory enough” to “is cross-GPU communication stable.”

In production inference, Tensor Parallel’s primary value isn’t making the system look more distributed—it’s splitting the matrix computations of a single model replica across multiple GPUs, allowing one large model to serve as a single logical replica. It solves the problem of “a single replica can’t fit or a single GPU is too slow,” not general horizontal scaling.

This is where many LLM serving projects stumble when first going multi-GPU:

  • The model starts and endpoints return results, but P95/P99 latency is very jittery
  • Single-request stress tests pass, but NCCL timeouts occur under concurrency
  • The same GPU set shows significant throughput differences when moved to different slots or nodes
  • Cross-node deployment increases TTFT and makes TPOT unstable

This article focuses on: how to choose tensor_parallel_size and pipeline_parallel_size, how to understand NCCL communication costs, how to enforce deployment constraints based on GPU/NIC topology, and what to stress test before launch.

Core Principles: Tensor Parallel Essentially Creates Communication at Every Layer

Tensor Parallel Splits Intra-Layer Matrices

In Transformer inference, both attention and MLP layers involve extensive matrix computations. Tensor Parallel splits the weight matrices within a layer column-wise or row-wise across multiple GPUs, allowing them to compute their shards simultaneously, then merge results via collective communication.

This is fundamentally different from Data Parallel:

ParallelismSplitting DimensionProblem SolvedCommunication Characteristics
Data ParallelMultiple replicas handle different requestsInsufficient throughputGradient sync (training) / No sync (inference)
Tensor ParallelSingle replica, intra-layer matrix splitSingle GPU can’t fit / insufficient computeCross-GPU sync potentially at every layer
Pipeline ParallelSingle replica, inter-layer splitSingle node can’t fitInter-layer passing, pipeline bubble exists

The Hugging Face Transformers Tensor Parallelism documentation describes it as “splitting model layers into multiple pieces and having multiple accelerators work simultaneously,” explicitly noting the need for fast intra-node communication because GPUs exchange partial results at every layer. This description is excellent for production teams to understand its cost boundary: Tensor Parallel’s benefit comes from parallel computation, its cost from per-layer communication.

NCCL is the Critical Path for Cross-GPU Communication

In NVIDIA GPU clusters, NCCL is the most common collective communication library. It provides primitives like AllReduce, Broadcast, Reduce, AllGather, ReduceScatter, and AlltoAll, as well as point-to-point send/receive. In Tensor Parallel inference, the common bottleneck isn’t some ordinary HTTP endpoint—it’s the cumulative overhead of these collective operations at every layer, every batch, and every decode step.

A typical pipeline can be abstracted as:

request -> tokenizer -> GPU shard 0/1/2/3 compute
  -> NCCL collective communication
  -> next layer compute
  -> NCCL collective communication
  -> logits -> sampling -> token response

If GPUs have NVLink or NVSwitch, intra-node Tensor Parallel tends to be more stable. With only PCIe, especially across CPU sockets or NUMA domains, communication latency and bandwidth become more sensitive. Cross-node Tensor Parallel imposes higher network requirements, typically needing InfiniBand, RoCE, GPUDirect RDMA, correct NIC selection, and proper container shared memory configuration.

Pipeline Parallel Splits Inter-Layer Stages

Pipeline Parallel differs in its splitting dimension. It divides the model into stages by layers, e.g., the first 20 layers on node A, the next 20 on node B. This can reduce some intra-layer AllReduce operations but introduces a pipeline bubble: some stages wait for the previous stage’s output, preventing GPUs from being fully utilized.

The vLLM parallelism scaling documentation offers practical advice:

  • If the model fits on a single GPU, distributed inference is unnecessary
  • If the model is too large but fits on a single node with multiple GPUs, use Tensor Parallel
  • If the model is too large for a single node, combine Tensor Parallel with Pipeline Parallel
  • Typically set tensor_parallel_size to the number of GPUs per node and pipeline_parallel_size to the number of nodes

This heuristic works well for most first-version production deployments.

Engineering Implementation: First Choose Parallelism, Then Enforce Topology Constraints

Step 1: Choose Parallel Strategy Based on Memory and Model Replica

Follow this order for initial judgment:

  1. Single GPU can fit the model, KV cache, and target concurrency: Prioritize single-GPU replicas + Data Parallel horizontal scaling
  2. Single GPU can’t fit, but a single node with multiple GPUs can: Prioritize Tensor Parallel
  3. Single node with multiple GPUs still can’t fit: Use Tensor Parallel + Pipeline Parallel
  4. GPU count can’t evenly split the model, or no high-speed interconnect within the node: Evaluate if Pipeline Parallel is more stable than Tensor Parallel

A very practical detail from the vLLM documentation: after startup, check the logs for GPU KV cache size and Maximum concurrency. The former indicates how many tokens the GPU KV cache can store simultaneously; the latter estimates how many concurrent requests can be supported given max_model_len. If this estimate is below business requirements, adjusting parallelism or adding GPUs is meaningful; otherwise, simply tuning the ingress queue and gateway rate limiting won’t solve the underlying capacity issue.

Step 2: Explicitly Hardcode Parallel Parameters

Don’t let production services “auto-guess” parallelism. Parallelism should be part of the release configuration and included in rollback records.

An example vLLM single-node, 4-GPU Tensor Parallel setup:

vllm serve meta-llama/Llama-3.1-70B-Instruct \
  --tensor-parallel-size 4 \
  --max-model-len 32768 \
  --gpu-memory-utilization 0.90

A combined example with 2 nodes, 8 GPUs per node:

vllm serve /models/llama-70b \
  --tensor-parallel-size 8 \
  --pipeline-parallel-size 2 \
  --distributed-executor-backend ray

These parameters aren’t just one-time command-line details; they are part of the release version. It’s recommended to record them in a model service configuration table, along with model version, quantization version, max_model_len, batch parameters, GPU SKU, and node pool labels.

Step 3: Enforce GPU and NIC Affinity Constraints

Multi-GPU inference stability heavily depends on topology. In production, at minimum, record the following information:

nvidia-smi topo -m
nvidia-smi -L
ibstat || true
NCCL_DEBUG=INFO vllm serve ...

On Kubernetes, avoid the scheduler placing multi-GPU tasks on unsuitable nodes or across NUMA topologies with poor connectivity. The vLLM documentation mentions that when configuring containers for GPUDirect RDMA, attention must be paid to IPC_LOCK, /dev/shm, shared memory mounts, etc. It also recommends using NCCL_DEBUG=TRACE to check logs for NET/IB/GDRDMA and ensure it hasn’t fallen back to NET/Socket.

A simplified Kubernetes constraint example:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: llm-tp-server
spec:
  template:
    spec:
      nodeSelector:
        gpu.interconnect: nvlink
        rdma.enabled: "true"
      containers:
        - name: vllm
          image: vllm/vllm-openai:latest
          securityContext:
            capabilities:
              add: ["IPC_LOCK"]
          resources:
            limits:
              nvidia.com/gpu: 8
          volumeMounts:
            - mountPath: /dev/shm
              name: dshm
      volumes:
        - name: dshm
          emptyDir:
            medium: Memory

The key is to make GPU interconnect, RDMA capability, node pool isolation, and container shared memory conditions configurable, rather than relying on manual memory.

Stress Testing Methodology: Separate Prefill, Decode, and Communication

Don’t Just Look at Total tokens/s

Total throughput can easily mask problems. A multi-GPU deployment might look good on average tokens/s but have terrible P99 TPOT, caused by requests with long-context prefills, communication congestion under certain batches, or some NIC paths falling back to TCP sockets.

It’s recommended to at least break down these metrics:

MetricFocus
TTFT (Time to First Token)Queuing, prefill, model loading status
TPOT / ITL (Inter-Token Latency)Cross-GPU sync cost during decode
P95 / P99 latencyTail latency, don’t just look at averages
GPU compute utilizationWhether compute is actually being used
GPU memory / KV cache usageWhether close to eviction or OOM
NCCL collective timeWhether communication is the main bottleneck
Cross-node network throughput, packet loss, retransmission, RoCE ECN/PFC statusEssential for cross-node TP

Stress Test Matrix Should Cover Parallelism Combinations

Establish a small matrix rather than testing just one configuration:

model: 70B instruct
input tokens:  512 / 4k / 16k / 32k
output tokens: 128 / 1k / 4k
parallelism:
  - TP=1, DP=N
  - TP=2, DP=N/2
  - TP=4, DP=N/4
  - TP=8
  - TP=8, PP=2
metrics:
  - TTFT p50/p95/p99
  - TPOT p50/p95/p99
  - tokens/s
  - request/s
  - GPU memory
  - NCCL time
  - error / timeout

If increasing TP from 4 to 8 doesn’t significantly improve throughput, or even worsens tail latency, it usually means communication overhead has offset the compute gains. At this point, don’t blindly increase TP further. Instead, evaluate better model quantization, reduce max_model_len, use more Data Parallel replicas, or switch from cross-node TP to single-node TP with multi-replica load balancing.

Include NCCL Logs in Canary Checks

The NCCL documentation emphasizes that collective operations require each rank to call with the same count and datatype, otherwise hangs, crashes, or data corruption can occur. In production, the symptom is often not an “immediate error” but stalls, timeouts, restarts, or some ranks being unresponsive for extended periods.

During canary testing, enable temporary verbose logging:

export NCCL_DEBUG=INFO
export NCCL_DEBUG_SUBSYS=INIT,GRAPH,NET,COLL

Key observations include:

  • Whether the expected network interface is being used
  • Whether InfiniBand / RDMA / GDRDMA is enabled
  • Whether socket fallback occurs
  • Whether any rank initializes slowly or communicator times out
  • Whether cross-NUMA, cross-socket, or low-speed links are involved

Log volume can be high, so it’s not recommended to keep TRACE enabled for all traffic long-term. However, samples must be retained during canary, stress testing, and incident postmortem phases.

Common Misconceptions

Misconception 1: More GPUs Always Mean Faster

Tensor Parallel isn’t free. Each additional GPU splits computation finer but also adds more communication synchronization. For small batches, short outputs, or nodes without high-speed interconnects, more GPUs can degrade single-request latency stability.

Misconception 2: Tensor Parallel Can Replace Data Parallel

They solve different problems. Tensor Parallel addresses a single replica not fitting or a single GPU being underpowered; Data Parallel addresses multi-request throughput. In production, it’s common to use TP to form one large model replica and then use multiple such replicas for DP.

Misconception 3: If the Model Starts Successfully, It’s Ready for Launch

A multi-GPU model starting successfully only confirms weight loading and basic communication. It doesn’t prove that long contexts, concurrent batches, error recovery, node restarts, network degradation, or NCCL timeouts are all under control. Stress testing with the target request distribution is mandatory before launch.

Misconception 4: Cross-Node TP and Single-Node TP Can Be Configured the Same Way

Cross-node TP is very sensitive to the network. Without InfiniBand, RoCE, GPUDirect RDMA, or proper NIC affinity, cross-node Tensor Parallel can cause significant tail latency jitter. In many scenarios, single-node TP with multi-replica DP is more stable than cross-node TP.

Applicable Scenarios

Scenarios suitable for Tensor Parallel:

  • Single GPU memory can’t accommodate model weights and target KV cache
  • Need to serve 70B, 100B+ models with high-speed GPU interconnect within the node
  • Single replica needs higher decode throughput, and the business can tolerate some cross-GPU communication overhead
  • Need to combine with Pipeline Parallel to run large models that don’t fit on a single node

Scenarios where Tensor Parallel is not the first choice:

  • Model runs stably on a single GPU, and the bottleneck is just request volume
  • Node lacks high-speed interconnect, with complex PCIe topology
  • Requests are mostly short context and short output, making communication overhead high
  • Team lacks experience with NCCL, GPU topology, RDMA, stress testing, and failure recovery

Pre-Launch Checklist

Before launch, at minimum confirm the following:

  1. Model version, quantization version, max_model_len, TP/PP/DP configurations are hardcoded
  2. GPU SKU, memory, NVLink/NVSwitch/PCIe topology, and NIC locations are recorded
  3. Stress test matrix for short input, long input, short output, and long output is completed
  4. TTFT, TPOT, P95/P99, tokens/s, and request/s are recorded separately
  5. vLLM logs for GPU KV cache size and Maximum concurrency are checked
  6. NCCL is verified to use the expected network path without unexpected socket fallback
  7. Kubernetes node labels, GPU resources, IPC_LOCK, /dev/shm, and RDMA conditions are included in deployment templates
  8. NCCL, GPU, network, and service layer logs are retained during canary phase
  9. Automatic removal and rollback strategies are defined for NCCL timeout, rank hang, GPU OOM, and node restart
  10. Degradation plans are prepared: reduce max_model_len, decrease concurrency, switch to a smaller model, fall back to single-node TP or multi-replica DP

References

  1. vLLM Parallelism and Scaling
  2. vLLM Engine Arguments
  3. Hugging Face Transformers: Tensor Parallelism
  4. NVIDIA NCCL Overview
  5. NVIDIA NCCL Collective Operations
  6. TensorRT-LLM Useful Build-Time Flags
  7. gLLM: Global Balanced Pipeline Parallelism System for Distributed LLM Serving with Token Throttling
  8. Parallel Track Transformers: Enabling Fast GPU Inference with Reduced Synchronization

FAQ

How should I choose between Tensor Parallel and Data Parallel?
If a single model replica cannot fit on one GPU, prioritize Tensor Parallel or Pipeline Parallel. If a single replica runs stably but throughput is insufficient, typically add more Data Parallel replicas first.
Why does latency get worse when adding more GPUs?
Cross-GPU inference introduces communication overhead from AllReduce, AllGather, ReduceScatter, etc. GPU topology, NVLink, PCIe, InfiniBand, GPUDirect RDMA, and NCCL configuration all affect tail latency.
What are the most critical stress testing metrics before launch?
Don't just look at tokens/s. Also monitor TTFT, TPOT, P95/P99 latency, GPU utilization, NCCL communication time, KV cache capacity, maximum concurrency estimates, and error/retry rates.
Can Tensor Parallel and Pipeline Parallel be used together?
Yes. A common approach is to use Tensor Parallel within a node and Pipeline Parallel across nodes. This way, each node handles a segment of the model, while multiple GPUs within the node share the intra-layer computation. Actual benefits depend on model size, layer count, GPU topology, network, and request distribution.